1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-11-06 06:25:54 +00:00

Merge branch 'miami' into lcs

* miami:
  wtf
  fix
  small cleanup
  Fix gOneShotCol
  Fix garage messages position
  Fix font on green screen counter
  Add MPG123_QUIET to mp3 files
  Make opus available alongside other formats
  Fix pickup text
  Fix char in stats
  Add missing GXT line
  fail
  minor refactoring
  Fix 16KHz track
  GET_WHEELIE_STATS fix
  Cleanup and fixes for new decoders
  Fixes for CVbFile
  Small fixes for new wav decoder
  Remove fastmath from premake's config
  Implementing our own WAV decoder to replace SndFile
This commit is contained in:
Sergeanur 2021-01-08 14:47:37 +02:00
commit 0e2af13656
23 changed files with 731 additions and 369 deletions

Binary file not shown.

View file

@ -125,11 +125,9 @@ workspace "reLCS"
filter { "platforms:*x86*" } filter { "platforms:*x86*" }
architecture "x86" architecture "x86"
floatingpoint "Fast"
filter { "platforms:*amd64*" } filter { "platforms:*amd64*" }
architecture "amd64" architecture "amd64"
floatingpoint "Fast"
filter { "platforms:*arm*" } filter { "platforms:*arm*" }
architecture "ARM" architecture "ARM"
@ -192,11 +190,9 @@ project "librw"
filter { "platforms:*x86*" } filter { "platforms:*x86*" }
architecture "x86" architecture "x86"
floatingpoint "Fast"
filter { "platforms:*amd64*" } filter { "platforms:*amd64*" }
architecture "amd64" architecture "amd64"
floatingpoint "Fast"
filter "platforms:win*" filter "platforms:win*"
staticruntime "on" staticruntime "on"

View file

@ -219,7 +219,9 @@ static const int32 gOneShotCol[] = {SFX_COL_TARMAC_1,
SFX_TYRE_BUMP, SFX_TYRE_BUMP,
SFX_COL_CARDBOARD_1, SFX_COL_CARDBOARD_1,
SFX_COL_TARMAC_1, SFX_COL_TARMAC_1,
SFX_COL_GATE}; SFX_COL_GATE,
SFX_COL_SAND_1,
SFX_COL_TARMAC_1 };
void void
cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col) cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)

View file

