819 lines
28 KiB
C++
819 lines
28 KiB
C++
//
|
|
// name: main.cpp
|
|
// description: contains entry function
|
|
//
|
|
|
|
#include "file/device_installer.h"
|
|
#include "fwutil/Gen9Settings.h"
|
|
#include "input/keyboard.h"
|
|
#include "input/keys.h"
|
|
#include "profile/rocky.h"
|
|
#include "system/memory.h"
|
|
#include "system/buddyallocator_config.h"
|
|
#include "system/platform.h"
|
|
#include "system/smallocator.h"
|
|
#include "system/threadtype.h"
|
|
#include "system/tmcommands.h"
|
|
#include "diag/tracker.h"
|
|
|
|
#include "streaming/streamingvisualize.h"
|
|
|
|
#if !__FINAL && RSG_ORBIS
|
|
#include <libdbg.h>
|
|
#endif
|
|
|
|
#define PGKNOWNREFPOOLSIZE ((__XENON || __PS3) ? 0x4000 : 0x8800)
|
|
|
|
#if RSG_PC || RSG_DURANGO || RSG_ORBIS
|
|
|
|
#if __64BIT
|
|
|
|
#if !defined(POOL_HEAP_SIZE)
|
|
# define POOL_HEAP_SIZE (24*1024)
|
|
#endif
|
|
|
|
#if USE_SPARSE_MEMORY
|
|
#define SIMPLE_HEAP_SIZE (620*1024)
|
|
#elif RSG_PC
|
|
#define SIMPLE_HEAP_SIZE (474*1024)
|
|
#elif RSG_DURANGO
|
|
#define SIMPLE_HEAP_SIZE (596*1024)
|
|
#elif RSG_ORBIS
|
|
#define SIMPLE_HEAP_SIZE (596*1024)
|
|
#else
|
|
#define SIMPLE_HEAP_SIZE (768*1024)
|
|
#endif
|
|
|
|
#if RSG_ORBIS
|
|
#define FLEX_HEAP_SIZE (22 * 1024)
|
|
#endif
|
|
|
|
#if RSG_ORBIS || RSG_DURANGO
|
|
#if ENABLE_DEBUG_HEAP
|
|
#define HEMLIS_HEAP_SIZE (17 * 1024)
|
|
#else
|
|
#define HEMLIS_HEAP_SIZE (220 * 1024)
|
|
#endif
|
|
#endif
|
|
|
|
#if ENABLE_DEBUG_HEAP && (RSG_DURANGO || RSG_ORBIS || RSG_PC)
|
|
#define RECORDER_HEAP_SIZE (20 * 1024)
|
|
#endif
|
|
|
|
#if USE_SPARSE_MEMORY && !FREE_PHYSICAL_RESOURCES
|
|
#define SIMPLE_VIRTUAL_SIZE (0)
|
|
#elif RSG_ORBIS
|
|
#define SIMPLE_VIRTUAL_SIZE (0)
|
|
#elif RSG_DURANGO
|
|
#define SIMPLE_VIRTUAL_SIZE (0)
|
|
#else
|
|
#define SIMPLE_VIRTUAL_SIZE (1024*1024)
|
|
#endif
|
|
|
|
#if USE_SPARSE_MEMORY && !FREE_PHYSICAL_RESOURCES
|
|
#define SIMPLE_PHYSICAL_SIZE (8192 * 1024)
|
|
#elif RSG_PC
|
|
#define SIMPLE_PHYSICAL_SIZE (256 *1024)
|
|
#elif RSG_ORBIS || RSG_DURANGO
|
|
#define SIMPLE_PHYSICAL_SIZE ((2482 * 1024) - SIMPLE_VIRTUAL_SIZE)
|
|
#else
|
|
#define SIMPLE_PHYSICAL_SIZE (0)
|
|
#endif
|
|
|
|
#else // __64BIT
|
|
#define SIMPLE_HEAP_SIZE (196*1024)
|
|
|
|
#define ONE_HEAP 0
|
|
#if ONE_HEAP
|
|
#define SIMPLE_VIRTUAL_SIZE 0
|
|
#define SIMPLE_PHYSICAL_SIZE (1024*1024)
|
|
#else
|
|
#define SIMPLE_PHYSICAL_SIZE (256*1024)
|
|
#define SIMPLE_VIRTUAL_SIZE (1024*1024)
|
|
#endif // ONE_HEAP
|
|
#endif // __64BIT
|
|
|
|
#elif __PPU
|
|
#include "grcore/wrapper_gcm.h"
|
|
#include "grcore/effect_config.h"
|
|
#include "renderer/psnvramrendertargettotal.h"
|
|
|
|
#if SMALL_ALLOCATOR_DEBUG_MIN_ALIGNMENT
|
|
# define DEBUG_MEMORY (6)
|
|
#else
|
|
# define DEBUG_MEMORY (4)
|
|
#endif
|
|
|
|
#define HEADER_HEAP_SIZE (512)
|
|
|
|
// Game Virtual - The fixed amount of memory reserved for the normal game heap in Kb.
|
|
#if __DEV
|
|
# if !__OPTIMIZED
|
|
# define GAME_VIRTUAL (((67+DEBUG_MEMORY)*1024) + 256) // Debug
|
|
# else
|
|
# define GAME_VIRTUAL (((67+DEBUG_MEMORY)*1024) + 256) // Beta
|
|
# endif
|
|
#elif __BANK
|
|
# define GAME_VIRTUAL (((67+DEBUG_MEMORY)*1024) + 256) // Bank release
|
|
#elif !__FINAL
|
|
# define GAME_VIRTUAL ((67 * 1024) + 256) // Release
|
|
#else
|
|
# define GAME_VIRTUAL ((62 * 1024) + 512) // Final (3.5 MB decrease)
|
|
#endif
|
|
|
|
// Define a realistic upper bound
|
|
#define VIRTUAL_HEAP_SIZE ((91 << 10) + 768)
|
|
|
|
// Audio physical - the fixed amount of VRAM reserved for audio wave assets in Kb
|
|
#define AUDIO_PHYSICAL (14 * 1024 + 512)
|
|
|
|
// VRAM reserved for render targets. Specified in Kb.
|
|
#define VRAM_GAME_RESERVED (PSN_VRAM_RENDER_TARGET_TOTAL_KB)
|
|
|
|
// Game physical - The fixed amount of memory reserved for the physical game heap in Kb.
|
|
CompileTimeAssert(SPU_GCM_FIFO);
|
|
#define GAME_PHYSICAL (77952 - VRAM_GAME_RESERVED)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Rage specification.
|
|
#define SIMPLE_HEAP_SIZE (GAME_VIRTUAL)
|
|
|
|
// Resource physical expressed as VRAM minus what is we need for game physical.
|
|
#define SIMPLE_PHYSICAL_SIZE (VRAM_SIZE - GAME_PHYSICAL - VRAM_GAME_RESERVED - AUDIO_PHYSICAL)
|
|
|
|
// Gcm buffer size.
|
|
# define GCM_BUFFER_SIZE (3*1024)
|
|
|
|
// Amount of memory reserved for memory containers. Must be multiple of 1Mb.
|
|
#define EXTERNAL_HEAP_SIZE (0)
|
|
|
|
// Amount of memory to reserve for thread stacks, in kilobytes. Must be multiple of 64k.
|
|
#define THREAD_STACK_SIZE (1472)
|
|
|
|
#elif __XENON
|
|
#define HEADER_HEAP_SIZE (1024)
|
|
|
|
#if __BANK
|
|
// If you get crashes allocating backing store textures, you need to make SIMPLE_PHYSICAL_SIZE *smaller*
|
|
#if __DEV // Beta
|
|
#define SIMPLE_HEAP_SIZE ((96 << 10) + 768)
|
|
#define SIMPLE_PHYSICAL_SIZE ((266 << 10) + 512) // Resource Virtual - Keep checking amount of title free pages in pix
|
|
#define SIMPLE_POOL_SIZE ((7 << 10) + 512)
|
|
#else // Bank Release
|
|
#define SIMPLE_HEAP_SIZE ((96 << 10) + 768)
|
|
#define SIMPLE_PHYSICAL_SIZE ((266 << 10) + 512) // bank release
|
|
#define SIMPLE_POOL_SIZE ((7 << 10) + 512)
|
|
#endif //_DEV
|
|
#elif __PROFILE || !__FINAL // Profile, Release
|
|
#define SIMPLE_HEAP_SIZE ((101 << 10) + 512) // pools are getting allocated out of here too (unlike in the __BANK builds)
|
|
#define SIMPLE_PHYSICAL_SIZE ((266 << 10) + 512) // keep checking amount of title free pages in pix
|
|
#define SIMPLE_POOL_SIZE ((0 << 10) + 0) // release is getting really close on XTL memory remaining.
|
|
#else // Final
|
|
#define SIMPLE_HEAP_SIZE ((92 << 10) + 512) // pools are getting allocated out of here too (unlike in the __BANK builds)
|
|
#define SIMPLE_PHYSICAL_SIZE ((275 << 10) + 512) // keep checking amount of title free pages in pix
|
|
#define SIMPLE_POOL_SIZE ((6 << 10) + 768)
|
|
#endif
|
|
|
|
//
|
|
// DON'T FUCK WITH THIS UNLESS YOU KNOW WHAT YOU'RE DOING!
|
|
// We have optimized the heap sizes to reduce TLB misses. Change this and you could fuck up performance (by as much as 1+ ms/frame)
|
|
#define SIMPLE_COMBINED_SIZE (SIMPLE_HEAP_SIZE + SIMPLE_PHYSICAL_SIZE)
|
|
//
|
|
#if !__BANK
|
|
CompileTimeAssert(SIMPLE_COMBINED_SIZE % (16*1024) == 0);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
// ====================== Platform Dependent =========================
|
|
// Set the debug heap size, in kilobytes (default is 8M). Current use appears to be about 4.4M
|
|
//#define DEBUG_HEAP_SIZE (((RSG_PC || RSG_DURANGO || RSG_ORBIS) ? 512 : 60) * 1024)
|
|
#define DEBUG_HEAP_SIZE (((RSG_PC || RSG_DURANGO || RSG_ORBIS) ? 220 : 60) * 1024)
|
|
// ====================== Platform Dependent =========================
|
|
|
|
#if RSG_DURANGO || RSG_ORBIS || RSG_PC
|
|
#define REPLAY_HEAP_SIZE (196 << 20)
|
|
#endif
|
|
|
|
#if RSG_DURANGO
|
|
// DON'T FUCK WITH THIS UNLESS YOU KNOW WHAT YOU'RE DOING!
|
|
// We have optimized the heap sizes to reduce TLB misses. Change this and you could fuck up performance (by as much as 1+ ms/frame)
|
|
CompileTimeAssert(SIMPLE_HEAP_SIZE % (4 << 10) == 0);
|
|
CompileTimeAssert(DEBUG_HEAP_SIZE % (4 << 10) == 0);
|
|
CompileTimeAssert(REPLAY_HEAP_SIZE % (4 << 20) == 0);
|
|
#endif
|
|
|
|
#if !__NO_OUTPUT
|
|
static void EarlyInit();
|
|
|
|
#define EARLY_INIT_CALLBACK EarlyInit
|
|
#endif
|
|
|
|
#define NO_XMEM_WRAPPERS
|
|
|
|
#if RSG_PC
|
|
#define WANT_PORTCULLIS
|
|
#endif
|
|
|
|
// rage headers
|
|
#include "audiohardware/driver.h"
|
|
#include "system/main.h"
|
|
#include "system/tinyheap.h"
|
|
#include "streaming/streaming_channel.h"
|
|
#include "streaming/streamingengine.h"
|
|
#include "string/string.h"
|
|
|
|
// game headers
|
|
#include "app.h"
|
|
#include "file/stream.h"
|
|
|
|
#if __WIN32PC
|
|
#include "grcore/device.h"
|
|
#include "system/xtl.h"
|
|
#include "dwmapi.h"
|
|
#include "diag/diagerrorcodes.h"
|
|
#include "fwutil/Gen9Settings.h"
|
|
#include "system/SystemInfo.h"
|
|
#pragma comment (lib,"Dwmapi.lib")
|
|
|
|
#endif
|
|
|
|
#if __XENON
|
|
#include "system/xtl.h"
|
|
# if _XDK_VER < 21256
|
|
//https://devstar.rockstargames.com/wiki/index.php/Project_Setup
|
|
# error "GTA5 requires at least XeDK version 21256 or better installed on your PC in order to build correctly."
|
|
# endif
|
|
|
|
#elif RSG_DURANGO
|
|
#include <xdk.h>
|
|
# if _XDK_VER < 11068 // pretending we only need June until the build machines can be updated (manifest file will still fail)
|
|
//http://rsgediwiki1/durango/index.php/Main_Page
|
|
# error "Game requires Xbox One XDK version 6.2.11291 (July XDK QFE3) or better installed on your PC in order to build correctly."
|
|
# endif
|
|
# define RSG_MIN_DURANGO_SYS (_XDK_VER)
|
|
|
|
#elif __PPU
|
|
# if CELL_SDK_VERSION < 0x430001
|
|
//https://devstar.rockstargames.com/wiki/index.php/Project_Setup
|
|
# error "GTA5 requires at least PS3 SDK version 430.001 or better installed on your PC in order to build correctly."
|
|
# endif
|
|
namespace rage {
|
|
#if __GERMAN_BUILD
|
|
char* XEX_TITLE_ID = "BLES01807";
|
|
char* XEX_TITLE_ID_HDD = "NPEB01283";
|
|
#elif __AUSSIE_BUILD
|
|
char* XEX_TITLE_ID = "BLES01807"; // fake; necessary for savegame and disk cache code.
|
|
char* XEX_TITLE_ID_HDD = "NPEB01283";
|
|
#elif __EUROPEAN_BUILD
|
|
char* XEX_TITLE_ID = "BLES01807"; // fake; necessary for savegame and disk cache code.
|
|
char* XEX_TITLE_ID_HDD = "NPEB01283";
|
|
#elif __AMERICAN_BUILD
|
|
char* XEX_TITLE_ID = "BLUS31156"; // fake; necessary for savegame and disk cache code.
|
|
char* XEX_TITLE_ID_HDD = "NPUB31154";
|
|
#elif __JAPANESE_BUILD
|
|
char* XEX_TITLE_ID = "BLJM61019"; // fake; necessary for savegame and disk cache code.
|
|
char* XEX_TITLE_ID_HDD = "NPEB01283"; // TODO: don't have this yet
|
|
#else
|
|
#error "Build needs either __<region>_BUILD set to 1"
|
|
#endif
|
|
|
|
// this is incompatible with unity builds so I just modified streambuffers.cpp to have these numbers in the first place.
|
|
// override the number of stream buffers used by the application (the default can be found in streambuffers.cpp in the RageCore library
|
|
// in the file directory. I have increased this limit for console builds due to the number of network log files generated by the network game
|
|
//#if IS_CONSOLE
|
|
//DECLARE_STREAM_BUFFERS(16)
|
|
//#else
|
|
//DECLARE_STREAM_BUFFERS(64)
|
|
//#endif
|
|
}
|
|
#elif RSG_ORBIS
|
|
// sdk 1.7 is minimum - note that gta5 requires a special patch (1.700.601) to be applied to 1.700.081 - 1.700.141
|
|
#define RSG_MIN_ORBIS_SDK 0x01700601u // minimum sdk required for compiling
|
|
#define RSG_MIN_ORBIS_SYS 0x01750061u // lowest supported firmware version
|
|
#if SCE_ORBIS_SDK_VERSION < RSG_MIN_ORBIS_SDK
|
|
#error "Game requires PS4 SDK version 1.700.601 or better installed on your PC in order to build correctly."
|
|
#endif
|
|
namespace rage {
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-writable-strings"
|
|
char *XEX_TITLE_ID = "CUSA00411"; // default to european, gets overridden later
|
|
#pragma GCC diagnostic pop
|
|
}
|
|
#endif //__XENON
|
|
#include "system\performancetimer.h"
|
|
|
|
#if __PPU && !__FINAL
|
|
#include "system/stack.h"
|
|
|
|
extern "C" {
|
|
|
|
extern void __real_exit (int code);
|
|
|
|
void __wrap_exit (int UNUSED_PARAM(code))
|
|
{
|
|
sysStack::PrintStackTrace();
|
|
|
|
Assertf(false,"Calling Exit: This might or might not be a problem");
|
|
|
|
__debugbreak();
|
|
}
|
|
|
|
};
|
|
#endif // __PPU && !__FINAL
|
|
|
|
NOSTRIP_FINAL_LOGGING_PARAM(output,"[startup] Enable all output even in !__DEV builds");
|
|
NOSTRIP_FINAL_LOGGING_PARAM(nooutput, "[startup] Disable all output even in __DEV builds");
|
|
PARAM(noaero, "[startup] Disable Windows' Aero theme");
|
|
PARAM(nokeyboardhook, "[startup] Don't disable the Windows key with a low-level keyboard hook.");
|
|
PARAM(forcekeyboardhook, "[startup] Force disabling the Windows key with a low-level keyboard hook, even with debugger attached.");
|
|
|
|
#if __WIN32PC
|
|
static HHOOK g_keyboardHook;
|
|
static LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (code == HC_ACTION)
|
|
{
|
|
// Check for pressing / releasing either Windows key, and having focus
|
|
KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
|
|
if ((wParam == WM_KEYUP || wParam == WM_KEYDOWN) && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) && GRCDEVICE.GetHasFocus())
|
|
{
|
|
return 1; // Eat the keystroke
|
|
}
|
|
}
|
|
return CallNextHookEx(g_keyboardHook, code, wParam, lParam);
|
|
}
|
|
|
|
static void RemoveKeyboardHook()
|
|
{
|
|
UnhookWindowsHookEx(g_keyboardHook);
|
|
}
|
|
|
|
static void AddKeyboardHook()
|
|
{
|
|
g_keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
|
|
|
|
atexit(RemoveKeyboardHook);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
CApp g_myApp;
|
|
|
|
namespace rage
|
|
{
|
|
XPARAM(nomtplacement);
|
|
# if RAGE_TRACKING
|
|
XPARAM(memvisualize);
|
|
# endif
|
|
# if STREAMING_VISUALIZE
|
|
XPARAM(streamingvisualize);
|
|
# endif
|
|
# if RSG_DURANGO || RSG_ORBIS
|
|
XPARAM(forceboothdd);
|
|
XPARAM(forceboothddloose);
|
|
# endif
|
|
}
|
|
XPARAM(playgoemu);
|
|
|
|
int Main()
|
|
{
|
|
// Should never reach here.
|
|
Assertf(false, "GTA V uses App style entry points.\n");
|
|
return 0;
|
|
}
|
|
|
|
bool Main_Prologue()
|
|
{
|
|
#if !__FINAL
|
|
#if RSG_DURANGO
|
|
Displayf("XB1 XDK version: %u", _XDK_VER);
|
|
OSVERSIONINFOEXW osVersionInfoEx;
|
|
osVersionInfoEx.dwOSVersionInfoSize = sizeof(osVersionInfoEx);
|
|
if(!GetVersionExW((OSVERSIONINFOW*)&osVersionInfoEx))
|
|
Quitf("Failed to get os version info, 0x%08x",GetLastError());
|
|
Displayf("XB1 system version: %u",osVersionInfoEx.dwBuildNumber);
|
|
if(osVersionInfoEx.dwBuildNumber<RSG_MIN_DURANGO_SYS)
|
|
Quitf("Unsupported system software version [%u] - must be at least %u",osVersionInfoEx.dwBuildNumber,RSG_MIN_DURANGO_SYS);
|
|
#elif RSG_ORBIS
|
|
Displayf("PS4 SDK version: %x.%03x.%03x",(SCE_ORBIS_SDK_VERSION&0xff000000u)>>24,(SCE_ORBIS_SDK_VERSION&0xfff000u)>>12,SCE_ORBIS_SDK_VERSION&0xfffu);
|
|
#if SCE_ORBIS_SDK_VERSION >= 0x01600071u
|
|
// Call IsDebuggerPresent() to ensure IsDevkit is initialised
|
|
sysBootManager::IsDebuggerPresent();
|
|
if(sysBootManager::IsDevkit())
|
|
{
|
|
char sysversion[SCE_SYSTEM_SOFTWARE_VERSION_LEN+1];
|
|
u32 hexver = 0;
|
|
sceDbgGetSystemSwVersion(sysversion,SCE_SYSTEM_SOFTWARE_VERSION_LEN+1);
|
|
for(int i=SCE_SYSTEM_SOFTWARE_VERSION_LEN,j=0;i>=0;i--)
|
|
if(sysversion[i]>='0' && sysversion[i]<='9')
|
|
hexver+=(sysversion[i]-'0')*pow(16,j++);
|
|
Displayf("PS4 system version: %s (minimum supported version: %x.%03x.%03x)",sysversion,(RSG_MIN_ORBIS_SYS&0xff000000u)>>24,(RSG_MIN_ORBIS_SYS&0xfff000u)>>12,RSG_MIN_ORBIS_SYS&0xfffu);
|
|
if(hexver<RSG_MIN_ORBIS_SYS && hexver!=0x01730000u) // also allow special version for gta5 that may still be in use (but shouldn't be)
|
|
Quitf("Unsupported system software version [%s] - must be at least %x.%03x.%03x",sysversion,(RSG_MIN_ORBIS_SYS&0xff000000u)>>24,(RSG_MIN_ORBIS_SYS&0xfff000u)>>12,RSG_MIN_ORBIS_SYS&0xfffu);
|
|
}
|
|
#endif
|
|
#endif
|
|
#endif // !__FINAL
|
|
|
|
// GTAV doesn't want output on in release builds.
|
|
#if !__NO_OUTPUT
|
|
if ((!__DEV && !__FINAL && !PARAM_output.Get()) ||
|
|
(__DEV && PARAM_nooutput.Get())
|
|
#if __FINAL_LOGGING
|
|
|| (__FINAL && PARAM_nooutput.Get())
|
|
#endif // __FINAL_LOGGING
|
|
)
|
|
{
|
|
Displayf("*** Output turned OFF, removing all output to popups, logs and tty. Use -output to restore normal display.");
|
|
#if __XENON
|
|
Displayf("*** Press LB+RB+LS+RS to toggle output on and off.");
|
|
#elif __PS3 || RSG_ORBIS
|
|
Displayf("*** Press L1+R1+L3+R3 to toggle output on and off.");
|
|
#endif
|
|
diagChannel::SetOutput(false);
|
|
}
|
|
#endif // !__NO_OUTPUT
|
|
|
|
|
|
#if SYSTMCMD_ENABLE
|
|
if (PARAM_rockstartargetmanager.Get())
|
|
{
|
|
static const char *const configFmt =
|
|
"<config>"
|
|
# if RSG_DURANGO
|
|
"<pdb>%s</pdb>"
|
|
"<fullpackagename>%s</fullpackagename>"
|
|
# if GTA_VERSION/100 == 5
|
|
"<symbol_server>N:\\RSGEDI\\Symbol\\Symbol_Server</symbol_server>"
|
|
# endif
|
|
# endif
|
|
"</config>";
|
|
# if !RSG_DURANGO
|
|
const char *const config = configFmt;
|
|
# else
|
|
char config[512];
|
|
snprintf(config, sizeof(config), configFmt, sysTmGetPdb(), sysTmGetFullPackageName());
|
|
config[sizeof(config)-1] = '\0';
|
|
# endif
|
|
sysTmCmdConfig(config);
|
|
|
|
# if RSG_ORBIS
|
|
// Determine whether or not we want to have the submitDone exception
|
|
// enabled. Same logic applies when not using R*TM, but we don't
|
|
// have any other way to change (or even read) the setting, so
|
|
// withou R*TM it is up to the user to get it right.
|
|
bool submitDoneException = __BANK ? false : true;
|
|
if (!submitDoneException)
|
|
Displayf("Requesting R*TM disable the submitDone exception due to build type (" RSG_CONFIGURATION_LOWERCASE ").");
|
|
# if RAGE_TRACKING
|
|
if (PARAM_memvisualize.Get()) {
|
|
submitDoneException = false;
|
|
Displayf("Requesting R*TM disable the submitDone exception due to mem visualize.");
|
|
}
|
|
# endif
|
|
# if STREAMING_VISUALIZE
|
|
if (PARAM_streamingvisualize.Get()) {
|
|
submitDoneException = false;
|
|
Displayf("Requesting R*TM disable the submitDone exception due to streaming visualize.");
|
|
}
|
|
# endif
|
|
if (!PARAM_forceboothdd.Get() && !PARAM_forceboothddloose.Get() && !PARAM_playgoemu.Get()) {
|
|
submitDoneException = false;
|
|
Displayf("Requesting R*TM disable the submitDone exception due to not booting from hdd.");
|
|
}
|
|
if (submitDoneException)
|
|
Displayf("Requesting R*TM enable the submitDone exception.");
|
|
sysTmCmdSubmitDoneExceptionEnabled(submitDoneException);
|
|
# endif
|
|
}
|
|
#endif
|
|
|
|
#if __WIN32PC
|
|
if (!PARAM_output.Get() ||
|
|
PARAM_nooutput.Get())
|
|
{
|
|
HWND handle = GetConsoleWindow();
|
|
if (handle)
|
|
ShowWindow(handle, SW_HIDE);
|
|
}
|
|
|
|
#if !__FINAL && __64BIT
|
|
if(!PARAM_nokeyboardhook.Get() && (!sysBootManager::IsDebuggerPresent() || PARAM_forcekeyboardhook.Get()))
|
|
#else
|
|
if (!PARAM_nokeyboardhook.Get())
|
|
#endif
|
|
{
|
|
AddKeyboardHook();
|
|
}
|
|
|
|
#if !__D3D11_1
|
|
if (PARAM_noaero.Get())
|
|
{
|
|
// Note: AH: Turn off Desktop Window Manager this disables compositing of the Windows screen in
|
|
// Win7 and can help performance in windowed mode if lots of other desktop rendering is happening
|
|
// simultaneously (using the Aero Win7 theme, for example).
|
|
// Most helpful for profiling and probably mostly affects the older graphics cards.
|
|
// See http://discussms.hosting.lsoft.com/SCRIPTS/WA-MSD.EXE?A2=DIRECTXDEV;e61eaeea.1105b for more details
|
|
// and slide 5 http://download.microsoft.com/download/b/8/c/b8cdd181-478c-4341-8d55-878438dc222f/Performance%20Considerations%20for%20Graphics%20on%20Windows.zip
|
|
BOOL dwmEnabled;
|
|
|
|
HRESULT hr = DwmIsCompositionEnabled( &dwmEnabled );
|
|
if( dwmEnabled )
|
|
{
|
|
hr = DwmEnableComposition( DWM_EC_DISABLECOMPOSITION );
|
|
Assert( hr == S_OK );
|
|
}
|
|
}
|
|
#endif // __D3D11_1 // Depreacated
|
|
|
|
#endif
|
|
|
|
// Rage turns this on by default, we want it off for the game.
|
|
sysMemAllowResourceAlloc = false;
|
|
|
|
#if !__DEV && !__FINAL
|
|
XPARAM(output);
|
|
if (!PARAM_output.Get())
|
|
PARAM_output.Set("0");
|
|
#endif
|
|
|
|
#if __ASSERT && (__XENON || __PS3)
|
|
const char *literal_string_constant = "Literal String Constant";
|
|
static char data_test[] = "Not a String Constant";
|
|
static char bss_test[16];
|
|
char stack_test[16] = "";
|
|
char *heap_test = rage_new char[16];
|
|
heap_test[0] = 0;
|
|
Assertf(IsConstString(literal_string_constant),"IsConstString(%p) is broken on this platform, will waste memory (_rodata_end is %p).",literal_string_constant,_rodata_end);
|
|
AssertMsg(!IsConstString(data_test),"IsConstString() is broken on this platform (data), must be fixed.");
|
|
AssertMsg(!IsConstString(bss_test),"IsConstString() is broken on this platform (bss), must be fixed.");
|
|
AssertMsg(!IsConstString(stack_test),"IsConstString() is broken on this platform (stack), must be fixed.");
|
|
AssertMsg(!IsConstString(heap_test),"IsConstString() is broken on this platform (heap), must be fixed.");
|
|
delete [] heap_test;
|
|
#endif
|
|
|
|
#if __WIN32PC && !__TOOL && !__RESOURCECOMPILER
|
|
diagErrorCodes::LoadLanguageFile();
|
|
CSystemInfo::Initialize();
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Main_OneLoopIteration()
|
|
{
|
|
PROFILER_FRAME("MainThread");
|
|
|
|
#if !__NO_OUTPUT
|
|
// We want a way to crash the game even when running with no target manager
|
|
// (eg. console set to release mode), so we can get what ever coredump the
|
|
// system OS supports. While this seems like an odd spot to put it, we do
|
|
// want it only in game code (not samples), but should be all games (so not
|
|
// part fof App::RunOneIteration()).
|
|
#if RSG_PC
|
|
if (ioKeyboard::KeyDown(KEY_CONTROL) && ioKeyboard::KeyDown(KEY_SHIFT) && ioKeyboard::KeyDown(KEY_DELETE))
|
|
{
|
|
Displayf("The player has pressed Ctrl+Shift+Delete so call __debugbreak()");
|
|
#else
|
|
if (ioKeyboard::KeyDown(KEY_CONTROL) && ioKeyboard::KeyDown(KEY_ALT) && ioKeyboard::KeyDown(KEY_DELETE))
|
|
{
|
|
Displayf("The player has pressed Ctrl+Alt+Delete so call __debugbreak()");
|
|
#endif
|
|
__debugbreak();
|
|
}
|
|
#endif
|
|
|
|
#if BACKTRACE_ENABLED
|
|
BACKTRACE_TEST_CRASH;
|
|
#endif
|
|
|
|
return g_myApp.RunOneIteration();
|
|
}
|
|
|
|
|
|
void Main_Epilogue()
|
|
{
|
|
|
|
}
|
|
|
|
SET_APP_ENTRY_POINTS(Main_Prologue, Main_OneLoopIteration, Main_Epilogue);
|
|
|
|
/*
|
|
extern void rage::SetProjectEntryPoints(bool (*pProjectPrologue)(void), bool (*pProjectDoOneLoop)(void), void (*pProjectEpilogue)(void));
|
|
|
|
// Called during global construtors to set the entry points.
|
|
static struct InitGameEntryPoints_t
|
|
{
|
|
InitGameEntryPoints_t()
|
|
{
|
|
rage::SetProjectEntryPoints(Main_Prologue, Main_OneLoopIteration, Main_Epilogue);
|
|
}
|
|
~InitGameEntryPoints_t()
|
|
{
|
|
}
|
|
} InitGameEntryPointsInstance;
|
|
*/
|
|
|
|
#if __XENON
|
|
|
|
#include "system/XMemWrapper.h"
|
|
|
|
void* WINAPI XMemAlloc(unsigned long dwSize, unsigned long dwAllocAttributes)
|
|
{
|
|
return XMemAllocCustom(dwSize, dwAllocAttributes);
|
|
}
|
|
|
|
void WINAPI XMemFree(void *pAddress, unsigned long dwAllocAttributes)
|
|
{
|
|
return XMemFreeCustom(pAddress, dwAllocAttributes);
|
|
}
|
|
|
|
SIZE_T WINAPI XMemSize (void *pAddress, unsigned long dwAllocAttributes)
|
|
{
|
|
return XMemSizeCustom(pAddress, dwAllocAttributes);
|
|
}
|
|
|
|
#endif // __XENON
|
|
|
|
#if !__NO_OUTPUT
|
|
#include "diag/channel.h"
|
|
#include "fwsys/timer.h"
|
|
|
|
static unsigned GetGameFrame()
|
|
{
|
|
return fwTimer::GetFrameCount();
|
|
}
|
|
|
|
static void EarlyInit()
|
|
{
|
|
rage::diagGetGameFrame = &GetGameFrame;
|
|
}
|
|
#endif
|
|
|
|
#include "system/exception.h"
|
|
|
|
#if BACKTRACE_ENABLED
|
|
|
|
#if RSG_DURANGO
|
|
#include "system/BacktraceDumpUpload.winrt.h"
|
|
#endif // RSG_DURANGO
|
|
|
|
class GameBacktraceConfig : public sysException::BacktraceConfig
|
|
{
|
|
public:
|
|
GameBacktraceConfig(const char* token, const char* submissionUrl) : BacktraceConfig(token, submissionUrl) {}
|
|
|
|
virtual void OnSetup() {}
|
|
virtual bool ShouldSubmitDump(const wchar_t* logFilename);
|
|
virtual bool UploadDump(const wchar_t* dumpFilename, const wchar_t* logFilename, const atMap<atString, atString>* annotations, const char* url);
|
|
};
|
|
|
|
#include "Network/Cloud/Tunables.h"
|
|
|
|
static void OnBacktraceEnabledTunableSet(bool enabled)
|
|
{
|
|
Displayf("[Backtrace] Tunable just set: backtrace enabled: %s", enabled ? "true" : "false");
|
|
|
|
// Disable if the kill-switch is set. We don't re-enable Backtrace later if the kill switch changes.
|
|
if (!enabled)
|
|
{
|
|
sysException::DisableBacktrace();
|
|
}
|
|
}
|
|
|
|
bool GameBacktraceConfig::ShouldSubmitDump(const wchar_t* path)
|
|
{
|
|
CApp::WriteCrashContextLog(path);
|
|
CApp::CollectAdditionalAttributes();
|
|
|
|
// Default values
|
|
bool enabled = true;
|
|
float rateLimit = 100.0f;
|
|
|
|
// Try to override with tunable values
|
|
if (Tunables::IsInstantiated())
|
|
{
|
|
CTunables* tunables = &Tunables::GetInstance();
|
|
|
|
// Tunable to disable Backtrace. We shouldn't get here if this is set, due to the callback function (above),
|
|
// but check anyway.
|
|
if (tunables->Access(CD_GLOBAL_HASH, ATSTRINGHASH("ENABLE_BACKTRACE", 0xB3627BBC), enabled))
|
|
{
|
|
Displayf("[Backtrace] Tunable set: Backtrace enabled: %s", enabled ? "true" : "false");
|
|
OnBacktraceEnabledTunableSet(enabled);
|
|
}
|
|
else
|
|
{
|
|
Displayf("[Backtrace] Tunable not set: Backtrace enabled");
|
|
}
|
|
|
|
// Tunable to set rate limit
|
|
if (tunables->Access(CD_GLOBAL_HASH, ATSTRINGHASH("BACKTRACE_RATE_LIMIT", 0x136ADE12), rateLimit))
|
|
{
|
|
Displayf("[Backtrace] Tunable set: Backtrace rate limit: %f", rateLimit);
|
|
}
|
|
else
|
|
{
|
|
Displayf("[Backtrace] Tunable not set: Backtrace rate limit");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Displayf("[Backtrace] Tunables not initialized yet");
|
|
}
|
|
|
|
// Early-out if disabled
|
|
if (!enabled)
|
|
{
|
|
Displayf("[Backtrace] Upload to Backtrace is disabled");
|
|
return false;
|
|
}
|
|
|
|
// Seed random number generator, discarding first 100 values as distribution is poor
|
|
mthRandom rnd(sysTimer::GetSystemMsTime());
|
|
for (int i = 0; i < 100; i++)
|
|
rnd.GetInt();
|
|
|
|
// Test rate limit against RNG
|
|
if (rnd.GetFloat() * 100.0f < rateLimit)
|
|
{
|
|
Displayf("[Backtrace] Upload to Backtrace passed rate limit");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
Displayf("[Backtrace] Upload to Backtrace failed rate limit");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Upload the dump in a callback function, both to avoid RageCode depending on RageNet, but also because this has to be done in a
|
|
// WinRT-enabled file.
|
|
bool GameBacktraceConfig::UploadDump(const wchar_t* dumpPath, const wchar_t* logPath, const atMap<atString, atString>* annotations, const char* url)
|
|
{
|
|
#if RSG_DURANGO
|
|
return BacktraceDumpUpload::UploadDump(dumpPath, logPath, annotations, url);
|
|
#else
|
|
(void)dumpPath;
|
|
(void)logPath;
|
|
(void)annotations;
|
|
(void)url;
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
// This sets the game Backtrace token and upload URL in a static initializer, as they need to be available before RAGE-level code runs
|
|
// Tokens from: https://backtrace.rockstargames.com/p/RDR2/settings/submission/tokens or https://bob.sp.backtrace.io/p/sandbox/settings/submission/tokens
|
|
|
|
// Internal instance URL: https://backtrace.rockstargames.com:6098
|
|
// External Bob instance URL (with Bob sandbox token): https://submit.backtrace.io/bob/9e4851f293570690ac5efea82e69aecb6629ab6bc125ffcdac230d4dfb2282db/minidump
|
|
// External Bob instance URL (with Bob RDR2 token): https://submit.backtrace.io/bob/f6cc6561434e06ca34f129f5f6d9f0d8ae046864024e708b22b89b5b89ddc39a/minidump
|
|
// External Paradise instance URL (with Paradise sandbox token): https://submit.backtrace.io/paradise/aef040908377c11bd4d8499790e8d227b57198354ef85fc01e747f7821f5ae7e/minidump
|
|
// External Paradise instance URL (with Paradise GTAV token): https://submit.backtrace.io/paradise/b7468900ead8ac96224f5ed076abc812690d9a690eb5446d5b880a92343e85df/minidump
|
|
// External Paradise instance URL (with Paradise GTAV-XBS token): https://submit.backtrace.io/paradise/c33e1d24da2985b5bc33ab957b08f5e5a75b9c6a08336f39f47ff9ba31f356c0/minidump
|
|
// External Paradise instance URL (with Paradise GTAV-XB1 token): https://submit.backtrace.io/paradise/26221444628213a334170087e91e55aa5daf9219e3285be6844674d9f8e47115/minidump
|
|
|
|
// Internal RDR2 token: a055a1848074e274b78b14c5a3f6fbff729250a740cc7a4567d2c96662208aae
|
|
// Internal TestProject token: cedc6a8c203ed626c149b02e32d04b69674c90304c6eb881896e37fe72554de5
|
|
// Internal TestProject2 token: 34f9a6e1b31b0dbd84afb3a4ad00a52a4c9d1c143887e42b19ab9b5a0e20ec0d
|
|
// External Bob sandbox token: 9e4851f293570690ac5efea82e69aecb6629ab6bc125ffcdac230d4dfb2282db
|
|
// External Bob RDR2 token: f6cc6561434e06ca34f129f5f6d9f0d8ae046864024e708b22b89b5b89ddc39a
|
|
// External Paradise sandbox token: aef040908377c11bd4d8499790e8d227b57198354ef85fc01e747f7821f5ae7e
|
|
// External Paradise GTAV token: b7468900ead8ac96224f5ed076abc812690d9a690eb5446d5b880a92343e85df
|
|
// External Paradise GTAV-XBS master token: c33e1d24da2985b5bc33ab957b08f5e5a75b9c6a08336f39f47ff9ba31f356c0
|
|
// External Paradise GTAV-XBS final token: ec8379f5f46beab0f241cb6cbd6a0f83bd3f0e6534defa9102c1b1583eadd826
|
|
// External Paradise GTAV-XB1 master token: 26221444628213a334170087e91e55aa5daf9219e3285be6844674d9f8e47115
|
|
// External Paradise GTAV-XB1 final token: eabd42626dd15b6e5dc704e8b1a8755475054a57e755567057b98189962bdc3e
|
|
|
|
#if RSG_SCARLETT
|
|
# if __MASTER
|
|
# define BACKTRACE_TOKEN "c33e1d24da2985b5bc33ab957b08f5e5a75b9c6a08336f39f47ff9ba31f356c0"
|
|
# define BACKTRACE_SUBMISSION_URL "https://submit.backtrace.io/paradise/" BACKTRACE_TOKEN "/minidump"
|
|
# else
|
|
# define BACKTRACE_TOKEN "ec8379f5f46beab0f241cb6cbd6a0f83bd3f0e6534defa9102c1b1583eadd826"
|
|
# define BACKTRACE_SUBMISSION_URL "https://submit.backtrace.io/paradise/" BACKTRACE_TOKEN "/minidump"
|
|
# endif // __MASTER
|
|
#elif RSG_DURANGO
|
|
# if __MASTER
|
|
# define BACKTRACE_TOKEN "26221444628213a334170087e91e55aa5daf9219e3285be6844674d9f8e47115"
|
|
# define BACKTRACE_SUBMISSION_URL "https://submit.backtrace.io/paradise/" BACKTRACE_TOKEN "/minidump"
|
|
# else
|
|
# define BACKTRACE_TOKEN "eabd42626dd15b6e5dc704e8b1a8755475054a57e755567057b98189962bdc3e"
|
|
# define BACKTRACE_SUBMISSION_URL "https://submit.backtrace.io/paradise/" BACKTRACE_TOKEN "/minidump"
|
|
# endif // __MASTER
|
|
#elif RSG_PC
|
|
# define BACKTRACE_TOKEN "b7468900ead8ac96224f5ed076abc812690d9a690eb5446d5b880a92343e85df"
|
|
# define BACKTRACE_SUBMISSION_URL "https://submit.backtrace.io/paradise/" BACKTRACE_TOKEN "/minidump"
|
|
#else
|
|
# define BACKTRACE_TOKEN "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
|
# define BACKTRACE_SUBMISSION_URL ""
|
|
#endif // RSG_SCARLETT
|
|
|
|
static GameBacktraceConfig s_backtraceTokenSetter(
|
|
BACKTRACE_TOKEN,
|
|
BACKTRACE_SUBMISSION_URL
|
|
);
|
|
|
|
#endif // BACKTRACE_ENABLED
|