From 0b8575270c369c30ac3f775f1efa9a48dacd81d9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 19 Jan 2018 00:09:42 +0000 Subject: [PATCH 01/13] Refactor memory handling in audio sources --- src/openrct2-ui/audio/AudioMixer.cpp | 73 +++++++-------------- src/openrct2-ui/audio/MemoryAudioSource.cpp | 68 ++++++++++--------- 2 files changed, 60 insertions(+), 81 deletions(-) diff --git a/src/openrct2-ui/audio/AudioMixer.cpp b/src/openrct2-ui/audio/AudioMixer.cpp index 9b3c476d19..de345e584f 100644 --- a/src/openrct2-ui/audio/AudioMixer.cpp +++ b/src/openrct2-ui/audio/AudioMixer.cpp @@ -14,10 +14,12 @@ *****************************************************************************/ #pragma endregion +#include +#include +#include #include #include #include -#include #include #include #include @@ -37,38 +39,6 @@ namespace OpenRCT2 { namespace Audio { - struct Buffer - { - private: - void * _data = nullptr; - size_t _capacity = 0; - - public: - void * GetData() const { return _data; } - void * GetData() { return _data; } - size_t GetCapacity() const { return _capacity; } - - ~Buffer() - { - Free(); - } - - void Free() - { - SafeFree(_data); - _capacity = 0; - } - - void EnsureCapacity(size_t capacity) - { - if (_capacity < capacity) - { - _capacity = capacity; - _data = Memory::Reallocate(_data, capacity); - } - } - }; - class AudioMixerImpl final : public IAudioMixer { private: @@ -86,9 +56,9 @@ namespace OpenRCT2 { namespace Audio IAudioSource * _css1Sources[SOUND_MAXID] = { nullptr }; IAudioSource * _musicSources[PATH_ID_END] = { nullptr }; - Buffer _channelBuffer; - Buffer _convertBuffer; - Buffer _effectBuffer; + std::vector _channelBuffer; + std::vector _convertBuffer; + std::vector _effectBuffer; public: AudioMixerImpl() @@ -159,9 +129,12 @@ namespace OpenRCT2 { namespace Audio } // Free buffers - _channelBuffer.Free(); - _convertBuffer.Free(); - _effectBuffer.Free(); + _channelBuffer.clear(); + _channelBuffer.shrink_to_fit(); + _convertBuffer.clear(); + _convertBuffer.shrink_to_fit(); + _effectBuffer.clear(); + _effectBuffer.shrink_to_fit(); } void Lock() override @@ -252,7 +225,7 @@ namespace OpenRCT2 { namespace Audio UpdateAdjustedSound(); // Zero the output buffer - Memory::Set(dst, 0, length); + std::fill_n(dst, length, 0); // Mix channels onto output buffer auto it = _channels.begin(); @@ -318,15 +291,15 @@ namespace OpenRCT2 { namespace Audio // Read raw PCM from channel sint32 readSamples = (sint32)(numSamples * rate); size_t readLength = (size_t)(readSamples / cvt.len_ratio) * byteRate; - _channelBuffer.EnsureCapacity(readLength); - size_t bytesRead = channel->Read(_channelBuffer.GetData(), readLength); + _channelBuffer.resize(readLength); + size_t bytesRead = channel->Read(_channelBuffer.data(), readLength); // Convert data to required format if necessary void * buffer = nullptr; size_t bufferLen = 0; if (mustConvert) { - if (Convert(&cvt, _channelBuffer.GetData(), bytesRead)) + if (Convert(&cvt, _channelBuffer.data(), bytesRead)) { buffer = cvt.buf; bufferLen = cvt.len_cvt; @@ -338,7 +311,7 @@ namespace OpenRCT2 { namespace Audio } else { - buffer = _channelBuffer.GetData(); + buffer = _channelBuffer.data(); bufferLen = bytesRead; } @@ -352,9 +325,9 @@ namespace OpenRCT2 { namespace Audio inRate = _format.freq; outRate = _format.freq * (1 / rate); } - _effectBuffer.EnsureCapacity(length); + _effectBuffer.resize(length); bufferLen = ApplyResample(channel, buffer, (sint32)(bufferLen / byteRate), numSamples, inRate, outRate); - buffer = _effectBuffer.GetData(); + buffer = _effectBuffer.data(); } // Apply panning and volume @@ -391,7 +364,7 @@ namespace OpenRCT2 { namespace Audio resampler, (const spx_int16_t *)srcBuffer, &inLen, - (spx_int16_t *)_effectBuffer.GetData(), + (spx_int16_t *)_effectBuffer.data(), &outLen); return outLen * byteRate; @@ -523,11 +496,11 @@ namespace OpenRCT2 { namespace Audio if (len != 0 && cvt->len_mult != 0) { size_t reqConvertBufferCapacity = len * cvt->len_mult; - _convertBuffer.EnsureCapacity(reqConvertBufferCapacity); - Memory::Copy(_convertBuffer.GetData(), src, len); + _convertBuffer.resize(reqConvertBufferCapacity); + std::copy_n((const uint8 *)src, len, _convertBuffer.data()); cvt->len = (sint32)len; - cvt->buf = (uint8 *)_convertBuffer.GetData(); + cvt->buf = (uint8 *)_convertBuffer.data(); if (SDL_ConvertAudio(cvt) >= 0) { result = true; diff --git a/src/openrct2-ui/audio/MemoryAudioSource.cpp b/src/openrct2-ui/audio/MemoryAudioSource.cpp index d439ff306a..a2f3b0bb30 100644 --- a/src/openrct2-ui/audio/MemoryAudioSource.cpp +++ b/src/openrct2-ui/audio/MemoryAudioSource.cpp @@ -14,6 +14,8 @@ *****************************************************************************/ #pragma endregion +#include +#include #include #include #include @@ -32,10 +34,15 @@ namespace OpenRCT2 { namespace Audio class MemoryAudioSource final : public ISDLAudioSource { private: - AudioFormat _format = { 0 }; - uint8 * _data = nullptr; - size_t _length = 0; - bool _isSDLWav = false; + AudioFormat _format = { 0 }; + std::vector _data; + uint8 * _dataSDL = nullptr; + size_t _length = 0; + + const uint8 * GetData() + { + return _dataSDL != nullptr ? _dataSDL : _data.data(); + } public: ~MemoryAudioSource() @@ -59,7 +66,12 @@ namespace OpenRCT2 { namespace Audio if (offset < _length) { bytesToRead = (size_t)Math::Min(len, _length - offset); - Memory::Copy(dst, _data + offset, bytesToRead); + + auto src = GetData(); + if (src != nullptr) + { + std::copy_n(src + offset, bytesToRead, (uint8 *)dst); + } } return bytesToRead; } @@ -76,14 +88,13 @@ namespace OpenRCT2 { namespace Audio { SDL_AudioSpec audiospec = { 0 }; uint32 audioLen; - SDL_AudioSpec * spec = SDL_LoadWAV_RW(rw, false, &audiospec, &_data, &audioLen); + SDL_AudioSpec * spec = SDL_LoadWAV_RW(rw, false, &audiospec, &_dataSDL, &audioLen); if (spec != nullptr) { _format.freq = spec->freq; _format.format = spec->format; _format.channels = spec->channels; _length = audioLen; - _isSDLWav = true; result = true; } else @@ -129,13 +140,13 @@ namespace OpenRCT2 { namespace Audio _format.format = AUDIO_S16LSB; _format.channels = waveFormat.channels; - _data = new (std::nothrow) uint8[_length]; - if (_data != nullptr) + try { - SDL_RWread(rw, _data, _length, 1); + _data.resize(_length); + SDL_RWread(rw, _data.data(), _length, 1); result = true; } - else + catch (const std::bad_alloc &) { log_verbose("Unable to allocate data"); } @@ -156,21 +167,21 @@ namespace OpenRCT2 { namespace Audio SDL_AudioCVT cvt; if (SDL_BuildAudioCVT(&cvt, _format.format, _format.channels, _format.freq, format->format, format->channels, format->freq) >= 0) { + auto src = GetData(); + auto cvtBuffer = std::vector(_length * cvt.len_mult); + std::copy_n(src, _length, cvtBuffer.data()); cvt.len = (sint32)_length; - cvt.buf = new uint8[cvt.len * cvt.len_mult]; - Memory::Copy(cvt.buf, _data, _length); + cvt.buf = cvtBuffer.data(); if (SDL_ConvertAudio(&cvt) >= 0) { + cvtBuffer.resize(cvt.len_cvt); + Unload(); - _data = cvt.buf; + _data = std::move(cvtBuffer); _length = cvt.len_cvt; _format = *format; return true; } - else - { - delete[] cvt.buf; - } } } return false; @@ -179,19 +190,14 @@ namespace OpenRCT2 { namespace Audio private: void Unload() { - if (_data != nullptr) - { - if (_isSDLWav) - { - SDL_FreeWAV(_data); - } - else - { - delete[] _data; - } - _data = nullptr; - } - _isSDLWav = false; + // Free our data + _data.clear(); + _data.shrink_to_fit(); + + // Free SDL2's data + SDL_FreeWAV(_dataSDL); + _dataSDL = nullptr; + _length = 0; } }; From ba5bc415c7ff4745561a3b1b975f930425e761c4 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 19 Jan 2018 00:32:53 +0000 Subject: [PATCH 02/13] Refactor memory handling in window sources --- src/openrct2-ui/windows/InstallTrack.cpp | 37 +++++++++------- src/openrct2-ui/windows/TrackList.cpp | 49 +++++++++++---------- src/openrct2/ride/TrackDesign.cpp | 2 +- src/openrct2/ride/TrackDesignRepository.cpp | 29 +++--------- src/openrct2/ride/TrackDesignRepository.h | 14 +++--- 5 files changed, 56 insertions(+), 75 deletions(-) diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index bc239d1fcc..0cad3e4dbd 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -14,6 +14,9 @@ *****************************************************************************/ #pragma endregion +#include +#include + #include #include #include @@ -94,10 +97,10 @@ static rct_window_event_list window_install_track_events = { nullptr }; -static rct_track_td6 *_trackDesign; -static utf8 *_trackPath; -static utf8 *_trackName; -static uint8 *_trackDesignPreviewPixels; +static rct_track_td6 * _trackDesign; +static std::string _trackPath; +static std::string _trackName; +static std::vector _trackDesignPreviewPixels; static void window_install_track_update_preview(); static void window_install_track_design(rct_window *w); @@ -142,9 +145,9 @@ rct_window * window_install_track_open(const utf8 *path) w->track_list.track_list_being_updated = false; window_push_others_right(w); - _trackPath = _strdup(path); - _trackName = track_repository_get_name_from_path(path); - _trackDesignPreviewPixels = Memory::AllocateArray(4 * TRACK_PREVIEW_IMAGE_SIZE); + _trackPath = path; + _trackName = GetNameFromTrackPath(path); + _trackDesignPreviewPixels.resize(4 * TRACK_PREVIEW_IMAGE_SIZE); window_install_track_update_preview(); window_invalidate(w); @@ -158,9 +161,10 @@ rct_window * window_install_track_open(const utf8 *path) */ static void window_install_track_close(rct_window *w) { - SafeFree(_trackPath); - SafeFree(_trackName); - SafeFree(_trackDesignPreviewPixels); + _trackPath.clear(); + _trackName.clear(); + _trackDesignPreviewPixels.clear(); + _trackDesignPreviewPixels.shrink_to_fit(); track_design_dispose(_trackDesign); _trackDesign = nullptr; } @@ -229,7 +233,7 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) gfx_fill_rect(dpi, x, y, x + 369, y + 216, colour); rct_g1_element g1temp = { nullptr }; - g1temp.offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); + g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); g1temp.width = 370; g1temp.height = 217; g1temp.flags = G1_FLAG_BMP; @@ -400,15 +404,14 @@ static void window_install_track_text_input(rct_window *w, rct_widgetindex widge return; } - free(_trackName); - _trackName = _strdup(text); + _trackName = text; window_event_mouse_up_call(w, WIDX_INSTALL); } static void window_install_track_update_preview() { - track_design_draw_preview(_trackDesign, _trackDesignPreviewPixels); + track_design_draw_preview(_trackDesign, _trackDesignPreviewPixels.data()); } static void window_install_track_design(rct_window *w) @@ -422,7 +425,7 @@ static void window_install_track_design(rct_window *w) return; } - safe_strcat_path(destPath, _trackName, sizeof(destPath)); + safe_strcat_path(destPath, _trackName.c_str(), sizeof(destPath)); path_append_extension(destPath, ".td6", sizeof(destPath)); if (platform_file_exists(destPath)) { @@ -433,11 +436,11 @@ static void window_install_track_design(rct_window *w) WIDX_INSTALL, STR_SELECT_NEW_NAME_FOR_TRACK_DESIGN, STR_AN_EXISTING_TRACK_DESIGN_ALREADY_HAS_THIS_NAME, - _trackName, + _trackName.c_str(), 255 ); } else { - if (track_repository_install(_trackPath)) { + if (track_repository_install(_trackPath.c_str())) { window_close(w); } else { context_show_error(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE); diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index 68d207e56c..cffd2a6ed3 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -14,8 +14,7 @@ *****************************************************************************/ #pragma endregion -#include - +#include #include #include #include @@ -30,7 +29,7 @@ #include #include #include -#include +#include enum { WIDX_BACKGROUND, @@ -108,13 +107,12 @@ static rct_window_event_list window_track_list_events = { ride_list_item _window_track_list_item; -static track_design_file_ref * _trackDesigns = nullptr; -static size_t _trackDesignsCount = 0; +static std::vector _trackDesigns; static utf8 _filterString[USER_STRING_MAX_LENGTH]; static std::vector _filteredTrackIds; static uint16 _loadedTrackDesignIndex; static rct_track_td6 * _loadedTrackDesign; -static uint8 * _trackDesignPreviewPixels; +static std::vector _trackDesignPreviewPixels; static void track_list_load_designs(ride_list_item item); static bool track_list_load_design_for_preview(utf8 *path); @@ -171,7 +169,7 @@ rct_window * window_track_list_open(ride_list_item item) // Start with first track highlighted w->selected_list_item = 0; - if (_trackDesignsCount != 0 && !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) { + if (_trackDesigns.size() != 0 && !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) { w->selected_list_item = 1; } @@ -179,7 +177,7 @@ rct_window * window_track_list_open(ride_list_item item) window_push_others_right(w); _currentTrackPieceDirection = 2; - _trackDesignPreviewPixels = Memory::AllocateArray(4 * TRACK_PREVIEW_IMAGE_SIZE); + _trackDesignPreviewPixels.resize(4 * TRACK_PREVIEW_IMAGE_SIZE); _loadedTrackDesign = nullptr; _loadedTrackDesignIndex = TRACK_DESIGN_INDEX_UNLOADED; @@ -194,7 +192,7 @@ static void window_track_list_filter_list() // Nothing to filter, so fill the list with all indices if (String::LengthOf(_filterString) == 0) { - for (uint16 i = 0; i < _trackDesignsCount; i++) + for (uint16 i = 0; i < _trackDesigns.size(); i++) _filteredTrackIds.push_back(i); return; @@ -207,7 +205,7 @@ static void window_track_list_filter_list() filterStringLower[i] = (utf8)tolower(filterStringLower[i]); // Fill the set with indices for tracks that match the filter - for (uint16 i = 0; i < _trackDesignsCount; i++) + for (uint16 i = 0; i < _trackDesigns.size(); i++) { utf8 trackNameLower[USER_STRING_MAX_LENGTH]; String::Set(trackNameLower, sizeof(trackNameLower), _trackDesigns[i].name); @@ -230,15 +228,16 @@ static void window_track_list_close(rct_window *w) // Dispose track design and preview track_design_dispose(_loadedTrackDesign); _loadedTrackDesign = nullptr; - SafeFree(_trackDesignPreviewPixels); + _trackDesignPreviewPixels.clear(); + _trackDesignPreviewPixels.shrink_to_fit(); // Dispose track list - for (size_t i = 0; i < _trackDesignsCount; i++) { - free(_trackDesigns[i].name); - free(_trackDesigns[i].path); + for (auto &trackDesign : _trackDesigns) + { + free(trackDesign.name); + free(trackDesign.path); } - SafeFree(_trackDesigns); - _trackDesignsCount = 0; + _trackDesigns.clear(); // If gScreenAge is zero, we're already in the process // of loading the track manager, so we shouldn't try @@ -501,7 +500,7 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi) sint32 listItemIndex = w->selected_list_item; if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { - if (_trackDesignsCount == 0 || listItemIndex == -1) + if (_trackDesigns.size() == 0 || listItemIndex == -1) return; } else { @@ -538,7 +537,7 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi) } rct_g1_element g1temp = { nullptr }; - g1temp.offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); + g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); g1temp.width = 370; g1temp.height = 217; g1temp.flags = G1_FLAG_BMP; @@ -684,7 +683,7 @@ static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 y = 0; size_t listIndex = 0; if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { - if (_trackDesignsCount == 0) { + if (_trackDesigns.size() == 0) { // No track designs gfx_draw_string_left(dpi, STR_NO_TRACK_DESIGNS_OF_THIS_TYPE, nullptr, COLOUR_BLACK, x, y - 1); return; @@ -735,6 +734,7 @@ static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, static void track_list_load_designs(ride_list_item item) { + auto repo = GetTrackDesignRepository(); if (!RideGroupManager::RideTypeHasRideGroups(item.type)) { char entry[9]; @@ -747,13 +747,14 @@ static void track_list_load_designs(ride_list_item item) entryPtr = entry; } } - _trackDesignsCount = track_repository_get_items_for_ride(&_trackDesigns, item.type, entryPtr); + + _trackDesigns = repo->GetItemsForObjectEntry(item.type, String::ToStd(entryPtr)); } else { - rct_ride_entry *rideEntry = get_ride_entry(item.entry_index); - const RideGroup * rideGroup = RideGroupManager::GetRideGroup(item.type, rideEntry); - _trackDesignsCount = track_repository_get_items_for_ride_group(&_trackDesigns, item.type, rideGroup); + auto rideEntry = get_ride_entry(item.entry_index); + auto rideGroup = RideGroupManager::GetRideGroup(item.type, rideEntry); + _trackDesigns = repo->GetItemsForRideGroup(item.type, rideGroup); } window_track_list_filter_list(); @@ -767,7 +768,7 @@ static bool track_list_load_design_for_preview(utf8 *path) _loadedTrackDesign = track_design_open(path); if (_loadedTrackDesign != nullptr && drawing_engine_get_type() != DRAWING_ENGINE_OPENGL) { - track_design_draw_preview(_loadedTrackDesign, _trackDesignPreviewPixels); + track_design_draw_preview(_loadedTrackDesign, _trackDesignPreviewPixels.data()); return true; } return false; diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 8cc325d94a..24b27c0742 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -114,7 +114,7 @@ rct_track_td6 * track_design_open(const utf8 * path) if (td6 != nullptr) { - td6->name = track_repository_get_name_from_path(path); + td6->name = String::Duplicate(GetNameFromTrackPath(path).c_str()); return td6; } } diff --git a/src/openrct2/ride/TrackDesignRepository.cpp b/src/openrct2/ride/TrackDesignRepository.cpp index 1df5fb3d9e..1b6b1d42d1 100644 --- a/src/openrct2/ride/TrackDesignRepository.cpp +++ b/src/openrct2/ride/TrackDesignRepository.cpp @@ -49,7 +49,7 @@ enum TRACK_REPO_ITEM_FLAGS TRIF_READ_ONLY = (1 << 0), }; -static std::string GetNameFromTrackPath(const std::string &path) +std::string GetNameFromTrackPath(const std::string &path) { std::string name = Path::GetFileNameWithoutExtension(path); //The track name should be the file name until the first instance of a dot @@ -222,7 +222,7 @@ public: * @param entry The entry name to build a track list for. Leave empty to build track list for the non-separated types (e.g. Hyper-Twister, Car Ride) * @return */ - size_t GetItemsForObjectEntry(track_design_file_ref * * outRefs, uint8 rideType, const std::string &entry) const override + std::vector GetItemsForObjectEntry(uint8 rideType, const std::string &entry) const override { std::vector refs; const IObjectRepository * repo = GetObjectRepository(); @@ -252,11 +252,10 @@ public: } } - *outRefs = Collections::ToArray(refs); - return refs.size(); + return refs; } - size_t GetItemsForRideGroup(track_design_file_ref **outRefs, uint8 rideType, const RideGroup * rideGroup) const override + std::vector GetItemsForRideGroup(uint8 rideType, const RideGroup * rideGroup) const override { std::vector refs; const IObjectRepository * repo = GetObjectRepository(); @@ -281,8 +280,7 @@ public: } } - *outRefs = Collections::ToArray(refs); - return refs.size(); + return refs; } void Scan() override @@ -418,18 +416,6 @@ extern "C" repo->Scan(); } - size_t track_repository_get_items_for_ride(track_design_file_ref * * outRefs, uint8 rideType, const utf8 * entry) - { - ITrackDesignRepository * repo = GetTrackDesignRepository(); - return repo->GetItemsForObjectEntry(outRefs, rideType, String::ToStd(entry)); - } - - size_t track_repository_get_items_for_ride_group(track_design_file_ref * * outRefs, uint8 rideType, const RideGroup * rideGroup) - { - ITrackDesignRepository * repo = GetTrackDesignRepository(); - return repo->GetItemsForRideGroup(outRefs, rideType, rideGroup); - } - bool track_repository_delete(const utf8 * path) { ITrackDesignRepository * repo = GetTrackDesignRepository(); @@ -449,9 +435,4 @@ extern "C" std::string newPath = repo->Install(srcPath); return !newPath.empty(); } - - utf8 * track_repository_get_name_from_path(const utf8 * path) - { - return String::Duplicate(GetNameFromTrackPath(path)); - } } diff --git a/src/openrct2/ride/TrackDesignRepository.h b/src/openrct2/ride/TrackDesignRepository.h index 8f81709290..88a109e234 100644 --- a/src/openrct2/ride/TrackDesignRepository.h +++ b/src/openrct2/ride/TrackDesignRepository.h @@ -42,12 +42,10 @@ interface ITrackDesignRepository virtual size_t GetCount() const abstract; virtual size_t GetCountForObjectEntry(uint8 rideType, const std::string &entry) const abstract; virtual size_t GetCountForRideGroup(uint8 rideType, const RideGroup * rideGroup) const abstract; - virtual size_t GetItemsForObjectEntry(track_design_file_ref * * outRefs, - uint8 rideType, - const std::string &entry) const abstract; - virtual size_t GetItemsForRideGroup(track_design_file_ref **outRefs, - uint8 rideType, - const RideGroup * rideGroup) const abstract; + virtual std::vector GetItemsForObjectEntry(uint8 rideType, + const std::string &entry) const abstract; + virtual std::vector GetItemsForRideGroup(uint8 rideType, + const RideGroup * rideGroup) const abstract; virtual void Scan() abstract; virtual bool Delete(const std::string &path) abstract; @@ -57,6 +55,7 @@ interface ITrackDesignRepository ITrackDesignRepository * CreateTrackDesignRepository(OpenRCT2::IPlatformEnvironment * env); ITrackDesignRepository * GetTrackDesignRepository(); +std::string GetNameFromTrackPath(const std::string &path); #endif @@ -65,9 +64,6 @@ extern "C" { #endif void track_repository_scan(); - size_t track_repository_get_items_for_ride(track_design_file_ref * * outRefs, uint8 rideType, const utf8 * entry); - size_t track_repository_get_items_for_ride_group(track_design_file_ref * * outRefs, uint8 rideType, const RideGroup * rideGroup); - utf8 * track_repository_get_name_from_path(const utf8 *path); bool track_repository_delete(const utf8 *path); bool track_repository_rename(const utf8 *path, const utf8 *newName); bool track_repository_install(const utf8 *srcPath); From badb90ba20d1f81da1e439d77c6ff91e83dc17df Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 19 Jan 2018 12:41:14 +0000 Subject: [PATCH 03/13] Refactor memory handling in Changelog.cpp --- src/openrct2-ui/windows/Changelog.cpp | 117 +++++++++++++------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/src/openrct2-ui/windows/Changelog.cpp b/src/openrct2-ui/windows/Changelog.cpp index 696f41627f..2624113cca 100644 --- a/src/openrct2-ui/windows/Changelog.cpp +++ b/src/openrct2-ui/windows/Changelog.cpp @@ -14,16 +14,17 @@ *****************************************************************************/ #pragma endregion +#include +#include #include #include #include -#include -#include - -#include +#include #include #include #include +#include +#include enum { WIDX_BACKGROUND, @@ -89,10 +90,8 @@ static rct_window_event_list window_changelog_events = { static bool window_changelog_read_file(); static void window_changelog_dispose_file(); -static char *_changelogText = nullptr; -static size_t _changelogTextSize = 0; -static char **_changelogLines = nullptr; -static sint32 _changelogNumLines = 0; +static std::string _changelogText; +static std::vector _changelogLines; static sint32 _changelogLongestLineWidth = 0; rct_window * window_changelog_open() @@ -164,7 +163,7 @@ static void window_changelog_resize(rct_window *w) static void window_changelog_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height) { *width = _changelogLongestLineWidth + 4; - *height = _changelogNumLines * 11; + *height = (sint32)(_changelogLines.size() * 11); } static void window_changelog_invalidate(rct_window *w) @@ -192,73 +191,76 @@ static void window_changelog_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 x = 3; sint32 y = 3; - for (sint32 i = 0; i < _changelogNumLines; i++) { - gfx_draw_string(dpi, _changelogLines[i], w->colours[0], x, y); + for (auto line : _changelogLines) + { + gfx_draw_string(dpi, (char *)line, w->colours[0], x, y); y += 11; } } -static bool window_changelog_read_file() +static std::string GetChangelogText() { - window_changelog_dispose_file(); utf8 path[MAX_PATH]; platform_get_changelog_path(path, sizeof(path)); - if (!readentirefile(path, (void**)&_changelogText, &_changelogTextSize)) { + +#if defined(_WIN32) && !defined(__MINGW32__) + auto pathW = String::ToUtf16(path); + auto fs = std::ifstream(pathW, std::ios::out | std::ios::app); +#else + auto fs = std::ifstream(path, std::ios::out | std::ios::app); +#endif + return std::string((std::istreambuf_iterator(fs)), std::istreambuf_iterator()); +} + +static bool window_changelog_read_file() +{ + try + { + _changelogText = GetChangelogText(); + } + catch (const std::bad_alloc &) + { + log_error("Unable to allocate memory for changelog.txt"); + return false; + } + catch (const std::exception &) + { log_error("Unable to read changelog.txt"); return false; } - void* new_memory = realloc(_changelogText, _changelogTextSize + 1); - if (new_memory == nullptr) { - log_error("Failed to reallocate memory for changelog text"); - return false; - } - _changelogText = (char*)new_memory; - _changelogText[_changelogTextSize++] = 0; - char *start = _changelogText; - if (_changelogTextSize >= 3 && utf8_is_bom(_changelogText)) + auto * start = _changelogText.data(); + if (_changelogText.size() >= 3 && utf8_is_bom(start)) + { start += 3; + } - sint32 changelogLinesCapacity = 8; - _changelogLines = Memory::Allocate(changelogLinesCapacity * sizeof(char*)); - _changelogLines[0] = start; - _changelogNumLines = 1; - - char *ch = start; - while (*ch != 0) { + _changelogLines.clear(); + _changelogLines.push_back(start); + auto ch = start; + while (*ch != '\0') + { uint8 c = *ch; - if (c == '\n') { + if (c == '\n') + { *ch++ = 0; - _changelogNumLines++; - if (_changelogNumLines > changelogLinesCapacity) { - changelogLinesCapacity *= 2; - new_memory = realloc(_changelogLines, changelogLinesCapacity * sizeof(char*)); - if (new_memory == nullptr) { - log_error("Failed to reallocate memory for change log lines"); - return false; - } - _changelogLines = (char**)new_memory; - } - _changelogLines[_changelogNumLines - 1] = ch; - } else if (c < 32 || c > 122) { - // A character that won't be drawn or change state. + _changelogLines.push_back(ch); + } + else if (utf8_is_format_code(c)) + { *ch++ = FORMAT_OUTLINE_OFF; - } else { + } + else + { ch++; } } - new_memory = realloc(_changelogLines, _changelogNumLines * sizeof(char*)); - if (new_memory == nullptr) { - log_error("Failed to reallocate memory for change log lines"); - return false; - } - _changelogLines = (char**)new_memory; - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; _changelogLongestLineWidth = 0; - for (sint32 i = 0; i < _changelogNumLines; i++) { - sint32 width = gfx_get_string_width(_changelogLines[i]); + for (auto line : _changelogLines) + { + auto width = gfx_get_string_width(line); _changelogLongestLineWidth = Math::Max(width, _changelogLongestLineWidth); } return true; @@ -266,8 +268,7 @@ static bool window_changelog_read_file() static void window_changelog_dispose_file() { - SafeFree(_changelogText); - SafeFree(_changelogLines); - _changelogTextSize = 0; - _changelogNumLines = 0; + _changelogText = std::string(); + _changelogLines.clear(); + _changelogLines.shrink_to_fit(); } From cbbb35bf791964bf1d11caf3e25887d3ff5583e9 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 19 Jan 2018 12:46:13 +0000 Subject: [PATCH 04/13] Refactor memory handling in ObjectLoadError.cpp --- src/openrct2-ui/windows/ObjectLoadError.cpp | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/openrct2-ui/windows/ObjectLoadError.cpp b/src/openrct2-ui/windows/ObjectLoadError.cpp index ddf24e2a15..415c584fe4 100644 --- a/src/openrct2-ui/windows/ObjectLoadError.cpp +++ b/src/openrct2-ui/windows/ObjectLoadError.cpp @@ -14,13 +14,14 @@ *****************************************************************************/ #pragma endregion -#include - +#include +#include #include -#include #include #include #include +#include +#include enum WINDOW_OBJECT_LOAD_ERROR_WIDGET_IDX { WIDX_BACKGROUND, @@ -96,9 +97,9 @@ static rct_window_event_list window_object_load_error_events = { window_object_load_error_scrollpaint }; -static rct_object_entry * _invalid_entries = nullptr; +static std::vector _invalid_entries; static sint32 highlighted_index = -1; -static utf8 * file_path = nullptr; +static std::string file_path; /** * Returns an rct_string_id that represents an rct_object_entry's type. @@ -187,9 +188,7 @@ static void copy_object_names_to_clipboard(rct_window *w) rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects, const rct_object_entry * missingObjects) { - size_t missingObjectsSize = numMissingObjects * sizeof(rct_object_entry); - _invalid_entries = Memory::AllocateArray(numMissingObjects); - memcpy(_invalid_entries, missingObjects, missingObjectsSize); + _invalid_entries = std::vector(missingObjects, missingObjects + numMissingObjects); // Check if window is already open rct_window * window = window_bring_to_front_by_class(WC_OBJECT_LOAD_ERROR); @@ -213,7 +212,7 @@ rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects // Refresh list items and path window->no_list_items = (uint16)numMissingObjects; - file_path = strndup(path, strnlen(path, MAX_PATH)); + file_path = path; window_invalidate(window); return window; @@ -221,7 +220,8 @@ rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects static void window_object_load_error_close(rct_window *w) { - SafeFree(_invalid_entries); + _invalid_entries.clear(); + _invalid_entries.shrink_to_fit(); } static void window_object_load_error_update(rct_window *w) @@ -303,7 +303,7 @@ static void window_object_load_error_paint(rct_window *w, rct_drawpixelinfo *dpi // Draw file name set_format_arg(0, rct_string_id, STR_OBJECT_ERROR_WINDOW_FILE); - set_format_arg(2, utf8*, file_path); + set_format_arg(2, utf8*, file_path.c_str()); gfx_draw_string_left_clipped(dpi, STR_BLACK_STRING, gCommonFormatArgs, COLOUR_BLACK, w->x + 5, w->y + 43, WW-5); } From 4d57a4b03a8380d635cb14a715059a8aaba328b6 Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 19 Jan 2018 12:49:46 +0000 Subject: [PATCH 05/13] Refactor memory handling in TrackDesignPlace.cpp --- src/openrct2-ui/windows/TrackDesignPlace.cpp | 21 ++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index f8b5ea691b..fe8944bebe 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -14,23 +14,23 @@ *****************************************************************************/ #pragma endregion -#include - +#include +#include #include #include #include #include -#include #include #include -#include -#include #include #include #include #include #include #include +#include +#include +#include #define TRACK_MINI_PREVIEW_WIDTH 168 #define TRACK_MINI_PREVIEW_HEIGHT 78 @@ -104,7 +104,7 @@ static rct_window_event_list window_track_place_events = { nullptr }; -static uint8 *_window_track_place_mini_preview; +static std::vector _window_track_place_mini_preview; static sint16 _window_track_place_last_x; static sint16 _window_track_place_last_y; @@ -135,7 +135,7 @@ static uint8 *draw_mini_preview_get_pixel_ptr(LocationXY16 pixel); */ static void window_track_place_clear_mini_preview() { - memset(_window_track_place_mini_preview, PALETTE_INDEX_TRANSPARENT, TRACK_MINI_PREVIEW_SIZE); + std::fill(_window_track_place_mini_preview.begin(), _window_track_place_mini_preview.end(), PALETTE_INDEX_TRANSPARENT); } #define swap(x, y) x = x ^ y; y = x ^ y; x = x ^ y; @@ -153,7 +153,7 @@ rct_window * window_track_place_open(const track_design_file_ref *tdFileRef) window_close_construction_windows(); - _window_track_place_mini_preview = Memory::Allocate(TRACK_MINI_PREVIEW_SIZE); + _window_track_place_mini_preview.resize(TRACK_MINI_PREVIEW_SIZE); rct_window *w = window_create( 0, @@ -198,7 +198,8 @@ static void window_track_place_close(rct_window *w) gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW; hide_gridlines(); - SafeFree(_window_track_place_mini_preview); + _window_track_place_mini_preview.clear(); + _window_track_place_mini_preview.shrink_to_fit(); track_design_dispose(_trackDesign); _trackDesign = nullptr; } @@ -468,7 +469,7 @@ static void window_track_place_paint(rct_window *w, rct_drawpixelinfo *dpi) rct_drawpixelinfo clippedDpi; if (clip_drawpixelinfo(&clippedDpi, dpi, w->x + 4, w->y + 18, 168, 78)) { rct_g1_element g1temp = { nullptr }; - g1temp.offset = _window_track_place_mini_preview; + g1temp.offset = _window_track_place_mini_preview.data(); g1temp.width = TRACK_MINI_PREVIEW_WIDTH; g1temp.height = TRACK_MINI_PREVIEW_HEIGHT; gfx_set_g1_element(SPR_TEMP, &g1temp); From b52333f53272c0e09a2f2232eb1f362cef53a2be Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 19 Jan 2018 13:05:34 +0000 Subject: [PATCH 06/13] Refactor memory handling in TitleScenarioSelect.cpp --- .../windows/TitleScenarioSelect.cpp | 196 +++++++++--------- 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/src/openrct2-ui/windows/TitleScenarioSelect.cpp b/src/openrct2-ui/windows/TitleScenarioSelect.cpp index 18345452b2..99ff4f4098 100644 --- a/src/openrct2-ui/windows/TitleScenarioSelect.cpp +++ b/src/openrct2-ui/windows/TitleScenarioSelect.cpp @@ -14,42 +14,46 @@ *****************************************************************************/ #pragma endregion -#include -#include -#include -#include -#include - +#include #include +#include +#include +#include #include #include +#include +#include #include -#include -#include #include +#include +#include #define INITIAL_NUM_UNLOCKED_SCENARIOS 5 -enum { - LIST_ITEM_TYPE_HEADING, - LIST_ITEM_TYPE_SCENARIO, - LIST_ITEM_TYPE_END, +enum class LIST_ITEM_TYPE : uint8 +{ + HEADING, + SCENARIO, }; -typedef struct sc_list_item { - uint8 type; - union { - struct { +struct sc_list_item +{ + LIST_ITEM_TYPE type; + union + { + struct + { rct_string_id string_id; } heading; - struct { - const scenario_index_entry *scenario; + struct + { + const scenario_index_entry * scenario; bool is_locked; } scenario; }; -} sc_list_item; +}; -static sc_list_item *_listItems = nullptr; +static std::vector _listItems; enum { WIDX_BACKGROUND, @@ -250,7 +254,8 @@ static void window_scenarioselect_init_tabs(rct_window *w) static void window_scenarioselect_close(rct_window *w) { - SafeFree(_listItems); + _listItems.clear(); + _listItems.shrink_to_fit(); } static void window_scenarioselect_mouseup(rct_window *w, rct_widgetindex widgetIndex) @@ -277,12 +282,14 @@ static void window_scenarioselect_mousedown(rct_window *w, rct_widgetindex widge static void window_scenarioselect_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height) { sint32 y = 0; - for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) { - switch (listItem->type) { - case LIST_ITEM_TYPE_HEADING: + for (const auto &listItem : _listItems) + { + switch (listItem.type) + { + case LIST_ITEM_TYPE::HEADING: y += 18; break; - case LIST_ITEM_TYPE_SCENARIO: + case LIST_ITEM_TYPE::SCENARIO: y += 24; break; } @@ -296,17 +303,19 @@ static void window_scenarioselect_scrollgetsize(rct_window *w, sint32 scrollInde */ static void window_scenarioselect_scrollmousedown(rct_window *w, sint32 scrollIndex, sint32 x, sint32 y) { - for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) { - switch (listItem->type) { - case LIST_ITEM_TYPE_HEADING: + for (const auto &listItem : _listItems) + { + switch (listItem.type) + { + case LIST_ITEM_TYPE::HEADING: y -= 18; break; - case LIST_ITEM_TYPE_SCENARIO: + case LIST_ITEM_TYPE::SCENARIO: y -= 24; - if (y < 0 && !listItem->scenario.is_locked) { + if (y < 0 && !listItem.scenario.is_locked) { audio_play_sound(SOUND_CLICK_1, 0, w->x + (w->width / 2)); gFirstTimeSaving = true; - _callback(listItem->scenario.scenario->path); + _callback(listItem.scenario.scenario->path); if (_titleEditor) { window_close(w); @@ -329,18 +338,20 @@ static void window_scenarioselect_scrollmouseover(rct_window *w, sint32 scrollIn bool originalShowLockedInformation = _showLockedInformation; _showLockedInformation = false; const scenario_index_entry *selected = nullptr; - for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) { - switch (listItem->type) { - case LIST_ITEM_TYPE_HEADING: + for (const auto &listItem : _listItems) + { + switch (listItem.type) + { + case LIST_ITEM_TYPE::HEADING: y -= 18; break; - case LIST_ITEM_TYPE_SCENARIO: + case LIST_ITEM_TYPE::SCENARIO: y -= 24; if (y < 0) { - if (listItem->scenario.is_locked) { + if (listItem.scenario.is_locked) { _showLockedInformation = true; } else { - selected = listItem->scenario.scenario; + selected = listItem.scenario.scenario; } } break; @@ -483,30 +494,32 @@ static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo * sint32 listWidth = listWidget->right - listWidget->left - 12; sint32 y = 0; - for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) { + for (const auto &listItem : _listItems) + { if (y > dpi->y + dpi->height) { continue; } - switch (listItem->type) { - case LIST_ITEM_TYPE_HEADING: + switch (listItem.type) + { + case LIST_ITEM_TYPE::HEADING: { const sint32 horizontalRuleMargin = 4; - draw_category_heading(w, dpi, horizontalRuleMargin, listWidth - horizontalRuleMargin, y + 2, listItem->heading.string_id); + draw_category_heading(w, dpi, horizontalRuleMargin, listWidth - horizontalRuleMargin, y + 2, listItem.heading.string_id); y += 18; break; } - case LIST_ITEM_TYPE_SCENARIO: + case LIST_ITEM_TYPE::SCENARIO: { // Draw hover highlight - const scenario_index_entry *scenario = listItem->scenario.scenario; + const scenario_index_entry *scenario = listItem.scenario.scenario; bool isHighlighted = w->highlighted_scenario == scenario; if (isHighlighted) { gfx_filter_rect(dpi, 0, y, w->width, y + 23, PALETTE_DARKEN_1); } bool isCompleted = scenario->highscore != nullptr; - bool isDisabled = listItem->scenario.is_locked; + bool isDisabled = listItem.scenario.is_locked; // Draw scenario name char buffer[64]; @@ -574,12 +587,8 @@ static void draw_category_heading(rct_window *w, rct_drawpixelinfo *dpi, sint32 static void initialise_list_items(rct_window *w) { - SafeFree(_listItems); - size_t numScenarios = scenario_repository_get_count(); - size_t capacity = numScenarios + 16; - size_t length = 0; - _listItems = Memory::AllocateArray(capacity); + _listItems.clear(); // Mega park unlock const uint32 rct1RequiredCompletedScenarios = (1 << SC_MEGA_PARK) - 1; @@ -596,8 +605,6 @@ static void initialise_list_items(rct_window *w) if (_titleEditor && scenario->source_game == SCENARIO_SOURCE_OTHER) continue; - sc_list_item *listItem; - // Category heading rct_string_id headingStringId = STR_NONE; if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor) { @@ -623,70 +630,69 @@ static void initialise_list_items(rct_window *w) } } - if (headingStringId != STR_NONE) { - // Ensure list capacity - if (length == capacity) { - capacity += 32; - _listItems = Memory::ReallocateArray(_listItems, capacity); - } - listItem = &_listItems[length++]; - - listItem->type = LIST_ITEM_TYPE_HEADING; - listItem->heading.string_id = headingStringId; + if (headingStringId != STR_NONE) + { + sc_list_item headerItem; + headerItem.type = LIST_ITEM_TYPE::HEADING; + headerItem.heading.string_id = headingStringId; + _listItems.push_back(std::move(headerItem)); } - // Ensure list capacity - if (length == capacity) { - capacity += 32; - _listItems = Memory::ReallocateArray(_listItems, capacity); - } - listItem = &_listItems[length++]; - // Scenario - listItem->type = LIST_ITEM_TYPE_SCENARIO; - listItem->scenario.scenario = scenario; - if (is_locking_enabled(w)) { - listItem->scenario.is_locked = numUnlocks <= 0; - if (scenario->highscore == nullptr) { + sc_list_item scenarioItem; + scenarioItem.type = LIST_ITEM_TYPE::SCENARIO; + scenarioItem.scenario.scenario = scenario; + if (is_locking_enabled(w)) + { + scenarioItem.scenario.is_locked = numUnlocks <= 0; + if (scenario->highscore == nullptr) + { numUnlocks--; - } else { + } + else + { // Mark RCT1 scenario as completed - if (scenario->sc_id < SC_MEGA_PARK) { + if (scenario->sc_id < SC_MEGA_PARK) + { rct1CompletedScenarios |= 1 << scenario->sc_id; } } // If scenario is Mega Park, keep a reference to it - if (scenario->sc_id == SC_MEGA_PARK) { - megaParkListItemIndex = length - 1; + if (scenario->sc_id == SC_MEGA_PARK) + { + megaParkListItemIndex = _listItems.size() - 1; } - } else { - listItem->scenario.is_locked = false; } + else + { + scenarioItem.scenario.is_locked = false; + } + _listItems.push_back(std::move(scenarioItem)); } - length++; - _listItems = Memory::ReallocateArray(_listItems, capacity); - _listItems[length - 1].type = LIST_ITEM_TYPE_END; - // Mega park handling - if (megaParkListItemIndex != SIZE_MAX) { + if (megaParkListItemIndex != SIZE_MAX) + { bool megaParkLocked = (rct1CompletedScenarios & rct1RequiredCompletedScenarios) != rct1RequiredCompletedScenarios; _listItems[megaParkListItemIndex].scenario.is_locked = megaParkLocked; - if (megaParkLocked && gConfigGeneral.scenario_hide_mega_park) { + if (megaParkLocked && gConfigGeneral.scenario_hide_mega_park) + { // Remove mega park - size_t remainingItems = length - megaParkListItemIndex - 1; - memmove(&_listItems[megaParkListItemIndex], &_listItems[megaParkListItemIndex + 1], remainingItems); + _listItems.pop_back(); // Remove empty headings - sint32 i = 0; - for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) { - if (listItem->type == LIST_ITEM_TYPE_HEADING && (listItem + 1)->type != LIST_ITEM_TYPE_SCENARIO) { - remainingItems = length - i - 1; - memmove(&_listItems[i], &_listItems[i + 1], remainingItems); - listItem--; - } else { - i++; + for (auto it = _listItems.begin(); it != _listItems.end(); it++) + { + const auto &listItem = *it; + if (listItem.type == LIST_ITEM_TYPE::HEADING) + { + if ((it + 1) == _listItems.end() || + (it + 1)->type == LIST_ITEM_TYPE::HEADING) + { + _listItems.erase(it); + it--; + } } } } From cb44dc5c2114cc2341ba9aca48b832f14eded248 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 21 Jan 2018 02:13:32 +0000 Subject: [PATCH 07/13] Fix changelog --- src/openrct2-ui/windows/Changelog.cpp | 23 +++++++++++++----- src/openrct2/PlatformEnvironment.cpp | 9 ++++++++ src/openrct2/PlatformEnvironment.h | 4 +++- src/openrct2/platform/Android.cpp | 5 ---- src/openrct2/platform/Linux.cpp | 27 ---------------------- src/openrct2/platform/Platform.Android.cpp | 5 ++++ src/openrct2/platform/Platform.Linux.cpp | 19 +++++++++++++++ src/openrct2/platform/Platform.Win32.cpp | 5 ++++ src/openrct2/platform/Platform.macOS.cpp | 5 ++++ src/openrct2/platform/Platform2.h | 1 + src/openrct2/platform/Windows.cpp | 6 ----- src/openrct2/platform/platform.h | 1 - 12 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/openrct2-ui/windows/Changelog.cpp b/src/openrct2-ui/windows/Changelog.cpp index 2624113cca..c818c3ca18 100644 --- a/src/openrct2-ui/windows/Changelog.cpp +++ b/src/openrct2-ui/windows/Changelog.cpp @@ -17,15 +17,18 @@ #include #include #include -#include #include #include #include +#include #include +#include #include #include #include +using namespace OpenRCT2; + enum { WIDX_BACKGROUND, WIDX_TITLE, @@ -198,17 +201,25 @@ static void window_changelog_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, } } +static std::string GetChangelogPath() +{ + auto env = GetContext()->GetPlatformEnvironment(); + return env->GetFilePath(PATHID::CHANGELOG); +} + static std::string GetChangelogText() { - utf8 path[MAX_PATH]; - platform_get_changelog_path(path, sizeof(path)); - + auto path = GetChangelogPath(); #if defined(_WIN32) && !defined(__MINGW32__) auto pathW = String::ToUtf16(path); - auto fs = std::ifstream(pathW, std::ios::out | std::ios::app); + auto fs = std::ifstream(pathW, std::ios::in); #else - auto fs = std::ifstream(path, std::ios::out | std::ios::app); + auto fs = std::ifstream(path, std::ios::in); #endif + if (!fs.is_open()) + { + throw std::runtime_error("Unable to open " + path); + } return std::string((std::istreambuf_iterator(fs)), std::istreambuf_iterator()); } diff --git a/src/openrct2/PlatformEnvironment.cpp b/src/openrct2/PlatformEnvironment.cpp index 7850f7bdc7..40b865ebc8 100644 --- a/src/openrct2/PlatformEnvironment.cpp +++ b/src/openrct2/PlatformEnvironment.cpp @@ -99,6 +99,8 @@ private: return DIRBASE::RCT1; case PATHID::SCORES_RCT2: return DIRBASE::RCT2; + case PATHID::CHANGELOG: + return DIRBASE::DOCUMENTATION; case PATHID::NETWORK_GROUPS: case PATHID::NETWORK_SERVERS: case PATHID::NETWORK_USERS: @@ -134,6 +136,7 @@ IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment() basePaths[(size_t)DIRBASE::USER] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_DATA), subDirectory); basePaths[(size_t)DIRBASE::CONFIG] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_CONFIG), subDirectory); basePaths[(size_t)DIRBASE::CACHE] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_CACHE), subDirectory); + basePaths[(size_t)DIRBASE::DOCUMENTATION] = Platform::GetDocsPath(); // Override paths that have been specified via the command line if (!String::IsNullOrEmpty(gCustomRCT2DataPath)) @@ -151,6 +154,11 @@ IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment() basePaths[(size_t)DIRBASE::CACHE] = gCustomUserDataPath; } + if (basePaths[(size_t)DIRBASE::DOCUMENTATION].empty()) + { + basePaths[(size_t)DIRBASE::DOCUMENTATION] = basePaths[(size_t)DIRBASE::OPENRCT2]; + } + auto env = OpenRCT2::CreatePlatformEnvironment(basePaths); // Now load the config so we can get the RCT1 and RCT2 paths @@ -225,5 +233,6 @@ const char * PlatformEnvironment::FileNames[] = "highscores.dat", // SCORES "scores.dat", // SCORES (LEGACY) "Saved Games" PATH_SEPARATOR "scores.dat", // SCORES (RCT2) + "changelog.txt" // CHANGELOG }; // clang-format on diff --git a/src/openrct2/PlatformEnvironment.h b/src/openrct2/PlatformEnvironment.h index de4b9894b8..32989f0ae0 100644 --- a/src/openrct2/PlatformEnvironment.h +++ b/src/openrct2/PlatformEnvironment.h @@ -31,8 +31,9 @@ namespace OpenRCT2 USER, // Base directory for OpenRCT2 user content. CONFIG, // Base directory for OpenRCT2 configuration. CACHE, // Base directory for OpenRCT2 cache files. + DOCUMENTATION, // Base directory for OpenRCT2 doc files. }; - constexpr sint32 DIRBASE_COUNT = 6; + constexpr sint32 DIRBASE_COUNT = 7; using DIRBASE_VALUES = std::string[DIRBASE_COUNT]; enum class DIRID @@ -67,6 +68,7 @@ namespace OpenRCT2 SCORES, // Scenario scores (highscores.dat). SCORES_LEGACY, // Scenario scores, legacy (scores.dat). SCORES_RCT2, // Scenario scores, rct2 (\Saved Games\scores.dat). + CHANGELOG, // Notable changes to the game between versions, distributed with the game. }; /** diff --git a/src/openrct2/platform/Android.cpp b/src/openrct2/platform/Android.cpp index d3429d1566..a80b562a08 100644 --- a/src/openrct2/platform/Android.cpp +++ b/src/openrct2/platform/Android.cpp @@ -69,11 +69,6 @@ float platform_get_default_scale() { return displayScale; } -void platform_get_changelog_path(utf8 *outPath, size_t outSize) -{ - STUB(); -} - bool platform_get_steam_path(utf8 * outPath, size_t outSize) { return false; diff --git a/src/openrct2/platform/Linux.cpp b/src/openrct2/platform/Linux.cpp index fda75ca297..8b2cd88d45 100644 --- a/src/openrct2/platform/Linux.cpp +++ b/src/openrct2/platform/Linux.cpp @@ -108,27 +108,6 @@ void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) { } } -/** -* Default directory fallback is: -* - /doc -* - /usr/share/doc/openrct2 -*/ -static void platform_posix_sub_resolve_openrct_doc_path(utf8 *out, size_t size) { - static const utf8 *searchLocations[] = { - "./doc", - "/usr/share/doc/openrct2", - }; - for (auto searchLocation : searchLocations) - { - log_verbose("Looking for OpenRCT2 doc path at %s", searchLocation); - if (platform_directory_exists(searchLocation)) - { - safe_strcpy(out, searchLocation, size); - return; - } - } -} - uint16 platform_get_locale_language(){ const char *langString = setlocale(LC_MESSAGES, ""); if(langString != NULL){ @@ -218,12 +197,6 @@ uint8 platform_get_locale_measurement_format(){ return MEASUREMENT_FORMAT_METRIC; } -void platform_get_changelog_path(utf8 *outPath, size_t outSize) -{ - platform_posix_sub_resolve_openrct_doc_path(outPath, outSize); - safe_strcat_path(outPath, "changelog.txt", outSize); -} - bool platform_get_steam_path(utf8 * outPath, size_t outSize) { const char * steamRoot = getenv("STEAMROOT"); diff --git a/src/openrct2/platform/Platform.Android.cpp b/src/openrct2/platform/Platform.Android.cpp index 18f257f50f..bdabd83035 100644 --- a/src/openrct2/platform/Platform.Android.cpp +++ b/src/openrct2/platform/Platform.Android.cpp @@ -34,6 +34,11 @@ namespace Platform return std::string(); } } + + std::string GetDocsPath() + { + return std::string(); + } } #endif diff --git a/src/openrct2/platform/Platform.Linux.cpp b/src/openrct2/platform/Platform.Linux.cpp index 3414dc1a6a..9db7b69b65 100644 --- a/src/openrct2/platform/Platform.Linux.cpp +++ b/src/openrct2/platform/Platform.Linux.cpp @@ -18,6 +18,7 @@ #include #include "../core/Path.hpp" +#include "platform.h" #include "Platform2.h" namespace Platform @@ -44,6 +45,24 @@ namespace Platform return std::string(); } } + + std::string GetDocsPath() + { + static const utf8 * searchLocations[] = + { + "./doc", + "/usr/share/doc/openrct2", + }; + for (auto searchLocation : searchLocations) + { + log_verbose("Looking for OpenRCT2 doc path at %s", searchLocation); + if (platform_directory_exists(searchLocation)) + { + return searchLocation; + } + } + return std::string(); + } } #endif diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 4586b9ea19..048f8170bb 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -147,6 +147,11 @@ namespace Platform return path; } + std::string GetDocsPath() + { + return std::string(); + } + static SYSTEMTIME TimeToSystemTime(std::time_t timestamp) { LONGLONG ll = Int32x32To64(timestamp, 10000000) + 116444736000000000; diff --git a/src/openrct2/platform/Platform.macOS.cpp b/src/openrct2/platform/Platform.macOS.cpp index 9eeec5e7d0..d82b28dc2f 100644 --- a/src/openrct2/platform/Platform.macOS.cpp +++ b/src/openrct2/platform/Platform.macOS.cpp @@ -39,6 +39,11 @@ namespace Platform return std::string(); } } + + std::string GetDocsPath() + { + return std::string(); + } } #endif diff --git a/src/openrct2/platform/Platform2.h b/src/openrct2/platform/Platform2.h index 9ae79139e1..38cdcefa77 100644 --- a/src/openrct2/platform/Platform2.h +++ b/src/openrct2/platform/Platform2.h @@ -36,6 +36,7 @@ namespace Platform std::string GetEnvironmentVariable(const std::string &name); std::string GetFolderPath(SPECIAL_FOLDER folder); std::string GetInstallPath(); + std::string GetDocsPath(); #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) std::string GetEnvironmentPath(const char * name); diff --git a/src/openrct2/platform/Windows.cpp b/src/openrct2/platform/Windows.cpp index 31f78e1d65..c816d0f9c1 100644 --- a/src/openrct2/platform/Windows.cpp +++ b/src/openrct2/platform/Windows.cpp @@ -244,12 +244,6 @@ void platform_get_openrct_data_path(utf8 *outPath, size_t outSize) safe_strcpy(outPath, _openrctDataDirectoryPath, outSize); } -void platform_get_changelog_path(utf8 *outPath, size_t outSize) -{ - safe_strcpy(outPath, gExePath, outSize); - safe_strcat_path(outPath, "changelog.txt", outSize); -} - bool platform_get_steam_path(utf8 * outPath, size_t outSize) { wchar_t * wSteamPath; diff --git a/src/openrct2/platform/platform.h b/src/openrct2/platform/platform.h index a4491413ae..a761d9454a 100644 --- a/src/openrct2/platform/platform.h +++ b/src/openrct2/platform/platform.h @@ -127,7 +127,6 @@ uint8 platform_get_locale_measurement_format(); uint8 platform_get_locale_temperature_format(); uint8 platform_get_locale_date_format(); bool platform_process_is_elevated(); -void platform_get_changelog_path(utf8 *outPath, size_t outSize); bool platform_get_steam_path(utf8 * outPath, size_t outSize); #ifndef NO_TTF From 589e0f40d05e26ebaa99bc3b5475fe381a3ae836 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 21 Jan 2018 02:25:20 +0000 Subject: [PATCH 08/13] Refactor memory handling in Map.cpp --- src/openrct2-ui/windows/Map.cpp | 37 +++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index fe57d79f2b..dbd2b0a7f1 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -14,24 +14,25 @@ *****************************************************************************/ #pragma endregion -#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include #include #include -#include -#include #include +#include #include #include #include #include - #include +#include +#include #include #define MAP_COLOUR_2(colourA, colourB) ((colourA << 8) | colourB) @@ -175,7 +176,7 @@ static uint8 _activeTool; static uint32 _currentLine; /** rct2: 0x00F1AD68 */ -static uint8 (*_mapImageData)[MAP_WINDOW_MAP_SIZE][MAP_WINDOW_MAP_SIZE]; +static std::vector _mapImageData; static sint32 _nextPeepSpawnIndex = 0; @@ -217,8 +218,12 @@ rct_window * window_map_open() return w; } - _mapImageData = Memory::Allocate(); - if (_mapImageData == nullptr) { + try + { + _mapImageData.resize(MAP_WINDOW_MAP_SIZE * MAP_WINDOW_MAP_SIZE); + } + catch (const std::bad_alloc &) + { return nullptr; } @@ -284,7 +289,8 @@ void window_map_reset() */ static void window_map_close(rct_window *w) { - free(_mapImageData); + _mapImageData.clear(); + _mapImageData.shrink_to_fit(); if ((input_test_flag(INPUT_FLAG_TOOL_ACTIVE)) && gCurrentToolWidget.window_classification == w->classification && gCurrentToolWidget.window_number == w->number) { @@ -889,7 +895,7 @@ static void window_map_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 gfx_clear(dpi, PALETTE_INDEX_10); rct_g1_element g1temp = { nullptr }; - g1temp.offset = (uint8 *)_mapImageData; + g1temp.offset = _mapImageData.data(); g1temp.width = MAP_WINDOW_MAP_SIZE; g1temp.height = MAP_WINDOW_MAP_SIZE; g1temp.x_offset = -8; @@ -914,7 +920,7 @@ static void window_map_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 */ static void window_map_init_map() { - memset(_mapImageData, PALETTE_INDEX_10, sizeof(*_mapImageData)); + std::fill(_mapImageData.begin(), _mapImageData.end(), PALETTE_INDEX_10); _currentLine = 0; } @@ -1653,12 +1659,11 @@ static uint16 map_window_get_pixel_colour_ride(sint32 x, sint32 y) static void map_window_set_pixels(rct_window *w) { uint16 colour = 0; - uint8 *destination; sint32 x = 0, y = 0, dx = 0, dy = 0; sint32 pos = (_currentLine * (MAP_WINDOW_MAP_SIZE - 1)) + MAXIMUM_MAP_SIZE_TECHNICAL - 1; LocationXY16 destinationPosition = MakeXY16(pos % MAP_WINDOW_MAP_SIZE, pos / MAP_WINDOW_MAP_SIZE); - destination = &(*_mapImageData)[destinationPosition.y][destinationPosition.x]; + auto destination = _mapImageData.data() + (destinationPosition.y * MAP_WINDOW_MAP_SIZE) + destinationPosition.x; switch (get_current_rotation()) { case 0: x = _currentLine * 32; @@ -1709,7 +1714,7 @@ static void map_window_set_pixels(rct_window *w) destinationPosition.x++; destinationPosition.y++; - destination = &(*_mapImageData)[destinationPosition.y][destinationPosition.x]; + destination = _mapImageData.data() + (destinationPosition.y * MAP_WINDOW_MAP_SIZE) + destinationPosition.x; } _currentLine++; if (_currentLine >= MAXIMUM_MAP_SIZE_TECHNICAL) From 7f8b795842827ef14393d1f39d5d0fb9f7149ff3 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 21 Jan 2018 02:39:52 +0000 Subject: [PATCH 09/13] Refactor memory handling in EditorObjectSelection.cpp --- .../windows/EditorObjectSelection.cpp | 122 ++++++++---------- .../windows/TitleCommandEditor.cpp | 2 +- 2 files changed, 52 insertions(+), 72 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index e54ad84265..eb71b770d9 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -14,32 +14,31 @@ *****************************************************************************/ #pragma endregion -#include - +#include #include #include - +#include #include #include #include -#include #include #include #include -#include #include +#include #include #include #include #include -#include #include #include #include #include #include -#include #include +#include +#include +#include enum { FILTER_RCT2 = (1 << 0), @@ -270,42 +269,34 @@ typedef struct list_item { static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem * item); -typedef sint32(*sortFunc_t)(const void *, const void *); +typedef bool (*sortFunc_t)(const list_item &, const list_item &); -static sint32 _numListItems = 0; -static list_item *_listItems = nullptr; +static std::vector _listItems; static sint32 _listSortType = RIDE_SORT_TYPE; static bool _listSortDescending = false; static void * _loadedObject = nullptr; static void visible_list_dispose() { - SafeFree(_listItems); - _numListItems = 0; + _listItems.clear(); + _listItems.shrink_to_fit(); } -static sint32 visible_list_sort_ride_name(const void *rawA, const void *rawB) +static bool visible_list_sort_ride_name(const list_item &a, const list_item &b) { - list_item *a = (list_item*)rawA; - list_item *b = (list_item*)rawB; - - const char *nameA = a->repositoryItem->Name; - const char *nameB = b->repositoryItem->Name; - return strcmp(nameA, nameB); + auto nameA = a.repositoryItem->Name; + auto nameB = b.repositoryItem->Name; + return strcmp(nameA, nameB) < 0; } -static sint32 visible_list_sort_ride_type(const void *rawA, const void *rawB) +static bool visible_list_sort_ride_type(const list_item &a, const list_item &b) { - list_item *a = (list_item*)rawA; - list_item *b = (list_item*)rawB; - - const char *rideTypeA = language_get_string(get_ride_type_string_id(a->repositoryItem)); - const char *rideTypeB = language_get_string(get_ride_type_string_id(b->repositoryItem)); + auto rideTypeA = language_get_string(get_ride_type_string_id(a.repositoryItem)); + auto rideTypeB = language_get_string(get_ride_type_string_id(b.repositoryItem)); sint32 result = strcmp(rideTypeA, rideTypeB); - if (result != 0) - return result; - - return visible_list_sort_ride_name(rawA, rawB); + return result != 0 ? + result < 0 : + visible_list_sort_ride_name(a, b); } static void visible_list_refresh(rct_window *w) @@ -314,10 +305,7 @@ static void visible_list_refresh(rct_window *w) visible_list_dispose(); w->selected_list_item = -1; - _listItems = Memory::AllocateArray(numObjects); - _numListItems = 0; - list_item *currentListItem = &_listItems[0]; const ObjectRepositoryItem *items = object_repository_get_items(); for (sint32 i = 0; i < numObjects; i++) { uint8 selectionFlags = _objectSelectionFlags[i]; @@ -333,29 +321,25 @@ static void visible_list_refresh(rct_window *w) filter->ride.category[0] = 0; filter->ride.category[1] = 0; filter->ride.ride_type = 0; - currentListItem->repositoryItem = item; - currentListItem->entry = (rct_object_entry *)&item->ObjectEntry; - currentListItem->filter = filter; - currentListItem->flags = &_objectSelectionFlags[i]; - currentListItem++; - _numListItems++; + + list_item currentListItem; + currentListItem.repositoryItem = item; + currentListItem.entry = (rct_object_entry *)&item->ObjectEntry; + currentListItem.filter = filter; + currentListItem.flags = &_objectSelectionFlags[i]; + _listItems.push_back(std::move(currentListItem)); } } - if (_numListItems == 0) + if (_listItems.size() == 0) { visible_list_dispose(); - window_invalidate(w); - return; } - - _listItems = Memory::ReallocateArray(_listItems, _numListItems); - if (_listItems == nullptr) { - _numListItems = 0; - log_error("Unable to reallocate list items"); - } else { + else + { sortFunc_t sortFunc = nullptr; - switch (_listSortType) { + switch (_listSortType) + { case RIDE_SORT_TYPE: sortFunc = visible_list_sort_ride_type; break; @@ -364,17 +348,14 @@ static void visible_list_refresh(rct_window *w) break; default: log_warning("Wrong sort type %d, leaving list as-is.", _listSortType); - window_invalidate(w); - return; + break; } - qsort(_listItems, _numListItems, sizeof(list_item), sortFunc); - - if (_listSortDescending) { - for (sint32 i = 0; i < _numListItems / 2; i++) { - sint32 ri = _numListItems - i - 1; - list_item temp = _listItems[i]; - _listItems[i] = _listItems[ri]; - _listItems[ri] = temp; + if (sortFunc != nullptr) + { + std::sort(_listItems.begin(), _listItems.end(), sortFunc); + if (_listSortDescending) + { + std::reverse(_listItems.begin(), _listItems.end()); } } } @@ -681,7 +662,7 @@ static void window_editor_object_selection_dropdown(rct_window *w, rct_widgetind */ static void window_editor_object_selection_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height) { - *height = _numListItems * 12; + *height = (sint32)(_listItems.size() * 12); } /** @@ -1110,7 +1091,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf */ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex) { - sint32 x, y, i, colour, colour2; + sint32 x, y, colour, colour2; bool ridePage = (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS); @@ -1118,27 +1099,26 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi gfx_clear(dpi, paletteIndex); y = 0; - for (i = 0; i < _numListItems; i++) { - list_item *listItem = &_listItems[i]; - + for (const auto &listItem : _listItems) + { if (y + 12 >= dpi->y && y <= dpi->y + dpi->height) { // Draw checkbox - if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && !(*listItem->flags & 0x20)) + if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && !(*listItem.flags & 0x20)) gfx_fill_rect_inset(dpi, 2, y, 11, y + 10, w->colours[1], INSET_RECT_F_E0); // Highlight background colour = COLOUR_BRIGHT_GREEN | COLOUR_FLAG_TRANSLUCENT; - if (listItem->entry == w->object_entry && !(*listItem->flags & OBJECT_SELECTION_FLAG_6)) { + if (listItem.entry == w->object_entry && !(*listItem.flags & OBJECT_SELECTION_FLAG_6)) { gfx_filter_rect(dpi, 0, y, w->width, y + 11, PALETTE_DARKEN_1); colour = COLOUR_BRIGHT_GREEN; } // Draw checkmark - if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && (*listItem->flags & OBJECT_SELECTION_FLAG_SELECTED)) { + if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && (*listItem.flags & OBJECT_SELECTION_FLAG_SELECTED)) { x = 2; gCurrentFontSpriteBase = colour == COLOUR_BRIGHT_GREEN ? FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK : FONT_SPRITE_BASE_MEDIUM_DARK; colour2 = NOT_TRANSLUCENT(w->colours[1]); - if (*listItem->flags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED)) + if (*listItem.flags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED)) colour2 |= COLOUR_FLAG_INSET; gfx_draw_string(dpi, (char*)CheckBoxMarkString, colour2, x, y); @@ -1148,7 +1128,7 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi char *bufferWithColour = gCommonStringFormatBuffer; char *buffer = utf8_write_codepoint(bufferWithColour, colour); - if (*listItem->flags & OBJECT_SELECTION_FLAG_6) { + if (*listItem.flags & OBJECT_SELECTION_FLAG_6) { colour = w->colours[1] & 0x7F; gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_DARK; } @@ -1159,14 +1139,14 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi if (ridePage) { // Draw ride type - rct_string_id rideTypeStringId = get_ride_type_string_id(listItem->repositoryItem); + rct_string_id rideTypeStringId = get_ride_type_string_id(listItem.repositoryItem); safe_strcpy(buffer, language_get_string(rideTypeStringId), 256 - (buffer - bufferWithColour)); gfx_draw_string(dpi, bufferWithColour, colour, x, y); x = w->widgets[WIDX_LIST_SORT_RIDE].left - w->widgets[WIDX_LIST].left; } // Draw text - safe_strcpy(buffer, listItem->repositoryItem->Name, 256 - (buffer - bufferWithColour)); + safe_strcpy(buffer, listItem.repositoryItem->Name, 256 - (buffer - bufferWithColour)); if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { while (*buffer != 0 && *buffer != 9) buffer++; @@ -1221,7 +1201,7 @@ static void window_editor_object_selection_set_pressed_tab(rct_window *w) static sint32 get_object_from_object_selection(uint8 object_type, sint32 y) { sint32 listItemIndex = y / 12; - if (listItemIndex < 0 || listItemIndex >= _numListItems) + if (listItemIndex < 0 || listItemIndex >= _listItems.size()) return -1; return listItemIndex; diff --git a/src/openrct2-ui/windows/TitleCommandEditor.cpp b/src/openrct2-ui/windows/TitleCommandEditor.cpp index f98631f1b8..98444a5b38 100644 --- a/src/openrct2-ui/windows/TitleCommandEditor.cpp +++ b/src/openrct2-ui/windows/TitleCommandEditor.cpp @@ -141,7 +141,7 @@ static rct_window_event_list window_title_command_editor_events = { nullptr, nullptr, nullptr, - window_title_command_editor_tool_down, + window_title_command_editor_tool_down, nullptr, nullptr, nullptr, From 131286f7582ce5db9b41425915b579e68d6cb314 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 21 Jan 2018 03:05:09 +0000 Subject: [PATCH 10/13] Refactor memory handling in OpenGLShaderProgram.cpp --- .../drawing/engines/SoftwareDrawingEngine.cpp | 7 ++-- .../engines/opengl/OpenGLShaderProgram.cpp | 37 +++++++++---------- .../engines/opengl/OpenGLShaderProgram.h | 5 ++- src/openrct2/PlatformEnvironment.cpp | 2 +- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp index 83f24daa03..0ec31d029a 100644 --- a/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/SoftwareDrawingEngine.cpp @@ -14,18 +14,17 @@ *****************************************************************************/ #pragma endregion +#include #include #include #include #include -#include #include #include +#include #include #include "DrawingEngines.h" -#include - using namespace OpenRCT2; using namespace OpenRCT2::Drawing; using namespace OpenRCT2::Ui; @@ -121,7 +120,7 @@ private: } // Copy pixels from the virtual screen buffer to the surface - Memory::Copy(_surface->pixels, _bits, _surface->pitch * _surface->h); + std::copy_n(_bits, _surface->pitch * _surface->h, (uint8 *)_surface->pixels); // Unlock the surface if (SDL_MUSTLOCK(_surface)) diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp index 4a8d18f3be..2bc989f59c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -16,29 +16,28 @@ #ifndef DISABLE_OPENGL +#include #include #include -#include #include #include +#include #include "OpenGLShaderProgram.h" -#include +using namespace OpenRCT2; OpenGLShader::OpenGLShader(const char * name, GLenum type) { _type = type; - utf8 path[MAX_PATH]; - GetPath(path, sizeof(path), name); - char * sourceCode = ReadSourceCode(path); + auto path = GetPath(name); + auto sourceCode = ReadSourceCode(path); + auto sourceCodeStr = sourceCode.c_str(); _id = glCreateShader(type); - glShaderSource(_id, 1, (const GLchar**)&sourceCode, nullptr); + glShaderSource(_id, 1, (const GLchar * *)&sourceCodeStr, nullptr); glCompileShader(_id); - Memory::Free(sourceCode); - GLint status; glGetShaderiv(_id, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) @@ -47,7 +46,7 @@ OpenGLShader::OpenGLShader(const char * name, GLenum type) glGetShaderInfoLog(_id, sizeof(buffer), nullptr, buffer); glDeleteShader(_id); - Console::Error::WriteLine("Error compiling %s", path); + Console::Error::WriteLine("Error compiling %s", path.c_str()); Console::Error::WriteLine(buffer); throw std::runtime_error("Error compiling shader."); @@ -64,22 +63,23 @@ GLuint OpenGLShader::GetShaderId() return _id; } -void OpenGLShader::GetPath(char * buffer, size_t bufferSize, const char * name) +std::string OpenGLShader::GetPath(const std::string &name) { - platform_get_openrct_data_path(buffer, bufferSize); - Path::Append(buffer, bufferSize, "shaders"); - Path::Append(buffer, bufferSize, name); + auto env = GetContext()->GetPlatformEnvironment(); + auto shadersPath = env->GetDirectoryPath(DIRBASE::OPENRCT2, DIRID::SHADER); + auto path = Path::Combine(shadersPath, name); if (_type == GL_VERTEX_SHADER) { - String::Append(buffer, bufferSize, ".vert"); + path += ".vert"; } else { - String::Append(buffer, bufferSize, ".frag"); + path += ".frag"; } + return path; } -char * OpenGLShader::ReadSourceCode(const utf8 * path) +std::string OpenGLShader::ReadSourceCode(const std::string &path) { auto fs = FileStream(path, FILE_MODE_OPEN); @@ -89,9 +89,8 @@ char * OpenGLShader::ReadSourceCode(const utf8 * path) throw IOException("Shader source too large."); } - utf8 * fileData = Memory::Allocate((size_t)fileLength + 1); - fs.Read(fileData, fileLength); - fileData[fileLength] = '\0'; + auto fileData = std::string((size_t)fileLength + 1, '\0'); + fs.Read(fileData.data(), fileLength); return fileData; } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h index 16cf496693..1740d9897c 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include "OpenGLAPI.h" @@ -34,8 +35,8 @@ public: GLuint GetShaderId(); private: - void GetPath(char * buffer, size_t bufferSize, const char * name); - static char * ReadSourceCode(const utf8 * path); + std::string GetPath(const std::string &name); + static std::string ReadSourceCode(const std::string &path); }; class OpenGLShaderProgram diff --git a/src/openrct2/PlatformEnvironment.cpp b/src/openrct2/PlatformEnvironment.cpp index 40b865ebc8..060fb00e81 100644 --- a/src/openrct2/PlatformEnvironment.cpp +++ b/src/openrct2/PlatformEnvironment.cpp @@ -214,7 +214,7 @@ const char * PlatformEnvironment::DirectoryNamesOpenRCT2[] = "scenario", // SCENARIO "screenshot", // SCREENSHOT "sequence", // SEQUENCE - "shader", // SHADER + "shaders", // SHADER "themes", // THEME "track", // TRACK }; From cebe13984f7cdf1e7d261ed0985abd8d25364d2b Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 21 Jan 2018 11:14:46 +0000 Subject: [PATCH 11/13] Remove most of remaining memory functions from libopenrct2ui --- src/openrct2-ui/audio/AudioMixer.cpp | 1 - src/openrct2-ui/audio/MemoryAudioSource.cpp | 1 - .../engines/opengl/OpenGLDrawingEngine.cpp | 36 +++++++++---------- .../engines/opengl/OpenGLFramebuffer.cpp | 12 +++---- .../drawing/engines/opengl/TextureCache.cpp | 15 ++++---- src/openrct2-ui/input/KeyboardShortcuts.cpp | 1 - src/openrct2-ui/windows/InstallTrack.cpp | 1 - src/openrct2-ui/windows/Map.cpp | 1 - src/openrct2-ui/windows/ObjectLoadError.cpp | 1 - .../windows/TitleScenarioSelect.cpp | 1 - src/openrct2-ui/windows/TrackList.cpp | 1 - 11 files changed, 29 insertions(+), 42 deletions(-) diff --git a/src/openrct2-ui/audio/AudioMixer.cpp b/src/openrct2-ui/audio/AudioMixer.cpp index de345e584f..22265e8f0a 100644 --- a/src/openrct2-ui/audio/AudioMixer.cpp +++ b/src/openrct2-ui/audio/AudioMixer.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/src/openrct2-ui/audio/MemoryAudioSource.cpp b/src/openrct2-ui/audio/MemoryAudioSource.cpp index a2f3b0bb30..ab50144759 100644 --- a/src/openrct2-ui/audio/MemoryAudioSource.cpp +++ b/src/openrct2-ui/audio/MemoryAudioSource.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include "AudioContext.h" diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 6cddc0cf8a..c8ee5f2938 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -16,33 +16,29 @@ #ifndef DISABLE_OPENGL +#include #include #include #include - #include #include -#include -#include +#include #include #include +#include #include #include -#include - -#include #include -#include -#include - +#include +#include #include "../DrawingEngines.h" -#include "GLSLTypes.h" -#include "OpenGLAPI.h" -#include "OpenGLFramebuffer.h" #include "ApplyPaletteShader.h" #include "DrawCommands.h" #include "DrawLineShader.h" #include "DrawRectShader.h" +#include "GLSLTypes.h" +#include "OpenGLAPI.h" +#include "OpenGLFramebuffer.h" #include "SwapFramebuffer.h" #include "TextureCache.h" #include "TransparencyDepth.h" @@ -346,27 +342,27 @@ private: uint8 * newBits = new uint8[newBitsSize]; if (_bits == nullptr) { - Memory::Set(newBits, 0, newBitsSize); + std::fill_n(newBits, newBitsSize, 0); } else { if (_pitch == pitch) { - Memory::Copy(newBits, _bits, Math::Min(_bitsSize, newBitsSize)); + std::copy_n(_bits, std::min(_bitsSize, newBitsSize), newBits); } else { uint8 * src = _bits; uint8 * dst = newBits; - uint32 minWidth = Math::Min(_width, width); - uint32 minHeight = Math::Min(_height, height); + uint32 minWidth = std::min(_width, width); + uint32 minHeight = std::min(_height, height); for (uint32 y = 0; y < minHeight; y++) { - Memory::Copy(dst, src, minWidth); + std::copy_n(src, minWidth, dst); if (pitch - minWidth > 0) { - Memory::Set(dst + minWidth, 0, pitch - minWidth); + std::fill_n(dst + minWidth, pitch - minWidth, 0); } src += _pitch; dst += pitch; @@ -716,8 +712,8 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm sint32 drawOffsetX = g1ElementMask->x_offset; sint32 drawOffsetY = g1ElementMask->y_offset; - sint32 drawWidth = Math::Min(g1ElementMask->width, g1ElementColour->width); - sint32 drawHeight = Math::Min(g1ElementMask->height, g1ElementColour->height); + sint32 drawWidth = std::min(g1ElementMask->width, g1ElementColour->width); + sint32 drawHeight = std::min(g1ElementMask->height, g1ElementColour->height); sint32 left = x + drawOffsetX; sint32 top = y + drawOffsetY; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp index f75731a462..e7a4fe1853 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -16,9 +16,10 @@ #ifndef DISABLE_OPENGL +#include +#include #include #include -#include #include "OpenGLFramebuffer.h" constexpr GLuint BACKBUFFER_ID = 0; @@ -94,21 +95,20 @@ void OpenGLFramebuffer::GetPixels(rct_drawpixelinfo &dpi) const { assert(dpi.width == _width && dpi.height == _height); - uint8 * pixels = Memory::Allocate(_width * _height); + auto pixels = std::make_unique(_width * _height); glBindTexture(GL_TEXTURE_2D, _texture); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels.get()); // Flip pixels vertically on copy - uint8 * src = pixels + ((_height - 1) * _width); + uint8 * src = pixels.get() + ((_height - 1) * _width); uint8 * dst = dpi.bits; for (sint32 y = 0; y < _height; y++) { - Memory::Copy(dst, src, _width); + std::copy_n(src, _width, dst); src -= _width; dst += dpi.width + dpi.pitch; } - Memory::Free(pixels); } void OpenGLFramebuffer::SwapColourBuffer(OpenGLFramebuffer &other) diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index df7119cfeb..18dda9014e 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -16,12 +16,11 @@ #ifndef DISABLE_OPENGL -#include +#include #include -#include -#include "TextureCache.h" - +#include #include +#include "TextureCache.h" constexpr uint32 UNUSED_INDEX = 0xFFFFFFFF; @@ -95,7 +94,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palet { GlyphId glyphId; glyphId.Image = image; - Memory::Copy(&glyphId.Palette, palette, sizeof(glyphId.Palette)); + std::copy_n((uint8 *)&glyphId.Palette, sizeof(glyphId.Palette), palette); auto kvp = _glyphTextureMap.find(glyphId); if (kvp != _glyphTextureMap.end()) @@ -290,8 +289,8 @@ void TextureCache::FreeTextures() rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height) { size_t numPixels = width * height; - uint8 * pixels8 = Memory::Allocate(numPixels); - Memory::Set(pixels8, 0, numPixels); + auto pixels8 = new uint8[numPixels]; + std::fill_n(pixels8, numPixels, 0); rct_drawpixelinfo dpi; dpi.bits = pixels8; @@ -306,7 +305,7 @@ rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height) void TextureCache::DeleteDPI(rct_drawpixelinfo dpi) { - Memory::Free(dpi.bits); + delete dpi.bits; } GLuint TextureCache::GetAtlasesTexture() diff --git a/src/openrct2-ui/input/KeyboardShortcuts.cpp b/src/openrct2-ui/input/KeyboardShortcuts.cpp index 4891a6106a..96464fa957 100644 --- a/src/openrct2-ui/input/KeyboardShortcuts.cpp +++ b/src/openrct2-ui/input/KeyboardShortcuts.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index 0cad3e4dbd..9dde814a1f 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index dbd2b0a7f1..7eb0bde28f 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/src/openrct2-ui/windows/ObjectLoadError.cpp b/src/openrct2-ui/windows/ObjectLoadError.cpp index 415c584fe4..72db5f7c06 100644 --- a/src/openrct2-ui/windows/ObjectLoadError.cpp +++ b/src/openrct2-ui/windows/ObjectLoadError.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/src/openrct2-ui/windows/TitleScenarioSelect.cpp b/src/openrct2-ui/windows/TitleScenarioSelect.cpp index 99ff4f4098..5cc2f9d392 100644 --- a/src/openrct2-ui/windows/TitleScenarioSelect.cpp +++ b/src/openrct2-ui/windows/TitleScenarioSelect.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index cffd2a6ed3..b99b6ffbb5 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include From 02d783a9937c226cdee8b7c09a23340cfceef13a Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 21 Jan 2018 12:41:42 +0000 Subject: [PATCH 12/13] Fix build --- src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp | 2 +- src/openrct2-ui/windows/Changelog.cpp | 3 ++- src/openrct2-ui/windows/EditorObjectSelection.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp index 2bc989f59c..d763a3b6a5 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -90,7 +90,7 @@ std::string OpenGLShader::ReadSourceCode(const std::string &path) } auto fileData = std::string((size_t)fileLength + 1, '\0'); - fs.Read(fileData.data(), fileLength); + fs.Read((void *)fileData.data(), fileLength); return fileData; } diff --git a/src/openrct2-ui/windows/Changelog.cpp b/src/openrct2-ui/windows/Changelog.cpp index c818c3ca18..99b63623e3 100644 --- a/src/openrct2-ui/windows/Changelog.cpp +++ b/src/openrct2-ui/windows/Changelog.cpp @@ -240,7 +240,8 @@ static bool window_changelog_read_file() return false; } - auto * start = _changelogText.data(); + // Non-const cast required until C++17 is enabled + auto * start = (char *)_changelogText.data(); if (_changelogText.size() >= 3 && utf8_is_bom(start)) { start += 3; diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index eb71b770d9..9693298914 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1201,7 +1201,7 @@ static void window_editor_object_selection_set_pressed_tab(rct_window *w) static sint32 get_object_from_object_selection(uint8 object_type, sint32 y) { sint32 listItemIndex = y / 12; - if (listItemIndex < 0 || listItemIndex >= _listItems.size()) + if (listItemIndex < 0 || (size_t)listItemIndex >= _listItems.size()) return -1; return listItemIndex; From df26354376517e22888d0f6c7051a264831e5a8c Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 24 Jan 2018 18:49:30 +0000 Subject: [PATCH 13/13] Fix drawing glyphs in OpenGL --- src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 18dda9014e..da2fc1e05f 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -94,7 +94,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palet { GlyphId glyphId; glyphId.Image = image; - std::copy_n((uint8 *)&glyphId.Palette, sizeof(glyphId.Palette), palette); + std::copy_n(palette, sizeof(glyphId.Palette), (uint8 *)&glyphId.Palette); auto kvp = _glyphTextureMap.find(glyphId); if (kvp != _glyphTextureMap.end())