Skip to content

Commit

Permalink
Full unicode support on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
captainurist committed Nov 6, 2023
1 parent 7731d38 commit b417455
Show file tree
Hide file tree
Showing 52 changed files with 607 additions and 213 deletions.
1 change: 1 addition & 0 deletions src/Application/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ target_link_libraries(application
media
library_platform_null
library_platform_implementation
library_environment_implementation
utility)
7 changes: 4 additions & 3 deletions src/Application/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,24 @@
#include "Media/MediaPlayer.h"

#include "Library/Platform/Application/PlatformApplication.h"
#include "Library/Environment/Interface/Environment.h"
#include "Library/Random/Random.h"
#include "Library/Logger/Logger.h"

#include "Utility/Format.h"
#include "Utility/DataPath.h"
#include "Utility/Exception.h"
#include "Utility/FileSystem.h"

void ShowMM7IntroVideo_and_LoadingScreen();

using Graphics::IRenderFactory;


void initDataPath(const std::string &dataPath) {
void initDataPath(Environment *environment, Platform *platform, const std::string &dataPath) {
std::string missing_file;

if (validateDataPath(dataPath, missing_file)) {
setDataPath(dataPath);
setDataPath(expandUserPath(dataPath, environment->path(PATH_HOME)));

std::string savesPath = makeDataPath("saves");
if (!std::filesystem::exists(savesPath)) {
Expand Down
5 changes: 3 additions & 2 deletions src/Application/Game.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
using Io::Mouse;

class IRender;
class Platform;
class PlatformApplication;
class GameTraceHandler;
class NuklearEventHandler;
class Platform;
class Environment;

class Game {
public:
Expand Down Expand Up @@ -49,6 +50,6 @@ class Game {
std::shared_ptr<Nuklear> _nuklear = nullptr;
};

void initDataPath(const std::string &dataPath);
void initDataPath(Environment *environment, Platform *platform, const std::string &dataPath);

extern class GraphicsImage *gamma_preview_image; // 506E40
29 changes: 12 additions & 17 deletions src/Application/GamePathResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
#include "Application/GamePathResolver.h"

#include "Library/Logger/Logger.h"
#include "Library/Platform/Interface/Platform.h"
#include "Library/Environment/Interface/Environment.h"

static std::string _resolvePath(Platform *platform, const char *envVarOverride, const std::vector<const char *> &registryKeys);
static std::string _resolvePath(Environment *environment, const char *envVarOverride, const std::vector<const char *> &registryKeys);

std::string resolveMm6Path(Platform *platform) {
std::string resolveMm6Path(Environment *environment) {
return _resolvePath(
platform,
environment,
mm6PathOverrideKey,
{
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/Games/1207661253/PATH",
Expand All @@ -23,9 +23,9 @@ std::string resolveMm6Path(Platform *platform) {
}


std::string resolveMm7Path(Platform *platform) {
std::string resolveMm7Path(Environment *environment) {
return _resolvePath(
platform,
environment,
mm7PathOverrideKey,
{
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/Games/1207658916/Path",
Expand All @@ -39,9 +39,9 @@ std::string resolveMm7Path(Platform *platform) {
}


std::string resolveMm8Path(Platform *platform) {
std::string resolveMm8Path(Environment *environment) {
return _resolvePath(
platform,
environment,
mm8PathOverrideKey,
{
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM8/PATH",
Expand All @@ -52,17 +52,12 @@ std::string resolveMm8Path(Platform *platform) {
);
}


static std::string _resolvePath(
Platform *platform,
const char *envVarOverride,
const std::vector<const char *> &registryKeys
) {
static std::string _resolvePath(Environment *environment, const char *envVarOverride, const std::vector<const char *> &registryKeys) {
#ifdef __ANDROID__
// TODO: find a better way to deal with paths and remove this android specific block.
std::string result = platform->storagePath(ANDROID_STORAGE_EXTERNAL);
std::string result = environment->path(PATH_ANDROID_STORAGE_EXTERNAL);
if (result.empty())
result = platform->storagePath(ANDROID_STORAGE_INTERNAL);
result = environment->path(PATH_ANDROID_STORAGE_INTERNAL);
if (result.empty())
platform->showMessageBox("Device currently unsupported", "Your device doesn't have any storage so it is unsupported!");
return result;
Expand All @@ -84,7 +79,7 @@ static std::string _resolvePath(
}

for (auto key : registryKeys) {
envPath = platform->winQueryRegistry(key);
envPath = environment->queryRegistry(key);
if (!envPath.empty()) {
return envPath;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Application/GamePathResolver.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include <string>

class Platform;
class Environment;

constexpr char mm6PathOverrideKey[] = "OPENENROTH_MM6_PATH";
constexpr char mm7PathOverrideKey[] = "OPENENROTH_MM7_PATH";
constexpr char mm8PathOverrideKey[] = "OPENENROTH_MM8_PATH";

std::string resolveMm6Path(Platform *platform);
std::string resolveMm7Path(Platform *platform);
std::string resolveMm8Path(Platform *platform);
std::string resolveMm6Path(Environment *environment);
std::string resolveMm7Path(Environment *environment);
std::string resolveMm8Path(Environment *environment);
14 changes: 8 additions & 6 deletions src/Application/GameStarter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include <string>

#include "Engine/Engine.h"
#include "Engine/EngineGlobals.h"

#include "Library/Environment/Interface/Environment.h"
#include "Library/Platform/Application/PlatformApplication.h"
#include "Library/Logger/Logger.h"
#include "Library/Logger/LogSink.h"
Expand All @@ -20,6 +20,9 @@
#include "Game.h"

GameStarter::GameStarter(GameStarterOptions options): _options(std::move(options)) {
// Init environment.
_environment = Environment::createStandardEnvironment();

// Init logger.
_bufferSink = std::make_unique<BufferLogSink>();
_defaultSink = LogSink::createDefaultSink();
Expand All @@ -32,7 +35,7 @@ GameStarter::GameStarter(GameStarterOptions options): _options(std::move(options
} else {
_platform = Platform::createStandardPlatform(_logger.get());
}
resolveDefaults(_platform.get(), &_options);
resolveDefaults(_environment.get(), &_options); // TODO(captainurist): move this call up?

// Init config - needs data paths initialized.
_config = std::make_shared<GameConfig>();
Expand All @@ -58,8 +61,7 @@ GameStarter::GameStarter(GameStarterOptions options): _options(std::move(options
_bufferSink->flush(_logger.get());

// Validate data paths.
::platform = _platform.get(); // TODO(captainurist): a hack to make validateDataPath work.
initDataPath(_options.dataPath);
initDataPath(_environment.get(), _platform.get(), _options.dataPath);

// Create application & game.
_application = std::make_unique<PlatformApplication>(_platform.get());
Expand All @@ -68,9 +70,9 @@ GameStarter::GameStarter(GameStarterOptions options): _options(std::move(options

GameStarter::~GameStarter() = default;

void GameStarter::resolveDefaults(Platform *platform, GameStarterOptions* options) {
void GameStarter::resolveDefaults(Environment *environment, GameStarterOptions* options) {
if (options->dataPath.empty())
options->dataPath = resolveMm7Path(platform);
options->dataPath = resolveMm7Path(environment);

if (options->useConfig && options->configPath.empty()) {
options->configPath = "openenroth.ini";
Expand Down
5 changes: 3 additions & 2 deletions src/Application/GameStarter.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "GameStarterOptions.h"

class Platform;
class PlatformLogger;
class Environment;
class Logger;
class BufferLogSink;
class LogSink;
Expand All @@ -29,10 +29,11 @@ class GameStarter {
void run();

private:
static void resolveDefaults(Platform *platform, GameStarterOptions* options);
static void resolveDefaults(Environment *environment, GameStarterOptions* options);

private:
GameStarterOptions _options;
std::unique_ptr<Environment> _environment;
std::unique_ptr<BufferLogSink> _bufferSink;
std::unique_ptr<LogSink> _defaultSink;
std::unique_ptr<Logger> _logger;
Expand Down
2 changes: 2 additions & 0 deletions src/Bin/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "Utility/DataPath.h"
#include "Utility/Exception.h"
#include "Utility/String.h"
#include "Utility/UnicodeCrt.h"

#include "CodeGenEnums.h"
#include "CodeGenMap.h"
Expand Down Expand Up @@ -389,6 +390,7 @@ int runBountyHuntCodeGen(CodeGenOptions options, GameResourceManager *resourceMa

int platformMain(int argc, char **argv) {
try {
UnicodeCrt _(argc, argv);
CodeGenOptions options = CodeGenOptions::parse(argc, argv);
if (options.helpPrinted)
return 1;
Expand Down
2 changes: 2 additions & 0 deletions src/Bin/LodTool/LodTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "Utility/Format.h"
#include "Utility/String.h"
#include "Utility/UnicodeCrt.h"

int runDump(const LodToolOptions &options) {
LodReader reader(options.lodPath, LOD_ALLOW_DUPLICATES);
Expand Down Expand Up @@ -41,6 +42,7 @@ int runDump(const LodToolOptions &options) {

int main(int argc, char **argv) {
try {
UnicodeCrt _(argc, argv);
LodToolOptions options = LodToolOptions::parse(argc, argv);
if (options.helpPrinted)
return 1;
Expand Down
2 changes: 2 additions & 0 deletions src/Bin/OpenEnroth/OpenEnroth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Library/Trace/EventTrace.h"

#include "Utility/Format.h"
#include "Utility/UnicodeCrt.h"

#include "OpenEnrothOptions.h"

Expand Down Expand Up @@ -55,6 +56,7 @@ int runOpenEnroth(OpenEnrothOptions options) {

int openEnrothMain(int argc, char **argv) {
try {
UnicodeCrt _(argc, argv);
OpenEnrothOptions options = OpenEnrothOptions::parse(argc, argv);
if (options.helpPrinted)
return 1;
Expand Down
1 change: 1 addition & 0 deletions src/Library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_subdirectory(Cli)
add_subdirectory(Color)
add_subdirectory(Compression)
add_subdirectory(Config)
add_subdirectory(Environment)
add_subdirectory(Geometry)
add_subdirectory(Image)
add_subdirectory(Json)
Expand Down
33 changes: 33 additions & 0 deletions src/Library/Environment/Android/AndroidEnvironment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "AndroidEnvironment.h"

#include <SDL.h>

std::string AndroidEnvironment::queryRegistry(const std::string &path) const {
return {}
}

std::string AndroidEnvironment::path(EnvironmentPath path) const {
const char *result = nullptr;
if (path == PATH_ANDROID_STORAGE_INTERNAL) {
result = SDL_AndroidGetInternalStoragePath();
} else if (path == PATH_ANDROID_STORAGE_EXTERNAL) {
result = SDL_AndroidGetExternalStoragePath();
}

// TODO(captainurist): No PATH_HOME on Android? Verify & write a comment here.

if (result)
return result;
return {};
}

std::string AndroidEnvironment::getenv(const std::string &key) const {
const char *result = SDL_getenv(key.c_str());
if (result)
return result;
return {};
}

std::unique_ptr<Environment> Environment::createStandardEnvironment() {
return std::make_unique<AndroidEnvironment>();
}
10 changes: 10 additions & 0 deletions src/Library/Environment/Android/AndroidEnvironment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "Library/Environment/Interface/Environment.h"

class AndroidEnvironment : public Environment {
public:
virtual std::string queryRegistry(const std::string &path) const override;
virtual std::string path(EnvironmentPath path) const override;
virtual std::string getenv(const std::string &key) const override;
};
16 changes: 16 additions & 0 deletions src/Library/Environment/Android/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.24 FATAL_ERROR)

set(LIBRARY_ENVIRONMENT_ANDROID_SOURCES
AndroidEnvironment.cpp)

set(LIBRARY_ENVIRONMENT_ANDROID_HEADERS
AndroidEnvironment.h)

if(BUILD_PLATFORM STREQUAL "android")
add_library(library_environment_android STATIC ${LIBRARY_ENVIRONMENT_ANDROID_SOURCES} ${LIBRARY_ENVIRONMENT_ANDROID_HEADERS})
target_check_style(library_environment_android)
target_link_libraries(library_environment_android PUBLIC library_environment_interface PRIVATE SDL2::SDL2OE)

add_library(library_environment_implementation INTERFACE)
target_link_libraries(library_environment_implementation INTERFACE library_environment_android)
endif()
7 changes: 7 additions & 0 deletions src/Library/Environment/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.24 FATAL_ERROR)

add_subdirectory(Android)
add_subdirectory(Interface)
add_subdirectory(Posix)
add_subdirectory(Test)
add_subdirectory(Win)
10 changes: 10 additions & 0 deletions src/Library/Environment/Interface/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.24 FATAL_ERROR)

set(LIBRARY_ENVIRONMENT_INTERFACE_SOURCES)

set(LIBRARY_ENVIRONMENT_INTERFACE_HEADERS
Environment.h
EnvironmentEnums.h)

add_library(library_environment_interface INTERFACE ${LIBRARY_ENVIRONMENT_INTERFACE_SOURCES} ${LIBRARY_ENVIRONMENT_INTERFACE_HEADERS})
target_check_style(library_environment_interface)
42 changes: 42 additions & 0 deletions src/Library/Environment/Interface/Environment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include <string>
#include <memory>

#include "EnvironmentEnums.h"

class Environment {
public:
virtual ~Environment() = default;

/**
* @return Newly created standard `Environment` instance.
*/
static std::unique_ptr<Environment> createStandardEnvironment();

/**
* Windows-only function for querying the registry. Always returns an empty string on non-Windows systems.
*
* @param path Registry path to query.
* @return Value at the given path, or an empty string in case of an error.
*/
virtual std::string queryRegistry(const std::string &path) const = 0;

/**
* Accessor for various system paths.
*
* @param path Path to get.
*/
virtual std::string path(EnvironmentPath path) const = 0;

/**
* Same as `std::getenv`, but takes & returns UTF8-encoded keys and values on all platforms.
*
* Returns an empty string for non-existent environment variables, and thus doesn't distinguish between empty and
* non-existent values (and you shouldn't, either).
*
* @param key UTF8-encoded name of the environment variable to query.
* @return UTF8-encoded value of the environment variable.
*/
virtual std::string getenv(const std::string &key) const = 0;
};
Loading

0 comments on commit b417455

Please sign in to comment.