Skip to content

Commit

Permalink
Maniac Patch/CallCommand Update - Support Expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
jetrotal committed Jan 9, 2025
1 parent bbcb8ff commit f03f5cb
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
28 changes: 4 additions & 24 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5123,31 +5123,11 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& co

case 4: { // Expression mode - interprets its own parameters as Maniac Expressions

//TODO - LEARN HOW THIS ACTUALLY WORKS
break;

auto expression_params = MakeSpan(com.parameters).subspan(5);

// Based on the encoding pattern, each expression seems to be encoded separately
// and the parameters are already split into the format ParseExpression expects
output_args.reserve(5); // Reserve space for typical expression array elements
auto values = ManiacPatch::ParseExpressions(MakeSpan(com.parameters).subspan(5), *this);

// Find end of expressions (when encountering a value that breaks the pattern)
size_t param_count = expression_params.size();
size_t current_param = 0;
output_args.reserve(values.size());
output_args.insert(output_args.end(), values.begin(), values.end());

while (current_param < param_count) {
// Try to get all bytes until we hit the end or an invalid expression marker
auto remaining_params = MakeSpan(expression_params).subspan(current_param);

// ParseExpression will handle breaking down each parameter into bytes
int32_t result = ManiacPatch::ParseExpression(remaining_params, *this);
output_args.push_back(result);

// Move to next expression based on the pattern of bytes used
// Need to figure out exact number of parameters used by ParseExpression
current_param += 1; // This needs to be adjusted based on how many parameters each expression consumes
}
break;
}

Expand All @@ -5168,7 +5148,7 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& co
for (int i = 0; i < cmd.parameters.size(); i++) params_str += " " + std::to_string(output_args[i]);
Output::Warning("Command parameters: {}", params_str);
Output::Info("--------------------\n");
*/
//*/

// Our implementation pushes a new frame containing the command instead of invoking it directly.
// This is incompatible to Maniacs but has a better compatibility with our code.
Expand Down
29 changes: 29 additions & 0 deletions src/maniac_patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,35 @@ int32_t ManiacPatch::ParseExpression(Span<const int32_t> op_codes, const Game_Ba
return Process(beg, ops.end(), interpreter);
}

std::vector<int32_t> ManiacPatch::ParseExpressions(Span<const int32_t> op_codes, const Game_BaseInterpreterContext& interpreter) {
std::vector<int32_t> ops;
for (auto& o : op_codes) {
auto uo = static_cast<uint32_t>(o);
ops.push_back(static_cast<int32_t>(uo & 0x000000FF));
ops.push_back(static_cast<int32_t>((uo & 0x0000FF00) >> 8));
ops.push_back(static_cast<int32_t>((uo & 0x00FF0000) >> 16));
ops.push_back(static_cast<int32_t>((uo & 0xFF000000) >> 24));
}

if (ops.empty()) {
return {};
}

auto it = ops.begin();

std::vector<int32_t> results;

while (true) {
results.push_back(Process(it, ops.end(), interpreter));

if (it != ops.end() && static_cast<Op>(*it) == Op::Null) {
break;
}
}

return results;
}

std::array<bool, 50> ManiacPatch::GetKeyRange() {
std::array<Input::Keys::InputKey, 50> keys = {
Input::Keys::A,
Expand Down
3 changes: 3 additions & 0 deletions src/maniac_patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <array>
#include <cstdint>
#include <vector>
#include "span.h"

#include "game_strings.h"
Expand All @@ -29,6 +30,8 @@ class Game_BaseInterpreterContext;

namespace ManiacPatch {
int32_t ParseExpression(Span<const int32_t> op_codes, const Game_BaseInterpreterContext& interpreter);
std::vector<int32_t> ParseExpressions(Span<const int32_t> op_codes, const Game_BaseInterpreterContext& interpreter);


std::array<bool, 50> GetKeyRange();

Expand Down

0 comments on commit f03f5cb

Please sign in to comment.