diff --git a/.gitignore b/.gitignore index b94e8d9a3..f246b2da1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,9 +13,9 @@ GameSpy/ DirectX/ # Output build folders -[Rr]elease* -[Pp]rofile* -[Dd]ebug* +[Rr]elease*/ +[Pp]rofile*/ +[Dd]ebug*/ Hybrid/ Max4_Release/ Max4_Hybrid/ diff --git a/Code/Commando/consolefunction.cpp b/Code/Commando/consolefunction.cpp index a56fe1ae9..ef487a645 100644 --- a/Code/Commando/consolefunction.cpp +++ b/Code/Commando/consolefunction.cpp @@ -159,6 +159,7 @@ #include "specialbuilds.h" #include "lightsolve.h" #include "lightsolvecontext.h" +#include "debugbreak.h" #include "openw3d.h" @@ -2311,7 +2312,7 @@ class BreakExecutionConsoleFunctionClass : public ConsoleFunctionClass { virtual const char * Get_Help( void ) override { return "BREAK - break execution. Do not use this just for fun."; } virtual void Activate( const char * /* input */ ) override { Print("Breaking execution on demand.\n"); - __debugbreak(); + debugbreak(); } }; diff --git a/Code/Commando/init.cpp b/Code/Commando/init.cpp index fc9ba3248..63580fd17 100644 --- a/Code/Commando/init.cpp +++ b/Code/Commando/init.cpp @@ -113,6 +113,7 @@ #include "shutdown.h" #include "specialbuilds.h" #include "wwdialog.h" +#include "debugbreak.h" #include extern const char *VALUE_NAME_TEXTURE_FILTER_MODE; @@ -352,7 +353,7 @@ void Commando_Assert_Handler(const char * message) m$" "m " */ - __debugbreak(); + debugbreak(); } if (cDevOptions::ExitThreadOnAssert.Is_True()) { diff --git a/Code/wwdebug/debugbreak.h b/Code/wwdebug/debugbreak.h new file mode 100644 index 000000000..cce61cfb7 --- /dev/null +++ b/Code/wwdebug/debugbreak.h @@ -0,0 +1,61 @@ +/* +** Command & Conquer Renegade(tm) +** Copyright 2026 OpenW3D. +** +** This program is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +*/ +#pragma once + +#if defined _MSC_VER +#define debugbreak() __debugbreak() +#elif defined __has_builtin && __has_builtin(__builtin_debugtrap) +#define debugbreak() __builtin_debugtrap() +/* If we have GCC or compiler that tries to be compatible, use GCC inline assembly. */ +#elif defined __GNUC__ || defined __clang__ +#if defined(__i386__) || defined(__x86_64__) +__attribute__((always_inline)) __inline__ static void debugbreak(void) +{ + __asm__ volatile("int3"); +} +#elif defined(__thumb__) +__attribute__((always_inline)) __inline__ static void debugbreak(void) +{ + __asm__ volatile(".inst 0xde01"); +} +#elif defined(__arm__) +__attribute__((always_inline)) __inline__ static void debugbreak(void) +{ + __asm__ volatile(".inst 0xe7f001f0"); +} +#elif defined(__aarch64__) +__attribute__((always_inline)) __inline__ static void debugbreak(void) +{ + __asm__ volatile(".inst 0xd4200000"); +} +#elif defined(__powerpc__) +__attribute__((always_inline)) __inline__ static void debugbreak(void) +{ + __asm__ volatile(".4byte 0x7d821008"); +} +#elif defined(__riscv) +__attribute__((always_inline)) __inline__ static void debugbreak(void) +{ + __asm__ volatile(".4byte 0x00100073"); +} +#else +#error debugbreak not currently supported on this processor platform, see debugbreak.h +#endif /* CPU architectures on GCC like compilers */ +#else +#error debugbreak not currently supported on this processor platform, see debugbreak.h +#endif diff --git a/Code/wwdebug/wwdebug.cpp b/Code/wwdebug/wwdebug.cpp index dc35970f6..bdcc11cd4 100644 --- a/Code/wwdebug/wwdebug.cpp +++ b/Code/wwdebug/wwdebug.cpp @@ -45,6 +45,7 @@ #include "wwdebug.h" #include "wwdialog.h" #include "unichar.h" +#include "debugbreak.h" #ifdef _WIN32 #include #endif @@ -320,7 +321,7 @@ void WWDebug_Assert_Fail(const char * expr,const char * file, int line) } if (code == MESSAGEBOX_BUTTON_RETRY) { - __debugbreak(); + debugbreak(); return; } } diff --git a/Code/wwdebug/wwdebug.h b/Code/wwdebug/wwdebug.h index 8fc14903d..feead5d33 100644 --- a/Code/wwdebug/wwdebug.h +++ b/Code/wwdebug/wwdebug.h @@ -41,6 +41,8 @@ #ifndef WWDEBUG_H #define WWDEBUG_H +#include "debugbreak.h" + // The macro MESSAGE allows user to put: // #pragma MESSAGE("Hello world") // anywhere in a source file. The message: @@ -141,9 +143,9 @@ void WWDebug_DBWin32_Message_Handler( const char * message); ** the debugger... */ #ifdef WWDEBUG -#define WWDEBUG_BREAK _asm int 0x03 +#define WWDEBUG_BREAK debugbreak() #else -#define WWDEBUG_BREAK _asm int 0x03 +#define WWDEBUG_BREAK debugbreak() #endif /* diff --git a/Code/wwlib/Except.cpp b/Code/wwlib/Except.cpp index 0c2964e3e..ac46b92f9 100644 --- a/Code/wwlib/Except.cpp +++ b/Code/wwlib/Except.cpp @@ -60,6 +60,7 @@ #include "vector.h" #include "wwdebug.h" #include "wwmemlog.h" +#include "debugbreak.h" #include #include @@ -190,10 +191,10 @@ int __cdecl _purecall(void) #ifdef WWDEBUG /* - ** Use int3 to cause an exception. + ** Use debugbreak to cause an exception. */ WWDEBUG_SAY(("Pure Virtual Function call. Oh No!\n")); - __debugbreak(); + debugbreak(); #endif //_DEBUG_ASSERT return(return_code);