@ -4,16 +4,23 @@
#include "stream.h" #include "stream.h"
#include "sampman.h" #include "sampman.h"
#ifdef AUDIO_OPUS
#include <opusfile.h>
#else
#ifdef _WIN32 #ifdef _WIN32
#ifdef AUDIO_OAL_USE_SNDFILE
#pragma comment( lib, "libsndfile-1.lib" ) #pragma comment( lib, "libsndfile-1.lib" )
#endif
#ifdef AUDIO_OAL_USE_MPG123
#pragma comment( lib, "libmpg123-0.lib" ) #pragma comment( lib, "libmpg123-0.lib" )
#endif #endif
#endif
#ifdef AUDIO_OAL_USE_SNDFILE
#include <sndfile.h> #include <sndfile.h>
#endif
#ifdef AUDIO_OAL_USE_MPG123
#include <mpg123.h> #include <mpg123.h>
#endif #endif
#ifdef AUDIO_OAL_USE_OPUS
#include <opusfile.h>
#endif
#ifndef _WIN32 #ifndef _WIN32
#include "crossplatform.h" #include "crossplatform.h"
@ -77,7 +84,315 @@ public:
CSortStereoBuffer SortStereoBuffer; CSortStereoBuffer SortStereoBuffer;
#ifndef AUDIO_OPUS class CImaADPCMDecoder
{
const uint16 StepTable[89] = {
7, 8, 9, 10, 11, 12, 13, 14,
16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66,
73, 80, 88, 97, 107, 118, 130, 143,
157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658,
724, 796, 876, 963, 1060, 1166, 1282, 1411,
1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767
};
int16 Sample, StepIndex;
public:
CImaADPCMDecoder()
{
Init(0, 0);
}
void Init(int16 _Sample, int16 _StepIndex)
{
Sample = _Sample;
StepIndex = _StepIndex;
}
void Decode(uint8 *inbuf, int16 *_outbuf, size_t size)
{
int16* outbuf = _outbuf;
for (size_t i = 0; i < size; i++)
{
*(outbuf++) = DecodeSample(inbuf[i] & 0xF);
*(outbuf++) = DecodeSample(inbuf[i] >> 4);
}
}
int16 DecodeSample(uint8 adpcm)
{
uint16 step = StepTable[StepIndex];
if (adpcm & 4)
StepIndex += ((adpcm & 3) + 1) * 2;
else
StepIndex--;
StepIndex = clamp(StepIndex, 0, 88);
int delta = step >> 3;
if (adpcm & 1) delta += step >> 2;
if (adpcm & 2) delta += step >> 1;
if (adpcm & 4) delta += step;
if (adpcm & 8) delta = -delta;
int newSample = Sample + delta;
Sample = clamp(newSample, -32768, 32767);
return Sample;
}
};
class CWavFile : public IDecoder
{
enum
{
WAVEFMT_PCM = 1,
WAVEFMT_IMA_ADPCM = 0x11,
WAVEFMT_XBOX_ADPCM = 0x69,
};
struct tDataHeader
{
uint32 ID;
uint32 Size;
};
struct tFormatHeader
{
uint16 AudioFormat;
uint16 NumChannels;
uint32 SampleRate;
uint32 ByteRate;
uint16 BlockAlign;
uint16 BitsPerSample;
uint16 extra[2]; // adpcm only
tFormatHeader() { memset(this, 0, sizeof(*this)); }
};
FILE *m_pFile;
bool m_bIsOpen;
tFormatHeader m_FormatHeader;
uint32 m_DataStartOffset; // TODO: 64 bit?
uint32 m_nSampleCount;
uint32 m_nSamplesPerBlock;
// ADPCM things
uint8 *m_pAdpcmBuffer;
int16 **m_ppPcmBuffers;
CImaADPCMDecoder *m_pAdpcmDecoders;
void Close()
{
if (m_pFile) {
fclose(m_pFile);
m_pFile = nil;
}
delete[] m_pAdpcmBuffer;
delete[] m_ppPcmBuffers;
delete[] m_pAdpcmDecoders;
}
uint32 GetCurrentSample() const
{
// TODO: 64 bit?
uint32 FilePos = ftell(m_pFile);
if (FilePos <= m_DataStartOffset)
return 0;
return (FilePos - m_DataStartOffset) / m_FormatHeader.BlockAlign * m_nSamplesPerBlock;
}
public:
CWavFile(const char* path) : m_bIsOpen(false), m_DataStartOffset(0), m_nSampleCount(0), m_nSamplesPerBlock(0), m_pAdpcmBuffer(nil), m_ppPcmBuffers(nil), m_pAdpcmDecoders(nil)
{
m_pFile = fopen(path, "rb");
if (!m_pFile) return;
#define CLOSE_ON_ERROR(op)\
if (op) { \
Close(); \
return; \
}
tDataHeader DataHeader;
CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0);
CLOSE_ON_ERROR(DataHeader.ID != 'FFIR');
// TODO? validate filesizes
int WAVE;
CLOSE_ON_ERROR(fread(&WAVE, 4, 1, m_pFile) == 0);
CLOSE_ON_ERROR(WAVE != 'EVAW')
CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0);
CLOSE_ON_ERROR(DataHeader.ID != ' tmf');
CLOSE_ON_ERROR(fread(&m_FormatHeader, Min(DataHeader.Size, sizeof(tFormatHeader)), 1, m_pFile) == 0);
CLOSE_ON_ERROR(DataHeader.Size > sizeof(tFormatHeader));
switch (m_FormatHeader.AudioFormat)
{
case WAVEFMT_XBOX_ADPCM:
m_FormatHeader.AudioFormat = WAVEFMT_IMA_ADPCM;
case WAVEFMT_IMA_ADPCM:
m_nSamplesPerBlock = (m_FormatHeader.BlockAlign / m_FormatHeader.NumChannels - 4) * 2 + 1;
m_pAdpcmBuffer = new uint8[m_FormatHeader.BlockAlign];
m_ppPcmBuffers = new int16*[m_FormatHeader.NumChannels];
m_pAdpcmDecoders = new CImaADPCMDecoder[m_FormatHeader.NumChannels];
break;
case WAVEFMT_PCM:
m_nSamplesPerBlock = 1;
if (m_FormatHeader.BitsPerSample != 16)
{
debug("Unsupported PCM (%d bits), only signed 16-bit is supported (%s)\n", m_FormatHeader.BitsPerSample, path);
Close();
return;
}
break;
default:
debug("Unsupported wav format 0x%x (%s)\n", m_FormatHeader.AudioFormat, path);
Close();
return;
}
while (true) {
CLOSE_ON_ERROR(fread(&DataHeader, sizeof(DataHeader), 1, m_pFile) == 0);
if (DataHeader.ID == 'atad')
break;
fseek(m_pFile, DataHeader.Size, SEEK_CUR);
// TODO? validate data size
// maybe check if there no extreme custom headers that might break this
}
m_DataStartOffset = ftell(m_pFile);
m_nSampleCount = DataHeader.Size / m_FormatHeader.BlockAlign * m_nSamplesPerBlock;
m_bIsOpen = true;
#undef CLOSE_ON_ERROR
}
~CWavFile()
{
Close();
}
bool IsOpened()
{
return m_bIsOpen;
}
uint32 GetSampleSize()
{
return sizeof(uint16);
}
uint32 GetSampleCount()
{
return m_nSampleCount;
}
uint32 GetSampleRate()
{
return m_FormatHeader.SampleRate;
}
uint32 GetChannels()
{
return m_FormatHeader.NumChannels;
}
void Seek(uint32 milliseconds)
{
if (!IsOpened()) return;
fseek(m_pFile, m_DataStartOffset + ms2samples(milliseconds) / m_nSamplesPerBlock * m_FormatHeader.BlockAlign, SEEK_SET);
}
uint32 Tell()
{
if (!IsOpened()) return 0;
return samples2ms(GetCurrentSample());
}
#define SAMPLES_IN_LINE (8)
uint32 Decode(void* buffer)
{
if (!IsOpened()) return 0;
if (m_FormatHeader.AudioFormat == WAVEFMT_PCM)
{
// just read the file and sort the samples
uint32 size = fread(buffer, 1, GetBufferSize(), m_pFile);
if (m_FormatHeader.NumChannels == 2)
SortStereoBuffer.SortStereo(buffer, size);
return size;
}
else if (m_FormatHeader.AudioFormat == WAVEFMT_IMA_ADPCM)
{
// trim the buffer size if we're at the end of our file
uint32 nMaxSamples = GetBufferSamples() / m_FormatHeader.NumChannels;
uint32 nSamplesLeft = m_nSampleCount - GetCurrentSample();
nMaxSamples = Min(nMaxSamples, nSamplesLeft);
// align sample count to our block
nMaxSamples = nMaxSamples / m_nSamplesPerBlock * m_nSamplesPerBlock;
// count the size of output buffer
uint32 OutBufSizePerChannel = nMaxSamples * GetSampleSize();
uint32 OutBufSize = OutBufSizePerChannel * m_FormatHeader.NumChannels;
// calculate the pointers to individual channel buffers
for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++)
m_ppPcmBuffers[i] = (int16*)((int8*)buffer + OutBufSizePerChannel * i);
uint32 samplesRead = 0;
while (samplesRead < nMaxSamples)
{
// read the file
uint8 *pAdpcmBuf = m_pAdpcmBuffer;
if (fread(m_pAdpcmBuffer, 1, m_FormatHeader.BlockAlign, m_pFile) == 0)
return 0;
// get the first sample in adpcm block and initialise the decoder(s)
for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++)
{
int16 Sample = *(int16*)pAdpcmBuf;
pAdpcmBuf += sizeof(int16);
int16 Step = *(int16*)pAdpcmBuf;
pAdpcmBuf += sizeof(int16);
m_pAdpcmDecoders[i].Init(Sample, Step);
*(m_ppPcmBuffers[i]) = Sample;
m_ppPcmBuffers[i]++;
}
samplesRead++;
// decode the rest of the block
for (uint32 s = 1; s < m_nSamplesPerBlock; s += SAMPLES_IN_LINE)
{
for (uint32 i = 0; i < m_FormatHeader.NumChannels; i++)
{
m_pAdpcmDecoders[i].Decode(pAdpcmBuf, m_ppPcmBuffers[i], SAMPLES_IN_LINE / 2);
pAdpcmBuf += SAMPLES_IN_LINE / 2;
m_ppPcmBuffers[i] += SAMPLES_IN_LINE;
}
samplesRead += SAMPLES_IN_LINE;
}
}
return OutBufSize;
}
return 0;
}
};
#ifdef AUDIO_OAL_USE_SNDFILE
class CSndFile : public IDecoder class CSndFile : public IDecoder
{ {
SNDFILE *m_pfSound; SNDFILE *m_pfSound;
@ -146,12 +461,11 @@ public:
return size; return size;
} }
}; };
#endif
#ifdef _WIN32 #ifdef AUDIO_OAL_USE_MPG123
// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though) // fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though)
#define MP3_USE_FUZZY_SEEK #define MP3_USE_FUZZY_SEEK
#endif // _WIN32
class CMP3File : public IDecoder class CMP3File : public IDecoder
{ {
@ -177,7 +491,7 @@ public:
if ( m_pMH ) if ( m_pMH )
{ {
#ifdef MP3_USE_FUZZY_SEEK #ifdef MP3_USE_FUZZY_SEEK
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0); mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0);
#endif #endif
long rate = 0; long rate = 0;
int channels = 0; int channels = 0;
@ -260,6 +574,55 @@ public:
} }
}; };
class CADFFile : public CMP3File
{
static ssize_t r_read(void* fh, void* buf, size_t size)
{
size_t bytesRead = fread(buf, 1, size, (FILE*)fh);
uint8* _buf = (uint8*)buf;
for (size_t i = 0; i < size; i++)
_buf[i] ^= 0x22;
return bytesRead;
}
static off_t r_seek(void* fh, off_t pos, int seekType)
{
fseek((FILE*)fh, pos, seekType);
return ftell((FILE*)fh);
}
static void r_close(void* fh)
{
fclose((FILE*)fh);
}
public:
CADFFile(const char* path)
{
m_pMH = mpg123_new(nil, nil);
if (m_pMH)
{
#ifdef MP3_USE_FUZZY_SEEK
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0);
#endif
long rate = 0;
int channels = 0;
int encoding = 0;
FILE* f = fopen(path, "rb");
m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK
&& mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if (IsOpened())
{
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
}
}
};
#endif
#define VAG_LINE_SIZE (0x10) #define VAG_LINE_SIZE (0x10)
#define VAG_SAMPLES_IN_LINE (28) #define VAG_SAMPLES_IN_LINE (28)
@ -287,7 +650,7 @@ public:
static short quantize(double sample) static short quantize(double sample)
{ {
int a = int(sample + 0.5); int a = int(sample + 0.5);
return short(clamp(int(sample + 0.5), -32768, 32767)); return short(clamp(a, -32768, 32767));
} }
void Decode(void* _inbuf, int16* _outbuf, size_t size) void Decode(void* _inbuf, int16* _outbuf, size_t size)
@ -331,10 +694,11 @@ public:
class CVbFile : public IDecoder class CVbFile : public IDecoder
{ {
FILE* pFile; FILE *m_pFile;
CVagDecoder *m_pVagDecoders;
size_t m_FileSize; size_t m_FileSize;
size_t m_nNumberOfBlocks; size_t m_nNumberOfBlocks;
CVagDecoder* decoders;
uint32 m_nSampleRate; uint32 m_nSampleRate;
uint8 m_nChannels; uint8 m_nChannels;
@ -342,53 +706,56 @@ class CVbFile : public IDecoder
uint16 m_LineInBlock; uint16 m_LineInBlock;
size_t m_CurrentBlock; size_t m_CurrentBlock;
uint8** ppTempBuffers; uint8 **m_ppVagBuffers; // buffers that cache actual ADPCM file data
int16 **m_ppPcmBuffers;
void ReadBlock(int32 block = -1) void ReadBlock(int32 block = -1)
{ {
// just read next block if -1 // just read next block if -1
if (block != -1) if (block != -1)
fseek(pFile, block * m_nChannels * VB_BLOCK_SIZE, SEEK_SET); fseek(m_pFile, block * m_nChannels * VB_BLOCK_SIZE, SEEK_SET);
for (int i = 0; i < m_nChannels; i++) for (int i = 0; i < m_nChannels; i++)
fread(ppTempBuffers[i], VB_BLOCK_SIZE, 1, pFile); fread(m_ppVagBuffers[i], VB_BLOCK_SIZE, 1, m_pFile);
m_bBlockRead = true; m_bBlockRead = true;
} }
public: public:
CVbFile(const char* path, uint32 nSampleRate = 32000, uint8 nChannels = 2) : m_nSampleRate(nSampleRate), m_nChannels(nChannels) CVbFile(const char* path, uint32 nSampleRate = 32000, uint8 nChannels = 2) : m_nSampleRate(nSampleRate), m_nChannels(nChannels), m_pVagDecoders(nil), m_ppVagBuffers(nil), m_ppPcmBuffers(nil),
m_FileSize(0), m_nNumberOfBlocks(0), m_bBlockRead(false), m_LineInBlock(0), m_CurrentBlock(0)
{ {
pFile = fopen(path, "rb"); m_pFile = fopen(path, "rb");
if (pFile) { if (!m_pFile) return;
fseek(pFile, 0, SEEK_END);
m_FileSize = ftell(pFile); fseek(m_pFile, 0, SEEK_END);
fseek(pFile, 0, SEEK_SET); m_FileSize = ftell(m_pFile);
fseek(m_pFile, 0, SEEK_SET);
m_nNumberOfBlocks = m_FileSize / (nChannels * VB_BLOCK_SIZE); m_nNumberOfBlocks = m_FileSize / (nChannels * VB_BLOCK_SIZE);
decoders = new CVagDecoder[nChannels]; m_pVagDecoders = new CVagDecoder[nChannels];
m_CurrentBlock = 0; m_ppVagBuffers = new uint8*[nChannels];
m_LineInBlock = 0; m_ppPcmBuffers = new int16*[nChannels];
m_bBlockRead = false;
ppTempBuffers = new uint8 * [nChannels];
for (uint8 i = 0; i < nChannels; i++) for (uint8 i = 0; i < nChannels; i++)
ppTempBuffers[i] = new uint8[VB_BLOCK_SIZE]; m_ppVagBuffers[i] = new uint8[VB_BLOCK_SIZE];
}
} }
~CVbFile() ~CVbFile()
{ {
if (pFile) if (m_pFile)
{ {
fclose(pFile); fclose(m_pFile);
delete decoders;
delete[] m_pVagDecoders;
for (int i = 0; i < m_nChannels; i++) for (int i = 0; i < m_nChannels; i++)
delete ppTempBuffers[i]; delete[] m_ppVagBuffers[i];
delete ppTempBuffers; delete[] m_ppVagBuffers;
delete[] m_ppPcmBuffers;
} }
} }
bool IsOpened() bool IsOpened()
{ {
return pFile != nil; return m_pFile != nil;
} }
uint32 GetSampleSize() uint32 GetSampleSize()
@ -416,15 +783,18 @@ public:
{ {
if (!IsOpened()) return; if (!IsOpened()) return;
uint32 samples = ms2samples(milliseconds); uint32 samples = ms2samples(milliseconds);
int32 block = samples / NUM_VAG_SAMPLES_IN_BLOCK;
// find the block of our sample
uint32 block = samples / NUM_VAG_SAMPLES_IN_BLOCK;
if (block > m_nNumberOfBlocks) if (block > m_nNumberOfBlocks)
{ {
samples = 0; samples = 0;
block = 0; block = 0;
} }
if (block != m_CurrentBlock) if (block != m_CurrentBlock)
ReadBlock(block); m_bBlockRead = false;
// find a line of our sample within our block
uint32 remainingSamples = samples - block * NUM_VAG_SAMPLES_IN_BLOCK; uint32 remainingSamples = samples - block * NUM_VAG_SAMPLES_IN_BLOCK;
uint32 newLine = remainingSamples / VAG_SAMPLES_IN_LINE / VAG_LINE_SIZE; uint32 newLine = remainingSamples / VAG_SAMPLES_IN_LINE / VAG_LINE_SIZE;
@ -432,8 +802,8 @@ public:
{ {
m_CurrentBlock = block; m_CurrentBlock = block;
m_LineInBlock = newLine; m_LineInBlock = newLine;
for (int i = 0; i < GetChannels(); i++) for (uint32 i = 0; i < GetChannels(); i++)
decoders[i].ResetState(); m_pVagDecoders[i].ResetState();
} }
} }
@ -449,44 +819,48 @@ public:
{ {
if (!IsOpened()) return 0; if (!IsOpened()) return 0;
if (m_CurrentBlock >= m_nNumberOfBlocks) return 0;
// cache current ADPCM block
if (!m_bBlockRead) if (!m_bBlockRead)
ReadBlock(m_CurrentBlock); ReadBlock(m_CurrentBlock);
if (m_CurrentBlock == m_nNumberOfBlocks) return 0; // trim the buffer size if we're at the end of our file
int size = 0; int numberOfRequiredLines = GetBufferSamples() / m_nChannels / VAG_SAMPLES_IN_LINE;
int numberOfRequiredLines = GetBufferSamples() / GetChannels() / VAG_SAMPLES_IN_LINE;
int numberOfRemainingLines = (m_nNumberOfBlocks - m_CurrentBlock) * NUM_VAG_LINES_IN_BLOCK - m_LineInBlock; int numberOfRemainingLines = (m_nNumberOfBlocks - m_CurrentBlock) * NUM_VAG_LINES_IN_BLOCK - m_LineInBlock;
int bufSizePerChannel = Min(numberOfRequiredLines, numberOfRemainingLines) * VAG_SAMPLES_IN_LINE * GetSampleSize(); int bufSizePerChannel = Min(numberOfRequiredLines, numberOfRemainingLines) * VAG_SAMPLES_IN_LINE * GetSampleSize();
if (numberOfRequiredLines > numberOfRemainingLines) // calculate the pointers to individual channel buffers
numberOfRemainingLines = numberOfRemainingLines; for (uint32 i = 0; i < m_nChannels; i++)
m_ppPcmBuffers[i] = (int16*)((int8*)buffer + bufSizePerChannel * i);
int16* buffers[2] = { (int16*)buffer, &((int16*)buffer)[bufSizePerChannel / GetSampleSize()] };
int size = 0;
while (size < bufSizePerChannel) while (size < bufSizePerChannel)
{ {
for (int i = 0; i < GetChannels(); i++) // decode the VAG lines
for (uint32 i = 0; i < m_nChannels; i++)
{ {
decoders[i].Decode(ppTempBuffers[i] + m_LineInBlock * VAG_LINE_SIZE, buffers[i], VAG_LINE_SIZE); m_pVagDecoders[i].Decode(m_ppVagBuffers[i] + m_LineInBlock * VAG_LINE_SIZE, m_ppPcmBuffers[i], VAG_LINE_SIZE);
buffers[i] += VAG_SAMPLES_IN_LINE; m_ppPcmBuffers[i] += VAG_SAMPLES_IN_LINE;
} }
size += VAG_SAMPLES_IN_LINE * GetSampleSize(); size += VAG_SAMPLES_IN_LINE * GetSampleSize();
m_LineInBlock++; m_LineInBlock++;
// block is over, read the next block
if (m_LineInBlock >= NUM_VAG_LINES_IN_BLOCK) if (m_LineInBlock >= NUM_VAG_LINES_IN_BLOCK)
{ {
m_CurrentBlock++; m_CurrentBlock++;
if (m_CurrentBlock >= m_nNumberOfBlocks) if (m_CurrentBlock >= m_nNumberOfBlocks) // end of file
break; break;
m_LineInBlock = 0; m_LineInBlock = 0;
ReadBlock(); ReadBlock();
} }
} }
return bufSizePerChannel * GetChannels(); return bufSizePerChannel * m_nChannels;
} }
}; };
#else #ifdef AUDIO_OAL_USE_OPUS
class COpusFile : public IDecoder class COpusFile : public IDecoder
{ {
OggOpusFile *m_FileH; OggOpusFile *m_FileH;
@ -582,64 +956,16 @@ public:
}; };
#endif #endif
class CADFFile : public CMP3File
{
static ssize_t r_read(void* fh, void* buf, size_t size)
{
size_t bytesRead = fread(buf, 1, size, (FILE*)fh);
uint8* _buf = (uint8*)buf;
for (size_t i = 0; i < size; i++)
_buf[i] ^= 0x22;
return bytesRead;
}
static off_t r_seek(void* fh, off_t pos, int seekType)
{
fseek((FILE*)fh, pos, seekType);
return ftell((FILE*)fh);
}
static void r_close(void* fh)
{
fclose((FILE*)fh);
}
public:
CADFFile(const char* path)
{
m_pMH = mpg123_new(nil, nil);
if (m_pMH)
{
#ifdef MP3_USE_FUZZY_SEEK
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
#endif
long rate = 0;
int channels = 0;
int encoding = 0;
FILE* f = fopen(path, "rb");
m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK
&& mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
m_nRate = rate;
m_nChannels = channels;
if (IsOpened())
{
mpg123_format_none(m_pMH);
mpg123_format(m_pMH, rate, channels, encoding);
}
}
}
};
void CStream::Initialise() void CStream::Initialise()
{ {
#ifndef AUDIO_OPUS #ifdef AUDIO_OAL_USE_MPG123
mpg123_init(); mpg123_init();
#endif #endif
} }
void CStream::Terminate() void CStream::Terminate()
{ {
#ifndef AUDIO_OPUS #ifdef AUDIO_OAL_USE_MPG123
mpg123_exit(); mpg123_exit();
#endif #endif
} }
@ -672,17 +998,22 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU
DEV("Stream %s\n", m_aFilename); DEV("Stream %s\n", m_aFilename);
#ifndef AUDIO_OPUS if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav"))
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) #ifdef AUDIO_OAL_USE_SNDFILE
m_pSoundFile = new CMP3File(m_aFilename);
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav"))
m_pSoundFile = new CSndFile(m_aFilename); m_pSoundFile = new CSndFile(m_aFilename);
#else
m_pSoundFile = new CWavFile(m_aFilename);
#endif
#ifdef AUDIO_OAL_USE_MPG123
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3"))
m_pSoundFile = new CMP3File(m_aFilename);
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf")) else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf"))
m_pSoundFile = new CADFFile(m_aFilename); m_pSoundFile = new CADFFile(m_aFilename);
#endif
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB")) else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB"))
m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate); m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate);
#else #ifdef AUDIO_OAL_USE_OPUS
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus"))
m_pSoundFile = new COpusFile(m_aFilename); m_pSoundFile = new COpusFile(m_aFilename);
#endif #endif
else else
@ -979,12 +1310,15 @@ void CStream::Update()
// Relying a lot on left buffer states in here // Relying a lot on left buffer states in here
do
{
//alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f); //alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f);
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]); alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]);
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]); alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
//alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f); //alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f);
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]); alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]); alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]);
} while (buffersProcessed[0] != buffersProcessed[1]);
ALint looping = AL_FALSE; ALint looping = AL_FALSE;
alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping); alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping);

