From b2b0813db4a5b61f5588b661a4a1d37f1d09a7c4 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Tue, 5 Feb 2019 10:59:57 +0100 Subject: [PATCH] Loader : Added emulation DLL, working towards this stub compiling, moved loader project to subfolder --- CMakeLists.txt | 6 +- projects/CxbxEmulator/CMakeLists.txt | 173 ++++++++++++++++++++++++++ projects/CxbxLoader/CMakeLists.txt | 2 +- src/Cxbx.h | 2 +- src/common/Logging.h | 4 +- src/emulator/CxbxEmulator.cpp | 170 +++++++++++++++++++++++++ src/emulator/dllmain.cpp | 55 ++++++++ src/emulator/targetver.h | 8 ++ src/{CxbxLoader => loader}/loader.cpp | 0 9 files changed, 415 insertions(+), 5 deletions(-) create mode 100644 projects/CxbxEmulator/CMakeLists.txt create mode 100644 src/emulator/CxbxEmulator.cpp create mode 100644 src/emulator/dllmain.cpp create mode 100644 src/emulator/targetver.h rename src/{CxbxLoader => loader}/loader.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa0349dc1..a0601210c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ file (GLOB CXBXR_HEADER_GUIv1 # Emulator (module) file (GLOB CXBXR_HEADER_EMU + "${CXBXR_ROOT_DIR}/src/common/AddressRanges.h" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/glextensions.h" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen.h" "${CXBXR_ROOT_DIR}/src/common/XADPCM.h" @@ -261,6 +262,7 @@ file (GLOB CXBXR_KRNL_CPP file (GLOB CXBXR_SOURCE_EMU "${CXBXR_KRNL_CPP}" "${CXBXR_ROOT_DIR}/HighPerformanceGraphicsEnabler.c" + "${CXBXR_ROOT_DIR}/src/common/LoaderTooling.cpp" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/glextensions.cpp" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_common.cpp" "${CXBXR_ROOT_DIR}/src/common/util/gloffscreen/gloffscreen_wgl.cpp" @@ -368,6 +370,8 @@ add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/cxbx") add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/CxbxLoader") +add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/CxbxEmulator") + # Issues with compile (the same with develop branch) and # for some reason did not put the files into virtual folder? # Might need to put the list in the source folder for workaround fix. @@ -397,6 +401,6 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])") endif() # Cxbx-Reloaded project with third-party libraries -set_target_properties(cxbx subhook XbSymbolDatabase libtommath libtomcrypt +set_target_properties(cxbx CxbxLoader CxbxEmulator subhook XbSymbolDatabase libtommath libtomcrypt PROPERTIES FOLDER Cxbx-Reloaded ) diff --git a/projects/CxbxEmulator/CMakeLists.txt b/projects/CxbxEmulator/CMakeLists.txt new file mode 100644 index 000000000..8dcfde4a6 --- /dev/null +++ b/projects/CxbxEmulator/CMakeLists.txt @@ -0,0 +1,173 @@ +cmake_minimum_required (VERSION 3.12) +project(CxbxEmulator) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 17) + +# Suppress extra stuff from generated solution +set(CMAKE_SUPPRESS_REGENERATION true) + +# Force exclude default libraries being included +#set(CMAKE_CXX_STANDARD_LIBRARIES "") + +include_directories( + "${CXBXR_ROOT_DIR}/src" + "${CXBXR_ROOT_DIR}/src/common" + "${CXBXR_ROOT_DIR}/src/common/Win32" + "${CXBXR_ROOT_DIR}/import/OpenXDK/include" + "${CXBXR_ROOT_DIR}/import/distorm/include" + "${CXBXR_ROOT_DIR}/import/glew-2.0.0/include" + "${CXBXR_ROOT_DIR}/import/subhook" + "${CXBXR_ROOT_DIR}/import/DirectX9/include" + "${CXBXR_ROOT_DIR}/import/XbSymbolDatabase" + "${CXBXR_ROOT_DIR}/import/simpleini" + "${CXBXR_ROOT_DIR}/import/libtommath" + "${CXBXR_ROOT_DIR}/import/libtomcrypt/src/headers" + "${CXBXR_ROOT_DIR}/import/winpcap/Include" +) + +link_directories( + "${CXBXR_ROOT_DIR}/import/distorm/lib/Win32" + "${CXBXR_ROOT_DIR}/import/glew-2.0.0/lib/Release/Win32" + "${CXBXR_ROOT_DIR}/import/DirectX9/lib" + "${CXBXR_ROOT_DIR}/import/winpcap/Lib" +) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + add_compile_definitions( + _CRT_SECURE_NO_WARNINGS + # Windows 7 minimum requirement + _WIN32_WINNT=0x0601 + LTM_DESC + USE_LTM + LTC_NO_TEST + LTC_NO_CIPHERS + LTC_NO_HASHES + LTC_NO_MACS + LTC_NO_PRNGS + LTC_NO_MISC + LTC_NO_PROTOTYPES + + # Use inline XXHash version + XXH_INLINE_ALL + ) + add_compile_options( + /EHs + /MP + /GF + /arch:SSE2 + ) +endif() + +add_compile_definitions( + NOMINMAX + CXBXEMULATOR_EXPORTS +) + +file (GLOB RESOURCES + "${CXBXR_ROOT_DIR}/CONTRIBUTORS" + "${CXBXR_ROOT_DIR}/COPYING" + "${CXBXR_ROOT_DIR}/README.md" +) + +source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES + ${CXBXR_HEADER_GUIv1} + ${CXBXR_HEADER_COMMON} + ${CXBXR_HEADER_EMU} + "${CXBXR_ROOT_DIR}/src/emulator/targetver.h" +) + +source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX source FILES + ${CXBXR_SOURCE_GUIv1} + ${CXBXR_SOURCE_COMMON} + ${CXBXR_SOURCE_EMU} + "${CXBXR_ROOT_DIR}/src/emulator/CxbxEmulator.cpp" + "${CXBXR_ROOT_DIR}/src/emulator/dllmain.cpp" +) + +source_group(TREE ${CXBXR_ROOT_DIR} FILES ${RESOURCES}) + +add_library(CxbxEmulator SHARED ${RESOURCES} + ${CXBXR_HEADER_COMMON} + ${CXBXR_HEADER_EMU} + "${CXBXR_ROOT_DIR}/src/emulator/targetver.h" + ${CXBXR_SOURCE_COMMON} + ${CXBXR_SOURCE_EMU} + ${CXBXR_GIT_VERSION_H} + "${CXBXR_ROOT_DIR}/src/emulator/CxbxEmulator.cpp" + "${CXBXR_ROOT_DIR}/src/emulator/dllmain.cpp" +) + +# Link and compile flags +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + set_target_properties(CxbxEmulator PROPERTIES + LINK_FLAGS " + /INCREMENTAL:NO + /LARGEADDRESSAWARE + /SAFESEH:NO + /STACK:65536,65536 + /NODEFAULTLIB:libcmt + /DELAYLOAD:wpcap.dll + " + LINK_FLAGS_RELEASE " + /LTCG + /DEBUG + " + ) + + # Set optimization options for release build + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} + /Zi + /Ob2 + /Oi + /Ot + /GL + + /GS- + /Gy + /Qpar + " + ) +endif() + +# Windows libraries +set(WINS_LIB + legacy_stdio_definitions + d3d9 + d3dcompiler + dinput8 + dxguid + odbc32 + odbccp32 + Shlwapi + dxerr9 + ws2_32 + dsound + winmm + ddraw + d3dx9 + dbghelp + comctl32 + XINPUT9_1_0 + Iphlpapi + wpcap +) + +target_link_libraries(CxbxEmulator + PUBLIC XbSymbolDatabase + subhook + libtomcrypt + SDL2 + + ${WINS_LIB} +) + +add_dependencies(CxbxEmulator CxbxLoader) + +set(CXBXR_GLEW_DLL "${CXBXR_ROOT_DIR}/import/glew-2.0.0/bin/Release/Win32/glew32.dll") + +# Copy glew32.dll to build type's folder after build. +add_custom_command(TARGET CxbxEmulator POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CXBXR_GLEW_DLL} $ +) diff --git a/projects/CxbxLoader/CMakeLists.txt b/projects/CxbxLoader/CMakeLists.txt index d99e598a0..677b18d2d 100644 --- a/projects/CxbxLoader/CMakeLists.txt +++ b/projects/CxbxLoader/CMakeLists.txt @@ -30,7 +30,7 @@ file (GLOB HEADERS file (GLOB SOURCES "${CXBXR_ROOT_DIR}/src/common/LoaderTooling.cpp" "${CXBXR_ROOT_DIR}/src/common/ReserveAddressRanges.cpp" - "${CXBXR_ROOT_DIR}/src/CxbxLoader/loader.cpp" + "${CXBXR_ROOT_DIR}/src/loader/loader.cpp" ) source_group(TREE ${CXBXR_ROOT_DIR}/src PREFIX header FILES ${HEADERS}) diff --git a/src/Cxbx.h b/src/Cxbx.h index 476d8a6f2..348c4404b 100644 --- a/src/Cxbx.h +++ b/src/Cxbx.h @@ -27,7 +27,7 @@ #include -//#define FUNC_EXPORTS __pragma(comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)) +#define FUNC_EXPORTS __pragma(comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)) /*! xbaddr is the type of a physical address */ typedef uint32_t xbaddr; diff --git a/src/common/Logging.h b/src/common/Logging.h index 471c1892b..d733937e8 100644 --- a/src/common/Logging.h +++ b/src/common/Logging.h @@ -239,8 +239,8 @@ constexpr const char* remove_prefix(const char* str, const char *prefix) { return (str_skip_prefix(str, prefix) == str + str_length(prefix)) ? str_skip_prefix(str, prefix) : str; } -constexpr char* xtl_prefix = "XTL::"; -constexpr char* emupatch_prefix = "EmuPatch_"; // See #define EMUPATCH +static const char* xtl_prefix = "XTL::"; +static const char* emupatch_prefix = "EmuPatch_"; // See #define EMUPATCH constexpr const char* remove_emupatch_prefix(const char* str) { // return an empty string when str isn't given diff --git a/src/emulator/CxbxEmulator.cpp b/src/emulator/CxbxEmulator.cpp new file mode 100644 index 000000000..b67715179 --- /dev/null +++ b/src/emulator/CxbxEmulator.cpp @@ -0,0 +1,170 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx 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 2 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 recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2017-2019 Patrick van Logchem +// * +// * All rights reserved +// * +// ****************************************************************** + +// CxbxEmulator.cpp : Defines the exported functions for the DLL application. + +#include "Cxbx.h" // For FUNC_EXPORTS +//#include "CxbxKrnl/CxbxKrnl.h" +//#include "CxbxKrnl/Emu.h" +#include "EmuShared.h" +//#include + +PCHAR* +CommandLineToArgvA( + PCHAR CmdLine, + int* _argc +) +{ + PCHAR* argv; + PCHAR _argv; + ULONG len; + ULONG argc; + CHAR a; + ULONG i, j; + + BOOLEAN in_QM; + BOOLEAN in_TEXT; + BOOLEAN in_SPACE; + + len = strlen(CmdLine); + i = ((len + 2) / 2) * sizeof(PVOID) + sizeof(PVOID); + + argv = (PCHAR*)LocalAlloc(GMEM_FIXED, + i + (len + 2) * sizeof(CHAR)); + + _argv = (PCHAR)(((PUCHAR)argv) + i); + + argc = 0; + argv[argc] = _argv; + in_QM = FALSE; + in_TEXT = FALSE; + in_SPACE = TRUE; + i = 0; + j = 0; + + while (a = CmdLine[i]) { + if (in_QM) { + if (a == '\"') { + in_QM = FALSE; + } + else { + _argv[j] = a; + j++; + } + } + else { + switch (a) { + case '\"': + in_QM = TRUE; + in_TEXT = TRUE; + if (in_SPACE) { + argv[argc] = _argv + j; + argc++; + } + in_SPACE = FALSE; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if (in_TEXT) { + _argv[j] = '\0'; + j++; + } + in_TEXT = FALSE; + in_SPACE = TRUE; + break; + default: + in_TEXT = TRUE; + if (in_SPACE) { + argv[argc] = _argv + j; + argc++; + } + _argv[j] = a; + j++; + in_SPACE = FALSE; + break; + } + } + i++; + } + _argv[j] = '\0'; + argv[argc] = NULL; + + (*_argc) = argc; + return argv; +} + +#define CXBX_BASE_ADDR 0x00010000 + +DWORD WINAPI Emulate() +{ + FUNC_EXPORTS + + /*! verify Cxbx-Loader.exe is loaded to base address 0x00010000 */ + if ((UINT_PTR)GetModuleHandle(nullptr) != CXBX_BASE_ADDR) { + /*! CXBX_BASE_ADDR is defined as 0x00010000, which is the base address of + the Cxbx-Loader.exe host executable. + Set in Cxbx-Loader.exe Project options, Linker, Advanced, Base Address */ + MessageBox(NULL, "Cxbx-Loader.exe was not loaded to base address 0x00010000 (which is a requirement for Xbox emulation)", "Cxbx-Reloaded", MB_OK); + return 1; + } + + /* Initialize Cxbx File Paths */ +// CxbxInitFilePaths(); + + /*! initialize shared memory */ + if (!EmuShared::Init(0)) { + MessageBox(NULL, "Could not map shared memory!", "Cxbx-Reloaded", MB_OK); + return 1; + } + + LPSTR CommandLine = GetCommandLine(); + int argc; + PCHAR *argv = CommandLineToArgvA(CommandLine, &argc); + +// CxbxKrnlMain(argc, argv); + + LocalFree(argv); + + /*! cleanup shared memory */ + EmuShared::Cleanup(); + + // Note : Emulate() must never return to it's caller (rawMain() in loader.cpp), + // because that function resides in a block of memory that's overwritten with + // xbox executable contents. Returning there would lead to undefined behaviour. + // Since we're done emulating, it's al right to terminate here : + TerminateProcess(GetCurrentProcess(), 0); // s/0/EXIT_? + return -1; // TODO : ERROR_? +} diff --git a/src/emulator/dllmain.cpp b/src/emulator/dllmain.cpp new file mode 100644 index 000000000..58510903c --- /dev/null +++ b/src/emulator/dllmain.cpp @@ -0,0 +1,55 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx 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 2 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 recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2017-2019 Patrick van Logchem +// * +// * All rights reserved +// * +// ****************************************************************** + +#include "EmuShared.h" // For hActiveModule + +// The entry point for the DLL application. +BOOL APIENTRY DllMain(HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved +) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + hActiveModule = hModule; // For shared code + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/src/emulator/targetver.h b/src/emulator/targetver.h new file mode 100644 index 000000000..90e767bfc --- /dev/null +++ b/src/emulator/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/src/CxbxLoader/loader.cpp b/src/loader/loader.cpp similarity index 100% rename from src/CxbxLoader/loader.cpp rename to src/loader/loader.cpp