Compare commits
3 Commits
528a22d86f
...
3346400775
Author | SHA1 | Date |
---|---|---|
Mr-Wiseguy | 3346400775 | |
Wiseguy | c90434962f | |
Wiseguy | 9981b922dc |
|
@ -1 +1 @@
|
||||||
Subproject commit ce68e96c171f7f036e29f539e22a604da04af824
|
Subproject commit 47feaaaa0da5b5f80e90b9daca144a4141b641b8
|
|
@ -416,8 +416,123 @@ namespace zelda64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
struct PreloadContext {
|
||||||
|
HANDLE handle;
|
||||||
|
HANDLE mapping_handle;
|
||||||
|
SIZE_T size;
|
||||||
|
PVOID view;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool preload_executable(PreloadContext& context) {
|
||||||
|
wchar_t module_name[MAX_PATH];
|
||||||
|
GetModuleFileNameW(NULL, module_name, MAX_PATH);
|
||||||
|
|
||||||
|
context.handle = CreateFileW(module_name, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
if (context.handle == INVALID_HANDLE_VALUE) {
|
||||||
|
fprintf(stderr, "Failed to load executable into memory!");
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LARGE_INTEGER module_size;
|
||||||
|
if (!GetFileSizeEx(context.handle, &module_size)) {
|
||||||
|
fprintf(stderr, "Failed to get size of executable!");
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.size = module_size.QuadPart;
|
||||||
|
|
||||||
|
context.mapping_handle = CreateFileMappingW(context.handle, nullptr, PAGE_READONLY, 0, 0, nullptr);
|
||||||
|
if (context.mapping_handle == nullptr) {
|
||||||
|
fprintf(stderr, "Failed to create file mapping of executable!");
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.view = MapViewOfFile(context.mapping_handle, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
if (context.view == nullptr) {
|
||||||
|
fprintf(stderr, "Failed to map view of of executable!");
|
||||||
|
CloseHandle(context.mapping_handle);
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD pid = GetCurrentProcessId();
|
||||||
|
HANDLE process_handle = OpenProcess(PROCESS_SET_QUOTA | PROCESS_QUERY_INFORMATION, FALSE, pid);
|
||||||
|
if (process_handle == nullptr) {
|
||||||
|
fprintf(stderr, "Failed to open own process!");
|
||||||
|
CloseHandle(context.mapping_handle);
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIZE_T minimum_set_size, maximum_set_size;
|
||||||
|
if (!GetProcessWorkingSetSize(process_handle, &minimum_set_size, &maximum_set_size)) {
|
||||||
|
fprintf(stderr, "Failed to get working set size!");
|
||||||
|
CloseHandle(context.mapping_handle);
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetProcessWorkingSetSize(process_handle, minimum_set_size + context.size, maximum_set_size + context.size)) {
|
||||||
|
fprintf(stderr, "Failed to set working set size!");
|
||||||
|
CloseHandle(context.mapping_handle);
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VirtualLock(context.view, context.size) == 0) {
|
||||||
|
fprintf(stderr, "Failed to lock view of executable! (Error: %08lx)\n", GetLastError());
|
||||||
|
CloseHandle(context.mapping_handle);
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_preload(PreloadContext& context) {
|
||||||
|
VirtualUnlock(context.view, context.size);
|
||||||
|
CloseHandle(context.mapping_handle);
|
||||||
|
CloseHandle(context.handle);
|
||||||
|
context = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct PreloadContext {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO implement on other platforms
|
||||||
|
bool preload_executable(PreloadContext& context) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release_preload(PreloadContext& context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
// Map this executable into memory and lock it, which should keep it in physical memory. This ensures
|
||||||
|
// that there are no stutters from the OS having to load new pages of the executable whenever a new code page is run.
|
||||||
|
PreloadContext preload_context;
|
||||||
|
bool preloaded = preload_executable(preload_context);
|
||||||
|
|
||||||
|
if (!preloaded) {
|
||||||
|
fprintf(stderr, "Failed to preload executable!\n");
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Set up console output to accept UTF-8 on windows
|
// Set up console output to accept UTF-8 on windows
|
||||||
|
@ -518,5 +633,9 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
NFD_Quit();
|
NFD_Quit();
|
||||||
|
|
||||||
|
if (preloaded) {
|
||||||
|
release_preload(preload_context);
|
||||||
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
#include "librecomp/game.hpp"
|
#include "librecomp/game.hpp"
|
||||||
|
|
||||||
void zelda64::register_patches() {
|
void zelda64::register_patches() {
|
||||||
recomp::overlays::register_patches(mm_patches_bin, sizeof(mm_patches_bin), section_table);
|
recomp::overlays::register_patches(mm_patches_bin, sizeof(mm_patches_bin), section_table, ARRLEN(section_table));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue