mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #1009 from zsilencer/develop
Decompile 6CB7FB, 6B49D9, 6C0BB5, 6C09D1, 6C0B83
This commit is contained in:
commit
54cf1c4371
|
@ -1427,13 +1427,8 @@ int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z)
|
|||
RCT2_GLOBAL(0x00F438AD, uint8) = 0;
|
||||
int volume = 0;
|
||||
if (ebx == 0x8001) {
|
||||
sint16 x2 = x & 0xFFE0; // round by 32
|
||||
sint16 y2 = y & 0xFFE0;
|
||||
if (x2 < 0x1FFF && y2 < 0x1FFF) {
|
||||
rct_map_element* mapelement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[((y2 * 256 + x2) & 0xFFFF) / 8];
|
||||
while (map_element_get_type(mapelement) != MAP_ELEMENT_TYPE_SURFACE) {
|
||||
mapelement++;
|
||||
}
|
||||
rct_map_element* mapelement = map_get_surface_element_at(x / 32, y / 32);
|
||||
if (mapelement) {
|
||||
if ((mapelement->base_height * 8) - 5 > z) {
|
||||
RCT2_GLOBAL(0x00F438AD, uint8) = 10;
|
||||
}
|
||||
|
@ -1560,7 +1555,7 @@ void start_title_music()
|
|||
&& RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO) {
|
||||
if (!RCT2_GLOBAL(0x009AF600, uint8)) {
|
||||
#ifdef USE_MIXER
|
||||
gTitleMusicChannel = Mixer_Play_Music(musicPathId);
|
||||
gTitleMusicChannel = Mixer_Play_Music(musicPathId, true);
|
||||
#else
|
||||
RCT2_GLOBAL(0x014241BC, uint32) = 1;
|
||||
int result = sound_channel_load_file2(3, (char*)get_file_path(musicPathId), 0);
|
||||
|
|
|
@ -31,21 +31,64 @@ extern "C" {
|
|||
|
||||
Mixer gMixer;
|
||||
|
||||
Sample::Sample()
|
||||
Source::~Source()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned long Source::GetSome(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
if (offset >= Length()) {
|
||||
return 0;
|
||||
}
|
||||
unsigned long size = length;
|
||||
if (offset + length > Length()) {
|
||||
size = Length() - offset;
|
||||
}
|
||||
return Read(offset, data, size);
|
||||
}
|
||||
|
||||
unsigned long Source::Length()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
const AudioFormat& Source::Format()
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
Source_Null::Source_Null()
|
||||
{
|
||||
length = 0;
|
||||
}
|
||||
|
||||
unsigned long Source_Null::Read(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Source_Sample::Source_Sample()
|
||||
{
|
||||
data = 0;
|
||||
length = 0;
|
||||
issdlwav = false;
|
||||
}
|
||||
|
||||
Sample::~Sample()
|
||||
Source_Sample::~Source_Sample()
|
||||
{
|
||||
Unload();
|
||||
}
|
||||
|
||||
bool Sample::Load(const char* filename)
|
||||
unsigned long Source_Sample::Read(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
log_verbose("Sample::Load(%s)", filename);
|
||||
*data = &Source_Sample::data[offset];
|
||||
return length;
|
||||
}
|
||||
|
||||
bool Source_Sample::LoadWAV(const char* filename)
|
||||
{
|
||||
log_verbose("Source_Sample::LoadWAV(%s)", filename);
|
||||
|
||||
utf8 utf8filename[512];
|
||||
win1252_to_utf8(utf8filename, filename, sizeof(utf8filename));
|
||||
|
@ -75,9 +118,9 @@ bool Sample::Load(const char* filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Sample::LoadCSS1(const char* filename, unsigned int offset)
|
||||
bool Source_Sample::LoadCSS1(const char* filename, unsigned int offset)
|
||||
{
|
||||
log_verbose("Sample::LoadCSS1(%s, %d)", filename, offset);
|
||||
log_verbose("Source_Sample::LoadCSS1(%s, %d)", filename, offset);
|
||||
|
||||
utf8 utf8filename[512];
|
||||
win1252_to_utf8(utf8filename, filename, sizeof(utf8filename));
|
||||
|
@ -107,13 +150,18 @@ bool Sample::LoadCSS1(const char* filename, unsigned int offset)
|
|||
format.freq = waveformat.nSamplesPerSec;
|
||||
format.format = AUDIO_S16LSB;
|
||||
format.channels = waveformat.nChannels;
|
||||
data = new uint8[length];
|
||||
data = new (std::nothrow) uint8[length];
|
||||
if (!data) {
|
||||
log_verbose("Unable to allocate data");
|
||||
SDL_RWclose(rw);
|
||||
return false;
|
||||
}
|
||||
SDL_RWread(rw, data, length, 1);
|
||||
SDL_RWclose(rw);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sample::Unload()
|
||||
void Source_Sample::Unload()
|
||||
{
|
||||
if (data) {
|
||||
if (issdlwav) {
|
||||
|
@ -127,16 +175,11 @@ void Sample::Unload()
|
|||
length = 0;
|
||||
}
|
||||
|
||||
bool Sample::Loaded()
|
||||
bool Source_Sample::Convert(AudioFormat format)
|
||||
{
|
||||
return data != 0;
|
||||
}
|
||||
|
||||
bool Sample::Convert(AudioFormat format)
|
||||
{
|
||||
if(Sample::format.format != format.format || Sample::format.channels != format.channels || Sample::format.freq != format.freq){
|
||||
if(Source_Sample::format.format != format.format || Source_Sample::format.channels != format.channels || Source_Sample::format.freq != format.freq){
|
||||
SDL_AudioCVT cvt;
|
||||
if (SDL_BuildAudioCVT(&cvt, Sample::format.format, Sample::format.channels, Sample::format.freq, format.format, format.channels, format.freq) < 0) {
|
||||
if (SDL_BuildAudioCVT(&cvt, Source_Sample::format.format, Source_Sample::format.channels, Source_Sample::format.freq, format.format, format.channels, format.freq) < 0) {
|
||||
return false;
|
||||
}
|
||||
cvt.len = length;
|
||||
|
@ -149,69 +192,147 @@ bool Sample::Convert(AudioFormat format)
|
|||
Unload();
|
||||
data = cvt.buf;
|
||||
length = cvt.len_cvt;
|
||||
Sample::format = format;
|
||||
Source_Sample::format = format;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8* Sample::Data()
|
||||
Source_SampleStream::Source_SampleStream()
|
||||
{
|
||||
return data;
|
||||
length = 0;
|
||||
rw = NULL;
|
||||
buffer = 0;
|
||||
buffersize = 0;
|
||||
}
|
||||
|
||||
unsigned long Sample::Length()
|
||||
Source_SampleStream::~Source_SampleStream()
|
||||
{
|
||||
return length;
|
||||
Unload();
|
||||
}
|
||||
|
||||
Stream::Stream()
|
||||
unsigned long Source_SampleStream::Read(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
sourcetype = SOURCE_NONE;
|
||||
}
|
||||
|
||||
unsigned long Stream::GetSome(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
unsigned long size = length;
|
||||
switch(sourcetype) {
|
||||
case SOURCE_SAMPLE:
|
||||
if (offset >= sample->Length()) {
|
||||
if (length > buffersize) {
|
||||
if (buffer) {
|
||||
delete[] buffer;
|
||||
}
|
||||
buffer = new (std::nothrow) uint8[length];
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
if (offset + length > sample->Length()) {
|
||||
size = sample->Length() - offset;
|
||||
buffersize = length;
|
||||
}
|
||||
*data = &sample->Data()[offset];
|
||||
return size;
|
||||
Sint64 currentposition = SDL_RWtell(rw);
|
||||
if (currentposition == -1) {
|
||||
return 0;
|
||||
}
|
||||
if (currentposition - databegin != offset) {
|
||||
Sint64 newposition = SDL_RWseek(rw, databegin + offset, SEEK_SET);
|
||||
if (newposition == -1) {
|
||||
return 0;
|
||||
}
|
||||
currentposition = newposition;
|
||||
}
|
||||
*data = buffer;
|
||||
int read = SDL_RWread(rw, buffer, 1, length);
|
||||
if (read == -1) {
|
||||
return 0;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
bool Source_SampleStream::LoadWAV(SDL_RWops* rw)
|
||||
{
|
||||
Unload();
|
||||
if (rw == NULL) {
|
||||
return false;
|
||||
}
|
||||
Source_SampleStream::rw = rw;
|
||||
Uint32 chunk_id = SDL_ReadLE32(rw);
|
||||
const Uint32 RIFF = 0x46464952;
|
||||
if (chunk_id != RIFF) {
|
||||
log_verbose("Not a WAV file");
|
||||
return false;
|
||||
}
|
||||
Uint32 chunk_size = SDL_ReadLE32(rw);
|
||||
Uint32 chunk_format = SDL_ReadLE32(rw);
|
||||
const Uint32 WAVE = 0x45564157;
|
||||
if (chunk_format != WAVE) {
|
||||
log_verbose("Not in WAVE format");
|
||||
return false;
|
||||
}
|
||||
const Uint32 FMT = 0x20746D66;
|
||||
Uint32 fmtchunk_size = FindChunk(rw, FMT);
|
||||
if (!fmtchunk_size) {
|
||||
log_verbose("Could not find FMT chunk");
|
||||
return false;
|
||||
}
|
||||
PCMWAVEFORMAT waveformat;
|
||||
SDL_RWread(rw, &waveformat, sizeof(waveformat), 1);
|
||||
if (waveformat.wf.wFormatTag != WAVE_FORMAT_PCM) {
|
||||
log_verbose("Not in proper format");
|
||||
return false;
|
||||
}
|
||||
format.freq = waveformat.wf.nSamplesPerSec;
|
||||
switch (waveformat.wBitsPerSample) {
|
||||
case 8:
|
||||
format.format = AUDIO_U8;
|
||||
break;
|
||||
case 16:
|
||||
format.format = AUDIO_S16LSB;
|
||||
break;
|
||||
default:
|
||||
log_verbose("Invalid bits per sample");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
format.channels = waveformat.wf.nChannels;
|
||||
const Uint32 DATA = 0x61746164;
|
||||
Uint32 datachunk_size = FindChunk(rw, DATA);
|
||||
if (!datachunk_size) {
|
||||
log_verbose("Could not find DATA chunk");
|
||||
return false;
|
||||
}
|
||||
length = datachunk_size;
|
||||
databegin = SDL_RWtell(rw);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long Stream::Length()
|
||||
Uint32 Source_SampleStream::FindChunk(SDL_RWops* rw, Uint32 wanted_id)
|
||||
{
|
||||
switch(sourcetype) {
|
||||
case SOURCE_SAMPLE:
|
||||
return sample->Length();
|
||||
break;
|
||||
Uint32 subchunk_id = SDL_ReadLE32(rw);
|
||||
Uint32 subchunk_size = SDL_ReadLE32(rw);
|
||||
if (subchunk_id == wanted_id) {
|
||||
return subchunk_size;
|
||||
}
|
||||
const Uint32 FACT = 0x74636166;
|
||||
const Uint32 LIST = 0x5453494c;
|
||||
const Uint32 BEXT = 0x74786562;
|
||||
const Uint32 JUNK = 0x4B4E554A;
|
||||
while (subchunk_id == FACT || subchunk_id == LIST || subchunk_id == BEXT || subchunk_id == JUNK) {
|
||||
SDL_RWseek(rw, subchunk_size, RW_SEEK_CUR);
|
||||
subchunk_id = SDL_ReadLE32(rw);
|
||||
subchunk_size = SDL_ReadLE32(rw);
|
||||
if (subchunk_id == wanted_id) {
|
||||
return subchunk_size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Stream::SetSource_Sample(Sample& sample)
|
||||
void Source_SampleStream::Unload()
|
||||
{
|
||||
sourcetype = SOURCE_SAMPLE;
|
||||
Stream::sample = &sample;
|
||||
}
|
||||
|
||||
const AudioFormat* Stream::Format()
|
||||
{
|
||||
switch(sourcetype) {
|
||||
case SOURCE_SAMPLE:
|
||||
return &sample->format;
|
||||
break;
|
||||
if (rw) {
|
||||
SDL_RWclose(rw);
|
||||
rw = NULL;
|
||||
}
|
||||
return 0;
|
||||
length = 0;
|
||||
if (buffer) {
|
||||
delete[] buffer;
|
||||
buffer = 0;
|
||||
}
|
||||
buffersize = 0;
|
||||
}
|
||||
|
||||
Channel::Channel()
|
||||
|
@ -223,7 +344,8 @@ Channel::Channel()
|
|||
SetPan(0.5f);
|
||||
done = true;
|
||||
stopping = false;
|
||||
stream = 0;
|
||||
source = 0;
|
||||
deletesourceondone = false;
|
||||
}
|
||||
|
||||
Channel::~Channel()
|
||||
|
@ -232,11 +354,14 @@ Channel::~Channel()
|
|||
speex_resampler_destroy(resampler);
|
||||
resampler = 0;
|
||||
}
|
||||
if (deletesourceondone) {
|
||||
delete source;
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::Play(Stream& stream, int loop = MIXER_LOOP_NONE)
|
||||
void Channel::Play(Source& source, int loop = MIXER_LOOP_NONE)
|
||||
{
|
||||
Channel::stream = &stream;
|
||||
Channel::source = &source;
|
||||
Channel::loop = loop;
|
||||
offset = 0;
|
||||
done = false;
|
||||
|
@ -286,14 +411,25 @@ unsigned long Channel::GetOffset()
|
|||
|
||||
bool Channel::SetOffset(unsigned long offset)
|
||||
{
|
||||
if (stream && offset < stream->Length()) {
|
||||
int samplesize = stream->Format()->channels * stream->Format()->BytesPerSample();
|
||||
if (source && offset < source->Length()) {
|
||||
int samplesize = source->Format().channels * source->Format().BytesPerSample();
|
||||
Channel::offset = (offset / samplesize) * samplesize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Mixer::Mixer()
|
||||
{
|
||||
effectbuffer = 0;
|
||||
for (int i = 0; i < countof(css1sources); i++) {
|
||||
css1sources[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < countof(musicsources); i++) {
|
||||
musicsources[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::Init(const char* device)
|
||||
{
|
||||
Close();
|
||||
|
@ -310,10 +446,15 @@ void Mixer::Init(const char* device)
|
|||
format.channels = have.channels;
|
||||
format.freq = have.freq;
|
||||
const char* filename = get_file_path(PATH_ID_CSS1);
|
||||
for (int i = 0; i < SOUND_MAXID; i++) {
|
||||
css1samples[i].LoadCSS1(filename, i);
|
||||
css1samples[i].Convert(format); // convert to audio output format, saves some cpu usage but requires a bit more memory, optional
|
||||
css1streams[i].SetSource_Sample(css1samples[i]);
|
||||
for (int i = 0; i < countof(css1sources); i++) {
|
||||
Source_Sample* source_sample = new Source_Sample;
|
||||
if (source_sample->LoadCSS1(filename, i)) {
|
||||
source_sample->Convert(format); // convert to audio output format, saves some cpu usage but requires a bit more memory, optional
|
||||
css1sources[i] = source_sample;
|
||||
} else {
|
||||
css1sources[i] = &source_null;
|
||||
delete source_sample;
|
||||
}
|
||||
}
|
||||
effectbuffer = new uint8[(have.samples * format.BytesPerSample() * format.channels)];
|
||||
SDL_PauseAudioDevice(deviceid, 0);
|
||||
|
@ -328,7 +469,22 @@ void Mixer::Close()
|
|||
}
|
||||
Unlock();
|
||||
SDL_CloseAudioDevice(deviceid);
|
||||
for (int i = 0; i < countof(css1sources); i++) {
|
||||
if (css1sources[i] && css1sources[i] != &source_null) {
|
||||
delete css1sources[i];
|
||||
css1sources[i] = 0;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < countof(musicsources); i++) {
|
||||
if (musicsources[i] && musicsources[i] != &source_null) {
|
||||
delete musicsources[i];
|
||||
musicsources[i] = 0;
|
||||
}
|
||||
}
|
||||
if (effectbuffer) {
|
||||
delete[] effectbuffer;
|
||||
effectbuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::Lock()
|
||||
|
@ -341,13 +497,14 @@ void Mixer::Unlock()
|
|||
SDL_UnlockAudioDevice(deviceid);
|
||||
}
|
||||
|
||||
Channel* Mixer::Play(Stream& stream, int loop, bool deleteondone)
|
||||
Channel* Mixer::Play(Source& source, int loop, bool deleteondone, bool deletesourceondone)
|
||||
{
|
||||
Lock();
|
||||
Channel* newchannel = new (std::nothrow) Channel();
|
||||
Channel* newchannel = new (std::nothrow) Channel;
|
||||
if (newchannel) {
|
||||
newchannel->Play(stream, loop);
|
||||
newchannel->Play(source, loop);
|
||||
newchannel->deleteondone = deleteondone;
|
||||
newchannel->deletesourceondone = deletesourceondone;
|
||||
newchannel->stopping = false;
|
||||
channels.push_back(newchannel);
|
||||
}
|
||||
|
@ -364,13 +521,20 @@ void Mixer::Stop(Channel& channel)
|
|||
|
||||
bool Mixer::LoadMusic(int pathid)
|
||||
{
|
||||
if (pathid >= PATH_ID_END) {
|
||||
if (pathid >= countof(musicsources)) {
|
||||
return false;
|
||||
}
|
||||
if (!musicsamples[pathid].Loaded()) {
|
||||
if (!musicsources[pathid]) {
|
||||
const char* filename = get_file_path(pathid);
|
||||
musicstreams[pathid].SetSource_Sample(musicsamples[pathid]);
|
||||
return musicsamples[pathid].Load(filename);
|
||||
Source_Sample* source_sample = new Source_Sample;
|
||||
if (source_sample->LoadWAV(filename)) {
|
||||
musicsources[pathid] = source_sample;
|
||||
return true;
|
||||
} else {
|
||||
delete source_sample;
|
||||
musicsources[pathid] = &source_null;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -394,8 +558,8 @@ void SDLCALL Mixer::Callback(void* arg, uint8* stream, int length)
|
|||
|
||||
void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
||||
{
|
||||
if (channel.stream && !channel.done) {
|
||||
AudioFormat streamformat = *channel.stream->Format();
|
||||
if (channel.source && channel.source->Length() > 0 && !channel.done) {
|
||||
AudioFormat streamformat = channel.source->Format();
|
||||
int loaded = 0;
|
||||
SDL_AudioCVT cvt;
|
||||
cvt.len_ratio = 1;
|
||||
|
@ -409,9 +573,9 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
}
|
||||
int samplestoread = (int)((samples - samplesloaded) * rate);
|
||||
int lengthloaded = 0;
|
||||
if (channel.offset < channel.stream->Length()) {
|
||||
if (channel.offset < channel.source->Length()) {
|
||||
bool mustconvert = false;
|
||||
if (MustConvert(*channel.stream)) {
|
||||
if (MustConvert(*channel.source)) {
|
||||
if (SDL_BuildAudioCVT(&cvt, streamformat.format, streamformat.channels, streamformat.freq, Mixer::format.format, Mixer::format.channels, Mixer::format.freq) == -1) {
|
||||
break;
|
||||
}
|
||||
|
@ -420,7 +584,7 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
|
||||
const uint8* datastream = 0;
|
||||
int toread = (int)(samplestoread / cvt.len_ratio) * samplesize;
|
||||
int readfromstream = (channel.stream->GetSome(channel.offset, &datastream, toread));
|
||||
int readfromstream = (channel.source->GetSome(channel.offset, &datastream, toread));
|
||||
if (readfromstream == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -519,7 +683,7 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
|
||||
loaded += lengthloaded;
|
||||
|
||||
if (channel.loop != 0 && channel.offset >= channel.stream->Length()) {
|
||||
if (channel.loop != 0 && channel.offset >= channel.source->Length()) {
|
||||
if (channel.loop != -1) {
|
||||
channel.loop--;
|
||||
}
|
||||
|
@ -528,7 +692,7 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
} while(loaded < length && channel.loop != 0 && !channel.stopping);
|
||||
|
||||
channel.oldvolume = channel.volume;
|
||||
if (channel.loop == 0 && channel.offset >= channel.stream->Length()) {
|
||||
if (channel.loop == 0 && channel.offset >= channel.source->Length()) {
|
||||
channel.done = true;
|
||||
}
|
||||
}
|
||||
|
@ -574,13 +738,10 @@ void Mixer::EffectFadeU8(uint8* data, int length, int startvolume, int endvolume
|
|||
}
|
||||
}
|
||||
|
||||
bool Mixer::MustConvert(Stream& stream)
|
||||
bool Mixer::MustConvert(Source& source)
|
||||
{
|
||||
const AudioFormat* streamformat = stream.Format();
|
||||
if (!streamformat) {
|
||||
return false;
|
||||
}
|
||||
if (streamformat->format != format.format || streamformat->channels != format.channels || streamformat->freq != format.freq) {
|
||||
const AudioFormat sourceformat = source.Format();
|
||||
if (sourceformat.format != format.format || sourceformat.channels != format.channels || sourceformat.freq != format.freq) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -609,11 +770,11 @@ void Mixer_Init(const char* device)
|
|||
|
||||
void* Mixer_Play_Effect(int id, int loop, int volume, float pan, double rate, int deleteondone)
|
||||
{
|
||||
if (id >= SOUND_MAXID) {
|
||||
if (id >= countof(gMixer.css1sources)) {
|
||||
return 0;
|
||||
}
|
||||
gMixer.Lock();
|
||||
Channel* channel = gMixer.Play(gMixer.css1streams[id], loop, deleteondone != 0);
|
||||
Channel* channel = gMixer.Play(*gMixer.css1sources[id], loop, deleteondone != 0, false);
|
||||
if (channel) {
|
||||
channel->SetVolume(volume);
|
||||
channel->SetPan(pan);
|
||||
|
@ -664,10 +825,33 @@ int Mixer_Channel_SetOffset(void* channel, unsigned long offset)
|
|||
return ((Channel*)channel)->SetOffset(offset);
|
||||
}
|
||||
|
||||
void* Mixer_Play_Music(int pathid)
|
||||
void* Mixer_Play_Music(int pathid, int streaming)
|
||||
{
|
||||
if (streaming) {
|
||||
const char* filename = get_file_path(pathid);
|
||||
|
||||
utf8 utf8filename[512];
|
||||
win1252_to_utf8(utf8filename, filename, sizeof(utf8filename));
|
||||
|
||||
SDL_RWops* rw = SDL_RWFromFile(utf8filename, "rb");
|
||||
if (rw == NULL) {
|
||||
return 0;
|
||||
}
|
||||
Source_SampleStream* source_samplestream = new Source_SampleStream;
|
||||
if (source_samplestream->LoadWAV(rw)) {
|
||||
Channel* channel = gMixer.Play(*source_samplestream, MIXER_LOOP_INFINITE, false, true);
|
||||
if (!channel) {
|
||||
delete source_samplestream;
|
||||
}
|
||||
return channel;
|
||||
} else {
|
||||
delete source_samplestream;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (gMixer.LoadMusic(pathid)) {
|
||||
return gMixer.Play(gMixer.musicstreams[pathid], MIXER_LOOP_INFINITE, false);
|
||||
return gMixer.Play(*gMixer.musicsources[pathid], MIXER_LOOP_INFINITE, false, false);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -43,45 +43,73 @@ struct AudioFormat {
|
|||
int channels;
|
||||
};
|
||||
|
||||
class Sample
|
||||
class Source
|
||||
{
|
||||
public:
|
||||
Sample();
|
||||
~Sample();
|
||||
bool Load(const char* filename);
|
||||
bool LoadCSS1(const char* filename, unsigned int offset);
|
||||
void Unload();
|
||||
bool Loaded();
|
||||
bool Convert(AudioFormat format);
|
||||
const uint8* Data();
|
||||
unsigned long Length();
|
||||
|
||||
friend class Stream;
|
||||
|
||||
private:
|
||||
AudioFormat format;
|
||||
uint8* data;
|
||||
unsigned long length;
|
||||
bool issdlwav;
|
||||
};
|
||||
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
Stream();
|
||||
virtual ~Source();
|
||||
unsigned long GetSome(unsigned long offset, const uint8** data, unsigned long length);
|
||||
unsigned long Length();
|
||||
void SetSource_Sample(Sample& sample);
|
||||
const AudioFormat* Format();
|
||||
const AudioFormat& Format();
|
||||
|
||||
friend class Mixer;
|
||||
|
||||
protected:
|
||||
virtual unsigned long Read(unsigned long offset, const uint8** data, unsigned long length) = 0;
|
||||
|
||||
AudioFormat format;
|
||||
unsigned long length;
|
||||
};
|
||||
|
||||
class Source_Null : public Source
|
||||
{
|
||||
public:
|
||||
Source_Null();
|
||||
|
||||
protected:
|
||||
unsigned long Read(unsigned long offset, const uint8** data, unsigned long length);
|
||||
};
|
||||
|
||||
class Source_Sample : public Source
|
||||
{
|
||||
public:
|
||||
Source_Sample();
|
||||
~Source_Sample();
|
||||
bool LoadWAV(const char* filename);
|
||||
bool LoadCSS1(const char* filename, unsigned int offset);
|
||||
|
||||
friend class Mixer;
|
||||
|
||||
protected:
|
||||
bool Convert(AudioFormat format);
|
||||
|
||||
private:
|
||||
enum {
|
||||
SOURCE_NONE = 0,
|
||||
SOURCE_SAMPLE
|
||||
} sourcetype;
|
||||
Sample* sample;
|
||||
void Unload();
|
||||
|
||||
uint8* data;
|
||||
bool issdlwav;
|
||||
|
||||
protected:
|
||||
unsigned long Read(unsigned long offset, const uint8** data, unsigned long length);
|
||||
};
|
||||
|
||||
class Source_SampleStream : public Source
|
||||
{
|
||||
public:
|
||||
Source_SampleStream();
|
||||
~Source_SampleStream();
|
||||
bool LoadWAV(SDL_RWops* rw);
|
||||
|
||||
private:
|
||||
Uint32 FindChunk(SDL_RWops* rw, Uint32 wanted_id);
|
||||
void Unload();
|
||||
|
||||
SDL_RWops* rw;
|
||||
Uint64 databegin;
|
||||
uint8* buffer;
|
||||
unsigned long buffersize;
|
||||
|
||||
protected:
|
||||
unsigned long Read(unsigned long offset, const uint8** data, unsigned long length);
|
||||
};
|
||||
|
||||
class Channel
|
||||
|
@ -89,7 +117,7 @@ class Channel
|
|||
public:
|
||||
Channel();
|
||||
~Channel();
|
||||
void Play(Stream& stream, int loop);
|
||||
void Play(Source& source, int loop);
|
||||
void SetRate(double rate);
|
||||
void SetVolume(int volume);
|
||||
void SetPan(float pan);
|
||||
|
@ -108,25 +136,27 @@ private:
|
|||
float pan;
|
||||
bool done;
|
||||
bool deleteondone;
|
||||
bool deletesourceondone;
|
||||
bool stopping;
|
||||
int oldvolume;
|
||||
SpeexResamplerState* resampler;
|
||||
Stream* stream;
|
||||
Source* source;
|
||||
};
|
||||
|
||||
class Mixer
|
||||
{
|
||||
public:
|
||||
Mixer();
|
||||
void Init(const char* device);
|
||||
void Close();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
Channel* Play(Stream& stream, int loop, bool deleteondone);
|
||||
Channel* Play(Source& source, int loop, bool deleteondone, bool deletesourceondone);
|
||||
void Stop(Channel& channel);
|
||||
bool LoadMusic(int pathid);
|
||||
|
||||
Stream css1streams[SOUND_MAXID];
|
||||
Stream musicstreams[PATH_ID_END];
|
||||
Source* css1sources[SOUND_MAXID];
|
||||
Source* musicsources[PATH_ID_END];
|
||||
|
||||
private:
|
||||
static void SDLCALL Callback(void* arg, uint8* data, int length);
|
||||
|
@ -135,14 +165,13 @@ private:
|
|||
void EffectPanU8(Channel& channel, uint8* data, int length);
|
||||
void EffectFadeS16(sint16* data, int length, int startvolume, int endvolume);
|
||||
void EffectFadeU8(uint8* data, int length, int startvolume, int endvolume);
|
||||
bool MustConvert(Stream& stream);
|
||||
bool MustConvert(Source& source);
|
||||
bool Convert(SDL_AudioCVT& cvt, const uint8* data, unsigned long length, uint8** dataout);
|
||||
SDL_AudioDeviceID deviceid;
|
||||
AudioFormat format;
|
||||
uint8* effectbuffer;
|
||||
Sample css1samples[SOUND_MAXID];
|
||||
Sample musicsamples[PATH_ID_END];
|
||||
std::list<Channel*> channels;
|
||||
Source_Null source_null;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
|
@ -158,7 +187,7 @@ void Mixer_Channel_Rate(void* channel, double rate);
|
|||
int Mixer_Channel_IsPlaying(void* channel);
|
||||
unsigned long Mixer_Channel_GetOffset(void* channel);
|
||||
int Mixer_Channel_SetOffset(void* channel, unsigned long offset);
|
||||
void* Mixer_Play_Music(int pathid);
|
||||
void* Mixer_Play_Music(int pathid, int streaming);
|
||||
|
||||
static int DStoMixerVolume(int volume) { return (int)(SDL_MIX_MAXVOLUME * (SDL_pow(10, (float)volume / 2000))); };
|
||||
static float DStoMixerPan(int pan) { return (((float)pan + -DSBPAN_LEFT) / DSBPAN_RIGHT) / 2; };
|
||||
|
|
|
@ -265,7 +265,7 @@ void sub_6BD3A4()
|
|||
for (int i = 200; i < 204; i++)
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[i] = STAFF_MODE_WALK;
|
||||
|
||||
sub_6C0C3F();
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
86
src/game.c
86
src/game.c
|
@ -358,7 +358,7 @@ static int game_check_affordability(int cost)
|
|||
}
|
||||
RCT2_GLOBAL(0x13CE952, uint32) = cost;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 827;
|
||||
return 0x80000000;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
static uint32 game_do_command_table[58];
|
||||
|
@ -411,13 +411,13 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
}
|
||||
cost = *ebx;
|
||||
|
||||
if (cost != 0x80000000) {
|
||||
if (cost != MONEY32_UNDEFINED) {
|
||||
// Check funds
|
||||
insufficientFunds = 0;
|
||||
if (RCT2_GLOBAL(0x009A8C28, uint8) == 1 && !(flags & 4) && !(flags & 0x20) && cost != 0)
|
||||
insufficientFunds = game_check_affordability(cost);
|
||||
|
||||
if (insufficientFunds != 0x80000000) {
|
||||
if (insufficientFunds != MONEY32_UNDEFINED) {
|
||||
*ebx = original_ebx;
|
||||
*edx = original_edx;
|
||||
*esi = original_esi;
|
||||
|
@ -438,7 +438,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
}
|
||||
*edx = *ebx;
|
||||
|
||||
if (*edx != 0x80000000 && *edx < cost)
|
||||
if (*edx != MONEY32_UNDEFINED && *edx < cost)
|
||||
cost = *edx;
|
||||
|
||||
// Decrement nest count
|
||||
|
@ -470,7 +470,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & 1) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & 8))
|
||||
window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16));
|
||||
|
||||
return 0x80000000;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
void pause_toggle()
|
||||
|
@ -797,7 +797,7 @@ char save_game()
|
|||
path_set_extension(path, ".SV6");
|
||||
|
||||
if (scenario_save(path, gConfigGeneral.save_plugin_data ? 1 : 0)) {
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
gfx_invalidate_screen();
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -874,21 +874,21 @@ void game_load_or_quit_no_save_prompt()
|
|||
#pragma region Game command function table
|
||||
|
||||
static uint32 game_do_command_table[58] = {
|
||||
0x006B2FC5,
|
||||
0,
|
||||
0x0066397F,
|
||||
0,
|
||||
0x006C511D,
|
||||
0x006C5B69,
|
||||
0,
|
||||
0x006B3F0F,
|
||||
0x006B49D9,
|
||||
0,
|
||||
0,
|
||||
0x006B52D4,
|
||||
0, // 10
|
||||
0,
|
||||
0x006660A8,
|
||||
0x0066640B,
|
||||
0x006E0E01,
|
||||
0,
|
||||
0x006E08F4,
|
||||
0x006E650F,
|
||||
0,
|
||||
|
@ -897,17 +897,17 @@ static uint32 game_do_command_table[58] = {
|
|||
0, // use new_game_command_table, original: 0x00663CCD, // 20
|
||||
0x006B53E9,
|
||||
0x00698D6C, // text input
|
||||
0x0068C542,
|
||||
0x0068C6D1,
|
||||
0,
|
||||
0,
|
||||
0x0068BC01,
|
||||
0x006E66A0,
|
||||
0x006E6878,
|
||||
0,
|
||||
0,
|
||||
0x006C5AE9,
|
||||
0, // use new_game_command_table, original: 0x006BEFA1, 29
|
||||
0x006C09D1, // 30
|
||||
0x006C0B83,
|
||||
0x006C0BB5,
|
||||
0x00669C6D,
|
||||
0, // 30
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x006649BD,
|
||||
0x006666E7,
|
||||
|
@ -916,20 +916,20 @@ static uint32 game_do_command_table[58] = {
|
|||
0,
|
||||
0, // 40
|
||||
0x006E519A,
|
||||
0x006E5597,
|
||||
0,
|
||||
0x006B893C,
|
||||
0x006B8E1B,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x006D13FE,
|
||||
0,
|
||||
0x006CDEE4,
|
||||
0x006B9E6D, // 50
|
||||
0x006BA058,
|
||||
0x006E0F26,
|
||||
0x006E56B5,
|
||||
0x006B909A,
|
||||
0x006BA16A,
|
||||
0, // 50
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x006648E3,
|
||||
0
|
||||
};
|
||||
|
@ -937,21 +937,21 @@ static uint32 game_do_command_table[58] = {
|
|||
void game_command_emptysub(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {}
|
||||
|
||||
static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
||||
game_command_emptysub,
|
||||
game_command_set_ride_appearance,
|
||||
game_command_emptysub,
|
||||
game_pause_toggle,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_load_or_quit,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_demolish_ride,
|
||||
game_command_set_ride_status,
|
||||
game_command_emptysub,
|
||||
game_command_set_ride_name, // 10
|
||||
game_command_set_ride_setting,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_remove_scenery,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_place_footpath,
|
||||
|
@ -960,16 +960,16 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
|||
game_command_change_surface_style, // 20
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_raise_land,
|
||||
game_command_lower_land,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_raise_water,
|
||||
game_command_lower_water,
|
||||
game_command_emptysub,
|
||||
game_command_hire_new_staff_member, //game_command_emptysub,
|
||||
game_command_emptysub, // 30
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_set_staff_patrol, // 30
|
||||
game_command_fire_staff_member,
|
||||
game_command_set_staff_order,
|
||||
game_command_set_park_name,
|
||||
game_command_set_park_open,
|
||||
game_command_emptysub,
|
||||
|
@ -979,20 +979,20 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
|||
game_command_set_park_entrance_fee,
|
||||
game_command_update_staff_colour, // 40
|
||||
game_command_emptysub,
|
||||
game_command_remove_fence,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_remove_large_scenery,
|
||||
game_command_set_current_loan,
|
||||
game_command_set_research_funding,
|
||||
game_command_emptysub,
|
||||
game_command_start_campaign,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub, // 50
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_place_banner, // 50
|
||||
game_command_remove_banner,
|
||||
game_command_set_scenery_colour,
|
||||
game_command_set_fence_colour,
|
||||
game_command_set_large_scenery_colour,
|
||||
game_command_set_banner_colour,
|
||||
game_command_emptysub,
|
||||
game_command_clear_scenery
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "common.h"
|
||||
|
||||
enum GAME_COMMAND {
|
||||
GAME_COMMAND_0,
|
||||
GAME_COMMAND_SET_RIDE_APPEARANCE,
|
||||
GAME_COMMAND_1,
|
||||
GAME_COMMAND_TOGGLE_PAUSE, // 2
|
||||
GAME_COMMAND_3, //Has something to do with ride construction
|
||||
|
@ -68,14 +68,14 @@ enum GAME_COMMAND {
|
|||
GAME_COMMAND_41,
|
||||
GAME_COMMAND_REMOVE_FENCE,
|
||||
GAME_COMMAND_43,
|
||||
GAME_COMMAND_44,
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
GAME_COMMAND_SET_CURRENT_LOAN, // 45
|
||||
GAME_COMMAND_SET_RESEARCH_FUNDING, // 46
|
||||
GAME_COMMAND_47,
|
||||
GAME_COMMAND_START_MARKETING_CAMPAIGN, // 48
|
||||
GAME_COMMAND_49,
|
||||
GAME_COMMAND_50, // New banner? (possibly scenery)
|
||||
GAME_COMMAND_51, // Remove banner
|
||||
GAME_COMMAND_PLACE_BANNER, // New banner? (possibly scenery)
|
||||
GAME_COMMAND_REMOVE_BANNER, // Remove banner
|
||||
GAME_COMMAND_52,
|
||||
GAME_COMMAND_53,
|
||||
GAME_COMMAND_54,
|
||||
|
|
|
@ -512,7 +512,7 @@ static void viewport_interaction_remove_large_scenery(rct_map_element *mapElemen
|
|||
1 | ((mapElement->type & 0x3) << 8),
|
||||
y,
|
||||
mapElement->base_height | ((mapElement->properties.scenerymultiple.type >> 10) << 8),
|
||||
GAME_COMMAND_44,
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
|
|
@ -192,6 +192,8 @@ enum {
|
|||
STR_LOCATE_SUBJECT_TIP = 1027,
|
||||
STR_OFF_EDGE_OF_MAP = 1028,
|
||||
|
||||
STR_CAN_ONLY_BUILD_THIS_ON_LAND = 1034,
|
||||
|
||||
STR_LOAD_GAME_DIALOG_TITLE = 1036,
|
||||
STR_LOAD_LANDSCAPE_DIALOG_TITLE = 1037,
|
||||
STR_CONVERT_SAVED_GAME_TO_SCENARIO_1038 = 1038,
|
||||
|
@ -319,6 +321,7 @@ enum {
|
|||
|
||||
STR_BUILD_FOOTPATH_TIP = 1173,
|
||||
|
||||
STR_BANNER_SIGN_IN_THE_WAY = 1174,
|
||||
STR_CANT_BUILD_THIS_ON_SLOPED_FOOTPATH = 1175,
|
||||
STR_CANT_BUILD_FOOTPATH_HERE = 1176,
|
||||
STR_CANT_REMOVE_FOOTPATH_FROM_HERE = 1177,
|
||||
|
@ -377,6 +380,7 @@ enum {
|
|||
STR_SHOPS_STALLS_TIP = 1228,
|
||||
|
||||
STR_ROTATE_OBJECTS_90 = 1327,
|
||||
STR_LEVEL_LAND_REQUIRED = 1328,
|
||||
STR_LAUNCH_SPEED = 1329,
|
||||
STR_LAUNCH_SPEED_TIP = 1330,
|
||||
|
||||
|
@ -739,6 +743,8 @@ enum {
|
|||
|
||||
STR_CANT_DEMOLISH_RIDE = 2248,
|
||||
|
||||
STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS = 2252,
|
||||
|
||||
STR_RESEARCH_TRANSPORT_RIDES = 2253,
|
||||
STR_RESEARCH_GENTLE_RIDES = 2254,
|
||||
STR_RESEARCH_ROLLER_COASTERS = 2255,
|
||||
|
@ -1066,6 +1072,8 @@ enum {
|
|||
STR_MUSIC_ACKNOWLEDGEMENTS_ELLIPSIS = 2862,
|
||||
STR_MUSIC_ACKNOWLEDGEMENTS = 2863,
|
||||
|
||||
STR_TOO_MANY_BANNERS_IN_GAME = 2980,
|
||||
|
||||
STR_CHANGE_BANNER_TEXT_TIP = 2986,
|
||||
STR_SET_AS_NO_ENTRY_BANNER_TIP = 2987,
|
||||
STR_DEMOLISH_BANNER_TIP = 2988,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
typedef int rct_expenditure_type;
|
||||
|
||||
enum {
|
||||
RCT_EXPENDITURE_TYPE_RIDE_CONSRUCTION,
|
||||
RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION,
|
||||
RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS,
|
||||
RCT_EXPENDITURE_TYPE_LAND_PURCHASE,
|
||||
RCT_EXPENDITURE_TYPE_LANDSCAPING,
|
||||
|
|
|
@ -907,10 +907,11 @@ int paint_large_scenery(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo*
|
|||
chunk += 1038;
|
||||
}
|
||||
|
||||
scenery_type->large_scenery.var_0C = (uint32)chunk;
|
||||
scenery_type->large_scenery.tiles = (rct_large_scenery_tile*)chunk;
|
||||
|
||||
// skip over large scenery tiles
|
||||
while (*((uint16*)chunk) != 0xFFFF){
|
||||
chunk += 9;
|
||||
chunk += sizeof(rct_large_scenery_tile);
|
||||
}
|
||||
|
||||
chunk += 2;
|
||||
|
@ -937,7 +938,7 @@ int paint_large_scenery(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo*
|
|||
rct_scenery_entry* scenery_type = (rct_scenery_entry*)esi;
|
||||
scenery_type->name = 0;
|
||||
scenery_type->image = 0;
|
||||
scenery_type->large_scenery.var_0C = 0;
|
||||
scenery_type->large_scenery.tiles = 0;
|
||||
scenery_type->large_scenery.scenery_tab_id = 0;
|
||||
scenery_type->large_scenery.var_12 = 0;
|
||||
scenery_type->large_scenery.var_16 = 0;
|
||||
|
|
|
@ -175,6 +175,21 @@ static void sub_693BE5(rct_peep* peep, uint8 al){
|
|||
sub_693B58(peep);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069A512
|
||||
*/
|
||||
void remove_peep_from_ride(rct_peep* peep)
|
||||
{
|
||||
if (peep->state == PEEP_STATE_QUEUING) {
|
||||
remove_peep_from_queue(peep);
|
||||
}
|
||||
peep_decrement_num_riders(peep);
|
||||
peep->state = PEEP_STATE_1;
|
||||
peep_window_state_update(peep);
|
||||
sub_693BE5(peep, 0);
|
||||
}
|
||||
|
||||
static void peep_state_reset(rct_peep* peep){
|
||||
peep_decrement_num_riders(peep);
|
||||
peep->state = PEEP_STATE_1;
|
||||
|
@ -556,7 +571,7 @@ void peep_sprite_remove(rct_peep* peep){
|
|||
//RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
//return;
|
||||
|
||||
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
|
||||
window_close_by_number(WC_PEEP, peep->sprite_index);
|
||||
|
@ -573,7 +588,7 @@ void peep_sprite_remove(rct_peep* peep){
|
|||
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] = 0;
|
||||
peep->type = 0xFF;
|
||||
sub_6C0C3F();
|
||||
staff_update_greyed_patrol_areas();
|
||||
peep->type = PEEP_TYPE_STAFF;
|
||||
|
||||
news_item_disable_news(NEWS_ITEM_PEEP, peep->sprite_index);
|
||||
|
@ -4562,7 +4577,7 @@ void peep_update_crowd_noise()
|
|||
// Load and play crowd noise
|
||||
#ifdef USE_MIXER
|
||||
if (!gCrowdSoundChannel) {
|
||||
gCrowdSoundChannel = Mixer_Play_Music(PATH_ID_CSS2);
|
||||
gCrowdSoundChannel = Mixer_Play_Music(PATH_ID_CSS2, false);
|
||||
}
|
||||
if (gCrowdSoundChannel) {
|
||||
Mixer_Channel_Volume(gCrowdSoundChannel, DStoMixerVolume(volume));
|
||||
|
|
|
@ -570,6 +570,7 @@ int peep_check_easteregg_name(int index, rct_peep *peep);
|
|||
int peep_get_easteregg_name_id(rct_peep *peep);
|
||||
int peep_is_mechanic(rct_peep *peep);
|
||||
int peep_has_food(rct_peep* peep);
|
||||
void peep_sprite_remove(rct_peep* peep);
|
||||
|
||||
void peep_window_state_update(rct_peep* peep);
|
||||
void peep_decrement_num_riders(rct_peep* peep);
|
||||
|
@ -583,6 +584,7 @@ void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_a
|
|||
|
||||
void peep_set_map_tooltip(rct_peep *peep);
|
||||
void sub_693B58(rct_peep* peep);
|
||||
void remove_peep_from_ride(rct_peep* peep);
|
||||
void remove_peep_from_queue(rct_peep* peep);
|
||||
|
||||
#endif
|
||||
|
|
117
src/peep/staff.c
117
src/peep/staff.c
|
@ -70,7 +70,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
RCT2_GLOBAL(0x009DEA62, uint16) = _dx;
|
||||
|
||||
if (RCT2_GLOBAL(0x13573C8, uint16) < 0x190) {
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME;
|
||||
return;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
}
|
||||
|
||||
if (i == STAFF_MAX_COUNT) {
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_STAFF_IN_GAME;
|
||||
return;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
|
||||
if (newPeep == NULL)
|
||||
{
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME;
|
||||
return;
|
||||
}
|
||||
|
@ -211,6 +211,95 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
*edi = newPeep->sprite_index;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0BB5
|
||||
*/
|
||||
void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = 40;
|
||||
uint8 order_id = *ebx >> 8;
|
||||
uint16 sprite_id = *edx;
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
if(order_id & 0x80){ // change costume
|
||||
uint8 sprite_type = order_id & ~0x80;
|
||||
sprite_type += 4;
|
||||
peep->sprite_type = sprite_type;
|
||||
peep->flags &= ~PEEP_FLAGS_SLOW_WALK;
|
||||
if(RCT2_ADDRESS(0x00982134, uint8)[sprite_type] & 1){
|
||||
peep->flags |= PEEP_FLAGS_SLOW_WALK;
|
||||
}
|
||||
peep->action_frame = 0;
|
||||
sub_693B58(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
window_invalidate_by_number(WC_PEEP, sprite_id);
|
||||
window_invalidate_by_class(WC_STAFF_LIST);
|
||||
}else{
|
||||
peep->staff_orders = order_id;
|
||||
window_invalidate_by_number(WC_PEEP, sprite_id);
|
||||
window_invalidate_by_class(WC_STAFF_LIST);
|
||||
}
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C09D1
|
||||
*/
|
||||
void game_command_set_staff_patrol(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
int x = *eax;
|
||||
int y = *ecx;
|
||||
uint16 sprite_id = *edx;
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
int patrolOffset = peep->staff_id * (64 * 64 / 8);
|
||||
int patrolIndex = ((x & 0x1F80) >> 7) | ((y & 0x1F80) >> 1);
|
||||
int mask = 1 << (patrolIndex & 0x1F);
|
||||
int base = patrolIndex >> 5;
|
||||
|
||||
uint32 *patrolBits = (uint32*)(0x013B0E72 + patrolOffset + (base * 4));
|
||||
*patrolBits ^= mask;
|
||||
|
||||
int ispatrolling = 0;
|
||||
for(int i = 0; i < 128; i++){
|
||||
ispatrolling |= *(uint32*)(0x013B0E72 + patrolOffset + (i * 4));
|
||||
}
|
||||
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] &= ~2;
|
||||
if(ispatrolling){
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] |= 2;
|
||||
}
|
||||
|
||||
for(int y2 = 0; y2 < 4; y2++){
|
||||
for(int x2 = 0; x2 < 4; x2++){
|
||||
map_invalidate_tile_full((x & 0x1F80) + (x2 * 32), (y & 0x1F80) + (y2 * 32));
|
||||
}
|
||||
}
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0B83
|
||||
*/
|
||||
void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = 40;
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
window_close_by_class(WC_FIRE_PROMPT);
|
||||
uint16 sprite_id = *edx;
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
remove_peep_from_ride(peep);
|
||||
peep_sprite_remove(peep);
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates the colour of the given staff type.
|
||||
*/
|
||||
|
@ -233,29 +322,33 @@ uint16 hire_new_staff_member(uint8 staffType)
|
|||
|
||||
int result = game_do_command_p(GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
if (result == 0x80000000)
|
||||
if (result == MONEY32_UNDEFINED)
|
||||
return 0xFFFF;
|
||||
|
||||
return edi;
|
||||
}
|
||||
|
||||
void sub_6C0C3F()
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0C3F
|
||||
*/
|
||||
void staff_update_greyed_patrol_areas()
|
||||
{
|
||||
register rct_peep* peep;
|
||||
rct_peep* peep;
|
||||
|
||||
for (register uint8 staff_type = 0; staff_type < STAFF_TYPE_COUNT; ++staff_type)
|
||||
for (int staff_type = 0; staff_type < STAFF_TYPE_COUNT; ++staff_type)
|
||||
{
|
||||
for (register uint8 i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + (staff_type + STAFF_MAX_COUNT) * 512, uint32)[i] = 0;
|
||||
for (int i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + ((staff_type + STAFF_MAX_COUNT) * 512), uint32)[i] = 0;
|
||||
|
||||
for (register uint16 sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next)
|
||||
for (uint16 sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next)
|
||||
{
|
||||
peep = GET_PEEP(sprite_index);
|
||||
|
||||
if (peep->type == PEEP_TYPE_STAFF && staff_type == peep->staff_type)
|
||||
{
|
||||
for (register uint8 i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + (staff_type + STAFF_MAX_COUNT) * 512, uint32)[i] |= RCT2_ADDRESS(0x13B0E72 + peep->staff_id * 512, uint32)[i];
|
||||
for (int i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + ((staff_type + STAFF_MAX_COUNT) * 512), uint32)[i] |= RCT2_ADDRESS(0x13B0E72 + (peep->staff_id * 512), uint32)[i];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,13 @@ enum STAFF_ORDERS{
|
|||
|
||||
void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_hire_new_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_staff_patrol(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
|
||||
void update_staff_colour(uint8 staffType, uint16 color);
|
||||
uint16 hire_new_staff_member(uint8 staffType);
|
||||
void sub_6C0C3F();
|
||||
void staff_update_greyed_patrol_areas();
|
||||
int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y);
|
||||
void staff_reset_stats();
|
||||
|
||||
|
|
272
src/ride/ride.c
272
src/ride/ride.c
|
@ -27,12 +27,14 @@
|
|||
#include "../localisation/date.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../management/finance.h"
|
||||
#include "../management/marketing.h"
|
||||
#include "../management/news_item.h"
|
||||
#include "../peep/peep.h"
|
||||
#include "../peep/staff.h"
|
||||
#include "../scenario.h"
|
||||
#include "../util/util.h"
|
||||
#include "../windows/error.h"
|
||||
#include "../world/banner.h"
|
||||
#include "../world/map.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "ride.h"
|
||||
|
@ -556,7 +558,7 @@ int ride_create_ride(ride_list_item listItem)
|
|||
|
||||
esi = GAME_COMMAND_6;
|
||||
game_do_command_p(esi, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return ebx == 0x80000000 ? -1 : edi;
|
||||
return ebx == MONEY32_UNDEFINED ? -1 : edi;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2660,7 +2662,7 @@ void ride_music_update_final()
|
|||
rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[ride_music_params->tuneid];
|
||||
#ifdef USE_MIXER
|
||||
rct_ride_music* ride_music = &gRideMusicList[ebx];
|
||||
ride_music->sound_channel = Mixer_Play_Music(ride_music_info->pathid);
|
||||
ride_music->sound_channel = Mixer_Play_Music(ride_music_info->pathid, true);
|
||||
if (ride_music->sound_channel) {
|
||||
ride_music->volume = ride_music_params->volume;
|
||||
ride_music->pan = ride_music_params->pan;
|
||||
|
@ -2676,7 +2678,7 @@ void ride_music_update_final()
|
|||
}
|
||||
Mixer_Channel_SetOffset(ride_music->sound_channel, offset);
|
||||
} else {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0;
|
||||
//RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0;
|
||||
}
|
||||
#else
|
||||
const char* filename = get_file_path(ride_music_info->pathid);
|
||||
|
@ -2781,13 +2783,13 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
if (setting == 0){
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1796;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ride->status != RIDE_STATUS_CLOSED){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1006;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2796,7 +2798,7 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
if (setting == 0 || setting == 4 || setting == 8 || setting == 9)
|
||||
{
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1797;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2805,7 +2807,7 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT &&
|
||||
new_value > 1){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 3141;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3590,6 +3592,262 @@ void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CB7FB
|
||||
*/
|
||||
int ride_get_refund_price(int ride_id)
|
||||
{
|
||||
uint8 oldpaused = RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F4413A, int) = 0;
|
||||
for(int x = 0; x < 8192; x += 32){
|
||||
for(int y = 0; y < 8192; y += 32){
|
||||
int tile_idx = ((y * 256) + x) / 32;
|
||||
rct_map_element* map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx];
|
||||
do{
|
||||
if((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_TRACK && map_element->properties.track.ride_index == ride_id){
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
eax = x;
|
||||
ebx = ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) << 8) | 0x01;
|
||||
ecx = y;
|
||||
edx = map_element->properties.track.type;
|
||||
edi = map_element->base_height * 8;
|
||||
if(map_element->properties.track.type == 101){
|
||||
edx = 2 << 8 | map_element->properties.track.ride_index;
|
||||
int oldeax = eax;
|
||||
int oldebx = ebx;
|
||||
int oldecx = ecx;
|
||||
int oldedx = edx;
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 0 << 0;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 1 << 8;
|
||||
ecx = oldecx;
|
||||
ecx += 16;
|
||||
edx = oldedx;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 2 << 8;
|
||||
eax = oldeax;
|
||||
eax += 16;
|
||||
ecx = oldecx;
|
||||
ecx += 16;
|
||||
edx = oldedx;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 3 << 8;
|
||||
eax = oldeax;
|
||||
eax += 16;
|
||||
ecx = oldecx;
|
||||
edx = oldedx;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
}else{
|
||||
edx |= 0xFF << 8;
|
||||
edx &= ((map_element->properties.track.sequence & 0xF) << 8) | 0xFF;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_4, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
}
|
||||
y -= 32;
|
||||
break;
|
||||
}
|
||||
map_element++;
|
||||
}while(!((map_element - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
|
||||
}
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = oldpaused;
|
||||
return RCT2_GLOBAL(0x00F4413A, int);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B49D9
|
||||
*/
|
||||
void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
uint8 ride_id = *(uint8*)edx;
|
||||
|
||||
RCT2_GLOBAL(0x009DEA5E, uint16) = 0;
|
||||
RCT2_GLOBAL(0x009DEA60, uint16) = 0;
|
||||
RCT2_GLOBAL(0x009DEA62, uint16) = 0;
|
||||
rct_ride *ride = &g_ride_list[ride_id];
|
||||
int x = 0, y = 0, z = 0;
|
||||
if(ride->overall_view != (uint16)-1){
|
||||
x = ((ride->overall_view & 0xFF) * 32) + 16;
|
||||
y = ((ride->overall_view >> 8) * 32) + 16;
|
||||
z = map_element_height(x, y);
|
||||
RCT2_GLOBAL(0x009DEA5E, uint16) = x;
|
||||
RCT2_GLOBAL(0x009DEA60, uint16) = y;
|
||||
RCT2_GLOBAL(0x009DEA62, uint16) = z;
|
||||
}
|
||||
if(!(*ebx & 0x40) && RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8)){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}else{
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
if(!(*ebx & 8)){
|
||||
window_close_by_number(WC_RIDE_CONSTRUCTION, ride_id);
|
||||
}
|
||||
window_close_by_number(WC_RIDE, ride_id);
|
||||
window_close_by_number(WC_DEMOLISH_RIDE_PROMPT, ride_id);
|
||||
window_close_by_class(WC_NEW_CAMPAIGN);
|
||||
if(RCT2_GLOBAL(0x01358103, uint8) && ride_id == RCT2_GLOBAL(0x01358117, uint8)){
|
||||
RCT2_GLOBAL(0x01358103, uint8) = 0;
|
||||
}
|
||||
if(RCT2_GLOBAL(0x01358107, uint8) && ride_id == RCT2_GLOBAL(0x0135811B, uint8)){
|
||||
RCT2_GLOBAL(0x01358107, uint8) = 0;
|
||||
}
|
||||
ride_clear_for_construction(ride_id);
|
||||
ride_remove_peeps(ride_id);
|
||||
RCT2_CALLPROC_X(0x00696707, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
*ebx = ride_get_refund_price(ride_id);
|
||||
|
||||
RCT2_CALLPROC(0x006CB945);
|
||||
news_item_disable_news(NEWS_ITEM_RIDE, ride_id);
|
||||
|
||||
for(int i = 0; i < MAX_BANNERS; i++){
|
||||
rct_banner *banner = &gBanners[i];
|
||||
if(banner->type != BANNER_NULL && banner->flags & BANNER_FLAG_2 && banner->colour == ride_id){
|
||||
banner->flags &= 0xFB;
|
||||
banner->string_idx = 778;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 spriteIndex;
|
||||
rct_peep *peep;
|
||||
FOR_ALL_GUESTS(spriteIndex, peep){
|
||||
uint8 ride_id_bit = ride_id & 0x3;
|
||||
uint8 ride_id_offset = ride_id / 8;
|
||||
peep->rides_been_on[ride_id_offset] &= ~(1 << ride_id_bit); // clear ride from potentially being in rides_been_on
|
||||
if(peep->state == PEEP_STATE_WATCHING){
|
||||
if(peep->current_ride == ride_id){
|
||||
peep->current_ride = MAX_RIDES;
|
||||
if(peep->time_to_stand >= 50){ // make peep stop watching the ride
|
||||
peep->time_to_stand = 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove any free voucher for this ride from peep
|
||||
if(peep->item_standard_flags & PEEP_ITEM_VOUCHER){
|
||||
if(peep->voucher_type == VOUCHER_TYPE_RIDE_FREE && peep->voucher_arguments == ride_id){
|
||||
peep->item_standard_flags &= ~(PEEP_ITEM_VOUCHER);
|
||||
}
|
||||
}
|
||||
// remove any photos of this ride from peep
|
||||
if(peep->item_standard_flags & PEEP_ITEM_PHOTO){
|
||||
if(peep->photo1_ride_ref == ride_id){
|
||||
peep->item_standard_flags &= ~PEEP_ITEM_PHOTO;
|
||||
}
|
||||
}
|
||||
if(peep->item_extra_flags && PEEP_ITEM_PHOTO2){
|
||||
if(peep->photo2_ride_ref == ride_id){
|
||||
peep->item_extra_flags &= ~PEEP_ITEM_PHOTO2;
|
||||
}
|
||||
}
|
||||
if(peep->item_extra_flags && PEEP_ITEM_PHOTO3){
|
||||
if(peep->photo3_ride_ref == ride_id){
|
||||
peep->item_extra_flags &= ~PEEP_ITEM_PHOTO3;
|
||||
}
|
||||
}
|
||||
if(peep->item_extra_flags && PEEP_ITEM_PHOTO4){
|
||||
if(peep->photo4_ride_ref == ride_id){
|
||||
peep->item_extra_flags &= ~PEEP_ITEM_PHOTO4;
|
||||
}
|
||||
}
|
||||
if(peep->guest_heading_to_ride_id == ride_id){
|
||||
peep->guest_heading_to_ride_id = MAX_RIDES;
|
||||
}
|
||||
if(peep->favourite_ride == ride_id){
|
||||
peep->favourite_ride = MAX_RIDES;
|
||||
}
|
||||
for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) {
|
||||
if(peep->thoughts[i].item == ride_id){
|
||||
// Clear top thought, push others up
|
||||
memmove(&peep->thoughts[i], &peep->thoughts[i + 1], sizeof(rct_peep_thought)*(PEEP_MAX_THOUGHTS - i - 1));
|
||||
peep->thoughts[PEEP_MAX_THOUGHTS - 1].type = PEEP_THOUGHT_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user_string_free(ride->name);
|
||||
ride->type = RIDE_TYPE_NULL;
|
||||
window_invalidate_by_class(WC_RIDE_LIST);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, money32) = calculate_park_value();
|
||||
RCT2_GLOBAL(0x009DEA5E, uint16) = x;
|
||||
RCT2_GLOBAL(0x009DEA60, uint16) = y;
|
||||
RCT2_GLOBAL(0x009DEA62, uint16) = z;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return;
|
||||
}else{
|
||||
*ebx = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B2FC5
|
||||
*/
|
||||
void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
uint8 ride_id = *edx;
|
||||
uint8 type = *ebx >> 8;
|
||||
uint8 value = *edx >> 8;
|
||||
int index = *edi;
|
||||
rct_ride *ride = &g_ride_list[ride_id];
|
||||
switch(type){
|
||||
case 0:
|
||||
ride->track_colour_main[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 1:
|
||||
ride->track_colour_additional[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 2:
|
||||
*((uint8*)(&ride->vehicle_colours[index])) = value;
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
case 3:
|
||||
*((uint8*)(&ride->vehicle_colours[index]) + 1) = value;
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
case 4:
|
||||
ride->track_colour_supports[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 5:
|
||||
ride->colour_scheme_type &= ~(RIDE_COLOUR_SCHEME_DIFFERENT_PER_TRAIN | RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR);
|
||||
ride->colour_scheme_type |= value;
|
||||
for(int i = 1; i < countof(ride->vehicle_colours); i++){
|
||||
ride->vehicle_colours[i] = ride->vehicle_colours[0];
|
||||
ride->vehicle_colours_extended[i] = ride->vehicle_colours_extended[0];
|
||||
}
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
case 6:
|
||||
ride->entrance_style = value;
|
||||
RCT2_GLOBAL(0x01358840, uint8) = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 7:
|
||||
ride->vehicle_colours_extended[index] = value;
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
window_invalidate_by_number(WC_RIDE, ride_id);
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
bool ride_type_has_flag(int rideType, int flag)
|
||||
{
|
||||
return (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (rideType * 8), uint32) & flag) != 0;
|
||||
|
|
|
@ -764,6 +764,9 @@ void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *e
|
|||
void ride_set_name(int rideIndex, const char *name);
|
||||
void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
int ride_get_refund_price(int ride_id);
|
||||
void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
|
||||
int get_var_10E_unk_1(rct_ride* ride);
|
||||
int get_var_10E_unk_2(rct_ride* ride);
|
||||
|
|
|
@ -784,7 +784,7 @@ int sub_6D2189(int* cost, uint8* ride_id){
|
|||
edx = track_design->type | (entry_index << 8);
|
||||
esi = GAME_COMMAND_6;
|
||||
|
||||
if (0x80000000 == game_do_command_p(GAME_COMMAND_6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp)) return 1;
|
||||
if (MONEY32_UNDEFINED == game_do_command_p(GAME_COMMAND_6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp)) return 1;
|
||||
|
||||
// bh
|
||||
*ride_id = edi & 0xFF;
|
||||
|
@ -840,7 +840,7 @@ int sub_6D2189(int* cost, uint8* ride_id){
|
|||
edi = sub_6D01B3((*ride_id << 8) | bl, map_size, map_size, z);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = backup_park_flags;
|
||||
|
||||
if (edi != 0x80000000){
|
||||
if (edi != MONEY32_UNDEFINED){
|
||||
|
||||
if (!find_object_in_entry_group(&track_design->vehicle_object, &entry_type, &entry_index)){
|
||||
RCT2_GLOBAL(0xF44151, uint8) |= 4;
|
||||
|
|
|
@ -314,7 +314,7 @@ int scenario_load_and_play_from_path(const char *path)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PROFIT, money32) = 0;
|
||||
RCT2_GLOBAL(0x01358334, money32) = 0;
|
||||
RCT2_GLOBAL(0x01358338, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_ADMISSIONS, uint32) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INCOME_FROM_ADMISSIONS, uint32) = 0;
|
||||
RCT2_GLOBAL(0x013587D8, uint16) = 63;
|
||||
|
@ -517,7 +517,7 @@ void scenario_objectives_check()
|
|||
park_value = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, sint32);
|
||||
|
||||
|
||||
if ( scenario_completed_company_value != 0x80000000)
|
||||
if ( scenario_completed_company_value != MONEY32_UNDEFINED)
|
||||
return;
|
||||
|
||||
switch (objective_type) {
|
||||
|
|
|
@ -201,7 +201,7 @@ static void window_banner_mouseup()
|
|||
window_close(w);
|
||||
break;
|
||||
case WIDX_BANNER_DEMOLISH:
|
||||
game_do_command(x, 1, y, map_element->base_height | (map_element->properties.banner.position << 8), GAME_COMMAND_51, 0, 0);
|
||||
game_do_command(x, 1, y, map_element->base_height | (map_element->properties.banner.position << 8), GAME_COMMAND_REMOVE_BANNER, 0, 0);
|
||||
break;
|
||||
case WIDX_BANNER_TEXT:
|
||||
window_text_input_open(w, WIDX_BANNER_TEXT, 2982, 2983, gBanners[w->number].string_idx, 0, 32);
|
||||
|
|
|
@ -103,7 +103,7 @@ void window_clear_scenery_open()
|
|||
window_init_scroll_widgets(window);
|
||||
window_push_others_below(window);
|
||||
|
||||
RCT2_GLOBAL(0x00F1AD62, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F1AD62, uint32) = MONEY32_UNDEFINED;
|
||||
window->colours[0] = 24;
|
||||
window->colours[1] = 24;
|
||||
window->colours[2] = 24;
|
||||
|
@ -209,7 +209,7 @@ static void window_clear_scenery_paint()
|
|||
// Draw cost amount
|
||||
x = (window_clear_scenery_widgets[WIDX_PREVIEW].left + window_clear_scenery_widgets[WIDX_PREVIEW].right) / 2 + w->x;
|
||||
y = window_clear_scenery_widgets[WIDX_PREVIEW].bottom + w->y + 5;
|
||||
if (RCT2_GLOBAL(0x00F1AD62, uint32) != 0x80000000 && RCT2_GLOBAL(0x00F1AD62, uint32) != 0)
|
||||
if (RCT2_GLOBAL(0x00F1AD62, uint32) != MONEY32_UNDEFINED && RCT2_GLOBAL(0x00F1AD62, uint32) != 0)
|
||||
gfx_draw_string_centred(dpi, 986, x, y, 0, (void*)0x00F1AD62);
|
||||
}
|
||||
|
||||
|
|
|
@ -865,7 +865,7 @@ static void window_finances_financial_graph_paint()
|
|||
money32 *balanceHistory = RCT2_ADDRESS(RCT2_ADDRESS_BALANCE_HISTORY, money32);
|
||||
for (i = 0; i < 64; i++) {
|
||||
money32 balance = balanceHistory[i];
|
||||
if (balance == 0x80000000)
|
||||
if (balance == MONEY32_UNDEFINED)
|
||||
continue;
|
||||
|
||||
// Modifier balance then keep halfing until less than 127 pixels
|
||||
|
@ -983,7 +983,7 @@ static void window_finances_park_value_graph_paint()
|
|||
money32 *parkValueHistory = RCT2_ADDRESS(RCT2_ADDRESS_PARK_VALUE_HISTORY, money32);
|
||||
for (i = 0; i < 64; i++) {
|
||||
money32 balance = parkValueHistory[i];
|
||||
if (balance == 0x80000000)
|
||||
if (balance == MONEY32_UNDEFINED)
|
||||
continue;
|
||||
|
||||
// Modifier balance then keep halfing until less than 255 pixels
|
||||
|
@ -1101,7 +1101,7 @@ static void window_finances_profit_graph_paint()
|
|||
money32 *weeklyProfitHistory = RCT2_ADDRESS(RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY, money32);
|
||||
for (i = 0; i < 64; i++) {
|
||||
money32 balance = weeklyProfitHistory[i];
|
||||
if (balance == 0x80000000)
|
||||
if (balance == MONEY32_UNDEFINED)
|
||||
continue;
|
||||
|
||||
// Modifier balance then keep halfing until less than 127 pixels
|
||||
|
|
|
@ -622,7 +622,7 @@ void window_guest_overview_mouse_up(){
|
|||
|
||||
w->var_48C = peep->x;
|
||||
|
||||
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
|
||||
sprite_move(0x8000, peep->y, peep->z, (rct_sprite*)peep);
|
||||
|
|
|
@ -605,7 +605,7 @@ static void window_loadsave_select(rct_window *w, const char *path)
|
|||
if (scenario_save((char*)path, gConfigGeneral.save_plugin_data ? 1 : 0)) {
|
||||
window_close(w);
|
||||
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -3808,22 +3808,22 @@ static void window_ride_colour_dropdown()
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_TRACK_MAIN_COLOUR:
|
||||
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_TRACK_ADDITIONAL_COLOUR:
|
||||
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_TRACK_SUPPORT_COLOUR:
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_MAZE_STYLE_DROPDOWN:
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_ENTRANCE_STYLE_DROPDOWN:
|
||||
game_do_command(0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
break;
|
||||
case WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN:
|
||||
game_do_command(0, (5 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, (5 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
w->var_48C = 0;
|
||||
break;
|
||||
case WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN:
|
||||
|
@ -3831,13 +3831,13 @@ static void window_ride_colour_dropdown()
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_VEHICLE_MAIN_COLOUR:
|
||||
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, w->var_48C, 0);
|
||||
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->var_48C, 0);
|
||||
break;
|
||||
case WIDX_VEHICLE_ADDITIONAL_COLOUR_1:
|
||||
game_do_command(0, (3 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, w->var_48C, 0);
|
||||
game_do_command(0, (3 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->var_48C, 0);
|
||||
break;
|
||||
case WIDX_VEHICLE_ADDITIONAL_COLOUR_2:
|
||||
game_do_command(0, (7 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, w->var_48C, 0);
|
||||
game_do_command(0, (7 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->var_48C, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ rct_window *window_construction_open()
|
|||
window_push_others_right(w);
|
||||
show_gridlines();
|
||||
|
||||
RCT2_GLOBAL(0xF44070, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0xF44070, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(0xF440CD, uint8) = 8;
|
||||
RCT2_GLOBAL(0xF440CE, uint8) = 18;
|
||||
RCT2_GLOBAL(0xF440CF, uint8) = 4;
|
||||
|
@ -307,7 +307,7 @@ void window_construction_mouseup_demolish(rct_window* w){
|
|||
RCT2_CALLPROC_X(0x6C9BA5, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
return;
|
||||
|
||||
RCT2_GLOBAL(0xF44070, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0xF44070, uint32) = MONEY32_UNDEFINED;
|
||||
sub_6C9627();
|
||||
|
||||
RCT2_GLOBAL(0xF440B8, uint8) = 3;
|
||||
|
@ -440,7 +440,7 @@ void window_construction_paint()
|
|||
short string_y = RCT2_GLOBAL(0x9D7C08, int16_t) + w->y - 23;
|
||||
if (RCT2_GLOBAL(0xF440A6, uint8_t) != 4) gfx_draw_string_centred(dpi, 1407, string_x, string_y, 0, w);
|
||||
string_y += 11;
|
||||
if (RCT2_GLOBAL(0xF44070, uint32_t) != 0x80000000 && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800))
|
||||
if (RCT2_GLOBAL(0xF44070, uint32_t) != MONEY32_UNDEFINED && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800))
|
||||
gfx_draw_string_centred(dpi, 1408, string_x, string_y, 0, (void*)0xF44070);
|
||||
}
|
||||
|
||||
|
|
|
@ -464,7 +464,7 @@ void window_scenery_open()
|
|||
window->scenery.hover_counter = 0;
|
||||
window_push_others_below(window);
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(0x00F64EC0, uint16) = 0;
|
||||
window_scenery_is_repaint_scenery_tool_on = 0; // repaint colored scenery tool state
|
||||
window_scenery_is_build_cluster_tool_on = 0; // build cluster tool state
|
||||
|
@ -643,7 +643,7 @@ static void window_scenery_mousedown(int widgetIndex, rct_window* w, rct_widget*
|
|||
if (widgetIndex >= WIDX_SCENERY_TAB_1 && widgetIndex <= WIDX_SCENERY_TAB_20) {
|
||||
window_scenery_active_tab_index = widgetIndex - WIDX_SCENERY_TAB_1;
|
||||
window_invalidate(w);
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = MONEY32_UNDEFINED;
|
||||
window_scenery_update_scroll(w);
|
||||
}
|
||||
}
|
||||
|
@ -817,7 +817,7 @@ void window_scenery_scrollmousedown()
|
|||
window_scenery_is_repaint_scenery_tool_on &= 0xFE;
|
||||
sound_play_panned(4, (w->width >> 1) + w->x, 0, 0, 0);
|
||||
w->scenery.hover_counter = -16;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = MONEY32_UNDEFINED;
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1057,7 @@ void window_scenery_paint()
|
|||
price = sceneryEntry->small_scenery.price * 10;
|
||||
}
|
||||
|
||||
if (w->scenery.selected_scenery_id == -1 && RCT2_GLOBAL(0x00F64EB4, uint32) != 0x80000000) {
|
||||
if (w->scenery.selected_scenery_id == -1 && RCT2_GLOBAL(0x00F64EB4, uint32) != MONEY32_UNDEFINED) {
|
||||
price = RCT2_GLOBAL(0x00F64EB4, uint32);
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@ static void window_sign_mouseup()
|
|||
1 | ((map_element->type&0x3) << 8),
|
||||
y,
|
||||
map_element->base_height | ((map_element->properties.scenerymultiple.type >> 10) << 8),
|
||||
GAME_COMMAND_44,
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
0,
|
||||
0);
|
||||
break;
|
||||
|
|
|
@ -457,7 +457,7 @@ void window_staff_overview_mouseup()
|
|||
|
||||
w->var_48C = peep->x;
|
||||
|
||||
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
|
||||
sprite_move( 0x8000, peep->y, peep->z, (rct_sprite*)peep);
|
||||
|
@ -573,19 +573,18 @@ void window_staff_overview_dropdown()
|
|||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
RCT2_GLOBAL(0x13B0E72 + ebx + i * 4, uint32) = 0;
|
||||
RCT2_ADDRESS(0x13B0E72 + (peep->staff_id * 512), uint32)[i] = 0;
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_STAFF_MODE_ARRAY + edi, uint16) &= 0xFD; // bug??
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] &= ~2;
|
||||
|
||||
window_invalidate(w);
|
||||
//RCT2_CALLPROC_EBPSAFE(0x006C0C3F);
|
||||
sub_6C0C3F();
|
||||
gfx_invalidate_screen();
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
else {
|
||||
if (!tool_set(w, widgetIndex, 22)) {
|
||||
show_gridlines();
|
||||
RCT2_GLOBAL(0x009DEA50, sint16) = w->number;
|
||||
window_invalidate(w);
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1417,7 +1417,7 @@ static void window_top_toolbar_scenery_tool_down(short x, short y, rct_window* w
|
|||
int cost;
|
||||
{
|
||||
int esi = 0, eax = grid_x, ecx = grid_y, edx = parameter_2, ebx = (parameter_1 & 0xFF00) | 1;
|
||||
cost = game_do_command_p(GAME_COMMAND_50, &eax, &ebx, &ecx, &edx, &esi, &banner_id, &ebp);
|
||||
cost = game_do_command_p(GAME_COMMAND_PLACE_BANNER, &eax, &ebx, &ecx, &edx, &esi, &banner_id, &ebp);
|
||||
}
|
||||
|
||||
if (cost == MONEY32_UNDEFINED)return;
|
||||
|
@ -1609,8 +1609,8 @@ void window_top_toolbar_land_tool_drag(short x, short y)
|
|||
|
||||
selection_raise_land(GAME_COMMAND_FLAG_APPLY);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, uint32) = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1619,8 +1619,8 @@ void window_top_toolbar_land_tool_drag(short x, short y)
|
|||
|
||||
selection_lower_land(GAME_COMMAND_FLAG_APPLY);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, uint32) = MONEY32_UNDEFINED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1666,8 +1666,8 @@ void window_top_toolbar_water_tool_drag(short x, short y)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16)
|
||||
);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, uint32) = MONEY32_UNDEFINED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1688,8 +1688,8 @@ void window_top_toolbar_water_tool_drag(short x, short y)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16)
|
||||
);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, uint32) = MONEY32_UNDEFINED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "../addresses.h"
|
||||
#include "../game.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "banner.h"
|
||||
|
||||
rct_banner *gBanners = (rct_banner*)0x0135A124;
|
||||
|
@ -32,3 +34,34 @@ void banner_init() {
|
|||
gBanners[i].type = BANNER_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* rct2: 0x006BA278
|
||||
* Creates a new banner and returns the index of the banner
|
||||
* If the flag GAME_COMMAND_FLAG_APPLY is NOT set then returns
|
||||
* the first unused index but does NOT mark the banner as created.
|
||||
* returns 0xFF on failure.
|
||||
*/
|
||||
int create_new_banner(uint8 flags){
|
||||
int banner_index = 0;
|
||||
for (; banner_index < MAX_BANNERS; banner_index++){
|
||||
if (gBanners[banner_index].type == BANNER_NULL){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (banner_index == MAX_BANNERS){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_MANY_BANNERS_IN_GAME;
|
||||
return BANNER_NULL;
|
||||
}
|
||||
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY){
|
||||
rct_banner* banner = &gBanners[banner_index];
|
||||
|
||||
banner->flags = 0;
|
||||
banner->type = 0;
|
||||
banner->string_idx = 778;
|
||||
banner->colour = 2;
|
||||
banner->text_colour = 2;
|
||||
}
|
||||
return banner_index;
|
||||
}
|
|
@ -44,5 +44,6 @@ enum{
|
|||
extern rct_banner *gBanners;
|
||||
|
||||
void banner_init();
|
||||
int create_new_banner(uint8 flags);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -345,7 +345,7 @@ void remove_banners_at_element(int x, int y, rct_map_element* mapElement){
|
|||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH)return;
|
||||
else if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_BANNER)continue;
|
||||
|
||||
game_do_command(x, 1, y, mapElement->base_height | mapElement->properties.banner.position << 8, GAME_COMMAND_51, 0, 0);
|
||||
game_do_command(x, 1, y, mapElement->base_height | mapElement->properties.banner.position << 8, GAME_COMMAND_REMOVE_BANNER, 0, 0);
|
||||
mapElement--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,5 +48,6 @@ void footpath_provisional_remove();
|
|||
void footpath_provisional_update();
|
||||
void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
|
||||
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
|
||||
void sub_673883(int x, int y, int z);
|
||||
|
||||
#endif
|
||||
|
|
947
src/world/map.c
947
src/world/map.c
File diff suppressed because it is too large
Load Diff
|
@ -129,6 +129,7 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
MAP_ELEMENT_FLAG_5 = (1 << 4),
|
||||
MAP_ELEMENT_FLAG_BROKEN = (1 << 5),
|
||||
MAP_ELEMENT_FLAG_LAST_TILE = (1 << 7)
|
||||
};
|
||||
|
@ -272,9 +273,23 @@ int sub_68B044();
|
|||
rct_map_element *map_element_insert(int x, int y, int z, int flags);
|
||||
int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *clearFunc, uint8 bl);
|
||||
int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl);
|
||||
int sub_6BA278(int ebx);
|
||||
|
||||
void game_command_remove_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_remove_large_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_remove_banner(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_scenery_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_fence_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_large_scenery_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_banner_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_clear_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_change_surface_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_raise_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_lower_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_lower_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_remove_fence(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_place_banner(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
|
||||
#define GET_MAP_ELEMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element)[x]))
|
||||
#define TILE_MAP_ELEMENT_POINTER(x) (RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[x])
|
||||
|
|
|
@ -48,7 +48,7 @@ void map_animation_create(int type, int x, int y, int z)
|
|||
{
|
||||
rct_map_animation *aobj = &gAnimatedObjects[0];
|
||||
int numAnimatedObjects = RCT2_GLOBAL(0x0138B580, uint16);
|
||||
for (; numAnimatedObjects > 0; aobj++) {
|
||||
for (int i = 0; i < numAnimatedObjects; i++, aobj++) {
|
||||
if (aobj->x != x)
|
||||
continue;
|
||||
if (aobj->y != y)
|
||||
|
|
|
@ -178,7 +178,7 @@ void scenery_remove_ghost_tool_placement(){
|
|||
105 | (RCT2_GLOBAL(0x00F64EC0, uint8) << 8),
|
||||
y,
|
||||
z,
|
||||
GAME_COMMAND_44,
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ void scenery_remove_ghost_tool_placement(){
|
|||
105,
|
||||
y,
|
||||
z | (RCT2_GLOBAL(0x00F64EC0, uint8) << 8),
|
||||
GAME_COMMAND_51,
|
||||
GAME_COMMAND_REMOVE_BANNER,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
|
|
@ -56,14 +56,27 @@ typedef enum {
|
|||
SMALL_SCENERY_FLAG18 = (1 << 17), // 0x20000
|
||||
SMALL_SCENERY_FLAG19 = (1 << 18), // 0x40000
|
||||
SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR = (1 << 19), // 0x80000
|
||||
SMALL_SCENERY_FLAG20 = (1 << 20), // 0x100000
|
||||
SMALL_SCENERY_FLAG21 = (1 << 21), // 0x200000
|
||||
SMALL_SCENERY_FLAG22 = (1 << 22), // 0x400000
|
||||
SMALL_SCENERY_FLAG23 = (1 << 23), // 0x800000
|
||||
SMALL_SCENERY_FLAG24 = (1 << 24), // 0x1000000
|
||||
SMALL_SCENERY_FLAG25 = (1 << 25), // 0x2000000
|
||||
} SMALL_SCENERY_FLAGS;
|
||||
|
||||
typedef struct {
|
||||
sint16 x_offset;
|
||||
sint16 y_offset;
|
||||
sint16 z_offset;
|
||||
uint8 pad_6[3];
|
||||
} rct_large_scenery_tile;
|
||||
|
||||
typedef struct {
|
||||
uint8 tool_id; // 0x06
|
||||
uint8 flags; // 0x07
|
||||
sint16 price; // 0x08
|
||||
sint16 removal_price; // 0x0A
|
||||
uint32 var_0C;
|
||||
rct_large_scenery_tile* tiles; // 0x0C
|
||||
uint8 scenery_tab_id; // 0x10
|
||||
uint8 var_11;
|
||||
uint32 var_12;
|
||||
|
|
Loading…
Reference in New Issue