Merge branch 'miami' of https://github.com/GTAmodding/re3 into VCSanim

This commit is contained in:
erorcun 2021-02-08 13:23:19 +03:00
commit b464bb7fd4
111 changed files with 1956 additions and 779 deletions

View file

@ -8846,7 +8846,7 @@ cAudioManager::ProcessFrontEnd()
break;
case SOUND_PICKUP_BONUS:
case SOUND_FRONTEND_MENU_STARTING:
case SOUND_HUD_SOUND:
case SOUND_HUD:
stereo = true;
m_sQueueSample.m_nSampleIndex = SFX_INFO_LEFT;
center = true;
@ -8882,11 +8882,11 @@ cAudioManager::ProcessFrontEnd()
case SOUND_CLOCK_TICK:
m_sQueueSample.m_nSampleIndex = SFX_TIMER;
break;
case SOUND_FRONTEND_NO_RADIO:
case SOUND_FRONTEND_RADIO_CHANGE:
case SOUND_FRONTEND_RADIO_TURN_OFF:
case SOUND_FRONTEND_RADIO_TURN_ON:
m_sQueueSample.m_nSampleIndex = SFX_RADIO_CLICK;
break;
case SOUND_FRONTEND_RADIO_CHANGE_2:
case SOUND_FRONTEND_HURRICANE:
m_sQueueSample.m_nSampleIndex = SFX_HURRICANE_MA;
break;
case SOUND_BULLETTRACE_1:
@ -8937,9 +8937,9 @@ cAudioManager::ProcessFrontEnd()
sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
if (sample == SOUND_FRONTEND_NO_RADIO)
if (sample == SOUND_FRONTEND_RADIO_TURN_OFF)
m_sQueueSample.m_nFrequency = 28509;
else if (sample == SOUND_FRONTEND_RADIO_CHANGE)
else if (sample == SOUND_FRONTEND_RADIO_TURN_ON)
m_sQueueSample.m_nFrequency = 32000;
else if (sample == SOUND_BULLETTRACE_1 || sample == SOUND_BULLETTRACE_2) {
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);

View file

