init.cpp

1
2
3
4
5
6
7
8
#include <planet/sdl/init.hpp>

#include <planet/folders.hpp>
#include <planet/log.hpp>

#include <iostream>

#include <SDL.h>

planet::sdl::configuration

14
15
namespace {
    bool try_make_folder(std::filesystem::path const &dir) {

Try to create the directory. This may not be possible on first initialisation on some platforms and there's not a lot we can do about a bad path anyway, so just ignore any errors.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
        std::error_code ec;
        std::filesystem::create_directories(dir, ec);
        if (ec) {
            planet::log::warning(
                    "Could not create save file directory", dir, "error",
                    ec.message());
            return false;
        } else {
            return true;
        }
    }
}
planet::sdl::configuration::configuration(std::string_view const appname) {
    log::active.store(log_level);
    std::filesystem::path home = base_storage_folder() / appname;
    set_game_folder(std::move(home));
}


planet::sdl::configuration::~configuration() {
    planet::log::stop_thread();
    logfile.close();
    auto const logs = log::counters::current();
    if (auto_remove_log_files and log_filename and not logs.error) {
        std::cerr << "Removing log file " << *log_filename << '\n';
        std::error_code ec;
        std::filesystem::remove(*log_filename, ec);
        if (ec) {
            std::cerr << "Error removing log file " << *log_filename << " "
                      << ec.message() << '\n';
        }
    } else {
        std::cerr << "Keeping log file\n";
    }
}


void planet::sdl::configuration::set_game_folder(std::filesystem::path path) {
    config_filename = path / "configuration";
    log_folder = path / "logs";
    save_folder = path / "saves";
    game_folder = std::move(path);

    if (try_make_folder(log_folder)) {
        auto const basename = std::to_string(
                std::chrono::duration_cast<std::chrono::seconds>(
                        std::chrono::system_clock::now().time_since_epoch())
                        .count());

These configuration items won't yet hold the values from the config file because that won't get loaded until much later...

 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
        if (save_logs_to_file) {
            log_filename = log_folder / (basename + ".plog");
            logfile.open(*log_filename, std::ios::binary);
            planet::log::log_output.store(&logfile);
        }
        if (upload_performance_data) {
            perf_filename = log_folder / (basename + ".perf");
            perfile.open(*perf_filename, std::ios::binary);
            planet::log::profile_output.store(&perfile);
        }
        log::write_file_headers();
        log::info(
                "Game path", game_folder, "configuration file", config_filename,
                "save folder", save_folder, "log file", log_filename);
    } else {
        log::info(
                "Game path", game_folder, "configuration file", config_filename,
                "save folder", save_folder, "log folder", log_folder);
    }
    try_make_folder(save_folder);
}


void planet::sdl::save(serialise::save_buffer &sb, configuration const &c) {
    sb.save_box(
            c.box, c.log_level, c.auto_remove_log_files, c.master_volume,
            c.music_volume, c.sfx_volume, c.audio_device_name,
            c.save_logs_to_file, c.upload_performance_data);
    telemetry::save_performance(sb, c.times_exited, c.times_loaded);
}
void planet::sdl::load(serialise::load_buffer &lb, configuration &c) {
    auto b = planet::serialise::load_type<planet::serialise::box>(lb);
    b.lambda(c.box, [&]() {
        b.fields(c.log_level, c.auto_remove_log_files);
        if (b.content.empty()) { return; }
        b.fields(c.master_volume, c.music_volume, c.sfx_volume);
        if (b.content.empty()) { return; }
        b.fields(c.audio_device_name);
        if (b.content.empty()) { return; }
        b.fields(c.save_logs_to_file, c.upload_performance_data);
    });
    if (not lb.empty()) {
        telemetry::load_performance(lb, c.times_exited, c.times_loaded);
    }
    log::active.store(c.log_level);

TODO Probably we need to deal with changes to the log and pref save file stuff now that the configuration has been loaded

122
}

planet::sdl::init

128
129
130
131
132
133
planet::sdl::init::init(felspar::io::warden &w, std::string_view an)
: config{an}, io{w} {
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
    static constexpr int iscapture = false;
    auto const device_count = SDL_GetNumAudioDevices(iscapture);
    if (device_count < 1) {

Apparently this can happen, but that doesn't mean that SDL will fail to be able to open one, it just means it doesn't know what is available. https://wiki.libsdl.org/SDL2/SDL_GetNumAudioDevices

139
140
141
142
143
144
145
146
147
148
149
150
151
    } else {
        for (int device = 0; device < device_count; ++device) {
            audio_device_list.push_back(
                    SDL_GetAudioDeviceName(device, iscapture));
        }
    }
    planet::log::debug(
            "Audio devices found", device_count, "device list",
            audio_device_list);
}


planet::sdl::init::~init() { SDL_Quit(); }