diff --git a/src/plugins/gta3/std.asi/ModuleInfo.cpp b/src/plugins/gta3/std.asi/ModuleInfo.cpp index 94042b3..0a84edf 100644 --- a/src/plugins/gta3/std.asi/ModuleInfo.cpp +++ b/src/plugins/gta3/std.asi/ModuleInfo.cpp @@ -518,56 +518,107 @@ extern const char aWritePrivateProfileStructA[] = "WritePrivateProfileStructA"; extern const char aGetFileAttributesA[] = "GetFileAttributesA"; extern const char aGetFileAttributesExA[] = "GetFileAttributesExA"; +extern const char aCreateFileW[] = "CreateFileW"; +extern const char aLoadLibraryW[] = "LoadLibraryW"; +extern const char aLoadLibraryExW[] = "LoadLibraryExW"; +extern const char aGetModuleFileNameW[] = "GetModuleFileNameW"; +extern const char aFindFirstFileW[] = "FindFirstFileW"; +extern const char aFindNextFileW[] = "FindNextFileW"; +extern const char aSetCurrentDirectoryW[] = "SetCurrentDirectoryW"; +extern const char aGetPrivateProfileIntW[] = "GetPrivateProfileIntW"; +extern const char aGetPrivateProfileSectionW[] = "GetPrivateProfileSectionW"; +extern const char aGetPrivateProfileSectionNamesW[] = "GetPrivateProfileSectionNamesW"; +extern const char aGetPrivateProfileStringW[] = "GetPrivateProfileStringW"; +extern const char aGetPrivateProfileStructW[] = "GetPrivateProfileStructW"; +extern const char aWritePrivateProfileSectionW[] = "WritePrivateProfileSectionW"; +extern const char aWritePrivateProfileStringW[] = "WritePrivateProfileStringW"; +extern const char aWritePrivateProfileStructW[] = "WritePrivateProfileStructW"; +extern const char aGetFileAttributesW[] = "GetFileAttributesW"; +extern const char aGetFileAttributesExW[] = "GetFileAttributesExW"; + // Operations -static path_translator_stdcall +static path_translator_stdcall psCreateFileA(0, AR_PATH_INE, 0, 0, 0, 0, 0, 0); -static path_translator_stdcall +static path_translator_stdcall psSetCurrentDirectoryA(0, AR_PATH_INE); // Do not work properly!! Don't use!!! - +static path_translator_stdcall + psCreateFileW(0, AR_PATH_INE, 0, 0, 0, 0, 0, 0); +static path_translator_stdcall + psSetCurrentDirectoryW(0, AR_PATH_INE); // Do not work properly!! Don't use!!! // File finding (used mostly to hack CLEO.asi) -static path_translator_stdcall +static path_translator_stdcall psFindFirstFileA(0, AR_PATH_INEB, 0); static path_translator_stdcall // Hack CLEO.asi psFindNextFileA(0, 0, 0); +static path_translator_stdcall + psFindFirstFileW(0, AR_PATH_INEB, 0); +static path_translator_stdcall // Hack CLEO.asi + psFindNextFileW(0, 0, 0); static path_translator_stdcall // Hack CLEO.asi psFindClose(0, 0); // Library routines -static path_translator_stdcall +static path_translator_stdcall psGetModuleFileNameA(0, 0, 0, 0); // I'll need to intercept this routine for some Ryosuke's plugins compatibility -static path_translator_stdcall +static path_translator_stdcall psLoadLibraryA(0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psLoadLibraryExA(0, AR_PATH_INE, 0, 0); +static path_translator_stdcall + psGetModuleFileNameW(0, 0, 0, 0); // I'll need to intercept this routine for some Ryosuke's plugins compatibility +static path_translator_stdcall + psLoadLibraryW(0, AR_PATH_INE); +static path_translator_stdcall + psLoadLibraryExW(0, AR_PATH_INE, 0, 0); // Get from INI -static path_translator_stdcall +static path_translator_stdcall psGetPrivateProfileIntA(0, 0, 0, 0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psGetPrivateProfileSectionA(0, 0, 0, 0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psGetPrivateProfileSectionNamesA(0, 0, 0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psGetPrivateProfileStringA(0, 0, 0, 0, 0, 0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psGetPrivateProfileStructA(0, 0, 0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psGetPrivateProfileIntW(0, 0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psGetPrivateProfileSectionW(0, 0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psGetPrivateProfileSectionNamesW(0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psGetPrivateProfileStringW(0, 0, 0, 0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psGetPrivateProfileStructW(0, 0, 0, 0, 0, AR_PATH_INE); // Write to INI -static path_translator_stdcall +static path_translator_stdcall psWritePrivateProfileSectionA(0, 0, 0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psWritePrivateProfileStringA(0, 0, 0, 0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psWritePrivateProfileStructA(0, 0, 0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psWritePrivateProfileSectionW(0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psWritePrivateProfileStringW(0, 0, 0, 0, AR_PATH_INE); +static path_translator_stdcall + psWritePrivateProfileStructW(0, 0, 0, 0, 0, AR_PATH_INE); // Something -static path_translator_stdcall +static path_translator_stdcall psGetFileAttributesA(0, AR_PATH_INE); -static path_translator_stdcall +static path_translator_stdcall psGetFileAttributesExA(0, AR_PATH_INE, 0, 0); +static path_translator_stdcall + psGetFileAttributesW(0, AR_PATH_INE); +static path_translator_stdcall + psGetFileAttributesExW(0, AR_PATH_INE, 0, 0); @@ -583,19 +634,45 @@ static path_translator_stdcall psfopen(0, AR_PATH_INE, 0); static path_translator_cdecl psfreopen(0, AR_PATH_INE, 0, 0); +static path_translator_cdecl + psfopens(0, 0, AR_PATH_INE, 0); +static path_translator_cdecl + psfreopens(0, 0, AR_PATH_INE, 0, 0); static path_translator_cdecl psrename(0, AR_PATH_INE, AR_PATH_IN); static path_translator_cdecl psremove(0, AR_PATH_INE); +static path_translator_cdecl + pswfopen(0, AR_PATH_INE, 0); +static path_translator_cdecl + pswfreopen(0, AR_PATH_INE, 0, 0); +static path_translator_cdecl + pswfopens(0, 0, AR_PATH_INE, 0); +static path_translator_cdecl + pswfreopens(0, 0, AR_PATH_INE, 0, 0); +static path_translator_cdecl + pswrename(0, AR_PATH_INE, AR_PATH_IN); +static path_translator_cdecl + pswremove(0, AR_PATH_INE); + /* @@ -612,7 +689,14 @@ extern const char aD3DXLoadMeshFromXA[] = "D3DXLoadMeshFromXA"; extern const char aD3DXCreateEffectFromFileA[] = "D3DXCreateEffectFromFileA"; extern const char aD3DXSaveSurfaceToFileA[] = "D3DXSaveSurfaceToFileA"; +extern const char aD3DXCreateTextureFromFileW[] = "D3DXCreateTextureFromFileW"; +extern const char aD3DXCompileShaderFromFileW[] = "D3DXCompileShaderFromFileW"; +extern const char aD3DXAssembleShaderFromFileW[] = "D3DXAssembleShaderFromFileW"; +extern const char aD3DXCreateVolumeTextureFromFileW[] = "D3DXCreateVolumeTextureFromFileW"; +extern const char aD3DXCreateCubeTextureFromFileW[] = "D3DXCreateCubeTextureFromFileW"; +extern const char aD3DXLoadMeshFromXW[] = "D3DXLoadMeshFromXW"; extern const char aD3DXCreateEffectFromFileW[] = "D3DXCreateEffectFromFileW"; +extern const char aD3DXSaveSurfaceToFileW[] = "D3DXSaveSurfaceToFileW"; @@ -635,8 +719,23 @@ static path_translator_stdcall psD3DXSaveSurfaceToFileA(0, AR_PATH_IN, 0, 0, 0, 0); +static path_translator_stdcall + psD3DXCreateTextureFromFileW(0, 0, AR_PATH_INE, 0); +static path_translator_stdcall + psD3DXCompileShaderFromFileW(0, AR_PATH_INE, 0, 0, 0, 0, 0, 0, 0, 0); +static path_translator_stdcall + psD3DXAssembleShaderFromFileW(0, AR_PATH_INE, 0, 0, 0, 0, 0); + +static path_translator_stdcall + psD3DXCreateVolumeTextureFromFileW(0, 0, AR_PATH_INE, 0); +static path_translator_stdcall + psD3DXCreateCubeTextureFromFileW(0, 0, AR_PATH_INE, 0); +static path_translator_stdcall + psD3DXLoadMeshFromXW(0, AR_PATH_INE, 0, 0, 0, 0, 0, 0, 0); static path_translator_stdcall psD3DXCreateEffectFromFileW(0, 0, AR_PATH_INE, 0, 0, 0, 0, 0, 0); +static path_translator_stdcall + psD3DXSaveSurfaceToFileW(0, AR_PATH_IN, 0, 0, 0, 0); diff --git a/src/plugins/gta3/std.asi/args_translator/translator_basic.hpp b/src/plugins/gta3/std.asi/args_translator/translator_basic.hpp index 1939c21..352539a 100644 --- a/src/plugins/gta3/std.asi/args_translator/translator_basic.hpp +++ b/src/plugins/gta3/std.asi/args_translator/translator_basic.hpp @@ -288,29 +288,37 @@ struct path_translator_base static const bool bIsWideChar = std::is_same::value; // Character independent strings - static const T a1[] = { '%', 's', '\0' }; // "%s" - static const T a2[] = { '%', 's', '\\', '%', 's', '\0' }; // "%s\\%s" - static const T a3[] = { '%', 's', '\\', '%', 's', '\\', // "%s\\%s\\%s" or "%s\\%s\\%ls" - '%', bIsWideChar? 'l' : 's', bIsWideChar? 's' : '\0', + // This got broken badly for wchar_t overload with Visual Studio 2015! + // swprintf %s will expect wchar_t* once again so we need to force char* by passing %hs + // See here: + // https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/ + static const T a1[] = { '%', 'h', 's', '\0' }; // "%hs" + static const T a2[] = { '%', 'h', 's', '\\', '%', 'h', 's', '\0' }; // "%hs\\%hs" + static const T a3[] = { '%', 'h', 's', '\\', '%', 'h', 's', '\\', // "%hs\\%hs\\%hs" or "%hs\\%hs\\%ls" + '%', bIsWideChar? 'l' : 'h', 's', '\0' }; - static const T a0[] = { '%', 's', '\\', // "%s\\%s" or "%s\\%ls" - '%', bIsWideChar? 'l' : 's', bIsWideChar? 's' : '\0', + static const T a0[] = { '%', 'h', 's', '\\', // "%hs\\%hs" or "%hs\\%ls" + '%', bIsWideChar? 'l' : 'h', 's', '\0' }; + + #ifndef _MSC_VER + #error Please check if printf formats in TranslatePathChar are compatible on this compiler! + #endif // Build output string based on received prefixes / suffixes / whatever if(currdir) { if(suffix) - sprintf(out, a3, prefix, currdir, suffix); // "%s\\%s\\%s" or "%s\\%s\\%ls" + sprintf(out, a3, prefix, currdir, suffix); // "%hs\\%hs\\%hs" or "%hs\\%hs\\%ls" else - sprintf(out, a2, prefix, currdir); // "%s\\%s" + sprintf(out, a2, prefix, currdir); // "%hs\\%hs" } else { if(suffix) - sprintf(out, a0, prefix, suffix); // "%s\\%s" or "%s\\%ls" + sprintf(out, a0, prefix, suffix); // "%hs\\%hs" or "%hs\\%ls" else - sprintf(out, a1, prefix); // "%s" + sprintf(out, a1, prefix); // "%hs" } // Done @@ -449,11 +457,11 @@ struct path_translator_basic : public path_translator_base if(LibName == aKernel32) { - bGetModuleFileName = (Symbol == aGetModuleFileNameA); - bSetCurrentDirectory=(Symbol == aSetCurrentDirectoryA); - bCreateFile = (Symbol == aCreateFileA); - bFindFirstFile = (Symbol == aFindFirstFileA); - bFindNextFile = (Symbol == aFindNextFileA); + bGetModuleFileName = (Symbol == aGetModuleFileNameA) || (Symbol == aGetModuleFileNameW); + bSetCurrentDirectory=(Symbol == aSetCurrentDirectoryA) || (Symbol == aSetCurrentDirectoryW); + bCreateFile = (Symbol == aCreateFileA) || (Symbol == aCreateFileW); + bFindFirstFile = (Symbol == aFindFirstFileA) || (Symbol == aFindFirstFileW); + bFindNextFile = (Symbol == aFindNextFileA) || (Symbol == aFindNextFileW); bFindClose = (Symbol == aFindClose); bIniOperations = false; } diff --git a/src/plugins/gta3/std.asi/args_translator/xtranslator.hpp b/src/plugins/gta3/std.asi/args_translator/xtranslator.hpp index a185240..0862d17 100644 --- a/src/plugins/gta3/std.asi/args_translator/xtranslator.hpp +++ b/src/plugins/gta3/std.asi/args_translator/xtranslator.hpp @@ -19,6 +19,12 @@ extern const char aFindFirstFileA[]; extern const char aFindNextFileA[]; extern const char aFindClose[]; +extern const char aCreateFileW[]; +extern const char aSetCurrentDirectoryW[]; +extern const char aGetModuleFileNameW[]; +extern const char aFindFirstFileW[]; +extern const char aFindNextFileW[]; + // Argument type enum eArgsType { diff --git a/src/plugins/gta3/std.stream/backend.cpp b/src/plugins/gta3/std.stream/backend.cpp index eeebfc1..86720da 100644 --- a/src/plugins/gta3/std.stream/backend.cpp +++ b/src/plugins/gta3/std.stream/backend.cpp @@ -398,6 +398,10 @@ void CAbstractStreaming::Patch() { plugin_ptr->Log("Initializing the streaming..."); + // III/VC reinitialize streaming on reloading + if(!gvm.IsSA()) + this->bHasInitializedStreaming = false; + // Pointers ms_aInfoForModel = ReadMemory(0x40D014, true); LoadCdDirectory2 = ReadRelativeOffset(0x5B8310 + 1).get(); @@ -416,13 +420,20 @@ void CAbstractStreaming::Patch() this->BuildPrevOnCdMap(); tmp_cd_dir.clear(); + // Clear imports in case this is not the first launch + this->imports.clear(); + // Do custom setup this->BuildClothesMap(); // Find out clothing hashes and remove clothes from raw_models this->LoadAbstractCdDirectory(refs_mapped(raw_models)); // Load abstract directory, our custom files // Mark streaming as initialized + this->bIsFirstLaunched = true; this->bHasInitializedStreaming = true; - this->raw_models.clear(); + + // We can discard it in SA but we still need it in III and VC + if(gvm.IsSA()) + this->raw_models.clear(); }); // Standard models diff --git a/src/plugins/gta3/std.stream/directory.cpp b/src/plugins/gta3/std.stream/directory.cpp index 6b7ed97..270b2fd 100644 --- a/src/plugins/gta3/std.stream/directory.cpp +++ b/src/plugins/gta3/std.stream/directory.cpp @@ -301,7 +301,7 @@ void CAbstractStreaming::LoadAbstractCdDirectory(ref_listbHasInitializedStreaming) + if(this->bIsFirstLaunched) this->FlushChannels(); // Fill entry buffer and advance iterator diff --git a/src/plugins/gta3/std.stream/streaming.cpp b/src/plugins/gta3/std.stream/streaming.cpp index d39bddd..2c1fb0f 100644 --- a/src/plugins/gta3/std.stream/streaming.cpp +++ b/src/plugins/gta3/std.stream/streaming.cpp @@ -27,6 +27,9 @@ CAbstractStreaming::~CAbstractStreaming() void CAbstractStreaming::InitialiseStructAbstraction() { + if(this->bIsFirstLaunched) + return; // We already init this once, no need to do again + this->sizeof_CStreamingInfo = CStreamingInfo::GetSizeof(); this->f92la = Fastman92LimitAdjusterCreate(); diff --git a/src/plugins/gta3/std.stream/streaming.hpp b/src/plugins/gta3/std.stream/streaming.hpp index 20a7f7d..23608dd 100644 --- a/src/plugins/gta3/std.stream/streaming.hpp +++ b/src/plugins/gta3/std.stream/streaming.hpp @@ -127,7 +127,8 @@ class CAbstractStreaming private: LibF92LA f92la; // - bool bHasInitializedStreaming = false; // Has the streaming initialized? + bool bIsFirstLaunched = false; // Required for III/VC which reinitialize streaming every load + bool bHasInitializedStreaming = false; // Has the streaming initialized? bool bIsUpdating = false; // Is updating the streaming (for a future refresh)? CRITICAL_SECTION cs; // This must be used together with imported files list for thread-safety std::string fbuffer; // File buffer to avoid a dynamic allocation everytime we open a model diff --git a/src/shared/f92la/f92la.h b/src/shared/f92la/f92la.h index c8dcb8a..ba35210 100644 --- a/src/shared/f92la/f92la.h +++ b/src/shared/f92la/f92la.h @@ -26,18 +26,15 @@ struct LibF92LA inline LibF92LA Fastman92LimitAdjusterCreate() { LibF92LA f92la; - if(GetModuleHandle("$fastman92limitAdjuster.asi")) + if(GetModuleHandleEx(0, "$fastman92limitAdjuster.asi", &f92la.hLib)) { - if(f92la.hLib = LoadLibraryA("$fastman92limitAdjuster.asi")) - { - f92la.GetNumberOfFileIDs = (decltype(f92la.GetNumberOfFileIDs)) GetProcAddress(f92la.hLib, "GetNumberOfFileIDs"); - f92la.GetFileInfoPrevFileID = (decltype(f92la.GetFileInfoPrevFileID)) GetProcAddress(f92la.hLib, "GetFileInfoPrevFileID"); - f92la.GetFileInfoNextFileID = (decltype(f92la.GetFileInfoNextFileID)) GetProcAddress(f92la.hLib, "GetFileInfoNextFileID"); - f92la.GetFileInfoNextOnCDfileID = (decltype(f92la.GetFileInfoNextOnCDfileID)) GetProcAddress(f92la.hLib, "GetFileInfoNextOnCDfileID"); - f92la.SetFileInfoPrevFileID = (decltype(f92la.SetFileInfoPrevFileID)) GetProcAddress(f92la.hLib, "SetFileInfoPrevFileID"); - f92la.SetFileInfoNextFileID = (decltype(f92la.SetFileInfoNextFileID)) GetProcAddress(f92la.hLib, "SetFileInfoNextFileID"); - f92la.SetFileInfoNextOnCDfileID = (decltype(f92la.SetFileInfoNextOnCDfileID)) GetProcAddress(f92la.hLib, "SetFileInfoNextOnCDfileID"); - } + f92la.GetNumberOfFileIDs = (decltype(f92la.GetNumberOfFileIDs)) GetProcAddress(f92la.hLib, "GetNumberOfFileIDs"); + f92la.GetFileInfoPrevFileID = (decltype(f92la.GetFileInfoPrevFileID)) GetProcAddress(f92la.hLib, "GetFileInfoPrevFileID"); + f92la.GetFileInfoNextFileID = (decltype(f92la.GetFileInfoNextFileID)) GetProcAddress(f92la.hLib, "GetFileInfoNextFileID"); + f92la.GetFileInfoNextOnCDfileID = (decltype(f92la.GetFileInfoNextOnCDfileID)) GetProcAddress(f92la.hLib, "GetFileInfoNextOnCDfileID"); + f92la.SetFileInfoPrevFileID = (decltype(f92la.SetFileInfoPrevFileID)) GetProcAddress(f92la.hLib, "SetFileInfoPrevFileID"); + f92la.SetFileInfoNextFileID = (decltype(f92la.SetFileInfoNextFileID)) GetProcAddress(f92la.hLib, "SetFileInfoNextFileID"); + f92la.SetFileInfoNextOnCDfileID = (decltype(f92la.SetFileInfoNextOnCDfileID)) GetProcAddress(f92la.hLib, "SetFileInfoNextOnCDfileID"); } return f92la; }