Skip to content

Commit

Permalink
String Var: Explicitly pass in Game_Variables
Browse files Browse the repository at this point in the history
Makes writing Unit tests easier later.
  • Loading branch information
Ghabry committed Nov 2, 2023
1 parent fc56095 commit f50c10b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 64 deletions.
68 changes: 36 additions & 32 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3614,8 +3614,8 @@ bool Game_Interpreter::CommandConditionalBranch(lcf::rpg::EventCommand const& co
int ignoreCase = com.parameters[4] >> 8 & 1;

std::string str_param = ToString(com.string);
StringView str_l = Main_Data::game_strings->GetWithMode(str_param, com.parameters[2], modes[0]+1);
StringView str_r = Main_Data::game_strings->GetWithMode(str_param, com.parameters[3], modes[1]);
StringView str_l = Main_Data::game_strings->GetWithMode(str_param, com.parameters[2], modes[0]+1, *Main_Data::game_variables);
StringView str_r = Main_Data::game_strings->GetWithMode(str_param, com.parameters[3], modes[1], *Main_Data::game_variables);
result = ManiacPatch::CheckString(str_l, str_r, op, ignoreCase);
}
break;
Expand Down Expand Up @@ -4318,7 +4318,8 @@ bool Game_Interpreter::CommandManiacShowStringPicture(lcf::rpg::EventCommand con
text.text = ToString(Main_Data::game_strings->GetWithMode(
components[1],
com.parameters[22],
delims[0] - 1
delims[0] - 1,
*Main_Data::game_variables
));
} else {
text.text = components[1];
Expand Down Expand Up @@ -4758,7 +4759,7 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
switch (fn)
{
case 0: //String <fn(string text, int min_size)>
result = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]));
result = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables));
args[1] = ValueOrVariable(modes[1], args[1]);

// min_size
Expand Down Expand Up @@ -4797,7 +4798,7 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
int pos = 0;
std::string op_string;
for (int i = 0; i < 3; i++) {
op_string += ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[i], modes[i], &pos));
op_string += ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[i], modes[i], &pos, *Main_Data::game_variables));
}
result = std::move(op_string);
break;
Expand All @@ -4808,8 +4809,8 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
std::string base, insert;

args[1] = ValueOrVariable(modes[1], args[1]);
base = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[0], modes[0], &pos));
insert = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[2], modes[2], &pos));
base = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[0], modes[0], &pos, *Main_Data::game_variables));
insert = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[2], modes[2], &pos, *Main_Data::game_variables));

result = base.insert(args[1], insert);
break;
Expand All @@ -4819,9 +4820,9 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
int pos = 0;
std::string base, search, replacement;

base = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[0], modes[0], &pos));
search = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[1], modes[1], &pos));
replacement = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[2], modes[2], &pos));
base = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[0], modes[0], &pos, *Main_Data::game_variables));
search = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[1], modes[1], &pos, *Main_Data::game_variables));
replacement = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[2], modes[2], &pos, *Main_Data::game_variables));

std::size_t index = base.find(search);
while (index != std::string::npos) {
Expand All @@ -4835,12 +4836,12 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
case 9: //Substring (subs) <fn(string base, int index, int size)>
args[1] = ValueOrVariable(modes[1], args[1]);
args[2] = ValueOrVariable(modes[2], args[2]);
result = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]).substr(args[1], args[2]));
result = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables).substr(args[1], args[2]));
break;
case 10: //Join (join) <fn(string delimiter, int id, int size)>
{
std::string op_string;
std::string delimiter = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]));
std::string delimiter = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables));

// args[1] & mode[1] relates to starting ID for strings to join
// mode 0 = id literal, 1 = direct var, 2 = var literal, 3 = direct var
Expand All @@ -4863,7 +4864,7 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
case 12: //File (file) <fn(string filename, int encode)>
{
// maniacs does not like a file extension
StringView filename = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]);
StringView filename = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables);
// args[1] is the encoding... 0 for ansi, 1 for utf8
bool do_yield;
result = Game_Strings::FromFile(filename, args[1], do_yield);
Expand All @@ -4879,17 +4880,17 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
case 13: //Remove (rem) <fn(string base, int index, int size)>
args[1] = ValueOrVariable(modes[1], args[1]);
args[2] = ValueOrVariable(modes[2], args[2]);
result = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]));
result = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables));
result = result.erase(args[1], args[2]);
break;
case 14: //Replace Ex (exRep) <fn(string base, string search, string replacement, bool first)>, edge case: the arg "first" is at ((flags >> 19) & 1). Wtf BingShan
{
int pos = 0;
std::string base, search, replacement;

base = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[0], modes[0], &pos));
search = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[1], modes[1], &pos));
replacement = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[2], modes[2], &pos));
base = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[0], modes[0], &pos, *Main_Data::game_variables));
search = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[1], modes[1], &pos, *Main_Data::game_variables));
replacement = ToString(Main_Data::game_strings->GetWithModeAndPos(str_param, args[2], modes[2], &pos, *Main_Data::game_variables));

