Skip to content

Commit 4001c2f

Browse files
authored
Feature/remove json from config (#70)
* config: uses plain struct instead of json object * utils: changed functions to use string_view * remove cereal includes from avocado core * config: moved json parser to platform/windows package
1 parent b1f7bdc commit 4001c2f

38 files changed

+364
-322
lines changed

premake5.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ filter "options:ubsan"
4848
buildoptions {"-fsanitize=undefined"}
4949
linkoptions {"-fsanitize=undefined"}
5050

51+
newoption {
52+
trigger = "time-trace",
53+
description = "Build with -ftime-trace (clang only)"
54+
}
55+
filter "options:time-trace"
56+
buildoptions {"-ftime-trace"}
57+
linkoptions {"-ftime-trace"}
58+
59+
5160
filter {}
5261
language "c++"
5362
cppdialect "C++17"

src/bios/functions.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,20 @@
99

1010
namespace bios {
1111

12-
Function::Function(const std::string& prototype, std::function<bool(System* sys)> callback) : callback(callback) {
12+
Function::Function(std::string_view prototype, std::function<bool(System* sys)> callback) : callback(callback) {
1313
auto argStart = prototype.find('(');
1414
auto argEnd = prototype.find(')');
1515

16-
assert(argStart != std::string::npos && argEnd != std::string::npos);
17-
std::string sArgs = prototype.substr(argStart + 1, argEnd - argStart - 1);
18-
std::vector<std::string> args = split(sArgs, ", "); // TODO: do trimming
16+
assert(argStart != std::string_view::npos && argEnd != std::string_view::npos);
17+
auto sArgs = prototype.substr(argStart + 1, argEnd - argStart - 1);
18+
auto args = split(sArgs, ", ");
1919

20-
std::string sFuncName = prototype.substr(0, argStart);
21-
22-
this->name = sFuncName.c_str();
20+
this->name = prototype.substr(0, argStart);
2321
for (auto sArg : args) {
2422
sArg = trim(sArg);
2523
auto delim = sArg.find_last_of(' ');
2624

27-
if (delim == std::string::npos) {
25+
if (delim == std::string_view::npos) {
2826
throw std::runtime_error(fmt::format("{} -> Invalid parameter without type", prototype));
2927
}
3028

@@ -363,7 +361,7 @@ const std::unordered_map<uint8_t, Function> B0 = {
363361
};
364362

365363
const std::unordered_map<uint8_t, Function> C0 = {
366-
//
364+
367365
{0x00, {"EnqueueTimerAndVblankIrqs(int priority)"}},
368366
{0x01, {"EnqueueSyscallHandler(int priority)"}},
369367
{0x02, {"SysEnqIntRP(int priority, void* struc)"}}, // ;bugged, use with care
@@ -399,7 +397,7 @@ const std::unordered_map<uint8_t, Function> C0 = {
399397
const std::array<std::unordered_map<uint8_t, Function>, 3> tables = {{A0, B0, C0}};
400398

401399
const std::unordered_map<uint8_t, Function> SYSCALL = {
402-
//
400+
403401
{0x00, {"NoFunction()"}}, {0x01, {"EnterCriticalSection()"}},
404402
{0x02, {"ExitCriticalSection()"}}, {0x03, {"ChangeThreadSubFunction(int addr)"}},
405403
{0x04, {"DeliverEvent()"}},

src/bios/functions.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22
#include <cstdint>
33
#include <functional>
4-
#include <string>
4+
#include <string_view>
55
#include <unordered_map>
66
#include <vector>
77

@@ -18,15 +18,15 @@ enum class Type {
1818

1919
struct Arg {
2020
Type type;
21-
std::string name;
21+
std::string_view name;
2222
};
2323

2424
struct Function {
25-
std::string name;
25+
std::string_view name;
2626
std::vector<Arg> args;
2727
std::function<bool(System* sys)> callback;
2828

29-
Function(const std::string& prototype, std::function<bool(System* sys)> callback = nullptr);
29+
Function(std::string_view prototype, std::function<bool(System* sys)> callback = nullptr);
3030
};
3131

3232
extern const std::unordered_map<uint8_t, Function> A0;

src/config.cpp

100755100644
Lines changed: 7 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
#include "config.h"
22
#include <fmt/core.h>
3-
#include "utils/file.h"
4-
5-
const char* CONFIG_NAME = "config.json";
63

74
namespace DefaultKeyBindings {
85
// clang-format off
9-
json none() {
6+
KeyBindings none() {
107
return {
118
{"dpad_up", ""},
129
{"dpad_right", ""},
@@ -36,7 +33,7 @@ json none() {
3633
};
3734
}
3835

39-
json keyboard_wadx() {
36+
KeyBindings keyboard_wadx() {
4037
return {
4138
{"dpad_up", "keyboard|Up"},
4239
{"dpad_right", "keyboard|Right"},
@@ -65,7 +62,7 @@ json keyboard_wadx() {
6562
{"r_left", ""},
6663
};
6764
}
68-
json keyboard_numpad() {
65+
KeyBindings keyboard_numpad() {
6966
return {
7067
{"dpad_up", "keyboard|Up"},
7168
{"dpad_right", "keyboard|Right"},
@@ -95,7 +92,7 @@ json keyboard_numpad() {
9592
};
9693
}
9794

98-
json controller(int n) {
95+
KeyBindings controller(int n) {
9996
auto C = [n](const char* key) {
10097
return fmt::format("controller{}|{}", n, key);
10198
};
@@ -128,7 +125,7 @@ json controller(int n) {
128125
};
129126
}
130127

131-
json mouse() {
128+
KeyBindings mouse() {
132129
return {
133130
{"dpad_up", ""},
134131
{"dpad_right", ""},
@@ -160,103 +157,5 @@ json mouse() {
160157
// clang-format on
161158
} // namespace DefaultKeyBindings
162159

163-
// clang-format off
164-
const json defaultConfig = {
165-
{"bios", ""},
166-
{"extension", ""},
167-
{"iso", ""},
168-
{"controller", {
169-
{"1", {
170-
{"type", ControllerType::analog},
171-
{"keys", DefaultKeyBindings::keyboard_numpad()}
172-
}},
173-
{"2", {
174-
{"type", ControllerType::none},
175-
{"keys", DefaultKeyBindings::none()}
176-
}}
177-
}},
178-
{"options", {
179-
{"graphics", {
180-
{"rendering_mode", RenderingMode::software},
181-
{"widescreen", false},
182-
{"forceWidescreen", false},
183-
{"resolution", {
184-
{"width", 640u},
185-
{"height", 480u}
186-
}},
187-
{"vsync", false},
188-
{"forceNtsc", false},
189-
}},
190-
{"sound", {
191-
{"enabled", true},
192-
}},
193-
{"emulator", {
194-
{"preserveState", true},
195-
{"timeTravel", true},
196-
}},
197-
}},
198-
{"debug", {
199-
{"log", {
200-
{ "bios", 0u },
201-
{ "cdrom", 0u },
202-
{ "controller", 0u },
203-
{ "dma", 0u },
204-
{ "gpu", 0u },
205-
{ "gte", 0u },
206-
{ "mdec", 0u },
207-
{ "memoryCard", 0u },
208-
{ "spu", 0u },
209-
{ "system", 1u },
210-
}}
211-
}},
212-
{"memoryCard", {
213-
{"1", "data/memory/card1.mcr"},
214-
{"2", ""}
215-
}},
216-
{"gui", {
217-
{"lastPath", ""},
218-
}},
219-
};
220-
// clang-format on
221-
222-
json config = defaultConfig;
223-
224-
json fixObject(json oldconfig, json newconfig) {
225-
for (auto oldField = oldconfig.begin(); oldField != oldconfig.end(); ++oldField) {
226-
auto newField = newconfig.find(oldField.key());
227-
228-
// Add nonexisting fields
229-
if (newField == newconfig.end()) {
230-
newconfig.emplace(oldField.key(), oldField.value());
231-
continue;
232-
}
233-
234-
// Repair these with invalid types
235-
if (newField.value().type() != oldField.value().type()) {
236-
newconfig[oldField.key()] = oldField.value();
237-
continue;
238-
}
239-
240-
// If field is an object or an array - fix it recursively
241-
if (newField.value().is_object() || newField.value().is_array()) {
242-
newconfig[oldField.key()] = fixObject(oldField.value(), newField.value());
243-
}
244-
}
245-
return newconfig;
246-
}
247-
248-
void saveConfigFile(const char* configName) { putFileContents(configName, config.dump(4)); }
249-
250-
void loadConfigFile(const char* configName) {
251-
auto file = getFileContents(configName);
252-
if (file.empty()) {
253-
saveConfigFile(configName);
254-
return;
255-
}
256-
nlohmann::json newconfig = json::parse(file.begin(), file.end());
257-
258-
// Add missing and repair invalid fields
259-
config = fixObject(config, newconfig);
260-
}
261-
262-
bool isEmulatorConfigured() { return !config["bios"].get<std::string>().empty(); }
160+
const avocado_config_t defaultConfig;
161+
avocado_config_t config = defaultConfig;

src/config.h

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
2-
#include <nlohmann/json.hpp>
32
#include <string>
3+
#include <unordered_map>
44
#include "device/controller/controller_type.h"
55
#include "device/gpu/rendering_mode.h"
66
#include "utils/event.h"
@@ -10,20 +10,87 @@
1010
#define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "AVOCADO", __VA_ARGS__);
1111
#endif
1212

13-
using json = nlohmann::json;
13+
using KeyBindings = std::unordered_map<std::string, std::string>;
1414

1515
namespace DefaultKeyBindings {
16-
json none();
17-
json keyboard_wadx();
18-
json keyboard_numpad();
19-
json mouse();
20-
json controller(int n);
16+
KeyBindings none();
17+
KeyBindings keyboard_wadx();
18+
KeyBindings keyboard_numpad();
19+
KeyBindings mouse();
20+
KeyBindings controller(int n);
2121
} // namespace DefaultKeyBindings
2222

23-
extern const char* CONFIG_NAME;
24-
extern const nlohmann::json defaultConfig;
25-
extern nlohmann::json config;
26-
void saveConfigFile(const char* configName);
27-
void loadConfigFile(const char* configName);
23+
struct avocado_config_t {
24+
std::string bios = "";
25+
std::string extension = "";
26+
std::string iso = "";
2827

29-
bool isEmulatorConfigured();
28+
struct {
29+
ControllerType type;
30+
KeyBindings keys;
31+
} controller[2]{
32+
{
33+
ControllerType::analog,
34+
DefaultKeyBindings::keyboard_numpad(),
35+
},
36+
{
37+
ControllerType::none,
38+
DefaultKeyBindings::none(),
39+
},
40+
};
41+
42+
struct {
43+
struct {
44+
RenderingMode renderingMode = RenderingMode::software;
45+
bool widescreen = false;
46+
bool forceWidescreen = false;
47+
struct {
48+
unsigned int width = 640;
49+
unsigned int height = 480;
50+
} resolution;
51+
bool vsync = false;
52+
bool forceNtsc = false;
53+
} graphics;
54+
55+
struct {
56+
bool enabled = true;
57+
} sound;
58+
59+
struct {
60+
bool preserveState = true;
61+
bool timeTravel = false;
62+
} emulator;
63+
64+
} options;
65+
66+
struct {
67+
struct {
68+
int bios = 0;
69+
int cdrom = 0;
70+
int controller = 0;
71+
int dma = 0;
72+
int gpu = 0;
73+
int gte = 0;
74+
int mdec = 0;
75+
int memoryCard = 0;
76+
int spu = 0;
77+
int system = 1;
78+
} log;
79+
} debug;
80+
81+
struct {
82+
std::string path;
83+
} memoryCard[2]{
84+
{"data/memory/card1.mcr"}, //
85+
{""}, //
86+
};
87+
88+
struct {
89+
std::string lastPath = "";
90+
} gui;
91+
92+
// Methods
93+
bool isEmulatorConfigured() const { return !bios.empty(); }
94+
};
95+
96+
extern avocado_config_t config;

src/cpu/gte/gte.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ constexpr std::array<uint8_t, 0x101> GTE::generateUnrTable() {
1717
}
1818

1919
void GTE::reload() {
20-
widescreenHack = config["options"]["graphics"]["forceWidescreen"];
21-
logging = config["debug"]["log"]["gte"].get<int>();
20+
widescreenHack = config.options.graphics.forceWidescreen;
21+
logging = config.debug.log.gte;
2222
}
2323

2424
uint32_t GTE::read(uint8_t n) {

src/device/cdrom/cdrom.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace device {
1212
namespace cdrom {
1313

1414
CDROM::CDROM(System* sys) : sys(sys) {
15-
verbose = config["debug"]["log"]["cdrom"];
15+
verbose = config.debug.log.cdrom;
1616
disc = std::make_unique<disc::Empty>();
1717
}
1818

src/device/controller/controller.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Controller::~Controller() { bus.unlistenAll(busToken); }
5454
void Controller::reload() {
5555
auto createDevice = [](int num) -> std::unique_ptr<peripherals::AbstractDevice> {
5656
num += 1;
57-
ControllerType type = config["controller"][std::to_string(num)]["type"];
57+
ControllerType type = config.controller[num - 1].type;
5858
if (type == ControllerType::digital) {
5959
return std::make_unique<peripherals::DigitalController>(num);
6060
} else if (type == ControllerType::analog) {
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
#pragma once
2-
#include "utils/json_enum.h"
3-
42
enum class ControllerType {
53
none,
64
digital,
75
analog,
86
mouse,
9-
};
10-
11-
JSON_ENUM(ControllerType);
7+
};

0 commit comments

Comments
 (0)