From 81b896e69ba192301457adf4b7066cfe7adc2cc8 Mon Sep 17 00:00:00 2001 From: Grinch_ Date: Thu, 12 Feb 2026 13:52:41 +0600 Subject: [PATCH 1/2] fix linux clang compile issues --- shared/Audio.cpp | 237 +++++++++++------- shared/Other.cpp | 79 +++--- shared/Other.h | 168 ++++++++----- .../premake/linux-clang-example/premake5.lua | 52 ++++ 4 files changed, 352 insertions(+), 184 deletions(-) create mode 100644 tools/premake/linux-clang-example/premake5.lua diff --git a/shared/Audio.cpp b/shared/Audio.cpp index dbe8be07..a3fe46e5 100644 --- a/shared/Audio.cpp +++ b/shared/Audio.cpp @@ -20,14 +20,17 @@ #include "CCamera.h" #pragma comment(lib, "bass.lib") -//#pragma comment(lib, "bass_fx.lib") +// #pragma comment(lib, "bass_fx.lib") -namespace plugin { - void BassSampleManager::FeedSample(std::string const& name, void* buffer, uint32_t length) { +namespace plugin +{ + void BassSampleManager::FeedSample(std::string const &name, void *buffer, uint32_t length) + { BASS_StreamPutData(GetSample(name)->handle, buffer, length); } - uint32_t BassSampleManager::CreateSample(std::string const& name, uint32_t channels, uint32_t freq) { + uint32_t BassSampleManager::CreateSample(std::string const &name, uint32_t channels, uint32_t freq) + { BassSample s; s.name = name; @@ -37,8 +40,7 @@ namespace plugin { channels, 0, STREAMPROC_PUSH, - 0 - ); + 0); s.loopStart = 0; s.loopEnd = -1; @@ -49,7 +51,8 @@ namespace plugin { return s.sample; } - uint32_t BassSampleManager::LoadSample(std::string const& file, uint32_t loopStart, int32_t loopEnd) { + uint32_t BassSampleManager::LoadSample(std::string const &file, uint32_t loopStart, int32_t loopEnd) + { BassSample s; s.name = plugin::RemoveExtension(plugin::RemovePath(file)); @@ -61,33 +64,40 @@ namespace plugin { return s.sample; } - void BassSampleManager::LoadAllSamplesFromFolder(std::string const& path) { + void BassSampleManager::LoadAllSamplesFromFolder(std::string const &path) + { auto files = plugin::GetAllFilesInFolder(path, ".wav"); - for (auto& file : files) { + for (auto &file : files) + { LoadSample(path + "\\" + file); } } - BassSampleManager::BassSample* BassSampleManager::GetSample(std::string const& name) { + BassSampleManager::BassSample *BassSampleManager::GetSample(std::string const &name) + { auto it = std::find_if(samples.begin(), samples.end(), - [name](const BassSample& s) { - return s.name == name; - }); + [name](const BassSample &s) + { + return s.name == name; + }); if (it != samples.end()) - return it._Ptr; + return std::addressof(*it); return nullptr; } - void BassSampleManager::ClearSamples() { - for (auto& it : samples) { + void BassSampleManager::ClearSamples() + { + for (auto &it : samples) + { BASS_SampleFree(it.handle); } samples = {}; } - void BassSampleManager::SetChannelFrequency(uint32_t channel, int32_t freq) { + void BassSampleManager::SetChannelFrequency(uint32_t channel, int32_t freq) + { if (channel == 0) return; @@ -99,7 +109,8 @@ namespace plugin { streams[channel].freq = freq; } - void BassSampleManager::SetChannel3DDistances(uint32_t channel, float min, float max) { + void BassSampleManager::SetChannel3DDistances(uint32_t channel, float min, float max) + { if (channel == 0) return; @@ -111,11 +122,12 @@ namespace plugin { BASS_Apply3D(); } - void BassSampleManager::SetChannel3DPosition(uint32_t channel, float x, float y, float z) { + void BassSampleManager::SetChannel3DPosition(uint32_t channel, float x, float y, float z) + { if (channel == 0) return; - BASS_3DVECTOR pos = { x, y, z }; + BASS_3DVECTOR pos = {x, y, z}; BASS_ChannelSet3DPosition(streams[channel].handle, &pos, NULL, NULL); BASS_Set3DFactors(1.0f, 1.0f, 1.0f); @@ -123,11 +135,12 @@ namespace plugin { BASS_Apply3D(); } - void BassSampleManager::SetChannel2DPositions(uint32_t channel) { + void BassSampleManager::SetChannel2DPositions(uint32_t channel) + { if (channel == 0) return; - BASS_3DVECTOR pos = { 0.0f, 0.0f, 0.0f }; + BASS_3DVECTOR pos = {0.0f, 0.0f, 0.0f}; BASS_ChannelSet3DPosition(streams[channel].handle, &listener.pos, NULL, NULL); BASS_Set3DFactors(1.0f, 1.0f, 1.0f); @@ -135,7 +148,8 @@ namespace plugin { BASS_Apply3D(); } - void BassSampleManager::SetChannelEmittingVolume(uint32_t channel, int32_t value) { + void BassSampleManager::SetChannelEmittingVolume(uint32_t channel, int32_t value) + { if (channel == 0) return; @@ -146,7 +160,8 @@ namespace plugin { streams[channel].volume = value; } - bool BassSampleManager::GetChannelUsedFlag(uint32_t channel) { + bool BassSampleManager::GetChannelUsedFlag(uint32_t channel) + { if (channel == 0) return true; @@ -154,22 +169,26 @@ namespace plugin { return res == BASS_ACTIVE_PLAYING; } - void BassSampleManager::SetChannelLoopCount(uint32_t channel, uint32_t count) { + void BassSampleManager::SetChannelLoopCount(uint32_t channel, uint32_t count) + { if (channel == 0) return; DWORD flags = 0; - if (count == 0) { + if (count == 0) + { flags = BASS_ChannelFlags(streams[channel].handle, BASS_SAMPLE_LOOP, BASS_SAMPLE_LOOP); } - else if (BASS_ChannelFlags(channel, 0, 0) & BASS_SAMPLE_LOOP) { + else if (BASS_ChannelFlags(channel, 0, 0) & BASS_SAMPLE_LOOP) + { flags = BASS_ChannelFlags(streams[channel].handle, 0, BASS_SAMPLE_LOOP); } streams[channel].loopCount = count; } - uint32_t BassSampleManager::GetChannelPosition(uint32_t channel) { + uint32_t BassSampleManager::GetChannelPosition(uint32_t channel) + { QWORD posBytes = BASS_ChannelGetPosition(streams[channel].handle, BASS_POS_BYTE); double posSeconds = BASS_ChannelBytes2Seconds(streams[channel].handle, posBytes); @@ -177,7 +196,8 @@ namespace plugin { return static_cast(posSeconds * GetSampleBaseFrequency(streams[channel].sampleId)); } - void BassSampleManager::SetChannelPosition(uint32_t channel, uint32_t pos, uint32_t mode) { + void BassSampleManager::SetChannelPosition(uint32_t channel, uint32_t pos, uint32_t mode) + { QWORD posBytes = BASS_ChannelSeconds2Bytes(streams[channel].handle, (double)(pos / GetSampleBaseFrequency(streams[channel].sampleId))); DWORD flags = BASS_POS_BYTE; @@ -186,11 +206,13 @@ namespace plugin { else if (mode == 2) flags = BASS_POS_END; - if (!BASS_ChannelSetPosition(streams[channel].handle, posBytes, flags)) { + if (!BASS_ChannelSetPosition(streams[channel].handle, posBytes, flags)) + { } } - void BassSampleManager::SetChannelLoopPoints(uint32_t channel, uint32_t loopStart, int32_t loopEnd) { + void BassSampleManager::SetChannelLoopPoints(uint32_t channel, uint32_t loopStart, int32_t loopEnd) + { if (channel == 0) return; @@ -207,39 +229,46 @@ namespace plugin { SetChannelPosition(channel, loopEnd, 2); } - uint32_t BassSampleManager::GetChannelLength(uint32_t channel) { + uint32_t BassSampleManager::GetChannelLength(uint32_t channel) + { QWORD lengthBytes = BASS_ChannelGetLength(streams[channel].handle, BASS_POS_BYTE); double lengthSeconds = BASS_ChannelBytes2Seconds(streams[channel].handle, lengthBytes); return static_cast(lengthSeconds * GetChannelFrequency(channel)); } - uint32_t BassSampleManager::GetSampleLength(uint32_t sample) { + uint32_t BassSampleManager::GetSampleLength(uint32_t sample) + { QWORD lengthBytes = BASS_ChannelGetLength(samples[sample].handle, BASS_POS_BYTE); double lengthSeconds = BASS_ChannelBytes2Seconds(samples[sample].handle, lengthBytes); return static_cast(lengthSeconds * GetSampleBaseFrequency(sample)); } - void BassSampleManager::SetChannelFramesToPlay(uint32_t channel, float frames) { + void BassSampleManager::SetChannelFramesToPlay(uint32_t channel, float frames) + { if (channel == 0) return; streams[channel].framesToPlay = frames; } - void BassSampleManager::SetChannel3D(uint32_t channel, bool on) { + void BassSampleManager::SetChannel3D(uint32_t channel, bool on) + { if (channel == 0) return; streams[channel].is3d = on; } - uint32_t BassSampleManager::GetChannelFrequency(uint32_t channel) { + uint32_t BassSampleManager::GetChannelFrequency(uint32_t channel) + { float freq; BASS_ChannelGetAttribute(streams[channel].handle, BASS_ATTRIB_FREQ, &freq); return static_cast(freq); } - uint32_t BassSampleManager::GetSampleBaseFrequency(uint32_t sample) { - if (samples[sample].isStream) { + uint32_t BassSampleManager::GetSampleBaseFrequency(uint32_t sample) + { + if (samples[sample].isStream) + { return samples[sample].streamFreq; } @@ -248,15 +277,17 @@ namespace plugin { return static_cast(info.freq); } - uint32_t BassSampleManager::AddSampleToQueue(uint8_t vol, uint32_t freq, std::string const& sample, bool loop, CVector const& pos, uint32_t framesToPlay, bool is3d) { - auto s = GetSample(sample); + uint32_t BassSampleManager::AddSampleToQueue(uint8_t vol, uint32_t freq, std::string const &sample, bool loop, CVector const &pos, uint32_t framesToPlay, bool is3d) + { + auto s = GetSample(sample); if (!s) return 0; return AddSampleToQueue(vol, freq, s->sample, loop, pos, framesToPlay, is3d); } - uint32_t BassSampleManager::AddSampleToQueue(uint8_t vol, uint32_t freq, uint32_t sample, bool loop, CVector const& pos, uint32_t framesToPlay, bool is3d) { + uint32_t BassSampleManager::AddSampleToQueue(uint8_t vol, uint32_t freq, uint32_t sample, bool loop, CVector const &pos, uint32_t framesToPlay, bool is3d) + { if (vol > 127) vol = 127; @@ -269,11 +300,13 @@ namespace plugin { q.loopStart = GetSampleLoopStartOffset(sample); q.loopEnd = GetSampleLoopEndOffset(sample); - if (loop) { + if (loop) + { q.loopCount = 0; q.framesToPlay = (float)framesToPlay; } - else { + else + { q.framesToPlay = 0.0f; q.loopCount = 1; } @@ -286,33 +319,38 @@ namespace plugin { return 0; } - void BassSampleManager::AddSampleToQueue(BassQueue const& queue) { + void BassSampleManager::AddSampleToQueue(BassQueue const &queue) + { this->queue.push_back(queue); } - bool BassSampleManager::InitialiseChannel(uint32_t channel, uint32_t sample) { + bool BassSampleManager::InitialiseChannel(uint32_t channel, uint32_t sample) + { if (channel == 0) return false; if (GetChannelUsedFlag(channel) && streams[channel].sampleId == sample) return true; - if (samples[sample].isStream) { + if (samples[sample].isStream) + { streams[channel].handle = samples[sample].handle; } - else { + else + { BASS_SAMPLE sampleInfo = {}; BASS_SampleGetInfo(samples[sample].handle, &sampleInfo); streams[channel].handle = BASS_SampleGetChannel(samples[sample].handle, false); - if (streams[channel].handle == 0) { + if (streams[channel].handle == 0) + { DWORD err = BASS_ErrorGetCode(); std::cout << "BassSampleManager error code " << err << std::endl; } } - + streams[channel].channelId = channel; streams[channel].sampleId = sample; @@ -320,67 +358,75 @@ namespace plugin { return true; } - void BassSampleManager::StartChannel(uint32_t channel) { + void BassSampleManager::StartChannel(uint32_t channel) + { if (settings.stop() || !settings.playPause()) return; BASS_ChannelPlay(streams[channel].handle, FALSE); } - void BassSampleManager::PauseChannel(uint32_t channel) { + void BassSampleManager::PauseChannel(uint32_t channel) + { if (channel == 0) return; BASS_ChannelPause(streams[channel].handle); } - void BassSampleManager::StopChannel(uint32_t channel) { + void BassSampleManager::StopChannel(uint32_t channel) + { if (channel == 0) return; BASS_ChannelStop(streams[channel].handle); } - void BassSampleManager::ResetChannel(uint32_t channel) { + void BassSampleManager::ResetChannel(uint32_t channel) + { if (channel == 0) return; BASS_ChannelSetPosition(streams[channel].handle, 0, BASS_POS_BYTE); } - uint32_t BassSampleManager::GetSampleLoopStartOffset(uint32_t sample) { + uint32_t BassSampleManager::GetSampleLoopStartOffset(uint32_t sample) + { return samples[sample].loopStart; } - int32_t BassSampleManager::GetSampleLoopEndOffset(uint32_t sample) { + int32_t BassSampleManager::GetSampleLoopEndOffset(uint32_t sample) + { return samples[sample].loopEnd; } - void BassSampleManager::ClearQueue() { + void BassSampleManager::ClearQueue() + { queue = {}; } - - void BassSampleManager::Process() { + void BassSampleManager::Process() + { #ifndef GTA2 auto pos = TheCamera.GetPosition(); auto forward = TheCamera.GetForward(); auto up = TheCamera.GetUp(); - listener.pos = { pos.x, pos.y, pos.z }; - listener.forward = { forward.x, forward.y, forward.z }; - listener.up = { up.x, up.y, up.z }; + listener.pos = {pos.x, pos.y, pos.z}; + listener.forward = {forward.x, forward.y, forward.z}; + listener.up = {up.x, up.y, up.z}; #endif - for (auto& it : streams) { + for (auto &it : streams) + { if (it.channelId == 0) continue; #ifdef GTA2 - void* wnd = GetHWnd(); + void *wnd = GetHWnd(); #elif RW - void* wnd = RsGlobal.ps->window; + void *wnd = RsGlobal.ps->window; #elif RAGE - void* wnd = GetHWnd(); + void *wnd = GetHWnd(); #endif if (!IsIconic((HWND)wnd) && !settings.mute()) @@ -389,23 +435,28 @@ namespace plugin { BASS_ChannelSetAttribute(it.handle, BASS_ATTRIB_VOL, 0.0f); auto a = BASS_ChannelIsActive(it.handle); - if (settings.playPause() && a == BASS_ACTIVE_PAUSED) { + if (settings.playPause() && a == BASS_ACTIVE_PAUSED) + { StartChannel(it.channelId); } - else if (!settings.playPause() && a == BASS_ACTIVE_PLAYING) { + else if (!settings.playPause() && a == BASS_ACTIVE_PLAYING) + { PauseChannel(it.channelId); } - if (settings.stop()) { + if (settings.stop()) + { StopChannel(it.channelId); } - if (!GetChannelUsedFlag(it.channelId) && settings.playPause()) { + if (!GetChannelUsedFlag(it.channelId) && settings.playPause()) + { it = BassStream(); continue; } - if (it.framesToPlay <= 0.0f) { + if (it.framesToPlay <= 0.0f) + { StopChannel(it.channelId); it = BassStream(); } @@ -416,9 +467,12 @@ namespace plugin { if (settings.stop() || !settings.playPause()) return; - for (auto&& it = queue.begin(); it != queue.end(); it++) { - if (!it->played) { - if (it->loopCount != 0) { + for (auto &&it = queue.begin(); it != queue.end(); it++) + { + if (!it->played) + { + if (it->loopCount != 0) + { uint32_t freq = it->freq; if (freq == 0) freq = GetSampleBaseFrequency(it->sample); @@ -430,20 +484,21 @@ namespace plugin { it->framesToPlay = (it->loopCount * GetSampleLength(it->sample)) / samplesPerFrame + 1.0f; } - auto a = std::find_if(streams.begin(), streams.end(), [&](const BassStream& item) { - return item.channelId != 0 && item.sampleId == it->sample; - }); - + auto a = std::find_if(streams.begin(), streams.end(), [&](const BassStream &item) + { return item.channelId != 0 && item.sampleId == it->sample; }); + uint32_t channel = 0; - if (a != streams.end()) { + if (a != streams.end()) + { channel = a->channelId; it->played = true; } else channel = FindAvailableChannel(); - if (InitialiseChannel(channel, it->sample)) { + if (InitialiseChannel(channel, it->sample)) + { SetChannelEmittingVolume(channel, it->volume); SetChannelFrequency(channel, it->freq); SetChannelLoopCount(channel, it->loopCount); @@ -452,11 +507,13 @@ namespace plugin { SetChannel3D(channel, it->is3d); SetChannel3DDistances(channel, 10.0f, 100.0f); - if (it->is3d) { + if (it->is3d) + { SetChannelReverbFlag(channel, it->reverb); SetChannel3DPosition(channel, it->pos.x, it->pos.y, it->pos.z); } - else { + else + { SetChannel2DPositions(channel); } @@ -469,20 +526,26 @@ namespace plugin { queue.clear(); } - uint32_t BassSampleManager::FindAvailableChannel() { - for (uint32_t i = 1; i < numChannels; i++) { - if (!GetChannelUsedFlag(i)) { + uint32_t BassSampleManager::FindAvailableChannel() + { + for (uint32_t i = 1; i < numChannels; i++) + { + if (!GetChannelUsedFlag(i)) + { return i; } } return 0; } - void BassSampleManager::SetChannelReverbFlag(uint32_t channel, bool reverb) { - ;; + void BassSampleManager::SetChannelReverbFlag(uint32_t channel, bool reverb) + { + ; + ; } - void BassSampleManager::StopAllChannels() { + void BassSampleManager::StopAllChannels() + { for (uint32_t i = 0; i < numChannels; i++) StopChannel(i); } diff --git a/shared/Other.cpp b/shared/Other.cpp index 96f07ef0..df1cc72a 100644 --- a/shared/Other.cpp +++ b/shared/Other.cpp @@ -8,9 +8,7 @@ #include #include -#if _HAS_CXX17 #include -#endif #define STB_IMAGE_IMPLEMENTATION #include "..\stb\stb_image.h" @@ -22,31 +20,36 @@ char plugin::FormattingUtils::buf[plugin::FormattingUtils::BUF_SIZE][4096]; unsigned int plugin::FormattingUtils::currentBufW = 0; wchar_t plugin::FormattingUtils::bufW[plugin::FormattingUtils::BUF_SIZE][4096]; -bool plugin::KeyPressed(unsigned int keyCode) { +bool plugin::KeyPressed(unsigned int keyCode) +{ return (GetKeyState(keyCode) & 0x8000) != 0; } -bool plugin::IsPluginInstalled(const TCHAR *pluginName) { +bool plugin::IsPluginInstalled(const TCHAR *pluginName) +{ return GetModuleHandle(pluginName) ? true : false; } -std::wstring plugin::AtoW(std::string const &str) { - std::wstring result; - result.resize(str.size()); - for (unsigned int i = 0; i < str.size(); i++) - result[i] = static_cast(static_cast(str[i])); - return result; +std::wstring plugin::AtoW(std::string const &str) +{ + std::wstring result; + result.resize(str.size()); + for (unsigned int i = 0; i < str.size(); i++) + result[i] = static_cast(static_cast(str[i])); + return result; } -std::string plugin::WtoA(std::wstring const &str) { - std::string result; - result.resize(str.size()); - for (unsigned int i = 0; i < str.size(); i++) - result[i] = static_cast(static_cast(str[i])); - return result; +std::string plugin::WtoA(std::wstring const &str) +{ + std::string result; + result.resize(str.size()); + for (unsigned int i = 0; i < str.size(); i++) + result[i] = static_cast(static_cast(str[i])); + return result; } -char *plugin::FormattingUtils::GetBuf() { +char *plugin::FormattingUtils::GetBuf() +{ char *result = buf[currentBuf]; currentBuf += 1; if (currentBuf >= BUF_SIZE) @@ -54,7 +57,8 @@ char *plugin::FormattingUtils::GetBuf() { return result; } -wchar_t *plugin::FormattingUtils::GetBufW() { +wchar_t *plugin::FormattingUtils::GetBufW() +{ wchar_t *result = bufW[currentBufW]; currentBufW += 1; if (currentBufW >= BUF_SIZE) @@ -62,11 +66,13 @@ wchar_t *plugin::FormattingUtils::GetBufW() { return result; } -bool plugin::CreateImageFromFile(std::string const& path, plugin::Image*& img) { +bool plugin::CreateImageFromFile(std::string const &path, plugin::Image *&img) +{ int32_t w, h, c; - uint8_t* p = stbi_load(path.c_str(), &w, &h, &c, 4); + uint8_t *p = stbi_load(path.c_str(), &w, &h, &c, 4); - if (p) { + if (p) + { if (!img) img = new plugin::Image(); @@ -81,15 +87,16 @@ bool plugin::CreateImageFromFile(std::string const& path, plugin::Image*& img) { return false; } -bool plugin::CreateImageFromMemory(std::string const& name, void* data, unsigned long size, class Image*& img) { +bool plugin::CreateImageFromMemory(std::string const &name, void *data, unsigned long size, class Image *&img) +{ int32_t w, h, c; - uint8_t* p = stbi_load_from_memory( - reinterpret_cast(data), + uint8_t *p = stbi_load_from_memory( + reinterpret_cast(data), size, - &w, &h, &c, 4 - ); + &w, &h, &c, 4); - if (p) { + if (p) + { if (!img) img = new plugin::Image(); @@ -104,21 +111,23 @@ bool plugin::CreateImageFromMemory(std::string const& name, void* data, unsigned return false; } -#if _HAS_CXX17 -std::vector plugin::GetAllFilesInFolder(std::string const& path, std::string const& ext, bool includePath) { +std::vector plugin::GetAllFilesInFolder(std::string const &path, std::string const &ext, bool includePath) +{ std::vector files = {}; - try { - for (auto& it : std::filesystem::directory_iterator(path)) { - if (it.path().extension() == ext) { + try + { + for (auto &it : std::filesystem::directory_iterator(path)) + { + if (it.path().extension() == ext) + { files.push_back(includePath ? it.path().string() : it.path().filename().string()); } } } - catch (const std::exception& ex) { + catch (const std::exception &ex) + { std::cerr << "Error: " << ex.what() << std::endl; } return files; } - -#endif diff --git a/shared/Other.h b/shared/Other.h index 8c3581c7..7f8978e4 100644 --- a/shared/Other.h +++ b/shared/Other.h @@ -13,8 +13,9 @@ #include #ifdef _WIN32 -extern "C" { - __declspec(dllimport) void* __stdcall GetStdHandle(unsigned long nStdHandle); +extern "C" +{ + __declspec(dllimport) void *__stdcall GetStdHandle(unsigned long nStdHandle); __declspec(dllimport) int __stdcall AllocConsole(); } #endif @@ -26,11 +27,13 @@ extern "C" { #include "CVector.h" #include "CVector2D.h" -namespace plugin { - static void OpenConsole() { +namespace plugin +{ + static void OpenConsole() + { #if defined(_WIN32) AllocConsole(); - FILE* dummy; + FILE *dummy; freopen_s(&dummy, "conin$", "r", stdin); freopen_s(&dummy, "conout$", "w", stdout); freopen_s(&dummy, "conout$", "w", stderr); @@ -38,25 +41,29 @@ namespace plugin { #endif } - template - static T RandomNumberInRange(T min, T max) { + template + static T RandomNumberInRange(T min, T max) + { static_assert(std::is_arithmetic::value, "Type T must be numeric"); std::random_device rd; std::mt19937 gen(rd()); - if constexpr (std::is_integral::value) { + if constexpr (std::is_integral::value) + { std::uniform_int_distribution dis(min, max); return dis(gen); } - else { + else + { std::uniform_real_distribution dis(min, max); return dis(gen); } } - template - static T Random() { + template + static T Random() + { return RandomNumberInRange(0, 999); } @@ -65,67 +72,76 @@ namespace plugin { std::wstring AtoW(std::string const &str); std::string WtoA(std::wstring const &str); - bool CreateImageFromFile(std::string const& path, class Image*& img); - bool CreateImageFromMemory(std::string const& name, void* data, unsigned long size, class Image*& img); + bool CreateImageFromFile(std::string const &path, class Image *&img); + bool CreateImageFromMemory(std::string const &name, void *data, unsigned long size, class Image *&img); -#if _HAS_CXX17 - std::vector GetAllFilesInFolder(std::string const& path, std::string const& ext, bool includePath = false); -#endif + std::vector GetAllFilesInFolder(std::string const &path, std::string const &ext, bool includePath = false); - class FormattingUtils { + class FormattingUtils + { static const unsigned int BUF_SIZE = 10; static unsigned int currentBuf; static char buf[BUF_SIZE][4096]; static unsigned int currentBufW; static wchar_t bufW[BUF_SIZE][4096]; + public: - template static T const &Arg(T const &arg) { return arg; } + template + static T const &Arg(T const &arg) { return arg; } static char const *Arg(std::string const &arg) { return arg.c_str(); } static wchar_t const *Arg(std::wstring const &arg) { return arg.c_str(); } static char *GetBuf(); static wchar_t *GetBufW(); }; - template - char *FormatStatic(const std::string &format, ArgTypes... args) { + template + char *FormatStatic(const std::string &format, ArgTypes... args) + { char *buf = FormattingUtils::GetBuf(); snprintf(buf, 4096, format.c_str(), FormattingUtils::Arg(args)...); return buf; } - template - std::string Format(const std::string &format, ArgTypes... args) { + template + std::string Format(const std::string &format, ArgTypes... args) + { return FormatStatic(format, FormattingUtils::Arg(args)...); } - template - wchar_t *FormatStatic(const std::wstring &format, ArgTypes... args) { + template + wchar_t *FormatStatic(const std::wstring &format, ArgTypes... args) + { wchar_t *buf = FormattingUtils::GetBufW(); _snwprintf(buf, 4096, format.c_str(), FormattingUtils::Arg(args)...); return buf; } - template - std::wstring Format(const std::wstring &format, ArgTypes... args) { + template + std::wstring Format(const std::wstring &format, ArgTypes... args) + { return FormatStatic(format, FormattingUtils::Arg(args)...); } - static std::wstring ToWString(const std::string& str) { + static std::wstring ToWString(const std::string &str) + { std::wstring wstr(str.size(), L'\0'); mbstowcs_s(nullptr, wstr.data(), wstr.size() + 1, str.c_str(), str.size()); return wstr; } - static std::string ToString(const std::wstring& wstr) { + static std::string ToString(const std::wstring &wstr) + { std::string str(wstr.size() * MB_CUR_MAX, '\0'); wcstombs_s(nullptr, str.data(), str.size() + 1, wstr.c_str(), wstr.size()); return str; } - static std::wstring ToUpper(std::wstring const& str, int32_t offset) { + static std::wstring ToUpper(std::wstring const &str, int32_t offset) + { std::wstring result = str; int32_t i = 0; - for (auto& c : result) { + for (auto &c : result) + { if (i > offset - 1) c = std::toupper(c); i++; @@ -133,10 +149,12 @@ namespace plugin { return result; } - static std::wstring ToLower(std::wstring const& str, int32_t offset) { + static std::wstring ToLower(std::wstring const &str, int32_t offset) + { std::wstring result = str; int32_t i = 0; - for (auto& c : result) { + for (auto &c : result) + { if (i > offset - 1) c = std::tolower(c); i++; @@ -144,10 +162,12 @@ namespace plugin { return result; } - static std::string ToUpper(std::string const& str, int32_t offset) { + static std::string ToUpper(std::string const &str, int32_t offset) + { std::string result = str; int32_t i = 0; - for (auto& c : result) { + for (auto &c : result) + { if (i > offset - 1) c = std::toupper(c); i++; @@ -155,10 +175,12 @@ namespace plugin { return result; } - static std::string ToLower(std::string const& str, int32_t offset) { + static std::string ToLower(std::string const &str, int32_t offset) + { std::string result = str; int32_t i = 0; - for (auto& c : result) { + for (auto &c : result) + { if (i > offset - 1) c = std::tolower(c); i++; @@ -166,52 +188,64 @@ namespace plugin { return result; } - static std::string RemoveExtension(std::string const& str) { + static std::string RemoveExtension(std::string const &str) + { std::string fileNoExt = str; size_t pos = fileNoExt.find_last_of('.'); - if (pos != std::string::npos) { + if (pos != std::string::npos) + { fileNoExt.erase(pos); } return fileNoExt; } - static std::string RemovePath(std::string const& str) { + static std::string RemovePath(std::string const &str) + { size_t pos = str.find_last_of("\\/"); - if (pos != std::string::npos) { + if (pos != std::string::npos) + { return str.substr(pos + 1); } - else { + else + { return str; } } - template - static T DegToRad(T x) { + template + static T DegToRad(T x) + { return (x * PI / (T)180); } - template - static T RadToDeg(T x) { + template + static T RadToDeg(T x) + { return (x * (T)180 / PI); } - template - static T Clamp(T v, T2 low, T3 high) { - return ((v) < (low) ? (low) : (v) > (high) ? (high) : (v)); + template + static T Clamp(T v, T2 low, T3 high) + { + return ((v) < (low) ? (low) : (v) > (high) ? (high) + : (v)); } - static float InterpF(float a, float b, float f) { + static float InterpF(float a, float b, float f) + { return (a + (f) * (b - a)); } - static CVector2D InterpV2D(CVector2D a, CVector2D b, float f) { - return CVector2D((a.x + (f) * (b.x - a.x)), (a.y + (f) * (b.y - a.y))); + static CVector2D InterpV2D(CVector2D a, CVector2D b, float f) + { + return CVector2D((a.x + (f) * (b.x - a.x)), (a.y + (f) * (b.y - a.y))); } - static float GetTimeStepFix() { + static float GetTimeStepFix() + { #if defined(RW) || defined(RAGE) return CTimer::ms_fTimeStep / (50.0f / 30.0f); #else @@ -219,19 +253,23 @@ namespace plugin { #endif } - static bool IsNearlyEqualF(float a, float b, float t) { + static bool IsNearlyEqualF(float a, float b, float t) + { return (fabs(a - b) <= t); } - static bool FileExists(const char* name) { + static bool FileExists(const char *name) + { struct stat buffer; return (stat(name, &buffer) == 0); } - static uint64_t GetAvailableMemory() { + static uint64_t GetAvailableMemory() + { MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); - if (GlobalMemoryStatusEx(&memInfo)) { + if (GlobalMemoryStatusEx(&memInfo)) + { DWORDLONG availableRAM = memInfo.ullAvailPhys / (1024 * 1024); return availableRAM; } @@ -239,16 +277,22 @@ namespace plugin { return 0; } - struct CaseInsensitiveUnorderedMap { - struct Comp { - bool operator() (const std::string& lhs, const std::string& rhs) const { + struct CaseInsensitiveUnorderedMap + { + struct Comp + { + bool operator()(const std::string &lhs, const std::string &rhs) const + { return _stricmp(lhs.c_str(), rhs.c_str()) == 0; } }; - struct Hash { - std::size_t operator() (std::string str) const { - for (std::size_t index = 0; index < str.size(); ++index) { + struct Hash + { + std::size_t operator()(std::string str) const + { + for (std::size_t index = 0; index < str.size(); ++index) + { auto ch = static_cast(str[index]); str[index] = static_cast(std::tolower(ch)); } diff --git a/tools/premake/linux-clang-example/premake5.lua b/tools/premake/linux-clang-example/premake5.lua new file mode 100644 index 00000000..8e2a71af --- /dev/null +++ b/tools/premake/linux-clang-example/premake5.lua @@ -0,0 +1,52 @@ +local sdkdir = os.getenv("PLUGIN_SDK_DIR") + +if not sdkdir then + error("WARNING: PLUGIN_SDK_DIR env var not found. Defaulting to current directory.") +end + +sdkdir = path.translate(sdkdir, "/") + +workspace "plugin" + configurations { "Release", "zDebug" } + location "build" + +project "Plugin_SA" + kind "StaticLib" + language "C++" + architecture "x32" + + targetname "Plugin" + + forceincludes { "cstring", "CPed.h" } + + defines { + "RW", + "PLUGIN_SGV_10US", + "GTASA" + } + + filter "action:gmake or action:gmake2 or action:codeblocks" + toolset "clang" + buildoptions { + "-std=c++2b", -- C++23 + "--target=i686-w64-mingw32", + "-fpermissive", + "-fcommon", + "-fms-extensions", + "-Wno-microsoft-include" + } + filter {} + + includedirs { + sdkdir, + sdkdir .. "/shared", + sdkdir .. "/shared/game", + sdkdir .. "/plugin_sa", + sdkdir .. "/plugin_sa/game_sa", + sdkdir .. "/plugin_sa/game_sa/rw" + } + + files { + sdkdir .. "/shared/**.cpp", + sdkdir .. "/plugin_sa/**.cpp" + } \ No newline at end of file From 0060f433533a63ceebfa52c0abf0a5d5258c1215 Mon Sep 17 00:00:00 2001 From: Grinch_ Date: Fri, 13 Feb 2026 12:43:00 +0600 Subject: [PATCH 2/2] More fixes for linux build --- injector/injector.hpp | 1149 +++++++++-------- plugin_sa/game_sa/CVisibilityPlugins.h | 182 +-- plugin_sa/game_sa/CWaterLevel.h | 50 +- .../premake/linux-clang-example/premake5.lua | 37 +- 4 files changed, 730 insertions(+), 688 deletions(-) diff --git a/injector/injector.hpp b/injector/injector.hpp index 87f4a47d..de4a8b47 100644 --- a/injector/injector.hpp +++ b/injector/injector.hpp @@ -6,19 +6,19 @@ * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. - * + * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: - * + * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. - * + * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. - * + * * 3. This notice may not be removed or altered from any source * distribution. * @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "gvm/gvm.hpp" #include "..\shared\DynAddress.h" @@ -51,7 +52,7 @@ INJECTOR_GVM_DUMMY If defined, the game_version_manager will be a dummy object By default it provides a nice gvm for Grand Theft Auto series - + INJECTOR_OWN_GVM If defined, the game_version_manager should be implemented by the user before including this library. By default it provides a nice gvm for Grand Theft Auto series @@ -59,727 +60,741 @@ #include "gvm/gvm.hpp" - namespace injector { -/* -* valid_pointer_type -* Concept to check if T is either a pointer or an integer that fits in a pointer -*/ + /* + * valid_pointer_type + * Concept to check if T is either a pointer or an integer that fits in a pointer + */ template concept valid_pointer_type = std::is_scalar_v && sizeof(T) <= sizeof(uintptr_t) && !std::is_floating_point_v; -/* -* to_void_pointer -* Function to convert a valid_pointer_type to a void* -*/ + /* + * to_void_pointer + * Function to convert a valid_pointer_type to a void* + */ template - inline void* to_void_pointer(T x) + inline void *to_void_pointer(T x) { - void* p = nullptr; - std::memcpy(&p, std::addressof(x), sizeof(T)); + void *p = nullptr; + std::memcpy(&p, std::addressof(x), sizeof(T)); return p; - } + } -/* - * auto_pointer - * Casts itself to another pointer type in the lhs - */ -union auto_pointer -{ + /* + * auto_pointer + * Casts itself to another pointer type in the lhs + */ + union auto_pointer + { protected: friend union memory_pointer_tr; - template friend union basic_memory_pointer; - - void* p; + template + friend union basic_memory_pointer; + + void *p; uintptr_t a; public: - auto_pointer() : p(0) {} - auto_pointer(const auto_pointer& x) : p(x.p) {} + auto_pointer() : p(0) {} + auto_pointer(const auto_pointer &x) : p(x.p) {} - template - explicit auto_pointer(T x) : p(to_void_pointer(x)) {} + template + explicit auto_pointer(T x) : p(to_void_pointer(x)) {} bool is_null() const { return this->p != nullptr; } - #if __cplusplus >= 201103L || _MSC_VER >= 1800 +#if __cplusplus >= 201103L || _MSC_VER >= 1800 explicit operator bool() const { return is_null(); } - #endif - - auto_pointer get() const { return *this; } - template T* get() const { return (T*) this->p; } - template T* get_raw() const { return (T*) this->p; } - - template - operator T*() const { return reinterpret_cast(p); } -}; +#endif -/* - * basic_memory_pointer - * A memory pointer class that is capable of many operations, including address translation - * MemTranslator is the translator functor - */ -template -union basic_memory_pointer -{ + auto_pointer get() const { return *this; } + template + T *get() const { return (T *)this->p; } + template + T *get_raw() const { return (T *)this->p; } + + template + operator T *() const { return reinterpret_cast(p); } + }; + + /* + * basic_memory_pointer + * A memory pointer class that is capable of many operations, including address translation + * MemTranslator is the translator functor + */ + template + union basic_memory_pointer + { protected: - void* p; + void *p; uintptr_t a; - + // Translates address p to the running executable pointer - static auto_pointer memory_translate(void* p) + static auto_pointer memory_translate(void *p) { return auto_pointer(MemTranslator()(p)); } public: - basic_memory_pointer() : p(nullptr) {} - basic_memory_pointer(std::nullptr_t) : p(nullptr) {} - template - basic_memory_pointer(T x) : p(to_void_pointer(x)) {} - basic_memory_pointer(const auto_pointer& x) : p(x.p) {} - basic_memory_pointer(const basic_memory_pointer& rhs) : p(rhs.p) {} - - - + basic_memory_pointer() : p(nullptr) {} + basic_memory_pointer(std::nullptr_t) : p(nullptr) {} + template + basic_memory_pointer(T x) : p(to_void_pointer(x)) {} + basic_memory_pointer(const auto_pointer &x) : p(x.p) {} + basic_memory_pointer(const basic_memory_pointer &rhs) : p(rhs.p) {} + // Gets the translated pointer (plus automatic casting to lhs) - auto_pointer get() const { return memory_translate(p); } - + auto_pointer get() const { return memory_translate(p); } + // Gets the translated pointer (casted to T*) - template T* get() const { return get(); } - + template + T *get() const { return get(); } + // Gets the raw pointer, without translation (casted to T*) - template T* get_raw() const { return auto_pointer(p); } - + template + T *get_raw() const { return auto_pointer(p); } + // This type can get assigned from any pointer and uintptr_t - template - basic_memory_pointer& operator=(T x) { return p = to_void_pointer(x), *this; } - basic_memory_pointer& operator=(uintptr_t x) { return a = x, *this; } - + template + basic_memory_pointer &operator=(T x) { return p = to_void_pointer(x), *this; } + basic_memory_pointer &operator=(uintptr_t x) { return a = x, *this; } + /* Arithmetic */ - basic_memory_pointer operator+(const basic_memory_pointer& rhs) const - { return basic_memory_pointer(this->a + rhs.a); } - - basic_memory_pointer operator-(const basic_memory_pointer& rhs) const - { return basic_memory_pointer(this->a - rhs.a); } - - basic_memory_pointer operator*(const basic_memory_pointer& rhs) const - { return basic_memory_pointer(this->a * rhs.a); } - - basic_memory_pointer operator/(const basic_memory_pointer& rhs) const - { return basic_memory_pointer(this->a / rhs.a); } - - + basic_memory_pointer operator+(const basic_memory_pointer &rhs) const + { + return basic_memory_pointer(this->a + rhs.a); + } + + basic_memory_pointer operator-(const basic_memory_pointer &rhs) const + { + return basic_memory_pointer(this->a - rhs.a); + } + + basic_memory_pointer operator*(const basic_memory_pointer &rhs) const + { + return basic_memory_pointer(this->a * rhs.a); + } + + basic_memory_pointer operator/(const basic_memory_pointer &rhs) const + { + return basic_memory_pointer(this->a / rhs.a); + } + /* Comparision */ - bool operator==(const basic_memory_pointer& rhs) const - { return this->a == rhs.a; } - - bool operator!=(const basic_memory_pointer& rhs) const - { return this->a != rhs.a; } - - bool operator<(const basic_memory_pointer& rhs) const - { return this->a < rhs.a; } - - bool operator<=(const basic_memory_pointer& rhs) const - { return this->a <= rhs.a; } - - bool operator>(const basic_memory_pointer& rhs) const - { return this->a > rhs.a; } - - bool operator>=(const basic_memory_pointer& rhs) const - { return this->a >=rhs.a; } - - bool is_null() const { return this->p == nullptr; } - uintptr_t as_int() const { return this->a; } // does not perform translation - - - -#if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 + bool operator==(const basic_memory_pointer &rhs) const + { + return this->a == rhs.a; + } + + bool operator!=(const basic_memory_pointer &rhs) const + { + return this->a != rhs.a; + } + + bool operator<(const basic_memory_pointer &rhs) const + { + return this->a < rhs.a; + } + + bool operator<=(const basic_memory_pointer &rhs) const + { + return this->a <= rhs.a; + } + + bool operator>(const basic_memory_pointer &rhs) const + { + return this->a > rhs.a; + } + + bool operator>=(const basic_memory_pointer &rhs) const + { + return this->a >= rhs.a; + } + + bool is_null() const { return this->p == nullptr; } + uintptr_t as_int() const { return this->a; } // does not perform translation + +#if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 /* Conversion to other types */ explicit operator uintptr_t() const - { return this->a; } // does not perform translation + { + return this->a; + } // does not perform translation explicit operator bool() const - { return this->p != nullptr; } + { + return this->p != nullptr; + } #else - //operator bool() -------------- Causes casting problems because of implicitness, use !is_null() + // operator bool() -------------- Causes casting problems because of implicitness, use !is_null() //{ return this->p != nullptr; } #endif - -}; - - // Typedefs including memory translator for the above type -typedef basic_memory_pointer memory_pointer; -typedef basic_memory_pointer memory_pointer_raw; -typedef basic_memory_pointer memory_pointer_aslr; - - - -/* - * memory_pointer_tr - * Stores a basic_memory_pointer as a raw pointer from translated pointer - */ -union memory_pointer_tr -{ + }; + + // Typedefs including memory translator for the above type + typedef basic_memory_pointer memory_pointer; + typedef basic_memory_pointer memory_pointer_raw; + typedef basic_memory_pointer memory_pointer_aslr; + + /* + * memory_pointer_tr + * Stores a basic_memory_pointer as a raw pointer from translated pointer + */ + union memory_pointer_tr + { protected: - void* p; + void *p; uintptr_t a; - + public: - template - memory_pointer_tr(const basic_memory_pointer& ptr) + template + memory_pointer_tr(const basic_memory_pointer &ptr) : p(ptr.get()) - {} // Constructs from a basic_memory_pointer - - memory_pointer_tr(const auto_pointer& ptr) + { + } // Constructs from a basic_memory_pointer + + memory_pointer_tr(const auto_pointer &ptr) : p(ptr.p) - {} // Constructs from a auto_pointer, probably comming from basic_memory_pointer::get - - memory_pointer_tr(const memory_pointer_tr& rhs) + { + } // Constructs from a auto_pointer, probably comming from basic_memory_pointer::get + + memory_pointer_tr(const memory_pointer_tr &rhs) : p(rhs.p) - {} // Constructs from my own type, copy constructor - - template + { + } // Constructs from my own type, copy constructor + + template memory_pointer_tr(T x) : p(memory_pointer(to_void_pointer(x)).get()) - {} // Constructs from any pointer or integer, translating the address - - // Just to be method-compatible with basic_memory_pointer ... - auto_pointer get() { return auto_pointer(p); } - template T* get() { return get(); } - template T* get_raw() { return get(); } - - memory_pointer_tr operator+(const uintptr_t& rhs) const - { return memory_pointer_raw(this->a + rhs); } - - memory_pointer_tr operator-(const uintptr_t& rhs) const - { return memory_pointer_raw(this->a - rhs); } - - memory_pointer_tr operator*(const uintptr_t& rhs) const - { return memory_pointer_raw(this->a * rhs); } - - memory_pointer_tr operator/(const uintptr_t& rhs) const - { return memory_pointer_raw(this->a / rhs); } - - bool is_null() const { return this->p == nullptr; } - uintptr_t as_int() const { return this->a; } - -#if __cplusplus >= 201103L - explicit operator uintptr_t() const - { return this->a; } -#else -#endif - -}; + { + } // Constructs from any pointer or integer, translating the address + // Just to be method-compatible with basic_memory_pointer ... + auto_pointer get() { return auto_pointer(p); } + template + T *get() { return get(); } + template + T *get_raw() { return get(); } + memory_pointer_tr operator+(const uintptr_t &rhs) const + { + return memory_pointer_raw(this->a + rhs); + } + memory_pointer_tr operator-(const uintptr_t &rhs) const + { + return memory_pointer_raw(this->a - rhs); + } + memory_pointer_tr operator*(const uintptr_t &rhs) const + { + return memory_pointer_raw(this->a * rhs); + } + memory_pointer_tr operator/(const uintptr_t &rhs) const + { + return memory_pointer_raw(this->a / rhs); + } + bool is_null() const { return this->p == nullptr; } + uintptr_t as_int() const { return this->a; } -/* - * ProtectMemory - * Makes the address @addr have a protection of @protection - */ -inline bool ProtectMemory(memory_pointer_tr addr, size_t size, DWORD protection) -{ - return VirtualProtect(addr.get(), size, protection, &protection) != 0; -} +#if __cplusplus >= 201103L + explicit operator uintptr_t() const + { + return this->a; + } +#else +#endif + }; -/* - * UnprotectMemory - * Unprotect the memory at @addr with size @size so it have all accesses (execute, read and write) - * Returns the old protection to out_oldprotect - */ -inline bool UnprotectMemory(memory_pointer_tr addr, size_t size, DWORD& out_oldprotect) -{ - return VirtualProtect(addr.get(), size, PAGE_EXECUTE_READWRITE, &out_oldprotect) != 0; -} + /* + * ProtectMemory + * Makes the address @addr have a protection of @protection + */ + inline bool ProtectMemory(memory_pointer_tr addr, size_t size, DWORD protection) + { + return VirtualProtect(addr.get(), size, protection, &protection) != 0; + } -/* - * scoped_unprotect - * RAII wrapper for UnprotectMemory - * On construction unprotects the memory, on destruction reprotects the memory - */ -struct scoped_unprotect -{ - memory_pointer_raw addr; - size_t size; - DWORD dwOldProtect; - bool bUnprotected; + /* + * UnprotectMemory + * Unprotect the memory at @addr with size @size so it have all accesses (execute, read and write) + * Returns the old protection to out_oldprotect + */ + inline bool UnprotectMemory(memory_pointer_tr addr, size_t size, DWORD &out_oldprotect) + { + return VirtualProtect(addr.get(), size, PAGE_EXECUTE_READWRITE, &out_oldprotect) != 0; + } - scoped_unprotect(memory_pointer_tr addr, size_t size) : - addr(addr.get()), - size(size) + /* + * scoped_unprotect + * RAII wrapper for UnprotectMemory + * On construction unprotects the memory, on destruction reprotects the memory + */ + struct scoped_unprotect { - if(size == 0) + memory_pointer_raw addr; + size_t size; + DWORD dwOldProtect; + bool bUnprotected; + + scoped_unprotect(memory_pointer_tr addr, size_t size) : addr(addr.get()), + size(size) { - bUnprotected = false; - dwOldProtect = 0; + if (size == 0) + { + bUnprotected = false; + dwOldProtect = 0; + } + else + { + bUnprotected = UnprotectMemory(addr, size, dwOldProtect); + } } - else + + ~scoped_unprotect() { - bUnprotected = UnprotectMemory(addr, size, dwOldProtect); + if (bUnprotected) + ProtectMemory(this->addr.get(), this->size, this->dwOldProtect); } - } - - ~scoped_unprotect() + }; + + /* + * WriteMemoryRaw + * Writes into memory @addr the content of @value with a sizeof @size + * Does memory unprotection if @vp is true + */ + inline void WriteMemoryRaw(memory_pointer_tr addr, void *value, size_t size, bool vp) { - if(bUnprotected) ProtectMemory(this->addr.get(), this->size, this->dwOldProtect); + scoped_unprotect xprotect(addr, vp ? size : 0); + memcpy(addr.get(), value, size); } -}; - - - - - - - - -/* - * WriteMemoryRaw - * Writes into memory @addr the content of @value with a sizeof @size - * Does memory unprotection if @vp is true - */ -inline void WriteMemoryRaw(memory_pointer_tr addr, void* value, size_t size, bool vp) -{ - scoped_unprotect xprotect(addr, vp? size : 0); - memcpy(addr.get(), value, size); -} -/* - * ReadMemoryRaw - * Reads the memory at @addr with a sizeof @size into address @ret - * Does memory unprotection if @vp is true - */ -inline void ReadMemoryRaw(memory_pointer_tr addr, void* ret, size_t size, bool vp) -{ - scoped_unprotect xprotect(addr, vp? size : 0); - memcpy(ret, addr.get(), size); -} - -/* - * MemoryFill - * Fills the memory at @addr with the byte @value doing it @size times - * Does memory unprotection if @vp is true - */ -inline void MemoryFill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) -{ - scoped_unprotect xprotect(addr, vp? size : 0); - memset(addr.get(), value, size); -} + /* + * ReadMemoryRaw + * Reads the memory at @addr with a sizeof @size into address @ret + * Does memory unprotection if @vp is true + */ + inline void ReadMemoryRaw(memory_pointer_tr addr, void *ret, size_t size, bool vp) + { + scoped_unprotect xprotect(addr, vp ? size : 0); + memcpy(ret, addr.get(), size); + } -/* - * WriteObject - * Assigns the object @value into the same object type at @addr - * Does memory unprotection if @vp is true - */ -template -inline T& WriteObject(memory_pointer_tr addr, const T& value, bool vp = false) -{ - scoped_unprotect xprotect(addr, vp? sizeof(value) : 0); - return (*addr.get() = value); -} + /* + * MemoryFill + * Fills the memory at @addr with the byte @value doing it @size times + * Does memory unprotection if @vp is true + */ + inline void MemoryFill(memory_pointer_tr addr, uint8_t value, size_t size, bool vp) + { + scoped_unprotect xprotect(addr, vp ? size : 0); + memset(addr.get(), value, size); + } -/* - * ReadObject - * Assigns the object @value with the value of the same object type at @addr - * Does memory unprotection if @vp is true - */ -template -inline T& ReadObject(memory_pointer_tr addr, T& value, bool vp = false) -{ - scoped_unprotect xprotect(addr, vp? sizeof(value) : 0); - return (value = *addr.get()); -} + /* + * WriteObject + * Assigns the object @value into the same object type at @addr + * Does memory unprotection if @vp is true + */ + template + inline T &WriteObject(memory_pointer_tr addr, const T &value, bool vp = false) + { + scoped_unprotect xprotect(addr, vp ? sizeof(value) : 0); + return (*addr.get() = value); + } + /* + * ReadObject + * Assigns the object @value with the value of the same object type at @addr + * Does memory unprotection if @vp is true + */ + template + inline T &ReadObject(memory_pointer_tr addr, T &value, bool vp = false) + { + scoped_unprotect xprotect(addr, vp ? sizeof(value) : 0); + return (value = *addr.get()); + } -/* - * WriteMemory - * Writes the object of type T into the address @addr - * Does memory unprotection if @vp is true - */ -template -inline void WriteMemory(memory_pointer_tr addr, T value, bool vp = false) -{ - WriteObject(addr, value, vp); -} + /* + * WriteMemory + * Writes the object of type T into the address @addr + * Does memory unprotection if @vp is true + */ + template + inline void WriteMemory(memory_pointer_tr addr, T value, bool vp = false) + { + WriteObject(addr, value, vp); + } -/* - * ReadMemory - * Reads the object type T at address @addr - * Does memory unprotection if @vp is true - */ -template -inline T ReadMemory(memory_pointer_tr addr, bool vp = false) -{ - T value; - return ReadObject(addr, value, vp); -} + /* + * ReadMemory + * Reads the object type T at address @addr + * Does memory unprotection if @vp is true + */ + template + inline T ReadMemory(memory_pointer_tr addr, bool vp = false) + { + T value; + return ReadObject(addr, value, vp); + } -/* - * AdjustPointer - * Searches in the range [@addr, @addr + @max_search] for a pointer in the range [@default_base, @default_end] and replaces - * it with the proper offset in the pointer @replacement_base. - * Does memory unprotection if @vp is true. - */ - inline memory_pointer_raw AdjustPointer(memory_pointer_tr addr, - memory_pointer_raw replacement_base, memory_pointer_tr default_base, memory_pointer_tr default_end, - size_t max_search = 8, bool vp = true) - { - scoped_unprotect xprotect(addr, vp? max_search + sizeof(void*) : 0); - for(size_t i = 0; i < max_search; ++i) - { - memory_pointer_raw ptr = ReadMemory(addr + i); - if(ptr >= default_base.get() && ptr <= default_end.get()) - { - auto result = replacement_base + (ptr - default_base.get()); - WriteMemory(addr + i, result.get()); - return result; + /* + * AdjustPointer + * Searches in the range [@addr, @addr + @max_search] for a pointer in the range [@default_base, @default_end] and replaces + * it with the proper offset in the pointer @replacement_base. + * Does memory unprotection if @vp is true. + */ + inline memory_pointer_raw AdjustPointer(memory_pointer_tr addr, + memory_pointer_raw replacement_base, memory_pointer_tr default_base, memory_pointer_tr default_end, + size_t max_search = 8, bool vp = true) + { + scoped_unprotect xprotect(addr, vp ? max_search + sizeof(void *) : 0); + for (size_t i = 0; i < max_search; ++i) + { + memory_pointer_raw ptr = ReadMemory(addr + i); + if (ptr >= default_base.get() && ptr <= default_end.get()) + { + auto result = replacement_base + (ptr - default_base.get()); + WriteMemory(addr + i, result.get()); + return result; + } } + return nullptr; } - return nullptr; - } - - + /* + * GetAbsoluteOffset + * Gets absolute address based on relative offset @rel_value from instruction that ends at @end_of_instruction + */ + inline memory_pointer_raw GetAbsoluteOffset(int rel_value, memory_pointer_tr end_of_instruction) + { + return end_of_instruction.get() + rel_value; + } + /* + * GetRelativeOffset + * Gets relative offset based on absolute address @abs_value for instruction that ends at @end_of_instruction + */ + inline uintptr_t GetRelativeOffset(memory_pointer_tr abs_value, memory_pointer_tr end_of_instruction) + { + return uintptr_t(abs_value.get() - end_of_instruction.get()); + } - -/* - * GetAbsoluteOffset - * Gets absolute address based on relative offset @rel_value from instruction that ends at @end_of_instruction - */ -inline memory_pointer_raw GetAbsoluteOffset(int rel_value, memory_pointer_tr end_of_instruction) -{ - return end_of_instruction.get() + rel_value; -} - -/* - * GetRelativeOffset - * Gets relative offset based on absolute address @abs_value for instruction that ends at @end_of_instruction - */ -inline uintptr_t GetRelativeOffset(memory_pointer_tr abs_value, memory_pointer_tr end_of_instruction) -{ - return uintptr_t(abs_value.get() - end_of_instruction.get()); -} - -/* - * ReadRelativeOffset - * Reads relative offset from address @at - */ -inline memory_pointer_raw ReadRelativeOffset(memory_pointer_tr at, size_t sizeof_addr = 4, bool vp = true) -{ - switch(sizeof_addr) + /* + * ReadRelativeOffset + * Reads relative offset from address @at + */ + inline memory_pointer_raw ReadRelativeOffset(memory_pointer_tr at, size_t sizeof_addr = 4, bool vp = true) { - case 1: return (GetAbsoluteOffset(ReadMemory (at, vp), at+sizeof_addr)); - case 2: return (GetAbsoluteOffset(ReadMemory(at, vp), at+sizeof_addr)); - case 4: return (GetAbsoluteOffset(ReadMemory(at, vp), at+sizeof_addr)); + switch (sizeof_addr) + { + case 1: + return (GetAbsoluteOffset(ReadMemory(at, vp), at + sizeof_addr)); + case 2: + return (GetAbsoluteOffset(ReadMemory(at, vp), at + sizeof_addr)); + case 4: + return (GetAbsoluteOffset(ReadMemory(at, vp), at + sizeof_addr)); + } + return nullptr; } - return nullptr; -} -/* - * MakeRelativeOffset - * Writes relative offset into @at based on absolute destination @dest - */ -inline void MakeRelativeOffset(memory_pointer_tr at, memory_pointer_tr dest, size_t sizeof_addr = 4, bool vp = true) -{ - switch(sizeof_addr) + /* + * MakeRelativeOffset + * Writes relative offset into @at based on absolute destination @dest + */ + inline void MakeRelativeOffset(memory_pointer_tr at, memory_pointer_tr dest, size_t sizeof_addr = 4, bool vp = true) { - case 1: WriteMemory (at, static_cast (GetRelativeOffset(dest, at+sizeof_addr)), vp); break; - case 2: WriteMemory(at, static_cast(GetRelativeOffset(dest, at+sizeof_addr)), vp); break; - case 4: WriteMemory(at, static_cast(GetRelativeOffset(dest, at+sizeof_addr)), vp); break; + switch (sizeof_addr) + { + case 1: + WriteMemory(at, static_cast(GetRelativeOffset(dest, at + sizeof_addr)), vp); + break; + case 2: + WriteMemory(at, static_cast(GetRelativeOffset(dest, at + sizeof_addr)), vp); + break; + case 4: + WriteMemory(at, static_cast(GetRelativeOffset(dest, at + sizeof_addr)), vp); + break; + } } -} -/* - * GetBranchDestination - * Gets the destination of a branch instruction at address @at - * *** Works only with JMP and CALL for now *** - */ -inline memory_pointer_raw GetBranchDestination(memory_pointer_tr at, bool vp = true) -{ - switch(ReadMemory(at, vp)) + /* + * GetBranchDestination + * Gets the destination of a branch instruction at address @at + * *** Works only with JMP and CALL for now *** + */ + inline memory_pointer_raw GetBranchDestination(memory_pointer_tr at, bool vp = true) { + switch (ReadMemory(at, vp)) + { // We need to handle other instructions (and prefixes) later... - case 0xE8: // call rel - case 0xE9: // jmp rel + case 0xE8: // call rel + case 0xE9: // jmp rel return ReadRelativeOffset(at + 1, 4, vp); - case 0xFF: - switch(ReadMemory(at + 1, vp)) + case 0xFF: + switch (ReadMemory(at + 1, vp)) { - case 0x15: // call dword ptr [addr] - case 0x25: // jmp dword ptr [addr] - return *(ReadMemory(at + 2, vp)); + case 0x15: // call dword ptr [addr] + case 0x25: // jmp dword ptr [addr] + return *(ReadMemory(at + 2, vp)); } break; + } + return nullptr; } - return nullptr; -} -/* - * MakeJMP - * Creates a JMP instruction at address @at that jumps into address @dest - * If there was already a branch instruction there, returns the previosly destination of the branch - */ -inline memory_pointer_raw MakeJMP(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) -{ -#if !(defined (_M_IX86) || defined (_X86_)) - dest = plugin::MakeTrampoline(at.as_int(), dest.get()); + /* + * MakeJMP + * Creates a JMP instruction at address @at that jumps into address @dest + * If there was already a branch instruction there, returns the previosly destination of the branch + */ + inline memory_pointer_raw MakeJMP(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { +#if !(defined(_M_IX86) || defined(_X86_)) + dest = plugin::MakeTrampoline(at.as_int(), dest.get()); #endif - auto p = GetBranchDestination(at, vp); - WriteMemory(at, 0xE9, vp); - MakeRelativeOffset(at+1, dest, 4, vp); - return p; -} + auto p = GetBranchDestination(at, vp); + WriteMemory(at, 0xE9, vp); + MakeRelativeOffset(at + 1, dest, 4, vp); + return p; + } -/* - * MakeCALL - * Creates a CALL instruction at address @at that jumps into address @dest - * If there was already a branch instruction there, returns the previosly destination of the branch - */ -inline memory_pointer_raw MakeCALL(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) -{ -#if !(defined (_M_IX86) || defined (_X86_)) - dest = plugin::MakeTrampoline(at.as_int(), dest.get()); + /* + * MakeCALL + * Creates a CALL instruction at address @at that jumps into address @dest + * If there was already a branch instruction there, returns the previosly destination of the branch + */ + inline memory_pointer_raw MakeCALL(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { +#if !(defined(_M_IX86) || defined(_X86_)) + dest = plugin::MakeTrampoline(at.as_int(), dest.get()); #endif - auto p = GetBranchDestination(at, vp); - WriteMemory(at, 0xE8, vp); - MakeRelativeOffset(at+1, dest, 4, vp); - return p; -} + auto p = GetBranchDestination(at, vp); + WriteMemory(at, 0xE8, vp); + MakeRelativeOffset(at + 1, dest, 4, vp); + return p; + } -/* - * MakeJA - * Creates a JA instruction at address @at that jumps if above into address @dest - * If there was already a branch instruction there, returns the previosly destination of the branch - */ -inline void MakeJA(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) -{ -#if !(defined (_M_IX86) || defined (_X86_)) - dest = plugin::MakeTrampoline(at.as_int(), dest.get()); + /* + * MakeJA + * Creates a JA instruction at address @at that jumps if above into address @dest + * If there was already a branch instruction there, returns the previosly destination of the branch + */ + inline void MakeJA(memory_pointer_tr at, memory_pointer_raw dest, bool vp = true) + { +#if !(defined(_M_IX86) || defined(_X86_)) + dest = plugin::MakeTrampoline(at.as_int(), dest.get()); #endif - WriteMemory(at, 0x87F0, vp); - MakeRelativeOffset(at+2, dest, 4, vp); -} - -/* - * MakeNOP - * Creates a bunch of NOP instructions at address @at - */ -inline void MakeNOP(memory_pointer_tr at, size_t count = 1, bool vp = true) -{ - MemoryFill(at, 0x90, count, vp); -} - -/* - * MakeRangedNOP - * Creates a bunch of NOP instructions at address @at until address @until - */ -inline void MakeRangedNOP(memory_pointer_tr at, memory_pointer_tr until, bool vp = true) -{ - return MakeNOP(at, size_t(until.get_raw() - at.get_raw()), vp); -} - - -/* - * MakeRET - * Creates a RET instruction at address @at popping @pop values from the stack - * If @pop is equal to 0 it will use the 1 byte form of the instruction - */ -inline void MakeRET(memory_pointer_tr at, uint16_t pop = 0, bool vp = true) -{ - WriteMemory(at, pop? 0xC2 : 0xC3, vp); - if(pop) WriteMemory(at+1, pop, vp); -} - + WriteMemory(at, 0x87F0, vp); + MakeRelativeOffset(at + 2, dest, 4, vp); + } + /* + * MakeNOP + * Creates a bunch of NOP instructions at address @at + */ + inline void MakeNOP(memory_pointer_tr at, size_t count = 1, bool vp = true) + { + MemoryFill(at, 0x90, count, vp); + } + /* + * MakeRangedNOP + * Creates a bunch of NOP instructions at address @at until address @until + */ + inline void MakeRangedNOP(memory_pointer_tr at, memory_pointer_tr until, bool vp = true) + { + return MakeNOP(at, size_t(until.get_raw() - at.get_raw()), vp); + } + /* + * MakeRET + * Creates a RET instruction at address @at popping @pop values from the stack + * If @pop is equal to 0 it will use the 1 byte form of the instruction + */ + inline void MakeRET(memory_pointer_tr at, uint16_t pop = 0, bool vp = true) + { + WriteMemory(at, pop ? 0xC2 : 0xC3, vp); + if (pop) + WriteMemory(at + 1, pop, vp); + } -/* - * lazy_pointer - * Lazy pointer, where it's final value will get evaluated only once when finally needed. - */ - template - struct lazy_pointer - { + /* + * lazy_pointer + * Lazy pointer, where it's final value will get evaluated only once when finally needed. + */ + template + struct lazy_pointer + { public: - // Returns the final raw pointer - static auto_pointer get() - { - return xget().get(); - } - - template - static T* get() - { - return get().get(); - } + // Returns the final raw pointer + static auto_pointer get() + { + return xget().get(); + } + + template + static T *get() + { + return get().get(); + } private: // Returns the final pointer static memory_pointer_raw xget() { - static void* ptr = nullptr; - if(!ptr) ptr = memory_pointer(addr).get(); + static void *ptr = nullptr; + if (!ptr) + ptr = memory_pointer(addr).get(); return memory_pointer_raw(ptr); } -}; - - /* - * lazy_object - * Lazy object, where it's final object will get evaluated only once when finally needed. - */ - template - struct lazy_object - { - static T& get() - { - static T data; - static bool has_data = false; - if(!has_data) - { - ReadObject(addr, data, true); - has_data = true; - } - return data; - } - }; - - - /* - Helpers - */ - - template -inline memory_pointer mem_ptr(T p) -{ - return memory_pointer(p); -} - -template -inline memory_pointer_raw raw_ptr(T p) -{ - return memory_pointer_raw(p); -} + }; + + /* + * lazy_object + * Lazy object, where it's final object will get evaluated only once when finally needed. + */ + template + struct lazy_object + { + static T &get() + { + static T data; + static bool has_data = false; + if (!has_data) + { + ReadObject(addr, data, true); + has_data = true; + } + return data; + } + }; -template -inline memory_pointer_raw raw_ptr(basic_memory_pointer p) -{ - return raw_ptr(p.get()); -} + /* + Helpers + */ -template -inline memory_pointer_raw lazy_ptr() -{ - return lazy_pointer::get(); -} + template + inline memory_pointer mem_ptr(T p) + { + return memory_pointer(p); + } -template -inline memory_pointer_aslr aslr_ptr(T p) -{ - return memory_pointer_aslr(p); -} + template + inline memory_pointer_raw raw_ptr(T p) + { + return memory_pointer_raw(p); + } + template + inline memory_pointer_raw raw_ptr(basic_memory_pointer p) + { + return raw_ptr(p.get()); + } + template + inline memory_pointer_raw lazy_ptr() + { + return lazy_pointer::get(); + } + template + inline memory_pointer_aslr aslr_ptr(T p) + { + return memory_pointer_aslr(p); + } +#ifndef INJECTOR_GVM_OWN_DETECT // Should we implement our detection method? + // Detects game, region and version; returns false if could not detect it + inline bool game_version_manager::Detect() + { + // Cleanup data + this->Clear(); -#ifndef INJECTOR_GVM_OWN_DETECT // Should we implement our detection method? + // Find NT header + uintptr_t base = (uintptr_t)GetModuleHandleA(NULL); + IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)(base); + IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + dos->e_lfanew); -// Detects game, region and version; returns false if could not detect it -inline bool game_version_manager::Detect() -{ - // Cleanup data - this->Clear(); - - // Find NT header - uintptr_t base = (uintptr_t) GetModuleHandleA(NULL); - IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)(base); - IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(base + dos->e_lfanew); - - // Look for game and version thought the entry-point - // Thanks to Silent for many of the entry point offsets - switch (base + nt->OptionalHeader.AddressOfEntryPoint + (0x400000 - base)) - { - case 0x5C1E70: // GTA III 1.0 + // Look for game and version thought the entry-point + // Thanks to Silent for many of the entry point offsets + switch (base + nt->OptionalHeader.AddressOfEntryPoint + (0x400000 - base)) + { + case 0x5C1E70: // GTA III 1.0 game = '3', major = 1, minor = 0, region = 0, steam = false; return true; - - case 0x5C2130: // GTA III 1.1 + + case 0x5C2130: // GTA III 1.1 game = '3', major = 1, minor = 1, region = 0, steam = false; return true; - - case 0x5C6FD0: // GTA III 1.1 (Cracked Steam Version) - case 0x9912ED: // GTA III 1.1 (Encrypted Steam Version) + + case 0x5C6FD0: // GTA III 1.1 (Cracked Steam Version) + case 0x9912ED: // GTA III 1.1 (Encrypted Steam Version) game = '3', major = 1, minor = 1, region = 0, steam = true; return true; - - case 0x667BF0: // GTA VC 1.0 + + case 0x667BF0: // GTA VC 1.0 game = 'V', major = 1, minor = 0, region = 0, steam = false; return true; - - case 0x667C40: // GTA VC 1.1 + + case 0x667C40: // GTA VC 1.1 game = 'V', major = 1, minor = 1, region = 0, steam = false; return true; - case 0x666BA0: // GTA VC 1.1 (Cracked Steam Version) - case 0xA402ED: // GTA VC 1.1 (Encrypted Steam Version) + case 0x666BA0: // GTA VC 1.1 (Cracked Steam Version) + case 0xA402ED: // GTA VC 1.1 (Encrypted Steam Version) game = 'V', major = 1, minor = 1, region = 0, steam = true; return true; - - case 0x82457C: // GTA SA 1.0 US Cracked - case 0x824570: // GTA SA 1.0 US Compact + + case 0x82457C: // GTA SA 1.0 US Cracked + case 0x824570: // GTA SA 1.0 US Compact game = 'S', major = 1, minor = 0, region = 'U', steam = false; - cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9? 'H' : 0; + cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9 ? 'H' : 0; return true; - case 0x8245BC: // GTA SA 1.0 EU Cracked (??????) - case 0x8245B0: // GTA SA 1.0 EU Cracked + case 0x8245BC: // GTA SA 1.0 EU Cracked (??????) + case 0x8245B0: // GTA SA 1.0 EU Cracked game = 'S', major = 1, minor = 0, region = 'E', steam = false; - cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9? 'H' : 0; // just to say 'securom' + cracker = injector::ReadMemory(raw_ptr(0x406A20), true) == 0xE9 ? 'H' : 0; // just to say 'securom' return true; - - case 0x8252FC: // GTA SA 1.1 US Cracked + + case 0x8252FC: // GTA SA 1.1 US Cracked game = 'S', major = 1, minor = 1, region = 'U', steam = false; return true; - - case 0x82533C: // GTA SA 1.1 EU Cracked + + case 0x82533C: // GTA SA 1.1 EU Cracked game = 'S', major = 1, minor = 1, region = 'E', steam = false; return true; - - case 0x85EC4A: // GTA SA 3.0 (Cracked Steam Version) - case 0xD3C3DB: // GTA SA 3.0 (Encrypted Steam Version) + + case 0x85EC4A: // GTA SA 3.0 (Cracked Steam Version) + case 0xD3C3DB: // GTA SA 3.0 (Encrypted Steam Version) game = 'S', major = 3, minor = 0, region = 0, steam = true; return true; - case 0xC965AD: // GTA IV 1.0.0.4 US + case 0xC965AD: // GTA IV 1.0.0.4 US game = 'I', major = 1, minor = 0, majorRevision = 0, minorRevision = 4, region = 'U', steam = false; return true; - case 0xD0D011: // GTA IV 1.0.0.7 US + case 0xD0D011: // GTA IV 1.0.0.7 US game = 'I', major = 1, minor = 0, majorRevision = 0, minorRevision = 7, region = 'U', steam = false; return true; - case 0xD0AF06: // GTA EFLC 1.1.2.0 US + case 0xD0AF06: // GTA EFLC 1.1.2.0 US game = 'E', major = 1, minor = 1, majorRevision = 2, minorRevision = 0, region = 'U', steam = false; return true; default: return false; + } } -} #endif - -} // namespace - +} // namespace diff --git a/plugin_sa/game_sa/CVisibilityPlugins.h b/plugin_sa/game_sa/CVisibilityPlugins.h index 753463e0..06651c7c 100644 --- a/plugin_sa/game_sa/CVisibilityPlugins.h +++ b/plugin_sa/game_sa/CVisibilityPlugins.h @@ -12,119 +12,123 @@ #include "CClumpModelInfo.h" #include "CAtomicModelInfo.h" #include "CLinkList.h" +#include -struct tAtomicVisibilityPlugin { +struct tAtomicVisibilityPlugin +{ public: short m_wModelId; unsigned short m_wFlags; }; -class PLUGIN_API CVisibilityPlugins { +class PLUGIN_API CVisibilityPlugins +{ public: - struct AlphaObjectInfo { - void* pObj; - void* RenderFn; + struct AlphaObjectInfo + { + void *pObj; + void *RenderFn; float dist; }; - static int& ms_atomicPluginOffset; - static CLinkList& m_alphaList; - static CLinkList& m_alphaEntityList; - static CLinkList& m_alphaBoatAtomicList; - static CLinkList& m_alphaUnderwaterEntityList; - static CLinkList& m_alphaReallyDrawLastList; - static CLinkList& ms_weaponPedsForPC; - static RwCamera*& ms_pCamera; - static RwV3d*& ms_pCameraPosn; - static float& ms_cullCompsDist; - static float& ms_cullBigCompsDist; - static float& ms_vehicleLod0RenderMultiPassDist; - static float& ms_vehicleLod0Dist; - static float& ms_vehicleLod1Dist; - static float& ms_bigVehicleLod0Dist; - static float& ms_pedLodDist; - static float& ms_pedFadeDist; - static float& gVehicleDistanceFromCamera; - static float& gVehicleAngleToCamera; + static int &ms_atomicPluginOffset; + static CLinkList &m_alphaList; + static CLinkList &m_alphaEntityList; + static CLinkList &m_alphaBoatAtomicList; + static CLinkList &m_alphaUnderwaterEntityList; + static CLinkList &m_alphaReallyDrawLastList; + static CLinkList &ms_weaponPedsForPC; + static RwCamera *&ms_pCamera; + static RwV3d *&ms_pCameraPosn; + static float &ms_cullCompsDist; + static float &ms_cullBigCompsDist; + static float &ms_vehicleLod0RenderMultiPassDist; + static float &ms_vehicleLod0Dist; + static float &ms_vehicleLod1Dist; + static float &ms_bigVehicleLod0Dist; + static float &ms_pedLodDist; + static float &ms_pedFadeDist; + static float &gVehicleDistanceFromCamera; + static float &gVehicleAngleToCamera; public: - static void AtomicConstructor(void* object); - static void AtomicCopyConstructor(void* object, void const* originalObject); - static void* AtomicDestructor(void* object); - static int CalculateFadingAtomicAlpha(CBaseModelInfo* pBaseModelInfo, CEntity* pEntity, float arg3); - static void ClearAtomicFlag(RpAtomic* pRpAtomic, int flag); - static void ClearAtomicFlag(RpAtomic* pRpAtomic, unsigned short flag); - static void ClearClumpForAllAtomicsFlag(RpClump* pRpClump, int flag); - static void ClumpConstructor(void* object); - static void ClumpCopyConstructor(void* object, void const* originalObject); - static void* ClumpDestructor(void* object); + static void AtomicConstructor(void *object); + static void AtomicCopyConstructor(void *object, void const *originalObject); + static void *AtomicDestructor(void *object); + static int CalculateFadingAtomicAlpha(CBaseModelInfo *pBaseModelInfo, CEntity *pEntity, float arg3); + static void ClearAtomicFlag(RpAtomic *pRpAtomic, int flag); + static void ClearAtomicFlag(RpAtomic *pRpAtomic, unsigned short flag); + static void ClearClumpForAllAtomicsFlag(RpClump *pRpClump, int flag); + static void ClumpConstructor(void *object); + static void ClumpCopyConstructor(void *object, void const *originalObject); + static void *ClumpDestructor(void *object); static int DefaultVisibilityCB(); // return 1; - static void FrameConstructor(void* object); - static void FrameCopyConstructor(void* object, void const* originalObject); - static void* FrameDestructor(void* arg0, int arg1, int arg2); - static bool FrustumSphereCB(RpClump* pRpClump); - static short GetAtomicId(RpAtomic* pRpAtomic); - static CAtomicModelInfo* GetAtomicModelInfo(RpAtomic* pRpAtomic); - static int GetClumpAlpha(RpClump* pRpClump); - static CClumpModelInfo* GetClumpModelInfo(RpClump* pRpClump); - static float GetDistanceSquaredFromCamera(RwFrame* pRwFrame); - static float GetDistanceSquaredFromCamera(RwV3d* pRwV3d); - static float GetDotProductWithCameraVector(RwMatrixTag* atomicMat, RwMatrixTag* rootMat, unsigned int flags); - static int GetFrameHierarchyId(RwFrame* pRwFrame); - static short GetModelInfoIndex(RpAtomic* pRpAtomic); - static short GetUserValue(RpAtomic* pRpAtomic); + static void FrameConstructor(void *object); + static void FrameCopyConstructor(void *object, void const *originalObject); + static void *FrameDestructor(void *arg0, int arg1, int arg2); + static bool FrustumSphereCB(RpClump *pRpClump); + static short GetAtomicId(RpAtomic *pRpAtomic); + static CAtomicModelInfo *GetAtomicModelInfo(RpAtomic *pRpAtomic); + static int GetClumpAlpha(RpClump *pRpClump); + static CClumpModelInfo *GetClumpModelInfo(RpClump *pRpClump); + static float GetDistanceSquaredFromCamera(RwFrame *pRwFrame); + static float GetDistanceSquaredFromCamera(RwV3d *pRwV3d); + static float GetDotProductWithCameraVector(RwMatrixTag *atomicMat, RwMatrixTag *rootMat, unsigned int flags); + static int GetFrameHierarchyId(RwFrame *pRwFrame); + static short GetModelInfoIndex(RpAtomic *pRpAtomic); + static short GetUserValue(RpAtomic *pRpAtomic); static void InitAlphaAtomicList(); static void InitAlphaEntityList(); static void Initialise(); - static bool InsertAtomicIntoReallyDrawLastList(RpAtomic* pRpAtomic, float arg2); - static bool InsertEntityIntoReallyDrawLastList(CEntity* pEntity, float arg2); - static bool InsertEntityIntoSortedList(CEntity* pEntity, float distance); - static bool IsAtomicVisible(RpAtomic* pRpAtomic); - static bool IsClumpVisible(RpClump* pRpClump); + static bool InsertAtomicIntoReallyDrawLastList(RpAtomic *pRpAtomic, float arg2); + static bool InsertEntityIntoReallyDrawLastList(CEntity *pEntity, float arg2); + static bool InsertEntityIntoSortedList(CEntity *pEntity, float distance); + static bool IsAtomicVisible(RpAtomic *pRpAtomic); + static bool IsClumpVisible(RpClump *pRpClump); static bool PluginAttach(); - static void RenderAlphaAtomic(RpAtomic* pRpAtomic, int dwAlpha); + static void RenderAlphaAtomic(RpAtomic *pRpAtomic, int dwAlpha); static void RenderAlphaAtomics(); - static void RenderAtomicWithAlphaCB(RpAtomic* pRpAtomic, void* pData); + static void RenderAtomicWithAlphaCB(RpAtomic *pRpAtomic, void *pData); static void RenderBoatAlphaAtomics(); - static void RenderEntity(void* entity, bool unused, float arg3); - static void RenderFadingAtomic(CBaseModelInfo* pBaseModelInfo, RpAtomic* pRpAtomic, int dwAlpha); - static void RenderFadingClump(CBaseModelInfo* pBaseModelInfo, RpClump* pRpClump, int dwAlpha); - static void RenderFadingClumpCB(RpAtomic* pRpAtomic); + static void RenderEntity(void *entity, bool unused, float arg3); + static void RenderFadingAtomic(CBaseModelInfo *pBaseModelInfo, RpAtomic *pRpAtomic, int dwAlpha); + static void RenderFadingClump(CBaseModelInfo *pBaseModelInfo, RpClump *pRpClump, int dwAlpha); + static void RenderFadingClumpCB(RpAtomic *pRpAtomic); static void RenderFadingEntities(); static void RenderFadingUnderwaterEntities(); - static void RenderHeliRotorAlphaCB(RpAtomic* pRpAtomic); - static void RenderHeliTailRotorAlphaCB(RpAtomic* pRpAtomic); - static void RenderObjNormalAtomic(RpAtomic* pRpAtomic); - static void RenderOrderedList(CLinkList& AlphaObjectInfoList); - static void RenderPedCB(RpAtomic* pRpAtomic); - static void RenderPlayerCB(RpAtomic* pRpAtomic); + static void RenderHeliRotorAlphaCB(RpAtomic *pRpAtomic); + static void RenderHeliTailRotorAlphaCB(RpAtomic *pRpAtomic); + static void RenderObjNormalAtomic(RpAtomic *pRpAtomic); + static void RenderOrderedList(CLinkList &AlphaObjectInfoList); + static void RenderPedCB(RpAtomic *pRpAtomic); + static void RenderPlayerCB(RpAtomic *pRpAtomic); static void RenderReallyDrawLastObjects(); - static void RenderTrainHiDetailAlphaCB(RpAtomic* pRpAtomic); - static void RenderTrainHiDetailCB(RpAtomic* pRpAtomic); - static void RenderVehicleHiDetailAlphaCB(RpAtomic* pRpAtomic); - static void RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic* pRpAtomic); - static void RenderVehicleHiDetailAlphaCB_Boat(RpAtomic* pRpAtomic); - static void RenderVehicleHiDetailCB(RpAtomic* pRpAtomic); - static void RenderVehicleHiDetailCB_BigVehicle(RpAtomic* pRpAtomic); - static void RenderVehicleHiDetailCB_Boat(RpAtomic* pRpAtomic); - static void RenderVehicleLoDetailCB_Boat(RpAtomic* pRpAtomic); - static void RenderVehicleReallyLowDetailCB(RpAtomic* pRpAtomic); - static void RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic* pRpAtomic); - static void RenderWeaponCB(RpAtomic* pRpAtomic); + static void RenderTrainHiDetailAlphaCB(RpAtomic *pRpAtomic); + static void RenderTrainHiDetailCB(RpAtomic *pRpAtomic); + static void RenderVehicleHiDetailAlphaCB(RpAtomic *pRpAtomic); + static void RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *pRpAtomic); + static void RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *pRpAtomic); + static void RenderVehicleHiDetailCB(RpAtomic *pRpAtomic); + static void RenderVehicleHiDetailCB_BigVehicle(RpAtomic *pRpAtomic); + static void RenderVehicleHiDetailCB_Boat(RpAtomic *pRpAtomic); + static void RenderVehicleLoDetailCB_Boat(RpAtomic *pRpAtomic); + static void RenderVehicleReallyLowDetailCB(RpAtomic *pRpAtomic); + static void RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *pRpAtomic); + static void RenderWeaponCB(RpAtomic *pRpAtomic); static void RenderWeaponPedsForPC(); - static void SetAtomicFlag(RpAtomic* pRpAtomic, int flag); - static void SetAtomicFlag(RpAtomic* pRpAtomic, unsigned short flag); - static void SetAtomicId(RpAtomic* pRpAtomic, int id); - static void SetAtomicRenderCallback(RpAtomic* pRpAtomic, RpAtomic* (*renderCB)(RpAtomic*)); - static void SetClumpAlpha(RpClump* pRpClump, int dwAlpha); - static void SetClumpModelInfo(RpClump* pRpClump, CClumpModelInfo* pClumpModelInfo); - static void SetFrameHierarchyId(RwFrame* pRwFrame, int id); - static void SetRenderWareCamera(RwCamera* pRwCamera); - static void SetUserValue(RpAtomic* pRpAtomic, unsigned short value); - static void SetupVehicleVariables(RpClump* pRpClump); + static void SetAtomicFlag(RpAtomic *pRpAtomic, int flag); + static void SetAtomicFlag(RpAtomic *pRpAtomic, unsigned short flag); + static void SetAtomicId(RpAtomic *pRpAtomic, int id); + static void SetAtomicRenderCallback(RpAtomic *pRpAtomic, RpAtomic *(*renderCB)(RpAtomic *)); + static void SetClumpAlpha(RpClump *pRpClump, int dwAlpha); + static void SetClumpModelInfo(RpClump *pRpClump, CClumpModelInfo *pClumpModelInfo); + static void SetFrameHierarchyId(RwFrame *pRwFrame, int id); + static void SetRenderWareCamera(RwCamera *pRwCamera); + static void SetUserValue(RpAtomic *pRpAtomic, unsigned short value); + static void SetupVehicleVariables(RpClump *pRpClump); static void Shutdown(); - static bool VehicleVisibilityCB(RpClump* pRpClump); - static bool VehicleVisibilityCB_BigVehicle(RpClump* pRpClump); + static bool VehicleVisibilityCB(RpClump *pRpClump); + static bool VehicleVisibilityCB_BigVehicle(RpClump *pRpClump); }; #define RpAtomicGetVisibilityPlugin(atomic) ((tAtomicVisibilityPlugin *)((unsigned int)atomic + CVisibilityPlugins::ms_atomicPluginOffset)) \ No newline at end of file diff --git a/plugin_sa/game_sa/CWaterLevel.h b/plugin_sa/game_sa/CWaterLevel.h index 4cf986c4..67e88bb5 100644 --- a/plugin_sa/game_sa/CWaterLevel.h +++ b/plugin_sa/game_sa/CWaterLevel.h @@ -7,8 +7,11 @@ #pragma once #include "PluginBase.h" #include "RenderWare.h" +#include "CVector.h" +#include "CObject.h" -struct CRenPar { +struct CRenPar +{ float z; float bigWaves; float smallWaves; @@ -16,13 +19,15 @@ struct CRenPar { char flowY; }; -struct CWaterVertex { +struct CWaterVertex +{ short x; short y; CRenPar rp; }; -enum eBeachToy : int32_t { +enum eBeachToy : int32_t +{ BEACHTOY_BEACHBALL = 0x1, BEACHTOY_LOUNGE_WOOD_UP = 0x2, BEACHTOY_LOUNGE_TOWEL_UP = 0x3, @@ -36,32 +41,33 @@ enum eBeachToy : int32_t { BEACHTOY_BEACHTOWEL_ANY = 0xB, }; -class CWaterLevel { +class CWaterLevel +{ public: - static int& m_nNumOfWaterTriangles; - static int& m_nNumOfWaterQuads; - static int& m_nNumOfWaterVertices; - static int& m_nWaterConfiguration; - static int& m_nNumWaterZonePolys; - static std::array& m_aVertices; - static int& DETAILEDWATERDIST; + static int &m_nNumOfWaterTriangles; + static int &m_nNumOfWaterQuads; + static int &m_nNumOfWaterVertices; + static int &m_nWaterConfiguration; + static int &m_nNumWaterZonePolys; + static std::array &m_aVertices; + static int &DETAILEDWATERDIST; public: - static void AddWaveToResult(float x, float y, float* pWaterZ, float BigWavesAmpl, float SmallWavesAmpl, CVector* pNormal); - static void AddWaveToResult(int32_t x, int32_t y, float* pWaterZ, float BigWavesAmpl, float SmallWavesAmpl); + static void AddWaveToResult(float x, float y, float *pWaterZ, float BigWavesAmpl, float SmallWavesAmpl, CVector *pNormal); + static void AddWaveToResult(int32_t x, int32_t y, float *pWaterZ, float BigWavesAmpl, float SmallWavesAmpl); static void BlockHit(int32_t BlockX, int32_t BlockY); - static void CalculateWavesOnlyForCoordinate(int32_t X, int32_t Y, float BigWavesAmpl, float SmallWavesAmpl, float* pResultHeight); + static void CalculateWavesOnlyForCoordinate(int32_t X, int32_t Y, float BigWavesAmpl, float SmallWavesAmpl, float *pResultHeight); static void ChangeWaterConfiguration(int32_t NewWaterConfig); - static CObject* CreateBeachToy(const CVector* pos, eBeachToy beachToy); + static CObject *CreateBeachToy(const CVector *pos, eBeachToy beachToy); static void FindNearestWaterAndItsFlow(); static bool GetWaterLevel( float x, float y, float z, - float* pWaterZ, + float *pWaterZ, bool bForceResult, - CVector* pNormal); - static bool GetWaterLevelNoWaves(float x, float y, float z, float* pWaterZ); + CVector *pNormal); + static bool GetWaterLevelNoWaves(float x, float y, float z, float *pWaterZ); static void PreRenderWater(); static void RenderAndEmptyRenderBuffer(); @@ -72,10 +78,10 @@ class CWaterLevel { static void RenderWaterFog(); static void ScanThroughBlocks(); static void SetCameraRange(); - static void WaterLevelInitialise(); + static void WaterLevelInitialise(); static void Shutdown(); }; -extern RwTexture* TexWaterClear256; -extern RwTexture* TexSeabd32; -extern RwTexture* TexWaterWake; +extern RwTexture *TexWaterClear256; +extern RwTexture *TexSeabd32; +extern RwTexture *TexWaterWake; diff --git a/tools/premake/linux-clang-example/premake5.lua b/tools/premake/linux-clang-example/premake5.lua index 8e2a71af..1624c3f2 100644 --- a/tools/premake/linux-clang-example/premake5.lua +++ b/tools/premake/linux-clang-example/premake5.lua @@ -8,16 +8,14 @@ sdkdir = path.translate(sdkdir, "/") workspace "plugin" configurations { "Release", "zDebug" } - location "build" + location (sdkdir .. "\\output") + targetdir (sdkdir .. "\\output\\lib") -project "Plugin_SA" +project "plugin_sa" kind "StaticLib" language "C++" architecture "x32" - - targetname "Plugin" - - forceincludes { "cstring", "CPed.h" } + staticruntime "On" defines { "RW", @@ -28,13 +26,30 @@ project "Plugin_SA" filter "action:gmake or action:gmake2 or action:codeblocks" toolset "clang" buildoptions { - "-std=c++2b", -- C++23 "--target=i686-w64-mingw32", "-fpermissive", "-fcommon", "-fms-extensions", - "-Wno-microsoft-include" + "-Wno-microsoft-include" , + "-static", } + + filter "files:**.cpp" + buildoptions { "-std=c++2b" } -- C++23 + + + filter "configurations:Release" + defines { "NDEBUG" } + optimize "On" + symbols "Off" + targetname "plugin" + + filter "configurations:zDebug" + defines { "DEBUG", "_DEBUG" } + symbols "On" + optimize "Debug" + targetname "plugin_d" + filter {} includedirs { @@ -43,10 +58,12 @@ project "Plugin_SA" sdkdir .. "/shared/game", sdkdir .. "/plugin_sa", sdkdir .. "/plugin_sa/game_sa", - sdkdir .. "/plugin_sa/game_sa/rw" + sdkdir .. "/plugin_sa/game_sa/rw", + sdkdir .. "/safetyhook" } files { sdkdir .. "/shared/**.cpp", - sdkdir .. "/plugin_sa/**.cpp" + sdkdir .. "/plugin_sa/**.cpp", + sdkdir .. "/safetyhook/**" } \ No newline at end of file