std::regex rexp(search);

Expand All @@ -4901,43 +4902,46 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
Output::Warning("Unknown or unimplemented string sub-operation {}", op);
break;
}
if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, result, op);
if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, result, op, nullptr, *Main_Data::game_variables);
else {
if (op == 0) Main_Data::game_strings->Asg(str_params, result);
if (op == 1) Main_Data::game_strings->Cat(str_params, result);
}
break;
case 2: //toNum <fn(int var_id)> takes hex
case 3: //getLen <fn(int var_id)>
if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, result, op, args);
if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, result, op, args, *Main_Data::game_variables);
else {
if (op == 2) Main_Data::game_strings->ToNum(str_params, args[0]);
if (op == 3) Main_Data::game_strings->GetLen(str_params, args[0]);
if (op == 2) {
int num = Main_Data::game_strings->ToNum(str_params, args[0], *Main_Data::game_variables);
Main_Data::game_variables->Set(args[0], num);
}
if (op == 3) Main_Data::game_strings->GetLen(str_params, args[0], *Main_Data::game_variables);
}
break;
case 4: //inStr <fn(string text, int var_id, int begin)> FIXME: takes hex?
{
StringView search = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]);
StringView search = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables);
args[1] = ValueOrVariable(modes[1], args[1]); // not sure this is necessary but better safe
args[2] = ValueOrVariable(modes[2], args[2]);

if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, ToString(search), op, args);
else Main_Data::game_strings->InStr(str_params, ToString(search), args[1], args[2]);
if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, ToString(search), op, args, *Main_Data::game_variables);
else Main_Data::game_strings->InStr(str_params, ToString(search), args[1], args[2], *Main_Data::game_variables);
break;
}
case 5: //split <fn(string text, int str_id, int var_id)> takes hex
{
StringView delimiter = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]);
StringView delimiter = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables);
args[1] = ValueOrVariable(modes[1], args[1]);
args[2] = ValueOrVariable(modes[2], args[2]);

if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, ToString(delimiter), op, args);
else Main_Data::game_strings->Split(str_params, ToString(delimiter), args[1], args[2]);
if (is_range) Main_Data::game_strings->RangeOp(str_params, string_id_1, ToString(delimiter), op, args, *Main_Data::game_variables);
else Main_Data::game_strings->Split(str_params, ToString(delimiter), args[1], args[2], *Main_Data::game_variables);
break;
}
case 7: //toFile <fn(string filename, int encode)> takes hex
{
StringView filename = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]);
StringView filename = Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables);
args[1] = ValueOrVariable(modes[1], args[1]);

Main_Data::game_strings->ToFile(str_params, ToString(filename), args[1]);
Expand All @@ -4957,16 +4961,16 @@ bool Game_Interpreter::CommandManiacControlStrings(lcf::rpg::EventCommand const&
case 10: //exMatch <fn(string text, int var_id, int begin, int str_id)>, edge case: the only command that generates 8 parameters instead of 7
{
// takes hex
std::string expr = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0]));
std::string expr = ToString(Main_Data::game_strings->GetWithMode(str_param, args[0], modes[0], *Main_Data::game_variables));
args[1] = ValueOrVariable(modes[1], args[1]); // output var
args[2] = ValueOrVariable(modes[2], args[2]); // beginning pos

if (is_range) {
Main_Data::game_strings->RangeOp(str_params, string_id_1, expr, op, args);
Main_Data::game_strings->RangeOp(str_params, string_id_1, expr, op, args, *Main_Data::game_variables);
}
else {
if (op == 9) Main_Data::game_strings->ExMatch(str_params, expr, args[1], args[2]);
else Main_Data::game_strings->ExMatch(str_params, expr, args[1], args[2], args[3]);
if (op == 9) Main_Data::game_strings->ExMatch(str_params, expr, args[1], args[2], -1, *Main_Data::game_variables);
else Main_Data::game_strings->ExMatch(str_params, expr, args[1], args[2], args[3], *Main_Data::game_variables);
}
break;
}
Expand Down
39 changes: 22 additions & 17 deletions src/game_strings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <regex>
#include <lcf/encoder.h>
#include "async_handler.h"
#include "game_map.h"
#include "game_message.h"
#include "game_strings.h"
#include "game_switches.h"
Expand Down Expand Up @@ -49,7 +50,7 @@ StringView Game_Strings::Cat(Str_Params params, StringView string) {
return it->second;
}

