Skip to content

Conversation

@jetrotal
Copy link
Contributor

@jetrotal jetrotal commented Dec 4, 2025

Implements the CommandManiacSaveImage function, allowing saving of screen or picture images to disk with options for dynamic effects and opacity. Registers the new command in ExecuteCommand and updates the header file with its declaration.

Maniac Patch: Image Saving Support

  • Added CommandManiacSaveImage to Game_Interpreter, which enables saving either the current screen or a specified picture to a PNG file. The command supports dynamic mode (applying color tone, flash, flip effects) and an option to force opaque pixels.
  • Registered the new Maniac event command (Maniac_SaveImage, command ID 3026) in the interpreter's command dispatcher, allowing it to be invoked from events.
  • Declared the new command function in the Game_Interpreter class header (game_interpreter.h).

Supporting Changes

  • Included the cache.h header in game_interpreter.cpp to support bitmap effect processing for dynamic image saving.

Implements the CommandManiacSaveImage function, allowing saving of screen or picture images to disk with options for dynamic effects and opacity. Registers the new command in ExecuteCommand and updates the header file with its declaration.
Copilot AI review requested due to automatic review settings December 4, 2025 17:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the CommandManiacSaveImage function for the Maniac Patch, enabling event commands to save either the current screen or a specified picture to disk as a PNG file. The implementation supports dynamic rendering effects (color tone, flash, flip) and an option to force opaque pixels.

Key Changes

  • Added CommandManiacSaveImage handler that supports saving screen captures or individual picture images with optional dynamic effects and opacity modifications
  • Registered the new Maniac event command (ID 3026) in the command dispatcher
  • Included cache.h header to enable bitmap effect processing

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/game_interpreter.h Declares the new CommandManiacSaveImage method in the Game_Interpreter class
src/game_interpreter.cpp Implements the save image command with screen/picture capture, dynamic effects application, opacity handling, and PNG file writing; registers command 3026 in the dispatcher; includes cache.h for bitmap effects

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Adds logic to mark pending picture requests as important and yield/repeat the async operation in CommandManiacSaveImage. This ensures that image save operations wait for picture requests to complete before proceeding.
@Ghabry
Copy link
Member

Ghabry commented Dec 7, 2025

Could you create a simple test case for me that has these things in it:

  • Save entire screen
  • Save a single image (you can use 320_240.png from the testgame) with an active spritesheet in all 4 combinations (with effects/without effects + opaque / non-opaque)

(btw wow static vs dynamic is such a awful way to name this. Why not apply effects))


To ensure this works when the save directory is redirected (e.g. web player or game inside a ZIP) FileFinder::OpenImage requires open_generic_with_fallback.


Also saving of a single picture looks pretty complicated. Will see if I can simplify this.

…d fallback on loading image

Refactored CommandManiacSaveImage to better handle opaque and effects flags, including loading cached images without transparency and applying effects only when needed. Added support for cropping spritesheet frames and ensured alpha is forced to 255 for opaque saves. Updated FileFinder to use open_generic_with_fallback for image loading.
@jetrotal
Copy link
Contributor Author

jetrotal commented Dec 7, 2025

Map0002.zip

Test cases + both output from maniacs and ours provide.

bool is_canvas = false;
if (picture.sprite && picture.sprite->GetBitmap()) {
// Canvas bitmaps have IDs starting with "Canvas:"
is_canvas = StartsWith(picture.sprite->GetBitmap()->GetId(), "Canvas:");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is a canvas bitmap?

@Ghabry
Copy link
Member

Ghabry commented Dec 15, 2025

(Note to myself thinking about reusing Sprite functionality)

What the image saving appears to do is:

  • When effects are applied its up to BlitScreenIntern but instead of doing an EffectsBlit it does a normal Blit at 0,0
  • When no effects are applied it blits bitmap instead of bitmap_effects but still uses the spritesheet (Problem: thats not supported by our Sprite code as the spritesheet is considered an "effect")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants