-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathparse-waves.cpp
More file actions
170 lines (152 loc) · 4.13 KB
/
parse-waves.cpp
File metadata and controls
170 lines (152 loc) · 4.13 KB
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
159
160
161
162
163
164
165
166
167
168
169
170
#include <cstring>
#pragma warning(push, 0)
#include <FL/filename.H>
#pragma warning(pop)
#include "parse-waves.h"
#include "utils.h"
Parsed_Waves::Parsed_Waves(const char *d) {
parse_waves(d);
}
std::string Parsed_Waves::get_error_message() const {
switch (_result) {
case Result::WAVES_OK:
return "OK.";
case Result::WAVES_BAD_FILE:
return "Cannot open wave samples file.";
case Result::WAVES_NO_WAVES:
return "No waves defined.";
case Result::WAVES_UNRECOGNIZED_MACRO:
return "Line " + std::to_string(_line_number) +
": Unrecognized macro.";
case Result::WAVES_TOO_FEW_SAMPLES:
return "Line " + std::to_string(_line_number) +
": Too few samples.";
case Result::WAVES_TOO_MANY_SAMPLES:
return "Line " + std::to_string(_line_number) +
": Too many samples.";
case Result::WAVES_INVALID_VALUE:
return "Line " + std::to_string(_line_number) +
": Invalid value.";
case Result::WAVES_NULL:
return "No *.asm file chosen.";
default:
return "Unspecified error.";
}
}
Parsed_Waves::Result Parsed_Waves::parse_wave(std::istringstream &lss, Wave &wave, bool nybbles) {
size_t i = 0;
for (std::string token; std::getline(lss, token, ',');) {
if (i >= NUM_WAVE_SAMPLES) {
return Result::WAVES_TOO_MANY_SAMPLES;
}
int32_t v;
if (!parse_value(token, v)) {
return Result::WAVES_INVALID_VALUE;
}
if (nybbles) {
if (v < 0 || v > 15) {
return Result::WAVES_INVALID_VALUE;
}
wave[i++] = v;
}
else {
if (v < 0 || v > 255) {
return Result::WAVES_INVALID_VALUE;
}
int32_t hi = v >> 4;
int32_t lo = v & 0x0F;
wave[i++] = hi;
wave[i++] = lo;
}
}
if (i != NUM_WAVE_SAMPLES) {
return Result::WAVES_TOO_FEW_SAMPLES;
}
return Result::WAVES_OK;
}
Parsed_Waves::Result Parsed_Waves::parse_waves(const char *d) {
char waves_file[FL_PATH_MAX] = {};
// first, try crysaudio/wave_samples.asm
strcpy(waves_file, d);
strcat(waves_file, DIR_SEP "crysaudio" DIR_SEP "wave_samples.asm");
if (try_parse_waves(waves_file) != Result::WAVES_BAD_FILE) {
return _result;
}
// second, try audio/wave_samples.asm
strcpy(waves_file, d);
strcat(waves_file, DIR_SEP "audio" DIR_SEP "wave_samples.asm");
if (try_parse_waves(waves_file) != Result::WAVES_BAD_FILE) {
return _result;
}
// third, try wave_samples.asm
strcpy(waves_file, d);
strcat(waves_file, DIR_SEP "wave_samples.asm");
if (try_parse_waves(waves_file) != Result::WAVES_BAD_FILE) {
return _result;
}
return _result;
}
static bool get_label(std::istringstream &iss, std::string &l, const std::string &scope = "") {
iss >> l;
rtrim(l, ":");
trim(l);
if (l.size() == 0) {
return false;
}
if (l[0] == '.') {
l = scope + l;
}
return true;
}
Parsed_Waves::Result Parsed_Waves::try_parse_waves(const char *f) {
_waves_file = f;
_waves_label = "";
_waves.clear();
_num_parsed_waves = 0;
_uses_dn = false;
_result = Result::WAVES_NULL;
_line_number = 0;
std::ifstream ifs;
open_ifstream(ifs, f);
if (!ifs.good()) {
return (_result = Result::WAVES_BAD_FILE);
}
while (ifs.good()) {
std::string line;
std::getline(ifs, line);
_line_number += 1;
remove_comment(line);
rtrim(line);
if (line.size() == 0) { continue; }
bool indented = is_indented(line);
std::istringstream lss(line);
if (!indented) {
if (_waves_label.size() == 0 && _waves.size() == 0) {
get_label(lss, _waves_label);
}
}
else {
std::string macro;
if (!leading_macro(lss, macro)) {
return (_result = Result::WAVES_UNRECOGNIZED_MACRO);
}
bool nybbles = equals_ignore_case(macro, "dn");
if (!nybbles && !equals_ignore_case(macro, "db")) {
return (_result = Result::WAVES_UNRECOGNIZED_MACRO);
}
_uses_dn |= nybbles;
Wave wave;
Result r = parse_wave(lss, wave, nybbles);
if (r != Result::WAVES_OK) {
return (_result = r);
}
_waves.push_back(wave);
}
}
_num_parsed_waves = (int32_t)_waves.size();
_waves.resize(16);
if (_num_parsed_waves == 0) {
return (_result = Result::WAVES_NO_WAVES);
}
return (_result = Result::WAVES_OK);
}