View file

@ -240,7 +240,7 @@ public:
extern cSampleManager SampleManager; extern cSampleManager SampleManager;
extern uint32 BankStartOffset[MAX_SFX_BANKS]; extern uint32 BankStartOffset[MAX_SFX_BANKS];
#ifdef AUDIO_OPUS #if defined(OPUS_AUDIO_PATHS)
static char StreamedNameTable[][25] = { static char StreamedNameTable[][25] = {
"AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS", "AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS",
"AUDIO\\MSX.OPUS", "AUDIO\\FLASH.OPUS", "AUDIO\\CHAT.OPUS", "AUDIO\\HEAD.OPUS", "AUDIO\\POLICE.OPUS", "AUDIO\\CITY.OPUS", "AUDIO\\MSX.OPUS", "AUDIO\\FLASH.OPUS", "AUDIO\\CHAT.OPUS", "AUDIO\\HEAD.OPUS", "AUDIO\\POLICE.OPUS", "AUDIO\\CITY.OPUS",
@ -275,8 +275,7 @@ static char StreamedNameTable[][25] = {
"AUDIO\\h5_b.OPUS", "AUDIO\\h5_c.OPUS", "AUDIO\\ammu_a.OPUS", "AUDIO\\ammu_b.OPUS", "AUDIO\\ammu_c.OPUS", "AUDIO\\door_1.OPUS", "AUDIO\\h5_b.OPUS", "AUDIO\\h5_c.OPUS", "AUDIO\\ammu_a.OPUS", "AUDIO\\ammu_b.OPUS", "AUDIO\\ammu_c.OPUS", "AUDIO\\door_1.OPUS",
"AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS", "AUDIO\\door_2.OPUS", "AUDIO\\door_3.OPUS", "AUDIO\\door_4.OPUS", "AUDIO\\door_5.OPUS", "AUDIO\\door_6.OPUS", "AUDIO\\t3_a.OPUS",
"AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"}; "AUDIO\\t3_b.OPUS", "AUDIO\\t3_c.OPUS", "AUDIO\\k1_b.OPUS", "AUDIO\\cat1.OPUS"};
#else #elif defined(PS2_AUDIO_PATHS)
#ifdef PS2_AUDIO
static char StreamedNameTable[][40] = static char StreamedNameTable[][40] =
{ {
"AUDIO\\MUSIC\\WILD.VB", "AUDIO\\MUSIC\\WILD.VB",
@ -1611,4 +1610,3 @@ static char StreamedNameTable[][25] =
"AUDIO\\BUST_27.WAV", "AUDIO\\BUST_27.WAV",
"AUDIO\\BUST_28.WAV", "AUDIO\\BUST_28.WAV",
}; };
#endif

View file

@ -30,7 +30,7 @@
#include "MusicManager.h" #include "MusicManager.h"
#include "Frontend.h" #include "Frontend.h"
#include "Timer.h" #include "Timer.h"
#ifdef AUDIO_OPUS #ifdef AUDIO_OAL_USE_OPUS
#include <opusfile.h> #include <opusfile.h>
#endif #endif
@ -83,7 +83,7 @@ char SampleBankDescFilename[] = "audio/sfx.SDT";
char SampleBankDataFilename[] = "audio/sfx.RAW"; char SampleBankDataFilename[] = "audio/sfx.RAW";
FILE *fpSampleDescHandle; FILE *fpSampleDescHandle;
#ifdef AUDIO_OPUS #ifdef OPUS_SFX
OggOpusFile *fpSampleDataHandle; OggOpusFile *fpSampleDataHandle;
#else #else
FILE *fpSampleDataHandle; FILE *fpSampleDataHandle;
@ -396,7 +396,7 @@ set_new_provider(int index)
static bool static bool
IsThisTrackAt16KHz(uint32 track) IsThisTrackAt16KHz(uint32 track)
{ {
return track == STREAMED_SOUND_RADIO_KCHAT || track == STREAMED_SOUND_RADIO_VCPR || track == STREAMED_SOUND_AMBSIL_AMBIENT; return track == STREAMED_SOUND_RADIO_KCHAT || track == STREAMED_SOUND_RADIO_VCPR || track == STREAMED_SOUND_RADIO_POLICE;
} }
cSampleManager::cSampleManager(void) cSampleManager::cSampleManager(void)
@ -1245,7 +1245,7 @@ cSampleManager::LoadSampleBank(uint8 nBank)
return false; return false;
} }
#ifdef AUDIO_OPUS #ifdef OPUS_SFX
int samplesRead = 0; int samplesRead = 0;
int samplesSize = nSampleBankSize[nBank] / 2; int samplesSize = nSampleBankSize[nBank] / 2;
op_pcm_seek(fpSampleDataHandle, 0); op_pcm_seek(fpSampleDataHandle, 0);
@ -1350,7 +1350,7 @@ cSampleManager::LoadPedComment(uint32 nComment)
} }
} }
#ifdef AUDIO_OPUS #ifdef OPUS_SFX
int samplesRead = 0; int samplesRead = 0;
int samplesSize = m_aSamples[nComment].nSize / 2; int samplesSize = m_aSamples[nComment].nSize / 2;
op_pcm_seek(fpSampleDataHandle, m_aSamples[nComment].nOffset / 2); op_pcm_seek(fpSampleDataHandle, m_aSamples[nComment].nOffset / 2);
@ -2007,7 +2007,7 @@ cSampleManager::InitialiseSampleBanks(void)
fpSampleDescHandle = fcaseopen(SampleBankDescFilename, "rb"); fpSampleDescHandle = fcaseopen(SampleBankDescFilename, "rb");
if ( fpSampleDescHandle == NULL ) if ( fpSampleDescHandle == NULL )
return false; return false;
#ifndef AUDIO_OPUS #ifndef OPUS_SFX
fpSampleDataHandle = fcaseopen(SampleBankDataFilename, "rb"); fpSampleDataHandle = fcaseopen(SampleBankDataFilename, "rb");
if ( fpSampleDataHandle == NULL ) if ( fpSampleDataHandle == NULL )
{ {
@ -2025,7 +2025,7 @@ cSampleManager::InitialiseSampleBanks(void)
fpSampleDataHandle = op_open_file(SampleBankDataFilename, &e); fpSampleDataHandle = op_open_file(SampleBankDataFilename, &e);
#endif #endif
fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle); fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
#ifdef AUDIO_OPUS #ifdef OPUS_SFX
int32 _nSampleDataEndOffset = m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nOffset + m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nSize; int32 _nSampleDataEndOffset = m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nOffset + m_aSamples[TOTAL_AUDIO_SAMPLES - 1].nSize;
#endif #endif
fclose(fpSampleDescHandle); fclose(fpSampleDescHandle);

View file

@ -12,6 +12,7 @@
#include "Physical.h" #include "Physical.h"
#include "ColStore.h" #include "ColStore.h"
#include "VarConsole.h" #include "VarConsole.h"
#include "Pools.h"
CPool<ColDef,ColDef> *CColStore::ms_pColPool; CPool<ColDef,ColDef> *CColStore::ms_pColPool;
#ifndef MASTER #ifndef MASTER
@ -184,7 +185,18 @@ CColStore::LoadCollision(const CVector2D &pos)
wantThisOne = true; wantThisOne = true;
}else{ }else{
for (int j = 0; j < MAX_CLEANUP; j++) { for (int j = 0; j < MAX_CLEANUP; j++) {
CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j); CPhysical* pEntity = nil;
cleanup_entity_struct* pCleanup = &CTheScripts::MissionCleanUp.m_sEntities[i];
if (pCleanup->type == CLEANUP_CAR) {
pEntity = CPools::GetVehiclePool()->GetAt(pCleanup->id);
if (!pEntity || pEntity->GetStatus() == STATUS_WRECKED)
continue;
}
else if (pCleanup->type == CLEANUP_CHAR) {
pEntity = CPools::GetPedPool()->GetAt(pCleanup->id);
if (!pEntity || ((CPed*)pEntity)->DyingOrDead())
continue;
}
if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) { if (pEntity && !pEntity->bDontLoadCollision && !pEntity->bIsFrozen) {
if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f)) if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f))
wantThisOne = true; wantThisOne = true;

