diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3664d6f6a1..3eba8200d9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,8 +61,8 @@ file(GLOB_RECURSE ORCT2_SOURCES "src/*.c" "src/*.cpp" "lib/argparse/*.c" "lib/cu
if (UNIX)
# force 32bit build for now and set necessary flags to compile code as is
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -std=gnu99")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -std=gnu99 -fno-omit-frame-pointer")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -std=gnu++11 -fno-omit-frame-pointer")
set(CMAKE_SHARED_LINKER_FLAGS "-m32")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
endif (UNIX)
diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 75abfce101..2d78655e37 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -28,6 +28,7 @@
+
@@ -508,4 +509,4 @@ xcopy /YS "$(SolutionDir)..\Data" "$(TargetDir)Data"
-
\ No newline at end of file
+
diff --git a/src/addresses.c b/src/addresses.c
new file mode 100644
index 0000000000..0e9f4d3a89
--- /dev/null
+++ b/src/addresses.c
@@ -0,0 +1,208 @@
+#include "addresses.h"
+
+#if defined(__GNUC__)
+#define DISABLE_OPT __attribute__((noinline,optimize("O0")))
+#else
+#define DISABLE_OPT
+#endif // defined(__GNUC__)
+
+int DISABLE_OPT RCT2_CALLPROC_X(int address, int _eax, int _ebx, int _ecx, int _edx, int _esi, int _edi, int _ebp)
+{
+ int result;
+ #ifdef _MSC_VER
+ __asm {
+ push ebp
+ push address
+ mov eax, _eax
+ mov ebx, _ebx
+ mov ecx, _ecx
+ mov edx, _edx
+ mov esi, _esi
+ mov edi, _edi
+ mov ebp, _ebp
+ call [esp]
+ lahf
+ pop ebp
+ pop ebp
+ /* Load result with flags */
+ mov result, eax
+ }
+ #else
+ __asm__ volatile ( "\
+ \n\
+ push %%ebx \n\
+ push %%ebp \n\
+ push %[address] \n\
+ mov %[eax], %%eax \n\
+ mov %[ebx], %%ebx \n\
+ mov %[ecx], %%ecx \n\
+ mov %[edx], %%edx \n\
+ mov %[esi], %%esi \n\
+ mov %[edi], %%edi \n\
+ mov %[ebp], %%ebp \n\
+ call *(%%esp) \n\
+ lahf \n\
+ add $4, %%esp \n\
+ pop %%ebp \n\
+ pop %%ebx \n\
+ /* Load result with flags */ \n\
+ mov %%eax, %[result] \n\
+ " : [address] "+m" (address), [eax] "+m" (_eax), [ebx] "+m" (_ebx), [ecx] "+m" (_ecx), [edx] "+m" (_edx), [esi] "+m" (_esi), [edi] "+m" (_edi), [ebp] "+m" (_ebp), [result] "+m" (result)
+ :
+ : "eax","ecx","edx","esi","edi","memory"
+ );
+ #endif
+ // lahf only modifies ah, zero out the rest
+ return result & 0xFF00;
+}
+
+int DISABLE_OPT RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_edx, int *_esi, int *_edi, int *_ebp)
+{
+ int result;
+ #ifdef _MSC_VER
+ __asm {
+ // Store C's base pointer
+ push ebp
+ push ebx
+ // Store address to call
+ push address
+
+ // Set all registers to the input values
+ mov eax, [_eax]
+ mov eax, [eax]
+ mov ebx, [_ebx]
+ mov ebx, [ebx]
+ mov ecx, [_ecx]
+ mov ecx, [ecx]
+ mov edx, [_edx]
+ mov edx, [edx]
+ mov esi, [_esi]
+ mov esi, [esi]
+ mov edi, [_edi]
+ mov edi, [edi]
+ mov ebp, [_ebp]
+ mov ebp, [ebp]
+
+ // Call function
+ call [esp]
+
+ // Store output eax
+ push eax
+ push ebp
+ push ebx
+ mov ebp, [esp + 20]
+ mov ebx, [esp + 16]
+
+ // Get resulting ecx, edx, esi, edi registers
+
+ mov eax, [_edi]
+ mov [eax], edi
+ mov eax, [_esi]
+ mov [eax], esi
+ mov eax, [_edx]
+ mov [eax], edx
+ mov eax, [_ecx]
+ mov [eax], ecx
+
+ // Pop ebx reg into ecx
+ pop ecx
+ mov eax, [_ebx]
+ mov[eax], ecx
+
+ // Pop ebp reg into ecx
+ pop ecx
+ mov eax, [_ebp]
+ mov[eax], ecx
+
+ pop eax
+ // Get resulting eax register
+ mov ecx, [_eax]
+ mov [ecx], eax
+
+ // Save flags as return in eax
+ lahf
+ // Pop address
+ pop ebp
+
+ pop ebx
+ pop ebp
+ /* Load result with flags */
+ mov result, eax
+ }
+ #else
+ __asm__ volatile ( "\
+ \n\
+ /* Store C's base pointer*/ \n\
+ push %%ebp \n\
+ push %%ebx \n\
+ \n\
+ /* Store %[address] to call*/ \n\
+ push %[address] \n\
+ \n\
+ /* Set all registers to the input values*/ \n\
+ mov %[_eax], %%eax \n\
+ mov (%%eax), %%eax \n\
+ mov %[_ebx], %%ebx \n\
+ mov (%%ebx), %%ebx \n\
+ mov %[_ecx], %%ecx \n\
+ mov (%%ecx), %%ecx \n\
+ mov %[_edx], %%edx \n\
+ mov (%%edx), %%edx \n\
+ mov %[_esi], %%esi \n\
+ mov (%%esi), %%esi \n\
+ mov %[_edi], %%edi \n\
+ mov (%%edi), %%edi \n\
+ mov %[_ebp], %%ebp \n\
+ mov (%%ebp), %%ebp \n\
+ \n\
+ /* Call function*/ \n\
+ call *(%%esp) \n\
+ \n\
+ /* Store output eax */ \n\
+ push %%eax \n\
+ push %%ebp \n\
+ push %%ebx \n\
+ mov 20(%%esp), %%ebp \n\
+ mov 16(%%esp), %%ebx \n\
+ /* Get resulting ecx, edx, esi, edi registers*/ \n\
+ mov %[_edi], %%eax \n\
+ mov %%edi, (%%eax) \n\
+ mov %[_esi], %%eax \n\
+ mov %%esi, (%%eax) \n\
+ mov %[_edx], %%eax \n\
+ mov %%edx, (%%eax) \n\
+ mov %[_ecx], %%eax \n\
+ mov %%ecx, (%%eax) \n\
+ /* Pop ebx reg into ecx*/ \n\
+ pop %%ecx \n\
+ mov %[_ebx], %%eax \n\
+ mov %%ecx, (%%eax) \n\
+ \n\
+ /* Pop ebp reg into ecx */\n\
+ pop %%ecx \n\
+ mov %[_ebp], %%eax \n\
+ mov %%ecx, (%%eax) \n\
+ \n\
+ pop %%eax \n\
+ /* Get resulting eax register*/ \n\
+ mov %[_eax], %%ecx \n\
+ mov %%eax, (%%ecx) \n\
+ \n\
+ /* Save flags as return in eax*/ \n\
+ lahf \n\
+ /* Pop address*/ \n\
+ pop %%ebp \n\
+ \n\
+ pop %%ebx \n\
+ pop %%ebp \n\
+ /* Load result with flags */ \n\
+ mov %%eax, %[result] \n\
+ " : [address] "+m" (address), [_eax] "+m" (_eax), [_ebx] "+m" (_ebx), [_ecx] "+m" (_ecx), [_edx] "+m" (_edx), [_esi] "+m" (_esi), [_edi] "+m" (_edi), [_ebp] "+m" (_ebp), [result] "+m" (result)
+
+ :
+ : "eax","ecx","edx","esi","edi","memory"
+ );
+ #endif
+ // lahf only modifies ah, zero out the rest
+ return result & 0xFF00;
+}
diff --git a/src/addresses.h b/src/addresses.h
index e4b4371a39..7f2622284e 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -650,55 +650,7 @@
*P = Parity flag
*All other bits are undefined.
*/
-static int RCT2_CALLPROC_X(int address, int _eax, int _ebx, int _ecx, int _edx, int _esi, int _edi, int _ebp)
-{
- int result;
- #ifdef _MSC_VER
- __asm {
- push ebp
- push address
- mov eax, _eax
- mov ebx, _ebx
- mov ecx, _ecx
- mov edx, _edx
- mov esi, _esi
- mov edi, _edi
- mov ebp, _ebp
- call [esp]
- lahf
- pop ebp
- pop ebp
- /* Load result with flags */
- mov result, eax
- }
- #else
- __asm__ ( "\
- \n\
- push %%ebx \n\
- push %%ebp \n\
- push %[address] \n\
- mov %[_eax], %%eax \n\
- mov %[_ebx], %%ebx \n\
- mov %[_ecx], %%ecx \n\
- mov %[_edx], %%edx \n\
- mov %[_esi], %%esi \n\
- mov %[_edi], %%edi \n\
- mov %[_ebp], %%ebp \n\
- call *(%%esp) \n\
- lahf \n\
- add $4, %%esp \n\
- pop %%ebp \n\
- pop %%ebx \n\
- /* Load result with flags */ \n\
- mov %%eax, %[result] \n\
- " : [address] "+m" (address), [_eax] "+m" (_eax), [_ebx] "+m" (_ebx), [_ecx] "+m" (_ecx), [_edx] "+m" (_edx), [_esi] "+m" (_esi), [_edi] "+m" (_edi), [_ebp] "+m" (_ebp), [result] "+m" (result)
- :
- : "eax","ecx","edx","esi","edi"
- );
- #endif
- // lahf only modifies ah, zero out the rest
- return result & 0xFF00;
-}
+int RCT2_CALLPROC_X(int address, int _eax, int _ebx, int _ecx, int _edx, int _esi, int _edi, int _ebp);
static int RCT2_CALLPROC_EBPSAFE(int address)
{
@@ -716,156 +668,7 @@ static int RCT2_CALLPROC_EBPSAFE(int address)
*P = Parity flag
*All other bits are undefined.
*/
-static int RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_edx, int *_esi, int *_edi, int *_ebp)
-{
- int result;
- #ifdef _MSC_VER
- __asm {
- // Store C's base pointer
- push ebp
- push ebx
- // Store address to call
- push address
-
- // Set all registers to the input values
- mov eax, [_eax]
- mov eax, [eax]
- mov ebx, [_ebx]
- mov ebx, [ebx]
- mov ecx, [_ecx]
- mov ecx, [ecx]
- mov edx, [_edx]
- mov edx, [edx]
- mov esi, [_esi]
- mov esi, [esi]
- mov edi, [_edi]
- mov edi, [edi]
- mov ebp, [_ebp]
- mov ebp, [ebp]
-
- // Call function
- call [esp]
-
- // Store output eax
- push eax
- push ebp
- push ebx
- mov ebp, [esp + 20]
- mov ebx, [esp + 16]
-
- // Get resulting ecx, edx, esi, edi registers
-
- mov eax, [_edi]
- mov [eax], edi
- mov eax, [_esi]
- mov [eax], esi
- mov eax, [_edx]
- mov [eax], edx
- mov eax, [_ecx]
- mov [eax], ecx
-
- // Pop ebx reg into ecx
- pop ecx
- mov eax, [_ebx]
- mov[eax], ecx
-
- // Pop ebp reg into ecx
- pop ecx
- mov eax, [_ebp]
- mov[eax], ecx
-
- pop eax
- // Get resulting eax register
- mov ecx, [_eax]
- mov [ecx], eax
-
- // Save flags as return in eax
- lahf
- // Pop address
- pop ebp
-
- pop ebx
- pop ebp
- /* Load result with flags */
- mov result, eax
- }
- #else
- __asm__ ( "\
- \n\
- /* Store C's base pointer*/ \n\
- push %%ebp \n\
- push %%ebx \n\
- \n\
- /* Store %[address] to call*/ \n\
- push %[address] \n\
- \n\
- /* Set all registers to the input values*/ \n\
- mov %[_eax], %%eax \n\
- mov (%%eax), %%eax \n\
- mov %[_ebx], %%ebx \n\
- mov (%%ebx), %%ebx \n\
- mov %[_ecx], %%ecx \n\
- mov (%%ecx), %%ecx \n\
- mov %[_edx], %%edx \n\
- mov (%%edx), %%edx \n\
- mov %[_esi], %%esi \n\
- mov (%%esi), %%esi \n\
- mov %[_edi], %%edi \n\
- mov (%%edi), %%edi \n\
- mov %[_ebp], %%ebp \n\
- mov (%%ebp), %%ebp \n\
- \n\
- /* Call function*/ \n\
- call *(%%esp) \n\
- \n\
- /* Store output eax */ \n\
- push %%eax \n\
- push %%ebp \n\
- push %%ebx \n\
- mov 20(%%esp), %%ebp \n\
- mov 16(%%esp), %%ebx \n\
- /* Get resulting ecx, edx, esi, edi registers*/ \n\
- mov %[_edi], %%eax \n\
- mov %%edi, (%%eax) \n\
- mov %[_esi], %%eax \n\
- mov %%esi, (%%eax) \n\
- mov %[_edx], %%eax \n\
- mov %%edx, (%%eax) \n\
- mov %[_ecx], %%eax \n\
- mov %%ecx, (%%eax) \n\
- /* Pop ebx reg into ecx*/ \n\
- pop %%ecx \n\
- mov %[_ebx], %%eax \n\
- mov %%ecx, (%%eax) \n\
- \n\
- /* Pop ebp reg into ecx */\n\
- pop %%ecx \n\
- mov %[_ebp], %%eax \n\
- mov %%ecx, (%%eax) \n\
- \n\
- pop %%eax \n\
- /* Get resulting eax register*/ \n\
- mov %[_eax], %%ecx \n\
- mov %%eax, (%%ecx) \n\
- \n\
- /* Save flags as return in eax*/ \n\
- lahf \n\
- /* Pop address*/ \n\
- pop %%ebp \n\
- \n\
- pop %%ebx \n\
- pop %%ebp \n\
- /* Load result with flags */ \n\
- mov %%eax, %[result] \n\
- " : [address] "+m" (address), [_eax] "+m" (_eax), [_ebx] "+m" (_ebx), [_ecx] "+m" (_ecx), [_edx] "+m" (_edx), [_esi] "+m" (_esi), [_edi] "+m" (_edi), [_ebp] "+m" (_ebp), [result] "+m" (result)
-
- :
- : "eax","ecx","edx","esi","edi"
- );
- #endif
- // lahf only modifies ah, zero out the rest
- return result & 0xFF00;
-}
+int RCT2_CALLFUNC_X(int address, int *_eax, int *_ebx, int *_ecx, int *_edx, int *_esi, int *_edi, int *_ebp);
typedef struct {
union {
diff --git a/src/platform/platform.h b/src/platform/platform.h
index a8c4b260d8..0cf3c727ee 100644
--- a/src/platform/platform.h
+++ b/src/platform/platform.h
@@ -183,7 +183,7 @@ bool platform_check_steam_overlay_attached();
#endif // __linux__
-#if !(POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
+#if !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
char *strndup(const char *src, size_t size);
#endif // !(POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)