@ -21,6 +21,10 @@
#include "DMAudio.h"
#include "GenericGameStorage.h"
#if !defined FIX_BUGS && (defined RADIO_SCROLL_TO_PREV_STATION || defined RADIO_OFF_TEXT)
static_assert(false, "R*'s radio implementation is quite buggy, RADIO_SCROLL_TO_PREV_STATION and RADIO_OFF_TEXT won't work without FIX_BUGS");
#endif
cMusicManager MusicManager;
int32 gNumRetunePresses;
int32 gRetuneCounter;
@ -52,7 +56,7 @@ cMusicManager::cMusicManager()
m_nPlayingTrack = NO_TRACK;
m_nUpcomingMusicMode = MUSICMODE_DISABLED;
m_nMusicMode = MUSICMODE_DISABLED;
field_2 = false;
m_bSetNextStation = false;
for (int i = 0; i < NUM_RADIOS; i++)
aListenTimeArray[i] = 0.0f;
@ -71,27 +75,27 @@ cMusicManager::ResetMusicAfterReload()
float afRadioTime[NUM_RADIOS];
m_bRadioSetByScript = false;
m_nRadioStation = WILDSTYLE;
m_nRadioStationScript = WILDSTYLE;
m_nRadioPosition = -1;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
field_2 = false;
m_bSetNextStation = false;
RadioStaticTimer = 0;
gNumRetunePresses = 0;
gRetuneCounter = 0;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
field_398E = false;
field_398F = false;
m_nStreamedTrack = NO_TRACK;
field_3994 = false;
field_3995 = false;
field_3996 = false;
field_3997 = false;
m_FrontendLoopFlag = false;
m_bTrackChangeStarted = false;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_bGameplayAllowsRadio = false;
m_bRadioStreamReady = false;
nFramesSinceCutsceneEnded = -1;
field_3999 = false;
field_399A = false;
field_399C = false;
m_bUserResumedGame = false;
m_bMusicModeChangeStarted = false;
m_bEarlyFrontendTrack = false;
m_nVolumeLatency = 0;
m_nCurrentVolume = 0;
m_nMaxVolume = 0;
@ -108,7 +112,7 @@ cMusicManager::ResetMusicAfterReload()
for (int i = 0; i < NUM_RADIOS; i++) {
aListenTimeArray[i] = afRadioTime[i];
uint32 trackPos = GetSavedRadioStationPosition(i);
int32 trackPos = GetSavedRadioStationPosition(i);
if (trackPos != -1) {
if (trackPos > m_aTracks[i].m_nLength) {
debug("Radio Track %d saved position is %d, Length is only %d\n", i, trackPos, m_aTracks[i].m_nLength);
@ -179,7 +183,7 @@ cMusicManager::Initialise()
m_bResetTimers = false;
m_nResetTime = 0;
m_bRadioSetByScript = false;
m_nRadioStation = WILDSTYLE;
m_nRadioStationScript = WILDSTYLE;
m_nRadioPosition = -1;
m_nRadioInCar = NO_TRACK;
gRetuneCounter = 0;
@ -188,18 +192,18 @@ cMusicManager::Initialise()
m_nPlayingTrack = NO_TRACK;
m_nUpcomingMusicMode = MUSICMODE_DISABLED;
m_nMusicMode = MUSICMODE_DISABLED;
field_398E = false;
field_398F = false;
m_nStreamedTrack = NO_TRACK;
field_3994 = false;
field_3995 = false;
field_3996 = false;
field_3997 = false;
m_FrontendLoopFlag = false;
m_bTrackChangeStarted = false;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_bGameplayAllowsRadio = false;
m_bRadioStreamReady = false;
nFramesSinceCutsceneEnded = -1;
field_3999 = false;
field_399A = false;
m_bUserResumedGame = false;
m_bMusicModeChangeStarted = false;
m_nMusicModeToBeSet = MUSICMODE_DISABLED;
field_399C = false;
m_bEarlyFrontendTrack = false;
m_nVolumeLatency = 0;
m_nCurrentVolume = 0;
m_nMaxVolume = 0;
@ -227,7 +231,7 @@ cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos)
station = STREAMED_SOUND_CITY_AMBIENT;
if (station <= STREAMED_SOUND_RADIO_POLICE) {
m_bRadioSetByScript = true;
m_nRadioStation = station;
m_nRadioStationScript = station;
m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
}
}
@ -292,7 +296,7 @@ cMusicManager::SetRadioInCar(uint32 station)
void
cMusicManager::RecordRadioStats()
{
if (m_nPlayingTrack < STREAMED_SOUND_CITY_AMBIENT) {
if (m_nPlayingTrack < NUM_RADIOS) {
double time /*Rusty*/ = CTimer::GetTimeInMillisecondsPauseMode();
if (time > m_nLastTrackServiceTime)
aListenTimeArray[m_nPlayingTrack] += time - m_nLastTrackServiceTime;
@ -321,11 +325,11 @@ cMusicManager::ChangeMusicMode(uint8 mode)
while (SampleManager.IsStreamPlaying(0))
SampleManager.StopStreamedFile(0);
m_nMusicMode = m_nUpcomingMusicMode;
field_399A = false;
field_398F = false;
m_nStreamedTrack = NO_TRACK;
field_3994 = false;
field_3995 = false;
m_bMusicModeChangeStarted = false;
m_bTrackChangeStarted = false;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_nPlayingTrack = NO_TRACK;
m_nFrontendTrack = NO_TRACK;
m_bAnnouncementInProgress = false;
@ -356,7 +360,7 @@ cMusicManager::Service()
if (!m_bIsInitialised || m_bDisabled) return;
if (!field_399A)
if (!m_bMusicModeChangeStarted)
m_nMusicModeToBeSet = m_nUpcomingMusicMode;
if (m_nMusicModeToBeSet == m_nMusicMode) {
if (!AudioManager.m_nUserPause || AudioManager.m_nPreviousUserPause || m_nMusicMode != MUSICMODE_FRONTEND)
@ -371,13 +375,13 @@ cMusicManager::Service()
else
m_nMusicMode = MUSICMODE_DISABLED;
} else {
field_399A = true;
if (!field_3999 && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause)
field_3999 = true;
m_bMusicModeChangeStarted = true;
if (!m_bUserResumedGame && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause)
m_bUserResumedGame = true;
if (AudioManager.m_FrameCounter % 4 == 0) {
gNumRetunePresses = 0;
gRetuneCounter = 0;
field_2 = false;
m_bSetNextStation = false;
if (SampleManager.IsStreamPlaying(0)) {
if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded)
{
@ -390,14 +394,14 @@ cMusicManager::Service()
} else {
bRadioStatsRecorded = false;
m_nMusicMode = m_nMusicModeToBeSet;
field_399A = false;
field_398F = false;
m_nStreamedTrack = NO_TRACK;
field_3994 = false;
field_3995 = false;
m_bMusicModeChangeStarted = false;
m_bTrackChangeStarted = false;
m_nNextTrack = NO_TRACK;
m_nNextLoopFlag = false;
m_bVerifyNextTrackStartedToPlay = false;
m_nPlayingTrack = NO_TRACK;
if (field_399C)
field_399C = false;
if (m_bEarlyFrontendTrack)
m_bEarlyFrontendTrack = false;
else
m_nFrontendTrack = NO_TRACK;
}
@ -417,19 +421,19 @@ cMusicManager::ServiceFrontEndMode()
g_bAnnouncementReadPosAlready = false;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_nStreamedTrack = NO_TRACK;
m_nNextTrack = NO_TRACK;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
}
if (AudioManager.m_FrameCounter % 4 != 0) return;
if (!field_398F && !field_3995) {
m_nStreamedTrack = m_nFrontendTrack;
field_3994 = field_398E;
if (!m_bTrackChangeStarted && !m_bVerifyNextTrackStartedToPlay) {
m_nNextTrack = m_nFrontendTrack;
m_nNextLoopFlag = m_FrontendLoopFlag;
}
if (m_nStreamedTrack == m_nPlayingTrack) {
if (m_nNextTrack == m_nPlayingTrack) {
if (SampleManager.IsStreamPlaying(0)) {
if (m_nVolumeLatency > 0) m_nVolumeLatency--;
else {
@ -444,25 +448,25 @@ cMusicManager::ServiceFrontEndMode()
ChangeMusicMode(MUSICMODE_GAME);
}
} else {
field_398F = true;
if (field_3995 || !SampleManager.IsStreamPlaying(0)) {
m_bTrackChangeStarted = true;
if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying(0)) {
bRadioStatsRecorded = false;
if (SampleManager.IsStreamPlaying(0) || m_nStreamedTrack == NO_TRACK) {
m_nPlayingTrack = m_nStreamedTrack;
field_3995 = false;
field_398F = false;
if (SampleManager.IsStreamPlaying(0) || m_nNextTrack == NO_TRACK) {
m_nPlayingTrack = m_nNextTrack;
m_bVerifyNextTrackStartedToPlay = false;
m_bTrackChangeStarted = false;
} else {
uint32 trackStartPos = (m_nStreamedTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nStreamedTrack);
if (m_nStreamedTrack != NO_TRACK) {
SampleManager.SetStreamedFileLoopFlag(field_3994, 0);
SampleManager.StartStreamedFile(m_nStreamedTrack, trackStartPos, 0);
uint32 trackStartPos = (m_nNextTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nNextTrack);
if (m_nNextTrack != NO_TRACK) {
SampleManager.SetStreamedFileLoopFlag(m_nNextLoopFlag, 0);
SampleManager.StartStreamedFile(m_nNextTrack, trackStartPos, 0);
m_nVolumeLatency = 3;
m_nCurrentVolume = 0;
m_nMaxVolume = 100;
SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
if (m_nStreamedTrack < STREAMED_SOUND_CITY_AMBIENT)
if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT)
m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
field_3995 = true;
m_bVerifyNextTrackStartedToPlay = true;
}
}
} else {
@ -483,8 +487,8 @@ cMusicManager::ServiceGameMode()
{
CPed *ped = FindPlayerPed();
CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
field_3997 = field_3996;
field_3996 = false;
m_bRadioStreamReady = m_bGameplayAllowsRadio;
m_bGameplayAllowsRadio = false;
switch (CGame::currArea)
{
@ -495,29 +499,28 @@ cMusicManager::ServiceGameMode()
case AREA_BLOOD:
case AREA_OVALRING:
case AREA_MALIBU_CLUB:
field_3996 = false;
m_bGameplayAllowsRadio = false;
break;
default:
if (SampleManager.GetMusicVolume()) {
if (PlayerInCar())
field_3996 = true;
m_bGameplayAllowsRadio = true;
} else
field_3996 = false;
m_bGameplayAllowsRadio = false;
break;
}
if (!field_3996) {
if (!m_bGameplayAllowsRadio) {
nFramesSinceCutsceneEnded = -1;
gNumRetunePresses = 0;
gRetuneCounter = 0;
field_2 = false;
m_bSetNextStation = false;
} else if (ped) {
if(!ped->DyingOrDead()) {
if(!ped->DyingOrDead() && vehicle) {
#ifdef GTA_PC
if (SampleManager.IsMP3RadioChannelAvailable()
&& vehicle->m_nRadioStation < USERTRACK
&& ControlsManager.GetIsKeyboardKeyJustDown(rsF9)
&& vehicle)
&& ControlsManager.GetIsKeyboardKeyJustDown(rsF9))
{
if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
gNumRetunePresses = 0;
@ -532,7 +535,7 @@ cMusicManager::ServiceGameMode()
}
}
#endif
if (CPad::GetPad(0)->ChangeStationJustDown() && vehicle)
if (CPad::GetPad(0)->ChangeStationJustDown())
{
if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
gNumRetunePresses++;
@ -540,147 +543,183 @@ cMusicManager::ServiceGameMode()
RadioStaticCounter = 0;
}
}
#ifdef RADIO_SCROLL_TO_PREV_STATION
else if(CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
if(!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
int scrollNext = ControlsManager.GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, MOUSE);
int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON
: scrollNext == rsMOUSEWHEELDOWNBUTTON ? rsMOUSEWHEELUPBUTTON : -1;
if(scrollPrev != -1 && !ControlsManager.IsAnyVehicleActionAssignedToMouseKey(scrollPrev)) {
gNumRetunePresses--;
gRetuneCounter = 20;
RadioStaticCounter = 0;
int track = gNumRetunePresses + vehicle->m_nRadioStation;
while(track < 0) track += NUM_RADIOS + 1;
while(track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1;
if(!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK) gNumRetunePresses--;
}
}
}
#endif
}
}
if (field_3999)
if (m_bUserResumedGame)
{
field_3997 = false;
field_3999 = false;
m_bRadioStreamReady = false;
m_bUserResumedGame = false;
}
if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK)
field_3997 = false;
m_bRadioStreamReady = false;
if (field_3996)
if (m_bGameplayAllowsRadio)
{
if (field_3997)
if (!m_bRadioStreamReady)
{
if (m_nAnnouncement < NO_TRACK) {
if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) {
if (m_bAnnouncementInProgress) {
field_2 = false;
gNumRetunePresses = 0;
gRetuneCounter = 0;
return;
}
if(m_nAnnouncement == NO_TRACK) {
m_nStreamedTrack = NO_TRACK;
m_nFrontendTrack = GetCarTuning();
field_2 = false;
gRetuneCounter = 0;
gNumRetunePresses = 0;
}
}
}
if (!m_bAnnouncementInProgress
&& m_nAnnouncement == NO_TRACK
&& m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER
&& !SampleManager.IsStreamPlaying(0))
{
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0);
}
if (!m_bRadioSetByScript)
{
if (gNumRetunePresses != 0)
{
if (--gRetuneCounter == 0)
{
field_2 = true;
gRetuneCounter = 0;
}
}
if (gRetuneCounter)
{
int32 station = gNumRetunePresses + vehicle->m_nRadioStation;
while (station >= RADIO_OFF) station -= RADIO_OFF;
if (!DMAudio.IsMP3RadioChannelAvailable() && station == USERTRACK)
{
++gNumRetunePresses;
station = NUM_RADIOS;
}
if (station == NUM_RADIOS)
{
if (gRetuneCounter == NUM_RADIOS + 9)
{
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_NO_RADIO, 0.0f);
RadioStaticCounter = 5;
}
}
else
{
if (station == WILDSTYLE && gRetuneCounter == NUM_RADIOS + 9)
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f);
AudioManager.DoPoliceRadioCrackle();
}
}
if (RadioStaticCounter < 2 && CTimer::GetTimeInMilliseconds() > RadioStaticTimer + 800)
{
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_RADIO_CHANGE, 0.0f);
RadioStaticCounter++;
RadioStaticTimer = CTimer::GetTimeInMilliseconds();
}
if (field_2)
m_nFrontendTrack = GetNextCarTuning();
if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
SetUpCorrectAmbienceTrack();
ServiceTrack(vehicle, ped);
if (field_2)
field_2 = false;
if(vehicle == nil) {
m_nFrontendTrack = STREAMED_SOUND_RADIO_WAVE; // huh?
return;
}
if (UsesPoliceRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
else if (UsesTaxiRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
else {
m_nFrontendTrack = m_nRadioStation;
vehicle->m_nRadioStation = m_nRadioStation;
if(m_bRadioSetByScript) {
if(UsesPoliceRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
else if(UsesTaxiRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
else {
m_nFrontendTrack = m_nRadioStationScript;
vehicle->m_nRadioStation = m_nRadioStationScript;
}
if(m_nRadioPosition != -1) {
m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
m_bRadioSetByScript = false;
return;
}
if (m_nRadioPosition != -1) {
m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
// This starts the radio when you enter the car.
m_nFrontendTrack = GetCarTuning();
return;
}
if (m_nAnnouncement < NO_TRACK) {
if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) {
if (m_bAnnouncementInProgress) {
m_bSetNextStation = false;
gNumRetunePresses = 0;
gRetuneCounter = 0;
return;
}
if(m_nAnnouncement == NO_TRACK) {
m_nNextTrack = NO_TRACK;
m_nFrontendTrack = GetCarTuning();
m_bSetNextStation = false;
gRetuneCounter = 0;
gNumRetunePresses = 0;
}
}
}
if (!m_bAnnouncementInProgress
&& m_nAnnouncement == NO_TRACK
&& m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER
&& !SampleManager.IsStreamPlaying(0))
{
SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0);
}
gRetuneCounter = 0;
gNumRetunePresses = 0;
field_2 = false;
m_bRadioSetByScript = false;
if (!m_bRadioSetByScript)
{
// Because when you switch radio back and forth, gNumRetunePresses will be 0 but gRetuneCounter won't.
#ifdef RADIO_SCROLL_TO_PREV_STATION
if(gRetuneCounter != 0) {
if(gRetuneCounter > 1)
gRetuneCounter--;
else if(gRetuneCounter == 1) {
m_bSetNextStation = true;
gRetuneCounter = 0;
}
}
#else
if (gNumRetunePresses != 0)
{
if (--gRetuneCounter == 0)
{
m_bSetNextStation = true;
gRetuneCounter = 0;
}
}
#endif
if (gRetuneCounter)
{
int32 station = gNumRetunePresses + vehicle->m_nRadioStation;
#ifdef RADIO_SCROLL_TO_PREV_STATION
while (station < 0) station += NUM_RADIOS + 1;
#endif
while (station >= NUM_RADIOS + 1) station -= NUM_RADIOS + 1;
// Scrolling back won't hit here, so increasing isn't problem
if (!DMAudio.IsMP3RadioChannelAvailable() && station == USERTRACK)
{
++gNumRetunePresses;
station = RADIO_OFF;
}
if (station == RADIO_OFF)
{
if (gRetuneCounter == 19) // One less then what switching radio sets, so runs right after turning off radio
{
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_OFF, 0.0f);
RadioStaticCounter = 5;
}
}
else
{
#ifdef RADIO_SCROLL_TO_PREV_STATION
if (vehicle->m_nRadioStation == RADIO_OFF && gRetuneCounter == 19) // Right after turning on the radio
#else
if (station == 0 && gRetuneCounter == 19) // Right after turning on the radio
#endif
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_TURN_ON, 0.0f);
AudioManager.DoPoliceRadioCrackle();
}
}
if (RadioStaticCounter < 2 && CTimer::GetTimeInMilliseconds() > RadioStaticTimer + 800)
{
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_RADIO_CHANGE, 0.0f);
RadioStaticCounter++;
RadioStaticTimer = CTimer::GetTimeInMilliseconds();
}
if (m_bSetNextStation)
m_nFrontendTrack = GetNextCarTuning();
if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
SetUpCorrectAmbienceTrack();
ServiceTrack(vehicle, ped);
if (field_2)
field_2 = false;
if (m_bSetNextStation)
m_bSetNextStation = false;
return;
}
if (vehicle == nil)
{
m_nFrontendTrack = STREAMED_SOUND_RADIO_WAVE; // huh?
return;
}
if (m_bRadioSetByScript)
{
if (UsesPoliceRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
else if (UsesTaxiRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
else {
m_nFrontendTrack = m_nRadioStation;
vehicle->m_nRadioStation = m_nRadioStation;
}
if (m_nRadioPosition != -1)
{
m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
m_bRadioSetByScript = false;
return;
if (UsesPoliceRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
else if (UsesTaxiRadio(vehicle))
m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
else {
m_nFrontendTrack = m_nRadioStationScript;
vehicle->m_nRadioStation = m_nRadioStationScript;
}
m_nFrontendTrack = GetCarTuning();
if (m_nRadioPosition != -1) {
m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
gRetuneCounter = 0;
gNumRetunePresses = 0;
m_bSetNextStation = false;
m_bRadioSetByScript = false;
if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
SetUpCorrectAmbienceTrack();
ServiceTrack(vehicle, ped);
if (m_bSetNextStation)
m_bSetNextStation = false;
return;
}
@ -692,7 +731,7 @@ cMusicManager::ServiceGameMode()
g_bAnnouncementReadPosAlready = false;
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
m_nStreamedTrack = NO_TRACK;
m_nNextTrack = NO_TRACK;
m_nFrontendTrack = NO_TRACK;
m_nPlayingTrack = NO_TRACK;
}
@ -834,7 +873,7 @@ cMusicManager::ServiceAnnouncement()
{
if (m_bAnnouncementInProgress) {
if (SampleManager.IsStreamPlaying(0))
m_nPlayingTrack = m_nStreamedTrack;
m_nPlayingTrack = m_nNextTrack;
else if (m_nPlayingTrack != NO_TRACK) {
m_nAnnouncement = NO_TRACK;
m_bAnnouncementInProgress = false;
@ -852,9 +891,9 @@ cMusicManager::ServiceAnnouncement()
} else {
g_bAnnouncementReadPosAlready = false;
m_nPlayingTrack = NO_TRACK;
m_nStreamedTrack = m_nAnnouncement;
SampleManager.SetStreamedFileLoopFlag(0, false);
SampleManager.StartStreamedFile(m_nStreamedTrack, 0, 0);
m_nNextTrack = m_nAnnouncement;
SampleManager.SetStreamedFileLoopFlag(0, 0);
SampleManager.StartStreamedFile(m_nNextTrack, 0, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 0, 0);
m_bAnnouncementInProgress = true;
}
@ -868,9 +907,9 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
static bool bRadioStatsRecorded = false;
static bool bRadioStatsRecorded2 = false;
uint8 volume;
if (!field_398F)
m_nStreamedTrack = m_nFrontendTrack;
if (gRetuneCounter != 0 || field_2) {
if (!m_bTrackChangeStarted)
m_nNextTrack = m_nFrontendTrack;
if (gRetuneCounter != 0 || m_bSetNextStation) {
if (SampleManager.IsStreamPlaying(0)) {
if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
@ -889,28 +928,35 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
m_nPlayingTrack = NO_TRACK;
}
if (m_nStreamedTrack != m_nPlayingTrack)
if (m_nNextTrack != m_nPlayingTrack)
{
field_398F = true;
m_bTrackChangeStarted = true;
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
if (!(AudioManager.m_FrameCounter & 1)) {
if (field_3995 || !SampleManager.IsStreamPlaying(0)) {
if (m_bVerifyNextTrackStartedToPlay || !SampleManager.IsStreamPlaying(0)) {
bRadioStatsRecorded2 = false;
if (SampleManager.IsStreamPlaying(0)) {
m_nPlayingTrack = m_nStreamedTrack;
field_3995 = false;
field_398F = false;
m_nPlayingTrack = m_nNextTrack;
m_bVerifyNextTrackStartedToPlay = false;
m_bTrackChangeStarted = false;
if (veh) {
if (veh->m_nRadioStation < STREAMED_SOUND_CITY_AMBIENT || veh->m_nRadioStation > STREAMED_SOUND_AMBSIL_AMBIENT)
#ifdef FIX_BUGS
if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
veh->m_nRadioStation = RADIO_OFF;
else if (m_nPlayingTrack < STREAMED_SOUND_CITY_AMBIENT)
veh->m_nRadioStation = m_nPlayingTrack;
#else
if (veh->m_nRadioStation >= STREAMED_SOUND_CITY_AMBIENT && veh->m_nRadioStation <= STREAMED_SOUND_AMBSIL_AMBIENT)
veh->m_nRadioStation = RADIO_OFF;
else
veh->m_nRadioStation = STREAMED_SOUND_CITY_AMBIENT;
veh->m_nRadioStation = m_nPlayingTrack;
#endif
}
} else {
uint32 pos = GetTrackStartPos(m_nStreamedTrack);
if (m_nStreamedTrack != NO_TRACK) {
uint32 pos = GetTrackStartPos(m_nNextTrack);
if (m_nNextTrack != NO_TRACK) {
SampleManager.SetStreamedFileLoopFlag(1, 0);
SampleManager.StartStreamedFile(m_nStreamedTrack, pos, 0);
SampleManager.StartStreamedFile(m_nNextTrack, pos, 0);
if (m_nFrontendTrack < STREAMED_SOUND_CITY_AMBIENT || m_nFrontendTrack > STREAMED_SOUND_AMBSIL_AMBIENT)
{
m_nVolumeLatency = 10;
@ -923,9 +969,9 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
ComputeAmbienceVol(true, volume);
SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
}
if (m_nStreamedTrack < STREAMED_SOUND_CITY_AMBIENT)
if (m_nNextTrack < STREAMED_SOUND_CITY_AMBIENT)
m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
field_3995 = true;
m_bVerifyNextTrackStartedToPlay = true;
}
}
} else {
@ -939,8 +985,8 @@ cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
RecordRadioStats();
if (m_nPlayingTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
{
if (m_nStreamedTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nStreamedTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE_2, 0.0);
if (m_nNextTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nNextTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_HURRICANE, 0.0);
}
}
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
@ -1050,14 +1096,14 @@ cMusicManager::StopCutSceneMusic(void)
}
void
cMusicManager::PlayFrontEndTrack(uint32 track, uint8 bPlayInFrontend)
cMusicManager::PlayFrontEndTrack(uint32 track, uint8 loopFlag)
{
if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND))
{
m_nFrontendTrack = track;
field_398E = bPlayInFrontend;
m_FrontendLoopFlag = loopFlag;
if (m_nMusicMode != MUSICMODE_FRONTEND)
field_399C = true;
m_bEarlyFrontendTrack = true;
}
}
@ -1083,10 +1129,18 @@ cMusicManager::GetNextCarTuning()
if (UsesPoliceRadio(veh)) return STREAMED_SOUND_RADIO_POLICE;
if (UsesTaxiRadio(veh)) return STREAMED_SOUND_RADIO_TAXI;
if (gNumRetunePresses != 0) {
#ifdef RADIO_SCROLL_TO_PREV_STATION
// m_nRadioStation is unsigned, so...
int station = veh->m_nRadioStation + gNumRetunePresses;
while(station < 0) station += NUM_RADIOS + 1;
while(station >= NUM_RADIOS + 1) station -= NUM_RADIOS + 1;
veh->m_nRadioStation = station;
#else
veh->m_nRadioStation += gNumRetunePresses;
while (veh->m_nRadioStation >= RADIO_OFF)
veh->m_nRadioStation -= RADIO_OFF;
DMAudio.IsMP3RadioChannelAvailable(); // woof, just call and do nothing =P
while(veh->m_nRadioStation >= NUM_RADIOS + 1)
veh->m_nRadioStation -= NUM_RADIOS + 1;
#endif
DMAudio.IsMP3RadioChannelAvailable(); // woof, just call and do nothing =P they manipulate gNumRetunePresses on DisplayRadioStationName in this case
gNumRetunePresses = 0;
}
return veh->m_nRadioStation;
@ -1129,7 +1183,7 @@ cMusicManager::GetTrackStartPos(uint32 track)
uint32
cMusicManager::GetRadioPosition(uint32 station)
{
if (station < STREAMED_SOUND_CITY_AMBIENT)
if (station < NUM_RADIOS)
return GetTrackStartPos(station);
return 0;
}
@ -1158,7 +1212,7 @@ cMusicManager::SetMalibuClubTrackPos(uint8 scriptObject)
{
if (!IsInitialised())
m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = 8640;
if (m_nStreamedTrack != STREAMED_SOUND_MALIBU_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_MALIBU_AMBIENT) {
if (m_nNextTrack != STREAMED_SOUND_MALIBU_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_MALIBU_AMBIENT) {
switch (scriptObject)
{
case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1:
@ -1180,7 +1234,7 @@ cMusicManager::SetStripClubTrackPos(uint8 scriptObject)
{
if (!IsInitialised())
m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = 0;
if (m_nStreamedTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT)
if (m_nNextTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT && m_nPlayingTrack != STREAMED_SOUND_STRIPCLUB_AMBIENT)
{
switch (scriptObject)
{
@ -1201,7 +1255,7 @@ cMusicManager::SetStripClubTrackPos(uint8 scriptObject)
void
cMusicManager::DisplayRadioStationName()
{
int8 gStreamedSound;
uint8 gStreamedSound;
static wchar *pCurrentStation = nil;
static uint8 cDisplay = 0;
@ -1211,20 +1265,28 @@ cMusicManager::DisplayRadioStationName()
if (vehicle)
{
uint8 track;
int8 track;
gStreamedSound = vehicle->m_nRadioStation;
if (gStreamedSound >= STREAMED_SOUND_CITY_AMBIENT && gStreamedSound <= STREAMED_SOUND_AMBSIL_AMBIENT)
gStreamedSound = STREAMED_SOUND_CITY_AMBIENT;
gStreamedSound = RADIO_OFF;
if (gNumRetunePresses != 0)
{
track = gNumRetunePresses + gStreamedSound;
while (track >= RADIO_OFF) track -= RADIO_OFF;
#ifdef RADIO_SCROLL_TO_PREV_STATION
while (track < 0) track += NUM_RADIOS + 1;
#endif
while (track >= NUM_RADIOS + 1) track -= NUM_RADIOS + 1;
// We already handle this condition while scrolling back, on key press. No need to change this.
if (!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK)
gNumRetunePresses++;
}
else
#ifdef FIX_BUGS
track = GetCarTuning(); // gStreamedSound or veh->m_nRadioStation would also work, but these don't cover police/taxi radios
#else
track = m_nFrontendTrack;
#endif
wchar* string = nil;
switch (track) {
@ -1241,6 +1303,18 @@ cMusicManager::DisplayRadioStationName()
if (!SampleManager.IsMP3RadioChannelAvailable())
return;
string = TheText.Get("FEA_MP3"); break;
#ifdef RADIO_OFF_TEXT
case RADIO_OFF: {
extern wchar WideErrorString[];
string = TheText.Get("FEA_FMN");
if (string == WideErrorString) {
pCurrentStation = nil;
return;
}
break;
}
#endif
default: return;
};
@ -1272,6 +1346,11 @@ cMusicManager::DisplayRadioStationName()
CFont::DrawFonts();
}
}
// Always show station text after entering car. Same behaviour as III and SA.
#ifdef FIX_BUGS
else
pCurrentStation = nil;
#endif
}
bool

View file

@ -18,7 +18,7 @@ class cMusicManager
public:
bool m_bIsInitialised;
bool m_bDisabled;
bool field_2;
bool m_bSetNextStation;
uint8 m_nVolumeLatency;
uint8 m_nCurrentVolume;
uint8 m_nMaxVolume;
@ -28,25 +28,25 @@ public:
bool m_bResetTimers;
uint32 m_nResetTime;
bool m_bRadioSetByScript;
uint8 m_nRadioStation;
uint32 m_nRadioPosition;
uint8 m_nRadioStationScript;
int32 m_nRadioPosition;
uint32 m_nRadioInCar;
uint32 m_nFrontendTrack;
uint32 m_nPlayingTrack;
uint8 m_nUpcomingMusicMode;
uint8 m_nMusicMode;
bool field_398E;
bool field_398F;
uint32 m_nStreamedTrack;
bool field_3994;
bool field_3995;
bool field_3996;
bool field_3997;
bool m_FrontendLoopFlag;
bool m_bTrackChangeStarted;
uint32 m_nNextTrack;
bool m_nNextLoopFlag;
bool m_bVerifyNextTrackStartedToPlay;
bool m_bGameplayAllowsRadio;
bool m_bRadioStreamReady;
int8 nFramesSinceCutsceneEnded;
bool field_3999;
bool field_399A;
bool m_bUserResumedGame;
bool m_bMusicModeChangeStarted;
uint8 m_nMusicModeToBeSet;
bool field_399C;
bool m_bEarlyFrontendTrack;
float aListenTimeArray[NUM_RADIOS];
float m_nLastTrackServiceTime;

View file

@ -14,8 +14,8 @@ enum eRadioStation
USERTRACK,
NUM_RADIOS = 10,
POLICE_RADIO = 10,
RADIO_OFF = 10,
//TAXI_RADIO,
RADIO_OFF,
};
enum eMusicMode

View file

@ -15,6 +15,8 @@ ALuint alFilters[MAXCHANNELS+MAX2DCHANNELS];
ALuint alBuffers[MAXCHANNELS+MAX2DCHANNELS];
bool bChannelsCreated = false;
int32 CChannel::channelsThatNeedService = 0;
void
CChannel::InitChannels()
{
@ -59,7 +61,9 @@ void CChannel::SetDefault()
Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f;
Distances[0] = 0.0f; Distances[1] = FLT_MAX;
LoopCount = 1;
LoopCount = 1;
LastProcessedOffset = UINT32_MAX;
LoopPoints[0] = 0; LoopPoints[1] = -1;
Frequency = MAX_FREQ;
@ -67,6 +71,10 @@ void CChannel::SetDefault()
void CChannel::Reset()
{
// Here is safe because ctor don't call this
if (LoopCount > 1)
channelsThatNeedService--;
ClearBuffer();
SetDefault();
}
@ -165,10 +173,51 @@ void CChannel::SetCurrentFreq(uint32 freq)
SetPitch(ALfloat(freq) / Frequency);
}
void CChannel::SetLoopCount(int32 loopCount) // fake. TODO:
void CChannel::SetLoopCount(int32 count)
{
if ( !HasSource() ) return;
alSourcei(alSources[id], AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
// 0: loop indefinitely, 1: play one time, 2: play two times etc...
// only > 1 needs manual processing
if (LoopCount > 1 && count < 2)
channelsThatNeedService--;
else if (LoopCount < 2 && count > 1)
channelsThatNeedService++;
alSourcei(alSources[id], AL_LOOPING, count == 1 ? AL_FALSE : AL_TRUE);
LoopCount = count;
}
bool CChannel::Update()
{
if (!HasSource()) return false;
if (LoopCount < 2) return false;
ALint state;
alGetSourcei(alSources[id], AL_SOURCE_STATE, &state);
if (state == AL_STOPPED) {
debug("Looping channels(%d in this case) shouldn't report AL_STOPPED, but nvm\n", id);
SetLoopCount(1);
return true;
}
assert(channelsThatNeedService > 0 && "Ref counting is broken");
ALint offset;
alGetSourcei(alSources[id], AL_SAMPLE_OFFSET, &offset);
// Rewound
if (offset < LastProcessedOffset) {
LoopCount--;
if (LoopCount == 1) {
// Playing last tune...
channelsThatNeedService--;
alSourcei(alSources[id], AL_LOOPING, AL_FALSE);
}
}
LastProcessedOffset = offset;
return true;
}
void CChannel::SetLoopPoints(ALint start, ALint end)
@ -200,6 +249,7 @@ void CChannel::SetPan(int32 pan)
void CChannel::ClearBuffer()
{
if ( !HasSource() ) return;
alSourcei(alSources[id], AL_LOOPING, AL_FALSE);
alSourcei(alSources[id], AL_BUFFER, AL_NONE);
Data = nil;
DataSize = 0;

View file

@ -19,7 +19,10 @@ class CChannel
float Distances[2];
int32 LoopCount;
ALint LoopPoints[2];
ALint LastProcessedOffset;
public:
static int32 channelsThatNeedService;
static void InitChannels();
static void DestroyChannels();
@ -37,7 +40,7 @@ public:
void SetVolume(int32 vol);
void SetSampleData(void *_data, size_t _DataSize, int32 freq);
void SetCurrentFreq(uint32 freq);
void SetLoopCount(int32 loopCount); // fake
void SetLoopCount(int32 count);
void SetLoopPoints(ALint start, ALint end);
void SetPosition(float x, float y, float z);
void SetDistances(float max, float min);
@ -45,6 +48,7 @@ public:
void ClearBuffer();
void SetReverbMix(ALuint slot, float mix);
void UpdateReverb(ALuint slot);
bool Update();
};
#endif

View file

@ -499,6 +499,7 @@ public:
m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
@ -980,7 +981,8 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
m_bReset(false),
m_nVolume(0),
m_nPan(0),
m_nPosBeforeReset(0)
m_nPosBeforeReset(0),
m_nLoopCount(1)
{
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
@ -1078,7 +1080,7 @@ bool CStream::IsPlaying()
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)
if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
return true;
}
@ -1236,6 +1238,8 @@ bool CStream::Setup()
{
if ( IsOpened() )
{
alSourcei(m_pAlSources[0], AL_LOOPING, AL_FALSE);
alSourcei(m_pAlSources[1], AL_LOOPING, AL_FALSE);
m_pSoundFile->Seek(0);
//SetPosition(0.0f, 0.0f, 0.0f);
SetPitch(1.0f);
@ -1246,6 +1250,13 @@ bool CStream::Setup()
return IsOpened();
}
void CStream::SetLoopCount(int32 count)
{
if ( !HasSource() ) return;
m_nLoopCount = count;
}
void CStream::SetPlay(bool state)
{
if ( !HasSource() ) return;
@ -1305,7 +1316,7 @@ void CStream::Update()
if ( !m_bPaused )
{
ALint sourceState[2];
ALint totalBuffers[2] = { 0, 0 };
ALint buffersProcessed[2] = { 0, 0 };
// Relying a lot on left buffer states in here
@ -1313,44 +1324,51 @@ void CStream::Update()
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_QUEUED, &totalBuffers[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_QUEUED, &totalBuffers[1]);
alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]);
} while (buffersProcessed[0] != buffersProcessed[1]);
ALint looping = AL_FALSE;
alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping);
if ( looping == AL_TRUE )
{
TRACE("stream set looping");
alSourcei(m_pAlSources[0], AL_LOOPING, AL_TRUE);
alSourcei(m_pAlSources[1], AL_LOOPING, AL_TRUE);
}
assert(buffersProcessed[0] == buffersProcessed[1]);
while( buffersProcessed[0]-- )
// Correcting OpenAL concepts here:
// AL_BUFFERS_QUEUED = Number of *all* buffers in queue, including processed, processing and pending
// AL_BUFFERS_PROCESSED = Index of the buffer being processing right now. Buffers coming after that(have greater index) are pending buffers.
// which means: totalBuffers[0] - buffersProcessed[0] = pending buffers
bool buffersRefilled = false;
// We should wait queue to be cleared to loop track, because position calculation relies on queue.
if (m_nLoopCount != 1 && m_bActive && totalBuffers[0] == 0)
{
ALuint buffer[2];
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
if (m_bActive && FillBuffer(buffer))
Setup();
buffersRefilled = FillBuffers() != 0;
if (m_nLoopCount != 0)
m_nLoopCount--;
}
else
{
while( buffersProcessed[0]-- )
{
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
ALuint buffer[2];
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
if (m_bActive && FillBuffer(buffer))
{
buffersRefilled = true;
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
}
}
}
if ( sourceState[0] != AL_PLAYING )
{
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
SetPlay(buffersProcessed[0]!=0);
}
// Two reasons: 1-Source may be starved to audio and stopped itself, 2- We're already waiting it to starve and die for looping track!
if (m_bActive && (buffersRefilled || (totalBuffers[1] - buffersProcessed[1] != 0)))
SetPlay(true);
}
}
@ -1362,6 +1380,7 @@ void CStream::ProviderInit()
{
SetPan(m_nPan);
SetVolume(m_nVolume);
SetLoopCount(m_nLoopCount);
SetPosMS(m_nPosBeforeReset);
if (m_bActive)
FillBuffers();

View file

@ -69,6 +69,7 @@ class CStream
uint32 m_nVolume;
uint8 m_nPan;
uint32 m_nPosBeforeReset;
int32 m_nLoopCount;
IDecoder *m_pSoundFile;
@ -103,6 +104,8 @@ public:
void Start();
void Stop();
void Update(void);
void SetLoopCount(int32);
void ProviderInit();
void ProviderTerm();

View file

@ -46,7 +46,6 @@
//TODO: fix eax3 reverb
//TODO: max channels
//TODO: loop count
cSampleManager SampleManager;
bool _bSampmanInitialised = false;
@ -1695,7 +1694,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
ASSERT(stream != NULL);
aStream[nStream] = stream;
if ( !stream->IsOpened() )
if ( !stream->Setup() )
{
delete stream;
aStream[nStream] = NULL;
@ -1725,7 +1724,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
if ( stream )
{
if ( stream->Setup() )
if ( stream->IsOpened() )
{
stream->Start();
}
@ -1771,13 +1770,13 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
aStream[nStream] = stream;
if (stream->IsOpened()) {
if (stream->Setup()) {
if (position != 0)
stream->SetPosMS(position);
if (stream->Setup()) {
stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
nStreamLoopedFlag[nStream] = true;
if (position != 0)
stream->SetPosMS(position);
stream->Start();
}
stream->Start();
return true;
} else {
@ -1798,10 +1797,8 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream], IsThisTrackAt16KHz(nFile) ? 16000 : 32000);
}
if (aStream[nStream]->IsOpened()) {
if (aStream[nStream]->Setup()) {
aStream[nStream]->Start();
}
if (aStream[nStream]->Setup()) {
aStream[nStream]->Start();
return true;
} else {
@ -1827,13 +1824,13 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
aStream[nStream] = stream;
if (stream->IsOpened()) {
if (stream->Setup()) {
if (position != 0)
stream->SetPosMS(position);
if (stream->Setup()) {
stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
nStreamLoopedFlag[nStream] = true;
if (position != 0)
stream->SetPosMS(position);
stream->Start();
}
stream->Start();
return true;
} else {
@ -1854,13 +1851,11 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
}
if (aStream[nStream]->IsOpened()) {
if (aStream[nStream]->Setup()) {
if (position != 0)
aStream[nStream]->SetPosMS(position);
if (aStream[nStream]->Setup()) {
if (position != 0)
aStream[nStream]->SetPosMS(position);
aStream[nStream]->Start();
}
aStream[nStream]->Start();
_bIsMp3Active = true;
return true;
@ -1884,13 +1879,13 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
aStream[nStream] = stream;
if ( stream->IsOpened() ) {
if ( stream->Setup() ) {
if (position != 0)
stream->SetPosMS(position);
if ( stream->Setup() ) {
stream->SetLoopCount(nStreamLoopedFlag[nStream] ? 0 : 1);
nStreamLoopedFlag[nStream] = true;
if (position != 0)
stream->SetPosMS(position);
stream->Start();
}
stream->Start();
return true;
} else {
@ -1913,6 +1908,9 @@ cSampleManager::StopStreamedFile(uint8 nStream)
{
delete stream;
aStream[nStream] = NULL;
if ( nStream == 0 )
_bIsMp3Active = false;
}
}
@ -1925,7 +1923,21 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
if ( stream )
{
return stream->GetPosMS();
if ( _bIsMp3Active )
{
tMP3Entry *mp3 = _GetMP3EntryByIndex(_CurMP3Index);
if ( mp3 != NULL )
{
return stream->GetPosMS() + mp3->nTrackStreamPos;
}
else
return 0;
}
else
{
return stream->GetPosMS();
}
}
return 0;
@ -2001,6 +2013,12 @@ cSampleManager::Service(void)
if ( stream )
stream->Update();
}
int refCount = CChannel::channelsThatNeedService;
for ( int32 i = 0; refCount && i < MAXCHANNELS+MAX2DCHANNELS; i++ )
{
if ( aChannel[i].Update() )
refCount--;
}
}
bool

View file

@ -171,22 +171,22 @@ enum eSound
SOUND_CAR_PED_COLLISION,
SOUND_CLOCK_TICK,
SOUND_PART_MISSION_COMPLETE,
SOUND_FRONTEND_MENU_STARTING, // same with SOUND_HUD_SOUND
SOUND_FRONTEND_MENU_STARTING, // same sound as SOUND_HUD
// TODO(Miami): What are 170-175??
SOUND_FRONTEND_NO_RADIO = 176, // those 3 are all same sound
SOUND_FRONTEND_RADIO_CHANGE,
SOUND_FRONTEND_RADIO_CHANGE_2,
SOUND_HUD_SOUND,
SOUND_FRONTEND_RADIO_TURN_OFF = 176, // those 2 are same sound
SOUND_FRONTEND_RADIO_TURN_ON,
SOUND_FRONTEND_HURRICANE, // yes, frontend
SOUND_HUD,
SOUND_180,
SOUND_181,
SOUND_182,
SOUND_LIGHTNING,
SOUND_BULLETTRACE_1,
SOUND_BULLETTRACE_2,
SOUND_186, // makes same sound with 40
SOUND_187, // makes same sound with 46
SOUND_186, // makes same sound as 40
SOUND_187, // makes same sound as 46
SOUND_MELEE_ATTACK_START,
SOUND_SKATING,
SOUND_WEAPON_MINIGUN_ATTACK,

View file

@ -307,8 +307,16 @@ CCollision::TestLineTriangle(const CColLine &line, const CompressedVector *verts
if(plane.CalcPoint(line.p0) * plane.CalcPoint(line.p1) > 0.0f)
return false;
float p0dist = DotProduct(line.p1 - line.p0, normal);
#ifdef FIX_BUGS
// line lines in the plane, assume no collision
if (p0dist == 0.0f)
return false;
#endif
// intersection parameter on line
t = -plane.CalcPoint(line.p0) / DotProduct(line.p1 - line.p0, normal);
t = -plane.CalcPoint(line.p0) / p0dist;
// find point of intersection
CVector p = line.p0 + (line.p1-line.p0)*t;
@ -1127,8 +1135,17 @@ CCollision::ProcessLineTriangle(const CColLine &line,
if(plane.CalcPoint(line.p0) * plane.CalcPoint(line.p1) > 0.0f)
return false;
float p0dist = DotProduct(line.p1 - line.p0, normal);
#ifdef FIX_BUGS
// line lines in the plane, assume no collision
if (p0dist == 0.0f)
return false;
#endif
// intersection parameter on line
t = -plane.CalcPoint(line.p0) / DotProduct(line.p1 - line.p0, normal);
t = -plane.CalcPoint(line.p0) / p0dist;
// early out if we're beyond the mindist
if(t >= mindist)
return false;

View file

@ -52,8 +52,8 @@ void CAutoPilot::Save(uint8*& buf)
WriteSaveBuf<int32>(buf, m_nCurrentRouteNode);
WriteSaveBuf<int32>(buf, m_nNextRouteNode);
WriteSaveBuf<int32>(buf, m_nPrevRouteNode);
WriteSaveBuf<uint32>(buf, m_nTimeEnteredCurve);
WriteSaveBuf<uint32>(buf, m_nTimeToSpendOnCurrentCurve);
WriteSaveBuf<int32>(buf, m_nTimeEnteredCurve);
WriteSaveBuf<int32>(buf, m_nTimeToSpendOnCurrentCurve);
WriteSaveBuf<uint32>(buf, m_nCurrentPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nNextPathNodeInfo);
WriteSaveBuf<uint32>(buf, m_nPreviousPathNodeInfo);
@ -95,8 +95,8 @@ void CAutoPilot::Load(uint8*& buf)
m_nCurrentRouteNode = ReadSaveBuf<int32>(buf);
m_nNextRouteNode = ReadSaveBuf<int32>(buf);
m_nPrevRouteNode = ReadSaveBuf<int32>(buf);
m_nTimeEnteredCurve = ReadSaveBuf<uint32>(buf);
m_nTimeToSpendOnCurrentCurve = ReadSaveBuf<uint32>(buf);
m_nTimeEnteredCurve = ReadSaveBuf<int32>(buf);
m_nTimeToSpendOnCurrentCurve = ReadSaveBuf<int32>(buf);
m_nCurrentPathNodeInfo = ReadSaveBuf<uint32>(buf);
m_nNextPathNodeInfo = ReadSaveBuf<uint32>(buf);
m_nPreviousPathNodeInfo = ReadSaveBuf<uint32>(buf);

View file

@ -64,8 +64,8 @@ public:
int32 m_nCurrentRouteNode;
int32 m_nNextRouteNode;
int32 m_nPrevRouteNode;
uint32 m_nTimeEnteredCurve;
uint32 m_nTimeToSpendOnCurrentCurve;
int32 m_nTimeEnteredCurve;
int32 m_nTimeToSpendOnCurrentCurve;
uint32 m_nCurrentPathNodeInfo;
uint32 m_nNextPathNodeInfo;
uint32 m_nPreviousPathNodeInfo;

View file

@ -2757,7 +2757,7 @@ void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
up.Normalise();
CVector forward(Cos(pPlane->m_fOrientation), Sin(pPlane->m_fOrientation), fForwardZ);
forward.Normalise();
CVector right = CrossProduct(forward, up);
CVector right = CrossProduct(up, forward);
right.z -= 5.0f * pPlane->m_fPlaneSteer;
right.Normalise();
up = CrossProduct(forward, right);

View file

@ -1285,7 +1285,7 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException)
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || pVehicle == pException)
if (!pVehicle || pVehicle == pException || pVehicle->GetStatus() == STATUS_WRECKED)
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
@ -1997,7 +1997,11 @@ float CGarages::FindDoorHeightForMI(int32 mi)
void CGarage::TidyUpGarage()
{
uint32 i = CPools::GetVehiclePool()->GetSize();
#ifdef FIX_BUGS
while (i--) {
#else
while (--i) {
#endif
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (pVehicle && (pVehicle->IsCar() || pVehicle->IsBike())) {
if (IsPointInsideGarage(pVehicle->GetPosition())) {
@ -2013,7 +2017,11 @@ void CGarage::TidyUpGarage()
void CGarage::TidyUpGarageClose()
{
uint32 i = CPools::GetVehiclePool()->GetSize();
#ifdef FIX_BUGS
while (i--) {
#else
while (--i) {
#endif
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle)
continue;
@ -2226,6 +2234,8 @@ void CGarages::SetAllDoorsBackToOriginalHeight()
default:
aGarages[i].RefreshDoorPointers(true);
if (aGarages[i].m_pDoor1) {
aGarages[i].m_pDoor1->GetMatrix().GetPosition().x = aGarages[i].m_fDoor1X;
aGarages[i].m_pDoor1->GetMatrix().GetPosition().y = aGarages[i].m_fDoor1Y;
aGarages[i].m_pDoor1->GetMatrix().GetPosition().z = aGarages[i].m_fDoor1Z;
if (aGarages[i].m_pDoor1->IsObject())
((CObject*)aGarages[i].m_pDoor1)->m_objectMatrix.GetPosition().z = aGarages[i].m_fDoor1Z;
@ -2235,6 +2245,8 @@ void CGarages::SetAllDoorsBackToOriginalHeight()
aGarages[i].m_pDoor1->UpdateRwFrame();
}
if (aGarages[i].m_pDoor2) {
aGarages[i].m_pDoor2->GetMatrix().GetPosition().x = aGarages[i].m_fDoor2X;
aGarages[i].m_pDoor2->GetMatrix().GetPosition().y = aGarages[i].m_fDoor2Y;
aGarages[i].m_pDoor2->GetMatrix().GetPosition().z = aGarages[i].m_fDoor2Z;
if (aGarages[i].m_pDoor2->IsObject())
((CObject*)aGarages[i].m_pDoor2)->m_objectMatrix.GetPosition().z = aGarages[i].m_fDoor2Z;

View file

@ -859,7 +859,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
mag = Sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
int width = Max(m_pathNodes[i].width, m_pathNodes[j].width);
uint8 width = Max(m_pathNodes[i].width, m_pathNodes[j].width);
if(i < j){
dx = -dx;
dy = -dy;

View file

@ -120,7 +120,7 @@ struct CCarPathLink
uint8 trafficLightDirection : 1;
uint8 trafficLightType : 2;
uint8 bBridgeLights : 1; // at least in LCS...
int8 width;
uint8 width;
CVector2D GetPosition(void) { return CVector2D(x/8.0f, y/8.0f); }
CVector2D GetDirection(void) { return CVector2D(dirX/100.0f, dirY/100.0f); }
@ -151,7 +151,7 @@ struct CPathInfoForObject
int8 numLeftLanes;
int8 numRightLanes;
int8 speedLimit;
int8 width;
uint8 width;
uint8 crossing : 1;
uint8 onlySmallBoats : 1;
@ -177,7 +177,7 @@ struct CTempNode
int16 link2;
int8 numLeftLanes;
int8 numRightLanes;
int8 width;
uint8 width;
bool isCross;
int8 linkState;
};
@ -188,7 +188,7 @@ struct CTempNodeExternal // made up name
int16 next;
int8 numLeftLanes;
int8 numRightLanes;
int8 width;
uint8 width;
bool isCross;
};

View file

@ -1701,6 +1701,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
pBoat->AutoPilot.m_vecDestinationCoors = pos;
pBoat->SetStatus(STATUS_PHYSICS);
pBoat->bEngineOn = true;
pBoat->AutoPilot.m_nCruiseSpeed = Max(1, pBoat->AutoPilot.m_nCruiseSpeed);
pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;

View file

@ -431,12 +431,12 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed);
if (ScriptParams[1]) {
pPed->bIsDucking = true;
pPed->bCrouchWhenShooting = true;
pPed->SetDuck(ScriptParams[2], true);
}
else {
pPed->ClearDuck(true);
pPed->bIsDucking = false;
pPed->bCrouchWhenShooting = false;
}
return 0;
}

View file

@ -1768,7 +1768,7 @@ CCamera::CamControl(void)
(m_bLookingAtPlayer || WhoIsInControlOfTheCamera == CAMCONTROL_OBBE) &&
!m_WideScreenOn &&
(WhoIsInControlOfTheCamera != CAMCONTROL_OBBE || bSwitchedToObbeCam))
DMAudio.PlayFrontEndSound(SOUND_HUD_SOUND, 0);
DMAudio.PlayFrontEndSound(SOUND_HUD, 0);
}
// What a mess!

View file

@ -43,6 +43,6 @@ char *CdStreamGetImageName(int32 cd);
void CdStreamRemoveImages(void);
int32 CdStreamGetNumImages(void);
#ifndef _WIN32
#ifdef FLUSHABLE_STREAMING
extern bool flushStream[MAX_CDCHANNELS];
#endif

View file

@ -21,9 +21,9 @@
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
// #define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash. (Also you may want to benefit from this via using all channels in Streaming.cpp)
#ifdef FLUSHABLE_STREAMING
bool flushStream[MAX_CDCHANNELS];
#endif
struct CdReadInfo
{
@ -76,7 +76,7 @@ CdStreamInitThread(void)
gChannelRequestQ.tail = 0;
gChannelRequestQ.size = gNumChannels + 1;
ASSERT(gChannelRequestQ.items != nil );
gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 1);
gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 0);
if (gCdStreamSema == SEM_FAILED) {
@ -91,7 +91,7 @@ CdStreamInitThread(void)
for ( int32 i = 0; i < gNumChannels; i++ )
{
sprintf(semName,"/semaphore_done%d",i);
gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 1);
gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 0);
if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED)
{
@ -99,9 +99,10 @@ CdStreamInitThread(void)
ASSERT(0);
return;
}
#ifdef ONE_THREAD_PER_CHANNEL
sprintf(semName,"/semaphore_start%d",i);
gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 1);
gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 0);
if (gpReadInfo[i].pStartSemaphore == SEM_FAILED)
{
@ -170,6 +171,7 @@ CdStreamInit(int32 numChannels)
gNumImages = 0;
gNumChannels = numChannels;
ASSERT( gNumChannels != 0 );
gpReadInfo = (CdReadInfo *)calloc(numChannels, sizeof(CdReadInfo));
ASSERT( gpReadInfo != nil );
@ -245,10 +247,12 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading ) {
if (pChannel->hFile == hImage - 1 && pChannel->nSectorOffset == _GET_OFFSET(offset) && pChannel->nSectorsToRead >= size)
return STREAM_SUCCESS;
#ifdef FLUSHABLE_STREAMING
flushStream[channel] = 1;
CdStreamSync(channel);
//return STREAM_NONE;
#else
return STREAM_NONE;
#endif
}
pChannel->hFile = hImage - 1;
@ -316,34 +320,34 @@ CdStreamSync(int32 channel)
CdReadInfo *pChannel = &gpReadInfo[channel];
ASSERT( pChannel != nil );
#ifdef FLUSHABLE_STREAMING
if (flushStream[channel]) {
#ifdef ONE_THREAD_PER_CHANNEL
pChannel->nSectorsToRead = 0;
#ifdef ONE_THREAD_PER_CHANNEL
pthread_kill(pChannel->pChannelThread, SIGUSR1);
if (pChannel->bReading) {
pChannel->bLocked = true;
while (pChannel->bLocked)
sem_wait(pChannel->pDoneSemaphore);
}
#else
pChannel->nSectorsToRead = 0;
if (pChannel->bReading) {
pChannel->bLocked = true;
pthread_kill(_gCdStreamThread, SIGUSR1);
#endif
while (pChannel->bLocked)
sem_wait(pChannel->pDoneSemaphore);
}
#endif
pChannel->bReading = false;
flushStream[channel] = false;
return STREAM_NONE;
}
#endif
if ( pChannel->nSectorsToRead != 0 )
{
pChannel->bLocked = true;
while (pChannel->bLocked)
while (pChannel->bLocked && pChannel->nSectorsToRead != 0){
sem_wait(pChannel->pDoneSemaphore);
}
pChannel->bLocked = false;
}
pChannel->bReading = false;
@ -395,7 +399,12 @@ void *CdStreamThread(void *param)
#ifndef ONE_THREAD_PER_CHANNEL
while (gCdStreamThreadStatus != 2) {
sem_wait(gCdStreamSema);
int32 channel = GetFirstInQueue(&gChannelRequestQ);
// spurious wakeup
if (channel == -1)
continue;
#else
int channel = *((int*)param);
while (gpReadInfo[channel].nThreadStatus != 2){
@ -447,7 +456,7 @@ void *CdStreamThread(void *param)
if ( pChannel->bLocked )
{
pChannel->bLocked = 0;
sem_post(pChannel->pDoneSemaphore);
sem_post(pChannel->pDoneSemaphore);
}
pChannel->bReading = false;
}
@ -524,7 +533,9 @@ void
CdStreamRemoveImages(void)
{
for ( int32 i = 0; i < gNumChannels; i++ ) {
#ifdef FLUSHABLE_STREAMING
flushStream[i] = 1;
#endif
CdStreamSync(i);
}

View file

@ -1765,6 +1765,51 @@ void CControllerConfigManager::DeleteMatching1rstPersonControls(e_ControllerActi
#undef CLEAR_ACTION_IF_NEEDED
#ifdef RADIO_SCROLL_TO_PREV_STATION
#define CHECK_ACTION(action) \
if (key == GetControllerKeyAssociatedWithAction(action, type))\
return true;
bool CControllerConfigManager::IsAnyVehicleActionAssignedToMouseKey(int32 key)
{
const eControllerType type = MOUSE;
if (!GetIsKeyBlank(key, type))
{
#ifdef BIND_VEHICLE_FIREWEAPON
CHECK_ACTION(VEHICLE_FIREWEAPON);
#endif
CHECK_ACTION(VEHICLE_LOOKBEHIND);
CHECK_ACTION(VEHICLE_LOOKLEFT);
CHECK_ACTION(VEHICLE_LOOKRIGHT);
CHECK_ACTION(VEHICLE_HORN);
CHECK_ACTION(VEHICLE_HANDBRAKE);
CHECK_ACTION(VEHICLE_ACCELERATE);
CHECK_ACTION(VEHICLE_BRAKE);
CHECK_ACTION(VEHICLE_CHANGE_RADIO_STATION);
CHECK_ACTION(TOGGLE_SUBMISSIONS);
CHECK_ACTION(VEHICLE_TURRETLEFT);
CHECK_ACTION(VEHICLE_TURRETRIGHT);
CHECK_ACTION(VEHICLE_TURRETUP);
CHECK_ACTION(VEHICLE_TURRETDOWN);
CHECK_ACTION(VEHICLE_ENTER_EXIT);
CHECK_ACTION(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
#ifndef BIND_VEHICLE_FIREWEAPON
CHECK_ACTION(PED_FIREWEAPON);
#endif
CHECK_ACTION(GO_LEFT);
CHECK_ACTION(GO_RIGHT);
CHECK_ACTION(NETWORK_TALK);
CHECK_ACTION(SWITCH_DEBUG_CAM_ON);
CHECK_ACTION(TOGGLE_DPAD);
CHECK_ACTION(TAKE_SCREEN_SHOT);
CHECK_ACTION(SHOW_MOUSE_POINTER_TOGGLE);
}
return false;
}
#undef CHECK_ACTION
#endif
void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction action, int32 key, eControllerType type)
{
if (!GetIsKeyBlank(key, type))

View file

@ -195,6 +195,10 @@ public:
void DeleteMatching1rstPersonControls (e_ControllerAction action, int32 key, eControllerType type);
void DeleteMatchingActionInitiators (e_ControllerAction action, int32 key, eControllerType type);
#ifdef RADIO_SCROLL_TO_PREV_STATION
bool IsAnyVehicleActionAssignedToMouseKey(int32 key);
#endif
bool GetIsKeyBlank(int32 key, eControllerType type);
e_ControllerActionType GetActionType(e_ControllerAction action);

View file

@ -5567,33 +5567,40 @@ void
CMenuManager::DrawQuitGameScreen(void)
{
static int32 exitSignalTimer = 0;
#ifdef FIX_BUGS
int alpha = clamp(m_nMenuFadeAlpha, 0, 255);
#else
int alpha = m_nMenuFadeAlpha;
#endif
#ifndef MUCH_SHORTER_OUTRO_SCREEN
static PauseModeTime lastTickIncrease = 0;
if (m_nMenuFadeAlpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) {
if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) {
exitSignalTimer++;
lastTickIncrease = CTimer::GetTimeInMillisecondsPauseMode();
}
#else
static PauseModeTime sincePress = 0;
sincePress += frameTime;
if (sincePress > 500)
static PauseModeTime firstTick = CTimer::GetTimeInMillisecondsPauseMode();
if (alpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - firstTick > 750) {
exitSignalTimer = 150;
}
#endif
static CSprite2d *splash = nil;
if (splash == nil)
splash = LoadSplash("OUTRO");
m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(28.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, -(m_nMenuFadeAlpha + 1)));
m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(28.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255 - alpha));
// Or we can see menu background from sides
#ifdef ASPECT_RATIO_SCALE
CSprite2d::DrawRect(CRect(0, 0, MENU_X_LEFT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(0, 0, 0, m_nMenuFadeAlpha));
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(0.f), 0, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, m_nMenuFadeAlpha));
CSprite2d::DrawRect(CRect(0, 0, MENU_X_LEFT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(0, 0, 0, alpha));
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(0.f), 0, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, alpha));
#endif
splash->Draw(CRect(MENU_X_LEFT_ALIGNED(0.f), 0, MENU_X_RIGHT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha));
if (m_nMenuFadeAlpha == 255 && exitSignalTimer == 150)
splash->Draw(CRect(MENU_X_LEFT_ALIGNED(0.f), 0, MENU_X_RIGHT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(255, 255, 255, alpha));
if (alpha == 255 && exitSignalTimer == 150)
RsEventHandler(rsQUITAPP, nil);
m_bShowMouse = false;

View file

@ -381,6 +381,11 @@ bool CGame::Initialise(const char* datFile)
CTxdStore::Create(gameTxdSlot);
CTxdStore::AddRef(gameTxdSlot);
#ifdef EXTENDED_PIPELINES
// for generic fallback
CustomPipes::SetTxdFindCallback();
#endif
LoadingScreen("Loading the Game", "Loading particles", nil);
int particleTxdSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD");
@ -440,10 +445,7 @@ bool CGame::Initialise(const char* datFile)
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
#ifdef EXTENDED_PIPELINES
// for generic fallback
CustomPipes::SetTxdFindCallback();
#endif
LoadingScreen("Loading the Game", "Add Particles", nil);
CWorld::AddParticles();
CVehicleModelInfo::LoadVehicleColours();
@ -591,7 +593,6 @@ bool CGame::ShutDown(void)
gPhoneInfo.Shutdown();
CWeapon::ShutdownWeapons();
CPedType::Shutdown();
CMBlur::MotionBlurClose();
for (int32 i = 0; i < NUMPLAYERS; i++)
{
@ -617,7 +618,7 @@ bool CGame::ShutDown(void)
CStreaming::Shutdown();
CTxdStore::GameShutdown();
CCollision::Shutdown();
CWaterLevel::DestroyWavyAtomic();
CWaterLevel::Shutdown();
CRubbish::Shutdown();
CClouds::Shutdown();
CShadows::Shutdown();
@ -626,6 +627,7 @@ bool CGame::ShutDown(void)
CWeaponEffects::Shutdown();
CParticle::Shutdown();
CPools::ShutDown();
CHud::ReInitialise();
CTxdStore::RemoveTxdSlot(gameTxdSlot);
CMBlur::MotionBlurClose();
CdStreamRemoveImages();

View file

@ -824,7 +824,7 @@ int32 CRadar::GetNewUniqueBlipIndex(int32 i)
uint32 CRadar::GetRadarTraceColour(uint32 color, bool bright)
{
int32 c;
uint32 c;
switch (color) {
case RADAR_TRACE_RED:
if (bright)

View file

@ -207,11 +207,15 @@ CStreaming::Init2(void)
// allocate streaming buffers
if(ms_streamingBufferSize & 1) ms_streamingBufferSize++;
#ifndef ONE_THREAD_PER_CHANNEL
ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE);
ms_streamingBufferSize /= 2;
ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
#ifdef ONE_THREAD_PER_CHANNEL
ms_pStreamingBuffer[2] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE);
#else
ms_pStreamingBuffer[0] = (int8*)RwMallocAlign(ms_streamingBufferSize*2*CDSTREAM_SECTOR_SIZE, CDSTREAM_SECTOR_SIZE);
ms_streamingBufferSize /= 2;
ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
ms_pStreamingBuffer[2] = ms_pStreamingBuffer[1] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
ms_pStreamingBuffer[3] = ms_pStreamingBuffer[2] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
#endif
debug("Streaming buffer size is %d sectors", ms_streamingBufferSize);
@ -2305,9 +2309,10 @@ CStreaming::LoadRequestedModels(void)
}
// Let's load models first, then process it. Unfortunately processing models are still single-threaded.
// Let's load models in 4 threads; when one of them becomes idle, process the file, and fill thread with another file. Unfortunately processing models are still single-threaded.
// Currently only supported on POSIX streamer.
#ifdef ONE_THREAD_PER_CHANNEL
// WIP - some files are loaded swapped (CdStreamPosix problem?)
#if 0 //def ONE_THREAD_PER_CHANNEL
void
CStreaming::LoadAllRequestedModels(bool priority)
{
@ -2326,14 +2331,18 @@ CStreaming::LoadAllRequestedModels(bool priority)
int streamIds[ARRAY_SIZE(ms_pStreamingBuffer)];
int streamSizes[ARRAY_SIZE(ms_pStreamingBuffer)];
int streamPoses[ARRAY_SIZE(ms_pStreamingBuffer)];
bool first = true;
int readOrder[4] = {-1}; // Channel IDs ordered by read time
int readI = 0;
int processI = 0;
bool first = true;
// All those "first" checks are because of variables aren't initialized in first pass.
while (true) {
// Enumerate files and start reading
for (int i=0; i<ARRAY_SIZE(ms_pStreamingBuffer); i++) {
// Channel has file to load
if (!first && streamIds[i] != -1) {
processI = i;
continue;
}
@ -2346,12 +2355,16 @@ CStreaming::LoadAllRequestedModels(bool priority)
if (ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)) {
streamIds[i] = -1;
// Big file, needs 2 buffer
if (size > (uint32)ms_streamingBufferSize) {
if (i + 1 == ARRAY_SIZE(ms_pStreamingBuffer))
continue;
break;
else if (!first && streamIds[i+1] != -1)
continue;
} else {
// Buffer of current channel is part of a "big file", pass
if (i != 0 && streamIds[i-1] != -1 && streamSizes[i-1] > (uint32)ms_streamingBufferSize)
continue;
}
@ -2361,8 +2374,18 @@ CStreaming::LoadAllRequestedModels(bool priority)
streamIds[i] = streamId;
streamSizes[i] = size;
streamPoses[i] = posn;
if (!first)
assert(readOrder[readI] == -1);
//printf("read: order %d, ch %d, id %d, size %d\n", readI, i, streamId, size);
CdStreamRead(i, ms_pStreamingBuffer[i], imgOffset+posn, size);
processI = i;
readOrder[readI] = i;
if (first && readI+1 != ARRAY_SIZE(readOrder))
readOrder[readI+1] = -1;
readI = (readI + 1) % ARRAY_SIZE(readOrder);
} else {
ms_aInfoForModel[streamId].RemoveFromList();
DecrementRef(streamId);
@ -2370,33 +2393,40 @@ CStreaming::LoadAllRequestedModels(bool priority)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
streamIds[i] = -1;
}
} else
} else {
streamIds[i] = -1;
break;
}
}
first = false;
int nextChannel = readOrder[processI];
// Now process
if (streamIds[processI] == -1)
// Now start processing
if (nextChannel == -1 || streamIds[nextChannel] == -1)
break;
// Try again on error
while (CdStreamSync(processI) != STREAM_NONE) {
CdStreamRead(processI, ms_pStreamingBuffer[processI], imgOffset+streamPoses[processI], streamSizes[processI]);
}
ms_aInfoForModel[streamIds[processI]].m_loadState = STREAMSTATE_READING;
MakeSpaceFor(streamSizes[processI] * CDSTREAM_SECTOR_SIZE);
ConvertBufferToObject(ms_pStreamingBuffer[processI], streamIds[processI]);
if(ms_aInfoForModel[streamIds[processI]].m_loadState == STREAMSTATE_STARTED)
FinishLoadingLargeFile(ms_pStreamingBuffer[processI], streamIds[processI]);
//printf("process: order %d, ch %d, id %d\n", processI, nextChannel, streamIds[nextChannel]);
if(streamIds[processI] < STREAM_OFFSET_TXD){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[processI]);
// Try again on error
while (CdStreamSync(nextChannel) != STREAM_NONE) {
CdStreamRead(nextChannel, ms_pStreamingBuffer[nextChannel], imgOffset+streamPoses[nextChannel], streamSizes[nextChannel]);
}
ms_aInfoForModel[streamIds[nextChannel]].m_loadState = STREAMSTATE_READING;
MakeSpaceFor(streamSizes[nextChannel] * CDSTREAM_SECTOR_SIZE);
ConvertBufferToObject(ms_pStreamingBuffer[nextChannel], streamIds[nextChannel]);
if(ms_aInfoForModel[streamIds[nextChannel]].m_loadState == STREAMSTATE_STARTED)
FinishLoadingLargeFile(ms_pStreamingBuffer[nextChannel], streamIds[nextChannel]);
if(streamIds[nextChannel] < STREAM_OFFSET_TXD){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(streamIds[nextChannel]);
if(mi->IsSimple())
mi->m_alpha = 255;
}
streamIds[processI] = -1;
streamIds[nextChannel] = -1;
readOrder[processI] = -1;
processI = (processI + 1) % ARRAY_SIZE(readOrder);
}
ms_bLoadingBigModel = false;
@ -2443,7 +2473,7 @@ CStreaming::LoadAllRequestedModels(bool priority)
status = CdStreamRead(0, ms_pStreamingBuffer[0], imgOffset+posn, size);
while(CdStreamSync(0) || status == STREAM_NONE);
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_READING;
MakeSpaceFor(size * CDSTREAM_SECTOR_SIZE);
ConvertBufferToObject(ms_pStreamingBuffer[0], streamId);
if(ms_aInfoForModel[streamId].m_loadState == STREAMSTATE_STARTED)
@ -2500,7 +2530,7 @@ CStreaming::FlushRequestList(void)
next = si->m_next;
RemoveModel(si - ms_aInfoForModel);
}
#ifndef _WIN32
#ifdef FLUSHABLE_STREAMING
if(ms_channel[0].state == CHANNELSTATE_READING) {
flushStream[0] = 1;
}
@ -3216,4 +3246,4 @@ CStreaming::PrintStreamingBufferState()
DoRWStuffEndOfFrame();
}
CTimer::Update();
}
}

View file

@ -88,7 +88,11 @@ public:
static int32 ms_oldSectorX;
static int32 ms_oldSectorY;
static int32 ms_streamingBufferSize;
#ifndef ONE_THREAD_PER_CHANNEL
static int8 *ms_pStreamingBuffer[2];
#else
static int8 *ms_pStreamingBuffer[4];
#endif
static size_t ms_memoryUsed;
static CStreamingChannel ms_channel[2];
static int32 ms_channelError;

View file

@ -367,7 +367,7 @@ CWorld::ProcessLineOfSightSectorList(CPtrList &list, const CColLine &line, CColP
} else if(e->bUsesCollision)
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, dist,
if(colmodel && CCollision::ProcessLineOfSight(line, e->GetMatrix(), *colmodel, point, mindist,
ignoreSeeThrough, ignoreShootThrough))
entity = e;
if(carTyres && ((CVehicle*)e)->SetUpWheelColModel(&tyreCol) && CCollision::ProcessLineOfSight(line, e->GetMatrix(), tyreCol, tyreColPoint, tyreDist, false, ignoreShootThrough)){
@ -466,7 +466,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
e->m_scanCode = GetCurrentScanCode();
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist,
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, mindist,
ignoreSeeThrough, false, poly))
entity = e;
}
@ -2239,8 +2239,12 @@ CWorld::UseDetonator(CEntity *pEntity)
{
int32 i = CPools::GetVehiclePool()->GetSize();
while(--i >= 0) {
#ifdef FIX_BUGS
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
#else
CAutomobile *pVehicle = (CAutomobile *)CPools::GetVehiclePool()->GetSlot(i);
if(pVehicle && !pVehicle->m_vehType && pVehicle->m_bombType == CARBOMB_REMOTE &&
#endif
if(pVehicle && pVehicle->m_bombType == CARBOMB_REMOTE &&
pVehicle->m_pBombRigger == pEntity) {
pVehicle->m_bombType = CARBOMB_NONE;
pVehicle->m_nBombTimer = 500;

View file

@ -355,7 +355,7 @@ __inline__ void TRACE(char *f, ...) { } // this is re3 only, and so the function
#ifndef MASTER
#define assert(_Expression) (void)( (!!(_Expression)) || (re3_assert(#_Expression, __FILE__, __LINE__, __FUNCTION__), 0) )
#else
#define assert(_Expression)
#define assert(_Expression) (_Expression)
#endif
#define ASSERT assert

View file

@ -251,6 +251,12 @@ enum Config {
#define FIX_BUGS_64 // Must have fixes to be able to run 64 bit build
#endif
#define ASCII_STRCMP // use faster ascii str comparisons
#if !defined _WIN32 || defined __MWERKS__ || defined __MINGW32__ || defined VANILLA_DEFINES
#undef ASCII_STRCMP
#endif
// Just debug menu entries
#ifdef DEBUGMENU
#define RELOADABLES // some debug menu options to reload TXD files
@ -306,8 +312,8 @@ enum Config {
// Hud, frontend and radar
#define PC_MENU
#define FIX_RADAR // use radar size from early version before R* broke it
#define RADIO_OFF_TEXT // Won't work without FIX_BUGS
#ifndef PC_MENU
# define PS2_MENU
@ -347,6 +353,10 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
#if SCRIPT_LOG_FILE_LEVEL == 0
#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#endif
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define USE_BASIC_SCRIPT_DEBUG_OUTPUT
#endif
@ -376,6 +386,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define FREE_CAM // Rotating cam
// Audio
#define RADIO_SCROLL_TO_PREV_STATION // Won't work without FIX_BUGS
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
//#define PS2_AUDIO_PATHS // changes audio paths for cutscenes and radio to PS2 paths (needs vbdec on MSS builds)
//#define AUDIO_OAL_USE_SNDFILE // use libsndfile to decode WAVs instead of our internal decoder
@ -393,11 +404,12 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#endif
#ifdef LIBRW
// these are not supported with librw yet
// Streaming
#if !defined(_WIN32) && !defined(__SWITCH__)
//#define ONE_THREAD_PER_CHANNEL // Don't use if you're not on SSD/Flash - also not utilized too much right now(see commented LoadAllRequestedModels in Streaming.cpp)
#define FLUSHABLE_STREAMING // Make it possible to interrupt reading when processing file isn't needed anymore.
#endif
// IMG
#define BIG_IMG // allows to read larger img files
#define BIG_IMG // Not complete - allows to read larger img files
//#define SQUEEZE_PERFORMANCE
#ifdef SQUEEZE_PERFORMANCE
@ -405,6 +417,8 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef NO_ISLAND_LOADING
#endif
// -------
#if defined __MWERKS__ || defined VANILLA_DEFINES
#define FINAL
#undef CHATTYSPLASH
@ -459,6 +473,7 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef BUTTON_ICONS
#undef FIX_RADAR
#undef RADIO_OFF_TEXT
#undef MAP_ENHANCEMENTS
#undef MUCH_SHORTER_OUTRO_SCREEN
@ -487,4 +502,6 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#undef IMPROVED_CAMERA
#undef FREE_CAM
#undef BIG_IMG
#undef RADIO_SCROLL_TO_PREV_STATION
#endif

View file

@ -1065,8 +1065,13 @@ DisplayGameDebugText()
#endif
FrameSamples++;
#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
FramesPerSecondCounter += frameTime / 1000.f; // convert to seconds
FramesPerSecond = FrameSamples / FramesPerSecondCounter;
#else
FramesPerSecondCounter += 1000.0f / (CTimer::GetTimeStepNonClippedInSeconds() * 1000.0f);
FramesPerSecond = FramesPerSecondCounter / FrameSamples;
#endif
if ( FrameSamples > 30 )
{

View file

@ -406,6 +406,10 @@ bool LoadINISettings()
ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult);
ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult);
#endif
ReadIniIfExists("Rendering", "BackfaceCulling", &gBackfaceCulling);
#ifdef NEW_RENDERER
ReadIniIfExists("Rendering", "NewRenderer", &gbNewRenderer);
#endif
#ifdef PROPER_SCALING
ReadIniIfExists("Draw", "ProperScaling", &CDraw::ms_bProperScaling);
@ -495,6 +499,9 @@ void SaveINISettings()
StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
#endif
StoreIni("Rendering", "BackfaceCulling", gBackfaceCulling);
#ifdef NEW_RENDERER
StoreIni("Rendering", "NewRenderer", gbNewRenderer);
#endif
#ifdef PROPER_SCALING
StoreIni("Draw", "ProperScaling", CDraw::ms_bProperScaling);
@ -706,7 +713,7 @@ void CTweakVars::Add(CTweakVar *var)
TweakVarsListSize = 0;
}
if(TweakVarsListSize > 63)
TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(*var));
TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(CTweakVar*));
TweakVarsList[TweakVarsListSize++] = var;
// TweakVarsList.push_back(var);

View file

@ -89,6 +89,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
}
int vsBits;
rw::uint32 flags = atomic->geometry->flags;
setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
setIndices(header->indexBuffer);
setVertexDeclaration(header->vertexDeclaration);
@ -120,7 +121,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
reflProps[3] = m->surfaceProps.specular == 0.0f ? 0.0f : VehicleSpecularity;
d3ddevice->SetVertexShaderConstantF(VSLOC_reflProps, reflProps, 1);
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
if(m->texture)
d3d::setTexture(0, m->texture);
@ -150,11 +151,11 @@ CreateVehiclePipe(void)
fp = ReadTweakValueTable(fp, SpecColor);
}
#include "shaders/neoVehicle_VS.inc"
#include "shaders/obj/neoVehicle_VS.inc"
neoVehicle_VS = rw::d3d::createVertexShader(neoVehicle_VS_cso);
assert(neoVehicle_VS);
#include "shaders/neoVehicle_PS.inc"
#include "shaders/obj/neoVehicle_PS.inc"
neoVehicle_PS = rw::d3d::createPixelShader(neoVehicle_PS_cso);
assert(neoVehicle_PS);
@ -260,11 +261,11 @@ CreateWorldPipe(void)
else
ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
#include "shaders/default_UV2_VS.inc"
#include "shaders/obj/default_UV2_VS.inc"
neoWorld_VS = rw::d3d::createVertexShader(default_UV2_VS_cso);
assert(neoWorld_VS);
#include "shaders/neoWorldVC_PS.inc"
#include "shaders/obj/neoWorldVC_PS.inc"
neoWorldVC_PS = rw::d3d::createPixelShader(neoWorldVC_PS_cso);
assert(neoWorldVC_PS);
@ -347,11 +348,11 @@ glossRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
void
CreateGlossPipe(void)
{
#include "shaders/neoGloss_VS.inc"
#include "shaders/obj/neoGloss_VS.inc"
neoGloss_VS = rw::d3d::createVertexShader(neoGloss_VS_cso);
assert(neoGloss_VS);
#include "shaders/neoGloss_PS.inc"
#include "shaders/obj/neoGloss_PS.inc"
neoGloss_PS = rw::d3d::createPixelShader(neoGloss_PS_cso);
assert(neoGloss_PS);
@ -421,6 +422,7 @@ rimRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
}
int vsBits;
rw::uint32 flags = atomic->geometry->flags;
setStreamSource(0, header->vertexStream[0].vertexBuffer, 0, header->vertexStream[0].stride);
setIndices(header->indexBuffer);
setVertexDeclaration(header->vertexDeclaration);
@ -438,7 +440,7 @@ rimRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
if(m->texture){
d3d::setTexture(0, m->texture);
@ -464,7 +466,7 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
}
int vsBits;
rw::uint32 flags = atomic->geometry->flags;
setStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
0, header->vertexStream[0].stride);
setIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
@ -485,7 +487,7 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 255);
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
if(inst->material->texture){
d3d::setTexture(0, m->texture);
@ -513,11 +515,11 @@ CreateRimLightPipes(void)
}
#include "shaders/neoRim_VS.inc"
#include "shaders/obj/neoRim_VS.inc"
neoRim_VS = rw::d3d::createVertexShader(neoRim_VS_cso);
assert(neoRim_VS);
#include "shaders/neoRimSkin_VS.inc"
#include "shaders/obj/neoRimSkin_VS.inc"
neoRimSkin_VS = rw::d3d::createVertexShader(neoRimSkin_VS_cso);
assert(neoRimSkin_VS);
@ -611,6 +613,7 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
assert(building->instHeader->platform == PLATFORM_D3D9);
building->fadeAlpha = 255;
building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
rw::uint32 flags = atomic->geometry->flags;
bool setupDone = false;
bool defer = false;
@ -640,7 +643,7 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
setupDone = true;
}
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
if(m->texture){
d3d::setTexture(0, m->texture);
@ -703,7 +706,7 @@ RenderBlendPass(int pass)
rw::RGBA color = m->color;
color.alpha = (color.alpha * building->fadeAlpha)/255;
setMaterial(color, m->surfaceProps);
setMaterial(color, m->surfaceProps); // always modulate here
if(m->texture){
d3d::setTexture(0, m->texture);

View file

@ -87,6 +87,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
Material *m;
rw::uint32 flags = atomic->geometry->flags;
setWorldMatrix(atomic->getFrame()->getLTM());
lightingCB(atomic);
@ -119,7 +120,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
while(n--){
m = inst->material;
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
setTexture(0, m->texture);
@ -160,8 +161,8 @@ CreateVehiclePipe(void)
{
#include "shaders/neoVehicle_fs_gl.inc"
#include "shaders/neoVehicle_vs_gl.inc"
#include "shaders/obj/neoVehicle_frag.inc"
#include "shaders/obj/neoVehicle_vert.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoVehicle_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, neoVehicle_frag_src, nil };
neoVehicleShader = Shader::create(vs, fs);
@ -271,8 +272,8 @@ CreateWorldPipe(void)
ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
{
#include "shaders/neoWorldVC_fs_gl.inc"
#include "shaders/default_UV2_gl.inc"
#include "shaders/obj/neoWorldVC_frag.inc"
#include "shaders/obj/default_UV2_vert.inc"
const char *vs[] = { shaderDecl, header_vert_src, default_UV2_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, neoWorldVC_frag_src, nil };
neoWorldShader = Shader::create(vs, fs);
@ -333,7 +334,12 @@ glossRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
V3d eyePos = rw::engine->currentCamera->getFrame()->getLTM()->pos;
glUniform3fv(U(u_eye), 1, (float*)&eyePos);
glUniform4fv(U(u_reflProps), 1, (float*)&GlossMult);
float reflProps[4];
reflProps[0] = GlossMult;
reflProps[1] = 0.0f;
reflProps[2] = 0.0f;
reflProps[3] = 0.0f;
glUniform4fv(U(u_reflProps), 1, reflProps);
SetRenderState(VERTEXALPHA, TRUE);
SetRenderState(SRCBLEND, BLENDONE);
@ -374,8 +380,8 @@ CreateGlossPipe(void)
using namespace rw::gl3;
{
#include "shaders/neoGloss_fs_gl.inc"
#include "shaders/neoGloss_vs_gl.inc"
#include "shaders/obj/neoGloss_frag.inc"
#include "shaders/obj/neoGloss_vert.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoGloss_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, neoGloss_frag_src, nil };
neoGlossShader = Shader::create(vs, fs);
@ -444,6 +450,7 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
Material *m;
rw::uint32 flags = atomic->geometry->flags;
setWorldMatrix(atomic->getFrame()->getLTM());
lightingCB(atomic);
@ -467,7 +474,7 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
while(n--){
m = inst->material;
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
setTexture(0, m->texture);
@ -494,6 +501,7 @@ rimRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
Material *m;
rw::uint32 flags = atomic->geometry->flags;
setWorldMatrix(atomic->getFrame()->getLTM());
lightingCB(atomic);
@ -515,7 +523,7 @@ rimRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
while(n--){
m = inst->material;
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
setTexture(0, m->texture);
@ -546,8 +554,8 @@ CreateRimLightPipes(void)
}
{
#include "shaders/simple_fs_gl.inc"
#include "shaders/neoRimSkin_gl.inc"
#include "shaders/obj/simple_frag.inc"
#include "shaders/obj/neoRimSkin_vert.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoRimSkin_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
neoRimSkinShader = Shader::create(vs, fs);
@ -555,8 +563,8 @@ CreateRimLightPipes(void)
}
{
#include "shaders/simple_fs_gl.inc"
#include "shaders/neoRim_gl.inc"
#include "shaders/obj/simple_frag.inc"
#include "shaders/obj/neoRim_vert.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoRim_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
neoRimShader = Shader::create(vs, fs);
@ -660,6 +668,7 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
assert(building->instHeader->platform == PLATFORM_GL3);
building->fadeAlpha = 255;
building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
rw::uint32 flags = atomic->geometry->flags;
WorldLights lights;
lights.numAmbients = 1;
@ -699,7 +708,7 @@ AtomicFirstPass(RpAtomic *atomic, int pass)
setupDone = true;
}
setMaterial(m->color, m->surfaceProps);
setMaterial(flags, m->color, m->surfaceProps);
setTexture(0, m->texture);
@ -768,7 +777,7 @@ RenderBlendPass(int pass)
rw::RGBA color = m->color;
color.alpha = (color.alpha * building->fadeAlpha)/255;
setMaterial(color, m->surfaceProps);
setMaterial(color, m->surfaceProps); // always modulate here
setTexture(0, m->texture);

View file

@ -142,17 +142,17 @@ CPostFX::Open(RwCamera *cam)
#ifdef RW_D3D9
#include "shaders/colourfilterVC_PS.inc"
#include "shaders/obj/colourfilterVC_PS.inc"
colourfilterVC_PS = rw::d3d::createPixelShader(colourfilterVC_PS_cso);
#include "shaders/contrastPS.inc"
#include "shaders/obj/contrastPS.inc"
contrast_PS = rw::d3d::createPixelShader(contrastPS_cso);
#endif
#ifdef RW_OPENGL
using namespace rw::gl3;
{
#include "shaders/im2d_gl.inc"
#include "shaders/colourfilterVC_fs_gl.inc"
#include "shaders/obj/im2d_vert.inc"
#include "shaders/obj/colourfilterVC_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, colourfilterVC_frag_src, nil };
colourFilterVC = Shader::create(vs, fs);
@ -160,8 +160,8 @@ CPostFX::Open(RwCamera *cam)
}
{
#include "shaders/im2d_gl.inc"
#include "shaders/contrast_fs_gl.inc"
#include "shaders/obj/im2d_vert.inc"
#include "shaders/obj/contrast_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, contrast_frag_src, nil };
contrast = Shader::create(vs, fs);

View file

@ -112,14 +112,14 @@ ScreenDroplets::InitDraw(void)
openim2d_uv2();
#ifdef RW_D3D9
#include "shaders/screenDroplet_PS.inc"
#include "shaders/obj/screenDroplet_PS.inc"
screenDroplet_PS = rw::d3d::createPixelShader(screenDroplet_PS_cso);
#endif
#ifdef RW_GL3
using namespace rw::gl3;
{
#include "shaders/im2d_UV2_gl.inc"
#include "shaders/screenDroplet_fs_gl.inc"
#include "shaders/obj/im2d_UV2_vert.inc"
#include "shaders/obj/screenDroplet_frag.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_UV2_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, screenDroplet_frag_src, nil };
screenDroplet = Shader::create(vs, fs);

View file

@ -1,78 +0,0 @@
all: im2d_gl.inc simple_fs_gl.inc default_UV2_gl.inc \
colourfilterVC_fs_gl.inc contrast_fs_gl.inc \
neoRim_gl.inc neoRimSkin_gl.inc \
neoWorldVC_fs_gl.inc neoGloss_vs_gl.inc neoGloss_fs_gl.inc \
neoVehicle_vs_gl.inc neoVehicle_fs_gl.inc \
im2d_UV2_gl.inc screenDroplet_fs_gl.inc
im2d_gl.inc: im2d.vert
(echo 'const char *im2d_vert_src =';\
sed 's/..*/"&\\n"/' im2d.vert;\
echo ';') >im2d_gl.inc
colourfilterVC_fs_gl.inc: colourfilterVC.frag
(echo 'const char *colourfilterVC_frag_src =';\
sed 's/..*/"&\\n"/' colourfilterVC.frag;\
echo ';') >colourfilterVC_fs_gl.inc
simple_fs_gl.inc: simple.frag
(echo 'const char *simple_frag_src =';\
sed 's/..*/"&\\n"/' simple.frag;\
echo ';') >simple_fs_gl.inc
default_UV2_gl.inc: default_UV2.vert
(echo 'const char *default_UV2_vert_src =';\
sed 's/..*/"&\\n"/' default_UV2.vert;\
echo ';') >default_UV2_gl.inc
contrast_fs_gl.inc: contrast.frag
(echo 'const char *contrast_frag_src =';\
sed 's/..*/"&\\n"/' contrast.frag;\
echo ';') >contrast_fs_gl.inc
neoRim_gl.inc: neoRim.vert
(echo 'const char *neoRim_vert_src =';\
sed 's/..*/"&\\n"/' neoRim.vert;\
echo ';') >neoRim_gl.inc
neoRimSkin_gl.inc: neoRimSkin.vert
(echo 'const char *neoRimSkin_vert_src =';\
sed 's/..*/"&\\n"/' neoRimSkin.vert;\
echo ';') >neoRimSkin_gl.inc
neoWorldVC_fs_gl.inc: neoWorldVC.frag
(echo 'const char *neoWorldVC_frag_src =';\
sed 's/..*/"&\\n"/' neoWorldVC.frag;\
echo ';') >neoWorldVC_fs_gl.inc
neoGloss_fs_gl.inc: neoGloss.frag
(echo 'const char *neoGloss_frag_src =';\
sed 's/..*/"&\\n"/' neoGloss.frag;\
echo ';') >neoGloss_fs_gl.inc
neoGloss_vs_gl.inc: neoGloss.vert
(echo 'const char *neoGloss_vert_src =';\
sed 's/..*/"&\\n"/' neoGloss.vert;\
echo ';') >neoGloss_vs_gl.inc
neoVehicle_vs_gl.inc: neoVehicle.vert
(echo 'const char *neoVehicle_vert_src =';\
sed 's/..*/"&\\n"/' neoVehicle.vert;\
echo ';') >neoVehicle_vs_gl.inc
neoVehicle_fs_gl.inc: neoVehicle.frag
(echo 'const char *neoVehicle_frag_src =';\
sed 's/..*/"&\\n"/' neoVehicle.frag;\
echo ';') >neoVehicle_fs_gl.inc
im2d_UV2_gl.inc: im2d_UV2.vert
(echo 'const char *im2d_UV2_vert_src =';\
sed 's/..*/"&\\n"/' im2d_UV2.vert;\
echo ';') >im2d_UV2_gl.inc
screenDroplet_fs_gl.inc: screenDroplet.frag
(echo 'const char *screenDroplet_frag_src =';\
sed 's/..*/"&\\n"/' screenDroplet.frag;\
echo ';') >screenDroplet_fs_gl.inc

View file

@ -0,0 +1,9 @@
#!sh
for i in *.vert; do
echo $i
./makeinc_glsl.sh $i
done
for i in *.frag; do
echo $i
./makeinc_glsl.sh $i
done

View file

@ -1,3 +1,3 @@
@echo off
for %%f in (*PS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T ps_2_0 /nologo /E main /Fo %%~nf.cso %%f
for %%f in (*VS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T vs_2_0 /nologo /E main /Fo %%~nf.cso %%f
for %%f in (*PS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T ps_2_0 /nologo /E main /Fo obj\%%~nf.cso %%f
for %%f in (*VS.hlsl) do "%DXSDK_DIR%\Utilities\bin\x86\fxc.exe" /T vs_2_0 /nologo /E main /Fo obj\%%~nf.cso %%f

View file

@ -0,0 +1,6 @@
#!sh
ext=${1##*.}
name=${1%.*}
(echo "const char *${name}_${ext}_src =";\
sed 's/..*/"&\\n"/' $1;\
echo ';') > obj/${name}_${ext}.inc

View file

@ -1,4 +1,5 @@
#!sh
cd obj
for i in *cso; do
(echo -n 'static '
xxd -i $i | grep -v '_len = ') > ${i%cso}inc

View file

@ -1609,7 +1609,7 @@ CPed::ProcessBuoyancy(void)
color.r = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f;
color.g = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f;
color.b = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f;
color.a = (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48;
color.a = CGeneral::GetRandomNumberInRange(48.0f, 96.0f);
bIsInWater = true;
ApplyMoveForce(buoyancyImpulse);
if (!DyingOrDead()) {

View file

@ -639,7 +639,7 @@ public:
uint32 m_threatFlags;
uint32 m_threatCheckTimer;
uint32 m_threatCheckInterval;
uint32 m_delayedSoundID;
int32 m_delayedSoundID;
uint32 m_delayedSoundTimer;
uint32 m_lastSoundStart;
uint32 m_soundStart;

View file

@ -113,7 +113,11 @@ const C2dEffect* CPedAttractorManager::GetEffectForIceCreamVan(CVehicle* pVehicl
CVehicleToEffect effect(pVehicle);
vVehicleToEffect.push_back(effect);
POP_MEMID();
#ifdef FIX_BUGS
return vVehicleToEffect.back().ChooseEffect(pos);
#else
return effect.ChooseEffect(pos);
#endif
}
CVehicle* CPedAttractorManager::GetIceCreamVanForEffect(C2dEffect* pEffect)

View file

@ -406,16 +406,19 @@ CFont::DrawButton(float x, float y)
if (PS2Symbol != BUTTON_NONE) {
CRect rect;
rect.left = x;
rect.top = Details.scaleY + Details.scaleY + y;
rect.right = Details.scaleY * 17.0f + x;
rect.bottom = Details.scaleY * 19.0f + y;
rect.top = RenderState.scaleY + RenderState.scaleY + y;
rect.right = RenderState.scaleY * 17.0f + x;
rect.bottom = RenderState.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));
if (RenderState.bIsShadow)
ButtonSprite[PS2Symbol].Draw(rect, RenderState.color);
else
ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, RenderState.color.a));
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)vertexAlphaState);
}
@ -585,7 +588,7 @@ CFont::RenderFontBuffer()
#ifdef BUTTON_ICONS
if(PS2Symbol != BUTTON_NONE) {
DrawButton(textPosX, textPosY);
textPosX += Details.scaleY * 17.0f;
textPosX += RenderState.scaleY * 17.0f;
PS2Symbol = BUTTON_NONE;
}
#endif

View file

@ -1140,18 +1140,18 @@ void CHud::Draw()
if (IntroRect.m_nTextureId >= 0) {
CRect rect (
IntroRect.m_sRect.left,
IntroRect.m_sRect.top,
IntroRect.m_sRect.bottom,
IntroRect.m_sRect.right,
IntroRect.m_sRect.bottom );
IntroRect.m_sRect.top );
CTheScripts::ScriptSprites[IntroRect.m_nTextureId].Draw(rect, IntroRect.m_sColor);
}
else {
CRect rect (
IntroRect.m_sRect.left,
IntroRect.m_sRect.top,
IntroRect.m_sRect.bottom,
IntroRect.m_sRect.right,
IntroRect.m_sRect.bottom );
IntroRect.m_sRect.top );
CSprite2d::DrawRect(rect, IntroRect.m_sColor);
}
@ -1172,7 +1172,14 @@ void CHud::Draw()
CFont::SetBackgroundColor(CRGBA(0, 0, 0, 128));
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetDropShadowPosition(0);
#ifdef CUTSCENE_BORDERS_SWITCH
if (!FrontEndMenuManager.m_PrefsCutsceneBorders) {
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
CFont::SetDropShadowPosition(2);
}
else
#endif
CFont::SetDropShadowPosition(0);
CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetColor(CRGBA(225, 225, 225, 255));
@ -1182,10 +1189,6 @@ void CHud::Draw()
onceItWasWidescreen = true;
if (FrontEndMenuManager.m_PrefsShowSubtitles || !CCutsceneMgr::IsRunning()) {
#ifdef CUTSCENE_BORDERS_SWITCH
if (!FrontEndMenuManager.m_PrefsCutsceneBorders)
CFont::SetDropShadowPosition(2);
#endif
CFont::SetCentreSize(SCREEN_WIDTH - SCREEN_SCALE_X(60.0f));
CFont::SetScale(SCREEN_SCALE_X(0.58f), SCREEN_SCALE_Y(1.2f));
CFont::PrintString(SCREEN_WIDTH / 2.f, SCREEN_SCALE_FROM_BOTTOM(80.0f), m_Message);
@ -1224,7 +1227,7 @@ void CHud::Draw()
m_HelpMessageDisplayTime = CMessages::GetWideStringLength(m_HelpMessage) * 0.05f + 3.0f;
if (TheCamera.m_ScreenReductionPercentage == 0.0f)
DMAudio.PlayFrontEndSound(SOUND_HUD_SOUND, 0);
DMAudio.PlayFrontEndSound(SOUND_HUD, 0);
break;
case 1:
case 2:

View file

@ -1394,6 +1394,10 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
void
CRenderer::InsertEntityIntoList(CEntity *ent)
{
#ifdef FIX_BUGS
if (!ent->m_rwObject) return;
#endif
#ifdef NEW_RENDERER
// TODO: there are more flags being checked here
if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))

View file

@ -73,7 +73,7 @@ RwRaster *gpWaterEnvBaseRaster;
RwRaster *gpWaterWakeRaster;
bool _bSeaLife;
float _fWaterZOffset = 0.5f;
float _fWaterZOffset = WATER_Z_OFFSET;
#ifdef PC_WATER
float fEnvScale = 0.25f;
@ -318,6 +318,7 @@ CWaterLevel::Shutdown()
_DELETE_TEXTURE(gpWaterTex);
_DELETE_TEXTURE(gpWaterEnvTex);
_DELETE_TEXTURE(gpWaterWakeTex);
_DELETE_TEXTURE(gpWaterEnvBaseTex);
#undef _DELETE_TEXTURE
@ -714,9 +715,9 @@ CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool
if ( y < 0 || y >= MAX_SMALL_SECTORS ) return false;
#endif
uint8 nBlock = aWaterFineBlockList[x][y];
int8 nBlock = aWaterFineBlockList[x][y];
if ( nBlock == 0x80 )
if ( nBlock == NO_WATER )
return false;
ASSERT( pfOutLevel != nil );
@ -756,9 +757,9 @@ CWaterLevel::GetWaterLevelNoWaves(float fX, float fY, float fZ, float *pfOutLeve
if ( y < 0 || y >= MAX_SMALL_SECTORS ) return false;
#endif
uint8 nBlock = aWaterFineBlockList[x][y];
int8 nBlock = aWaterFineBlockList[x][y];
if ( nBlock == 0x80 )
if ( nBlock == NO_WATER )
return false;
ASSERT( pfOutLevel != nil );
@ -1076,7 +1077,7 @@ CWaterLevel::RenderWater()
{
for ( int32 y = 0; y < 5; y++ )
{
float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - 400.0f;
float fX = WATER_SIGN_X(float(x) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f - WATER_X_OFFSET;
float fY = WATER_SIGN_Y(float(y) * EXTRAHUGE_SECTOR_SIZE) - 1280.0f;
if ( !bUseCamStartY )
@ -1462,7 +1463,7 @@ CWaterLevel::RenderTransparentWater(void)
int32 nBlock;
int32 BlockX = WATER_TO_SMALL_SECTOR_X(fCamX + 400.0f) + 1;
int32 BlockX = WATER_TO_SMALL_SECTOR_X(fCamX + WATER_X_OFFSET) + 1;
int32 BlockY = WATER_TO_SMALL_SECTOR_Y(fCamY) + 1;
if (_IsColideWithBlock(BlockX, BlockY, nBlock))
@ -1472,7 +1473,7 @@ CWaterLevel::RenderTransparentWater(void)
float fMaskX = Floor(fCamX / 2.0f) * 2.0f;
float fMaskY = Floor(fCamY / 2.0f) * 2.0f;
float fWaterZ = CWaterLevel::ms_aWaterZs[nBlock];
float fSectorX = WATER_FROM_SMALL_SECTOR_X(BlockX) - 400.0f;
float fSectorX = WATER_FROM_SMALL_SECTOR_X(BlockX) - WATER_X_OFFSET;
float fSectorY = WATER_FROM_SMALL_SECTOR_Y(BlockY);
RenderWavyMask(fMaskX, fMaskY, fWaterZ,

View file

@ -1,6 +1,7 @@
#pragma warning( push )
#pragma warning( disable : 4005)
#pragma warning( pop )
#define FORCE_PC_SCALING
#ifndef LIBRW
#define WITHD3D
#endif
@ -320,7 +321,11 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
splash->Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), SCREEN_SCALE_FROM_RIGHT(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(64, 64, 64, 255));
#ifdef FIX_BUGS
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 150, 225, 255));
#else
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(240.0f), (SCREEN_SCALE_FROM_RIGHT(200.0f) - SCREEN_SCALE_X(200.0f)) * ((float)num / (float)count) + SCREEN_SCALE_X(200.0f), SCREEN_SCALE_Y(248.0f)), CRGBA(255, 217, 106, 255));
#endif
CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(120.0f), SCREEN_SCALE_Y(150.0f), SCREEN_SCALE_FROM_RIGHT(120.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(220.0f)), CRGBA(50, 50, 50, 210));
CFont::SetBackgroundOff();
@ -329,7 +334,11 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
CFont::SetCentreOff();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
CFont::SetJustifyOff();
#ifdef FIX_BUGS
CFont::SetColor(CRGBA(255, 150, 225, 255));
#else
CFont::SetColor(CRGBA(255, 217, 106, 255));
#endif
CFont::SetBackGroundOnlyTextOff();
CFont::SetFontStyle(FONT_STANDARD);
CFont::PrintString(SCREEN_SCALE_X(170.0f), SCREEN_SCALE_Y(160.0f), TheText.Get(text));

View file

@ -96,6 +96,10 @@ CVisibilityPlugins::InitAlphaEntityList(void)
bool
CVisibilityPlugins::InsertEntityIntoSortedList(CEntity *e, float dist)
{
#ifdef FIX_BUGS
if (!e->m_rwObject) return true;
#endif
AlphaObjectInfo item;
item.entity = e;
item.sort = dist;

View file

@ -67,16 +67,16 @@ bool StillToFadeOut;
uint32 TimeStartedCountingForFade;
uint32 TimeToStayFadedBeforeFadeOut = 1750;
uint32 RadioStationPosition[NUM_RADIOS];
int32 RadioStationPosition[NUM_RADIOS];
void
InitRadioStationPositionList()
{
for (int i = 0; i < NUM_RADIOS; i++)
RadioStationPosition[i] = 0;
RadioStationPosition[i] = -1;
}
uint32
int32
GetSavedRadioStationPosition(int32 station)
{
return RadioStationPosition[station];

View file

@ -6,7 +6,7 @@
#define SLOT_COUNT (8)
void InitRadioStationPositionList();
uint32 GetSavedRadioStationPosition(int32 station);
int32 GetSavedRadioStationPosition(int32 station);
void PopulateRadioStationPositionList();
bool GenericSave(int file);
bool GenericLoad();

View file

@ -32,8 +32,8 @@ HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char *folder = strtok(pathCopy, "*");
char *extension = strtok(NULL, "*");
// because strtok doesn't return NULL for last delimiter
if (extension - folder == strlen(pathname))
// because I remember like strtok might not return NULL for last delimiter
if (extension && extension - folder == strlen(pathname))
extension = nil;
// Case-sensitivity and backslashes...
@ -187,7 +187,7 @@ char* casepath(char const* path, bool checkPathFirst)
rl = 1;
}
bool cantProceed = false; // just convert slashes in what's left in string, not case sensitivity
bool cantProceed = false; // just convert slashes in what's left in string, don't correct case of letters(because we can't)
bool mayBeTrailingSlash = false;
char* c;
while (c = strsep(&p, "/\\"))
@ -251,7 +251,7 @@ char* casepath(char const* path, bool checkPathFirst)
}
if (rl > l + 2) {
printf("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%d chars)\n\tCorrected: %s (%d chars)\n\n", path, l, out, rl);
printf("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%zu chars)\n\tCorrected: %s (%zu chars)\n\n", path, l, out, rl);
}
return out;
}

View file

@ -1271,10 +1271,11 @@ void terminateHandler(int sig, siginfo_t *info, void *ucontext) {
RsGlobal.quit = TRUE;
}
#ifdef FLUSHABLE_STREAMING
void dummyHandler(int sig){
// Don't kill the app pls
}
#endif
#endif
void resizeCB(GLFWwindow* window, int width, int height) {
@ -1447,7 +1448,7 @@ bool rshiftStatus = false;
void
keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key >= 0 && key <= GLFW_KEY_LAST) {
if (key >= 0 && key <= GLFW_KEY_LAST && action != GLFW_REPEAT) {
RsKeyCodes ks = (RsKeyCodes)keymap[key];
if (key == GLFW_KEY_LEFT_SHIFT)
@ -1458,7 +1459,6 @@ keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
if (action == GLFW_RELEASE) RsKeyboardEventHandler(rsKEYUP, &ks);
else if (action == GLFW_PRESS) RsKeyboardEventHandler(rsKEYDOWN, &ks);
else if (action == GLFW_REPEAT) RsKeyboardEventHandler(rsKEYDOWN, &ks);
}
}
@ -1528,11 +1528,13 @@ main(int argc, char *argv[])
act.sa_sigaction = terminateHandler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &act, NULL);
#ifdef FLUSHABLE_STREAMING
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_handler = dummyHandler;
sa.sa_flags = 0;
sigaction(SIGUSR1, &sa, NULL); // Needed for CdStreamPosix
sigaction(SIGUSR1, &sa, NULL);
#endif
#endif
/*

View file

@ -9,7 +9,7 @@
#include "Text.h"
#include "Timer.h"
static wchar WideErrorString[25];
wchar WideErrorString[25];
CText TheText;

View file

@ -152,7 +152,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
if(m_audioEntityId >= 0)
DMAudio.SetEntityStatus(m_audioEntityId, true);
//m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK;
//m_nRadioStation = CGeneral::GetRandomNumber() % NUM_RADIOS;
switch(GetModelIndex()){
case MI_HUNTER:
case MI_ANGEL:
@ -169,7 +169,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
m_nRadioStation = RADIO_OFF;
break;
default:
m_nRadioStation = CGeneral::GetRandomNumber() % USERTRACK;
m_nRadioStation = CGeneral::GetRandomNumber() % NUM_RADIOS;
break;
}
m_pCurGroundEntity = nil;

View file

@ -266,7 +266,7 @@ public:
eCarLock m_nDoorLock;
int8 m_nLastWeaponDamage; // see eWeaponType, -1 if no damage
CEntity *m_pLastDamageEntity;
int8 m_nRadioStation;
uint8 m_nRadioStation;
uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter;
uint32 m_nCarHornTimer;