View file

@ -1414,11 +1414,7 @@ void CGarages::PrintMessages()
CFont::SetDropShadowPosition(2); CFont::SetDropShadowPosition(2);
CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetDropColor(CRGBA(0, 0, 0, 255));
#if defined(GTA_PS2) || defined (FIX_BUGS) float y_offset = SCREEN_SCALE_Y(140.0f);
float y_offset = SCREEN_HEIGHT / 3 - SCREEN_SCALE_Y(40.0f); // THIS is PS2 calculation
#else
float y_offset = SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(84.0f); // This is PC and results in text being written over some HUD elements
#endif
if (MessageNumberInString2 >= 0) { if (MessageNumberInString2 >= 0) {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString); CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString);

View file

@ -93,6 +93,7 @@ VALIDATE_SIZE(CStoredCar, 0x28);
class CGarage class CGarage
{ {
public:
uint8 m_eGarageType; uint8 m_eGarageType;
uint8 m_eGarageState; uint8 m_eGarageState;
uint8 m_nMaxStoredCars; uint8 m_nMaxStoredCars;
@ -189,9 +190,6 @@ class CGarage
int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); } int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); }
friend class CGarages;
friend class cAudioManager;
friend class CCamera;
}; };
class CGarages class CGarages
@ -199,6 +197,7 @@ class CGarages
enum { enum {
MESSAGE_LENGTH = 8, MESSAGE_LENGTH = 8,
}; };
public:
static int32 BankVansCollected; static int32 BankVansCollected;
static bool BombsAreFree; static bool BombsAreFree;
static bool RespraysAreFree; static bool RespraysAreFree;
@ -218,7 +217,6 @@ class CGarages
static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS]; static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
static bool bCamShouldBeOutisde; static bool bCamShouldBeOutisde;
public:
static void Init(void); static void Init(void);
#ifndef PS2 #ifndef PS2
static void Shutdown(void); static void Shutdown(void);
@ -259,7 +257,6 @@ public:
static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; } static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; }
static void SetMaxNumStoredCarsForGarage(int16 garage, uint8 num) { aGarages[garage].m_nMaxStoredCars = num; } static void SetMaxNumStoredCarsForGarage(int16 garage, uint8 num) { aGarages[garage].m_nMaxStoredCars = num; }
private:
static bool IsCarSprayable(CVehicle*); static bool IsCarSprayable(CVehicle*);
static float FindDoorHeightForMI(int32); static float FindDoorHeightForMI(int32);
static void CloseHideOutGaragesBeforeSave(void); static void CloseHideOutGaragesBeforeSave(void);
@ -296,7 +293,4 @@ private:
} }
static bool IsThisGarageTypeSafehouse(uint8 type) { return FindSafeHouseIndexForGarageType(type) >= 0; } static bool IsThisGarageTypeSafehouse(uint8 type) { return FindSafeHouseIndexForGarageType(type) >= 0; }
friend class cAudioManager;
friend class CReplay;
friend class CGarage;
}; };

View file

@ -1336,7 +1336,7 @@ CPickups::RenderPickUpText()
#ifdef FIX_BUGS #ifdef FIX_BUGS
const float MAX_SCALE = SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH; const float MAX_SCALE = SCREEN_WIDTH / DEFAULT_SCREEN_WIDTH;
#else #else
const float MAX_SCALE = RsGlobal.width / DEFAULT_SCREEN_WIDTH; float MAX_SCALE = RsGlobal.width / DEFAULT_SCREEN_WIDTH;
#endif #endif
float fScaleY = aMessages[i].m_dist.y / 30.0f; float fScaleY = aMessages[i].m_dist.y / 30.0f;
@ -1345,11 +1345,7 @@ CPickups::RenderPickUpText()
float fScaleX = aMessages[i].m_dist.x / 30.0f; float fScaleX = aMessages[i].m_dist.x / 30.0f;
if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE;
#ifdef FIX_BUGS CFont::SetScale(fScaleX, fScaleY); // this shouldn't be scaled
CFont::SetScale(SCREEN_SCALE_X(fScaleX), SCREEN_SCALE_Y(fScaleY));
#else
CFont::SetScale(fScaleX, fScaleY);
#endif
CFont::SetCentreOn(); CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_WIDTH); CFont::SetCentreSize(SCREEN_WIDTH);
CFont::SetJustifyOff(); CFont::SetJustifyOff();

View file

