mirror of
https://github.com/isledecomp/LEGOIslandRebuilder.git
synced 2025-03-23 19:19:40 -04:00
ported some patches
This commit is contained in:
parent
f5dae0804a
commit
f0904e54b9
12 changed files with 346 additions and 100 deletions
|
@ -11,6 +11,10 @@ option(BUILD_UNICODE "Build with Unicode support" ON)
|
|||
# Build our code injected DLL
|
||||
#
|
||||
add_library(Rebld SHARED
|
||||
cmn/path.cpp
|
||||
cmn/path.h
|
||||
lib/config.cpp
|
||||
lib/config.h
|
||||
lib/dllmain.cpp
|
||||
lib/hooks.cpp
|
||||
lib/hooks.h
|
||||
|
@ -21,7 +25,7 @@ add_library(Rebld SHARED
|
|||
lib/worker.h
|
||||
)
|
||||
target_compile_options(Rebld PRIVATE /MT)
|
||||
target_link_libraries(Rebld PRIVATE winmm.lib)
|
||||
target_link_libraries(Rebld PRIVATE winmm.lib shlwapi.lib)
|
||||
|
||||
# Add property grid
|
||||
set(PROPERTYGRID_BUILD_APP OFF CACHE BOOL "")
|
||||
|
@ -31,6 +35,8 @@ add_subdirectory(ext/PropertyGrid)
|
|||
# Build launcher/configuration executable
|
||||
#
|
||||
add_executable(Rebuilder WIN32
|
||||
cmn/path.cpp
|
||||
cmn/path.h
|
||||
res/res.rc
|
||||
res/resource.h
|
||||
src/app.cpp
|
||||
|
|
11
cmn/combo.h
Normal file
11
cmn/combo.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COMBO_H
|
||||
#define COMBO_H
|
||||
|
||||
enum ModelQuality {
|
||||
kModelQualityInfinite,
|
||||
kModelQualityHigh,
|
||||
kModelQualityMedium,
|
||||
kModelQualityLow
|
||||
};
|
||||
|
||||
#endif // COMBO_H
|
94
cmn/path.cpp
Normal file
94
cmn/path.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "path.h"
|
||||
|
||||
#include <SHLOBJ.H>
|
||||
#include <SHLWAPI.H>
|
||||
#include <STRING>
|
||||
#include <TCHAR.H>
|
||||
|
||||
LPCTSTR appName = TEXT("Rebuilder");
|
||||
|
||||
BOOL DirectoryExists(LPCTSTR szPath)
|
||||
{
|
||||
return PathFileExists(szPath) && PathIsDirectory(szPath);
|
||||
}
|
||||
|
||||
BOOL RecursivelyCreateDirectory(LPCTSTR directory)
|
||||
{
|
||||
if (DirectoryExists(directory)) {
|
||||
// Directory already exists, do nothing
|
||||
return TRUE;
|
||||
} else {
|
||||
// Determine directory of this directory
|
||||
std::basic_string<TCHAR> copy = directory;
|
||||
PathRemoveFileSpec(©[0]);
|
||||
|
||||
// Create if necessary
|
||||
if (RecursivelyCreateDirectory(copy.c_str())) {
|
||||
return CreateDirectory(directory, NULL);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
typedef BOOL (WINAPI *SHGetSpecialFolderPathSignature)(HWND hwndOwner, LPWSTR lpszPath, int nFolder, BOOL fCreate);
|
||||
#else
|
||||
typedef BOOL (WINAPI *SHGetSpecialFolderPathSignature)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
||||
#endif
|
||||
BOOL GetAppDataPath(LPTSTR s)
|
||||
{
|
||||
OSVERSIONINFO info;
|
||||
ZeroMemory(&info, sizeof(info));
|
||||
info.dwOSVersionInfoSize = sizeof(info);
|
||||
GetVersionEx(&info);
|
||||
|
||||
// Dynamically link to SHGetSpecialFolderPath because not all versions of Windows have it
|
||||
#ifdef UNICODE
|
||||
LPCSTR functionName = "SHGetSpecialFolderPathW";
|
||||
#else
|
||||
LPCSTR functionName = "SHGetSpecialFolderPathA";
|
||||
#endif
|
||||
|
||||
SHGetSpecialFolderPathSignature GetSpecialFolderPath = (SHGetSpecialFolderPathSignature)GetProcAddress(GetModuleHandle(_T("SHELL32.DLL")), functionName);
|
||||
BOOL haveDir = FALSE;
|
||||
BOOL usedShell = FALSE;
|
||||
if (GetSpecialFolderPath) {
|
||||
haveDir = GetSpecialFolderPath(NULL, s, CSIDL_APPDATA, TRUE);
|
||||
usedShell = TRUE;
|
||||
} else {
|
||||
// Assume we're on Windows 95 which has no application data folder, we bodge it to write to
|
||||
// "C:\Windows\Application Data" which is roughly where 98/Me would do it
|
||||
GetWindowsDirectory(s, MAX_PATH);
|
||||
_tcscat(s, _T("\\Application Data"));
|
||||
haveDir = TRUE;
|
||||
}
|
||||
|
||||
//MessageBox(0, s, usedShell ? _T("Using API") : _T("Is this Windows 95?"), 0);
|
||||
return haveDir;
|
||||
}
|
||||
|
||||
BOOL GetConfigFilename(LPTSTR s)
|
||||
{
|
||||
if (GetAppDataPath(s)) {
|
||||
_tcscat(s, _T("\\LEGOIslandRebuilder"));
|
||||
if (RecursivelyCreateDirectory(s)) {
|
||||
_tcscat(s, _T("\\settings.ini"));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL GetSafeLEGOIslandSavePath(LPTSTR s)
|
||||
{
|
||||
if (GetAppDataPath(s)) {
|
||||
_tcscat(s, _T("\\LEGO Island"));
|
||||
if (RecursivelyCreateDirectory(s)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
12
cmn/path.h
Normal file
12
cmn/path.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef PATH_H
|
||||
#define PATH_H
|
||||
|
||||
#include <WINDOWS.H>
|
||||
|
||||
BOOL GetSafeLEGOIslandSavePath(LPTSTR s);
|
||||
|
||||
BOOL GetConfigFilename(LPTSTR s);
|
||||
|
||||
extern LPCTSTR appName;
|
||||
|
||||
#endif // PATH_H
|
24
lib/config.cpp
Normal file
24
lib/config.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <SHLWAPI.H>
|
||||
|
||||
#include "../cmn/path.h"
|
||||
|
||||
Config config;
|
||||
|
||||
Config::Config()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL Config::Load()
|
||||
{
|
||||
// Get config file
|
||||
m_configFile.resize(MAX_PATH);
|
||||
return GetConfigFilename(&m_configFile[0]) && PathFileExists(m_configFile.c_str());
|
||||
}
|
||||
|
||||
UINT Config::GetInt(LPCTSTR name, UINT defaultValue)
|
||||
{
|
||||
return GetPrivateProfileInt(appName, name, defaultValue, m_configFile.c_str());
|
||||
}
|
24
lib/config.h
Normal file
24
lib/config.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <STRING>
|
||||
#include <TCHAR.H>
|
||||
#include <WINDOWS.H>
|
||||
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
Config();
|
||||
|
||||
BOOL Load();
|
||||
|
||||
UINT GetInt(LPCTSTR name, UINT defaultValue = 0);
|
||||
|
||||
private:
|
||||
std::basic_string<TCHAR> m_configFile;
|
||||
|
||||
};
|
||||
|
||||
extern Config config;
|
||||
|
||||
#endif // CONFIG_H
|
|
@ -2,19 +2,23 @@
|
|||
|
||||
#include <STDIO.H>
|
||||
|
||||
#include "../cmn/path.h"
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
|
||||
HWND isleWindow = NULL;
|
||||
|
||||
void InterceptOutputDebugStringA(LPCSTR s)
|
||||
{
|
||||
printf("%s\n", s);
|
||||
MessageBoxA(0,s,"LEGO Island sez",0);
|
||||
MessageBoxA(isleWindow, s, "LEGO Island sez", 0);
|
||||
}
|
||||
|
||||
HWND WINAPI InterceptCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
|
||||
{
|
||||
HWND window = CreateWindowExA(dwExStyle, lpClassName, "LEGO Island: Rebuilt", dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
|
||||
return window;
|
||||
// Grab a copy of the ISLE window so we can do stuff with it
|
||||
isleWindow = CreateWindowExA(dwExStyle, lpClassName, "LEGO Island: Rebuilt", dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
return isleWindow;
|
||||
}
|
||||
|
||||
HWND WINAPI InterceptFindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName)
|
||||
|
@ -106,10 +110,71 @@ HRESULT WINAPI InterceptDirectDrawCreate(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUn
|
|||
{
|
||||
HRESULT res = ddCreateOriginal(lpGUID, lplpDD, pUnkOuter);
|
||||
|
||||
if (res == DD_OK && !originalGetDisplayMode) {
|
||||
originalGetDisplayMode = (ddGetDisplayModeFunction)OverwriteVirtualTable(*lplpDD, 0xC, (LPVOID)InterceptGetDisplayMode);
|
||||
originalCreateSurfaceFunction = (ddCreateSurfaceFunction)OverwriteVirtualTable(*lplpDD, 0x6, (LPVOID)InterceptCreateSurface);
|
||||
if (res == DD_OK) {
|
||||
if (!originalGetDisplayMode) {
|
||||
originalGetDisplayMode = (ddGetDisplayModeFunction)OverwriteVirtualTable(*lplpDD, 0xC, (LPVOID)InterceptGetDisplayMode);
|
||||
}
|
||||
|
||||
ddCreateSurfaceFunction f = (ddCreateSurfaceFunction)OverwriteVirtualTable(*lplpDD, 0x6, (LPVOID)InterceptCreateSurface);
|
||||
if (f != InterceptCreateSurface) {
|
||||
originalCreateSurfaceFunction = f;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void ReturnRegistryYESNOFromBool(LPBYTE lpData, BOOL value)
|
||||
{
|
||||
strcpy((char*)lpData, value ? "YES" : "NO");
|
||||
}
|
||||
|
||||
LONG WINAPI InterceptRegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
|
||||
{
|
||||
if (!strcmp(lpValueName, "Music")) {
|
||||
|
||||
// Music option
|
||||
ReturnRegistryYESNOFromBool(lpData, config.GetInt(_T("MusicToggle"), 1));
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
} else if (!strcmp(lpValueName, "UseJoystick")) {
|
||||
|
||||
ReturnRegistryYESNOFromBool(lpData, config.GetInt(_T("UseJoystick"), 0));
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
} else if (!strcmp(lpValueName, "Full Screen")) {
|
||||
|
||||
ReturnRegistryYESNOFromBool(lpData, config.GetInt(_T("FullScreen"), 1));
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
} else if (!strcmp(lpValueName, "Draw Cursor")) {
|
||||
|
||||
ReturnRegistryYESNOFromBool(lpData, config.GetInt(_T("DrawCursor"), 1));
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
} else if (!strcmp(lpValueName, "savepath")) {
|
||||
|
||||
// If enabled, return a safe %APPDATA% based save location rather than its default
|
||||
// "C:\Program Files" location
|
||||
if (config.GetInt(_T("RedirectSaveData"))) {
|
||||
// Generate directory
|
||||
TCHAR save_path[MAX_PATH];
|
||||
if (GetSafeLEGOIslandSavePath(save_path)) {
|
||||
strcpy((char*)lpData, save_path);
|
||||
return ERROR_SUCCESS;
|
||||
} else {
|
||||
MessageBoxA(isleWindow, "Failed to redirect save path. Default will be used instead.", 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!strcmp(lpValueName, "diskpath") || !strcmp(lpValueName, "cdpath")) {
|
||||
|
||||
// Pass through
|
||||
|
||||
} else {
|
||||
MessageBoxA(isleWindow, lpValueName, "ISLE asked for...", 0);
|
||||
}
|
||||
|
||||
// Pass these through
|
||||
return RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
||||
}
|
||||
|
|
11
lib/hooks.h
11
lib/hooks.h
|
@ -21,6 +21,17 @@ HWND WINAPI InterceptCreateWindowExA(
|
|||
LPVOID lpParam
|
||||
);
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
InterceptRegQueryValueExA (
|
||||
HKEY hKey,
|
||||
LPCSTR lpValueName,
|
||||
LPDWORD lpReserved,
|
||||
LPDWORD lpType,
|
||||
LPBYTE lpData,
|
||||
LPDWORD lpcbData
|
||||
);
|
||||
|
||||
HWND WINAPI InterceptFindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName);
|
||||
|
||||
typedef HRESULT (WINAPI *ddCreateFunction)(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuterS);
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
#include "worker.h"
|
||||
|
||||
#include <TCHAR.H>
|
||||
#include <VECTOR>
|
||||
|
||||
#include "config.h"
|
||||
#include "hooks.h"
|
||||
#include "util.h"
|
||||
|
||||
DWORD WINAPI Patch()
|
||||
{
|
||||
MessageBoxA(0,"Connect debugger now",0,0);
|
||||
if (!config.Load()) {
|
||||
MessageBoxA(0, "Failed to find Rebuilder configuration. No patches will be active.", 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Hook import address table
|
||||
LPVOID exeBase = GetModuleHandle(TEXT("ISLE.EXE"));
|
||||
|
@ -15,31 +20,47 @@ DWORD WINAPI Patch()
|
|||
|
||||
// Redirect various imports
|
||||
OverwriteImport(exeBase, "CreateWindowExA", (LPVOID)InterceptCreateWindowExA);
|
||||
OverwriteImport(exeBase, "FindWindowA", (LPVOID)InterceptFindWindowA);
|
||||
OverwriteImport(dllBase, "OutputDebugStringA", (LPVOID)InterceptOutputDebugStringA);
|
||||
OverwriteImport(exeBase, "RegQueryValueExA", (LPVOID)InterceptRegQueryValueExA);
|
||||
ddCreateOriginal = (ddCreateFunction)OverwriteImport(dllBase, "DirectDrawCreate", (LPVOID)InterceptDirectDrawCreate);
|
||||
|
||||
// Stay active when defocused
|
||||
SearchReplacePattern(exeBase, "\x89\x58\x70", "\x90\x90\x90", 3);
|
||||
SearchReplacePattern(dllBase, "\xC7\x44\x24\x24\xE0\x00\x00\x00", "\xC7\x44\x24\x24\xE0\x80\x00\x00", 8);
|
||||
SearchReplacePattern(dllBase, "\xC7\x44\x24\x24\xB0\x00\x00\x00", "\xC7\x44\x24\x24\xB0\x80\x00\x00", 8);
|
||||
SearchReplacePattern(dllBase, "\xC7\x45\xCC\x11\x00\x00\x00", "\xC7\x45\xCC\x11\x80\x00\x00", 7);
|
||||
SearchReplacePattern(dllBase, "\xC7\x45\xCC\xE0\x00\x00\x00", "\xC7\x45\xCC\xE0\x80\x00\x00", 7);
|
||||
if (config.GetInt(_T("StayActiveWhenDefocused"))) {
|
||||
// Patch jump if window isn't active
|
||||
SearchReplacePattern(exeBase, "\x89\x58\x70", "\x90\x90\x90", 3);
|
||||
|
||||
// Patch DirectSound flags so that sound doesn't mute when inactive
|
||||
SearchReplacePattern(dllBase, "\xC7\x44\x24\x24\xE0\x00\x00\x00", "\xC7\x44\x24\x24\xE0\x80\x00\x00", 8);
|
||||
SearchReplacePattern(dllBase, "\xC7\x44\x24\x24\xB0\x00\x00\x00", "\xC7\x44\x24\x24\xB0\x80\x00\x00", 8);
|
||||
SearchReplacePattern(dllBase, "\xC7\x45\xCC\x11\x00\x00\x00", "\xC7\x45\xCC\x11\x80\x00\x00", 7);
|
||||
SearchReplacePattern(dllBase, "\xC7\x45\xCC\xE0\x00\x00\x00", "\xC7\x45\xCC\xE0\x80\x00\x00", 7);
|
||||
}
|
||||
|
||||
// Allow multiple instances
|
||||
if (config.GetInt(_T("AllowMultipleInstances"))) {
|
||||
// Patch FindWindowA import to always tell ISLE that no other ISLE window exists
|
||||
OverwriteImport(exeBase, "FindWindowA", (LPVOID)InterceptFindWindowA);
|
||||
}
|
||||
|
||||
// Debug mode
|
||||
if (config.GetInt(_T("DebugToggle"))) {
|
||||
// LEGO1 uses a string pointer to know if OGEL has been typed, if the string pointer sees 0x0
|
||||
// (null-terminator/end of string), then debug mode is enabled. So we just replace the first
|
||||
// character with 0x0 and it's permanently on.
|
||||
SearchReplacePattern(dllBase, "OGEL", "\x0GEL", 4, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// DDRAW GetSurfaceDesc Override
|
||||
//OverwriteCall((LPVOID) ((UINT_PTR)dllBase+0xBA7D5), (LPVOID)InterceptSurfaceGetDesc);
|
||||
OverwriteCall((LPVOID) ((UINT_PTR)dllBase+0xBA7D5), (LPVOID)InterceptSurfaceGetDesc);
|
||||
|
||||
// Window size hack
|
||||
/*SearchReplacePattern(exeBase,
|
||||
"\x80\x02\x00\x00\xE0\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x02\x00\x00\xE0\x01\x00\x00",
|
||||
"\x40\x01\x00\x00\xE0\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x02\x00\x00\xE0\x01\x00\x00", 24);*/
|
||||
|
||||
/*char debug[5];
|
||||
debug[0] = 0xE8;
|
||||
*(UINT_PTR*)(&debug[1]) = (UINT_PTR)InterceptOutputDebugStringA;
|
||||
if (SIZE_T replacements = SearchReplacePattern(legoBase, "\xE8\x34\x08\x00\x00", debug, 5)) {
|
||||
printf("Hooked some other debug function %lu times", replacements);
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "patchgrid.h"
|
||||
|
||||
#include <SSTREAM>
|
||||
|
||||
#include "../cmn/path.h"
|
||||
|
||||
PatchGrid::PatchGrid()
|
||||
{
|
||||
SetBoldModified(true);
|
||||
|
@ -39,13 +43,14 @@ PatchGrid::PatchGrid()
|
|||
HSECTION sectionControls = AddSection(_T("Controls"));
|
||||
|
||||
AddPatch("UseWASD",
|
||||
_T(""),
|
||||
_T("Enables the use of WASD keys for movement rather than the arrow keys. "
|
||||
"NOTE: When using Debug Mode, this patch will re-map the conflicting debug keys to the arrow keys."),
|
||||
AddBoolItem(sectionControls, _T("Use WASD"), false));
|
||||
AddPatch("UseJoystick",
|
||||
_T(""),
|
||||
_T("Enables Joystick functionality."),
|
||||
AddBoolItem(sectionControls, _T("Use Joystick"), false));
|
||||
AddPatch("MouseDeadzone",
|
||||
_T(""),
|
||||
_T("Sets the radius from the center of the screen where the mouse will do nothing (40 = default)."),
|
||||
AddIntegerItem(sectionControls, _T("Mouse Deadzone"), 40));
|
||||
AddPatch("UnhookTurnSpeed",
|
||||
_T("LEGO Island contains a bug where the turning speed is influenced by the frame rate. Enable this to make the turn speed independent of the frame rate."),
|
||||
|
@ -129,12 +134,55 @@ PatchGrid::PatchGrid()
|
|||
AddBoolItem(sectionMusic, _T("Play Music"), true));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string toString(const T &value)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
BOOL PatchGrid::SaveConfiguration(LPCTSTR filename)
|
||||
{
|
||||
LPCTSTR appName = TEXT("Rebuilder");
|
||||
|
||||
for (std::map<std::string, HITEM>::const_iterator it=m_mPatchItems.begin(); it!=m_mPatchItems.end(); it++) {
|
||||
CItem *item = FindItem(it->second);
|
||||
|
||||
std::string value;
|
||||
|
||||
// Convert value to string
|
||||
switch (item->m_type) {
|
||||
case IT_STRING:
|
||||
case IT_TEXT:
|
||||
case IT_FILE:
|
||||
case IT_FOLDER:
|
||||
value = item->m_strValue;
|
||||
break;
|
||||
case IT_BOOLEAN:
|
||||
value = toString(item->m_bValue);
|
||||
break;
|
||||
case IT_COMBO:
|
||||
case IT_INTEGER:
|
||||
value = toString(item->m_nValue);
|
||||
break;
|
||||
case IT_DOUBLE:
|
||||
value = toString(item->m_dValue);
|
||||
break;
|
||||
case IT_COLOR:
|
||||
value = toString(item->m_clrValue);
|
||||
break;
|
||||
case IT_CUSTOM:
|
||||
case IT_DATE:
|
||||
case IT_DATETIME:
|
||||
case IT_FONT:
|
||||
{
|
||||
// Report inability to serialize
|
||||
TCHAR buf[200];
|
||||
sprintf(buf, "Failed to serialize %s to string.", it->first.c_str());
|
||||
MessageBox(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->GetItemValue(it->second, value);
|
||||
if (!WritePrivateProfileString(appName, it->first.c_str(), value.c_str(), filename)) {
|
||||
return FALSE;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "window.h"
|
||||
|
||||
#include <SHLWAPI.H>
|
||||
#include <WINDOWS.H>
|
||||
|
||||
#include "../cmn/path.h"
|
||||
#include "launcher.h"
|
||||
#include "../res/resource.h"
|
||||
|
||||
|
@ -91,10 +91,8 @@ DWORD WINAPI WaitForProcessToClose(HANDLE hProcess)
|
|||
void CRebuilderWindow::OnRunClick()
|
||||
{
|
||||
TCHAR configPath[MAX_PATH];
|
||||
if (GetConfigPath(configPath)) {
|
||||
// Append path and save configuration
|
||||
_tcscat(configPath, _T("\\settings.ini"));
|
||||
|
||||
if (GetConfigFilename(configPath)) {
|
||||
if (m_cPatchGrid.SaveConfiguration(configPath)) {
|
||||
if (HANDLE proc = Launcher::Launch(this->GetSafeHwnd())) {
|
||||
m_lProcesses.push_back(proc);
|
||||
|
@ -252,72 +250,6 @@ void CRebuilderWindow::SwitchButtonMode(BOOL running)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL DirectoryExists(LPCTSTR szPath)
|
||||
{
|
||||
return PathFileExists(szPath) && PathIsDirectory(szPath);
|
||||
}
|
||||
|
||||
BOOL RecursivelyCreateDirectory(LPCTSTR directory)
|
||||
{
|
||||
if (DirectoryExists(directory)) {
|
||||
// Directory already exists, do nothing
|
||||
return TRUE;
|
||||
} else {
|
||||
// Determine directory of this directory
|
||||
std::basic_string<TCHAR> copy = directory;
|
||||
PathRemoveFileSpec(©[0]);
|
||||
|
||||
// Create if necessary
|
||||
if (RecursivelyCreateDirectory(copy.c_str())) {
|
||||
return CreateDirectory(directory, NULL);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
typedef BOOL (WINAPI *SHGetSpecialFolderPathSignature)(HWND hwndOwner, LPWSTR lpszPath, int nFolder, BOOL fCreate);
|
||||
#else
|
||||
typedef BOOL (WINAPI *SHGetSpecialFolderPathSignature)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
||||
#endif
|
||||
BOOL CRebuilderWindow::GetConfigPath(LPTSTR s)
|
||||
{
|
||||
OSVERSIONINFO info;
|
||||
ZeroMemory(&info, sizeof(info));
|
||||
info.dwOSVersionInfoSize = sizeof(info);
|
||||
GetVersionEx(&info);
|
||||
|
||||
// Dynamically link to SHGetSpecialFolderPath because not all versions of Windows have it
|
||||
#ifdef UNICODE
|
||||
LPCSTR functionName = "SHGetSpecialFolderPathW";
|
||||
#else
|
||||
LPCSTR functionName = "SHGetSpecialFolderPathA";
|
||||
#endif
|
||||
|
||||
SHGetSpecialFolderPathSignature GetSpecialFolderPath = (SHGetSpecialFolderPathSignature)GetProcAddress(GetModuleHandle(_T("SHELL32.DLL")), functionName);
|
||||
BOOL haveDir = FALSE;
|
||||
BOOL usedShell = FALSE;
|
||||
if (GetSpecialFolderPath) {
|
||||
haveDir = GetSpecialFolderPath(NULL, s, CSIDL_APPDATA, TRUE);
|
||||
usedShell = TRUE;
|
||||
} else {
|
||||
// Assume we're on Windows 95 which has no application data folder, we bodge it to write to
|
||||
// "C:\Windows\Application Data" which is roughly where 98/Me would do it
|
||||
GetWindowsDirectory(s, MAX_PATH);
|
||||
_tcscat(s, _T("\\Application Data"));
|
||||
haveDir = TRUE;
|
||||
}
|
||||
|
||||
if (haveDir) {
|
||||
_tcscat(s, _T("\\LEGOIslandRebuilder"));
|
||||
MessageBox(s, usedShell ? _T("Using API") : _T("Is this Windows 95?"));
|
||||
return RecursivelyCreateDirectory(s);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CRebuilderWindow, super)
|
||||
ON_WM_SIZE()
|
||||
ON_WM_GETMINMAXINFO()
|
||||
|
|
|
@ -34,8 +34,6 @@ private:
|
|||
|
||||
void SwitchButtonMode(BOOL running);
|
||||
|
||||
BOOL GetConfigPath(LPTSTR s);
|
||||
|
||||
enum {
|
||||
ID_RUN = 1000,
|
||||
ID_KILL,
|
||||
|
|
Loading…
Add table
Reference in a new issue