Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Windows registry with .ini file #10

Merged
merged 8 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
144 changes: 48 additions & 96 deletions ISLE/isleapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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];

if (!ReadReg("diskpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetHD());
}

m_hdPath = new char[strlen(buffer) + 1];
strcpy(m_hdPath, buffer);
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);

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);

int backBuffersInVRAM;
if (ReadRegBool("Back Buffers in Video RAM", &backBuffersInVRAM)) {
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 = 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;
}
Expand All @@ -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");
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);
}
m_islandTexture = atoi(buffer);

if (ReadReg("3D Device ID", buffer, sizeof(buffer))) {
m_deviceId = new char[strlen(buffer) + 1];
strcpy(m_deviceId, 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);

if (ReadReg("savepath", buffer, sizeof(buffer))) {
m_savePath = new char[strlen(buffer) + 1];
strcpy(m_savePath, buffer);
}
iniparser_freedict(dict);
delete[] iniConfig;
SDL_free(prefPath);
SDL_free(basePath);
}

// FUNCTION: ISLE 0x402c20
Expand Down
12 changes: 4 additions & 8 deletions ISLE/isleapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down
12 changes: 6 additions & 6 deletions LEGO1/omni/src/main/mxomni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
Expand Down
Loading