@ -85,7 +85,7 @@ uint16 CTheScripts::NumScriptDebugLines;
uint16 CTheScripts::NumberOfIntroRectanglesThisFrame; uint16 CTheScripts::NumberOfIntroRectanglesThisFrame;
uint16 CTheScripts::NumberOfIntroTextLinesThisFrame; uint16 CTheScripts::NumberOfIntroTextLinesThisFrame;
uint8 CTheScripts::UseTextCommands; uint8 CTheScripts::UseTextCommands;
CMissionCleanup CTheScripts::MissionCleanup; CMissionCleanup CTheScripts::MissionCleanUp;
CUpsideDownCarCheck CTheScripts::UpsideDownCars; CUpsideDownCarCheck CTheScripts::UpsideDownCars;
CStuckCarCheck CTheScripts::StuckCars; CStuckCarCheck CTheScripts::StuckCars;
uint16 CTheScripts::CommandsExecuted; uint16 CTheScripts::CommandsExecuted;
@ -1693,17 +1693,6 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type)
m_nCount++; m_nCount++;
} }
static void PossiblyWakeThisEntity(CPhysical* pEntity, bool ifColLoaded = false)
{
if (!pEntity->bIsStaticWaitingForCollision)
return;
if (!ifColLoaded || CColStore::HasCollisionLoaded(pEntity->GetPosition())) {
pEntity->bIsStaticWaitingForCollision = false;
if (!pEntity->GetIsStatic())
pEntity->AddToMovingList();
}
}
void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
{ {
for (int i = 0; i < MAX_CLEANUP; i++){ for (int i = 0; i < MAX_CLEANUP; i++){
@ -1711,23 +1700,38 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
switch (m_sEntities[i].type) { switch (m_sEntities[i].type) {
case CLEANUP_CAR: case CLEANUP_CAR:
{ {
CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
if (v) if (pVehicle) {
PossiblyWakeThisEntity(v); if (pVehicle->bIsStaticWaitingForCollision) {
pVehicle->bIsStaticWaitingForCollision = false;
if (!pVehicle->GetIsStatic())
pVehicle->AddToMovingList();
}
}
break; break;
} }
case CLEANUP_CHAR: case CLEANUP_CHAR:
{ {
CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id); CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
if (p) if (pPed) {
PossiblyWakeThisEntity(p); if (pPed->bIsStaticWaitingForCollision) {
pPed->bIsStaticWaitingForCollision = false;
if (!pPed->GetIsStatic())
pPed->AddToMovingList();
}
}
break; break;
} }
case CLEANUP_OBJECT: case CLEANUP_OBJECT:
{ {
CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
if (o) if (pObject) {
PossiblyWakeThisEntity(o); if (pObject->bIsStaticWaitingForCollision) {
pObject->bIsStaticWaitingForCollision = false;
if (!pObject->GetIsStatic())
pObject->AddToMovingList();
}
}
break; break;
} }
default: default:
@ -1746,23 +1750,44 @@ void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects()
switch (m_sEntities[i].type) { switch (m_sEntities[i].type) {
case CLEANUP_CAR: case CLEANUP_CAR:
{ {
CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
if (v) if (pVehicle) {
PossiblyWakeThisEntity(v, true); if (pVehicle->bIsStaticWaitingForCollision) {
if (CColStore::HasCollisionLoaded(pVehicle->GetPosition())) {
pVehicle->bIsStaticWaitingForCollision = false;
if (!pVehicle->GetIsStatic())
pVehicle->AddToMovingList();
}
}
}
break; break;
} }
case CLEANUP_CHAR: case CLEANUP_CHAR:
{ {
CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id); CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
if (p) if (pPed) {
PossiblyWakeThisEntity(p, true); if (pPed->bIsStaticWaitingForCollision) {
if (CColStore::HasCollisionLoaded(pPed->GetPosition())) {
pPed->bIsStaticWaitingForCollision = false;
if (!pPed->GetIsStatic())
pPed->AddToMovingList();
}
}
}
break; break;
} }
case CLEANUP_OBJECT: case CLEANUP_OBJECT:
{ {
CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id); CObject* pObject = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
if (o) if (pObject) {
PossiblyWakeThisEntity(o, true); if (pObject->bIsStaticWaitingForCollision) {
if (CColStore::HasCollisionLoaded(pObject->GetPosition())) {
pObject->bIsStaticWaitingForCollision = false;
if (!pObject->GetIsStatic())
pObject->AddToMovingList();
}
}
}
break; break;
} }
default: default:
@ -1771,21 +1796,6 @@ void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObjects()
} }
} }
CPhysical* CMissionCleanup::DoesThisEntityWaitForCollision(int i)
{
if (m_sEntities[i].type == CLEANUP_CAR) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
if (pVehicle && pVehicle->GetStatus() != STATUS_WRECKED)
return pVehicle;
}
else if (m_sEntities[i].type == CLEANUP_CHAR) {
CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
if (pPed && !pPed->DyingOrDead())
return pPed;
}
return nil;
}
void CMissionCleanup::Process() void CMissionCleanup::Process()
{ {
CPopulation::m_AllRandomPedsThisType = -1; CPopulation::m_AllRandomPedsThisType = -1;
@ -1878,10 +1888,16 @@ void CUpsideDownCarCheck::Init()
bool CUpsideDownCarCheck::IsCarUpsideDown(int32 id) bool CUpsideDownCarCheck::IsCarUpsideDown(int32 id)
{ {
CVehicle* v = CPools::GetVehiclePool()->GetAt(id); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(id);
return v->GetUp().z <= -0.97f && return IsCarUpsideDown(pVehicle);
v->GetMoveSpeed().Magnitude() < 0.01f && }
v->GetTurnSpeed().Magnitude() < 0.02f;
bool CUpsideDownCarCheck::IsCarUpsideDown(CVehicle* pVehicle)
{
assert(pVehicle);
return pVehicle->GetUp().z <= UPSIDEDOWN_UP_THRESHOLD &&
pVehicle->GetMoveSpeed().Magnitude() < UPSIDEDOWN_MOVE_SPEED_THRESHOLD &&
pVehicle->GetTurnSpeed().Magnitude() < UPSIDEDOWN_TURN_SPEED_THRESHOLD;
} }
void CUpsideDownCarCheck::UpdateTimers() void CUpsideDownCarCheck::UpdateTimers()
@ -1904,7 +1920,7 @@ void CUpsideDownCarCheck::UpdateTimers()
bool CUpsideDownCarCheck::AreAnyCarsUpsideDown() bool CUpsideDownCarCheck::AreAnyCarsUpsideDown()
{ {
for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){
if (m_sCars[i].m_nVehicleIndex >= 0 && m_sCars[i].m_nUpsideDownTimer > 1000) if (m_sCars[i].m_nVehicleIndex >= 0 && m_sCars[i].m_nUpsideDownTimer > UPSIDEDOWN_TIMER_THRESHOLD)
return true; return true;
} }
return false; return false;
@ -1915,8 +1931,10 @@ void CUpsideDownCarCheck::AddCarToCheck(int32 id)
uint16 index = 0; uint16 index = 0;
while (index < MAX_UPSIDEDOWN_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0) while (index < MAX_UPSIDEDOWN_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0)
index++; index++;
#ifdef FIX_BUGS
if (index >= MAX_UPSIDEDOWN_CAR_CHECKS) if (index >= MAX_UPSIDEDOWN_CAR_CHECKS)
return; return;
#endif
m_sCars[index].m_nVehicleIndex = id; m_sCars[index].m_nVehicleIndex = id;
m_sCars[index].m_nUpsideDownTimer = 0; m_sCars[index].m_nUpsideDownTimer = 0;
} }
@ -1935,7 +1953,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id)
{ {
for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){ for (int i = 0; i < MAX_UPSIDEDOWN_CAR_CHECKS; i++){
if (m_sCars[i].m_nVehicleIndex == id) if (m_sCars[i].m_nVehicleIndex == id)
return m_sCars[i].m_nUpsideDownTimer > 1000; return m_sCars[i].m_nUpsideDownTimer > UPSIDEDOWN_TIMER_THRESHOLD;
} }
return false; return false;
} }
@ -1985,7 +2003,10 @@ void CStuckCarCheck::AddCarToCheck(int32 id, float radius, uint32 time)
int index = 0; int index = 0;
while (index < MAX_STUCK_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0) while (index < MAX_STUCK_CAR_CHECKS && m_sCars[index].m_nVehicleIndex >= 0)
index++; index++;
/* Would be nice to return if index >= MAX_STUCK_CAR_CHECKS... */ #ifdef FIX_BUGS
if (index >= MAX_STUCK_CAR_CHECKS)
return;
#endif
m_sCars[index].m_nVehicleIndex = id; m_sCars[index].m_nVehicleIndex = id;
m_sCars[index].m_vecPos = pv->GetPosition(); m_sCars[index].m_vecPos = pv->GetPosition();
m_sCars[index].m_nLastCheck = CTimer::GetTimeInMilliseconds(); m_sCars[index].m_nLastCheck = CTimer::GetTimeInMilliseconds();
@ -2217,7 +2238,7 @@ void CTheScripts::Init()
ScriptsArray[i].Init(); ScriptsArray[i].Init();
ScriptsArray[i].AddScriptToList(&pIdleScripts); ScriptsArray[i].AddScriptToList(&pIdleScripts);
} }
MissionCleanup.Init(); MissionCleanUp.Init();
UpsideDownCars.Init(); UpsideDownCars.Init();
StuckCars.Init(); StuckCars.Init();
CFileMgr::SetDir("data"); CFileMgr::SetDir("data");
@ -2345,7 +2366,7 @@ void CTheScripts::Process()
float timeStep = CTimer::GetTimeStepInMilliseconds(); float timeStep = CTimer::GetTimeStepInMilliseconds();
UpsideDownCars.UpdateTimers(); UpsideDownCars.UpdateTimers();
StuckCars.Process(); StuckCars.Process();
MissionCleanup.CheckIfCollisionHasLoadedForMissionObjects(); MissionCleanUp.CheckIfCollisionHasLoadedForMissionObjects();
DrawScriptSpheres(); DrawScriptSpheres();
if (FailCurrentMission) if (FailCurrentMission)
--FailCurrentMission; --FailCurrentMission;
@ -3669,7 +3690,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_DELETE_CHAR: case COMMAND_DELETE_CHAR:
@ -3678,7 +3699,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]);
CTheScripts::RemoveThisPed(ped); CTheScripts::RemoveThisPed(ped);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_CHAR_WANDER_DIR: case COMMAND_CHAR_WANDER_DIR:
@ -3899,7 +3920,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
ScriptParams[0] = handle; ScriptParams[0] = handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR);
return 0; return 0;
} }
case COMMAND_DELETE_CAR: case COMMAND_DELETE_CAR:
@ -3912,7 +3933,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
delete car; delete car;
} }
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
return 0; return 0;
} }
case COMMAND_CAR_GOTO_COORDINATES: case COMMAND_CAR_GOTO_COORDINATES:
@ -4227,7 +4248,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
{ {
if (!m_bIsMissionScript) if (!m_bIsMissionScript)
return 0; return 0;
CTheScripts::MissionCleanup.Process(); CTheScripts::MissionCleanUp.Process();
return 0; return 0;
} }
case COMMAND_STORE_CAR_CHAR_IS_IN: case COMMAND_STORE_CAR_CHAR_IS_IN:
@ -4250,7 +4271,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
pOld->bIsLocked = false; pOld->bIsLocked = false;
CCarCtrl::NumRandomCars++; CCarCtrl::NumRandomCars++;
CCarCtrl::NumMissionCars--; CCarCtrl::NumMissionCars--;
CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
} }
} }
@ -4261,14 +4282,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
CCarCtrl::NumMissionCars++; CCarCtrl::NumMissionCars++;
CCarCtrl::NumRandomCars--; CCarCtrl::NumRandomCars--;
CTheScripts::StoreVehicleWasRandom = true; CTheScripts::StoreVehicleWasRandom = true;
CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
break; break;
case PARKED_VEHICLE: case PARKED_VEHICLE:
pCurrent->VehicleCreatedBy = MISSION_VEHICLE; pCurrent->VehicleCreatedBy = MISSION_VEHICLE;
CCarCtrl::NumMissionCars++; CCarCtrl::NumMissionCars++;
CCarCtrl::NumParkedCars--; CCarCtrl::NumParkedCars--;
CTheScripts::StoreVehicleWasRandom = true; CTheScripts::StoreVehicleWasRandom = true;
CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
break; break;
case MISSION_VEHICLE: case MISSION_VEHICLE:
case PERMANENT_VEHICLE: case PERMANENT_VEHICLE:
@ -4301,7 +4322,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
pOld->bIsLocked = false; pOld->bIsLocked = false;
CCarCtrl::NumRandomCars++; CCarCtrl::NumRandomCars++;
CCarCtrl::NumMissionCars--; CCarCtrl::NumMissionCars--;
CTheScripts::MissionCleanup.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
} }
} }
@ -4312,14 +4333,14 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
CCarCtrl::NumMissionCars++; CCarCtrl::NumMissionCars++;
CCarCtrl::NumRandomCars--; CCarCtrl::NumRandomCars--;
CTheScripts::StoreVehicleWasRandom = true; CTheScripts::StoreVehicleWasRandom = true;
CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
break; break;
case PARKED_VEHICLE: case PARKED_VEHICLE:
pCurrent->VehicleCreatedBy = MISSION_VEHICLE; pCurrent->VehicleCreatedBy = MISSION_VEHICLE;
CCarCtrl::NumMissionCars++; CCarCtrl::NumMissionCars++;
CCarCtrl::NumParkedCars--; CCarCtrl::NumParkedCars--;
CTheScripts::StoreVehicleWasRandom = true; CTheScripts::StoreVehicleWasRandom = true;
CTheScripts::MissionCleanup.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(CTheScripts::StoreVehicleIndex, CLEANUP_CAR);
break; break;
case MISSION_VEHICLE: case MISSION_VEHICLE:
case PERMANENT_VEHICLE: case PERMANENT_VEHICLE:
@ -4468,7 +4489,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT);
return 0; return 0;
} }
case COMMAND_DELETE_OBJECT: case COMMAND_DELETE_OBJECT:
@ -4481,7 +4502,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
delete pObj; delete pObj;
} }
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
return 0; return 0;
} }
case COMMAND_ADD_SCORE: case COMMAND_ADD_SCORE:
@ -4697,7 +4718,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD: case COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD:
@ -4747,81 +4768,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
return -1; return -1;
} }
void CRunningScript::Save(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
WriteSaveBuf<char>(buf, m_abScriptName[i]);
WriteSaveBuf<uint32>(buf, m_nIp);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
WriteSaveBuf<uint32>(buf, m_anStack[i]);
WriteSaveBuf<uint16>(buf, m_nStackPointer);
SkipSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
WriteSaveBuf<bool>(buf, m_bIsActive);
WriteSaveBuf<bool>(buf, m_bCondResult);
WriteSaveBuf<bool>(buf, m_bIsMissionScript);
WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
WriteSaveBuf<uint32>(buf, m_nWakeTime);
WriteSaveBuf<uint16>(buf, m_nAndOrState);
WriteSaveBuf<bool>(buf, m_bNotFlag);
WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled);
WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted);
WriteSaveBuf<bool>(buf, m_bMissionFlag);
SkipSaveBuf(buf, 2);
#else
WriteSaveBuf(buf, *this);
#endif
}
void CRunningScript::Load(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
m_abScriptName[i] = ReadSaveBuf<char>(buf);
m_nIp = ReadSaveBuf<uint32>(buf);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
m_anStack[i] = ReadSaveBuf<uint32>(buf);
m_nStackPointer = ReadSaveBuf<uint16>(buf);
SkipSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
m_bIsActive = ReadSaveBuf<bool>(buf);
m_bCondResult = ReadSaveBuf<bool>(buf);
m_bIsMissionScript = ReadSaveBuf<bool>(buf);
m_bSkipWakeTime = ReadSaveBuf<bool>(buf);
m_nWakeTime = ReadSaveBuf<uint32>(buf);
m_nAndOrState = ReadSaveBuf<uint16>(buf);
m_bNotFlag = ReadSaveBuf<bool>(buf);
m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf);
m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf);
m_bMissionFlag = ReadSaveBuf<bool>(buf);
SkipSaveBuf(buf, 2);
#else
CRunningScript* n = next;
CRunningScript* p = prev;
*this = ReadSaveBuf<CRunningScript>(buf);
next = n;
prev = p;
#endif
}
#ifdef MISSION_REPLAY #ifdef MISSION_REPLAY
bool CRunningScript::CanAllowMissionReplay() bool CRunningScript::CanAllowMissionReplay()
@ -4856,7 +4802,7 @@ void RetryMission(int type, int unk)
else if (type == 2) { else if (type == 2) {
doingMissionRetry = false; doingMissionRetry = false;
AllowMissionReplay = 6; AllowMissionReplay = 6;
CTheScripts::MissionCleanup.Process(); CTheScripts::MissionCleanUp.Process();
} }
} }