int Game_Strings::ToNum(Str_Params params, int var_id) {
int Game_Strings::ToNum(Str_Params params, int var_id, Game_Variables& variables) {
if (params.string_id <= 0) {
return -1;
}
Expand All @@ -65,23 +66,25 @@ int Game_Strings::ToNum(Str_Params params, int var_id) {
else
num = static_cast<int>(std::strtol(it->second.c_str(), nullptr, 0));

Main_Data::game_variables->Set(var_id, num);
variables.Set(var_id, num);
Game_Map::SetNeedRefresh(true);
return num;
}

int Game_Strings::GetLen(Str_Params params, int var_id) const {
int Game_Strings::GetLen(Str_Params params, int var_id, Game_Variables& variables) const {
// Note: The length differs between Maniac and EasyRPG due to different internal encoding (utf-8 vs. ansi)

if (params.string_id <= 0) {
return -1;
}

int len = Get(params.string_id).length();
Main_Data::game_variables->Set(var_id, len);
variables.Set(var_id, len);
Game_Map::SetNeedRefresh(true);
return len;
}

int Game_Strings::InStr(Str_Params params, std::string search, int var_id, int begin) const {
int Game_Strings::InStr(Str_Params params, std::string search, int var_id, int begin, Game_Variables& variables) const {
if (params.string_id <= 0) {
return -1;
}
Expand All @@ -91,11 +94,12 @@ int Game_Strings::InStr(Str_Params params, std::string search, int var_id, int b
}

int index = Get(params.string_id).find(search, begin);
Main_Data::game_variables->Set(var_id, index);
variables.Set(var_id, index);
Game_Map::SetNeedRefresh(true);
return index;
}

int Game_Strings::Split(Str_Params params, const std::string& delimiter, int string_out_id, int var_id) {
int Game_Strings::Split(Str_Params params, const std::string& delimiter, int string_out_id, int var_id, Game_Variables& variables) {
if (params.string_id <= 0) {
return -1;
}
Expand All @@ -119,7 +123,7 @@ int Game_Strings::Split(Str_Params params, const std::string& delimiter, int str

// set the remaining string
Set(params, str);
Main_Data::game_variables->Set(var_id, splits);
variables.Set(var_id, splits);
return splits;
}

Expand Down Expand Up @@ -209,7 +213,7 @@ StringView Game_Strings::PopLine(Str_Params params, int offset, int string_out_i
return Get(params.string_id);
}

StringView Game_Strings::ExMatch(Str_Params params, std::string expr, int var_id, int begin, int string_out_id) {
StringView Game_Strings::ExMatch(Str_Params params, std::string expr, int var_id, int begin, int string_out_id, Game_Variables& variables) {
int var_result;
std::string str_result;
std::smatch match;
Expand All @@ -224,7 +228,8 @@ StringView Game_Strings::ExMatch(Str_Params params, std::string expr, int var_id
std::regex_search(base, match, r);

var_result = match.position() + begin;
Main_Data::game_variables->Set(var_id, var_result);
variables.Set(var_id, var_result);
Game_Map::SetNeedRefresh(true);

str_result = match.str();
if (string_out_id > 0) {
Expand All @@ -234,7 +239,7 @@ StringView Game_Strings::ExMatch(Str_Params params, std::string expr, int var_id
return str_result;
}

const Game_Strings::Strings_t& Game_Strings::RangeOp(Str_Params params, int string_id_1, std::string string, int op, int args[]) {
const Game_Strings::Strings_t& Game_Strings::RangeOp(Str_Params params, int string_id_1, std::string string, int op, int args[], Game_Variables& variables) {
if (EP_UNLIKELY(ShouldWarn(params.string_id))) {
WarnGet(params.string_id);
}
Expand All @@ -256,13 +261,13 @@ const Game_Strings::Strings_t& Game_Strings::RangeOp(Str_Params params, int stri
switch (op) {
case 0: Asg(params, string); break;
case 1: Cat(params, string); break;
case 2: ToNum(params, args[0] + (params.string_id - start)); break;
case 3: GetLen(params, args[0] + (params.string_id - start)); break;
case 4: InStr(params, string, args[1], args[2]); break;
case 5: params.string_id += Split(params, string, args[1], args[2]); break;
case 2: ToNum(params, args[0] + (params.string_id - start), variables); break;
case 3: GetLen(params, args[0] + (params.string_id - start), variables); break;
case 4: InStr(params, string, args[1], args[2], variables); break;
case 5: params.string_id += Split(params, string, args[1], args[2], variables); break;
case 8: break; // range case not applicable for popLine; see case in game_interpreter.cpp
case 9: ExMatch(params, string, args[1] + (params.string_id - start), args[2]); break;
case 10: ExMatch(params, string, args[1] + (params.string_id - start), args[2], args[3]); break;
case 9: ExMatch(params, string, args[1] + (params.string_id - start), args[2], -1, variables); break;
case 10: ExMatch(params, string, args[1] + (params.string_id - start), args[2], args[3], variables); break;
}
}
return GetData();
Expand Down
30 changes: 15 additions & 15 deletions src/game_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ class Game_Strings {
std::vector<lcf::DBString> GetLcfData() const;

StringView Get(int id) const;
StringView GetIndirect(int id) const;
StringView GetWithMode(StringView str_data, int arg, int mode) const;
StringView GetWithModeAndPos(StringView str_data, int arg, int mode, int* pos);
StringView GetIndirect(int id, const Game_Variables& variables) const;
StringView GetWithMode(StringView str_data, int arg, int mode, const Game_Variables& variables) const;
StringView GetWithModeAndPos(StringView str_data, int arg, int mode, int* pos, const Game_Variables& variables);

StringView Asg(Str_Params params, StringView string);
StringView Cat(Str_Params params, StringView string);
int ToNum(Str_Params params, int var_id);
int GetLen(Str_Params params, int var_id) const;
int InStr(Str_Params params, std::string search, int var_id, int begin = 0) const;
int Split(Str_Params params, const std::string& delimiter, int string_out_id, int var_id);
int ToNum(Str_Params params, int var_id, Game_Variables& variables);
int GetLen(Str_Params params, int var_id, Game_Variables& variables) const;
int InStr(Str_Params params, std::string search, int var_id, int begin, Game_Variables& variables) const;
int Split(Str_Params params, const std::string& delimiter, int string_out_id, int var_id, Game_Variables& variables);
static std::string FromFile(StringView filename, int encoding, bool& do_yield);
StringView ToFile(Str_Params params, std::string filename, int encoding);
StringView PopLine(Str_Params params, int offset, int string_out_id);
StringView ExMatch(Str_Params params, std::string expr, int var_id, int begin, int string_out_id = -1);
StringView ExMatch(Str_Params params, std::string expr, int var_id, int begin, int string_out_id, Game_Variables& variables);

const Strings_t& RangeOp(Str_Params params, int string_id_1, std::string string, int op, int args[] = nullptr);
const Strings_t& RangeOp(Str_Params params, int string_id_1, std::string string, int op, int args[], Game_Variables& variables);

static std::string PrependMin(StringView string, int min_size, char c);
static std::string Extract(StringView string, bool as_hex);
Expand Down Expand Up @@ -151,23 +151,23 @@ inline StringView Game_Strings::Get(int id) const {
return it->second;
}

inline StringView Game_Strings::GetIndirect(int id) const {
auto val_indirect = Main_Data::game_variables->Get(id);
inline StringView Game_Strings::GetIndirect(int id, const Game_Variables& variables) const {
auto val_indirect = variables.Get(id);
return Get(static_cast<int>(val_indirect));
}

inline StringView Game_Strings::GetWithMode(StringView str_data, int arg, int mode) const {
inline StringView Game_Strings::GetWithMode(StringView str_data, int arg, int mode, const Game_Variables& variables) const {
switch (mode) {
case 1: // direct string reference
return Get(arg);
case 2: // indirect string reference
return GetIndirect(arg);
return GetIndirect(arg, variables);
default:
return str_data;
}
}

inline StringView Game_Strings::GetWithModeAndPos(StringView str_data, int arg, int mode, int* pos) {
inline StringView Game_Strings::GetWithModeAndPos(StringView str_data, int arg, int mode, int* pos, const Game_Variables& variables) {
StringView ret;
switch (mode) {
case 0:
Expand All @@ -178,7 +178,7 @@ inline StringView Game_Strings::GetWithModeAndPos(StringView str_data, int arg,
case 1: // direct string reference
return Get(arg);
case 2: // indirect string reference
return GetIndirect(arg);
return GetIndirect(arg, variables);
default:
return ret;
}
Expand Down

0 comments on commit f50c10b

Please sign in to comment.