Skip to content

bugfix(logic): Fix broken camera edge scroll after loading a savegame from the ingame menu#2000

Merged
xezon merged 1 commit intoTheSuperHackers:mainfrom
stephanmeesters:bugfix-camera-scroll-savegame
Mar 24, 2026
Merged

bugfix(logic): Fix broken camera edge scroll after loading a savegame from the ingame menu#2000
xezon merged 1 commit intoTheSuperHackers:mainfrom
stephanmeesters:bugfix-camera-scroll-savegame

Conversation

@stephanmeesters
Copy link
Copy Markdown

@stephanmeesters stephanmeesters commented Dec 16, 2025

Closes #1922

The capture state of TheMouse includes a paused state, however this paused state is not currently reset when a new game is started. This PR addresses this by resetting the paused state in GameLogic:reset().

@stephanmeesters stephanmeesters force-pushed the bugfix-camera-scroll-savegame branch from d92da0d to 513cdf8 Compare December 16, 2025 19:13

m_rankPointsToAddAtGameStart = 0;

TheMouse->onGamePaused(FALSE);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The observation makes sense.

The implementation is not optimal. It will be better to replace

	m_pauseFrame = 0;
	m_gamePaused = FALSE;
	m_pauseSound = FALSE;
	m_pauseMusic = FALSE;
	m_pauseInput = FALSE;
	m_inputEnabledMemory = TRUE;
	m_mouseVisibleMemory = TRUE;
	m_logicTimeScaleEnabledMemory = FALSE;

with

	setGamePaused(FALSE);
	m_pauseFrame = 0;
	m_inputEnabledMemory = TRUE;
	m_mouseVisibleMemory = TRUE;
	m_logicTimeScaleEnabledMemory = FALSE;

higher up in this function and probably also in the init function.

This way other events can also properly update on pause state change.

Not sure if

	m_inputEnabledMemory = TRUE;
	m_mouseVisibleMemory = TRUE;
	m_logicTimeScaleEnabledMemory = FALSE;

still need to be reset then. I suspect it does not matter, but not sure.

Copy link
Copy Markdown
Author

@stephanmeesters stephanmeesters Dec 17, 2025

Choose a reason for hiding this comment

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

I've made the requested changes and moved the memory resets above the setGamePaused(FALSE) so that things like TheMouse->setVisibility are updated as expected

Mouse edge scroll behavior, music and sound effects and mouse appear fine after the change. I do now notice a very short audio music glitch when loading the savegame probably (confirmed) because we're now calling TheAudio->resumeAudio(AudioAffect_Music) in reset()

@xezon xezon added Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project labels Dec 16, 2025
@stephanmeesters stephanmeesters force-pushed the bugfix-camera-scroll-savegame branch 2 times, most recently from 7797d40 to 474d1da Compare December 18, 2025 11:45
@L3-M
Copy link
Copy Markdown

L3-M commented Dec 19, 2025

