calref / cboe

Classic Blades of Exile
http://spiderwebforums.ipbhost.com/index.php?/forum/12-blades-of-exile/
Other
167 stars 41 forks source link

call redraw_everything() when cDialogs move #289

Closed NQNStudios closed 1 year ago

NQNStudios commented 1 year ago

Provides a partial fix for #208.

Based on this thread here it seems that SFML doesn't track an event for window movement. However, it tracks mouse movement and provides RenderWindow.getPosition(). So this patch tracks whether win.getPosition() reports a new position after a mouse movement event in cDialog. If the position has changed, it calls redraw_everything() and this fixes the artifacts left by dragging the dialog.

It's a little janky, but I've made a function pointer for redraw_everything in the cDialog class so that function can be provided in boe.main.cpp -- since it doesn't exist yet at cDialog's compile-time.

This is only a partial fix. It does not redraw over the artifacts left if the player drags the zenity file browser window, because that seems to be invoked as a subprocess and is not a cDialog.

If there are other dialogs that don't inherit cDialog, it also won't fix those cases.

And, as noted in the SFML forum thread, getPosition() won't report a window movement until the mouse has been released (very unfortunate). So the artifact will appear while you drag the dialogue, but at least it gets fixed when you finish dragging.

A real ideal solution would be if SFML provides a way to lock the buffer of the main window whenever a cDialog opens or the zenity subprocess is called. I haven't found such a feature yet, and wanted to share this partial fix as one option.

CelticMinstrel commented 1 year ago

It's kind of annoying that MacOS is smart enough not to have to do this but Windows and Linux are not, but I guess if it works, then that should be fine.

I'll do a quick check to make sure it builds on my computer and then probably merge it.

If there are other dialogs that don't inherit cDialog, it also won't fix those cases.

I think that might mean the minimap window?

NQNStudios commented 1 year ago

In testing, I’ve found that the minimap window doesn’t cause the artifact. Someone said something in the #208 discussion about this problem only affecting modal dialogs and that the map isn’t one. Could that be it?

I realized another solution that would handle all cases, and for most (maybe even all) modern games things are done this way: simply re-rendering EVERY frame.

On Wed, Jan 4, 2023 at 5:08 PM Celtic Minstrel @.***> wrote:

It's kind of annoying that MacOS is smart enough not to have to do this but Windows and Linux are not, but I guess if it works, then that should be fine.

I'll do a quick check to make sure it builds on my computer and then probably merge it.

If there are other dialogs that don't inherit cDialog, it also won't fix those cases.

I think that might mean the minimap window?

— Reply to this email directly, view it on GitHub https://github.com/calref/cboe/pull/289#issuecomment-1371565920, or unsubscribe https://github.com/notifications/unsubscribe-auth/AATXBKJQMNQLH5JKBNC7533WQYGGTANCNFSM6AAAAAATRJK7WE . You are receiving this because you authored the thread.Message ID: @.***>

CelticMinstrel commented 1 year ago

Could that be it?

Certainly.

simply re-rendering EVERY frame.

It wouldn't even need to fully re-render every frame – the terrain and most of the text-heavy areas are cached on off-screen surfaces, which there should be no need to keep updating when nothing has changed.

We do have a draw manager now. Ultimately I'd like it to be responsible for the entirety of the final phase of rendering. At that point it would be relatively easy to just call draw_all() on the main loop. But currently almost nothing is actually using the draw manager, so that's a lot of work.