View file

@ -21,26 +21,31 @@ extern int32 ScriptParams[32];
void FlushLog(); void FlushLog();
#define script_assert(_Expression) FlushLog(); assert(_Expression); #define script_assert(_Expression) FlushLog(); assert(_Expression);
#define PICKUP_PLACEMENT_OFFSET 0.5f #define PICKUP_PLACEMENT_OFFSET (0.5f)
#define PED_FIND_Z_OFFSET 5.0f #define PED_FIND_Z_OFFSET (5.0f)
#define COP_PED_FIND_Z_OFFSET 10.0f #define COP_PED_FIND_Z_OFFSET (10.0f)
#define SPHERE_MARKER_R 252 #define UPSIDEDOWN_UP_THRESHOLD (-0.97f)
#define SPHERE_MARKER_G 138 #define UPSIDEDOWN_MOVE_SPEED_THRESHOLD (0.01f)
#define SPHERE_MARKER_B 242 #define UPSIDEDOWN_TURN_SPEED_THRESHOLD (0.02f)
#define SPHERE_MARKER_A 228 #define UPSIDEDOWN_TIMER_THRESHOLD (1000)
#define SPHERE_MARKER_R (252)
#define SPHERE_MARKER_G (138)
#define SPHERE_MARKER_B (242)
#define SPHERE_MARKER_A (228)
#define SPHERE_MARKER_PULSE_PERIOD 2048 #define SPHERE_MARKER_PULSE_PERIOD 2048
#define SPHERE_MARKER_PULSE_FRACTION 0.1f #define SPHERE_MARKER_PULSE_FRACTION 0.1f
#ifdef USE_PRECISE_MEASUREMENT_CONVERTION #ifdef USE_PRECISE_MEASUREMENT_CONVERTION
#define METERS_IN_FOOT 0.3048f #define METERS_IN_FOOT (0.3048f)
#define FEET_IN_METER 3.28084f #define FEET_IN_METER (3.28084f)
#else #else
#define METERS_IN_FOOT 0.3f #define METERS_IN_FOOT (0.3f)
#define FEET_IN_METER 3.33f #define FEET_IN_METER (3.33f)
#endif #endif
#define KEY_LENGTH_IN_SCRIPT 8 #define KEY_LENGTH_IN_SCRIPT (8)
//#define GTA_SCRIPT_COLLECTIVE //#define GTA_SCRIPT_COLLECTIVE
@ -96,7 +101,7 @@ struct intro_text_line
m_bBackground = false; m_bBackground = false;
m_bBackgroundOnly = false; m_bBackgroundOnly = false;
m_fWrapX = 182.0f; m_fWrapX = 182.0f;
m_fCenterSize = 640.0f; m_fCenterSize = DEFAULT_SCREEN_WIDTH;
m_sBackgroundColor = CRGBA(128, 128, 128, 128); m_sBackgroundColor = CRGBA(128, 128, 128, 128);
m_bTextProportional = true; m_bTextProportional = true;
m_bTextBeforeFade = false; m_bTextBeforeFade = false;
@ -149,10 +154,10 @@ enum {
class CMissionCleanup class CMissionCleanup
{ {
public:
cleanup_entity_struct m_sEntities[MAX_CLEANUP]; cleanup_entity_struct m_sEntities[MAX_CLEANUP];
uint8 m_nCount; uint8 m_nCount;
public:
CMissionCleanup(); CMissionCleanup();
void Init(); void Init();
@ -161,10 +166,9 @@ public:
void RemoveEntityFromList(int32, uint8); void RemoveEntityFromList(int32, uint8);
void Process(); void Process();
void CheckIfCollisionHasLoadedForMissionObjects(); void CheckIfCollisionHasLoadedForMissionObjects();
CPhysical* DoesThisEntityWaitForCollision(int i);
}; };
struct CUpsideDownCarCheckEntry struct upsidedown_car_data
{ {
int32 m_nVehicleIndex; int32 m_nVehicleIndex;
uint32 m_nUpsideDownTimer; uint32 m_nUpsideDownTimer;
@ -172,11 +176,12 @@ struct CUpsideDownCarCheckEntry
class CUpsideDownCarCheck class CUpsideDownCarCheck
{ {
CUpsideDownCarCheckEntry m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS]; upsidedown_car_data m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS];
public: public:
void Init(); void Init();
bool IsCarUpsideDown(int32); bool IsCarUpsideDown(int32);
bool IsCarUpsideDown(CVehicle*);
void UpdateTimers(); void UpdateTimers();
bool AreAnyCarsUpsideDown(); bool AreAnyCarsUpsideDown();
void AddCarToCheck(int32); void AddCarToCheck(int32);
@ -194,7 +199,7 @@ struct stuck_car_data
bool m_bStuck; bool m_bStuck;
stuck_car_data() { } stuck_car_data() { }
inline void Reset(); void Reset();
}; };
class CStuckCarCheck class CStuckCarCheck
@ -273,6 +278,7 @@ enum {
class CTheScripts class CTheScripts
{ {
public:
static uint8 ScriptSpace[SIZE_SCRIPT_SPACE]; static uint8 ScriptSpace[SIZE_SCRIPT_SPACE];
static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS]; static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS];
static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES]; static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
@ -286,7 +292,7 @@ class CTheScripts
static CStoredLine aStoredLines[MAX_NUM_STORED_LINES]; static CStoredLine aStoredLines[MAX_NUM_STORED_LINES];
static bool DbgFlag; static bool DbgFlag;
static uint32 OnAMissionFlag; static uint32 OnAMissionFlag;
static CMissionCleanup MissionCleanup; static CMissionCleanup MissionCleanUp;
static CStuckCarCheck StuckCars; static CStuckCarCheck StuckCars;
static CUpsideDownCarCheck UpsideDownCars; static CUpsideDownCarCheck UpsideDownCars;
static int32 StoreVehicleIndex; static int32 StoreVehicleIndex;
@ -319,11 +325,10 @@ class CTheScripts
static int16 CardStack[CARDS_IN_STACK]; static int16 CardStack[CARDS_IN_STACK];
static int16 CardStackPosition; static int16 CardStackPosition;
#endif #endif
public:
static bool bPlayerIsInTheStatium; static bool bPlayerIsInTheStatium;
static uint8 RiotIntensity; static uint8 RiotIntensity;
static bool bPlayerHasMetDebbieHarry; static bool bPlayerHasMetDebbieHarry;
public:
static void Init(); static void Init();
static void Process(); static void Process();
@ -377,8 +382,6 @@ public:
return Read4BytesFromScript(&tmp); return Read4BytesFromScript(&tmp);
} }
private:
static CRunningScript* StartNewScript(uint32); static CRunningScript* StartNewScript(uint32);
static void CleanUpThisVehicle(CVehicle*); static void CleanUpThisVehicle(CVehicle*);
@ -436,18 +439,11 @@ public:
static void SetObjectiveForAllPedsInCollective(int, eObjective); static void SetObjectiveForAllPedsInCollective(int, eObjective);
#endif #endif
friend class CRunningScript;
friend class CHud;
friend void CMissionCleanup::Process();
friend class CColStore;
#ifdef FIX_BUGS
friend void RetryMission(int, int);
#endif
}; };
enum { enum {
MAX_STACK_DEPTH = 6, // 4 PS2 MAX_STACK_DEPTH = 6,
NUM_LOCAL_VARS = 16, NUM_LOCAL_VARS = 16,
NUM_TIMERS = 2 NUM_TIMERS = 2
}; };
@ -474,6 +470,7 @@ class CRunningScript
ORS_8 ORS_8
}; };
public:
CRunningScript* next; CRunningScript* next;
CRunningScript* prev; CRunningScript* prev;
char m_abScriptName[8]; char m_abScriptName[8];
@ -512,7 +509,6 @@ public:
static const uint32 nSaveStructSize; static const uint32 nSaveStructSize;
private:
void CollectParameters(uint32*, int16); void CollectParameters(uint32*, int16);
int32 CollectNextParameterWithoutIncreasingPC(uint32); int32 CollectNextParameterWithoutIncreasingPC(uint32);
int32* GetPointerToScriptVariable(uint32*, int16); int32* GetPointerToScriptVariable(uint32*, int16);
@ -580,7 +576,6 @@ private:
static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami); static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami);
friend class CTheScripts;
}; };
#ifdef USE_DEBUG_SCRIPT_LOADER #ifdef USE_DEBUG_SCRIPT_LOADER