What is the current status of this change?
Successfully merging this pull request will not close the linked issues ( #1922 and #1999 ) with this current description. Please check GitHub Docs:

https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword

@stephanmeesters
Copy link
Copy Markdown
Author

stephanmeesters commented Dec 19, 2025

The description has been updated to link the issues.

I've been looking for a clean solution, the problem right now is that setGamePaused does not only affect state but also performs actions like resuming sounds and music, which now leads to an audio glitch when you do that in reset() or init(), which ideally is a function only concerned about state.

Also setGamePaused deals with memory variables for restoring variables which does not apply for init() and reset().

So I think either we add some parameter to setGamePaused to indicate we only want state changes and no side effects, or we keep reset() much like it was before and i will do another pass to see that we properly reset everything.

It was possible to clean up init() a bit by using reset() there see refactor commit.

@xezon
Copy link
Copy Markdown

xezon commented Dec 19, 2025

Better make the deduplication a separate refactor change to reduce the complexity of this bug fix.

As for music bug, check why it happens and try to figure out an elegant way to avoid this.

@stephanmeesters stephanmeesters force-pushed the bugfix-camera-scroll-savegame branch from 474d1da to 6dfcb89 Compare December 19, 2025 19:46
@stephanmeesters
Copy link
Copy Markdown
Author

Alright the deduplication commit is gone from this and I've added a parameter to setGamePaused to prevent resuming audio in init() and reset().

The audio mishap was because reset would resume the music, and then milliseconds later the audiomanager subsystem would also reset which does a hard stop on all sounds

@stephanmeesters stephanmeesters force-pushed the bugfix-camera-scroll-savegame branch from 7f91a78 to 3a4c348 Compare January 3, 2026 12:49
@xezon
Copy link
Copy Markdown

xezon commented Jan 3, 2026

I am confused by this change. The title says that this concerns camera edge scrolling, but the code touches resume audio code. How does this relate?

@stephanmeesters
Copy link
Copy Markdown
Author

In your first review you suggested using setGamePaused to reset the mouse, but this had the side-effect of resuming audio at a point of time you don't want it, so the extra code was added to avoid creating an audio bug.

In hindsight calling setGamePaused in reset() may not be so elegant so let me know if you want a simpler solution that doesn't touch audio

@xezon
Copy link
Copy Markdown

xezon commented Jan 3, 2026

If we can not need Bool allowResumeAudio then that would be great. I would try to understand why this audio bug happens and then try to make it robust so that pausing or unpausing would not interfere with the audio muting in undesired ways. If we need multiple reasons for muting audio, then consider introducing mute flags that are reserved for different users.

For example MuteAudio(MuteAudioReason_GamePaused), MuteAudio(MuteAudioReason_GameLoading). Something like that.

Note I did not debug this issue so I cannot accurately say what the right course of action now is, but seeing the observations in this pull and the attempted workarounds make it look brittle.

@xezon
Copy link
Copy Markdown

xezon commented Jan 28, 2026

What is the status of this change?

@stephanmeesters
Copy link
Copy Markdown
Author

I will be focusing on this again. Probably will need a separate refactor PR for the audio

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Feb 4, 2026

Greptile Summary

Replaced direct member variable assignments with proper function calls in GameLogic::reset() to ensure the mouse capture state is correctly unblocked when starting a new game, fixing the camera edge scroll issue after loading a savegame from the in-game menu.

Key changes:

  • m_gamePaused = FALSEpauseGameLogic(FALSE) - ensures proper game pause state reset
  • m_pauseInput = FALSEpauseGameInput(FALSE) - ensures TheMouse->onGamePaused(FALSE) is called to unblock mouse cursor capture
  • Changes are mirrored in both Generals and GeneralsMD codebases

Confidence Score: 5/5

  • This PR is safe to merge with no risk
  • The fix correctly addresses the root cause by ensuring proper cleanup of mouse capture state through the existing pauseGameInput() API instead of bypassing it with direct member variable assignments. The change is minimal, focused, and identical across both codebases (Generals/GeneralsMD).
  • No files require special attention

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp Replaced direct member variable assignments with proper pauseGameLogic(FALSE) and pauseGameInput(FALSE) calls to ensure mouse capture state is reset correctly
GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp Replaced direct member variable assignments with proper pauseGameLogic(FALSE) and pauseGameInput(FALSE) calls to ensure mouse capture state is reset correctly

Last reviewed commit: 1f46bfd

Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@stephanmeesters
Copy link
Copy Markdown
Author

stephanmeesters commented Feb 4, 2026

I think this should be good to go. The edge scrolling after loading is fixed, and I noticed no audio glitches anymore. Played through some skirmish/campaign/loads and sounds are normal

@stephanmeesters stephanmeesters force-pushed the bugfix-camera-scroll-savegame branch from ec0563f to 1f46bfd Compare February 23, 2026 21:23
@xezon xezon changed the title bugfix: Camera edge scroll broken after loading a savegame from ingame menu bugfix(logic): Fix broken camera edge scroll after loading a savegame from the ingame menu Feb 23, 2026
m_mouseVisibleMemory = TRUE;
m_logicTimeScaleEnabledMemory = FALSE;
pauseGameLogic(FALSE);
pauseGameInput(FALSE);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This means

	m_inputEnabledMemory = TRUE;
	m_mouseVisibleMemory = TRUE;

is set before pauseGameInput is called. Is this correct? Should not be called before?

Copy link
Copy Markdown
Author

@stephanmeesters stephanmeesters Feb 23, 2026

Choose a reason for hiding this comment

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

I think it's alright, with paused set to false and m_inputEnabledMemory set to true it will trigger an additional call to TheInGameUI->SetInputEnabled(TRUE) however very shortly after it will call the reset function of TheInGameUI and reset any changes anyway

So it should be fine regardless of order but I’ll check if swapping is more efficient here in case m_inputEnabledMemory is often false

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I had another look still think it's OK: input=enabled and mouse=visible are the right default values to enforce, plus I was only ever able to see both m_inputEnabledMemory = TRUE and m_mouseVisibleMemory = TRUE in the debugger when entering reset.

@L3-M L3-M added Gen Relates to Generals ZH Relates to Zero Hour Saveload Is Saveload/Xfer related Input labels Mar 24, 2026
@xezon xezon merged commit a7553c8 into TheSuperHackers:main Mar 24, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals Input Minor Severity: Minor < Major < Critical < Blocker Saveload Is Saveload/Xfer related ThisProject The issue was introduced by this project, or this task is specific to this project ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Camera edge scroll broken after loading a savegame from ingame menu

3 participants