Replace Windows registry with .ini file (#10)

* Replace Windows registry with .ini file

* Update README.md

* Update CMakeLists.txt

* comment

* set CMake policy

* Try this

* Try this

* Adjust comments
This commit is contained in:
Christian Semmler 2024-05-31 14:04:00 -04:00 committed by Anonymous Maarten
parent 889bd4c1cd
commit dda6778665
5 changed files with 77 additions and 111 deletions

View file

@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
# MSVC runtime library flags are selected by an abstraction
cmake_policy(SET CMP0091 NEW)
# To set BUILD_* variables for iniparser below. Is there another way?
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
project(isle CXX C)
# By configuring CMake with -DDOWNLOAD_DEPENDENCIES=ON/OFF,
@ -19,11 +22,23 @@ if(DOWNLOAD_DEPENDENCIES)
EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(SDL3)
FetchContent_Declare(
iniparser
GIT_REPOSITORY "https://github.com/ndevilla/iniparser.git"
GIT_TAG "main"
EXCLUDE_FROM_ALL
)
set(BUILD_DOCS off)
set(BUILD_SHARED_LIBS off)
FetchContent_MakeAvailable(iniparser)
else()
# find_package looks for already-installed system packages.
# Configure with `-DCMAKE_PREFIX_PATH="/path/to/package1;/path/to/package2"`
# to add search paths.
find_package(SDL3 CONFIG REQUIRED)
# TODO add iniparser?
endif()
include(CheckCXXSourceCompiles)
@ -479,7 +494,10 @@ if (ISLE_BUILD_APP)
target_compile_definitions(isle PRIVATE ISLE_APP)
# Use internal DirectX 5 if required
target_link_libraries(isle PRIVATE $<$<BOOL:${ISLE_USE_DX5}>:DirectX5::DirectX5> SDL3::SDL3)
target_link_libraries(isle PRIVATE $<$<BOOL:${ISLE_USE_DX5}>:DirectX5::DirectX5>)
# Link SDL and iniparser
target_link_libraries(isle PRIVATE SDL3::SDL3 iniparser-static)
# Link DSOUND, WINMM, and LEGO1
target_link_libraries(isle PRIVATE dsound winmm lego1)

View file

@ -28,8 +28,11 @@
#include "viewmanager/viewmanager.h"
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_main.h>
#include <dsound.h>
#include <iniparser.h>
DECOMP_SIZE_ASSERT(IsleApp, 0x8c)
@ -240,6 +243,9 @@ void IsleApp::SetupVideoFlags(
int SDL_AppInit(void** appstate, int argc, char** argv)
{
// Add subsystems as necessary later
SDL_Init(SDL_INIT_TIMER);
// Look for another instance, if we find one, bring it to the foreground instead
if (!FindExistingInstance()) {
return 1;
@ -348,6 +354,7 @@ int SDL_AppEvent(void* appstate, const SDL_Event* event)
void SDL_AppQuit(void* appstate)
{
DestroyWindow((HWND) appstate);
SDL_Quit();
}
// FUNCTION: ISLE 0x401ca0
@ -694,97 +701,42 @@ MxResult IsleApp::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine)
return SUCCESS;
}
// FUNCTION: ISLE 0x402740
BOOL IsleApp::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize)
{
HKEY hKey;
DWORD valueType;
BOOL out = FALSE;
DWORD size = outSize;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Mindscape\\LEGO Island", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExA(hKey, name, NULL, &valueType, (LPBYTE) outValue, &size) == ERROR_SUCCESS) {
if (RegCloseKey(hKey) == ERROR_SUCCESS) {
out = TRUE;
}
}
}
return out;
}
// FUNCTION: ISLE 0x4027b0
BOOL IsleApp::ReadRegBool(LPCSTR name, BOOL* out)
{
char buffer[256];
BOOL read = ReadReg(name, buffer, sizeof(buffer));
if (read) {
if (strcmp("YES", buffer) == 0) {
*out = TRUE;
return read;
}
if (strcmp("NO", buffer) == 0) {
*out = FALSE;
return read;
}
read = FALSE;
}
return read;
}
// FUNCTION: ISLE 0x402880
BOOL IsleApp::ReadRegInt(LPCSTR name, int* out)
{
char buffer[256];
BOOL read = ReadReg(name, buffer, sizeof(buffer));
if (read) {
*out = atoi(buffer);
}
return read;
}
// FUNCTION: ISLE 0x4028d0
void IsleApp::LoadConfig()
{
char buffer[1024];
char* basePath = SDL_GetBasePath();
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
char* iniConfig = new char[strlen(prefPath) + strlen("isle.ini") + 1]();
strcat(iniConfig, prefPath);
strcat(iniConfig, "isle.ini");
dictionary* dict = iniparser_load(iniConfig);
if (!ReadReg("diskpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetHD());
}
m_hdPath = new char[strlen(buffer) + 1];
strcpy(m_hdPath, buffer);
const char* hdPath = iniparser_getstring(dict, "isle:diskpath", basePath);
m_hdPath = new char[strlen(hdPath) + 1];
strcpy(m_hdPath, hdPath);
MxOmni::SetHD(m_hdPath);
if (!ReadReg("cdpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetCD());
}
m_cdPath = new char[strlen(buffer) + 1];
strcpy(m_cdPath, buffer);
const char* cdPath = iniparser_getstring(dict, "isle:cdpath", MxOmni::GetCD());
m_cdPath = new char[strlen(cdPath) + 1];
strcpy(m_cdPath, cdPath);
MxOmni::SetCD(m_cdPath);
ReadRegBool("Flip Surfaces", &m_flipSurfaces);
ReadRegBool("Full Screen", &m_fullScreen);
ReadRegBool("Wide View Angle", &m_wideViewAngle);
ReadRegBool("3DSound", &m_use3dSound);
ReadRegBool("Music", &m_useMusic);
ReadRegBool("UseJoystick", &m_useJoystick);
ReadRegInt("JoystickIndex", &m_joystickIndex);
ReadRegBool("Draw Cursor", &m_drawCursor);
m_flipSurfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flipSurfaces);
m_fullScreen = iniparser_getboolean(dict, "isle:Full Screen", m_fullScreen);
m_wideViewAngle = iniparser_getboolean(dict, "isle:Wide View Angle", m_wideViewAngle);
m_use3dSound = iniparser_getboolean(dict, "isle:3DSound", m_use3dSound);
m_useMusic = iniparser_getboolean(dict, "isle:Music", m_useMusic);
m_useJoystick = iniparser_getboolean(dict, "isle:UseJoystick", m_useJoystick);
m_joystickIndex = iniparser_getint(dict, "isle:JoystickIndex", m_joystickIndex);
m_drawCursor = iniparser_getboolean(dict, "isle:Draw Cursor", m_drawCursor);
int backBuffersInVRAM;
if (ReadRegBool("Back Buffers in Video RAM", &backBuffersInVRAM)) {
int backBuffersInVRAM = iniparser_getboolean(dict, "isle:Back Buffers in Video RAM", -1);
if (backBuffersInVRAM != -1) {
m_backBuffersInVram = !backBuffersInVRAM;
}
int bitDepth;
if (ReadRegInt("Display Bit Depth", &bitDepth)) {
int bitDepth = iniparser_getint(dict, "isle:Display Bit Depth", -1);
if (bitDepth != -1) {
if (bitDepth == 8) {
m_using8bit = TRUE;
}
@ -793,25 +745,25 @@ void IsleApp::LoadConfig()
}
}
if (!ReadReg("Island Quality", buffer, sizeof(buffer))) {
strcpy(buffer, "1");
}
m_islandQuality = atoi(buffer);
m_islandQuality = iniparser_getint(dict, "isle:Island Quality", 1);
m_islandTexture = iniparser_getint(dict, "isle:Island Texture", 1);
if (!ReadReg("Island Texture", buffer, sizeof(buffer))) {
strcpy(buffer, "1");
}
m_islandTexture = atoi(buffer);
if (ReadReg("3D Device ID", buffer, sizeof(buffer))) {
m_deviceId = new char[strlen(buffer) + 1];
strcpy(m_deviceId, buffer);
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
if (deviceId != NULL) {
m_deviceId = new char[strlen(deviceId) + 1];
strcpy(m_deviceId, deviceId);
}
if (ReadReg("savepath", buffer, sizeof(buffer))) {
m_savePath = new char[strlen(buffer) + 1];
strcpy(m_savePath, buffer);
}
// [library:config] The original game does not save any data if no savepath is given.
// Instead, we use SDLs prefPath as a default fallback and always save data.
const char* savePath = iniparser_getstring(dict, "isle:savepath", prefPath);
m_savePath = new char[strlen(savePath) + 1];
strcpy(m_savePath, savePath);
iniparser_freedict(dict);
delete[] iniConfig;
SDL_free(prefPath);
SDL_free(basePath);
}
// FUNCTION: ISLE 0x402c20

View file

@ -28,10 +28,6 @@ class IsleApp {
);
MxResult SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine);
BOOL ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize);
BOOL ReadRegBool(LPCSTR name, BOOL* out);
BOOL ReadRegInt(LPCSTR name, int* out);
void LoadConfig();
void Tick(BOOL sleepIfNotNextFrame);
void SetupCursor(WPARAM wParam);
@ -47,10 +43,10 @@ class IsleApp {
inline void SetWindowActive(BOOL p_windowActive) { m_windowActive = p_windowActive; }
private:
LPSTR m_hdPath; // 0x00
LPSTR m_cdPath; // 0x04
LPSTR m_deviceId; // 0x08
LPSTR m_savePath; // 0x0c
char* m_hdPath; // 0x00
char* m_cdPath; // 0x04
char* m_deviceId; // 0x08
char* m_savePath; // 0x0c
BOOL m_fullScreen; // 0x10
BOOL m_flipSurfaces; // 0x14
BOOL m_backBuffersInVram; // 0x18

View file

@ -19,10 +19,10 @@
#include "mxvideomanager.h"
// GLOBAL: LEGO1 0x101015b8
char g_hdPath[1024] = "";
MxString g_hdPath = "";
// GLOBAL: LEGO1 0x101019b8
char g_cdPath[1024] = "E:";
MxString g_cdPath = "E:";
// GLOBAL: LEGO1 0x10101db8
MxBool g_use3dSound = FALSE;
@ -362,25 +362,25 @@ MxLong MxOmni::HandleEndAction(MxParam& p_param)
// FUNCTION: LEGO1 0x100b0900
const char* MxOmni::GetHD()
{
return g_hdPath;
return g_hdPath.GetData();
}
// FUNCTION: LEGO1 0x100b0910
void MxOmni::SetHD(const char* p_hd)
{
strcpy(g_hdPath, p_hd);
g_hdPath = p_hd;
}
// FUNCTION: LEGO1 0x100b0940
const char* MxOmni::GetCD()
{
return g_cdPath;
return g_cdPath.GetData();
}
// FUNCTION: LEGO1 0x100b0950
void MxOmni::SetCD(const char* p_cd)
{
strcpy(g_cdPath, p_cd);
g_cdPath = p_cd;
}
// FUNCTION: LEGO1 0x100b0980

View file

@ -23,7 +23,7 @@ To achieve our goal of platform independence, we need to replace any Windows-onl
| Library/subsystem | Substitution | Status | |
| - | - | - | - |
| Window, Events | [SDL3](https://www.libsdl.org/) | WIP | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Awindow%5D%22&type=code) |
| Windows Registry (Configuration) | [libiniparser](https://github.com/ndevilla/iniparser) | | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aconfig%5D%22&type=code) |
| Windows Registry (Configuration) | [libiniparser](https://github.com/ndevilla/iniparser) | | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aconfig%5D%22&type=code) |
| Filesystem | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Afilesystem%5D%22&type=code) |
| Threads, Mutexes (Synchronization) | [SDL3](https://www.libsdl.org/) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Asynchronization%5D%22&type=code) |
| Keyboard/Mouse, Joystick, DirectInput (Input) | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Ainput%5D%22&type=code) |