34 std::unique_ptr<metaRowInfo> _last_mri;
35 std::unique_ptr<metaRowInfo> _mri;
48 _last_mri = std::make_unique<metaRowInfo>(calc);
49 _mri = std::make_unique<metaRowInfo>(calc);
53 const std::array<std::vector<int>, NUM_Skillset> pmods = { {
89 const std::array<float, NUM_Skillset> basescalers = {
90 0.F, 1.F, 1.F, 1.F, 0.93F, 1.F, 1.F, 1.F
94 virtual const std::array<std::vector<int>, NUM_Skillset>& get_pmods()
const
98 virtual const std::array<float, NUM_Skillset>& get_basescalers()
const
102 virtual void adj_diff_func(
107 const float& adj_npsbase,
109 std::array<float, NUM_Skillset>& pmod_product_cur_interval)
114 case Skill_Jumpstream: {
116 case Skill_Handstream: {
118 case Skill_JackSpeed:
120 case Skill_Chordjack:
122 case Skill_Technical:
125 pmod_product_cur_interval.at(ss) * basescalers.at(ss);
132 virtual void apply_keymode_multipliers(
133 std::vector<float>& cur_iteration_skillset_vals)
const
142 for (
auto& hand : both_hands) {
143 for (
auto& base : {TechBase}) {
146 std::fill(v.begin(), v.end(), 0.F);
158 full_agnostic_reset();
159 reset_row_sequencing();
161 run_agnostic_pmod_loop();
162 run_dependent_pmod_loop();
165 virtual void full_agnostic_reset() {
166 _gchordstream.full_reset();
171 _last_mri.get()->reset();
174 virtual void setup_agnostic_pmods() {
178 virtual void advance_agnostic_sequencing()
180 _hb.advance_sequencing(_mri->notes, _calc);
183 virtual void set_agnostic_pmods(
const int& itv) {
184 PatternMods::set_agnostic(
185 _gchordstream._pmod, _gchordstream(_mitvi), itv, _calc);
186 PatternMods::set_agnostic(_cj._pmod, _cj(_mitvi), itv, _calc);
187 PatternMods::set_agnostic(_hb._pmod, _hb(), itv, _calc);
190 virtual void run_agnostic_pmod_loop() {
191 setup_agnostic_pmods();
193 for (
auto itv = 0; itv < _calc.
numitv; ++itv) {
194 for (
auto row = 0; row < _calc.
itv_size.at(itv); ++row) {
196 const auto& ri = _calc.
adj_ni.at(itv).at(row);
198 *_last_mri, _mitvi, ri.row_time, ri.row_count, ri.row_notes);
200 advance_agnostic_sequencing();
205 swap(_mri, _last_mri);
209 set_agnostic_pmods(itv);
212 _mitvi.handle_interval_end();
215 PatternMods::run_agnostic_smoothing_pass(_calc.
numitv, _calc);
218 PatternMods::bruh_they_the_same(_calc.
numitv, _calc);
222 virtual void reset_row_sequencing() {
226 virtual void setup_dependent_mods() {
230 virtual void set_dependent_pmods(
const int& itv) {
231 PatternMods::set_dependent(
232 hand, _gstream._pmod, _gstream(_mitvghi), itv, _calc);
233 PatternMods::set_dependent(
234 hand, _gbracketing._pmod, _gbracketing(_mitvghi), itv, _calc);
237 virtual void full_hand_reset() {
240 _gstream.full_reset();
241 _gbracketing.full_reset();
246 virtual void handle_dependent_interval_end(
const int& itv) {
247 set_dependent_pmods(itv);
249 set_sequenced_base_diffs(itv);
254 virtual void set_sequenced_base_diffs(
const int& itv)
const {
258 virtual void run_dependent_pmod_loop() {
259 setup_dependent_mods();
262 for (
const auto& ids : _calc.hand_col_masks) {
269 auto row_time = s_init;
270 auto last_row_time = s_init;
271 auto any_ms = ms_init;
273 for (
auto itv = 0; itv < _calc.
numitv; ++itv) {
274 for (
auto row = 0; row < _calc.
itv_size.at(itv); row++) {
275 const auto& ri = _calc.
adj_ni.at(itv).at(row);
276 row_time = ri.row_time;
277 row_notes = ri.row_notes;
278 any_ms = ms_from(row_time, last_row_time);
279 auto masked_notes = row_notes & ids;
281 auto non_empty_cols = find_non_empty_cols(masked_notes);
282 if (non_empty_cols.empty()) {
286 for (
auto& c : non_empty_cols) {
287 lazy_jacks(c, row_time);
291 _mitvghi.handle_row(masked_notes, ids);
296 lazy_jacks.get_lowest_jack_ms(hand, _calc)) *
297 basescalers[Skill_JackSpeed] };
298 if (std::isnan(thing.second)) {
301 _calc.
jack_diff.at(hand).push_back(thing);
303 last_row_time = row_time;
305 handle_dependent_interval_end(itv);
307 PatternMods::run_dependent_smoothing_pass(_calc.
numitv, _calc);
313#if !defined(STANDALONE_CALC) && !defined(PHPCALC)
315 virtual const std::string get_calc_param_xml()
const {
316 return "Save/CalcParams_generic.xml";
319 virtual void load_calc_params_internal(
const XNode& params)
const {
320 load_params_for_mod(¶ms, _gstream._params, _gstream.name);
321 load_params_for_mod(¶ms, _gchordstream._params, _gchordstream.name);
322 load_params_for_mod(¶ms, _gbracketing._params, _gbracketing.name);
323 load_params_for_mod(¶ms, _cj._params, _cj.name);
324 load_params_for_mod(¶ms, _hb._params, _hb.name);
327 virtual XNode* make_param_node_internal(
XNode* calcparams)
const
329 calcparams->AppendChild(
330 make_mod_param_node(_gstream._params, _gstream.name));
331 calcparams->AppendChild(
332 make_mod_param_node(_gchordstream._params, _gchordstream.name));
333 calcparams->AppendChild(
334 make_mod_param_node(_gbracketing._params, _gbracketing.name));
335 calcparams->AppendChild(make_mod_param_node(_cj._params, _cj.name));
336 calcparams->AppendChild(make_mod_param_node(_hb._params, _hb.name));
343 const auto fn = get_calc_param_xml();
347 thread_local XNode params;
349 thread_local bool paramsLoaded =
false;
353 if (paramsLoaded && !bForce)
357 if (pFile ==
nullptr || bForce || !pFile->IsOpen()) {
361 if (!pFile->Open(fn, RageFile::READ))
366 if (params.ChildrenEmpty() || bForce) {
367 if (!XmlFileUtil::LoadFromFileShowErrors(params, *pFile)) {
375 params.GetAttrValue(
"vers", vers);
376 if (vers.empty() || stoi(vers) != GetCalcVersion()) {
381 load_calc_params_internal(params);
387 const auto fn = get_calc_param_xml();
388 const std::unique_ptr<XNode> xml(make_param_node());
392 if (!f.Open(fn, RageFile::WRITE)) {
395 XmlFileUtil::SaveToFile(xml.get(), f,
"",
false);
399 static auto make_mod_param_node(
400 const std::vector<std::pair<std::string, float*>>& param_map,
401 const std::string& name) ->
XNode*
403 auto* pmod =
new XNode(name);
404 for (
const auto& p : param_map) {
405 pmod->AppendChild(p.first, std::to_string(*p.second));
411 static void load_params_for_mod(
413 const std::vector<std::pair<std::string, float*>>& param_map,
414 const std::string& name)
417 const auto* pmod = node->GetChild(name);
418 if (pmod ==
nullptr) {
421 for (
const auto& p : param_map) {
422 const auto* ch = pmod->GetChild(p.first);
427 ch->GetTextValue(boat);
432 XNode* make_param_node()
const {
433 auto* calcparams =
new XNode(
"CalcParams");
434 calcparams->AppendAttr(
"vers", GetCalcVersion());
435 return make_param_node_internal(calcparams);