-
Notifications
You must be signed in to change notification settings - Fork 0
/
configs.c
158 lines (136 loc) · 3.44 KB
/
configs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
69
70
71
72
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "configs.h"
#include "log.h"
#include "utils.h"
#include <cargs.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_WIDTH 800
#define DEFAULT_HEIGHT 600
#define DEFAULT_CLOCK_SPEED 400 /* Speed in Hz */
#define MAX_CLOCK_SPEED 1000
enum {
LOG_ALL = -1,
LOG_QUIET = 0,
};
#ifdef USE_DEBUG
static int32_t log_mode = LOG_ALL;
#else
static int32_t log_mode = LOG_QUIET;
#endif
/* This is the main configuration of options available. */
static struct cag_option options[] = {
{
.identifier = 'c',
.access_letters = "c",
.access_name = "clock",
.value_name = "<int>",
.description = "Set clock speed.",
},
{
.identifier = 'w',
.access_letters = NULL,
.access_name = "width",
.value_name = "<int>",
.description = "Set window width.",
},
{
.identifier = 'h',
.access_letters = NULL,
.access_name = "height",
.value_name = "<int>",
.description = "Set window height.",
},
{
.identifier = 'v',
.access_letters = NULL,
.access_name = "verbose",
.description = "Enable log output.",
},
{
.identifier = 'q',
.access_letters = NULL,
.access_name = "quiet",
.description = "Disable log output.",
},
{
.identifier = 'a',
.access_letters = "h",
.access_name = "help",
.description = "Show help message.",
},
};
static int8_t fetch_identifier(
cag_option_context *context, configs_t *config, char identifier
);
static void set_clock(uint16_t *clock, const char *value);
static void set_width(int16_t *width, const char *value);
static void set_height(int16_t *height, const char *value);
int8_t cfg_parse_options(configs_t *config, int argc, char *argv[]) {
char identifier;
cag_option_context context;
*config = (configs_t){
.rom_filepath = "",
.clock_speed = DEFAULT_CLOCK_SPEED,
.width = DEFAULT_WIDTH,
.height = DEFAULT_HEIGHT,
};
cag_option_prepare(&context, options, CAG_ARRAY_SIZE(options), argc, argv);
while (cag_option_fetch(&context)) {
identifier = cag_option_get(&context);
if (fetch_identifier(&context, config, identifier) == STATUS_STOP) {
return STATUS_STOP;
}
}
/* Set logging mode. */
log_set_quiet(log_mode == LOG_QUIET);
memcpy(config->rom_filepath, argv[context.index], MAX_FILEPATH_SIZE);
config->rom_filepath[MAX_FILEPATH_SIZE - 1] = '\0';
return STATUS_OK;
}
static int8_t fetch_identifier(
cag_option_context *context, configs_t *config, char identifier
) {
const char *value = cag_option_get_value(context);
switch (identifier) {
case 'c':
set_clock(&config->clock_speed, value);
break;
case 'w':
set_width(&config->width, value);
break;
case 'h':
set_height(&config->height, value);
break;
case 'v':
log_mode = LOG_ALL;
break;
case 'q':
log_mode = LOG_QUIET;
break;
case 'a':
/* TODO: Better help message. */
printf("Usage: Chip8 [OPTIONS] <path-to-rom>");
cag_option_print(options, CAG_ARRAY_SIZE(options), stdout);
return STATUS_STOP;
}
return STATUS_OK;
}
static void set_clock(uint16_t *clock, const char *value) {
if (value != NULL) {
int32_t speed = strtol(value, NULL, 10);
*clock = speed > 0 && speed < MAX_CLOCK_SPEED ? speed : DEFAULT_CLOCK_SPEED;
}
}
static void set_width(int16_t *width, const char *value) {
if (value != NULL) {
int32_t size = strtol(value, NULL, 10);
*width = size != 0 ? size : DEFAULT_WIDTH;
}
}
static void set_height(int16_t *height, const char *value) {
if (value != NULL) {
int32_t size = strtol(value, NULL, 10);
*height = size != 0 ? size : DEFAULT_HEIGHT;
}
}