View file

@ -1048,7 +1048,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
CTheScripts::CleanUpThisPed(pPed); CTheScripts::CleanUpThisPed(pPed);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED: case COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED:
@ -1057,7 +1057,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
CTheScripts::CleanUpThisVehicle(pVehicle); CTheScripts::CleanUpThisVehicle(pVehicle);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
return 0; return 0;
} }
case COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED: case COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED:
@ -1066,7 +1066,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
CTheScripts::CleanUpThisObject(pObject); CTheScripts::CleanUpThisObject(pObject);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
return 0; return 0;
} }
case COMMAND_DONT_REMOVE_CHAR: case COMMAND_DONT_REMOVE_CHAR:
@ -1074,7 +1074,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]); CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
script_assert(pPed); script_assert(pPed);
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_DONT_REMOVE_CAR: case COMMAND_DONT_REMOVE_CAR:
@ -1082,7 +1082,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pVehicle); script_assert(pVehicle);
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
return 0; return 0;
} }
case COMMAND_DONT_REMOVE_OBJECT: case COMMAND_DONT_REMOVE_OBJECT:
@ -1090,7 +1090,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]); CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
script_assert(pObject); script_assert(pObject);
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
return 0; return 0;
} }
case COMMAND_CREATE_CHAR_AS_PASSENGER: case COMMAND_CREATE_CHAR_AS_PASSENGER:
@ -1157,7 +1157,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT: case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT:

View file

