diff options
author | Nikolay Korolev <nickvnuk@gmail.com> | 2021-01-07 16:38:40 +0100 |
---|---|---|
committer | Nikolay Korolev <nickvnuk@gmail.com> | 2021-01-07 16:38:40 +0100 |
commit | 5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3 (patch) | |
tree | 435e3b7d8d0c9b0a8e75bd97a34bbf446c0d9730 | |
parent | some lcs stuff (diff) | |
parent | fail (diff) | |
download | re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.tar re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.tar.gz re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.tar.bz2 re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.tar.lz re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.tar.xz re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.tar.zst re3-5e10f1fe6ae08fe1b6ec2f52f8d097d54c4b8ab3.zip |
67 files changed, 2439 insertions, 613 deletions
diff --git a/premake5.lua b/premake5.lua index 26c64c35..9796b8a9 100644 --- a/premake5.lua +++ b/premake5.lua @@ -125,11 +125,9 @@ workspace "reVC" filter { "platforms:*x86*" } architecture "x86" - floatingpoint "Fast" filter { "platforms:*amd64*" } architecture "amd64" - floatingpoint "Fast" filter { "platforms:*arm*" } architecture "ARM" @@ -192,11 +190,9 @@ project "librw" filter { "platforms:*x86*" } architecture "x86" - floatingpoint "Fast" filter { "platforms:*amd64*" } architecture "amd64" - floatingpoint "Fast" filter "platforms:win*" staticruntime "on" diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp index 8f03d66a..01b33fa5 100644 --- a/src/audio/AudioLogic.cpp +++ b/src/audio/AudioLogic.cpp @@ -4201,109 +4201,109 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) switch (sound) { case SOUND_STEP_START: case SOUND_STEP_END: - if (!params.m_pPed->bIsLooking) { - emittingVol = m_anRandomTable[3] % 15 + 45; - if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) - emittingVol /= 2; - maxDist = 400.f; - switch (params.m_pPed->m_nSurfaceTouched) { - case SURFACE_GRASS: - sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; - break; - case SURFACE_GRAVEL: - case SURFACE_MUD_DRY: - sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; - break; - case SURFACE_CAR: - case SURFACE_GARAGE_DOOR: - case SURFACE_CAR_PANEL: - case SURFACE_THICK_METAL_PLATE: - case SURFACE_SCAFFOLD_POLE: - case SURFACE_LAMP_POST: - case SURFACE_FIRE_HYDRANT: - case SURFACE_GIRDER: - case SURFACE_METAL_CHAIN_FENCE: - case SURFACE_CONTAINER: - case SURFACE_NEWS_VENDOR: - sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; - break; - case SURFACE_SAND: - sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; - break; - case SURFACE_WATER: - sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; - break; - case SURFACE_WOOD_CRATES: - case SURFACE_WOOD_BENCH: - case SURFACE_WOOD_SOLID: - sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; - break; - case SURFACE_HEDGE: - sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; - break; - default: - sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; - break; - } - m_sQueueSample.m_nSampleIndex = sampleIndex; - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 32; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - switch (params.m_pPed->m_nMoveState) { - case PEDMOVE_WALK: - emittingVol /= 4; - m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; - break; - case PEDMOVE_RUN: - emittingVol /= 2; - m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; - break; - case PEDMOVE_SPRINT: - m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; - break; - default: - break; - } - m_sQueueSample.m_nReleasingVolumeModificator = 5; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 20.0f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; + if (params.m_pPed->bIsInTheAir) + continue; + emittingVol = m_anRandomTable[3] % 15 + 45; + if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity) + emittingVol /= 2; + maxDist = 400.f; + switch (params.m_pPed->m_nSurfaceTouched) { + case SURFACE_GRASS: + sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1; + break; + case SURFACE_GRAVEL: + case SURFACE_MUD_DRY: + sampleIndex = m_anRandomTable[4] % 5 + SFX_FOOTSTEP_GRAVEL_1; + break; + case SURFACE_CAR: + case SURFACE_GARAGE_DOOR: + case SURFACE_CAR_PANEL: + case SURFACE_THICK_METAL_PLATE: + case SURFACE_SCAFFOLD_POLE: + case SURFACE_LAMP_POST: + case SURFACE_FIRE_HYDRANT: + case SURFACE_GIRDER: + case SURFACE_METAL_CHAIN_FENCE: + case SURFACE_CONTAINER: + case SURFACE_NEWS_VENDOR: + sampleIndex = m_anRandomTable[0] % 5 + SFX_FOOTSTEP_METAL_1; + break; + case SURFACE_SAND: + sampleIndex = (m_anRandomTable[4] & 3) + SFX_FOOTSTEP_SAND_1; + break; + case SURFACE_WATER: + sampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + break; + case SURFACE_WOOD_CRATES: + case SURFACE_WOOD_BENCH: + case SURFACE_WOOD_SOLID: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_WOOD_1; + break; + case SURFACE_HEDGE: + sampleIndex = m_anRandomTable[2] % 5 + SFX_COL_VEG_1; + break; + default: + sampleIndex = m_anRandomTable[2] % 5 + SFX_FOOTSTEP_CONCRETE_1; + break; + } + m_sQueueSample.m_nSampleIndex = sampleIndex; + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - SOUND_STEP_START + 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + switch (params.m_pPed->m_nMoveState) { + case PEDMOVE_WALK: + emittingVol /= 4; + m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_RUN: + emittingVol /= 2; + m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10; + break; + case PEDMOVE_SPRINT: + m_sQueueSample.m_nFrequency = 12 * m_sQueueSample.m_nFrequency / 10; + break; + default: + break; } + m_sQueueSample.m_nReleasingVolumeModificator = 5; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 20.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; break; case SOUND_FALL_LAND: case SOUND_FALL_COLLAPSE: - if (!ped->bIsLooking) { - maxDist = SQR(30); - emittingVol = m_anRandomTable[3] % 20 + 80; - if (ped->m_nSurfaceTouched == SURFACE_WATER) { - m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; - } else if (sound == SOUND_FALL_LAND) { - m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; - } else { - m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; - } - m_sQueueSample.m_nBankIndex = SFX_BANK_0; - m_sQueueSample.m_nCounter = 1; - m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); - m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); - m_sQueueSample.m_nReleasingVolumeModificator = 2; - m_sQueueSample.m_fSpeedMultiplier = 0.0f; - m_sQueueSample.m_fSoundIntensity = 30.0f; - m_sQueueSample.m_nLoopCount = 1; - m_sQueueSample.m_nLoopStart = 0; - m_sQueueSample.m_nLoopEnd = -1; - m_sQueueSample.m_nEmittingVolume = emittingVol; - m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReleasingSoundFlag = true; - m_sQueueSample.m_bRequireReflection = true; + if (ped->bIsInTheAir) + continue; + maxDist = SQR(30); + emittingVol = m_anRandomTable[3] % 20 + 80; + if (ped->m_nSurfaceTouched == SURFACE_WATER) { + m_sQueueSample.m_nSampleIndex = (m_anRandomTable[3] & 3) + SFX_FOOTSTEP_WATER_1; + } else if (sound == SOUND_FALL_LAND) { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND; + } else { + m_sQueueSample.m_nSampleIndex = SFX_BODY_LAND_AND_FALL; } + m_sQueueSample.m_nBankIndex = SFX_BANK_0; + m_sQueueSample.m_nCounter = 1; + m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex); + m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17); + m_sQueueSample.m_nReleasingVolumeModificator = 2; + m_sQueueSample.m_fSpeedMultiplier = 0.0f; + m_sQueueSample.m_fSoundIntensity = 30.0f; + m_sQueueSample.m_nLoopCount = 1; + m_sQueueSample.m_nLoopStart = 0; + m_sQueueSample.m_nLoopEnd = -1; + m_sQueueSample.m_nEmittingVolume = emittingVol; + m_sQueueSample.m_bIs2D = false; + m_sQueueSample.m_bReleasingSoundFlag = true; + m_sQueueSample.m_bRequireReflection = true; break; case SOUND_FIGHT_37: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1; @@ -4342,6 +4342,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nFrequency = 20000; goto AddFightSound; case SOUND_FIGHT_46: + case SOUND_187: m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5; m_sQueueSample.m_nFrequency = 18000; goto AddFightSound; @@ -4354,7 +4355,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nFrequency = 20000; AddFightSound: { - uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? stroring int as float + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float uint8 damagerType = soundParams & 0xFF; uint32 weaponType = soundParams >> 8; @@ -4402,7 +4403,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) case SOUND_WEAPON_BAT_ATTACK: case SOUND_WEAPON_KNIFE_ATTACK: { - uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? stroring int as float + uint32 soundParams = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i]; // wtf? storing int as float uint8 damagerType = soundParams & 0xFF; uint32 weaponType = soundParams >> 8; if (damagerType == ENTITY_TYPE_PED) { @@ -4461,7 +4462,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) continue; m_sQueueSample.m_nSampleIndex = SFX_CAR_ACCEL_13; m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW - m_sQueueSample.m_nCounter = 64; + m_sQueueSample.m_nCounter = 70; m_sQueueSample.m_nFrequency = 27000; m_sQueueSample.m_nReleasingVolumeModificator = 3; m_sQueueSample.m_fSpeedMultiplier = 3.0f; @@ -4473,7 +4474,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_ACCEL_13); m_sQueueSample.m_nEmittingVolume = 100; m_sQueueSample.m_bIs2D = false; - m_sQueueSample.m_bReverbFlag = false; + m_sQueueSample.m_bReleasingSoundFlag = false; m_sQueueSample.m_nReleasingVolumeDivider = 5; break; case SOUND_WEAPON_CHAINSAW_IDLE: @@ -5159,7 +5160,7 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms) m_sQueueSample.m_nReleasingVolumeDivider = 3; } } - break; + continue; default: SetupPedComments(params, sound); continue; @@ -9922,7 +9923,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) nCheckPlayingDelay[slot] = 0; nFramesUntilFailedLoad[slot] = 0; } else if (!m_nUserPause) { - if (++nFramesForPretendPlaying[slot] < 120) { + if (++nFramesForPretendPlaying[slot] < 90) { m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING; } else { m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED; @@ -9938,7 +9939,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) } else { if (m_nUserPause) SampleManager.PauseStream(1, slot + 1); - if (m_sMissionAudio.m_bPredefinedProperties) { + if (m_sMissionAudio.m_bPredefinedProperties[slot]) { if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAL) SampleManager.SetStreamedVolumeAndPan(80, 0, 1, slot + 1); else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAR) @@ -9992,7 +9993,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot) else { SampleManager.PauseStream(0, slot + 1); - if (!m_sMissionAudio.m_bPredefinedProperties) { + if (!m_sMissionAudio.m_bPredefinedProperties[slot]) { distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]); if (distSquared >= SQR(80.0f)) { emittingVol = 0; diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index d441b750..721a7acc 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -10,6 +10,7 @@ #include "sampman.h" #include "Camera.h" #include "World.h" +#include "ZoneCull.h" cAudioManager AudioManager; @@ -17,12 +18,16 @@ const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples); const int policeChannel = channels + 1; const int allChannels = channels + 2; +#define SPEED_OF_SOUND 343.f +#define TIME_SPENT 40 + cAudioManager::cAudioManager() { m_bIsInitialised = false; m_bReverb = true; - m_fSpeedOfSound = 6.86f; - m_nTimeSpent = 50; + field_6 = 0; + m_fSpeedOfSound = SPEED_OF_SOUND / TIME_SPENT; + m_nTimeSpent = TIME_SPENT; m_nActiveSamples = NUM_SOUNDS_SAMPLES_SLOTS; m_nActiveSampleQueue = 1; ClearRequestedQueue(); @@ -585,7 +590,7 @@ cAudioManager::AddSampleToRequestedQueue() } m_sQueueSample.m_nCalculatedVolume = calculatedVolume; m_sQueueSample.m_bLoopEnded = false; - if (m_sQueueSample.m_bIs2D) { + if (m_sQueueSample.m_bIs2D || CCullZones::InRoomForAudio()) { m_sQueueSample.m_bRequireReflection = false; m_sQueueSample.m_nLoopsRemaining = 0; } @@ -597,6 +602,9 @@ cAudioManager::AddSampleToRequestedQueue() } m_sQueueSample.m_bRequireReflection = false; + if ( m_bReverb && m_sQueueSample.m_bIs2D ) + m_sQueueSample.field_4C = 30; + if (!m_bDynamicAcousticModelingStatus) m_sQueueSample.m_bReverbFlag = false; @@ -643,9 +651,9 @@ cAudioManager::AddReflectionsToRequestedQueue() emittingVolume = m_sQueueSample.m_nVolume; oldFreq = m_sQueueSample.m_nFrequency; } else { - emittingVolume = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 16); + emittingVolume = (9 * m_sQueueSample.m_nVolume) / 16; } - m_sQueueSample.m_fSoundIntensity = m_sQueueSample.m_fSoundIntensity / 2.f; + m_sQueueSample.m_fSoundIntensity /= 2.f; int halfOldFreq = oldFreq >> 1; diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp index c4abf351..acfe09c3 100644 --- a/src/audio/MusicManager.cpp +++ b/src/audio/MusicManager.cpp @@ -25,7 +25,7 @@ cMusicManager MusicManager; int32 gNumRetunePresses; int32 gRetuneCounter; bool g_bAnnouncementReadPosAlready; -uint8 RadioStaticCounter; +uint8 RadioStaticCounter = 5; uint32 RadioStaticTimer; CVector vecRiotPosition(300.7f, -322.0f, 12.0f); @@ -435,7 +435,7 @@ cMusicManager::ServiceFrontEndMode() else { if (m_nCurrentVolume < m_nMaxVolume) m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6); - SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63u, 0, 0); + SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0); } } else { if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER) @@ -991,6 +991,7 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped) } } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) { SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, 0, 0); + nFramesSinceCutsceneEnded = 0; } else { if (nFramesSinceCutsceneEnded == -1) volume = m_nCurrentVolume; diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp index 3a1f748f..cdf063fa 100644 --- a/src/audio/oal/stream.cpp +++ b/src/audio/oal/stream.cpp @@ -8,10 +8,14 @@ #include <opusfile.h> #else #ifdef _WIN32 +#ifdef AUDIO_OAL_USE_SNDFILE #pragma comment( lib, "libsndfile-1.lib" ) +#endif #pragma comment( lib, "libmpg123-0.lib" ) #endif +#ifdef AUDIO_OAL_USE_SNDFILE #include <sndfile.h> +#endif #include <mpg123.h> #endif @@ -19,7 +23,374 @@ #include "crossplatform.h" #endif +/* +As we ran onto an issue of having different volume levels for mono streams +and stereo streams we are now handling all the stereo panning ourselves. +Each stream now has two sources - one panned to the left and one to the right, +and uses two separate buffers to store data for each individual channel. +For that we also have to reshuffle all decoded PCM stereo data from LRLRLRLR to +LLLLRRRR (handled by CSortStereoBuffer). +*/ + +class CSortStereoBuffer +{ + uint16* PcmBuf; + size_t BufSize; +public: + CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {} + ~CSortStereoBuffer() + { + if (PcmBuf) + free(PcmBuf); + } + + uint16* GetBuffer(size_t size) + { + if (size == 0) return nil; + if (!PcmBuf) + { + BufSize = size; + PcmBuf = (uint16*)malloc(BufSize); + } + else if (BufSize < size) + { + BufSize = size; + PcmBuf = (uint16*)realloc(PcmBuf, size); + } + return PcmBuf; + } + + void SortStereo(void* buf, size_t size) + { + uint16* InBuf = (uint16*)buf; + uint16* OutBuf = GetBuffer(size); + + if (!OutBuf) return; + + size_t rightStart = size / 4; + for (size_t i = 0; i < size / 4; i++) + { + OutBuf[i] = InBuf[i*2]; + OutBuf[i+rightStart] = InBuf[i*2+1]; + } + + memcpy(InBuf, OutBuf, size); + } + +}; + +CSortStereoBuffer SortStereoBuffer; + #ifndef AUDIO_OPUS +class CImaADPCMDecoder +{ + const uint16 StepTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, + 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 + }; + + int16 Sample, StepIndex; + +public: + CImaADPCMDecoder() + { + Init(0, 0); + } + + void Init(int16 _Sample, int16 _StepIndex) + { + Sample = _Sample; + StepIndex = _StepIndex; + } + + void Decode(uint8 *inbuf, int16 *_outbuf, size_t size) + { + int16* outbuf = _outbuf; + for (size_t i = 0; i < size; i++) + { + *(outbuf++) = DecodeSample(inbuf[i] & 0xF); + *(outbuf++) = DecodeSample(inbuf[i] >> 4); + } + } + + int16 DecodeSample(uint8 adpcm) + { + uint16 step = StepTable[StepIndex]; + + if (adpcm & 4) + StepIndex += ((adpcm & 3) + 1) * 2; + else + StepIndex--; + + StepIndex = clamp(StepIndex, 0, 88); + + int delta = step >> 3; + if (adpcm & 1) delta += step >> 2; + if (adpcm & 2) delta += step >> 1; + if (adpcm & 4) delta += step; + if (adpcm & 8) delta = -delta; + + int newSample = Sample + delta; + Sample = clamp(newSample, -32768, 32767); + return Sample; + } +}; + +class CWavFile : public IDecoder +{ + enum + { + WAVEFMT_PCM = 1, + WAVEFMT_IMA_ADPCM = 0x11, + WAVEFMT_XBOX_ADPCM = 0x69, + }; + + struct tDataHeader + { + uint32 ID; + uint32 Size; + }; + + struct tFormatHeader + { + uint16 AudioFormat; + uint16 NumChannels; + uint32 SampleRate; + uint32 ByteRate; + uint16 BlockAlign; + uint16 BitsPerSample; + uint16 extra[2]; // adpcm only + + tFormatHeader() { memset(this, 0, sizeof(*this)); } + }; + + FILE *m_pFile; + bool m_bIsOpen; + + tFormatHeader m_FormatHeader; + + uint32 m_DataStartOffset; // TODO: 64 bit? + uint32 m_nSampleCount; + uint32 m_nSamplesPerBlock; + + // ADPCM things + uint8 *m_pAdpcmBuffer; + int16 **m_ppPcmBuffers; + CImaADPCMDecoder *m_pAdpcmDecoders; + + void Close() + { + if (m_pFile) { + fclose(m_pFile); + m_pFile = nil; + } + delete[] m_pAdpcmBuffer; + delete[] m_ppPcmBuffers; + delete[] m_pAdpcmDecoders; + } + + uint32 GetCurrentSample() const + { + // TODO: 64 bit? + uint32 FilePos = ftell(m_pFile); + if (FilePos <= m_DataStartOffset) + return 0; + return (FilePos - m_DataStartOffset) / m_FormatHeader.BlockAlign * m_nSamplesPerBlock; + } + +public: + CWavFile(const char* path) : m_bIsOpen(false), m_DataStartOffset(0), m_nSampleCount(0), m_nSamplesPerBlock(0), m_pAdpcmBuffer(nil), m_ppPcmBuffers(nil), m_pAdpcmDecoders(nil) + { + m_pFile = fopen(path, "rb"); + if (!m_pFile) return; + +#define CLOSE_ON_ERROR(op)\ + if (op) { \ + Close(); \ + return; \ + } + + tDataHeader DataHeader; + + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.ID != 'FFIR'); + + // TODO? validate filesizes + + int WAVE; + CLOSE_ON_ERROR(fread(&WAVE, 4, 1, m_pFile) == 0); + CLOSE_ON_ERROR(WAVE != 'EVAW') + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.ID != ' tmf'); + + CLOSE_ON_ERROR(fread(&m_FormatHeader, Min(DataHeader.Size, sizeof(tFormatHeader)), 1, m_pFile) == 0); + CLOSE_ON_ERROR(DataHeader.Size > sizeof(tFormatHeader)); + + switch (m_FormatHeader.AudioFormat) + { + case WAVEFMT_XBOX_ADPCM: + m_FormatHeader.AudioFormat = WAVEFMT_IMA_ADPCM; + case WAVEFMT_IMA_ADPCM: + m_nSamplesPerBlock = (m_FormatHeader.BlockAlign / m_FormatHeader.NumChannels - 4) * 2 + 1; + m_pAdpcmBuffer = new uint8[m_FormatHeader.BlockAlign]; + m_ppPcmBuffers = new int16*[m_FormatHeader.NumChannels]; + m_pAdpcmDecoders = new CImaADPCMDecoder[m_FormatHeader.NumChannels]; + break; + case WAVEFMT_PCM: + m_nSamplesPerBlock = 1; + if (m_FormatHeader.BitsPerSample != 16) + { + debug("Unsupported PCM (%d bits), only signed 16-bit is supported (%s)\n", m_FormatHeader.BitsPerSample, path); + Close(); + return; + } + break; + default: + debug("Unsupported wav format 0x%x (%s)\n", m_FormatHeader.AudioFormat, path); + Close(); + return; + } + + while (true) { + CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0); + if (DataHeader.ID == 'atad') + break; + fseek(m_pFile, DataHeader.Size, SEEK_CUR); + // TODO? validate data size + // maybe check if there no extreme custom headers that might break this + } + + m_DataStartOffset = ftell(m_pFile); + m_nSampleCount = DataHeader.Size / m_FormatHeader.BlockAlign * m_nSamplesPerBlock; + + m_bIsOpen = true; +#undef CLOSE_ON_ERROR + } + + ~CWavFile() + { + Close(); + } + + bool IsOpened() + { + return m_bIsOpen; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + return m_nSampleCount; + } + + uint32 GetSampleRate() + { + return m_FormatHeader.SampleRate; + } + + uint32 GetChannels() + { + return m_FormatHeader.NumChannels; + } + + void Seek(uint32 milliseconds) + { + if (!IsOpened()) return; + fseek(m_pFile, m_DataStartOffset + ms2samples(milliseconds) / m_nSamplesPerBlock * m_FormatHeader.BlockAlign, SEEK_SET); + } + + uint32 Tell() + { + if (!IsOpened()) return 0; + return samples2ms(GetCurrentSample()); + } + +#define SAMPLES_IN_LINE (8) + + uint32 Decode(void* buffer) + { + if (!IsOpened()) return 0; + + if (m_FormatHeader.AudioFormat == WAVEFMT_PCM) + { + // just read the file and sort the samples + uint32 size = fread(buffer, 1, GetBufferSize(), m_pFile); + if (m_FormatHeader.NumChannels == 2) + SortStereoBuffer.SortStereo(buffer, size); + return size; + } + else if (m_FormatHeader.AudioFormat == WAVEFMT_IMA_ADPCM) + { + // trim the buffer size if we're at the end of our file + uint32 nMaxSamples = GetBufferSamples() / m_FormatHeader.NumChannels; + uint32 nSamplesLeft = m_nSampleCount - GetCurrentSample(); + nMaxSamples = Min(nMaxSamples, nSamplesLeft); + + // align sample count to our block + nMaxSamples = nMaxSamples / m_nSamplesPerBlock * m_nSamplesPerBlock; + + // count the size of output buffer + uint32 OutBufSizePerChannel = nMaxSamples * GetSampleSize(); + uint32 OutBufSize = OutBufSizePerChannel * m_FormatHeader.NumChannels; + + // calculate the pointers to individual channel buffers + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + m_ppPcmBuffers[i] = (int16*)((int8*)buffer + OutBufSizePerChannel * i); + + uint32 samplesRead = 0; + while (samplesRead < nMaxSamples) + { + // read the file + uint8 *pAdpcmBuf = m_pAdpcmBuffer; + if (fread(m_pAdpcmBuffer, 1, m_FormatHeader.BlockAlign, m_pFile) == 0) + return 0; + + // get the first sample in adpcm block and initialise the decoder(s) + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + { + int16 Sample = *(int16*)pAdpcmBuf; + pAdpcmBuf += sizeof(int16); + int16 Step = *(int16*)pAdpcmBuf; + pAdpcmBuf += sizeof(int16); + m_pAdpcmDecoders[i].Init(Sample, Step); + *(m_ppPcmBuffers[i]) = Sample; + m_ppPcmBuffers[i]++; + } + samplesRead++; + + // decode the rest of the block + for (uint32 s = 1; s < m_nSamplesPerBlock; s += SAMPLES_IN_LINE) + { + for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++) + { + m_pAdpcmDecoders[i].Decode(pAdpcmBuf, m_ppPcmBuffers[i], SAMPLES_IN_LINE / 2); + pAdpcmBuf += SAMPLES_IN_LINE / 2; + m_ppPcmBuffers[i] += SAMPLES_IN_LINE; + } + samplesRead += SAMPLES_IN_LINE; + } + } + return OutBufSize; + } + return 0; + } +}; + +#ifdef AUDIO_OAL_USE_SNDFILE class CSndFile : public IDecoder { SNDFILE *m_pfSound; @@ -81,9 +452,20 @@ public: uint32 Decode(void *buffer) { if ( !IsOpened() ) return 0; - return sf_read_short(m_pfSound, (short *)buffer, GetBufferSamples()) * GetSampleSize(); + + size_t size = sf_read_short(m_pfSound, (short*)buffer, GetBufferSamples()) * GetSampleSize(); + if (GetChannels()==2) + SortStereoBuffer.SortStereo(buffer, size); + return size; } }; +#endif + +#ifdef _WIN32 +// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though) +#define MP3_USE_FUZZY_SEEK +#endif // _WIN32 + class CMP3File : public IDecoder { @@ -108,6 +490,9 @@ public: m_pMH = mpg123_new(nil, nil); if ( m_pMH ) { +#ifdef MP3_USE_FUZZY_SEEK + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0); +#endif long rate = 0; int channels = 0; int encoding = 0; @@ -183,9 +568,249 @@ public: assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX)); #endif if (err != MPG123_OK && err != MPG123_DONE) return 0; + if (GetChannels() == 2) + SortStereoBuffer.SortStereo(buffer, size); return (uint32)size; } }; + +#define VAG_LINE_SIZE (0x10) +#define VAG_SAMPLES_IN_LINE (28) + +class CVagDecoder +{ + const double f[5][2] = { { 0.0, 0.0 }, + { 60.0 / 64.0, 0.0 }, + { 115.0 / 64.0, -52.0 / 64.0 }, + { 98.0 / 64.0, -55.0 / 64.0 }, + { 122.0 / 64.0, -60.0 / 64.0 } }; + + double s_1; + double s_2; +public: + CVagDecoder() + { + ResetState(); + } + + void ResetState() + { + s_1 = s_2 = 0.0; + } + + static short quantize(double sample) + { + int a = int(sample + 0.5); + return short(clamp(a, -32768, 32767)); + } + + void Decode(void* _inbuf, int16* _outbuf, size_t size) + { + uint8* inbuf = (uint8*)_inbuf; + int16* outbuf = _outbuf; + size &= ~(VAG_LINE_SIZE - 1); + + while (size > 0) { + double samples[VAG_SAMPLES_IN_LINE]; + + int predict_nr, shift_factor, flags; + predict_nr = *(inbuf++); + shift_factor = predict_nr & 0xf; + predict_nr >>= 4; + flags = *(inbuf++); + if (flags == 7) // TODO: ignore? + break; + for (int i = 0; i < VAG_SAMPLES_IN_LINE; i += 2) { + int d = *(inbuf++); + int16 s = int16((d & 0xf) << 12); + samples[i] = (double)(s >> shift_factor); + s = int16((d & 0xf0) << 8); + samples[i + 1] = (double)(s >> shift_factor); + } + + for (int i = 0; i < VAG_SAMPLES_IN_LINE; i++) { + samples[i] = samples[i] + s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1]; + s_2 = s_1; + s_1 = samples[i]; + *(outbuf++) = quantize(samples[i] + 0.5); + } + size -= VAG_LINE_SIZE; + } + } +}; + +#define VB_BLOCK_SIZE (0x2000) +#define NUM_VAG_LINES_IN_BLOCK (VB_BLOCK_SIZE / VAG_LINE_SIZE) +#define NUM_VAG_SAMPLES_IN_BLOCK (NUM_VAG_LINES_IN_BLOCK * VAG_SAMPLES_IN_LINE) + +class CVbFile : public IDecoder +{ + FILE *m_pFile; + CVagDecoder *m_pVagDecoders; + + size_t m_FileSize; + size_t m_nNumberOfBlocks; + + uint32 m_nSampleRate; + uint8 m_nChannels; + bool m_bBlockRead; + uint16 m_LineInBlock; + size_t m_CurrentBlock; + + uint8 **m_ppVagBuffers; // buffers that cache actual ADPCM file data + int16 **m_ppPcmBuffers; + + void ReadBlock(int32 block = -1) + { + // just read next block if -1 + if (block != -1) + fseek(m_pFile, block * m_nChannels * VB_BLOCK_SIZE, SEEK_SET); + + for (int i = 0; i < m_nChannels; i++) + fread(m_ppVagBuffers[i], VB_BLOCK_SIZE, 1, m_pFile); + m_bBlockRead = true; + } + +public: + CVbFile(const char* path, uint32 nSampleRate = 32000, uint8 nChannels = 2) : m_nSampleRate(nSampleRate), m_nChannels(nChannels), m_pVagDecoders(nil), m_ppVagBuffers(nil), m_ppPcmBuffers(nil), + m_FileSize(0), m_nNumberOfBlocks(0), m_bBlockRead(false), m_LineInBlock(0), m_CurrentBlock(0) + { + m_pFile = fopen(path, "rb"); + if (!m_pFile) return; + + fseek(m_pFile, 0, SEEK_END); + m_FileSize = ftell(m_pFile); + fseek(m_pFile, 0, SEEK_SET); + + m_nNumberOfBlocks = m_FileSize / (nChannels * VB_BLOCK_SIZE); + m_pVagDecoders = new CVagDecoder[nChannels]; + m_ppVagBuffers = new uint8*[nChannels]; + m_ppPcmBuffers = new int16*[nChannels]; + for (uint8 i = 0; i < nChannels; i++) + m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE]; + } + + ~CVbFile() + { + if (m_pFile) + { + fclose(m_pFile); + + delete[] m_pVagDecoders; + for (int i = 0; i < m_nChannels; i++) + delete[] m_ppVagBuffers[i]; + delete[] m_ppVagBuffers; + delete[] m_ppPcmBuffers; + } + } + + bool IsOpened() + { + return m_pFile != nil; + } + + uint32 GetSampleSize() + { + return sizeof(uint16); + } + + uint32 GetSampleCount() + { + if (!IsOpened()) return 0; + return m_nNumberOfBlocks * NUM_VAG_LINES_IN_BLOCK * VAG_SAMPLES_IN_LINE; + } + + uint32 GetSampleRate() + { + return m_nSampleRate; + } + + uint32 GetChannels() + { + return m_nChannels; + } + + void Seek(uint32 milliseconds) + { + if (!IsOpened()) return; + uint32 samples = ms2samples(milliseconds); + + // find the block of our sample + uint32 block = samples / NUM_VAG_SAMPLES_IN_BLOCK; + if (block > m_nNumberOfBlocks) + { + samples = 0; + block = 0; + } + if (block != m_CurrentBlock) + m_bBlockRead = false; + + // find a line of our sample within our block + uint32 remainingSamples = samples - block * NUM_VAG_SAMPLES_IN_BLOCK; + uint32 newLine = remainingSamples / VAG_SAMPLES_IN_LINE / VAG_LINE_SIZE; + + if (m_CurrentBlock != block || m_LineInBlock != newLine) + { + m_CurrentBlock = block; + m_LineInBlock = newLine; + for (uint32 i = 0; i < GetChannels(); i++) + m_pVagDecoders[i].ResetState(); + } + + } + + uint32 Tell() + { + if (!IsOpened()) return 0; + uint32 pos = (m_CurrentBlock * NUM_VAG_LINES_IN_BLOCK + m_LineInBlock) * VAG_SAMPLES_IN_LINE; + return samples2ms(pos); + } + + uint32 Decode(void* buffer) + { + if (!IsOpened()) return 0; + + if (m_CurrentBlock >= m_nNumberOfBlocks) return 0; + + // cache current ADPCM block + if (!m_bBlockRead) + ReadBlock(m_CurrentBlock); + + // trim the buffer size if we're at the end of our file + int numberOfRequiredLines = GetBufferSamples() / m_nChannels / VAG_SAMPLES_IN_LINE; + int numberOfRemainingLines = (m_nNumberOfBlocks - m_CurrentBlock) * NUM_VAG_LINES_IN_BLOCK - m_LineInBlock; + int bufSizePerChannel = Min(numberOfRequiredLines, numberOfRemainingLines) * VAG_SAMPLES_IN_LINE * GetSampleSize(); + + // calculate the pointers to individual channel buffers + for (uint32 i = 0; i < m_nChannels; i++) + m_ppPcmBuffers[i] = (int16*)((int8*)buffer + bufSizePerChannel * i); + + int size = 0; + while (size < bufSizePerChannel) + { + // decode the VAG lines + for (uint32 i = 0; i < m_nChannels; i++) + { + m_pVagDecoders[i].Decode(m_ppVagBuffers[i] + m_LineInBlock * VAG_LINE_SIZE, m_ppPcmBuffers[i], VAG_LINE_SIZE); + m_ppPcmBuffers[i] += VAG_SAMPLES_IN_LINE; + } + size += VAG_SAMPLES_IN_LINE * GetSampleSize(); + m_LineInBlock++; + + // block is over, read the next block + if (m_LineInBlock >= NUM_VAG_LINES_IN_BLOCK) + { + m_CurrentBlock++; + if (m_CurrentBlock >= m_nNumberOfBlocks) // end of file + break; + m_LineInBlock = 0; + ReadBlock(); + } + } + + return bufSizePerChannel * m_nChannels; + } +}; #else class COpusFile : public IDecoder { @@ -274,6 +899,9 @@ public: if (size < 0) return 0; + if (GetChannels() == 2) + SortStereoBuffer.SortStereo(buffer, size * m_nChannels * GetSampleSize()); + return size * m_nChannels * GetSampleSize(); } }; @@ -285,7 +913,7 @@ class CADFFile : public CMP3File { size_t bytesRead = fread(buf, 1, size, (FILE*)fh); uint8* _buf = (uint8*)buf; - for (int i = 0; i < size; i++) + for (size_t i = 0; i < size; i++) _buf[i] ^= 0x22; return bytesRead; } @@ -304,6 +932,9 @@ public: m_pMH = mpg123_new(nil, nil); if (m_pMH) { +#ifdef MP3_USE_FUZZY_SEEK + mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0); +#endif long rate = 0; int channels = 0; int encoding = 0; @@ -338,8 +969,8 @@ void CStream::Terminate() #endif } -CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) : - m_alSource(source), +CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate) : + m_pAlSources(sources), m_alBuffers(buffers), m_pBuffer(nil), m_bPaused(false), @@ -370,9 +1001,15 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) m_pSoundFile = new CMP3File(m_aFilename); else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) +#ifdef AUDIO_OAL_USE_SNDFILE m_pSoundFile = new CSndFile(m_aFilename); +#else + m_pSoundFile = new CWavFile(m_aFilename); +#endif else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf")) m_pSoundFile = new CADFFile(m_aFilename); + else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB")) + m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate); #else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) m_pSoundFile = new COpusFile(m_aFilename); @@ -422,7 +1059,7 @@ void CStream::Delete() bool CStream::HasSource() { - return m_alSource != AL_NONE; + return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE); } bool CStream::IsOpened() @@ -436,9 +1073,10 @@ bool CStream::IsPlaying() if ( !m_bPaused ) { - ALint sourceState; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - if ( m_bActive || sourceState == AL_PLAYING ) + ALint sourceState[2]; + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); + if ( m_bActive || sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING) return true; } @@ -449,9 +1087,12 @@ void CStream::Pause() { if ( !HasSource() ) return; ALint sourceState = AL_PAUSED; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - if (sourceState != AL_PAUSED ) - alSourcePause(m_alSource); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED) + alSourcePause(m_pAlSources[0]); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PAUSED) + alSourcePause(m_pAlSources[1]); } void CStream::SetPause(bool bPause) @@ -473,19 +1114,21 @@ void CStream::SetPause(bool bPause) void CStream::SetPitch(float pitch) { if ( !HasSource() ) return; - alSourcef(m_alSource, AL_PITCH, pitch); + alSourcef(m_pAlSources[0], AL_PITCH, pitch); + alSourcef(m_pAlSources[1], AL_PITCH, pitch); } void CStream::SetGain(float gain) { if ( !HasSource() ) return; - alSourcef(m_alSource, AL_GAIN, gain); + alSourcef(m_pAlSources[0], AL_GAIN, gain); + alSourcef(m_pAlSources[1], AL_GAIN, gain); } -void CStream::SetPosition(float x, float y, float z) +void CStream::SetPosition(int i, float x, float y, float z) { if ( !HasSource() ) return; - alSource3f(m_alSource, AL_POSITION, x, y, z); + alSource3f(m_pAlSources[i], AL_POSITION, x, y, z); } void CStream::SetVolume(uint32 nVol) @@ -496,8 +1139,13 @@ void CStream::SetVolume(uint32 nVol) void CStream::SetPan(uint8 nPan) { + m_nPan = clamp((int8)nPan - 63, 0, 63); + SetPosition(0, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f))); + + m_nPan = clamp((int8)nPan + 64, 64, 127); + SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f))); + m_nPan = nPan; - SetPosition((nPan - 63)/64.0f, 0.0f, Sqrt(1.0f-SQR((nPan-63)/64.0f))); } void CStream::SetPosMS(uint32 nPos) @@ -514,10 +1162,10 @@ uint32 CStream::GetPosMS() ALint offset; //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset); - alGetSourcei(m_alSource, AL_BYTE_OFFSET, &offset); + alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset); return m_pSoundFile->Tell() - - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS-1)) / m_pSoundFile->GetChannels() + - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels() + m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels(); } @@ -527,33 +1175,41 @@ uint32 CStream::GetLengthMS() return m_pSoundFile->GetLength(); } -bool CStream::FillBuffer(ALuint alBuffer) +bool CStream::FillBuffer(ALuint *alBuffer) { if ( !HasSource() ) return false; if ( !IsOpened() ) return false; - if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) ) + if ( !(alBuffer[0] != AL_NONE && alIsBuffer(alBuffer[0])) ) + return false; + if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) ) return false; uint32 size = m_pSoundFile->Decode(m_pBuffer); if( size == 0 ) return false; - alBufferData(alBuffer, m_pSoundFile->GetChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, - m_pBuffer, size, m_pSoundFile->GetSampleRate()); - + uint32 channelSize = size / m_pSoundFile->GetChannels(); + + alBufferData(alBuffer[0], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate()); + // TODO: use just one buffer if we play mono + if (m_pSoundFile->GetChannels() == 1) + alBufferData(alBuffer[1], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate()); + else + alBufferData(alBuffer[1], AL_FORMAT_MONO16, (uint8*)m_pBuffer + channelSize, channelSize, m_pSoundFile->GetSampleRate()); return true; } int32 CStream::FillBuffers() { int32 i = 0; - for ( i = 0; i < NUM_STREAMBUFFERS; i++ ) + for ( i = 0; i < NUM_STREAMBUFFERS/2; i++ ) { - if ( !FillBuffer(m_alBuffers[i]) ) + if ( !FillBuffer(&m_alBuffers[i*2]) ) break; - alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]); + alSourceQueueBuffers(m_pAlSources[0], 1, &m_alBuffers[i*2]); + alSourceQueueBuffers(m_pAlSources[1], 1, &m_alBuffers[i*2+1]); } return i; @@ -563,12 +1219,15 @@ void CStream::ClearBuffers() { if ( !HasSource() ) return; - ALint buffersQueued; - alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued); + ALint buffersQueued[2]; + alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &buffersQueued[0]); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &buffersQueued[1]); ALuint value; - while (buffersQueued--) - alSourceUnqueueBuffers(m_alSource, 1, &value); + while (buffersQueued[0]--) + alSourceUnqueueBuffers(m_pAlSources[0], 1, &value); + while (buffersQueued[1]--) + alSourceUnqueueBuffers(m_pAlSources[1], 1, &value); } bool CStream::Setup() @@ -576,7 +1235,6 @@ bool CStream::Setup() if ( IsOpened() ) { m_pSoundFile->Seek(0); - alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE); //SetPosition(0.0f, 0.0f, 0.0f); SetPitch(1.0f); //SetPan(m_nPan); @@ -592,17 +1250,29 @@ void CStream::SetPlay(bool state) if ( state ) { ALint sourceState = AL_PLAYING; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); if (sourceState != AL_PLAYING ) - alSourcePlay(m_alSource); + alSourcePlay(m_pAlSources[0]); + + sourceState = AL_PLAYING; + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_PLAYING) + alSourcePlay(m_pAlSources[1]); + m_bActive = true; } else { ALint sourceState = AL_STOPPED; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState); if (sourceState != AL_STOPPED ) - alSourceStop(m_alSource); + alSourceStop(m_pAlSources[0]); + + sourceState = AL_STOPPED; + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState); + if (sourceState != AL_STOPPED) + alSourceStop(m_pAlSources[1]); + m_bActive = false; } } @@ -633,35 +1303,51 @@ void CStream::Update() if ( !m_bPaused ) { - ALint sourceState; - ALint buffersProcessed = 0; + ALint sourceState[2]; + ALint buffersProcessed[2] = { 0, 0 }; - alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState); - alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); + // Relying a lot on left buffer states in here + + do + { + //alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f); + alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]); + alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]); + //alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f); + alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); + alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]); + } while (buffersProcessed[0] != buffersProcessed[1]); ALint looping = AL_FALSE; - alGetSourcei(m_alSource, AL_LOOPING, &looping); + alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping); if ( looping == AL_TRUE ) { TRACE("stream set looping"); - alSourcei(m_alSource, AL_LOOPING, AL_TRUE); + alSourcei(m_pAlSources[0], AL_LOOPING, AL_TRUE); + alSourcei(m_pAlSources[1], AL_LOOPING, AL_TRUE); } - while( buffersProcessed-- ) + assert(buffersProcessed[0] == buffersProcessed[1]); + + while( buffersProcessed[0]-- ) { - ALuint buffer; + ALuint buffer[2]; - alSourceUnqueueBuffers(m_alSource, 1, &buffer); + alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]); + alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]); - if ( m_bActive && FillBuffer(buffer) ) - alSourceQueueBuffers(m_alSource, 1, &buffer); + if (m_bActive && FillBuffer(buffer)) + { + alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]); + alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]); + } } - if ( sourceState != AL_PLAYING ) + if ( sourceState[0] != AL_PLAYING ) { - alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); - SetPlay(buffersProcessed!=0); + alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]); + SetPlay(buffersProcessed[0]!=0); } } } diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h index 2476abcc..bcbc5e54 100644 --- a/src/audio/oal/stream.h +++ b/src/audio/oal/stream.h @@ -3,7 +3,7 @@ #ifdef AUDIO_OAL #include <AL/al.h> -#define NUM_STREAMBUFFERS 4 +#define NUM_STREAMBUFFERS 8 class IDecoder { @@ -57,7 +57,7 @@ public: class CStream { char m_aFilename[128]; - ALuint &m_alSource; + ALuint *m_pAlSources; ALuint (&m_alBuffers)[NUM_STREAMBUFFERS]; bool m_bPaused; @@ -73,20 +73,20 @@ class CStream IDecoder *m_pSoundFile; bool HasSource(); - void SetPosition(float x, float y, float z); + void SetPosition(int i, float x, float y, float z); void SetPitch(float pitch); void SetGain(float gain); void Pause(); void SetPlay(bool state); - bool FillBuffer(ALuint alBuffer); + bool FillBuffer(ALuint *alBuffer); int32 FillBuffers(); void ClearBuffers(); public: static void Initialise(); static void Terminate(); - CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]); + CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS], uint32 overrideSampleRate = 32000); ~CStream(); void Delete(); diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp index 80f19e50..0d82d552 100644 --- a/src/audio/sampman_oal.cpp +++ b/src/audio/sampman_oal.cpp @@ -102,7 +102,7 @@ CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS]; uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS]; uint32 nStreamLength[TOTAL_STREAMED_SOUNDS]; -ALuint ALStreamSources[MAX_STREAMS]; +ALuint ALStreamSources[MAX_STREAMS][2]; ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS]; struct tMP3Entry @@ -245,9 +245,9 @@ release_existing() if (stream) stream->ProviderTerm(); - alDeleteSources(1, &ALStreamSources[i]); alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); } + alDeleteSources(MAX_STREAMS*2, ALStreamSources[0]); CChannel::DestroyChannels(); @@ -287,7 +287,10 @@ set_new_provider(int index) //TODO: _maxSamples = MAXCHANNELS; - ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0}; + ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ, + ALC_MONO_SOURCES, MAX_STREAMS * 2 + MAXCHANNELS, + 0, + }; ALDevice = alcOpenDevice(providers[index].id); ASSERT(ALDevice != NULL); @@ -319,11 +322,17 @@ set_new_provider(int index) alGenAuxiliaryEffectSlots(1, &ALEffectSlot); alGenEffects(1, &ALEffect); } - + + alGenSources(MAX_STREAMS*2, ALStreamSources[0]); for ( int32 i = 0; i < MAX_STREAMS; i++ ) { - alGenSources(1, &ALStreamSources[i]); alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]); + alSourcei(ALStreamSources[i][0], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ALStreamSources[i][0], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(ALStreamSources[i][0], AL_GAIN, 1.0f); + alSourcei(ALStreamSources[i][1], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(ALStreamSources[i][1], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSourcef(ALStreamSources[i][1], AL_GAIN, 1.0f); CStream *stream = aStream[i]; if (stream) @@ -384,6 +393,12 @@ set_new_provider(int index) return false; } +static bool +IsThisTrackAt16KHz(uint32 track) +{ + return track == STREAMED_SOUND_RADIO_KCHAT || track == STREAMED_SOUND_RADIO_VCPR || track == STREAMED_SOUND_RADIO_POLICE; +} + cSampleManager::cSampleManager(void) { ; @@ -989,7 +1004,7 @@ cSampleManager::Initialise(void) for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ ) { - aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]); + aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0], IsThisTrackAt16KHz(i) ? 16000 : 32000); if ( aStream[0] && aStream[0]->IsOpened() ) { @@ -1542,10 +1557,11 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume) nChannelVolume[nChannel] = vol; - if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE - && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE ) - { - nChannelVolume[nChannel] = vol / 4; + if (MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE ) { + if (MusicManager.GetCurrentTrack() == STREAMED_SOUND_CUTSCENE_FINALE) + nChannelVolume[nChannel] = 0; + else + nChannelVolume[nChannel] >>= 2; } // no idea, does this one looks like a bug or it's SetChannelVolume ? @@ -1671,7 +1687,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream) strcpy(filename, StreamedNameTable[nFile]); - CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1746,7 +1762,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) nFile = 0; strcat(filename, StreamedNameTable[nFile]); - CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1770,12 +1786,12 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) } if (mp3->pLinkPath != NULL) - aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); else { strcpy(filename, _mp3DirectoryPath); strcat(filename, mp3->aFilename); - aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); } if (aStream[nStream]->IsOpened()) { @@ -1802,7 +1818,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) { nFile = 0; strcat(filename, StreamedNameTable[nFile]); - CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; @@ -1826,7 +1842,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) } if (e->pLinkPath != NULL) - aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]); + aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); else { strcpy(filename, _mp3DirectoryPath); strcat(filename, e->aFilename); @@ -1859,7 +1875,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream) strcpy(filename, StreamedNameTable[nFile]); - CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]); + CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000); ASSERT(stream != NULL); aStream[nStream] = stream; diff --git a/src/collision/ColStore.cpp b/src/collision/ColStore.cpp index 192c373d..f1e695fe 100644 --- a/src/collision/ColStore.cpp +++ b/src/collision/ColStore.cpp @@ -11,8 +11,13 @@ #include "Frontend.h" #include "Physical.h" #include "ColStore.h" +#include "VarConsole.h" +#include "Pools.h" CPool<ColDef,ColDef> *CColStore::ms_pColPool; +#ifndef MASTER +bool bDispColInMem; +#endif void CColStore::Initialise(void) @@ -20,6 +25,9 @@ CColStore::Initialise(void) if(ms_pColPool == nil) ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles"); AddColSlot("generic"); // slot 0. not streamed +#ifndef MASTER + VarConsole.Add("Display collision in memory", &bDispColInMem, true); +#endif } void @@ -177,7 +185,18 @@ CColStore::LoadCollision(const CVector2D &pos) wantThisOne = true; }else{ for (int j = 0; j < MAX_CLEANUP; j++) { - CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j); + CPhysical* pEntity = nil; + cleanup_entity_struct* pCleanup = &CTheScripts::MissionCleanUp.m_sEntities[i]; + if (pCleanup->type == CLEANUP_CAR) { + pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id); + if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED) + continue; + } + else if (pCleanup->type == CLEANUP_CHAR) { + pEntity = CPools::GetPedPool()->GetAt(pCleanup->id); + if (!pEntity || ((CPed*)pEntity)->DyingOrDead()) + continue; + } if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) { if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f)) wantThisOne = true; diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 779041cc..72053f8d 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -23,6 +23,7 @@ #include "Vehicle.h" #include "Wanted.h" #include "World.h" +#include "VarConsole.h" //--MIAMI: file done @@ -129,8 +130,15 @@ int32 hGarages = AEHANDLE_NONE; CGarage CGarages::aGarages[NUM_GARAGES]; bool CGarages::bCamShouldBeOutisde; +#ifndef MASTER +bool bPrintNearestObject; +#endif + void CGarages::Init(void) { +#ifndef MASTER + VarConsole.Add("Print nearest object", &bPrintNearestObject, true); +#endif CrushedCarId = -1; NumGarages = 0; MessageEndTime = 0; diff --git a/src/control/Garages.h b/src/control/Garages.h index 46ae1542..3d12d4a2 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -93,6 +93,7 @@ VALIDATE_SIZE(CStoredCar, 0x28); class CGarage { +public: uint8 m_eGarageType; uint8 m_eGarageState; uint8 m_nMaxStoredCars; @@ -189,9 +190,6 @@ class CGarage int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); } - friend class CGarages; - friend class cAudioManager; - friend class CCamera; }; class CGarages @@ -199,6 +197,7 @@ class CGarages enum { MESSAGE_LENGTH = 8, }; +public: static int32 BankVansCollected; static bool BombsAreFree; static bool RespraysAreFree; @@ -218,7 +217,6 @@ class CGarages static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS]; static bool bCamShouldBeOutisde; -public: static void Init(void); #ifndef PS2 static void Shutdown(void); @@ -259,7 +257,6 @@ public: static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; } static void SetMaxNumStoredCarsForGarage(int16 garage, uint8 num) { aGarages[garage].m_nMaxStoredCars = num; } -private: static bool IsCarSprayable(CVehicle*); static float FindDoorHeightForMI(int32); static void CloseHideOutGaragesBeforeSave(void); @@ -296,7 +293,4 @@ private: } static bool IsThisGarageTypeSafehouse(uint8 type) { return FindSafeHouseIndexForGarageType(type) >= 0; } - friend class cAudioManager; - friend class CReplay; - friend class CGarage; }; diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 1c68cad9..37a54999 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1508,12 +1508,12 @@ void CReplay::RestoreStuffFromMem(void) tmp1.UpdateRW(); } else if (mi == MI_HUNTER) { - RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LF]), 0); - RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RB]), 0); } else if (vehicle->IsRealHeli()) { + RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LF]), 0); + RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(car->m_aCarNodes[CAR_WHEEL_RB]), 0); } diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 4e34c4b2..a453c077 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -85,7 +85,7 @@ uint16 CTheScripts::NumScriptDebugLines; uint16 CTheScripts::NumberOfIntroRectanglesThisFrame; uint16 CTheScripts::NumberOfIntroTextLinesThisFrame; uint8 CTheScripts::UseTextCommands; -CMissionCleanup CTheScripts::MissionCleanup; +CMissionCleanup CTheScripts::MissionCleanUp; CUpsideDownCarCheck CTheScripts::UpsideDownCars; CStuckCarCheck CTheScripts::StuckCars; uint16 CTheScripts::CommandsExecuted; @@ -1751,19 +1751,6 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type) m_nCount++; } -// done(LCS) -static void PossiblyWakeThisEntity(CPhysical* pEntity, bool ifColLoaded = false) -{ - if (!pEntity->bIsStaticWaitingForCollision) - return; - if (!ifColLoaded || CColStore::HasCollisionLoaded(pEntity->GetPosition())) { - pEntity->bIsStaticWaitingForCollision = false; - if (!pEntity->GetIsStatic()) - pEntity->AddToMovingList(); - } -} - -// done(LCS) void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) { for (int i = 0; i < MAX_CLEANUP; i++){ @@ -1771,23 +1758,38 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) switch (m_sEntities[i].type) { case CLEANUP_CAR: { - CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); - if (v) - PossiblyWakeThisEntity(v); + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); + if (pVehicle) { + if (pVehicle->bIsStaticWaitingForCollision) { + pVehicle->bIsStaticWaitingForCollision = false; + if (!pVehicle->GetIsStatic()) + pVehicle->AddToMovingList(); + } + } break; } case CLEANUP_CHAR: { - CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id); - if (p) - PossiblyWakeThisEntity(p); + CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); + if (pPed) { + if (pPed->bIsStaticWaitingForCollision) { + pPed->bIsStaticWaitingForCollision = false; + if (!pPed->GetIsStatic()) + pPed->AddToMovingList(); + } + } break; } case CLEANUP_OBJECT: { - CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); - if (o) - PossiblyWakeThisEntity(o); + CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); + if (pObject) { + if (pObject->bIsStaticWaitingForCollision) { + pObject->bIsStaticWaitingForCollision = false; + if (!pObject->GetIsStatic()) + pObject->AddToMovingList(); + } + } break; } default: @@ -1895,23 +1897,6 @@ void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects() } } -// TODO(LCS) -CPhysical* CMissionCleanup::DoesThisEntityWaitForCollision(int i) -{ - if (m_sEntities[i].type == CLEANUP_CAR) { - CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); - if (pVehicle && pVehicle->GetStatus() != STATUS_WRECKED) - return pVehicle; - } - else if (m_sEntities[i].type == CLEANUP_CHAR) { - CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id); - if (pPed && !pPed->DyingOrDead()) - return pPed; - } - return nil; -} - -// done(LCS) except TODO void CMissionCleanup::Process() { CPopulation::m_AllRandomPedsThisType = -1; @@ -2012,13 +1997,18 @@ void CUpsideDownCarCheck::Init() // done(LCS) bool CUpsideDownCarCheck::IsCarUpsideDown(int32 id) { - CVehicle* v = CPools::GetVehiclePool()->GetAt(id); - return v->GetUp().z <= -0.97f && - v->GetMoveSpeed().Magnitude() < 0.01f && - v->GetTurnSpeed().Magnitude() < 0.02f; + CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(id); + return IsCarUpsideDown(pVehicle); +} + +bool CUpsideDownCarCheck::IsCarUpsideDown(CVehicle* pVehicle) +{ + assert(pVehicle); + return pVehicle->GetUp().z <= UPSIDEDOWN_UP_THRESHOLD && + pVehicle->GetMoveSpeed().Magnitude() < UPSIDEDOWN_MOVE_SPEED_THRESHOLD && + pVehicle->GetTurnSpeed().Magnitude() < UPSIDEDOWN_TURN_SPEED_THRESHOLD; } -// done(LCS) void CUpsideDownCarCheck::UpdateTimers() { uint32 timeStep = CTimer::GetTimeStepInMilliseconds(); @@ -2040,7 +2030,7 @@ void CUpsideDownCarCheck::UpdateTimers() bool CUpsideDownCarCheck::AreAnyCarsUpsideDown() { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ - if (m_sCars[i].m_nVehicleIndex >= 0 && m_sCars[i].m_nUpsideDownTimer > 1000) + if (m_sCars[i].m_nVehicleIndex >= 0 && m_sCars[i].m_nUpsideDownTimer > UPSIDEDOWN_TIMER_THRESHOLD) return true; } return false; @@ -2052,8 +2042,10 @@ void CUpsideDownCarCheck::AddCarToCheck(int32 id) uint16 index = 0; while (index < MAX_UPSIDEDOWN_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0) index++; +#ifdef FIX_BUGS if (index >= MAX_UPSIDEDOWN_CAR_CHECKS) return; +#endif m_sCars[index].m_nVehicleIndex = id; m_sCars[index].m_nUpsideDownTimer = 0; } @@ -2074,7 +2066,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id) { for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ if (m_sCars[i].m_nVehicleIndex == id) - return m_sCars[i].m_nUpsideDownTimer > 1000; + return m_sCars[i].m_nUpsideDownTimer > UPSIDEDOWN_TIMER_THRESHOLD; } return false; } @@ -2124,7 +2116,10 @@ void CStuckCarCheck::AddCarToCheck(int32 id, float radius, uint32 time) int index = 0; while (index < MAX_STUCK_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0) index++; - /* Would be nice to return if index >= MAX_STUCK_CAR_CHECKS... */ +#ifdef FIX_BUGS + if (index >= MAX_STUCK_CAR_CHECKS) + return; +#endif m_sCars[index].m_nVehicleIndex = id; m_sCars[index].m_vecPos = pv->GetPosition(); m_sCars[index].m_nLastCheck = CTimer::GetTimeInMilliseconds(); @@ -2356,7 +2351,7 @@ void CTheScripts::Init() ScriptsArray[i].Init(); ScriptsArray[i].AddScriptToList(&pIdleScripts); } - MissionCleanup.Init(); + MissionCleanUp.Init(); UpsideDownCars.Init(); StuckCars.Init(); CFileMgr::SetDir("data"); @@ -2484,7 +2479,7 @@ void CTheScripts::Process() float timeStep = CTimer::GetTimeStepInMilliseconds(); UpsideDownCars.UpdateTimers(); StuckCars.Process(); - MissionCleanup.CheckIfCollisionHasLoadedForMissionObjects(); + MissionCleanUp.CheckIfCollisionHasLoadedForMissionObjects(); DrawScriptSpheres(); if (FailCurrentMission) --FailCurrentMission; @@ -3808,7 +3803,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_DELETE_CHAR: @@ -3817,7 +3812,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); CTheScripts::RemoveThisPed(ped); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_CHAR_WANDER_DIR: @@ -4038,7 +4033,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) ScriptParams[0] = handle; StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR); return 0; } case COMMAND_DELETE_CAR: @@ -4051,7 +4046,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) delete car; } if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_CAR_GOTO_COORDINATES: @@ -4171,9 +4166,9 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) car->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1]; if (missionRetryScriptIndex == 40 && car->GetModelIndex() == MI_CHEETAH) // Turismo car->AutoPilot.m_nCruiseSpeed = 8 * car->AutoPilot.m_nCruiseSpeed / 10; - car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); + car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fMaxCruiseVelocity); #else - car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); + car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fMaxCruiseVelocity); #endif return 0; } @@ -4366,7 +4361,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) { if (!m_bIsMissionScript) return 0; - CTheScripts::MissionCleanup.Process(); + CTheScripts::MissionCleanUp.Process(); return 0; } case COMMAND_STORE_CAR_CHAR_IS_IN: @@ -4389,7 +4384,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pOld->bIsLocked = false; CCarCtrl::NumRandomCars++; CCarCtrl::NumMissionCars--; - CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); } } @@ -4400,14 +4395,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) CCarCtrl::NumMissionCars++; CCarCtrl::NumRandomCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case PARKED_VEHICLE: pCurrent->VehicleCreatedBy = MISSION_VEHICLE; CCarCtrl::NumMissionCars++; CCarCtrl::NumParkedCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case MISSION_VEHICLE: case PERMANENT_VEHICLE: @@ -4440,7 +4435,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) pOld->bIsLocked = false; CCarCtrl::NumRandomCars++; CCarCtrl::NumMissionCars--; - CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); } } @@ -4451,14 +4446,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) CCarCtrl::NumMissionCars++; CCarCtrl::NumRandomCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case PARKED_VEHICLE: pCurrent->VehicleCreatedBy = MISSION_VEHICLE; CCarCtrl::NumMissionCars++; CCarCtrl::NumParkedCars--; CTheScripts::StoreVehicleWasRandom = true; - CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); break; case MISSION_VEHICLE: case PERMANENT_VEHICLE: @@ -4607,7 +4602,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_DELETE_OBJECT: @@ -4620,7 +4615,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) delete pObj; } if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_ADD_SCORE: @@ -4836,7 +4831,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD: @@ -4886,81 +4881,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command) return -1; } - -void CRunningScript::Save(uint8*& buf) -{ -#ifdef COMPATIBLE_SAVES - SkipSaveBuf(buf, 8); - for (int i = 0; i < 8; i++) - WriteSaveBuf<char>(buf, m_abScriptName[i]); - WriteSaveBuf<uint32>(buf, m_nIp); -#ifdef CHECK_STRUCT_SIZES - static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); -#endif - for (int i = 0; i < MAX_STACK_DEPTH; i++) - WriteSaveBuf<uint32>(buf, m_anStack[i]); - WriteSaveBuf<uint16>(buf, m_nStackPointer); - SkipSaveBuf(buf, 2); -#ifdef CHECK_STRUCT_SIZES - static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); -#endif - for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) - WriteSaveBuf<int32>(buf, m_anLocalVariables[i]); - WriteSaveBuf<bool>(buf, m_bIsActive); - WriteSaveBuf<bool>(buf, m_bCondResult); - WriteSaveBuf<bool>(buf, m_bIsMissionScript); - WriteSaveBuf<bool>(buf, m_bSkipWakeTime); - WriteSaveBuf<uint32>(buf, m_nWakeTime); - WriteSaveBuf<uint16>(buf, m_nAndOrState); - WriteSaveBuf<bool>(buf, m_bNotFlag); - WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled); - WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted); - WriteSaveBuf<bool>(buf, m_bMissionFlag); - SkipSaveBuf(buf, 2); -#else - WriteSaveBuf(buf, *this); -#endif -} - -void CRunningScript::Load(uint8*& buf) -{ -#ifdef COMPATIBLE_SAVES - SkipSaveBuf(buf, 8); - for (int i = 0; i < 8; i++) - m_abScriptName[i] = ReadSaveBuf<char>(buf); - m_nIp = ReadSaveBuf<uint32>(buf); -#ifdef CHECK_STRUCT_SIZES - static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); -#endif - for (int i = 0; i < MAX_STACK_DEPTH; i++) - m_anStack[i] = ReadSaveBuf<uint32>(buf); - m_nStackPointer = ReadSaveBuf<uint16>(buf); - SkipSaveBuf(buf, 2); -#ifdef CHECK_STRUCT_SIZES - static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); -#endif - for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) - m_anLocalVariables[i] = ReadSaveBuf<int32>(buf); - m_bIsActive = ReadSaveBuf<bool>(buf); - m_bCondResult = ReadSaveBuf<bool>(buf); - m_bIsMissionScript = ReadSaveBuf<bool>(buf); - m_bSkipWakeTime = ReadSaveBuf<bool>(buf); - m_nWakeTime = ReadSaveBuf<uint32>(buf); - m_nAndOrState = ReadSaveBuf<uint16>(buf); - m_bNotFlag = ReadSaveBuf<bool>(buf); - m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf); - m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf); - m_bMissionFlag = ReadSaveBuf<bool>(buf); - SkipSaveBuf(buf, 2); -#else - CRunningScript* n = next; - CRunningScript* p = prev; - *this = ReadSaveBuf<CRunningScript>(buf); - next = n; - prev = p; -#endif -} - #ifdef MISSION_REPLAY bool CRunningScript::CanAllowMissionReplay() @@ -4995,7 +4915,7 @@ void RetryMission(int type, int unk) else if (type == 2) { doingMissionRetry = false; AllowMissionReplay = 6; - CTheScripts::MissionCleanup.Process(); + CTheScripts::MissionCleanUp.Process(); } } diff --git a/src/control/Script.h b/src/control/Script.h index 2690b4ff..f35d0261 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -1,5 +1,6 @@ #pragma once #include "common.h" +#include "Font.h" #include "Ped.h" #include "PedType.h" #include "Text.h" @@ -20,26 +21,31 @@ extern int32 ScriptParams[32]; void FlushLog(); #define script_assert(_Expression) FlushLog(); assert(_Expression); -#define PICKUP_PLACEMENT_OFFSET 0.5f -#define PED_FIND_Z_OFFSET 5.0f -#define COP_PED_FIND_Z_OFFSET 10.0f +#define PICKUP_PLACEMENT_OFFSET (0.5f) +#define PED_FIND_Z_OFFSET (5.0f) +#define COP_PED_FIND_Z_OFFSET (10.0f) -#define SPHERE_MARKER_R 252 -#define SPHERE_MARKER_G 138 -#define SPHERE_MARKER_B 242 -#define SPHERE_MARKER_A 228 +#define UPSIDEDOWN_UP_THRESHOLD (-0.97f) +#define UPSIDEDOWN_MOVE_SPEED_THRESHOLD (0.01f) +#define UPSIDEDOWN_TURN_SPEED_THRESHOLD (0.02f) +#define UPSIDEDOWN_TIMER_THRESHOLD (1000) + +#define SPHERE_MARKER_R (252) +#define SPHERE_MARKER_G (138) +#define SPHERE_MARKER_B (242) +#define SPHERE_MARKER_A (228) #define SPHERE_MARKER_PULSE_PERIOD 2048 #define SPHERE_MARKER_PULSE_FRACTION 0.1f #ifdef USE_PRECISE_MEASUREMENT_CONVERTION -#define METERS_IN_FOOT 0.3048f -#define FEET_IN_METER 3.28084f +#define METERS_IN_FOOT (0.3048f) +#define FEET_IN_METER (3.28084f) #else -#define METERS_IN_FOOT 0.3f -#define FEET_IN_METER 3.33f +#define METERS_IN_FOOT (0.3f) +#define FEET_IN_METER (3.33f) #endif -#define KEY_LENGTH_IN_SCRIPT 8 +#define KEY_LENGTH_IN_SCRIPT (8) //#define GTA_SCRIPT_COLLECTIVE @@ -94,12 +100,12 @@ struct intro_text_line m_bCentered = false; m_bBackground = false; m_bBackgroundOnly = false; - m_fWrapX = 182.0f; /* TODO: scaling as bugfix */ - m_fCenterSize = 640.0f; /* --||-- */ + m_fWrapX = 182.0f; + m_fCenterSize = DEFAULT_SCREEN_WIDTH; m_sBackgroundColor = CRGBA(128, 128, 128, 128); m_bTextProportional = true; m_bTextBeforeFade = false; - m_nFont = 2; /* enum? */ + m_nFont = FONT_STANDARD; m_fAtX = 0.0f; m_fAtY = 0.0f; memset(&m_Text, 0, sizeof(m_Text)); @@ -148,10 +154,10 @@ enum { class CMissionCleanup { +public: cleanup_entity_struct m_sEntities[MAX_CLEANUP]; uint8 m_nCount; -public: CMissionCleanup(); void Init(); @@ -160,10 +166,9 @@ public: void RemoveEntityFromList(int32, uint8); void Process(); void CheckIfCollisionHasLoadedForMissionObjects(); - CPhysical* DoesThisEntityWaitForCollision(int i); }; -struct CUpsideDownCarCheckEntry +struct upsidedown_car_data { int32 m_nVehicleIndex; uint32 m_nUpsideDownTimer; @@ -171,11 +176,12 @@ struct CUpsideDownCarCheckEntry class CUpsideDownCarCheck { - CUpsideDownCarCheckEntry m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS]; + upsidedown_car_data m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS]; public: void Init(); bool IsCarUpsideDown(int32); + bool IsCarUpsideDown(CVehicle*); void UpdateTimers(); bool AreAnyCarsUpsideDown(); void AddCarToCheck(int32); @@ -193,7 +199,7 @@ struct stuck_car_data bool m_bStuck; stuck_car_data() { } - inline void Reset(); + void Reset(); }; class CStuckCarCheck @@ -259,7 +265,7 @@ enum { enum { MAX_NUM_SCRIPTS = 128, - MAX_NUM_INTRO_TEXT_LINES = 2, + MAX_NUM_INTRO_TEXT_LINES = 48, MAX_NUM_INTRO_RECTANGLES = 16, MAX_NUM_SCRIPT_SRPITES = 16, MAX_NUM_SCRIPT_SPHERES = 16, @@ -273,6 +279,7 @@ enum { class CTheScripts { +public: static uint8 ScriptSpace[SIZE_SCRIPT_SPACE]; static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS]; static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; @@ -286,7 +293,7 @@ class CTheScripts static CStoredLine aStoredLines[MAX_NUM_STORED_LINES]; static bool DbgFlag; static uint32 OnAMissionFlag; - static CMissionCleanup MissionCleanup; + static CMissionCleanup MissionCleanUp; static CStuckCarCheck StuckCars; static CUpsideDownCarCheck UpsideDownCars; static int32 StoreVehicleIndex; @@ -321,11 +328,10 @@ class CTheScripts static int AllowedCollision[MAX_ALLOWED_COLLISIONS]; #endif -public: static bool bPlayerIsInTheStatium; static uint8 RiotIntensity; static bool bPlayerHasMetDebbieHarry; -public: + static void Init(); static void Process(); @@ -379,8 +385,6 @@ public: return Read4BytesFromScript(&tmp); } -private: - static CRunningScript* StartNewScript(uint32); static void CleanUpThisVehicle(CVehicle*); @@ -438,18 +442,11 @@ public: static void SetObjectiveForAllPedsInCollective(int, eObjective); #endif - friend class CRunningScript; - friend class CHud; - friend void CMissionCleanup::Process(); - friend class CColStore; -#ifdef FIX_BUGS - friend void RetryMission(int, int); -#endif }; enum { - MAX_STACK_DEPTH = 6, // 4 PS2 + MAX_STACK_DEPTH = 6, NUM_LOCAL_VARS = 16, NUM_TIMERS = 2 }; @@ -476,6 +473,7 @@ class CRunningScript ORS_8 }; +public: CRunningScript* next; CRunningScript* prev; char m_abScriptName[8]; @@ -514,7 +512,6 @@ public: static const uint32 nSaveStructSize; -private: void CollectParameters(uint32*, int16); int32 CollectNextParameterWithoutIncreasingPC(uint32); int32* GetPointerToScriptVariable(uint32*, int16); @@ -582,7 +579,6 @@ private: static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); - friend class CTheScripts; }; #ifdef USE_DEBUG_SCRIPT_LOADER diff --git a/src/control/Script2.cpp b/src/control/Script2.cpp index 93098dac..a94bf907 100644 --- a/src/control/Script2.cpp +++ b/src/control/Script2.cpp @@ -1048,7 +1048,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CTheScripts::CleanUpThisPed(pPed); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED: @@ -1057,7 +1057,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CTheScripts::CleanUpThisVehicle(pVehicle); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED: @@ -1066,7 +1066,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); CTheScripts::CleanUpThisObject(pObject); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_DONT_REMOVE_CHAR: @@ -1074,7 +1074,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); script_assert(pPed); - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_DONT_REMOVE_CAR: @@ -1082,7 +1082,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); script_assert(pVehicle); - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_DONT_REMOVE_OBJECT: @@ -1090,7 +1090,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) CollectParameters(&m_nIp, 1); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); script_assert(pObject); - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); return 0; } case COMMAND_CREATE_CHAR_AS_PASSENGER: @@ -1142,6 +1142,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->SetPosition(pVehicle->GetPosition()); pPed->SetOrientation(0.0f, 0.0f, 0.0f); CPopulation::ms_nTotalMissionPeds++; + CWorld::Add(pPed); if (ScriptParams[3] >= 0) pVehicle->AddPassenger(pPed, ScriptParams[3]); else @@ -1149,16 +1150,14 @@ int8 CRunningScript::ProcessCommands400To499(int32 command) pPed->m_pMyVehicle = pVehicle; pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle); pPed->bInVehicle = true; - pVehicle->SetStatus(STATUS_PHYSICS); pPed->SetPedState(PED_DRIVING); pPed->bUsesCollision = false; pPed->AddInCarAnims(pVehicle, false); pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition()); - CWorld::Add(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT: diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp index a34c89a9..7476d8de 100644 --- a/src/control/Script3.cpp +++ b/src/control/Script3.cpp @@ -325,11 +325,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) CollectParameters(&m_nIp, 1); UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0])); return 0; +/* case COMMAND_SET_FREE_BOMBS: CollectParameters(&m_nIp, 1); CGarages::SetFreeBombs(ScriptParams[0] != 0); return 0; -#ifdef GTA_PS2 case COMMAND_SET_POWERPOINT: { CollectParameters(&m_nIp, 7); @@ -363,8 +363,6 @@ int8 CRunningScript::ProcessCommands500To599(int32 command) return 0; } -#endif // GTA_PS2 - /* case COMMAND_SET_ALL_TAXI_LIGHTS: CollectParameters(&m_nIp, 1); CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0); @@ -1279,7 +1277,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); return 0; } /* @@ -1343,7 +1341,6 @@ int8 CRunningScript::ProcessCommands600To699(int32 command) return 0; } #endif - /* case COMMAND_IS_PLAYER_STOPPED: { CollectParameters(&m_nIp, 1); @@ -1835,7 +1832,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -1890,7 +1887,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp index 31f50257..2177afa4 100644 --- a/src/control/Script4.cpp +++ b/src/control/Script4.cpp @@ -155,7 +155,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ++CCarCtrl::NumMissionCars; --CCarCtrl::NumRandomCars; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR); } ScriptParams[0] = handle; StoreParameters(&m_nIp, 1); @@ -188,7 +188,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ++CCarCtrl::NumMissionCars; --CCarCtrl::NumRandomCars; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR); } ScriptParams[0] = handle; StoreParameters(&m_nIp, 1); @@ -254,6 +254,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) pPed->SetObjective(OBJECTIVE_CATCH_TRAIN); return 0; } + */ #ifdef GTA_SCRIPT_COLLECTIVE case COMMAND_SET_COLL_OBJ_CATCH_TRAIN: CollectParameters(&m_nIp, 1); @@ -608,7 +609,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) } } if (m_bIsMissionScript) - CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_STAY_IN_SAME_PLACE: @@ -1055,7 +1056,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR: diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp index ab3c5b7f..822a70a8 100644 --- a/src/control/Script5.cpp +++ b/src/control/Script5.cpp @@ -2251,6 +2251,80 @@ VALIDATESAVEBUF(size) #undef SCRIPT_DATA_SIZE +void CRunningScript::Save(uint8*& buf) +{ +#ifdef COMPATIBLE_SAVES + SkipSaveBuf(buf, 8); + for (int i = 0; i < 8; i++) + WriteSaveBuf<char>(buf, m_abScriptName[i]); + WriteSaveBuf<uint32>(buf, m_nIp); +#ifdef CHECK_STRUCT_SIZES + static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); +#endif + for (int i = 0; i < MAX_STACK_DEPTH; i++) + WriteSaveBuf<uint32>(buf, m_anStack[i]); + WriteSaveBuf<uint16>(buf, m_nStackPointer); + SkipSaveBuf(buf, 2); +#ifdef CHECK_STRUCT_SIZES + static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); +#endif + for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) + WriteSaveBuf<int32>(buf, m_anLocalVariables[i]); + WriteSaveBuf<bool>(buf, m_bIsActive); + WriteSaveBuf<bool>(buf, m_bCondResult); + WriteSaveBuf<bool>(buf, m_bIsMissionScript); + WriteSaveBuf<bool>(buf, m_bSkipWakeTime); + WriteSaveBuf<uint32>(buf, m_nWakeTime); + WriteSaveBuf<uint16>(buf, m_nAndOrState); + WriteSaveBuf<bool>(buf, m_bNotFlag); + WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled); + WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted); + WriteSaveBuf<bool>(buf, m_bMissionFlag); + SkipSaveBuf(buf, 2); +#else + WriteSaveBuf(buf, *this); +#endif +} + +void CRunningScript::Load(uint8*& buf) +{ +#ifdef COMPATIBLE_SAVES + SkipSaveBuf(buf, 8); + for (int i = 0; i < 8; i++) + m_abScriptName[i] = ReadSaveBuf<char>(buf); + m_nIp = ReadSaveBuf<uint32>(buf); +#ifdef CHECK_STRUCT_SIZES + static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6"); +#endif + for (int i = 0; i < MAX_STACK_DEPTH; i++) + m_anStack[i] = ReadSaveBuf<uint32>(buf); + m_nStackPointer = ReadSaveBuf<uint16>(buf); + SkipSaveBuf(buf, 2); +#ifdef CHECK_STRUCT_SIZES + static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18"); +#endif + for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++) + m_anLocalVariables[i] = ReadSaveBuf<int32>(buf); + m_bIsActive = ReadSaveBuf<bool>(buf); + m_bCondResult = ReadSaveBuf<bool>(buf); + m_bIsMissionScript = ReadSaveBuf<bool>(buf); + m_bSkipWakeTime = ReadSaveBuf<bool>(buf); + m_nWakeTime = ReadSaveBuf<uint32>(buf); + m_nAndOrState = ReadSaveBuf<uint16>(buf); + m_bNotFlag = ReadSaveBuf<bool>(buf); + m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf); + m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf); + m_bMissionFlag = ReadSaveBuf<bool>(buf); + SkipSaveBuf(buf, 2); +#else + CRunningScript* n = next; + CRunningScript* p = prev; + *this = ReadSaveBuf<CRunningScript>(buf); + next = n; + prev = p; +#endif +} + void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity) { static CColPoint aTempColPoints[MAX_COLLISION_POINTS]; diff --git a/src/control/Script6.cpp b/src/control/Script6.cpp index 501a7873..76780941 100644 --- a/src/control/Script6.cpp +++ b/src/control/Script6.cpp @@ -703,7 +703,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CAR); return 0; } case COMMAND_START_BOAT_FOAM_ANIMATION: @@ -1191,7 +1191,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CollectParameters(&m_nIp, 8); CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CVehicle *pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]); - pPed->AttachPedToEntity(pVehicle, *(CVector*)&ScriptParams[2], ScriptParams[5], DEGTORAD(ScriptParams[6]), (eWeaponType)ScriptParams[7]); + pPed->AttachPedToEntity(pVehicle, *(CVector*)&ScriptParams[2], ScriptParams[5], DEGTORAD(*(float*)&ScriptParams[6]), (eWeaponType)ScriptParams[7]); return 0; } case COMMAND_DETACH_CHAR_FROM_CAR: @@ -1272,7 +1272,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); @@ -1320,7 +1320,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); diff --git a/src/control/Script7.cpp b/src/control/Script7.cpp index 1bad3407..1eaa6cd0 100644 --- a/src/control/Script7.cpp +++ b/src/control/Script7.cpp @@ -576,11 +576,11 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) CollectParameters(&m_nIp, 1); CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; ScriptParams[0] = pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels; - ScriptParams[1] = *(int*)&pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels; + *(float*)&ScriptParams[1] = pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels; ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie; - ScriptParams[3] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnWheelie; + *(float*)&ScriptParams[3] = pPlayerInfo->m_nLastDistanceTravelledOnWheelie; ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie; - ScriptParams[5] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnStoppie; + *(float*)&ScriptParams[5] = pPlayerInfo->m_nLastDistanceTravelledOnStoppie; StoreParameters(&m_nIp, 6); pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels = 0; pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels = 0.0f; @@ -1201,7 +1201,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER: @@ -1231,7 +1231,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); StoreParameters(&m_nIp, 1); if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); return 0; } case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: diff --git a/src/control/Script8.cpp b/src/control/Script8.cpp index a75692a0..0416d464 100644 --- a/src/control/Script8.cpp +++ b/src/control/Script8.cpp @@ -283,7 +283,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) pPed->bRespondsToThreats = false; ++CPopulation::ms_nTotalMissionPeds; if (m_bIsMissionScript) - CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); + CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR); } ScriptParams[0] = ped_handle; StoreParameters(&m_nIp, 1); diff --git a/src/control/SetPieces.cpp b/src/control/SetPieces.cpp index c5142a0a..bbcfa1ea 100644 --- a/src/control/SetPieces.cpp +++ b/src/control/SetPieces.cpp @@ -10,6 +10,7 @@ #include "Vehicle.h" #include "Wanted.h" #include "World.h" +#include "VarConsole.h" #define TIME_BETWEEN_SETPIECE_SPAWNS 20000 @@ -23,6 +24,9 @@ void CSetPieces::Init(void) { bDebug = false; NumSetPieces = 0; +#ifndef MASTER + VarConsole.Add("Show set pieces", &bDebug, true); +#endif } void CSetPieces::AddOne(uint8 type, CVector2D vTriggerInf, CVector2D vTriggerSup, CVector2D vSpawn1, CVector2D vTarget1, CVector2D vSpawn2, CVector2D vTarget2) @@ -47,6 +51,9 @@ void CSetPieces::Update(void) int nLast = NumSetPieces * (CTimer::GetFrameCounter() % 8 + 1) / 8; for (int i = nFirst; i < nLast; i++) aSetPieces[i].Update(); +#ifndef MASTER + // TODO: debug code from mobile +#endif // !MASTER } void CSetPieces::Save(uint8* buf, uint32* size) diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index 2cf1748c..d4188299 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -2370,8 +2370,10 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } - while(Beta >= PI) Beta -= 2*PI; - while(Beta < -PI) Beta += 2*PI; + if (!isAttached) { + while(Beta >= TWOPI) Beta -= TWOPI; + while(Beta < 0) Beta += TWOPI; + } if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); @@ -2414,13 +2416,14 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) } } }else{ - while(Beta < -PI) Beta += 2*PI; - while(Beta >= PI) Beta -= 2*PI; + while(Beta < -PI) Beta += TWOPI; + while(Beta >= PI) Beta -= TWOPI; } mat = TargetPed->m_attachedTo->GetMatrix(); rot.SetRotateX(Alpha); switch(TargetPed->m_attachType){ + case 0: rot.RotateZ(Beta); break; case 1: rot.RotateZ(Beta + HALFPI); break; case 2: rot.RotateZ(Beta + PI); break; case 3: rot.RotateZ(Beta - HALFPI); break; diff --git a/src/core/Clock.cpp b/src/core/Clock.cpp index 6c54ac63..b391e508 100644 --- a/src/core/Clock.cpp +++ b/src/core/Clock.cpp @@ -4,6 +4,7 @@ #include "Pad.h" #include "Clock.h" #include "Stats.h" +#include "VarConsole.h" // --MIAMI: File done @@ -20,6 +21,10 @@ uint32 CClock::ms_nMillisecondsPerGameMinute; uint32 CClock::ms_nLastClockTick; bool CClock::ms_bClockHasBeenStored; +#ifndef MASTER +bool gbFreezeTime; +#endif + void CClock::Initialise(uint32 scale) { @@ -31,6 +36,10 @@ CClock::Initialise(uint32 scale) ms_nLastClockTick = CTimer::GetTimeInMilliseconds(); ms_bClockHasBeenStored = false; debug("CClock ready\n"); +#ifndef MASTER + VarConsole.Add("Time (hour of day)", &ms_nGameClockHours, 1, 0, 23, true); + VarConsole.Add("Freeze time", &gbFreezeTime, true); +#endif } void @@ -50,6 +59,10 @@ CClock::Update(void) } } +#ifndef MASTER + else if (gbFreezeTime) + ms_nLastClockTick = CTimer::GetTimeInMilliseconds(); +#endif else if(CTimer::GetTimeInMilliseconds() - ms_nLastClockTick > ms_nMillisecondsPerGameMinute || gbFastTime) { ms_nGameClockMinutes++; diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp index fe865865..b2dad358 100644 --- a/src/core/ControllerConfig.cpp +++ b/src/core/ControllerConfig.cpp @@ -2354,15 +2354,15 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act #define VFB(b) #endif -#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT) \ +#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT, RSL, RSR) \ {{ \ O, /* PED_FIREWEAPON */ \ R2, /* PED_CYCLE_WEAPON_RIGHT */ \ L2, /* PED_CYCLE_WEAPON_LEFT */ \ nil, /* GO_FORWARD */ \ nil, /* GO_BACK */ \ - nil, /* GO_LEFT */ \ - nil, /* GO_RIGHT */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ Q, /* PED_SNIPER_ZOOM_IN */ \ X, /* PED_SNIPER_ZOOM_OUT */ \ T, /* VEHICLE_ENTER_EXIT */ \ @@ -2370,6 +2370,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act Q, /* PED_JUMPING */ \ X, /* PED_SPRINT */ \ R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ VFB(O) /* VEHICLE_FIREWEAPON */ \ X, /* VEHICLE_ACCELERATE */ \ Q, /* VEHICLE_BRAKE */ \ @@ -2382,10 +2384,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* VEHICLE_LOOKLEFT */ \ R2, /* VEHICLE_LOOKRIGHT */ \ nil, /* VEHICLE_LOOKBEHIND */ \ - nil, /* VEHICLE_TURRETLEFT */ \ - nil, /* VEHICLE_TURRETRIGHT */ \ - nil, /* VEHICLE_TURRETUP */ \ - nil, /* VEHICLE_TURRETDOWN */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ L2, /* PED_CYCLE_TARGET_LEFT */ \ R2, /* PED_CYCLE_TARGET_RIGHT */ \ L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ @@ -2397,6 +2399,7 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act nil, /* TOGGLE_DPAD */ \ nil, /* SWITCH_DEBUG_CAM_ON */ \ nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ }, \ { \ @@ -2405,8 +2408,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* PED_CYCLE_WEAPON_LEFT */ \ nil, /* GO_FORWARD */ \ nil, /* GO_BACK */ \ - nil, /* GO_LEFT */ \ - nil, /* GO_RIGHT */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ Q, /* PED_SNIPER_ZOOM_IN */ \ X, /* PED_SNIPER_ZOOM_OUT */ \ T, /* VEHICLE_ENTER_EXIT */ \ @@ -2414,6 +2417,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act Q, /* PED_JUMPING */ \ X, /* PED_SPRINT */ \ R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ VFB(O) /* VEHICLE_FIREWEAPON */ \ X, /* VEHICLE_ACCELERATE */ \ Q, /* VEHICLE_BRAKE */ \ @@ -2426,10 +2431,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* VEHICLE_LOOKLEFT */ \ R2, /* VEHICLE_LOOKRIGHT */ \ nil, /* VEHICLE_LOOKBEHIND */ \ - nil, /* VEHICLE_TURRETLEFT */ \ - nil, /* VEHICLE_TURRETRIGHT */ \ - nil, /* VEHICLE_TURRETUP */ \ - nil, /* VEHICLE_TURRETDOWN */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ L2, /* PED_CYCLE_TARGET_LEFT */ \ R2, /* PED_CYCLE_TARGET_RIGHT */ \ L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ @@ -2441,6 +2446,7 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act nil, /* TOGGLE_DPAD */ \ nil, /* SWITCH_DEBUG_CAM_ON */ \ nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ }, \ { \ @@ -2449,8 +2455,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* PED_CYCLE_WEAPON_LEFT */ \ nil, /* GO_FORWARD */ \ nil, /* GO_BACK */ \ - nil, /* GO_LEFT */ \ - nil, /* GO_RIGHT */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ T, /* PED_SNIPER_ZOOM_IN */ \ Q, /* PED_SNIPER_ZOOM_OUT */ \ L1, /* VEHICLE_ENTER_EXIT */ \ @@ -2458,6 +2464,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act Q, /* PED_JUMPING */ \ O, /* PED_SPRINT */ \ R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ VFB(O) /* VEHICLE_FIREWEAPON */ \ X, /* VEHICLE_ACCELERATE */ \ Q, /* VEHICLE_BRAKE */ \ @@ -2470,10 +2478,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* VEHICLE_LOOKLEFT */ \ R2, /* VEHICLE_LOOKRIGHT */ \ nil, /* VEHICLE_LOOKBEHIND */ \ - nil, /* VEHICLE_TURRETLEFT */ \ - nil, /* VEHICLE_TURRETRIGHT */ \ - nil, /* VEHICLE_TURRETUP */ \ - nil, /* VEHICLE_TURRETDOWN */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ L2, /* PED_CYCLE_TARGET_LEFT */ \ R2, /* PED_CYCLE_TARGET_RIGHT */ \ T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ @@ -2485,6 +2493,7 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act nil, /* TOGGLE_DPAD */ \ nil, /* SWITCH_DEBUG_CAM_ON */ \ nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ }, \ { \ @@ -2493,8 +2502,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* PED_CYCLE_WEAPON_LEFT */ \ nil, /* GO_FORWARD */ \ nil, /* GO_BACK */ \ - nil, /* GO_LEFT */ \ - nil, /* GO_RIGHT */ \ + LEFT, /* GO_LEFT */ \ + RIGHT, /* GO_RIGHT */ \ Q, /* PED_SNIPER_ZOOM_IN */ \ X, /* PED_SNIPER_ZOOM_OUT */ \ T, /* VEHICLE_ENTER_EXIT */ \ @@ -2502,6 +2511,8 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act Q, /* PED_JUMPING */ \ X, /* PED_SPRINT */ \ R3, /* PED_LOOKBEHIND */ \ + L3, /* PED_DUCK */ \ + L1, /* PED_ANSWER_PHONE */ \ VFB(R1) /* VEHICLE_FIREWEAPON */ \ nil, /* VEHICLE_ACCELERATE */ \ nil, /* VEHICLE_BRAKE */ \ @@ -2514,10 +2525,10 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act L2, /* VEHICLE_LOOKLEFT */ \ R2, /* VEHICLE_LOOKRIGHT */ \ nil, /* VEHICLE_LOOKBEHIND */ \ - nil, /* VEHICLE_TURRETLEFT */ \ - nil, /* VEHICLE_TURRETRIGHT */ \ - nil, /* VEHICLE_TURRETUP */ \ - nil, /* VEHICLE_TURRETDOWN */ \ + RSL, /* VEHICLE_TURRETLEFT */ \ + RSR, /* VEHICLE_TURRETRIGHT */ \ + UP, /* VEHICLE_TURRETUP */ \ + DOWN, /* VEHICLE_TURRETDOWN */ \ L2, /* PED_CYCLE_TARGET_LEFT */ \ R2, /* PED_CYCLE_TARGET_RIGHT */ \ O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \ @@ -2529,14 +2540,26 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act nil, /* TOGGLE_DPAD */ \ nil, /* SWITCH_DEBUG_CAM_ON */ \ nil, /* TAKE_SCREEN_SHOT */ \ + nil, /* UNKNOWN_ACTION */ \ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \ }} +#ifdef BUTTON_ICONS +#define UP "~U~" +#define DOWN "~D~" +#define LEFT "~<~" +#define RIGHT "~>~" +#else +#define UP "UP" +#define DOWN "DOWN" +#define LEFT "LEFT" +#define RIGHT "RIGHT" +#endif -const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK"); +const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK", "right stick left", "right stick right"); #ifdef BUTTON_ICONS -const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK"); +const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK", "~(~", "~)~"); #endif @@ -2558,11 +2581,11 @@ const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O #endif const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] = - CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT"); + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT", "right stick left", "right stick right"); #ifdef BUTTON_ICONS const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = - CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT"); + CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT", "~(~", "~)~"); #endif #undef PS2_TRIANGLE @@ -2570,6 +2593,11 @@ const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] = #undef PS2_CROSS #undef PS2_SQUARE +#undef UP +#undef DOWN +#undef LEFT +#undef RIGHT + #undef CONTROLLER_BUTTONS #undef VFB diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index db5da918..e5e42b8c 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -1280,6 +1280,9 @@ CMenuManager::DrawStandardMenus(bool activeScreen) case MENUACTION_CFO_SELECT: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions) if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue) option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; @@ -4786,7 +4789,11 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u TheCamera.m_fMouseAccelHorzntl = 0.0025f; CVehicle::m_bDisableMouseSteering = true; m_ControlMethod = CONTROL_STANDARD; +#ifdef PC_PLAYER_CONTROLS TheCamera.m_bUseMouse3rdPerson = true; +#else + TheCamera.m_bUseMouse3rdPerson = false; +#endif SaveSettings(); } SetHelperText(2); @@ -4806,6 +4813,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u case MENUACTION_CFO_DYNAMIC: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + break; + if (!option.m_CFOSelect->onlyApplyOnEnter) { option.m_CFOSelect->displayedValue++; if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) @@ -4954,6 +4964,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u case MENUACTION_CFO_DYNAMIC: CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; if (option.m_Action == MENUACTION_CFO_SELECT) { + if (option.m_CFOSelect->disableIfGameLoaded && !m_bGameNotLoaded) + break; + if (changeAmount > 0) { option.m_CFOSelect->displayedValue++; if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts) diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 5e18c29a..b27cccb5 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -403,9 +403,10 @@ struct CCFOSelect : CCFO int8 displayedValue; // only if onlyApplyOnEnter enabled for now int8 lastSavedValue; // only if onlyApplyOnEnter enabled ChangeFunc changeFunc; + bool disableIfGameLoaded; CCFOSelect() {}; - CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){ + CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc = nil, bool disableIfGameLoaded = false){ this->value = value; if (value) this->lastSavedValue = this->displayedValue = *value; @@ -415,6 +416,7 @@ struct CCFOSelect : CCFO this->numRightTexts = numRightTexts; this->onlyApplyOnEnter = onlyApplyOnEnter; this->changeFunc = changeFunc; + this->disableIfGameLoaded = disableIfGameLoaded; } }; diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 348ac26d..8405c2ec 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -96,6 +96,7 @@ #include "postfx.h" #include "custompipes.h" #include "screendroplets.h" +#include "VarConsole.h" #ifdef USE_TEXTURE_POOL #include "TexturePools.h" #endif @@ -113,6 +114,10 @@ char CGame::aDatFile[32]; bool CGame::russianGame = false; bool CGame::japaneseGame = false; #endif +#ifndef MASTER +CVector CGame::PlayerCoords; +bool8 CGame::VarUpdatePlayerCoords; +#endif int gameTxdSlot; @@ -557,6 +562,16 @@ bool CGame::Initialise(const char* datFile) #ifdef USE_TEXTURE_POOL _TexturePoolsUnknown(true); #endif + +#ifndef MASTER + PlayerCoords = FindPlayerCoors(); + VarConsole.Add("X PLAYER COORD", &PlayerCoords.x, 10.0f, -10000.0f, 10000.0f, true); + VarConsole.Add("Y PLAYER COORD", &PlayerCoords.y, 10.0f, -10000.0f, 10000.0f, true); + VarConsole.Add("Z PLAYER COORD", &PlayerCoords.z, 10.0f, -10000.0f, 10000.0f, true); + VarConsole.Add("UPDATE PLAYER COORD", &VarUpdatePlayerCoords, true); +#endif + + DMAudio.SetStartingTrackPositions(true); DMAudio.ChangeMusicMode(MUSICMODE_GAME); return true; @@ -837,6 +852,12 @@ void CGame::Process(void) CWindModifiers::Number = 0; if (!CTimer::GetIsPaused()) { +#ifndef MASTER + if (VarUpdatePlayerCoords) { + FindPlayerPed()->Teleport(PlayerCoords); + VarUpdatePlayerCoords = false; + } +#endif CSprite2d::SetRecipNearClip(); CSprite2d::InitPerFrame(); CFont::InitPerFrame(); diff --git a/src/core/Game.h b/src/core/Game.h index ee9ca943..4052eb00 100644 --- a/src/core/Game.h +++ b/src/core/Game.h @@ -48,6 +48,11 @@ public: static bool playingIntro; static char aDatFile[32]; +#ifndef MASTER + static CVector PlayerCoords; + static bool8 VarUpdatePlayerCoords; +#endif + static bool InitialiseOnceBeforeRW(void); static bool InitialiseRenderWare(void); static void ShutdownRenderWare(void); diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 173de805..72e19c49 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -217,8 +217,10 @@ CMenuScreen aScreens[] = { { "FET_CTL", MENUPAGE_OPTIONS, 0, #ifdef PC_PLAYER_CONTROLS MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER, -#endif MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 0, 0, MENUALIGN_CENTER, +#else + MENUACTION_KEYBOARDCTRLS,"FEC_RED", SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS, 320, 150, MENUALIGN_CENTER, +#endif MENUACTION_CHANGEMENU, "FEC_MOU", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, 0, 0, MENUALIGN_CENTER, MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, MENUALIGN_CENTER, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, 0, 0, 0, MENUALIGN_CENTER, diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp index 96e3be07..70c92ce8 100644 --- a/src/core/MenuScreensCustom.cpp +++ b/src/core/MenuScreensCustom.cpp @@ -24,7 +24,7 @@ #ifdef CUSTOM_FRONTEND_OPTIONS #ifdef IMPROVED_VIDEOMODE - #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) }, 0, 0, MENUALIGN_LEFT, + #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange, true) }, 0, 0, MENUALIGN_LEFT, #else #define VIDEOMODE_SELECTOR #endif @@ -36,19 +36,19 @@ #endif #ifdef CUTSCENE_BORDERS_SWITCH - #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, + #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, #else #define CUTSCENE_BORDERS_TOGGLE #endif #ifdef FREE_CAM - #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, + #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, #else #define FREE_CAM_TOGGLE #endif #ifdef PS2_ALPHA_TEST - #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, + #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, #else #define DUALPASS_SELECTOR #endif @@ -61,14 +61,14 @@ #ifdef EXTENDED_COLOURFILTER #define POSTFX_SELECTORS \ - MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \ - MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, + MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT, #else #define POSTFX_SELECTORS #endif #ifdef INVERT_LOOK_FOR_PAD - #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false, nil) }, 150, 0, MENUALIGN_LEFT, + #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false) }, 150, 0, MENUALIGN_LEFT, #else #define INVERT_PAD_SELECTOR #endif @@ -548,8 +548,10 @@ CMenuScreenCustom aScreens[] = { { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil, #ifdef PC_PLAYER_CONTROLS MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER, -#endif MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 0, 0, MENUALIGN_CENTER, +#else + MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 320, 150, MENUALIGN_CENTER, +#endif #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER, #endif diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 4a78e834..feda19c6 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -1692,12 +1692,11 @@ void CPad::UpdatePads(void) bUpdate = false; if ( bUpdate ) - { GetPad(0)->Update(0); - // GetPad(1)->Update(0); // not in VC - } -#if defined(MASTER) && !defined(XINPUT) +#ifndef MASTER + GetPad(1)->Update(1); +#else GetPad(1)->NewState.Clear(); GetPad(1)->OldState.Clear(); #endif diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 2fd8bf1c..3e470fde 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -36,6 +36,7 @@ #include "MemoryHeap.h" #include "Font.h" #include "Frontend.h" +#include "VarConsole.h" //--MIAMI: file done (possibly bugs) @@ -82,6 +83,12 @@ CEntity *pIslandLODbeachEntity; int32 islandLODmainland; int32 islandLODbeach; +#ifndef MASTER +bool gbPrintStats; +bool gbPrintVehiclesInMemory; // TODO +bool gbPrintStreamingBuffer; // TODO +#endif + bool CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) { @@ -237,8 +244,14 @@ CStreaming::Init2(void) pIslandLODbeachEntity = nil; islandLODmainland = -1; islandLODbeach = -1; - CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland); - CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach); + CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland); + CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach); + +#ifndef MASTER + VarConsole.Add("Streaming Debug", &gbPrintStats, true); + VarConsole.Add("Streaming Vehicle Debug", &gbPrintVehiclesInMemory, true); + VarConsole.Add("Printf Streaming Buffer contents", &gbPrintStreamingBuffer, true); +#endif } void @@ -1908,10 +1921,12 @@ CStreaming::LoadBigBuildingsWhenNeeded(void) ISLAND_LOADING_IS(LOW) CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition()); +#ifdef NO_ISLAND_LOADING else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) { RemoveIslandsNotUsed(CGame::currLevel); CStreaming::RequestIslands(CGame::currLevel); } +#endif CStreaming::LoadAllRequestedModels(false); diff --git a/src/core/SurfaceTable.cpp b/src/core/SurfaceTable.cpp index 56cea203..8018076d 100644 --- a/src/core/SurfaceTable.cpp +++ b/src/core/SurfaceTable.cpp @@ -138,7 +138,7 @@ CSurfaceTable::GetWetMultiplier(uint8 surfaceType) case SURFACE_SAND: case SURFACE_SAND_BEACH: - return 1.0f - CWeather::WetRoads*0.5f; + return 1.0f + CWeather::WetRoads*0.5f; default: return 1.0f; diff --git a/src/core/common.h b/src/core/common.h index 155b5dba..3fb2e963 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -79,6 +79,10 @@ typedef int64_t int64; // hardcode ucs-2 typedef uint16_t wchar; +typedef uint8 bool8; +typedef uint16 bool16; +typedef uint32 bool32; + #if defined(_MSC_VER) typedef ptrdiff_t ssize_t; #endif diff --git a/src/core/config.h b/src/core/config.h index 8fd3bc1c..a06ed1be 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -338,6 +338,11 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually #define USE_BASIC_SCRIPT_DEBUG_OUTPUT #endif +#ifdef MASTER +#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT +#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT +#endif + // Replay //#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!) @@ -360,6 +365,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually // Audio #define AUDIO_CACHE // cache sound lengths to speed up the cold boot //#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS +//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder #ifdef LIBRW diff --git a/src/core/main.cpp b/src/core/main.cpp index 85e04540..d9579fee 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -72,6 +72,7 @@ #include "postfx.h" #include "custompipes.h" #include "screendroplets.h" +#include "VarConsole.h" GlobalScene Scene; @@ -133,6 +134,9 @@ bool gbNewRenderer; #define CLEARMODE (rwCAMERACLEARZ) #endif +bool bDisplayNumOfAtomicsRendered = false; +bool bDisplayPosn = false; + void ValidateVersion() { @@ -473,6 +477,11 @@ Initialise3D(void *param) { PUSH_MEMID(MEMID_RENDER); +#ifndef MASTER + VarConsole.Add("Display number of atomics rendered", &bDisplayNumOfAtomicsRendered, true); + VarConsole.Add("Display posn and framerate", &bDisplayPosn, true); +#endif + if (RsRwInitialize(param)) { POP_MEMID(); @@ -1008,7 +1017,6 @@ return; void DisplayGameDebugText() { - static bool bDisplayPosn = false; static bool bDisplayCheatStr = false; // custom #ifndef FINAL @@ -1382,6 +1390,10 @@ RenderMenus(void) { FrontEndMenuManager.DrawFrontEnd(); } +#ifndef MASTER + else + VarConsole.Check(); +#endif } void diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 5e3d8922..0e5ed2af 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -225,7 +225,6 @@ void LoadINISettings() void SaveINISettings() { bool changed = false; - char temp[4]; #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) { @@ -647,7 +646,7 @@ extern bool gbRenderWorld2; #endif DebugMenuAddVar("Render", "Drunkness", &CMBlur::Drunkness, nil, 0.05f, 0, 1.0f); #ifndef MASTER - DebugMenuAddVarBool8("Render", "Occlusion debug", &bDisplayOccDebugStuff, nil); + DebugMenuAddVarBool8("Render", "Occlusion debug", &bDispayOccDebugStuff, nil); #endif #ifdef EXTENDED_PIPELINES static const char *vehpipenames[] = { "MatFX", "Neo" }; diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 9b6be5f6..1073deb3 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -126,6 +126,7 @@ CEntity::CreateRwObject(void) m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); else if(RwObjectGetType(m_rwObject) == rpCLUMP) m_matrix.AttachRW(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); + mi->AddRef(); } } @@ -139,6 +140,7 @@ CEntity::AttachToRwObject(RwObject *obj) m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false); else if(RwObjectGetType(m_rwObject) == rpCLUMP) m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false); + CModelInfo::GetModelInfo(m_modelIndex)->AddRef(); } } @@ -239,12 +241,8 @@ CEntity::GetBoundRadius(void) void CEntity::UpdateRwFrame(void) { - if(m_rwObject){ - if(RwObjectGetType(m_rwObject) == rpATOMIC) - RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject)); - else if(RwObjectGetType(m_rwObject) == rpCLUMP) - RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject)); - } + if(m_rwObject) + RwFrameUpdateObjects((RwFrame*)rwObjectGetParent(m_rwObject)); } void diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp index acf9c702..706b469c 100644 --- a/src/entities/Physical.cpp +++ b/src/entities/Physical.cpp @@ -235,6 +235,7 @@ CPhysical::GetBoundRect(void) return CRect(center.x-radius, center.y-radius, center.x+radius, center.y+radius); } +// --MIAMI: Proof-read once void CPhysical::AddToMovingList(void) { @@ -242,6 +243,7 @@ CPhysical::AddToMovingList(void) m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this); } +// --MIAMI: Proof-read once void CPhysical::RemoveFromMovingList(void) { @@ -261,12 +263,14 @@ CPhysical::SetDamagedPieceRecord(uint16 piece, float impulse, CEntity *entity, C m_vecDamageNormal = dir; } +// --MIAMI: Proof-read once void CPhysical::AddCollisionRecord(CEntity *ent) { AddCollisionRecord_Treadable(ent); this->bHasCollided = true; ent->bHasCollided = true; + this->m_nLastTimeCollided = CTimer::GetTimeInMilliseconds(); if(IsVehicle() && ent->IsVehicle()){ if(((CVehicle*)this)->m_nAlarmState == -1) ((CVehicle*)this)->m_nAlarmState = 15000; @@ -280,10 +284,10 @@ CPhysical::AddCollisionRecord(CEntity *ent) return; if(m_nCollisionRecords < PHYSICAL_MAX_COLLISIONRECORDS) m_aCollisionRecords[m_nCollisionRecords++] = ent; - m_nLastTimeCollided = CTimer::GetTimeInMilliseconds(); } } +// --MIAMI: Proof-read once void CPhysical::AddCollisionRecord_Treadable(CEntity *ent) { @@ -291,6 +295,7 @@ CPhysical::AddCollisionRecord_Treadable(CEntity *ent) } } +// --MIAMI: Proof-read once bool CPhysical::GetHasCollidedWith(CEntity *ent) { @@ -302,20 +307,23 @@ CPhysical::GetHasCollidedWith(CEntity *ent) return false; } +// --MIAMI: Proof-read once void CPhysical::RemoveRefsToEntity(CEntity *ent) { - int i, j; + int i = 0, j; - for(i = 0; i < m_nCollisionRecords; i++){ + while (i < m_nCollisionRecords){ if(m_aCollisionRecords[i] == ent){ for(j = i; j < m_nCollisionRecords-1; j++) m_aCollisionRecords[j] = m_aCollisionRecords[j+1]; m_nCollisionRecords--; - } + } else + i++; } } +// --MIAMI: Proof-read once void CPhysical::PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phys, CVector localPos) { @@ -332,6 +340,7 @@ CPhysical::PlacePhysicalRelativeToOtherPhysical(CPhysical *other, CPhysical *phy CWorld::Add(phys); } +// --MIAMI: Proof-read once int32 CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) { @@ -350,6 +359,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) return numSpheres; } +// --MIAMI: Proof-read once void CPhysical::ProcessControl(void) { @@ -417,6 +427,7 @@ CPhysical::GetSpeed(const CVector &r) return m_vecMoveSpeed + m_vecMoveFriction + CrossProduct(m_vecTurnFriction + m_vecTurnSpeed, r); } +// --MIAMI: Proof-read once void CPhysical::ApplyMoveSpeed(void) { @@ -426,7 +437,7 @@ CPhysical::ApplyMoveSpeed(void) GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep()); } - +// --MIAMI: Proof-read once void CPhysical::ApplyTurnSpeed(void) { @@ -442,12 +453,14 @@ CPhysical::ApplyTurnSpeed(void) } } +// --MIAMI: Proof-read once void CPhysical::ApplyMoveForce(float jx, float jy, float jz) { m_vecMoveSpeed += CVector(jx, jy, jz)*(1.0f/m_fMass); } +// --MIAMI: Proof-read once void CPhysical::ApplyTurnForce(float jx, float jy, float jz, float px, float py, float pz) { @@ -462,6 +475,7 @@ CPhysical::ApplyFrictionMoveForce(float jx, float jy, float jz) m_vecMoveFriction += CVector(jx, jy, jz)*(1.0f/m_fMass); } +// --MIAMI: Proof-read once void CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float py, float pz) { @@ -470,6 +484,7 @@ CPhysical::ApplyFrictionTurnForce(float jx, float jy, float jz, float px, float m_vecTurnFriction += turnimpulse*(1.0f/m_fTurnMass); } +// --MIAMI: Proof-read once bool CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias) { @@ -483,6 +498,7 @@ CPhysical::ApplySpringCollision(float springConst, CVector &springDir, CVector & return true; } +// --MIAMI: Proof-read once bool CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir) { @@ -500,6 +516,7 @@ CPhysical::ApplySpringCollisionAlt(float springConst, CVector &springDir, CVecto return true; } +// --MIAMI: Proof-read once // What exactly is speed? bool CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed) @@ -560,17 +577,16 @@ CPhysical::ApplyFriction(void) m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f); } +// --MIAMI: Proof-read once void CPhysical::ApplyAirResistance(void) { if(m_fAirResistance > 0.1f){ - if(GetStatus() != STATUS_GHOST){ - float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); - m_vecMoveSpeed *= f; - m_vecTurnSpeed *= f; - } - }else{ - float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep()); + float f = Pow(m_fAirResistance, CTimer::GetTimeStep()); + m_vecMoveSpeed *= f; + m_vecTurnSpeed *= f; + }else if(GetStatus() != STATUS_GHOST){ + float f = Pow(1.0f/Abs(1.0f + m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr()), CTimer::GetTimeStep()); m_vecMoveSpeed *= f; m_vecTurnSpeed *= 0.99f; } @@ -1015,6 +1031,7 @@ CPhysical::ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CV return false; } +// --MIAMI: Proof-read once bool CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) { @@ -1044,7 +1061,11 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) impulseB = (speedSum - fOtherSpeedB) * B->m_fMass; impulseLimit = adhesiveLimit*CTimer::GetTimeStep(); if(impulseA < -impulseLimit) impulseA = -impulseLimit; - if(impulseB > impulseLimit) impulseB = impulseLimit; // BUG: game has A's clamp again here, but this can't be right +#ifdef FIX_BUGS + if(impulseB > impulseLimit) impulseB = impulseLimit; +#else + if(impulseA < -impulseLimit) impulseA = -impulseLimit; // duplicate +#endif A->ApplyFrictionMoveForce(frictionDir*impulseA); B->ApplyFrictionMoveForce(frictionDir*impulseB); return true; @@ -1139,6 +1160,7 @@ CPhysical::ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint) return false; } +// --MIAMI: Proof-read once bool CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) { @@ -1176,7 +1198,7 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) if(fOtherSpeed > 0.0f){ frictionDir = vOtherSpeed * (1.0f/fOtherSpeed); fImpulse = -fOtherSpeed * m_fMass; - impulseLimit = adhesiveLimit*CTimer::GetTimeStep() * 1.5f; + impulseLimit = adhesiveLimit*CTimer::GetTimeStep() * 1.5; if(fImpulse < -impulseLimit) fImpulse = -impulseLimit; ApplyFrictionMoveForce(frictionDir*fImpulse); ApplyFrictionTurnForce(frictionDir*fImpulse, pointpos); @@ -1194,6 +1216,7 @@ CPhysical::ApplyFriction(float adhesiveLimit, CColPoint &colpoint) return false; } +// --MIAMI: Proof-read once bool CPhysical::ProcessShiftSectorList(CPtrList *lists) { @@ -1267,7 +1290,8 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) skipShift = true; Aobj->m_pCollidingEntity = B; } - } + } else + skipShift = true; }else if(B->IsObject() && A->IsVehicle()){ CObject *Bobj = (CObject*)B; if(Bobj->ObjectCreatedBy != TEMP_OBJECT && @@ -1282,7 +1306,8 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) if(size.z < A->GetPosition().z || (Invert(A->GetMatrix(), inv) * size).z < 0.0f) skipShift = true; - } + } else + skipShift = true; }else if(IsBodyPart(A->GetModelIndex()) && B->IsPed()) skipShift = true; else if(A->IsPed() && IsBodyPart(B->GetModelIndex())) @@ -1354,6 +1379,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists) return true; } +// --MIAMI: Proof-read once bool CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists) { @@ -1520,6 +1546,7 @@ collision: return true; } +// --MIAMI: Proof-read once bool CPhysical::ProcessCollisionSectorList(CPtrList *lists) { @@ -1656,8 +1683,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) return true; if(numCollisions == 0 && A == (CEntity*)FindPlayerPed() && Aped->m_pCollidingEntity == B) Aped->m_pCollidingEntity = nil; - }else if(B->IsBuilding() || B->bIsStuck || B->bInfiniteMass || altcollision){ - + }else if(B->IsBuilding() || B->bIsStuck || B->m_phy_flagA08 || altcollision){ // This is the case where B doesn't move B->m_scanCode = CWorld::GetCurrentScanCode(); @@ -1925,18 +1951,22 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists) CMatrix inv; CVector size = CModelInfo::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize(); size = B->GetMatrix() * size; - if(size.z < B->GetPosition().z || + if(size.z < A->GetPosition().z || (Invert(A->GetMatrix(), inv) * size).z < 0.0f) Bobj->ObjectDamage(50.0f); } }else if(A->IsObject() && A->bUsesCollision && B->IsVehicle()){ if(Aobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f) Aobj->ObjectDamage(maxImpulseB); +#ifdef FIX_BUGS else if(Aobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){ +#else + else if(Bobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){ +#endif CMatrix inv; CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize(); size = A->GetMatrix() * size; - if(size.z < A->GetPosition().z || + if(size.z < B->GetPosition().z || (Invert(B->GetMatrix(), inv) * size).z < 0.0f) Aobj->ObjectDamage(50.0f); } @@ -1987,6 +2017,7 @@ CPhysical::CheckCollision_SimpleCar(void) float PHYSICAL_SHIFT_SPEED_DAMP = 0.707f; +// --MIAMI: Proof-read once void CPhysical::ProcessShift(void) { @@ -1997,8 +2028,8 @@ CPhysical::ProcessShift(void) RemoveAndAdd(); }else{ CPhysical *surf; - if(bHasHitWall && IsPed() && (surf = ((CPed*)this)->m_pCurrentPhysSurface, surf == nil || !surf->bInfiniteMass || surf->m_phy_flagA08) || - CWorld::bSecondShift){ + if(bHasHitWall && (IsPed() && (surf = ((CPed*)this)->m_pCurrentPhysSurface, surf == nil || !surf->bInfiniteMass || surf->m_phy_flagA08) || + CWorld::bSecondShift)){ m_vecMoveSpeed *= Pow(PHYSICAL_SHIFT_SPEED_DAMP, CTimer::GetTimeStep()); m_vecTurnSpeed *= Pow(PHYSICAL_SHIFT_SPEED_DAMP, CTimer::GetTimeStep()); } diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp index 1f154250..8a95a49a 100644 --- a/src/extras/frontendoption.cpp +++ b/src/extras/frontendoption.cpp @@ -111,7 +111,7 @@ void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint option.m_TargetMenu = targetMenu; } -void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName) +void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName, bool disableIfGameLoaded) { int8 screenOptionOrder = RegisterNewOption(); @@ -133,6 +133,7 @@ void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align option.m_CFOSelect->save = saveName; option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter; option.m_CFOSelect->changeFunc = changeFunc; + option.m_CFOSelect->disableIfGameLoaded = disableIfGameLoaded; } void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName) diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h index 6670c323..2719f076 100644 --- a/src/extras/frontendoption.h +++ b/src/extras/frontendoption.h @@ -78,7 +78,7 @@ void FrontendOptionSetCursor(int screen, int8 option, bool overwrite = false); // var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to saveName param. obv), otherwise pass nil/0 void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE); -void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName = nil); +void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName = nil, bool disableIfGameLoaded = false); void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = nil); // lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT diff --git a/src/extras/ini_parser.hpp b/src/extras/ini_parser.hpp index 99acf1ee..8e88bc29 100644 --- a/src/extras/ini_parser.hpp +++ b/src/extras/ini_parser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Denilson das Mercęs Amorim <dma_2012@hotmail.com> + * Copyright (c) 2013-2015 Denilson das MercÊs Amorim <dma_2012@hotmail.com> * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/src/extras/screendroplets.cpp b/src/extras/screendroplets.cpp index 6ea72f09..ac3a17b2 100644 --- a/src/extras/screendroplets.cpp +++ b/src/extras/screendroplets.cpp @@ -391,7 +391,7 @@ void ScreenDroplets::RegisterSplash(CParticleObject *pobj) { CVector dist = pobj->GetPosition() - ms_prevCamPos; - if(dist.MagnitudeSqr() < 20.0f){ + if(dist.MagnitudeSqr() < 50.0f){ // 20 originally ms_splashDuration = 14; ms_splashObject = pobj; } diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp index 37567927..863407b9 100644 --- a/src/fakerw/fake.cpp +++ b/src/fakerw/fake.cpp @@ -14,6 +14,7 @@ using namespace rw; RwUInt8 RwObjectGetType(const RwObject *obj) { return obj->type; } +RwFrame* rwObjectGetParent(const RwObject *obj) { return (RwFrame*)obj->parent; } void *RwMalloc(size_t size) { return engine->memfuncs.rwmalloc(size, 0); } diff --git a/src/fakerw/rwplcore.h b/src/fakerw/rwplcore.h index 511f7678..69c921cc 100644 --- a/src/fakerw/rwplcore.h +++ b/src/fakerw/rwplcore.h @@ -108,12 +108,12 @@ enum RwCorePluginID //struct RwObject; typedef rw::Object RwObject; +typedef rw::Frame RwFrame; typedef RwObject *(*RwObjectCallBack)(RwObject *object, void *data); RwUInt8 RwObjectGetType(const RwObject *obj); - - +RwFrame* rwObjectGetParent(const RwObject *obj); #define rwsprintf sprintf #define rwvsprintf vsprintf diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 88a16a95..6c0d9987 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -1003,7 +1003,7 @@ public: // My names. Inlined in VC AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) { if (m_nPedType == PEDTYPE_COP && weapon->IsFlagSet(WEAPONFLAG_COP3_RD)) - return ANIM_WEAPON_FIRE_3RD; + return Get3rdFireAnim(weapon); else return GetPrimaryFireAnim(weapon); } diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 364e18d8..16e6c8e2 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -924,10 +924,10 @@ CPed::ProcessObjective(void) m_pMyVehicle->SetStatus(STATUS_PHYSICS); m_pMyVehicle->AutoPilot.m_nPrevRouteNode = 0; if (m_nPedType == PEDTYPE_COP) { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity); + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity); m_pMyVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel(); } else { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity * 0.8f; + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity * 0.8f; m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY; } m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; @@ -1921,7 +1921,7 @@ CPed::ProcessObjective(void) ClearObjective(); CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle); m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity; + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity; m_pMyVehicle->SetStatus(STATUS_PHYSICS); } else { SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); @@ -2147,10 +2147,10 @@ CPed::SelectGunIfArmed(void) if (GetWeapon(i).m_nAmmoTotal > 0) { eWeaponType weaponType = GetWeapon(i).m_eWeaponType; - if (weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_PYTHON || weaponType == WEAPONTYPE_SHOTGUN || + if (weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_MP5 || weaponType == WEAPONTYPE_M4 || + weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_PYTHON || weaponType == WEAPONTYPE_SHOTGUN || weaponType == WEAPONTYPE_SPAS12_SHOTGUN || weaponType == WEAPONTYPE_STUBBY_SHOTGUN || - weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_M4 || weaponType == WEAPONTYPE_MP5 || - weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_FLAMETHROWER || weaponType == WEAPONTYPE_SNIPERRIFLE) { + weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_SNIPERRIFLE || weaponType == WEAPONTYPE_FLAMETHROWER) { SetCurrentWeapon(i); return true; } @@ -2269,7 +2269,7 @@ CPed::ReactToAttack(CEntity *attacker) CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle); m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity; + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fMaxCruiseVelocity; m_pMyVehicle->SetStatus(STATUS_PHYSICS); } @@ -5458,7 +5458,7 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker) if (nearVehDriver && nearVehDriver != this && nearVehDriver->m_nPedType == m_nPedType && nearVehDriver->CharCreatedBy == RANDOM_CHAR) { if (nearVeh->IsVehicleNormal() && nearVeh->IsCar()) { - nearVeh->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * nearVeh->pHandling->Transmission.fUnkMaxVelocity * 0.8f; + nearVeh->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * nearVeh->pHandling->Transmission.fMaxCruiseVelocity * 0.8f; nearVeh->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY; nearVeh->SetStatus(STATUS_PHYSICS); nearVeh->AutoPilot.m_nTempAction = TEMPACT_NONE; diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp index 79c6f367..eaa2aa3d 100644 --- a/src/peds/PedFight.cpp +++ b/src/peds/PedFight.cpp @@ -661,9 +661,7 @@ CPed::Attack(void) { CAnimBlendAssociation *weaponAnimAssoc; int32 weaponAnim; - eWeaponType ourWeaponType; float weaponAnimTime; - eWeaponFire ourWeaponFire; float animLoopEnd; CWeaponInfo *ourWeapon; bool attackShouldContinue; @@ -673,9 +671,7 @@ CPed::Attack(void) float animLoopStart; CVector firePos; - ourWeaponType = GetWeapon()->m_eWeaponType; - ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType); - ourWeaponFire = ourWeapon->m_eWeaponFire; + ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); weaponAnimAssoc = nil; attackShouldContinue = !!bIsAttacking; reloadAnimAssoc = nil; @@ -694,14 +690,15 @@ CPed::Attack(void) delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire; } } - } else { - AnimationId anim = GetFireAnimNotDucking(ourWeapon); - weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), anim); - if (anim == ANIM_WEAPON_FIRE_3RD && weaponAnimAssoc) { + } else if (m_nPedType == PEDTYPE_COP && Get3rdFireAnim(ourWeapon)){ + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), Get3rdFireAnim(ourWeapon)); + if (weaponAnimAssoc) { animLoopStart = 11.f/30.f; animLoopEnd = 19.f/30.f; delayBetweenAnimAndFire = 14.f/30.f; } + } else { + weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(ourWeapon)); } if (GetReloadAnim(ourWeapon)) { @@ -778,15 +775,15 @@ CPed::Attack(void) if (!weaponAnimAssoc) { if (!throwAssoc) { if (attackShouldContinue) { - if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) { + if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) { if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(ourWeapon)) { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetCrouchFireAnim(ourWeapon), 8.0f); } else if(GetSecondFireAnim(ourWeapon) && CGeneral::GetRandomNumber() & 1){ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f); - } else if(!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE || - GetFireAnimGround(ourWeapon) || + } else if(!CGame::nastyGame || ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE || + !GetFireAnimGround(ourWeapon, false) || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) { weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetFireAnimNotDucking(ourWeapon), 8.0f); @@ -831,11 +828,11 @@ CPed::Attack(void) m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM; } - if (ourWeaponType != WEAPONTYPE_CHAINSAW + if (GetWeapon()->m_eWeaponType != WEAPONTYPE_CHAINSAW || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) { - if (ourWeaponType == WEAPONTYPE_CHAINSAW) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW) { DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_ATTACK, 0.0f); } else if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) { if (weaponAnimAssoc->speed < 1.0f) @@ -859,11 +856,11 @@ CPed::Attack(void) GetWeapon()->Fire(this, &firePos); - if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE || - ourWeaponType == WEAPONTYPE_TEARGAS) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_MOLOTOV || GetWeapon()->m_eWeaponType == WEAPONTYPE_GRENADE || GetWeapon()->m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE || + GetWeapon()->m_eWeaponType == WEAPONTYPE_TEARGAS) { RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nModelId); } - if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { + if (GetWeapon()->m_nAmmoTotal == 0 && ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) { SelectGunIfArmed(); } @@ -875,13 +872,13 @@ CPed::Attack(void) switch (ourWeapon->m_AnimToPlay) { case ASSOCGRP_UNARMED: if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (ourWeaponType << 8))); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (GetWeapon()->m_eWeaponType << 8))); break; case ASSOCGRP_KNIFE: case ASSOCGRP_BASEBALLBAT: case ASSOCGRP_GOLFCLUB: case ASSOCGRP_CHAINSAW: - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8))); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (GetWeapon()->m_eWeaponType << 8))); break; default: break; @@ -944,14 +941,13 @@ CPed::Attack(void) } if (IsPlayer()) { - eWeaponType weaponType = GetWeapon()->m_eWeaponType; - if (weaponType == WEAPONTYPE_BASEBALLBAT || weaponType == WEAPONTYPE_GOLFCLUB || weaponType == WEAPONTYPE_KATANA) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT || GetWeapon()->m_eWeaponType == WEAPONTYPE_GOLFCLUB || GetWeapon()->m_eWeaponType == WEAPONTYPE_KATANA) { float loopEndWithDelay = animLoopEnd; if (loopEndWithDelay >= 98.0f) loopEndWithDelay = (14.0f / 30.0f) + delayBetweenAnimAndFire; if (weaponAnimAssoc->flags & ASSOC_RUNNING) { if (weaponAnimAssoc->currentTime >= animLoopStart && weaponAnimAssoc->currentTime <= loopEndWithDelay) - CSpecialFX::AddWeaponStreak(weaponType); + CSpecialFX::AddWeaponStreak(GetWeapon()->m_eWeaponType); } } } @@ -970,7 +966,7 @@ CPed::Attack(void) weaponAnimTime = weaponAnimAssoc->currentTime; // Anim loop end, either start the loop again or finish the attack - if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) { + if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeapon->m_eWeaponFire != WEAPON_FIRE_PROJECTILE) { if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING) { if (GetReloadAnim(ourWeapon) && !reloadAnimAssoc) { if (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) { @@ -997,7 +993,7 @@ CPed::Attack(void) PedOnGroundState pedOnGroundState; if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE && (CGame::nastyGame && ((pedOnGroundState = CheckForPedsOnGroundToAttack(this, nil)) > PED_IN_FRONT_OF_ATTACKER) - || ourWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { + || GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) { AnimationId fireAnim = GetFireAnimGround(ourWeapon, false); if (weaponAnimAssoc->animId == fireAnim) @@ -1030,10 +1026,10 @@ CPed::Attack(void) // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading) if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType); // Fun fact: removing this part leds to reloading flamethrower - if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) { weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT; weaponAnimAssoc->flags &= ~ASSOC_RUNNING; weaponAnimAssoc->blendDelta = -4.0f; @@ -2021,9 +2017,9 @@ CPed::PlayHitSound(CPed *hitTo) if (weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE) { if (m_curFightMove >= FIGHTMOVE_MELEE1) { if (m_curFightMove == FIGHTMOVE_MELEE3) { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (weapon << 8) | 3); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (weapon << 8) | ENTITY_TYPE_PED); } else { - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_KNIFE_ATTACK, (weapon << 8) | 3); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_KNIFE_ATTACK, (weapon << 8) | ENTITY_TYPE_PED); } return; } @@ -2048,7 +2044,7 @@ CPed::PlayHitSound(CPed *hitTo) } if (soundId != NO_SND) - DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | 3); + DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | ENTITY_TYPE_PED); } // --MIAMI: Done @@ -3567,7 +3563,7 @@ CPed::CollideWithPed(CPed *collideWith) animAssoc->flags |= ASSOC_FADEOUTWHENDONE; collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 1000; if (m_nPedState == PED_ATTACK) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, 0.0f); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f); } } else { // We're at his right side @@ -3985,7 +3981,7 @@ CPed::DriveVehicle(void) } if (neededAngForWheelie >= 0.15f) { if (bike->m_fBrakePedal <= 0.5f || velocityFwdDotProd <= 0.01f) { - if (bike->m_fGasPedal > 0.5f && targetUDLean <= 0.0f && 0.3f * bike->pHandling->Transmission.fUnkMaxVelocity > velocityFwdDotProd) { + if (bike->m_fGasPedal > 0.5f && targetUDLean <= 0.0f && 0.3f * bike->pHandling->Transmission.fMaxCruiseVelocity > velocityFwdDotProd) { targetUDLean = Min(0.1f, targetUDLean); } } else { diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 8220b370..f07d1ac7 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -22,10 +22,14 @@ #include "Script.h" #include "Replay.h" #include "PedPlacement.h" +#include "VarConsole.h" #define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f bool CPlayerPed::bDontAllowWeaponChange; +#ifndef MASTER +bool CPlayerPed::bDebugPlayerInfo; +#endif const uint32 CPlayerPed::nSaveStructSize = #ifdef COMPATIBLE_SAVES @@ -61,7 +65,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1) m_pWanted->Initialise(); m_pArrestingCop = nil; m_currentWeapon = WEAPONTYPE_UNARMED; - m_nSelectedWepSlot = 0; + m_nSelectedWepSlot = WEAPONSLOT_UNARMED; m_nSpeedTimer = 0; m_bSpeedTimerFlag = false; SetWeaponLockOnTarget(nil); @@ -182,6 +186,11 @@ CPlayerPed::SetupPlayerPed(int32 index) CWorld::Add(player); player->m_wepAccuracy = 100; + +#ifndef MASTER + VarConsole.Add("Debug PlayerPed", &CPlayerPed::bDebugPlayerInfo, true); + VarConsole.Add("Tweak Vehicle Handling", &CVehicle::m_bDisplayHandlingInfo, true); +#endif } // --MIAMI: Done @@ -300,7 +309,7 @@ CPlayerPed::SetInitialState(void) m_nLastPedState = PED_NONE; m_animGroup = ASSOCGRP_PLAYER; m_fMoveSpeed = 0.0f; - m_nSelectedWepSlot = WEAPONTYPE_UNARMED; + m_nSelectedWepSlot = WEAPONSLOT_UNARMED; m_nEvadeAmount = 0; m_pEvadingFrom = nil; bIsPedDieAnimPlaying = false; @@ -748,17 +757,20 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed) && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_CAMERA) { - for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) { + // I don't know what kind of loop that was + m_nSelectedWepSlot = m_currentWeapon - 1; + do { if (m_nSelectedWepSlot < 0) m_nSelectedWepSlot = TOTAL_WEAPON_SLOTS - 1; - if (m_nSelectedWepSlot == 0) + if (m_nSelectedWepSlot == WEAPONSLOT_UNARMED) break; - if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) { + if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) break; - } - } + + --m_nSelectedWepSlot; + } while (m_nSelectedWepSlot != WEAPONSLOT_UNARMED); } } } @@ -772,17 +784,17 @@ spentAmmoCheck: || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_ROCKETLAUNCHER) return; - if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR - || GetWeapon(2).m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE) - m_nSelectedWepSlot = m_currentWeapon - 1; + if (GetWeapon()->m_eWeaponType == WEAPONTYPE_DETONATOR + && GetWeapon(WEAPONSLOT_PROJECTILE).m_eWeaponType == WEAPONTYPE_DETONATOR_GRENADE) + m_nSelectedWepSlot = WEAPONSLOT_PROJECTILE; else - m_nSelectedWepSlot = 2; + m_nSelectedWepSlot = m_currentWeapon - 1; - for (; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) { + for (; m_nSelectedWepSlot >= WEAPONSLOT_UNARMED; --m_nSelectedWepSlot) { // BUG: m_nSelectedWepSlot and GetWeapon(..) takes slot in VC but they compared them against weapon types in whole condition! jeez #ifdef FIX_BUGS - if (m_nSelectedWepSlot == 1 || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != 2) { + if (m_nSelectedWepSlot == WEAPONSLOT_MELEE || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONSLOT_PROJECTILE) { #else if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(WEAPONTYPE_BASEBALLBAT).m_eWeaponType == WEAPONTYPE_BASEBALLBAT || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 @@ -791,15 +803,16 @@ spentAmmoCheck: goto switchDetectDone; } } - m_nSelectedWepSlot = 0; + m_nSelectedWepSlot = WEAPONSLOT_UNARMED; } } switchDetectDone: if (m_nSelectedWepSlot != m_currentWeapon) { - if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT) + if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT) { RemoveWeaponAnims(m_currentWeapon, -1000.0f); MakeChangesForNewWeapon(m_nSelectedWepSlot); + } } } @@ -1775,7 +1788,7 @@ CPlayerPed::ProcessControl(void) if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK) && !m_attachedTo) { if (TheCamera.Using1stPersonWeaponMode()) { if (padUsed) - PlayerControlFighter(padUsed); + PlayerControlSniper(padUsed); } else if (TheCamera.Cams[0].Using3rdPersonMouseCam() #ifdef FREE_CAM diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 3c58f7f5..1b7158b5 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -15,7 +15,7 @@ public: float m_fCurrentStamina; float m_fMaxStamina; float m_fStaminaProgress; - int8 m_nSelectedWepSlot; // eWeaponType + int8 m_nSelectedWepSlot; bool m_bSpeedTimerFlag; uint8 m_nEvadeAmount; uint32 m_nSpeedTimer; // m_nStandStillTimer? @@ -46,6 +46,9 @@ public: unsigned int m_nLastBusFareCollected; static bool bDontAllowWeaponChange; +#ifndef MASTER + static bool bDebugPlayerInfo; +#endif CPlayerPed(); ~CPlayerPed(); diff --git a/src/render/Font.cpp b/src/render/Font.cpp index d6a06db8..3517031d 100644 --- a/src/render/Font.cpp +++ b/src/render/Font.cpp @@ -297,12 +297,10 @@ CFont::Initialise(void) CTxdStore::AddRef(ButtonsSlot); CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(ButtonsSlot); -#if 0 // unused - ButtonSprite[BUTTON_UP].SetTexture("up"); - ButtonSprite[BUTTON_DOWN].SetTexture("down"); - ButtonSprite[BUTTON_LEFT].SetTexture("left"); - ButtonSprite[BUTTON_RIGHT].SetTexture("right"); -#endif + ButtonSprite[BUTTON_UP].SetTexture("thumblyu"); + ButtonSprite[BUTTON_DOWN].SetTexture("thumblyd"); + ButtonSprite[BUTTON_LEFT].SetTexture("thumblxl"); + ButtonSprite[BUTTON_RIGHT].SetTexture("thumblxr"); ButtonSprite[BUTTON_CROSS].SetTexture("cross"); ButtonSprite[BUTTON_CIRCLE].SetTexture("circle"); ButtonSprite[BUTTON_SQUARE].SetTexture("square"); @@ -313,6 +311,8 @@ CFont::Initialise(void) ButtonSprite[BUTTON_R1].SetTexture("r1"); ButtonSprite[BUTTON_R2].SetTexture("r2"); ButtonSprite[BUTTON_R3].SetTexture("r3"); + ButtonSprite[BUTTON_RSTICK_LEFT].SetTexture("thumbrxl"); + ButtonSprite[BUTTON_RSTICK_RIGHT].SetTexture("thumbrxr"); CTxdStore::PopCurrentTxd(); } #endif // BUTTON_ICONS @@ -411,9 +411,12 @@ CFont::DrawButton(float x, float y) rect.bottom = Details.scaleY * 19.0f + y; int vertexAlphaState; + void *raster; RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &vertexAlphaState); + RwRenderStateGet(rwRENDERSTATETEXTURERASTER, &raster); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE); ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, Details.color.a)); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)vertexAlphaState); } } @@ -926,14 +929,6 @@ CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, f if (Details.slant != 0.0f && !IsJapanese()) y = (Details.slantRefX - x) * Details.slant + Details.slantRefY; -#ifdef BUTTON_ICONS - if (PS2Symbol != BUTTON_NONE) { - DrawButton(x, y); - x += Details.scaleY * 17.0f; - PS2Symbol = BUTTON_NONE; - } -#endif - PrintChar(x, y, c); x += GetCharacterSize(c); if (c == 0 && (!NewLine || !IsJapanese())) // space @@ -1132,12 +1127,10 @@ CFont::GetStringWidth(wchar *s, bool spaces) s++; #ifdef BUTTON_ICONS switch (*s) { -#if 0 // unused case 'U': case 'D': case '<': case '>': -#endif case 'X': case 'O': case 'Q': @@ -1148,6 +1141,8 @@ CFont::GetStringWidth(wchar *s, bool spaces) case 'J': case 'V': case 'C': + case '(': + case ')': w += 17.0f * Details.scaleY; break; default: @@ -1170,12 +1165,10 @@ CFont::GetStringWidth(wchar *s, bool spaces) s++; #ifdef BUTTON_ICONS switch (*s) { -#if 0 // unused case 'U': case 'D': case '<': case '>': -#endif case 'X': case 'O': case 'Q': @@ -1186,6 +1179,8 @@ CFont::GetStringWidth(wchar *s, bool spaces) case 'J': case 'V': case 'C': + case '(': + case ')': w += 17.0f * Details.scaleY; break; default: @@ -1280,12 +1275,10 @@ CFont::ParseToken(wchar *s, bool japShit) case 'w': SetColor(CRGBA(175, 175, 175, 255)); break; case 'y': SetColor(CRGBA(210, 196, 106, 255)); break; #ifdef BUTTON_ICONS -#if 0 // unused case 'U': PS2Symbol = BUTTON_UP; break; case 'D': PS2Symbol = BUTTON_DOWN; break; case '<': PS2Symbol = BUTTON_LEFT; break; case '>': PS2Symbol = BUTTON_RIGHT; break; -#endif case 'X': PS2Symbol = BUTTON_CROSS; break; case 'O': PS2Symbol = BUTTON_CIRCLE; break; case 'Q': PS2Symbol = BUTTON_SQUARE; break; @@ -1296,6 +1289,8 @@ CFont::ParseToken(wchar *s, bool japShit) case 'J': PS2Symbol = BUTTON_R1; break; case 'V': PS2Symbol = BUTTON_R2; break; case 'C': PS2Symbol = BUTTON_R3; break; + case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; + case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; #endif } } else if (IsJapanese()) { @@ -1342,12 +1337,10 @@ CFont::ParseToken(wchar *s) #endif case 'y': SetColor(CRGBA(255, 227, 79, 255)); Details.anonymous_23 = true; break; #ifdef BUTTON_ICONS -#if 0 // unused case 'U': PS2Symbol = BUTTON_UP; break; case 'D': PS2Symbol = BUTTON_DOWN; break; case '<': PS2Symbol = BUTTON_LEFT; break; case '>': PS2Symbol = BUTTON_RIGHT; break; -#endif case 'X': PS2Symbol = BUTTON_CROSS; break; case 'O': PS2Symbol = BUTTON_CIRCLE; break; case 'Q': PS2Symbol = BUTTON_SQUARE; break; @@ -1358,6 +1351,8 @@ CFont::ParseToken(wchar *s) case 'J': PS2Symbol = BUTTON_R1; break; case 'V': PS2Symbol = BUTTON_R2; break; case 'C': PS2Symbol = BUTTON_R3; break; + case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; + case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; #endif } while(*s != '~') s++; @@ -1450,6 +1445,24 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) color.g = 227; color.b = 79; break; +#ifdef BUTTON_ICONS + case 'U': PS2Symbol = BUTTON_UP; break; + case 'D': PS2Symbol = BUTTON_DOWN; break; + case '<': PS2Symbol = BUTTON_LEFT; break; + case '>': PS2Symbol = BUTTON_RIGHT; break; + case 'X': PS2Symbol = BUTTON_CROSS; break; + case 'O': PS2Symbol = BUTTON_CIRCLE; break; + case 'Q': PS2Symbol = BUTTON_SQUARE; break; + case 'T': PS2Symbol = BUTTON_TRIANGLE; break; + case 'K': PS2Symbol = BUTTON_L1; break; + case 'M': PS2Symbol = BUTTON_L2; break; + case 'A': PS2Symbol = BUTTON_L3; break; + case 'J': PS2Symbol = BUTTON_R1; break; + case 'V': PS2Symbol = BUTTON_R2; break; + case 'C': PS2Symbol = BUTTON_R3; break; + case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; + case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; +#endif default: break; } @@ -1503,7 +1516,17 @@ CFont::RenderFontBuffer() color = RenderState.color; } if (*pRenderStateBufPointer.pStr == '~') { +#ifdef BUTTON_ICONS + PS2Symbol = BUTTON_NONE; +#endif pRenderStateBufPointer.pStr = ParseToken(pRenderStateBufPointer.pStr, color, bFlash, bBold); +#ifdef BUTTON_ICONS + if(PS2Symbol != BUTTON_NONE) { + DrawButton(textPosX, textPosY); + textPosX += Details.scaleY * 17.0f; + PS2Symbol = BUTTON_NONE; + } +#endif if (bFlash) { if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) { Details.bFlashState = !Details.bFlashState; diff --git a/src/render/Font.h b/src/render/Font.h index d61ca6e7..36424bf5 100644 --- a/src/render/Font.h +++ b/src/render/Font.h @@ -95,12 +95,10 @@ enum enum { BUTTON_NONE = -1, -#if 0 // unused BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT, -#endif BUTTON_CROSS, BUTTON_CIRCLE, BUTTON_SQUARE, @@ -111,6 +109,8 @@ enum BUTTON_R1, BUTTON_R2, BUTTON_R3, + BUTTON_RSTICK_LEFT, + BUTTON_RSTICK_RIGHT, MAX_BUTTON_ICONS }; #endif // BUTTON_ICONS diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index c4e78a91..3432f32c 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -24,6 +24,7 @@ #include "Stats.h" #include "main.h" #include "General.h" +#include "VarConsole.h" // --MIAMI: file done @@ -1119,7 +1120,7 @@ void CHud::Draw() CFont::SetPropOff(); CFont::SetFontStyle(FONT_LOCALE(CTheScripts::IntroTextLines[i].m_nFont)); - CFont::PrintString(SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text); + CFont::PrintString(SCREEN_WIDTH - SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - CTheScripts::IntroTextLines[i].m_fAtX), SCREEN_HEIGHT - SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - CTheScripts::IntroTextLines[i].m_fAtY), CTheScripts::IntroTextLines[i].m_Text); } } for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) { @@ -1461,7 +1462,7 @@ void CHud::DrawAfterFade() CFont::SetPropOff(); CFont::SetFontStyle(line.m_nFont); - CFont::PrintString(SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text); + CFont::PrintString(SCREEN_WIDTH - SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - line.m_fAtX), SCREEN_HEIGHT - SCREEN_SCALE_Y(DEFAULT_SCREEN_HEIGHT - line.m_fAtY), line.m_Text); } } for (int i = 0; i < ARRAY_SIZE(CTheScripts::IntroRectangles); i++) { @@ -1760,6 +1761,9 @@ void CHud::Initialise() m_LastWanted = 0; m_LastWeapon = 0; +#ifndef MASTER + VarConsole.Add("Draw HUD", &m_Wants_To_Draw_Hud, false); +#endif CTxdStore::PopCurrentTxd(); } diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp index 2b15e75b..3ea5678c 100644 --- a/src/render/Occlusion.cpp +++ b/src/render/Occlusion.cpp @@ -9,6 +9,7 @@ #include "Draw.h" #include "Timer.h" #include "RwHelper.h" +#include "VarConsole.h" int32 COcclusion::NumOccludersOnMap; int16 COcclusion::FarAwayList; @@ -31,20 +32,20 @@ CVector gOccluderCoorsOnScreen[8]; CVector gOccluderCoors[8]; #ifndef MASTER -bool bDisplayOccDebugStuff; +bool bDispayOccDebugStuff; // disPAY, yeah #endif void COcclusion::Init(void) { NumOccludersOnMap = 0; +#ifndef MASTER + VarConsole.Add("Occlusion debug", &bDispayOccDebugStuff, true); +#endif FarAwayList = -1; NearbyList = -1; ListWalkThroughFA = -1; PreviousListWalkThroughFA = -1; -#ifndef MASTER - bDisplayOccDebugStuff = false; -#endif } void @@ -458,7 +459,7 @@ bool COcclusion::IsPositionOccluded(CVector pos, float side) { RwIm2DVertex vertexbufferT[2]; void COcclusion::Render() { - if (!bDisplayOccDebugStuff || !(CTimer::GetTimeInMilliseconds() & 0x200)) + if (!bDispayOccDebugStuff || !(CTimer::GetTimeInMilliseconds() & 0x200)) return; RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); diff --git a/src/render/Occlusion.h b/src/render/Occlusion.h index 8a444525..e0edef53 100644 --- a/src/render/Occlusion.h +++ b/src/render/Occlusion.h @@ -58,5 +58,5 @@ bool CalcScreenCoors(CVector const &in, CVector *out, float *outw, float *outh); bool CalcScreenCoors(CVector const &in, CVector *out); #ifndef MASTER -extern bool bDisplayOccDebugStuff; +extern bool bDispayOccDebugStuff; #endif
\ No newline at end of file diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp index e8be23bd..2b1df555 100644 --- a/src/render/Shadows.cpp +++ b/src/render/Shadows.cpp @@ -25,6 +25,7 @@ #include "CutsceneObject.h" #include "CutsceneShadow.h" #include "Clock.h" +#include "VarConsole.h" #ifdef DEBUGMENU SETTWEAKPATH("Shadows"); @@ -57,6 +58,9 @@ CStaticShadow CShadows::aStaticShadows [MAX_STATICSHADOWS]; CPolyBunch *CShadows::pEmptyBunchList; CPermanentShadow CShadows::aPermanentShadows[MAX_PERMAMENTSHADOWS]; +#ifndef MASTER +bool gbCountPolysInShadow; +#endif void CShadows::Init(void) @@ -154,6 +158,10 @@ CShadows::Init(void) { aPermanentShadows[i].m_nType = SHADOWTYPE_NONE; } + +#ifndef MASTER + VarConsole.Add("Count polys in shadow", &gbCountPolysInShadow, true); +#endif } void diff --git a/src/render/VarConsole.cpp b/src/render/VarConsole.cpp new file mode 100644 index 00000000..372a091a --- /dev/null +++ b/src/render/VarConsole.cpp @@ -0,0 +1,786 @@ +#include "common.h" +#include "VarConsole.h" +#include "Font.h" +#include "Pad.h" + +#define VAR_CONSOLE_PAD 1 + +CVarConsole VarConsole; + +void +CVarConsole::Initialise() +{ + m_nCountEntries = 0; + m_nCurPage = 1; + m_bIsOpen = false; + m_nCurEntry = 0; + m_nFirstEntryOnPage = 0; +} + +void +CVarConsole::Add(char *text, int8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt8Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT8; + m_aEntries[i].I8_step = step; + m_aEntries[i].I8_min = min; + m_aEntries[i].I8_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, int16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt16Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT16; + m_aEntries[i].I16_step = step; + m_aEntries[i].I16_min = min; + m_aEntries[i].I16_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, int32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt32Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT32; + m_aEntries[i].I32_step = step; + m_aEntries[i].I32_min = min; + m_aEntries[i].I32_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, int64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pInt64Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_INT64; + m_aEntries[i].I64_step = step; + m_aEntries[i].I64_min = min; + m_aEntries[i].I64_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint8Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT8; + m_aEntries[i].I8_step = step; + m_aEntries[i].I8_min = min; + m_aEntries[i].I8_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint16Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT16; + m_aEntries[i].I16_step = step; + m_aEntries[i].I16_min = min; + m_aEntries[i].I16_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint32Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT32; + m_aEntries[i].I32_step = step; + m_aEntries[i].I32_min = min; + m_aEntries[i].I32_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, uint64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint64Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_UINT64; + m_aEntries[i].I64_step = step; + m_aEntries[i].I64_min = min; + m_aEntries[i].I64_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, float *pVal, float step, float min, float max, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pFloatValue = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_FLOAT; + m_aEntries[i].F_step = step; + m_aEntries[i].F_min = min; + m_aEntries[i].F_max = max; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pBoolValue = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool8 *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint8Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL8; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool16 *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint16Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL16; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, bool32 *pVal, bool8 isVar) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pUint32Value = pVal; + m_aEntries[i].bAllowExceedBounds = isVar; + m_aEntries[i].VarType = VCE_TYPE_BOOL32; + m_nCountEntries++; +} + +void +CVarConsole::Add(char *text, void (*pCallback)(void)) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + return; + } + + m_aEntries[i].text = text; + m_aEntries[i].pCallback = pCallback; + m_aEntries[i].VarType = VCE_TYPE_FUNCTION; + m_nCountEntries++; +} + +void +CVarConsole::Remove(char *text) +{ + int i; + for (i = 0; i < m_nCountEntries; i++) { + if (m_aEntries[i].text == text) + { + for (int j = i; j < m_nCountEntries-1; j++) + m_aEntries[j] = m_aEntries[j+1]; + m_nCountEntries--; + return; + } + } +} + +void +CVarConsole::SortPages() +{ + m_nNumPages = m_nCountEntries / 30 + 1; +} + +void +CVarConsole::Display() +{ + char s[256]; + wchar ws[256]; + + CFont::SetColor(CRGBA(200, 200, 200, 255)); + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.6f)); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + CFont::SetPropOn(); + CFont::SetWrapx(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); + CFont::SetRightJustifyWrap(0.0f); + sprintf(s, "PAGE %d", m_nCurPage); + AsciiToUnicode(s, ws); + CFont::SetRightJustifyOn(); + CFont::PrintString(SCREEN_SCALE_X(310.0f), SCREEN_SCALE_Y(30.0f), ws); + CFont::SetRightJustifyOff(); + int y = 45; + for (int i = m_nFirstEntryOnPage; i < m_nCountEntries && i < m_nFirstEntryOnPage + 30; i++) + { + switch (m_aEntries[i].VarType) + { + case VCE_TYPE_INT8: + sprintf(s, "(%d) %s:I8:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt8Value); + break; + case VCE_TYPE_INT16: + sprintf(s, "(%d) %s:I16:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt16Value); + break; + case VCE_TYPE_INT32: + sprintf(s, "(%d) %s:I32:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt32Value); + break; + case VCE_TYPE_INT64: +#ifdef FIX_BUGS + sprintf(s, "(%d) %s:I64:%lld", i + 1, m_aEntries[i].text, *m_aEntries[i].pInt64Value); +#else + sprintf(s, "(%d) %s:I64:%d", i + 1, m_aEntries[i].text, (int32)*m_aEntries[i].pInt64Value); +#endif + break; + case VCE_TYPE_UINT8: + sprintf(s, "(%d) %s:U8:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint8Value); + break; + case VCE_TYPE_UINT16: + sprintf(s, "(%d) %s:U6:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint16Value); + break; + case VCE_TYPE_UINT32: + sprintf(s, "(%d) %s:U32:%d", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint32Value); + break; + case VCE_TYPE_UINT64: +#ifdef FIX_BUGS + sprintf(s, "(%d) %s:U64:%llu", i + 1, m_aEntries[i].text, *m_aEntries[i].pUint64Value); +#else + sprintf(s, "(%d) %s:U64:%d", i + 1, m_aEntries[i].text, (uint32)*m_aEntries[i].pUint64Value); +#endif + break; + case VCE_TYPE_FLOAT: + sprintf(s, "(%d) %s:F:%f", i + 1, m_aEntries[i].text, *m_aEntries[i].pFloatValue); + break; + case VCE_TYPE_BOOL: + if (*m_aEntries[i].pBoolValue) + sprintf(s, "(%d) %s:B:TRUE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B : FALSE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_BOOL8: + if (*m_aEntries[i].pUint8Value == FALSE) + sprintf(s, "(%d) %s:B8:FALSE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B8:TRUE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_BOOL16: + if (*m_aEntries[i].pUint16Value == FALSE) + sprintf(s, "(%d) %s:B16:FALSE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B16:TRUE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_BOOL32: + if (*m_aEntries[i].pUint32Value == FALSE) + sprintf(s, "(%d) %s:B32:FALSE", i + 1, m_aEntries[i].text); + else + sprintf(s, "(%d) %s:B32:TRUE", i + 1, m_aEntries[i].text); + break; + case VCE_TYPE_FUNCTION: + sprintf(s, "(%d) %s:FUNCTION:call this function?", i + 1, m_aEntries[i].text); + break; + } + AsciiToUnicode(s, ws); + if (m_nCurEntry == i) { + CFont::SetBackgroundOn(); +#ifdef FIX_BUGS + CFont::SetBackgroundColor(CRGBA(128, 128, 128, 128)); +#endif + } +#ifdef FIX_BUGS + else + CFont::SetBackgroundColor(CRGBA(128, 128, 128, 0)); +#endif + + CFont::SetColor(CRGBA(200, 200, 200, 255)); + CFont::PrintString(SCREEN_SCALE_X(30.0f), SCREEN_SCALE_Y(y), ws); + if (m_nCurEntry == i) + CFont::SetBackgroundOff(); + y += 12; + } +} + +void +CVarConsole::ModifyLeft() +{ + CVarConsoleEntry &entry = m_aEntries[m_nCurEntry]; + switch (entry.VarType) + { + case VCE_TYPE_INT8: + *entry.pInt8Value -= entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt8Value < entry.I8_min) + *entry.pInt8Value = entry.I8_max; + } else { + if (*entry.pInt8Value < entry.I8_min) + *entry.pInt8Value = entry.I8_min; + } + break; + case VCE_TYPE_INT16: + *entry.pInt16Value -= entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt16Value < entry.I16_min) + *entry.pInt16Value = entry.I16_max; + } + else { + if (*entry.pInt16Value < entry.I16_min) + *entry.pInt16Value = entry.I16_min; + } + break; + case VCE_TYPE_INT32: + *entry.pInt32Value -= entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt32Value < entry.I32_min) + *entry.pInt32Value = entry.I32_max; + } + else { + if (*entry.pInt32Value < entry.I32_min) + *entry.pInt32Value = entry.I32_min; + } + break; + case VCE_TYPE_INT64: + *entry.pInt64Value -= entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt64Value < entry.I64_min) + *entry.pInt64Value = entry.I64_max; + } + else { + if (*entry.pInt64Value < entry.I64_min) + *entry.pInt64Value = entry.I64_min; + } + break; + case VCE_TYPE_UINT8: + *entry.pUint8Value -= entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*(int8*)entry.pUint8Value < entry.I8_min) + *entry.pUint8Value = entry.I8_max; + } + else { + if (*(int8*)entry.pUint8Value < entry.I8_min) + *entry.pUint8Value = entry.I8_min; + } + break; + case VCE_TYPE_UINT16: + *entry.pUint16Value -= entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*(int16*)entry.pUint16Value < entry.I16_min) + *entry.pUint16Value = entry.I16_max; + } + else { + if (*(int16*)entry.pUint16Value < entry.I16_min) + *entry.pUint16Value = entry.I16_min; + } + break; + case VCE_TYPE_UINT32: + *entry.pUint32Value -= entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*(int32*)entry.pUint32Value < entry.I32_min) + *entry.pUint32Value = entry.I32_max; + } + else { + if (*(int32*)entry.pUint32Value < entry.I32_min) + *entry.pUint32Value = entry.I32_min; + } + break; + case VCE_TYPE_UINT64: + *entry.pUint64Value -= entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*(int64*)entry.pUint64Value < entry.I64_min) + *entry.pUint64Value = entry.I64_max; + } + else { + if (*(int64*)entry.pUint64Value < entry.I64_min) + *entry.pUint64Value = entry.I64_min; + } + break; + case VCE_TYPE_FLOAT: + *entry.pFloatValue -= entry.F_step; + if (entry.bAllowExceedBounds) { + if (*entry.pFloatValue < entry.F_min) + *entry.pFloatValue = entry.F_max; + } + else { + if (*entry.pFloatValue < entry.F_min) + *entry.pFloatValue = entry.F_min; + } + break; + case VCE_TYPE_BOOL: + if (entry.bAllowExceedBounds) + *entry.pBoolValue ^= true; + else + *entry.pBoolValue = false; + break; + case VCE_TYPE_BOOL8: + if (entry.bAllowExceedBounds) + *entry.pUint8Value = *entry.pUint8Value == false; + else + *entry.pUint8Value = false; + break; + case VCE_TYPE_BOOL16: + if (entry.bAllowExceedBounds) + *entry.pUint16Value = *entry.pUint16Value == false; + else + *entry.pUint16Value = false; + break; + case VCE_TYPE_BOOL32: + if (entry.bAllowExceedBounds) + *entry.pUint32Value = *entry.pUint32Value == false; + else + *entry.pUint32Value = false; + break; + case VCE_TYPE_FUNCTION: + entry.pCallback(); + break; + default: + return; + } +} + +void +CVarConsole::ModifyRight() +{ + CVarConsoleEntry &entry = m_aEntries[m_nCurEntry]; + switch (entry.VarType) + { + case VCE_TYPE_INT8: + *entry.pInt8Value += entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt8Value > entry.I8_max) + *entry.pInt8Value = entry.I8_min; + } + else { + if (*entry.pInt8Value > entry.I8_max) + *entry.pInt8Value = entry.I8_max; + } + break; + case VCE_TYPE_INT16: + *entry.pInt16Value += entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt16Value > entry.I16_max) + *entry.pInt16Value = entry.I16_min; + } + else { + if (*entry.pInt16Value > entry.I16_max) + *entry.pInt16Value = entry.I16_max; + } + break; + case VCE_TYPE_INT32: + *entry.pInt32Value += entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt32Value > entry.I32_max) + *entry.pInt32Value = entry.I32_min; + } + else { + if (*entry.pInt32Value > entry.I32_max) + *entry.pInt32Value = entry.I32_max; + } + break; + case VCE_TYPE_INT64: + *entry.pInt64Value += entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*entry.pInt64Value > entry.I64_max) + *entry.pInt64Value = entry.I64_min; + } + else { + if (*entry.pInt64Value > entry.I64_max) + *entry.pInt64Value = entry.I64_max; + } + break; + case VCE_TYPE_UINT8: + *entry.pUint8Value += entry.I8_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint8Value > (uint8)entry.I8_max) + *entry.pUint8Value = entry.I8_min; + } + else { + if (*entry.pUint8Value > (uint8)entry.I8_max) + *entry.pUint8Value = entry.I8_max; + } + break; + case VCE_TYPE_UINT16: + *entry.pUint16Value += entry.I16_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint16Value > (uint16)entry.I16_max) + *entry.pUint16Value = entry.I16_min; + } + else { + if (*entry.pUint16Value > (uint16)entry.I16_max) + *entry.pUint16Value = entry.I16_max; + } + break; + case VCE_TYPE_UINT32: + *entry.pUint32Value += entry.I32_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint32Value > (uint32)entry.I32_max) + *entry.pUint32Value = entry.I32_min; + } + else { + if (*entry.pUint32Value > (uint32)entry.I32_max) + *entry.pUint32Value = entry.I32_max; + } + break; + case VCE_TYPE_UINT64: + *entry.pUint64Value += entry.I64_step; + if (entry.bAllowExceedBounds) { + if (*entry.pUint64Value > (uint64)entry.I64_max) + *entry.pUint64Value = entry.I64_min; + } + else { + if (*entry.pUint64Value > (uint64)entry.I64_max) + *entry.pUint64Value = entry.I64_max; + } + break; + case VCE_TYPE_FLOAT: + *entry.pFloatValue += entry.F_step; + if (entry.bAllowExceedBounds) { + if (*entry.pFloatValue > entry.F_max) + *entry.pFloatValue = entry.F_min; + } + else { + if (*entry.pFloatValue > entry.F_max) + *entry.pFloatValue = entry.F_max; + } + break; + case VCE_TYPE_BOOL: + if (entry.bAllowExceedBounds) + *entry.pBoolValue ^= true; + else + *entry.pBoolValue = true; + break; + case VCE_TYPE_BOOL8: + if (entry.bAllowExceedBounds) + *entry.pUint8Value = *entry.pUint8Value == false; + else + *entry.pUint8Value = true; + break; + case VCE_TYPE_BOOL16: + if (entry.bAllowExceedBounds) + *entry.pUint16Value = *entry.pUint16Value == false; + else + *entry.pUint16Value = true; + break; + case VCE_TYPE_BOOL32: + if (entry.bAllowExceedBounds) + *entry.pUint32Value = *entry.pUint32Value == false; + else + *entry.pUint32Value = true; + break; + case VCE_TYPE_FUNCTION: + entry.pCallback(); + break; + default: + return; + } +} + +void +CVarConsole::Enter() +{ + m_bIsOpen = true; +} + +void +CVarConsole::Exit() +{ + m_bIsOpen = false; +} + +void +CVarConsole::Input() +{ + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadDownJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadDown()) + { + m_nCurEntry++; + if (m_nCurEntry < m_nCountEntries) + { + if (m_nCurEntry > m_nFirstEntryOnPage + 29) + { + m_nFirstEntryOnPage = m_nCurEntry; + ++m_nCurPage; + } + } + else + { + m_nCurEntry = m_nCountEntries - 1; + } + } + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadUpJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadUp()) + { + m_nCurEntry--; + if (m_nCurEntry < m_nFirstEntryOnPage) + { + m_nFirstEntryOnPage = m_nCurEntry - 29; + --m_nCurPage; + } + if (m_nFirstEntryOnPage < 0) + { + m_nCurEntry = 0; + m_nFirstEntryOnPage = 0; + m_nCurPage = 1; + } + } + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetSquare()) + ModifyLeft(); + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetTriangle()) + ModifyRight(); + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadLeftJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadLeft()) + ModifyLeft(); + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetDPadRightJustDown() || CPad::GetPad(VAR_CONSOLE_PAD)->GetAnaloguePadRight()) + ModifyRight(); + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder2JustDown()) + { + if (m_nCurPage > 1) + { + m_nCurPage--; + m_nFirstEntryOnPage -= 30; + m_nCurEntry = m_nFirstEntryOnPage; + if (m_nFirstEntryOnPage < 0) + { + m_nFirstEntryOnPage = 0; + m_nCurEntry = m_nFirstEntryOnPage; + m_nCurPage = 1; + } + } + } + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder2JustDown()) + { + if (m_nCurPage < m_nNumPages) + { + m_nCurPage++; + m_nFirstEntryOnPage += 30; + m_nCurEntry = m_nFirstEntryOnPage; + if (m_nFirstEntryOnPage >= m_nCountEntries) + { + m_nFirstEntryOnPage -= 30; + m_nCurEntry = m_nFirstEntryOnPage; + m_nCurPage--; + } + } + } + + if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder1JustDown() && CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder1JustDown()) + Exit(); +} + +void +CVarConsole::Process() +{ + Input(); + SortPages(); + Display(); +} + +bool8 +CVarConsole::Open() +{ + return m_bIsOpen; +} + +void +CVarConsole::Check() +{ + if (Open()) + Process(); + else if (CPad::GetPad(VAR_CONSOLE_PAD)->GetRightShoulder1JustDown() && CPad::GetPad(VAR_CONSOLE_PAD)->GetLeftShoulder1JustDown()) + Enter(); +}
\ No newline at end of file diff --git a/src/render/VarConsole.h b/src/render/VarConsole.h new file mode 100644 index 00000000..5179a10d --- /dev/null +++ b/src/render/VarConsole.h @@ -0,0 +1,92 @@ +#pragma once + +enum eVarConsoleEntryType +{ + VCE_TYPE_INT8, + VCE_TYPE_INT16, + VCE_TYPE_INT32, + VCE_TYPE_INT64, + VCE_TYPE_UINT8, + VCE_TYPE_UINT16, + VCE_TYPE_UINT32, + VCE_TYPE_UINT64, + VCE_TYPE_FLOAT, + VCE_TYPE_BOOL, + VCE_TYPE_BOOL8, + VCE_TYPE_BOOL16, + VCE_TYPE_BOOL32, + VCE_TYPE_FUNCTION, +}; + +struct CVarConsoleEntry +{ + char *text; + int8 *pInt8Value; + int16 *pInt16Value; + int32 *pInt32Value; + int64 *pInt64Value; + uint8 *pUint8Value; + uint16 *pUint16Value; + uint32 *pUint32Value; + uint64 *pUint64Value; + float *pFloatValue; + bool *pBoolValue; + void (*pCallback)(void); + int8 I8_step, I8_max, I8_min; + int16 I16_step, I16_max, I16_min; + int32 I32_step, I32_max, I32_min; + int64 I64_step, I64_max, I64_min; + float F_step, F_max, F_min; + bool8 bAllowExceedBounds; + uint8 VarType; +}; + + +class CVarConsole +{ + int32 m_nCountEntries; + bool8 m_bIsOpen; + int32 m_nCurEntry; + int32 m_nFirstEntryOnPage; + int32 m_nCurPage; + int32 m_nNumPages; + CVarConsoleEntry m_aEntries[91]; +public: +#ifdef FIX_BUGS + CVarConsole() { Initialise(); } +#endif + void Initialise(); + void Add(char *text, int8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar); + void Add(char *text, int16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar); + void Add(char *text, int32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar); + void Add(char *text, int64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar); + void Add(char *text, uint8 *pVal, uint8 step, int8 min, int8 max, bool8 isVar); + void Add(char *text, uint16 *pVal, uint16 step, int16 min, int16 max, bool8 isVar); + void Add(char *text, uint32 *pVal, uint32 step, int32 min, int32 max, bool8 isVar); + void Add(char *text, uint64 *pVal, uint64 step, int64 min, int64 max, bool8 isVar); + void Add(char *text, float *pVal, float step, float min, float max, bool8 isVar); + void Add(char *text, bool *pVal, bool8 isVar); + void Add(char *text, bool8 *pVal, bool8 isVar); + void Add(char *text, bool16 *pVal, bool8 isVar); + void Add(char *text, bool32 *pVal, bool8 isVar); + void Add(char *text, void (*pVar)(void)); + + void Remove(char *text); + + void SortPages(); + void Display(); + + void ModifyLeft(); + void ModifyRight(); + + void Enter(); + void Exit(); + + void Input(); + void Process(); + + bool8 Open(); + void Check(); +}; + +extern CVarConsole VarConsole;
\ No newline at end of file diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp index b698a5b2..854653f0 100644 --- a/src/render/WaterLevel.cpp +++ b/src/render/WaterLevel.cpp @@ -58,7 +58,7 @@ int32 CWaterLevel::m_nRenderWaterLayers; RpAtomic *CWaterLevel::ms_pWavyAtomic; RpAtomic *CWaterLevel::ms_pMaskAtomic; -//"Custom" Donīt Render Water Toggle +//"Custom" Don't Render Water Toggle bool gbDontRenderWater; @@ -895,7 +895,7 @@ SectorRadius(float fSize) void CWaterLevel::RenderWater() { -//"Custom" Donīt Render Water Toggle +//"Custom" Don't Render Water Toggle #ifndef MASTER if (gbDontRenderWater) return; diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp index 52e93951..17c45fcd 100644 --- a/src/render/Weather.cpp +++ b/src/render/Weather.cpp @@ -226,15 +226,15 @@ void CWeather::Update(void) // Rain float fNewRain; if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) { - // if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s - fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f; + // if raining for >1 hour, values: 0, 0.33, switching every ~16.5s + fNewRain = (((uint16)CTimer::GetTimeInMilliseconds() >> 14) & 1) * 0.33f; if (OldWeatherType != WEATHER_RAINY && OldWeatherType != WEATHER_HURRICANE) { if (InterpolationValue < 0.4f) // if rain has just started (<24 minutes), always 0.5 fNewRain = 0.5f; else - // if rain is ongoing for >24 minutes, values: 0.25, 0.5, 0.75, 1.0, switching every ~16.5s - fNewRain = 0.25f + ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.25f; + // if rain is ongoing for >24 minutes, values: 0.25, 0.5, switching every ~16.5s + fNewRain = 0.25f + (((uint16)CTimer::GetTimeInMilliseconds() >> 14) & 1) * 0.25f; } fNewRain = Max(fNewRain, 0.5f); } diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 8a771a40..a946bacb 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -252,12 +252,15 @@ CVector vecHunterRocketPos(2.5f, 1.0f, -0.5f); CVector vecDAMAGE_ENGINE_POS_SMALL(-0.1f, -0.1f, 0.0f); CVector vecDAMAGE_ENGINE_POS_BIG(-0.5f, -0.3f, 0.0f); +#pragma optimize("", off) // a workaround for another compiler bug + void CAutomobile::ProcessControl(void) { int i; float wheelRot; CColModel *colModel; + float brake = 0.0f; if(bUsingSpecialColModel) colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; @@ -448,7 +451,7 @@ CAutomobile::ProcessControl(void) m_fBrakePedal = 1.0f; m_fGasPedal = 0.0f; } - if(CPad::GetPad(0)->WeaponJustDown()) + if(CPad::GetPad(0)->CarGunJustDown()) ActivateBomb(); break; @@ -680,7 +683,6 @@ CAutomobile::ProcessControl(void) AutoPilot.m_nCarMission == MISSION_PLANE_FLYTOCOORS) skipPhysics = true; - float brake; if(skipPhysics){ bHasContacted = false; bIsInSafePosition = false; @@ -835,11 +837,16 @@ CAutomobile::ProcessControl(void) if(bAudioChangingGear && m_fGasPedal > 0.4f && m_fBrakePedal < 0.1f && fwdSpeed > 0.15f && this == FindPlayerVehicle() && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){ - if(GetStatus() == STATUS_PLAYER && pHandling->Flags & HANDLING_IS_BUS){ + if(GetStatus() == STATUS_PLAYER && !(pHandling->Flags & HANDLING_IS_BUS)){ if(m_nBusDoorTimerEnd == 0) m_nBusDoorTimerEnd = 1000; - else if(m_nBusDoorTimerEnd > CTimer::GetTimeStepInMilliseconds()) - m_nBusDoorTimerEnd -= CTimer::GetTimeStepInMilliseconds(); + else { + uint32 timeStepInMs = CTimer::GetTimeStepInMilliseconds(); + if(m_nBusDoorTimerEnd > timeStepInMs) + m_nBusDoorTimerEnd -= timeStepInMs; + else + m_nBusDoorTimerEnd = 0; + } } if((m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[2] < 1.0f) && @@ -1676,8 +1683,8 @@ CAutomobile::ProcessControl(void) Abs(m_vecMoveSpeed.y) < 0.005f && Abs(m_vecMoveSpeed.z) < 0.005f && !(m_fDamageImpulse > 0.0f && m_pDamageEntity == FindPlayerPed()) && - (m_aSuspensionSpringRatioPrev[0] < 1.0f && m_aSuspensionSpringRatioPrev[1] < 1.0f && - m_aSuspensionSpringRatioPrev[2] < 1.0f && m_aSuspensionSpringRatioPrev[3] < 1.0f)){ + (m_aSuspensionSpringRatioPrev[0] < 1.0f || m_aSuspensionSpringRatioPrev[1] < 1.0f || + m_aSuspensionSpringRatioPrev[2] < 1.0f || m_aSuspensionSpringRatioPrev[3] < 1.0f)){ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); m_vecTurnSpeed.z = 0.0f; } @@ -1701,6 +1708,8 @@ CAutomobile::ProcessControl(void) } } +#pragma optimize("", on) + void CAutomobile::Teleport(CVector pos) { @@ -5786,7 +5795,7 @@ CAutomobile::PopBootUsingPhysics(void) case DOOR_STATUS_OK: case DOOR_STATUS_SMASHED: Damage.SetDoorStatus(DOOR_BOOT, DOOR_STATUS_SWINGING); - Doors[DOOR_BOOT].m_fAngle = -2.0f; + Doors[DOOR_BOOT].m_fAngVel = -2.0f; } void diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp index 0cfbedc1..19e95a6e 100644 --- a/src/vehicles/Bike.cpp +++ b/src/vehicles/Bike.cpp @@ -2694,7 +2694,7 @@ CBike::KnockOffRider(eWeaponType weapon, uint8 direction, CPed *ped, bool bGetBa switch(direction){ case 0: anim = ANIM_KO_SKID_BACK; break; case 1: anim = ANIM_KD_RIGHT; break; - case 2: anim = ANIM_KO_SKID_FRONT; break; + case 2: anim = ANIM_BIKE_FALL_R; break; case 3: anim = ANIM_KD_LEFT; break; } if(m_nWheelsOnGround == 0) diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp index b8c8566c..611ddcc9 100644 --- a/src/vehicles/HandlingMgr.cpp +++ b/src/vehicles/HandlingMgr.cpp @@ -300,7 +300,7 @@ cHandlingDataMgr::LoadHandlingData(void) case 11: handling->fTractionBias = atof(word); break; case 12: handling->Transmission.nNumberOfGears = atoi(word); break; case 13: handling->Transmission.fMaxVelocity = atof(word); break; - case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4f; break; + case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4; break; case 15: handling->Transmission.nDriveType = word[0]; break; case 16: handling->Transmission.nEngineType = word[0]; break; case 17: handling->fBrakeDeceleration = atof(word); break; @@ -362,26 +362,32 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling) handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass; handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->fMass; - // What the hell is going on here? - specificVolume = handling->Dimension.x*handling->Dimension.z*0.5f / handling->fMass; // ? + // Don't quite understand this. What seems to be going on is that + // we calculate a drag (air resistance) deceleration for a given velocity and + // find the intersection between that and the max engine acceleration. + // at that point the car cannot accelerate any further and we've found the max velocity. a = 0.0f; b = 100.0f; velocity = handling->Transmission.fMaxVelocity; while(a < b && velocity > 0.0f){ velocity -= 0.01f; + // what's the 1/6? a = handling->Transmission.fEngineAcceleration/6.0f; - b = -velocity * (1.0f/(specificVolume * sq(velocity) + 1.0f) - 1.0f); + // no density or drag coefficient here... + float a_drag = 0.5f*SQR(velocity) * handling->Dimension.x*handling->Dimension.z / handling->fMass; + // can't make sense of this... maybe v - v/(drag + 1) ? but that doesn't make so much sense either + b = -velocity * (1.0f/(a_drag + 1.0f) - 1.0f); } if(handling->nIdentifier == HANDLING_RCBANDIT){ - handling->Transmission.fUnkMaxVelocity = handling->Transmission.fMaxVelocity; + handling->Transmission.fMaxCruiseVelocity = handling->Transmission.fMaxVelocity; handling->Transmission.fMaxReverseVelocity = -handling->Transmission.fMaxVelocity; }else if(handling->nIdentifier >= HANDLING_BIKE && handling->nIdentifier <= HANDLING_FREEWAY){ - handling->Transmission.fUnkMaxVelocity = velocity; + handling->Transmission.fMaxCruiseVelocity = velocity; handling->Transmission.fMaxVelocity = velocity * 1.2f; handling->Transmission.fMaxReverseVelocity = -0.05f; }else{ - handling->Transmission.fUnkMaxVelocity = velocity; + handling->Transmission.fMaxCruiseVelocity = velocity; handling->Transmission.fMaxVelocity = velocity * 1.2f; handling->Transmission.fMaxReverseVelocity = -0.2f; } diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp index cc994ac6..b3e1af7d 100644 --- a/src/vehicles/Transmission.cpp +++ b/src/vehicles/Transmission.cpp @@ -123,7 +123,7 @@ cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, fl else fCheat = 1.0f; float targetVelocity = Gears[gear].fMaxVelocity*speedMul*fCheat; - float accel = fEngineAcceleration*accelMul * (targetVelocity - fVelocity)/Abs(targetVelocity); + float accel = (targetVelocity - fVelocity) * (fEngineAcceleration*accelMul) / Abs(targetVelocity); if(Abs(fVelocity) < Abs(Gears[gear].fMaxVelocity*fCheat)) fAcceleration = gasPedal * accel * CTimer::GetTimeStep(); else diff --git a/src/vehicles/Transmission.h b/src/vehicles/Transmission.h index 8eeef1e8..a3d15513 100644 --- a/src/vehicles/Transmission.h +++ b/src/vehicles/Transmission.h @@ -18,7 +18,7 @@ public: uint8 Flags; float fEngineAcceleration; float fMaxVelocity; - float fUnkMaxVelocity; + float fMaxCruiseVelocity; float fMaxReverseVelocity; float fCurVelocity; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 325eb160..1849fd7f 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -48,6 +48,9 @@ bool CVehicle::bAllTaxisHaveNitro; bool CVehicle::m_bDisableMouseSteering = true; bool CVehicle::bDisableRemoteDetonation; bool CVehicle::bDisableRemoteDetonationOnContact; +#ifndef MASTER +bool CVehicle::m_bDisplayHandlingInfo; +#endif void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); } void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); } @@ -146,6 +149,7 @@ CVehicle::CVehicle(uint8 CreatedBy) m_nAlarmState = 0; m_nDoorLock = CARLOCK_UNLOCKED; m_nLastWeaponDamage = -1; + m_pLastDamageEntity = nil; m_fMapObjectHeightAhead = m_fMapObjectHeightBehind = 0.0f; m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this); if(m_audioEntityId >= 0) @@ -836,11 +840,11 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon if(IsBike()) brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f); else if(pHandling->fMass < 500.0f) - brake = mod_HandlingManager.fWheelFriction / m_fMass; + brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass; else if(GetModelIndex() == MI_RCBANDIT) - brake = 0.2f * mod_HandlingManager.fWheelFriction / m_fMass; + brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass; else - brake = mod_HandlingManager.fWheelFriction / m_fMass; + brake = mod_HandlingManager.fWheelFriction / pHandling->fMass; #ifdef FIX_BUGS brake *= CTimer::GetTimeStepFix(); #endif @@ -1232,7 +1236,7 @@ CVehicle::InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage if (m_randomSeed < DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE) { CCarCtrl::SwitchVehicleToRealPhysics(this); AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; - AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fUnkMaxVelocity; + AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fMaxCruiseVelocity; SetStatus(STATUS_PHYSICS); } } @@ -1873,7 +1877,7 @@ CVehicle::AddPassenger(CPed *passenger) int i; if(IsBike()) - ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); + ApplyTurnForce(-0.02f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); else ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, passenger->GetPosition().x - GetPosition().x, @@ -1896,7 +1900,7 @@ CVehicle::AddPassenger(CPed *passenger, uint8 n) return AddPassenger(passenger); if(IsBike()) - ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); + ApplyTurnForce(-0.02f*passenger->m_fMass * GetUp(), -0.1f*GetForward()); else ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass, passenger->GetPosition().x - GetPosition().x, diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index a42106cc..7388bfab 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -402,6 +402,9 @@ public: static bool m_bDisableMouseSteering; static bool bDisableRemoteDetonation; static bool bDisableRemoteDetonationOnContact; +#ifndef MASTER + static bool m_bDisplayHandlingInfo; +#endif }; void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle); |