Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion UnleashedRecomp/gpu/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ static constexpr RenderFormat BACKBUFFER_FORMAT = RenderFormat::B8G8R8A8_UNORM;
static std::unique_ptr<RenderCommandSemaphore> g_acquireSemaphores[NUM_FRAMES];
static std::unique_ptr<RenderCommandSemaphore> g_renderSemaphores[NUM_FRAMES];
static uint32_t g_backBufferIndex;
static std::unique_ptr<GuestSurface> g_backBufferHolder;
static GuestSurface* g_backBuffer;

static std::unique_ptr<RenderTexture> g_intermediaryBackBufferTexture;
Expand Down Expand Up @@ -1968,7 +1969,10 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver)
desc.renderTargetCount = 1;
g_gammaCorrectionPipeline = g_device->createGraphicsPipeline(desc);

g_backBuffer = g_userHeap.AllocPhysical<GuestSurface>(ResourceType::RenderTarget);
// NOTE: We initially allocate this on host memory to make the installer work, even if the 4 GB memory allocation fails.
g_backBufferHolder = std::make_unique<GuestSurface>(ResourceType::RenderTarget);

g_backBuffer = g_backBufferHolder.get();
g_backBuffer->width = 1280;
g_backBuffer->height = 720;
g_backBuffer->format = BACKBUFFER_FORMAT;
Expand Down Expand Up @@ -2026,6 +2030,17 @@ static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
LoadTexture((uint8_t *)achievement.pImageBuffer, achievement.ImageBufferSize).release();
}

// Move backbuffer to guest memory.
assert(!g_memory.IsInMemoryRange(g_backBuffer) && g_backBufferHolder != nullptr);
g_backBuffer = g_userHeap.AllocPhysical<GuestSurface>(std::move(*g_backBufferHolder));

// Check for stale reference. BeginCommandList() gets called before CreateDevice() which is where the assignment happens.
if (g_renderTarget == g_backBufferHolder.get()) g_renderTarget = g_backBuffer;
if (g_depthStencil == g_backBufferHolder.get()) g_depthStencil = g_backBuffer;

// Free the host backbuffer.
g_backBufferHolder = nullptr;

auto device = g_userHeap.AllocPhysical<GuestDevice>();
memset(device, 0, sizeof(*device));

Expand Down
6 changes: 6 additions & 0 deletions UnleashedRecomp/kernel/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Memory::Memory()
if (base == nullptr)
base = (uint8_t*)VirtualAlloc(nullptr, PPC_MEMORY_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

if (base == nullptr)
return;

DWORD oldProtect;
VirtualProtect(base, 4096, PAGE_NOACCESS, &oldProtect);
#else
Expand All @@ -17,6 +20,9 @@ Memory::Memory()
if (base == (uint8_t*)MAP_FAILED)
base = (uint8_t*)mmap(NULL, PPC_MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);

if (base == nullptr)
return;

mprotect(base, 4096, PROT_NONE);
#endif

Expand Down
11 changes: 11 additions & 0 deletions UnleashedRecomp/locale/locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,17 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>>
{ ELanguage::Italian, "Impossibile trovare il modulo \"%s\".\n\nAssicurati che:\n\n- Hai estratto questa copia di Unleashed Recompiled correttamente e non solo il file *.exe.\n- Non stai eseguendo Unleashed Recompiled da un file *.zip." }
}
},
{
"System_MemoryAllocationFailed",
{
{ ELanguage::English, "Failed to allocate game memory.\n\nPlease make sure that:\n\n- You meet the minimum system requirements (8 GB).\n- Your page file is configured with at least 4-8 GB of virtual memory." },
{ ELanguage::Japanese, "ゲームメモリの割り当てに失敗しました\n\n次の点を確認してください:\n\n※最小システム要件(8 GB)を満たしていること。\n※ページファイルに少なくとも4~8 GBの仮想メモリが設定されていること" },
{ ELanguage::German, "Fehler beim Zuweisen des Spielspeichers.\n\nBitte stelle sicher, dass:\n\n- Die Mindestanforderungen für das System erfüllt sind (8 GB).\n- Die Auslagerungsdatei mit mindestens 4-8 GB virtuellem Speicher konfiguriert ist." },
{ ELanguage::French, "Échec d'allocation de la mémoire du jeu.\n\nVeuillez vous assurer que :\n\n- Vous disposez de la configuration minimale requise (8 Go).\n- Votre fichier d’échange est configuré avec au moins 4 à 8 Go de mémoire virtuelle." },
{ ELanguage::Spanish, "Fallo al asignar memoria del juego.\n\nPor favor, asegúrate de que:\n\n- Cumples los requisitos mínimos del sistema (8 GB).\n- Tu archivo de páginación está configurado con al menos 4 u 8 GB de memoria virtual." },
{ ELanguage::Italian, "Impossibile allocare la memoria per il gioco.\n\nAssicurati che:\n\n- Soddisfi i requisiti minimi di sistema (8 GB).\n- Il tuo file di paging sia configurato con almeno 4 o 8 GB di memoria virtuale." }
}
},
{
"IntegrityCheck_Success",
{
Expand Down
10 changes: 8 additions & 2 deletions UnleashedRecomp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,20 @@ void HostStartup()
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif

g_userHeap.Init();

hid::Init();
}

// Name inspired from nt's entry point
void KiSystemStartup()
{
if (g_memory.base == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, GameWindow::GetTitle(), Localise("System_MemoryAllocationFailed").c_str(), GameWindow::s_pWindow);
std::_Exit(1);
}

g_userHeap.Init();

const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game");
const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update");
XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game");
Expand Down