@ -325,11 +325,11 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0])); UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0]));
return 0; return 0;
/*
case COMMAND_SET_FREE_BOMBS: case COMMAND_SET_FREE_BOMBS:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CGarages::SetFreeBombs(ScriptParams[0] != 0); CGarages::SetFreeBombs(ScriptParams[0] != 0);
return 0; return 0;
#ifdef GTA_PS2
case COMMAND_SET_POWERPOINT: case COMMAND_SET_POWERPOINT:
{ {
CollectParameters(&m_nIp, 7); CollectParameters(&m_nIp, 7);
@ -363,8 +363,6 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
return 0; return 0;
} }
#endif // GTA_PS2
/*
case COMMAND_SET_ALL_TAXI_LIGHTS: case COMMAND_SET_ALL_TAXI_LIGHTS:
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0); CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0);
@ -1279,7 +1277,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj); ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObj);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT);
return 0; return 0;
} }
/* /*
@ -1834,7 +1832,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pPed->bRespondsToThreats = false; pPed->bRespondsToThreats = false;
++CPopulation::ms_nTotalMissionPeds; ++CPopulation::ms_nTotalMissionPeds;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR);
} }
ScriptParams[0] = ped_handle; ScriptParams[0] = ped_handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
@ -1889,7 +1887,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pPed->bRespondsToThreats = false; pPed->bRespondsToThreats = false;
++CPopulation::ms_nTotalMissionPeds; ++CPopulation::ms_nTotalMissionPeds;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR);
} }
ScriptParams[0] = ped_handle; ScriptParams[0] = ped_handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);

View file

@ -68,7 +68,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CPed* pLeader = CWorld::Players[ScriptParams[1]].m_pPed; CPed* pLeader = CWorld::Players[ScriptParams[1]].m_pPed;
script_assert(pPed); script_assert(pPed);
script_assert(pLeader); script_assert(pLeader);
UpdateCompareFlag(pPed->m_leader == pLeader); UpdateCompareFlag(pPed->m_leader == pLeader && !pPed->bWaitForLeaderToComeCloser);
return 0; return 0;
} }
case COMMAND_EXPLODE_CHAR_HEAD: case COMMAND_EXPLODE_CHAR_HEAD:
@ -92,7 +92,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CBoat* pBoat = (CBoat*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CBoat* pBoat = (CBoat*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pBoat && pBoat->m_vehType == VEHICLE_TYPE_BOAT); script_assert(pBoat && pBoat->m_vehType == VEHICLE_TYPE_BOAT);
pBoat->m_bIsAnchored = (ScriptParams[1] == 0); pBoat->m_bIsAnchored = (ScriptParams[1] != 0);
return 0; return 0;
} }
case COMMAND_SET_ZONE_GROUP: case COMMAND_SET_ZONE_GROUP:
@ -155,7 +155,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
++CCarCtrl::NumMissionCars; ++CCarCtrl::NumMissionCars;
--CCarCtrl::NumRandomCars; --CCarCtrl::NumRandomCars;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR);
} }
ScriptParams[0] = handle; ScriptParams[0] = handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
@ -188,7 +188,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
++CCarCtrl::NumMissionCars; ++CCarCtrl::NumMissionCars;
--CCarCtrl::NumRandomCars; --CCarCtrl::NumRandomCars;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(handle, CLEANUP_CAR);
} }
ScriptParams[0] = handle; ScriptParams[0] = handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
@ -609,7 +609,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
} }
} }
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_SET_CHAR_STAY_IN_SAME_PLACE: case COMMAND_SET_CHAR_STAY_IN_SAME_PLACE:
@ -1056,7 +1056,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR: case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR:

View file

@ -2251,6 +2251,80 @@ VALIDATESAVEBUF(size)
#undef SCRIPT_DATA_SIZE #undef SCRIPT_DATA_SIZE
void CRunningScript::Save(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
WriteSaveBuf<char>(buf, m_abScriptName[i]);
WriteSaveBuf<uint32>(buf, m_nIp);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
WriteSaveBuf<uint32>(buf, m_anStack[i]);
WriteSaveBuf<uint16>(buf, m_nStackPointer);
SkipSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
WriteSaveBuf<bool>(buf, m_bIsActive);
WriteSaveBuf<bool>(buf, m_bCondResult);
WriteSaveBuf<bool>(buf, m_bIsMissionScript);
WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
WriteSaveBuf<uint32>(buf, m_nWakeTime);
WriteSaveBuf<uint16>(buf, m_nAndOrState);
WriteSaveBuf<bool>(buf, m_bNotFlag);
WriteSaveBuf<bool>(buf, m_bDeatharrestEnabled);
WriteSaveBuf<bool>(buf, m_bDeatharrestExecuted);
WriteSaveBuf<bool>(buf, m_bMissionFlag);
SkipSaveBuf(buf, 2);
#else
WriteSaveBuf(buf, *this);
#endif
}
void CRunningScript::Load(uint8*& buf)
{
#ifdef COMPATIBLE_SAVES
SkipSaveBuf(buf, 8);
for (int i = 0; i < 8; i++)
m_abScriptName[i] = ReadSaveBuf<char>(buf);
m_nIp = ReadSaveBuf<uint32>(buf);
#ifdef CHECK_STRUCT_SIZES
static_assert(MAX_STACK_DEPTH == 6, "Compatibility loss: MAX_STACK_DEPTH != 6");
#endif
for (int i = 0; i < MAX_STACK_DEPTH; i++)
m_anStack[i] = ReadSaveBuf<uint32>(buf);
m_nStackPointer = ReadSaveBuf<uint16>(buf);
SkipSaveBuf(buf, 2);
#ifdef CHECK_STRUCT_SIZES
static_assert(NUM_LOCAL_VARS + NUM_TIMERS == 18, "Compatibility loss: NUM_LOCAL_VARS + NUM_TIMERS != 18");
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
m_bIsActive = ReadSaveBuf<bool>(buf);
m_bCondResult = ReadSaveBuf<bool>(buf);
m_bIsMissionScript = ReadSaveBuf<bool>(buf);
m_bSkipWakeTime = ReadSaveBuf<bool>(buf);
m_nWakeTime = ReadSaveBuf<uint32>(buf);
m_nAndOrState = ReadSaveBuf<uint16>(buf);
m_bNotFlag = ReadSaveBuf<bool>(buf);
m_bDeatharrestEnabled = ReadSaveBuf<bool>(buf);
m_bDeatharrestExecuted = ReadSaveBuf<bool>(buf);
m_bMissionFlag = ReadSaveBuf<bool>(buf);
SkipSaveBuf(buf, 2);
#else
CRunningScript* n = next;
CRunningScript* p = prev;
*this = ReadSaveBuf<CRunningScript>(buf);
next = n;
prev = p;
#endif
}
void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity) void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity)
{ {
static CColPoint aTempColPoints[MAX_COLLISION_POINTS]; static CColPoint aTempColPoints[MAX_COLLISION_POINTS];

View file

@ -703,7 +703,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle); ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CAR);
return 0; return 0;
} }
case COMMAND_START_BOAT_FOAM_ANIMATION: case COMMAND_START_BOAT_FOAM_ANIMATION:
@ -1272,7 +1272,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
pPed->bRespondsToThreats = false; pPed->bRespondsToThreats = false;
++CPopulation::ms_nTotalMissionPeds; ++CPopulation::ms_nTotalMissionPeds;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR);
} }
ScriptParams[0] = ped_handle; ScriptParams[0] = ped_handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
@ -1320,7 +1320,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
pPed->bRespondsToThreats = false; pPed->bRespondsToThreats = false;
++CPopulation::ms_nTotalMissionPeds; ++CPopulation::ms_nTotalMissionPeds;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR);
} }
ScriptParams[0] = ped_handle; ScriptParams[0] = ped_handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);

View file

@ -576,11 +576,11 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
ScriptParams[0] = pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels; ScriptParams[0] = pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels;
ScriptParams[1] = *(int*)&pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels; *(float*)&ScriptParams[1] = pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels;
ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie; ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie;
ScriptParams[3] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnWheelie; *(float*)&ScriptParams[3] = pPlayerInfo->m_nLastDistanceTravelledOnWheelie;
ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie; ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie;
ScriptParams[5] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnStoppie; *(float*)&ScriptParams[5] = pPlayerInfo->m_nLastDistanceTravelledOnStoppie;
StoreParameters(&m_nIp, 6); StoreParameters(&m_nIp, 6);
pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels = 0; pPlayerInfo->m_nLastTimeCarSpentOnTwoWheels = 0;
pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels = 0.0f; pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels = 0.0f;
@ -1201,7 +1201,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER: case COMMAND_CREATE_RANDOM_CHAR_AS_PASSENGER:
@ -1231,7 +1231,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed); ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
return 0; return 0;
} }
case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS: case COMMAND_SET_CHAR_IGNORE_THREATS_BEHIND_OBJECTS:

View file

@ -283,7 +283,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command)
pPed->bRespondsToThreats = false; pPed->bRespondsToThreats = false;
++CPopulation::ms_nTotalMissionPeds; ++CPopulation::ms_nTotalMissionPeds;
if (m_bIsMissionScript) if (m_bIsMissionScript)
CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR); CTheScripts::MissionCleanUp.AddEntityToList(ped_handle, CLEANUP_CHAR);
} }
ScriptParams[0] = ped_handle; ScriptParams[0] = ped_handle;
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);

View file

@ -3639,7 +3639,7 @@ CMenuManager::ExportStats()
char *statValue = UnicodeToAscii(gUString2); char *statValue = UnicodeToAscii(gUString2);
for (int j = 0; statValue[j] != '\0'; ++j) { for (int j = 0; statValue[j] != '\0'; ++j) {
if (statValue[j] == '_') if (statValue[j] == '_')
statValue[j] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation statValue[j] = '\xBA'; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation
} }
if (statValue) if (statValue)
fprintf(txtFile, "%s\n\n", statValue); fprintf(txtFile, "%s\n\n", statValue);
@ -3701,7 +3701,7 @@ CMenuManager::ExportStats()
char *statValue = UnicodeToAscii(gUString2); char *statValue = UnicodeToAscii(gUString2);
for (int l = 0; statValue[l] != '\0'; ++l) { for (int l = 0; statValue[l] != '\0'; ++l) {
if (statValue[l] == '_') if (statValue[l] == '_')
statValue[l] = 0xBA; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation statValue[l] = '\xBA'; // This is degree symbol, but my editors keeps messing up with it so I wrote hex representation
} }
if (statValue) if (statValue)
fprintf(htmlFile, "%s", statValue); fprintf(htmlFile, "%s", statValue);

View file

@ -338,6 +338,11 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
#define USE_BASIC_SCRIPT_DEBUG_OUTPUT #define USE_BASIC_SCRIPT_DEBUG_OUTPUT
#endif #endif
#ifdef MASTER
#undef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#undef USE_BASIC_SCRIPT_DEBUG_OUTPUT
#endif
// Replay // Replay
//#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool! //#define DONT_FIX_REPLAY_BUGS // keeps various bugs in CReplay, some of which are fairly cool!
//#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!) //#define USE_BETA_REPLAY_MODE // adds another replay mode, a few seconds slomo (caution: buggy!)
@ -359,8 +364,21 @@ static_assert(false, "SUPPORT_XBOX_SCRIPT and SUPPORT_MOBILE_SCRIPT are mutually
// Audio // Audio
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot #define AUDIO_CACHE // cache sound lengths to speed up the cold boot
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS //#define 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
#define AUDIO_OAL_USE_MPG123 // use mpg123 to support mp3 files
#ifdef AUDIO_OPUS
#define AUDIO_OAL_USE_OPUS // enable support of opus files
//#define OPUS_AUDIO_PATHS // (not supported on VC yet) changes audio paths to opus paths (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
//#define OPUS_SFX // enable if your sfx.raw is encoded with opus (doesn't work if AUDIO_OAL_USE_OPUS isn't enabled)
#ifndef AUDIO_OAL_USE_OPUS
#undef OPUS_AUDIO_PATHS
#undef OPUS_SFX
#endif
#endif
#ifdef LIBRW #ifdef LIBRW
// these are not supported with librw yet // these are not supported with librw yet

View file

@ -186,7 +186,7 @@ CSpecialFX::Render2DFXs(void)
CFont::SetCentreOff(); CFont::SetCentreOff();
CFont::SetPropOn(); CFont::SetPropOn();
CFont::SetColor(CRGBA(0, 255, 0, 200)); CFont::SetColor(CRGBA(0, 255, 0, 200));
FONT_LOCALE(FONT_STANDARD); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63 sprintf(gString, "%d", CTimer::GetFrameCounter() & 0x3F); // mb % 63
AsciiToUnicode(gString, gUString); AsciiToUnicode(gString, gUString);
CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString);
@ -211,7 +211,7 @@ CSpecialFX::Render2DFXs(void)
CFont::SetCentreOff(); CFont::SetCentreOff();
CFont::SetPropOn(); CFont::SetPropOn();
CFont::SetColor(CRGBA(100, 100, 100, 200)); CFont::SetColor(CRGBA(100, 100, 100, 200));
FONT_LOCALE(FONT_STANDARD); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString); CFont::PrintString(SCREEN_WIDTH * 8 / 10, SCREEN_HEIGHT * 8 / 10, gUString);
for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) { for (int32 i = 0; i < SCREEN_HEIGHT; i += 4) {
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);

View file

@ -14394,6 +14394,9 @@ XBOX
[FEC_IVP] [FEC_IVP]
INVERT PAD VERTICALLY INVERT PAD VERTICALLY
[FEM_NON]
NONE
{ end of file } { end of file }
[DUMMY] [DUMMY]
THIS LABEL NEEDS TO BE HERE !!! THIS LABEL NEEDS TO BE HERE !!!