Skip to content

Commit 4aeebe0

Browse files
committed
Maniacs Patch - GetGameInfo (pixel data extraction
Added support for the 'Pixel Info' option in the CommandManiacGetGameInfo function. This captures a screen region, extracts pixel data as packed AARRGGBB values, and stores them in game variables, matching Maniacs behavior. Out-of-bounds pixels are skipped, and alpha is forced to opaque.
1 parent 8e20078 commit 4aeebe0

File tree

1 file changed

+73
-3
lines changed

1 file changed

+73
-3
lines changed

src/game_interpreter.cpp

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4206,10 +4206,79 @@ bool Game_Interpreter::CommandManiacGetGameInfo(lcf::rpg::EventCommand const& co
42064206
Main_Data::game_variables->Set(var, Player::screen_width);
42074207
Main_Data::game_variables->Set(var + 1, Player::screen_height);
42084208
break;
4209-
case 3: // Get pixel info
4210-
// FIXME: figure out how 'Pixel info' works
4211-
Output::Warning("GetGameInfo: Option 'Pixel Info' not implemented.");
4209+
case 3: {
4210+
// 1. Decode Parameters
4211+
// [0] contains packed modes (4 bits each)
4212+
int p_x = ValueOrVariableBitfield(com.parameters[0], 0, com.parameters[3]);
4213+
int p_y = ValueOrVariableBitfield(com.parameters[0], 1, com.parameters[4]);
4214+
int p_w = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[5]);
4215+
int p_h = ValueOrVariableBitfield(com.parameters[0], 3, com.parameters[6]);
4216+
// Destination variable ID is direct in parameter 7
4217+
int dest_var_id = com.parameters[7];
4218+
4219+
bool ignore_alpha = (com.parameters[2] & 1) != 0;
4220+
4221+
// 2. Capture Screen
4222+
// Creates a snapshot of the current frame
4223+
BitmapRef screen = DisplayUi->CaptureScreen();
4224+
if (!screen) return true;
4225+
4226+
// 3. Prepare for Raw Access
4227+
// Ensure format is 32-bit (4 bytes per pixel)
4228+
if (screen->bpp() != 4) {
4229+
//Output::Debug("ManiacGetGameInfo: Screen capture is not 32-bit.");
4230+
//return true;
4231+
}
4232+
4233+
int screen_w = screen->GetWidth();
4234+
int screen_h = screen->GetHeight();
4235+
4236+
// Sanitize
4237+
if (p_w <= 0 || p_h <= 0) return true;
4238+
4239+
uint32_t* pixels = static_cast<uint32_t*>(screen->pixels());
4240+
int pitch = screen->pitch() / 4; // stride in uint32 elements
4241+
4242+
auto& variables = *Main_Data::game_variables;
4243+
4244+
int var_idx = 0;
4245+
uint8_t r = 0, g = 0, b = 0, a = 0;
4246+
4247+
// 4. Read Loop
4248+
for (int iy = 0; iy < p_h; ++iy) {
4249+
int sy = p_y + iy;
4250+
4251+
// If row out of bounds, skip variables for this row
4252+
if (sy < 0 || sy >= screen_h) {
4253+
var_idx += p_w;
4254+
continue;
4255+
}
4256+
4257+
for (int ix = 0; ix < p_w; ++ix) {
4258+
int target_var = dest_var_id + var_idx++;
4259+
int sx = p_x + ix;
4260+
4261+
if (sx >= 0 && sx < screen_w) {
4262+
uint32_t raw_pixel;
4263+
4264+
if (!ignore_alpha) {
4265+
raw_pixel = pixels[sy * pitch + sx];
4266+
// Convert backend format to standard RGBA
4267+
Bitmap::pixel_format.uint32_to_rgba(raw_pixel, r, g, b, a);
4268+
4269+
//Maniacs has no transparency beneath parallax layer
4270+
a = 255;
4271+
}
4272+
4273+
// Maniacs format: Signed 32-bit AARRGGBB
4274+
uint32_t packed = (a << 24) | (r << 16) | (g << 8) | b;
4275+
variables.Set(target_var, static_cast<int32_t>(packed));
4276+
}
4277+
// Else: Out of bounds, do nothing.
4278+
}
4279+
}
42124280
break;
4281+
}
42134282
case 4: // Get command interpreter state
42144283
{
42154284
// Parameter "Nest" in the English version of Maniacs
@@ -6045,3 +6114,4 @@ bool Game_Interpreter_Inspector::IsInActiveExcecution(Game_CommonEvent const& ce
60456114
}
60466115
return ce.interpreter && ce.interpreter->IsRunning();
60476116
}
6117+
////////////

0 commit comments

Comments
 (0)