-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Building a battle.net replacement - need to re-capture keyboard/mouse in windowed mode #371
Comments
Are you sure you want to use SetCapture/ReleaseCapture? These functions are most of the time used incorrectly (you don't need them, they do more harm than good). And why would you hide the parent? Can't you just create a child window with the same size as the parent? Overall, you might only need to set "fixchild=0" so cnc-ddraw doesn't mess around with your child window and also set "nonexclusive=true" to make sure you are in fake fullscreen. Other than that there should be nothing you have to do |
I am fairly new to GUI programming and was following what blizzard did originally with battle.net for sc/bw. I'm not using directdraw for the ui I'm building (SFML is openGL) so it's not rendered within the cnc-ddraw window. I was trying to get the parent window location/size but GetWindowRect always just yields (0, 0, 640, 480) for the window handle I have which is of course not useful. I suppose I could try to find the window handle of the cnc-ddraw window and read that. As-is I can open my gui, call the appropriate code to create a lobby, then exit my gui but I'd like keyboard/mouse focus to automatically return to the main window once I do so. That's why I was trying to use SetCapture/ReleaseCapture. here's a quick video (with audio) showing what's going on. 2024-12-24.14-25-00.remuxed.mp4 |
cnc-ddraw does have a endless amount of hooks, all functions that return window size/position will return fake values. This is needed to trick fullscreen games to run in a window (it can't be disabled). But you can use DDGetProcAddress exported from cnc-ddraw to get the real functions. Maybe that's the problem? I don't know if the GUI framework you are using can handle all these hooks. I'm not sure if cnc-ddraw will be the best solution for what you're trying to do, adding another window that doesn't use DirectDraw would also add all kinds of limitations (upscaling wouldn't work anymore either) Edit: |
The child window is spawned from a library that's loaded (Blizzard .snp network provider files are just dlls), but it should actually still be the same process. Starcraft calls a storm function that calls a function in my library that loads the UI. I know it's not the ideal way of doing things but that's actually how blizzard designed starcraft/brood war. The original battle.net implementation hides the main window and spawns a new window for battle.net then unhides the main window when you create a game. Not sure why they didn't just integrate it in the main UI... but it's not a proper child window. Seems like I should be able to accomplish what I need with DDGetProcAddress though! |
Hm, that's strange. Can you upload me a debug log so I can check what's going on? Your window also doesn't seem to be a child window from the looks of it. #44 The original battle.net does not hide the main window BTW (I've spent a lot time with that mess!). It creates a bunch of additional top level windows (not child windows) that are layered on top of the main window. Took quite some effort to get windowed mode working, I have to move each of these windows manually when the main window is being moved around |
Here you go: Thank you for your assistance by the way! Yes. My window isn't a proper child window either. Basically doing this: ReleaseCapture();
ShowWindow(parent, SW_HIDE);
auto window = sf::RenderWindow(sf::VideoMode({1280u, 960u}), "SFML Window");
shape.setFillColor(sf::Color(100, 250, 50));
// instantly closing to keep cnc-ddraw log file small
window.close();
ShowWindow(parent, SW_SHOW);
SetFocus(parent);
SetCapture(parent); SFML has a method to create a drawing context within an existing window handle but I couldn't get it to work properly with the window handle I have. |
It does look good in the logs actually. You should only have to move the window on the exact same location as the main window and also call ShowCursor to make your cursor visible. Only problem is that when you alt+tab it would unlock your cursor, then you have to click on the window again to lock the cursor. I could probably export a function for that. But just to make it clear, if you click on the main window after your custom window was closed, is everything working fine then? |
Yes absolutely! This is merely a very small user friction point and not a
big deal at all.
…On Tue, Dec 24, 2024, 3:10 PM FunkyFr3sh ***@***.***> wrote:
It does look good in the logs actually.
You should only have to move the window on the exact same location as the
main window and also call ShowCursor to make your cursor visible.
Only problem is that when you alt+tab it would unlock your cursor, then
you have to click on the window again to lock the cursor. I could probably
export a function for that.
But just to make it clear, if you click on the main window after your
custom window was closed, is everything working fine then?
—
Reply to this email directly, view it on GitHub
<#371 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AELNPYEBYWHWST4KBAPKEWT2HHSWXAVCNFSM6AAAAABUFGRPGCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNRRGQ4DINRXGE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Ah nice! Well, I do have such code already for the original battle.net. cnc-ddraw detects when battle.net was closed and then does automatically lock the cursor. It would probably be the most simple way to do the same for your solution. If you could give your window a unique name or class name then I could detect it and lock the cursor automatically With the current name of your window it's not possible, the logic would trigger for other games as well |
That would be wonderful! How about I get a little bit farther down the
development process and reach out once I have things more finalized?
Thanks so much
…On Tue, Dec 24, 2024, 3:17 PM FunkyFr3sh ***@***.***> wrote:
Yes absolutely! This is merely a very small user friction point and not a
big deal at all.
… <#m_1275869613145864677_>
Ah nice! Well, I do have such code already for the original battle.net
it. cnc-ddraw detects when battle.net was closed and then does
automatically lock the cursor. It would probably be the most simple way to
do the same for your solution.
If you could give your window a unique name or class name then I could
detect it and lock the cursor automatically
With the current name of your window it's not possible, the logic would
trigger for other games as well
WindowName=
ClassName=STATIC
—
Reply to this email directly, view it on GitHub
<#371 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AELNPYHSEJCDOGGTBQ6CJDL2HHTQPAVCNFSM6AAAAABUFGRPGCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNRRGQ4DMMRRGE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Sure! Just let me know! If there are issues, here's also a test build with CrownLink.snp added to the hook exception list. Not sure how well that will work, you'll have to try if it's better to do it with or without hooks. Line 577 in 98ace77
This should work without DDGetProcAddress |
Hmm, not sure how much experience you have with SFML, but our best case scenario would be total ownership of the window and the ability to draw over it with SFML, it would allow us even more than just the battle.net replacements. Adding debug menus, console, overlay windows for missing UI, and etc trivial. I am not sure what it takes to do it, but probably ditching cncdraw completely, but maybe there is a way to create an SFML drawing context inside of the existing cncdraw window, redrawing what the game already draws, and forwarding the events back to original handlers. Not sure, just food for thought, something I wanted to do for a while, but haven't really investigated. Thanks for the help you have provided to @impromptu1583 EDIT: SFML or SDL |
Some guys hooked "ImGui" into cnc-ddraw and added their own custom menus to the game, maybe that's an option too? At least you don't have to create another window for that. I have never used SFML, so I don't know if the same can be done with it |
I recently built a peer to peer SNP network provider CrownLink for use with the broodwar project Cosmonarchy. I'm working on migrating it to a custom UI similar to battle.net. I'm building a custom UI with SFML.
I'm able to call
ReleaseCapture()
andShowWindow(parent, SW_HIDE)
when I load my interface, but when I want to switch back to the main UI withShowWindow(parent, SW_SHOW)
andSetCapture(parent)
the mouse/keyboard focus is not correctly captured in windowed mode. It works fine in fullscreen mode.The
parent
HWND in this scenario is passed to my code by starcraft and from my testing appears to be the actual 640x480 "fake" fullscreen window. Do you have any suggestions on making this code work properly when using CNC DDraw? Is there any API to recapture keyboard mouse so I could test if CNC DDraw is loaded then call a function to recapture keyboard/mouse?Thank you
The text was updated successfully, but these errors were encountered: