|
Currently buggy! dosbox and me are working on it, if you wanna help, read the last posts and try the lastest stuff, thx.
Hey Hou
I think everyone knows about the annoying Windows 7 crash problem. There are several ways how to lower the chance of a freeze (f.e. closing explorer.exe) and others to get no freezes at all anymore but instead the b.net interface fucks up (ddraw to opengl mapping).
The only solution I know which has no problems is playing in window mode with Xenotrons wmode plugin. At home I have 2 monitors so I'm using my second monitor in 640x480 mode and like this I can play BroodWar in "fullscreen" without any freezes.
On my Netbook I don't have this option, so I could use a different fix, like running ICCup Launcher (Or ChaosLauncher or whatever) in compatibility mode (640x480) this is bad because I can't alt+tab into another resolution anymore and adjusting the bw windows sucks too.
As I was unhappy with all the current "solutions" I made myself a little program which checks if BroodWar is the foreground window and if it is the resolution is changed to 640x480. If you alt tab out of BroodWar the resolution is restored to what you used when the proggy is started.
There is currently an issue with mouse scrolling, sometimes it wont work right, all you need to do is press alt+f1 (cursor capture for wmode) once or twice and its fine again.
I tested it on my Netbook and it worked fine so far. But there are still a lot of things that could be made better or which could not work on more complex setups (multi monitor, multi graphics card, ...) If you get problems either let me know or fix the code yourself. + Show Spoiler +#include <windows.h> #include <stdio.h>
DEVMODE lastDevmode; DEVMODE devmodeBW; int exitThread = 0;
// Constant Values const int BW_FULL_POS_X = -5; const int BW_FULL_POS_Y = -31; const int BW_WIDTH = 650; const int BW_HEIGHT = 517;
// FUNCTION PROTOTYPES DEVMODE GetCurrentDeviceMode(); int CheckForegroundWindow(); bool IsBroodWarWindow(HWND hWnd);
int main(char argc, char* argv[]) { printf("Press Alt+F1 if you can't scroll inside BW.\n"); printf("Press Alt+F11 to make BW the TOPMOST window.\n"); printf("press any key to exit...");
DEVMODE d = GetCurrentDeviceMode(); if (d.dmSize == 0) { ExitProcess(1); } memcpy(&lastDevmode, &d, sizeof(DEVMODE)); memcpy(&devmodeBW, &d, sizeof(DEVMODE)); devmodeBW.dmPelsWidth = 640; devmodeBW.dmPelsHeight = 480;
DWORD threadId = 0; HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)CheckForegroundWindow, 0, 0, &threadId);
getchar(); exitThread = 1; ChangeDisplaySettings(&lastDevmode, 0); }
DEVMODE GetCurrentDeviceMode() { DISPLAY_DEVICE d; DEVMODE devMode; d.cb = sizeof(DISPLAY_DEVICE); devMode.dmSize = sizeof(DEVMODE); int devNum = 0; int result = 0; do { result = EnumDisplayDevices(0, devNum, &d, 0); // check if it's the main device if (result && ((d.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)) { EnumDisplaySettings(d.DeviceName, -1, &devMode); return devMode; } devNum++; } while (result);
// Current Devicemode not found devMode.dmSize = 0; return devMode; }
int CheckForegroundWindow() { HWND hWndBW = 0; bool isInsideBW = false;
while(!exitThread){ // check if BroodWar is started, if not we wait for it do { Sleep(250); hWndBW = FindWindow("SWarClass", 0); } while (!hWndBW);
// BroodWar is running, check if it's the ForeGroundWindow HWND fgWindow = GetForegroundWindow(); if (IsBroodWarWindow(fgWindow)) { if (!isInsideBW) { ChangeDisplaySettings(&devmodeBW, 0); } isInsideBW = true; } else { if (isInsideBW) { ChangeDisplaySettings(&lastDevmode, 0); } isInsideBW = false; }
// adjust the broodwar window position RECT rectBW; GetWindowRect(hWndBW, &rectBW); if (isInsideBW && (rectBW.left != BW_FULL_POS_X || rectBW.top != BW_FULL_POS_Y)) { SetWindowPos(hWndBW, 0, BW_FULL_POS_X, BW_FULL_POS_Y, BW_WIDTH, BW_HEIGHT, 0); } if (!isInsideBW && rectBW.left == BW_FULL_POS_X && rectBW.top == BW_FULL_POS_Y) { // Reset the BW window position so it can be draged again SetWindowPos(hWndBW, 0, 0, 0, BW_WIDTH, BW_HEIGHT, 0); } }
return 0; }
bool IsBroodWarWindow(HWND hWnd) { char szWindowClass[255]; int size = RealGetWindowClass(hWnd, szWindowClass, 255); int cmpSWC = strncmp(szWindowClass, "SWarClass", 9); int cmpSDD = strncmp(szWindowClass, "#32770", 6); // b.net's ugly interface
return (cmpSWC == 0) || (cmpSDD == 0); } (I used MS Visual Studio 2010, I didn't pay any attention to make it standard C or anything)
Download the exe from here If you get an error that you need to reinstall, try installing the MSVC2010 runtimes from here
|
A while ago, blizzard released a patch fixing the color issue. Personally I've never really suffered from BW crashing very often (maybe once every 100 games), but friends of mine have downloaded that color fix and say that it solved their problem.
But this sounds like a nifty fix for people who rely on WM to not crash. I remember watching my friend change his screen resolution every time he wanted to play BW before we discovered the color fix.
http://us.blizzard.com/support/article.xml?locale=en_US&articleId=36371&pageNumber=1&searchQuery=windows 7
|
Hm I have a different problem when I'm playing, I get the color bug & the crashes but that's not what is the most annoying. I get small delay/lagg in every game which makes it unplayable, does anyone know a fix for that? (windows 7 x64)
|
On July 22 2011 20:12 MeyerA wrote: Hm I have a different problem when I'm playing, I get the color bug & the crashes but that's not what is the most annoying. I get small delay/lagg in every game which makes it unplayable, does anyone know a fix for that? (windows 7 x64)
Are these for online games or does it affect singleplayer as well?
|
I use the color fix from blizzard and my BW has not crashed once, using win 7 64 bit.
|
hi WhuazGoodJaggah,
this seems like a good trick to use w-mode as a power house as it already has the bnet interface hack in place. i cannot confirm how well would it work in general, but it _might_ mess up people's desktop icon placement at least, if they have a lot of them and more spread out.
on the other hand relying less on old ddraw code to render at newer os versions, being in full screen or window mode might be a good general idea for the future and that's why there are some projects out there that try to (plan and) solve this...if possible.
here is an ugly mod to "listen" for bw (edit: cleanup, safer exit):
+ Show Spoiler + #include <windows.h> #include <stdio.h>
DEVMODE lastDevmode; DEVMODE devmodeBW; int mainDevice = 0; HWND hWndBW = 0; // HWND lastForegroundWindow = 0; int exitThread = 0; BOOL WaitFlag = TRUE; BOOL WasInBW = FALSE; // BOOL inBnet = FALSE;
// Constant Values const int BW_FULL_POS_X = -5; const int BW_FULL_POS_Y = -32; const int BW_WEIGHT = 650; const int BW_HEIGHT = 517;
// FUNCTION PROTOTYPES DEVMODE GetCurrentDeviceMode(); int CheckForegroundWindow(); HWND FindBW();
//int main(int argc, char* argv[]) { int main(void) { DWORD threadId; HANDLE hThread; DEVMODE d;
d = GetCurrentDeviceMode(); if (!d.dmSize) ExitProcess(1);
memcpy(&lastDevmode, &d, sizeof(DEVMODE)); memcpy(&devmodeBW, &d, sizeof(DEVMODE)); devmodeBW.dmPelsWidth = 640; devmodeBW.dmPelsHeight = 480;
printf("Press Alt+F1 if you can't scroll inside BW.\n"); printf("Press any key to exit...\n\n"); if (FindBW()) printf("BW seems to be active on start.\n"); threadId = 0; hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)CheckForegroundWindow, 0, 0, &threadId);
getchar();
printf("Exiting...\n"); exitThread = 1; CloseHandle(hThread); ExitProcess(1); }
DEVMODE GetCurrentDeviceMode() { int devNum = 0; int result = 0; DISPLAY_DEVICE d; DEVMODE devMode; d.cb = sizeof(DISPLAY_DEVICE); memset(&devMode, 0, sizeof(DEVMODE));
do { result = EnumDisplayDevices(0, devNum, &d, 0); // check if it's the main device if (result && ((d.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)) { EnumDisplaySettings(d.DeviceName, (DWORD)-1, &devMode); devMode.dmSize = sizeof(DEVMODE); return devMode; } devNum++; } while (result);
// Current Devicemode not found, exiting process printf("Current Devicemode not found, exiting process.\n"); return devMode; }
int CheckForegroundWindow() { while(!exitThread) { if (FindBW()) { if (!WaitFlag) { printf("BW Found.\n"); WaitFlag = TRUE; } if (GetForegroundWindow() == hWndBW) { ChangeDisplaySettings(&devmodeBW, 0); SetWindowPos(hWndBW, 0, BW_FULL_POS_X, BW_FULL_POS_Y, BW_WEIGHT, BW_HEIGHT, 0); WasInBW = TRUE; } else { if (WasInBW) { // Reset the BW window position so it can be draged again ChangeDisplaySettings(&lastDevmode, 0); SetWindowPos(hWndBW, 0, 0, 0, BW_WEIGHT, BW_HEIGHT, 0); WasInBW = FALSE; } } } else { if (WaitFlag) { printf("Waiting for BW...\n"); ChangeDisplaySettings(&lastDevmode, 0); WaitFlag = FALSE; } } Sleep(50); } return 0; }
// Find BW HWND FindBW(void) { hWndBW = 0; if (!FindWindow("SDlgDialog", 0)) { hWndBW = FindWindow("SWarClass", 0); } return hWndBW; }
dosbox
|
Lol so all this does is save like two clicks to change the resolution manually? The real problem with wmode is the sluggish mouse.
|
On July 24 2011 04:54 djcube wrote: Lol so all this does is save like two clicks to change the resolution manually? The real problem with wmode is the sluggish mouse.
you can not change the resolution to 640x480 in win 7 as microsoft decided to only allow 800x600 as lowest resolution. I really don't feel any difference for mouse interface be it on my netbook or my desktop (both with wmode in 640x480). If you feel strange behaviour you may need to check your chaos plugin settings, as they are different for fullscreen and window mode.
@dosbox I'll check your changes tomorrow when I'm not as drunk as I'm right now btw. i have a lot of icons on my desktop and it was a concern for me too, but as of now the icons didnt get messed up, but if they do, I know already how to handle it
|
Ah I see. I didn't realize the lowest resolution through the W7 interface was 800x600. I always used Catalyst Control Center to change it to the lowest possible. The mouse doesn't feel any slower/sluggish when you play on wmode, though? It happens when I choose the option to enclose the mouse cursor within the window.
|
On July 24 2011 08:37 djcube wrote: Ah I see. I didn't realize the lowest resolution through the W7 interface was 800x600. I always used Catalyst Control Center to change it to the lowest possible. The mouse doesn't feel any slower/sluggish when you play on wmode, though? It happens when I choose the option to enclose the mouse cursor within the window. I agree with djcube on this one. I set the resolution of iccup launcher to 640x480 and then run bw in windows mode to make it feel like it's feel screen. However the main problem is the mouse feels so sluggish it's almost impossible to play. I even resort to just not using windows mode and risking the crashes just to avoid the sluggish mouse. Does anyone have a fix for this?
|
On July 22 2011 20:56 Lorch wrote: I use the color fix from blizzard and my BW has not crashed once, using win 7 64 bit.
the colour fix is not related to the FREEZE. its not a crash, the game continues running but the system does not update the display or input.
the colour fix is also only applicable to the stock english binary for BW as the other language binaries change the appid.
|
[B] you can not change the resolution to 640x480 in win 7 as microsoft decided to only allow 800x600 as lowest resolution.
False, the application properties has a compatibility option to set 640x480, the limitation only applies to the windows resolution properties. Other applications can set 640x480 (like the NVCP/CCC)
|
On July 26 2011 20:23 squall leonhart wrote:Show nested quote +[B] you can not change the resolution to 640x480 in win 7 as microsoft decided to only allow 800x600 as lowest resolution. False, the application properties has a compatibility option to set 640x480, the limitation only applies to the windows resolution properties. Other applications can set 640x480 (like the NVCP/CCC)
I wrote about the compatibility mode in the first post. My code will change the resolution to 640x480 so I'm aware that I can do it with other software than the microsoft resolution changer. The convenience this code offers, is that it switches the resolution on "alt+tab" out of and in to broodwar.
|
What I've done before when running in wmode seems a lot easier than this. right-click the bw launcher you're using (mini/iccup etc) -> properties -> compatibility: Run with 640*480 res. When done playing, just remember to close the launcher aswell to get back to the original resolution.
Scratch that, this is actually a lot easier when I got it working correctly.
|
how is it easier to use compatibility mode than this?
the effect is the same (broodwar in 640x480) if you want to browse tl.net while playing bw (waiting for a friend or game or whatever) you simply alt tab and get back to your old resolution, with compatibility mode the resolution stays at 640x480. another problem I had with compatibility mode is that I sometimes had to adjust the window position as the bw window in wmode is bigger than 640x480. the third problem I have with ICC launcher f.e. is that its always hidden in the tray icons place so its a bitch to close it to get back to your normal resolution.
|
This looks an awesome little app Whuazgood! I'll try this on my laptop tomorrow, hopefully without bugs ^_^
|
as i've said above i confirm that this solution is a good one.
if wmode works ok for you in general and if you need to play and stream(!) bw in fullscreen under windows 7 or any other OS, you can use this...for streaming works good with vhscrcap + fme and you can also use "bcoverlay" for overlays, but you might get some flickering and have to disable the window focus for the overlay (f10).
here is the modified version from WhuazGoodJaggah's original that listens for broodwar (you can start the win7fixforbw.exe before or after bw is already started).
http://dl.dropbox.com/u/28720954/bw_fixes/win7fixforbw.exe (9 kb)
|
Hey Whuazgood and Dosbox thanks for writing these things up!
Dosbox, I was using your version and everytime I'm at battle.net logon screen or in chat channels it jumps me to desktop, but once I'm in gamelobby in flips me back to 640x480, is there anyway to stop this from happening? Also, how would this affect livestreaming, would teh colors mess up?
|
hello Armathai,
here is a small fix for a possible crash (mod updated in the code above as well): http://dl.dropbox.com/u/28720954/bw_fixes/win7fixforbw.exe
basically when bw enters bnet, it starts using windows widgets like buttons and pretty much conducts into one of the most *horrific game interfaces* ever written by blizzard or any one else. xenotron's w-mode code (and other people's attempts) compensates for all that so that broodwar works in window mode, however this now starts to conflict with Whuazgood's idea as it does not account for that at all.
it is possible to run the bnet interface fullscreen with the "win7fixforbw.exe" idea, however this is very unstable at this point, so for now bnet will make it exit fullscreen and re-enter again when in game.
the stream will not be affected much, apart from the streaming content (bw / bnet window) being shifted slightly out of the screen for the viewers. (afaik)
regards --
|
You are right.
When the b.net interface is up, the SWarClass window is not the topmost anymore, this causes the resolution change. I will change the code a little so it wont change the resolution if SDlgDialog is top most, maybe this will help.
The streaming is possible just like when you stream with normal window mode, so you can use procaster or xsplit or whatever.
|
On July 30 2011 01:39 WhuazGoodJaggah wrote: You are right.
When the b.net interface is up, the SWarClass window is not the topmost anymore, this causes the resolution change. I will change the code a little so it wont change the resolution if SDlgDialog is top most, maybe this will help.
The streaming is possible just like when you stream with normal window mode, so you can use procaster or xsplit or whatever.
to spare you some time perhaps, one major problem is that blizzard wrote all their widgets relative to the screen 0,0 and thats why w-mode or any other alternative "solution" has to be in the lines of 3k lines of code and consider every single widget. last time i've hooked into bw, there were many instances of "SDlgDialog"...
w-mode grabs all those widgets and renders them relative to the window 0,0 position on move. so basically you might need to hook w-mode, find its *main* window when in bnet, move it -5, -32, but also trigger correctly that "relocation" of all those child widgets along with it.
some of the above are just speculations...
btw you can use my mod version above - its working ok and compiling without warnings with msvc / gcc...
|
I have been trying to get my BW to stop crashing in win7 for a few weeks now and I'm getting desperate.
I use the exe that kills explorer and launches the Iccup launcher as well the color fix patch from blizz but my game continues to crash though the colors are fine.
I would like to try the solution in the OP but I kind of clueless about how or why its supposed to work. If I understand correctly it allows me to run BW in windowed mode which will stop the crash but fullscreens it while keeping it at the lowest resolution so that its not too small to play.
If anyone can explain how I can get this working I would appreciate it. I downloaded the exe but when it runs I get a system error, "this program can't start because MSVCR 100.dll is missing from your computer. Try reinstalling the program to fix this problem."
I appreciate any help, I miss and this fix seems very promising.
|
On July 22 2011 19:54 Zyferous wrote:A while ago, blizzard released a patch fixing the color issue. Personally I've never really suffered from BW crashing very often (maybe once every 100 games), but friends of mine have downloaded that color fix and say that it solved their problem. But this sounds like a nifty fix for people who rely on WM to not crash. I remember watching my friend change his screen resolution every time he wanted to play BW before we discovered the color fix. http://us.blizzard.com/support/article.xml?locale=en_US&articleId=36371&pageNumber=1&searchQuery=windows 7 I never knew about this :O I was still using the kill explorer thing.
|
Allright, I updated the first post with a new version and added a spoilertag for the updated code. I added all of dosbox' suggestions so you can start the prog now before or after you start bw. The b.net interface shouldn't cause any resolution changes anymore, but since I implemented that a little bit different than dosbox, it might not work for others, please let me know.
@Armathai I tested streaming with Livestream ProCaster and it worked (my pc is way to slow, but no graphic errors)
@Azerbaijan I forgot to post a link to the MSVC runtime sutff, I added the link to the first post. http://www.microsoft.com/download/en/details.aspx?id=5555 download and install this and the error should be gone.
@djcube & peanutter I conntacted XeNotRoN and told him the issue with the sluggish mouse, we will see whats possible.
|
United Kingdom1689 Posts
On July 22 2011 20:12 MeyerA wrote: Hm I have a different problem when I'm playing, I get the color bug & the crashes but that's not what is the most annoying. I get small delay/lagg in every game which makes it unplayable, does anyone know a fix for that? (windows 7 x64)
Hi Meyera- I saw you at Dreamhack ^^.
I've noticed that odd problem on my brother's computer, but I've never had it on any of mine. It feels like the game is too fast for the hardware (absurd of course).
|
On July 30 2011 18:46 WhuazGoodJaggah wrote: Allright, I updated the first post with a new version and added a spoilertag for the updated code. I added all of dosbox' suggestions so you can start the prog now before or after you start bw. The b.net interface shouldn't cause any resolution changes anymore, but since I implemented that a little bit different than dosbox, it might not work for others, please let me know.
there are some major problems still:
1) i get a c0000005 if i try alt+tab-ing multiple times between bw and something else while in the bnet interface. i've noticed this yesterday, so thats why i left full screen bnet out of my attempt. just a guess, but looks to me that w-mode might not be liking that something else is moving the window. crash-dump: + Show Spoiler + Faulting application starcraft.exe, version 1.16.1.1, faulting module unknown, version 0.0.0.0, fault address 0x00cfa664.
<snip>
eax=6b62c7c7 ebx=00000000 ecx=00000001 edx=00000000 esi=04000d99 edi=0152c000 eip=00cfa664 esp=0012f344 ebp=0012f450 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200206
function: <nosymbols> 00cfa5a6 81c704000000 add edi,0x4 00cfa5ac 8b06 mov eax,[esi] 00cfa5ae 81c604000000 add esi,0x4 00cfa5b4 8907 mov [edi],eax 00cfa5b6 81c704000000 add edi,0x4 00cfa5bc 8b06 mov eax,[esi] 00cfa5be 81c604000000 add esi,0x4 00cfa5c4 8907 mov [edi],eax 00cfa5c6 81c704000000 add edi,0x4 00cfa5cc 8b06 mov eax,[esi] 00cfa5ce 81c604000000 add esi,0x4 00cfa5d4 8907 mov [edi],eax 00cfa5d6 81c704000000 add edi,0x4 00cfa5dc 8b06 mov eax,[esi] 00cfa5de 81c604000000 add esi,0x4 00cfa5e4 8907 mov [edi],eax 00cfa5e6 81c704000000 add edi,0x4 00cfa5ec 8b06 mov eax,[esi] 00cfa5ee 81c604000000 add esi,0x4 00cfa5f4 8907 mov [edi],eax 00cfa5f6 81c704000000 add edi,0x4 00cfa5fc 8b06 mov eax,[esi] 00cfa5fe 81c604000000 add esi,0x4 00cfa604 8907 mov [edi],eax 00cfa606 81c704000000 add edi,0x4 00cfa60c 8b06 mov eax,[esi] 00cfa60e 81c604000000 add esi,0x4 00cfa614 8907 mov [edi],eax 00cfa616 81c704000000 add edi,0x4 00cfa61c 8b06 mov eax,[esi] 00cfa61e 81c604000000 add esi,0x4 00cfa624 8907 mov [edi],eax 00cfa626 81c704000000 add edi,0x4 00cfa62c 8b06 mov eax,[esi] 00cfa62e 81c604000000 add esi,0x4 00cfa634 8907 mov [edi],eax 00cfa636 81c704000000 add edi,0x4 00cfa63c 8b06 mov eax,[esi] 00cfa63e 81c604000000 add esi,0x4 00cfa644 8907 mov [edi],eax 00cfa646 81c704000000 add edi,0x4 00cfa64c 8b06 mov eax,[esi] 00cfa64e 81c604000000 add esi,0x4 00cfa654 8907 mov [edi],eax 00cfa656 81c704000000 add edi,0x4 00cfa65c 8b06 mov eax,[esi] 00cfa65e 81c604000000 add esi,0x4 FAULT ->00cfa664 8907 mov [edi],eax ds:0023:0152c000=???????? 00cfa666 81c704000000 add edi,0x4 00cfa66c 8b06 mov eax,[esi] 00cfa66e 81c604000000 add esi,0x4 00cfa674 8907 mov [edi],eax 00cfa676 81c704000000 add edi,0x4 00cfa67c 8b06 mov eax,[esi] 00cfa67e 81c604000000 add esi,0x4 00cfa684 8907 mov [edi],eax 00cfa686 81c704000000 add edi,0x4 00cfa68c 8b06 mov eax,[esi] 00cfa68e 81c604000000 add esi,0x4 00cfa694 8907 mov [edi],eax 00cfa696 81c704000000 add edi,0x4 00cfa69c 8b06 mov eax,[esi] 00cfa69e 81c604000000 add esi,0x4 00cfa6a4 8907 mov [edi],eax 00cfa6a6 81c704000000 add edi,0x4 00cfa6ac 8b06 mov eax,[esi] 00cfa6ae 81c604000000 add esi,0x4 00cfa6b4 8907 mov [edi],eax 00cfa6b6 81c704000000 add edi,0x4 00cfa6bc 8b06 mov eax,[esi] 00cfa6be 81c604000000 add esi,0x4 00cfa6c4 8907 mov [edi],eax 00cfa6c6 81c704000000 add edi,0x4 00cfa6cc 8b06 mov eax,[esi] 00cfa6ce 81c604000000 add esi,0x4 00cfa6d4 8907 mov [edi],eax 00cfa6d6 81c704000000 add edi,0x4 00cfa6dc 8b06 mov eax,[esi] 00cfa6de 81c604000000 add esi,0x4 00cfa6e4 8907 mov [edi],eax 00cfa6e6 81c704000000 add edi,0x4 00cfa6ec 8b06 mov eax,[esi] 00cfa6ee 81c604000000 add esi,0x4 00cfa6f4 8907 mov [edi],eax 00cfa6f6 81c704000000 add edi,0x4 00cfa6fc 8b06 mov eax,[esi] 00cfa6fe 81c604000000 add esi,0x4 00cfa704 8907 mov [edi],eax 00cfa706 81c704000000 add edi,0x4 00cfa70c 8b06 mov eax,[esi] 00cfa70e 81c604000000 add esi,0x4 00cfa714 8907 mov [edi],eax *----> Stack Back Trace <----* ChildEBP RetAddr Args to Child 0012f450 0000180f 000001e0 0012f4a8 15036589 0xcfa664
2) quiting bw leaves the resolution to 640x480 over here (until you quit "the fix"), also i believe after the first or second start/quit of bw, when you get into the bw window (and the "fix" is running in the bkg), you first need to alt+tab to some other window - then in bw and only then it will enter fullscreen. i think my approach covered all of these issues nicely and you can take another look at it if you want...
some code related remarks: - the code in the fix is absolutely not requiring the 2010 runtimes at all (until compiled with that newer version compiler). if you build with mingw for example you get pretty much not such dependencies. you could even use msvc 6.0 if it wasn't for EnumDisplayDevices.
- not using CloseHandle(hThread); at the end of main will cause a small memory leak.
- "int main(char argc, char* argv[]) " should be "int main(int argc, char* argv[]) "
- if you change the following to the macro versions the code will become plain c like the base of the api itself: bool -> BOOL, true -> TRUE, false -> FALSE.
sorry if i'm way to critical or something... cheers
|
Hehe, I like your criticism, don't worry I'm not offended :D
- ofc you are right about the MSVC 2010 runtimes, I just couldn't be fucked to compile it with MinGW. - forgot about the CloseHandle will fix that thanks. - fixed the main function - oh, I didn't know that C doesn't know bool, true and false
I'm currently playing and therefore testing it. I can't reproduce your problem with the resolution begin stuck at 640x480 when quitting bw, allthough I tought my code would do that (I was surprised it worked here, hahaha). I also can't reproduce your crash when I alt+tab in and out of bw in the b.net interface. I ran into some other problem with bwRepInfo though, and I think my approach is maybe too hacky. I already got a different Idea how to do it, but I have to think it through first.
|
ok cool, here is a small report from a buddy of mine: - dual boot vista / win7 on a pc. - the "not switching from 640x480 until exiting the "fix"" is reproducible on both os he says. - the crash only occurs on vista on his side (and in my case i have xp), but not on win7.
this is his screen shot (vista):
![[image loading]](http://dl.dropbox.com/u/28720954/bw_fixes/bwcrash0001.jpg)
it slighly hints about the possible bnet ui widget mess-up. the on-screen copy effect that occurs is because w-mode, after fiddling with all the current widgets present on the ui is combining the ddraw and gdi rendering to one unified surface (i believe). no idea why it does not happen on win7 though.
|
Ok, the other way works way better. This is the idea: If broodwar is not minimized it is used, so the resolution is switched to 640x480. As soon as BW is minimized the resolution switches back to the original.
To minimize BW one can not click on the minimize button anymore, and alt+tab wont work either, as its not minimizing bw but switching to another window. To minimize I need an own "command".
So I made a Chaos Launcher plugin now, its subclassing the window and checking for F12, if F12 is pressed BW is minimized and the resolution is restored. If BW gets the focus again, the resolution is changed to 640x480 again. F12 is just a testkey, I couldn't come up with something better, maybe someone has a better idea.
Code: + Show Spoiler +#include <windows.h> #include <stdio.h>
HANDLE hThread; BOOL mainThreadRunning = TRUE; BOOL minimizeBW = FALSE; LONG prevWindowProc; DEVMODE lastDevmode; DEVMODE devmodeBW;
int MainThread(); LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); DEVMODE GetCurrentDeviceMode();
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: DWORD threadId; hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MainThread, 0, 0, &threadId); break; case DLL_PROCESS_DETACH: mainThreadRunning = FALSE; CloseHandle(hThread); ChangeDisplaySettings(&lastDevmode, 0); break; }
return TRUE; }
int MainThread() { Sleep(2000); // wait until BW window is created, 2seconds should be enough DEVMODE d = GetCurrentDeviceMode(); memcpy(&lastDevmode, &d, sizeof(DEVMODE)); memcpy(&devmodeBW, &d, sizeof(DEVMODE)); devmodeBW.dmPelsWidth = 640; devmodeBW.dmPelsHeight = 480;
HWND hWndBW = FindWindow("SWarClass", 0); prevWindowProc = SetWindowLong(hWndBW, GWL_WNDPROC, (LONG)WindowProc); BOOL wasMinimized = TRUE;
while (mainThreadRunning) { WINDOWPLACEMENT wndPl; wndPl.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(hWndBW, &wndPl); if (wndPl.showCmd == SW_SHOWMINIMIZED) { // set bw resolution if(!wasMinimized){ ChangeDisplaySettings(&lastDevmode, 0); wasMinimized = TRUE; } } else { // set normal resolution if(wasMinimized){ ChangeDisplaySettings(&devmodeBW, 0); SetWindowPos(hWndBW, 0, -5, -31, 0, 0, SWP_NOSIZE); wasMinimized = FALSE; } }
if (minimizeBW == TRUE) { ShowWindow(hWndBW, SW_MINIMIZE); minimizeBW = FALSE; } Sleep(250); }
ChangeDisplaySettings(&lastDevmode, 0); return 0; }
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_KEYUP: if (wParam == VK_F12) { // minimize bw minimizeBW = TRUE; } break; } return CallWindowProc((WNDPROC)prevWindowProc, hwnd, uMsg, wParam, lParam); }
DEVMODE GetCurrentDeviceMode() { DISPLAY_DEVICE d; DEVMODE devMode; d.cb = sizeof(DISPLAY_DEVICE); devMode.dmSize = sizeof(DEVMODE); int devNum = 0; int result = 0; do { result = EnumDisplayDevices(0, devNum, &d, 0); // check if it's the main device if (result && ((d.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)) { EnumDisplaySettings(d.DeviceName, -1, &devMode); return devMode; } devNum++; } while (result);
// Current Devicemode not found devMode.dmSize = 0; return devMode; }
Download: http://213.133.99.163/win7bwfix.zip
P.S. really need to get some food now, hahaha
|
Hey just wanted to report I'm getting mixed results from everything sofar.
I'm using windowed mode + resolution changer as chaoslauncher plugin.
I can use f12 to minimize ingame, but not in chat or lobby.
I'm still getting pretty bad lag with the mouse running in windowed mode(although tried compensating by increasing mousespeed in chaoslauncher, but that makes it jittery), so unless xenotron knows what the issue is, windowed mode kind of doesn't become an option as long as running on laptop rather than desktop(dif refresh rates possible).
Thanks for the work though!
|
hi WhuazGoodJaggah,
i like the idea of a shared library for the injector, however it has to be white-listed in *all anti-hack* lauchers and other software or it won't be possible to be used with anti-hack settings enabled to my knowledge.
this is the major reason i sort of branched to the exe path yet again...: bellow are new modifications (tested on xp, vista, win7): - i've noticed that you might have found the -32 problematic Y offset on your own - it was causing the glitching of the bnet UI on my end. -31 or higher fixed that, but makes some pixels visible on the top. - there is an additional thread that updates faster and attempts to grab the alt+tab, winkey and other system keys and minimize before that. this should fix the crash (xp, vista) caused for example by alt+tabbing in and out of the bnet - looks like some sort of a w-mode / win7fixforbw conflict. - i've copy pasted the earlier IsBroodWarWindow method from your code.
i don't think i will be having much more time to work on this, but hopefully it will be useful to someone...
edit / note: btw, F12 seems to be taken by Alt+F12 in w-mode, but also it might not always work with a WinProc, since the window loses focus when in the bnet ui.
+ Show Spoiler + #include <windows.h> #include <stdio.h>
// structs, vars and flags DEVMODE lastDevmode; DEVMODE devmodeBW; HWND hWndBW = NULL; BOOL exitThread = FALSE; BOOL WaitFlag = TRUE; BOOL isFS = FALSE; BOOL isMin = TRUE;
// Constant Values const int BW_FULL_POS_X = -5; const int BW_FULL_POS_Y = -31; // lower value causes the bnet ui mess-up const int BW_WIDTH = 650; const int BW_HEIGHT = 517;
// FUNCTION PROTOTYPES DEVMODE GetCurrentDeviceMode(); int CheckForegroundWindow(); int KeyHandler(); HWND FindBW(); BOOL IsBroodWarWindow();
#define KEYP(x) (GetKeyState(x) < 0)
// Entry int main(void) { // int main(int argc, char* argv[]) { DWORD threadId, khId; HANDLE hThread, khThread; DEVMODE d;
d = GetCurrentDeviceMode(); if (!d.dmSize) { printf("Current Devicemode not found, exiting process.\n"); ExitProcess(1); }
memcpy(&lastDevmode, &d, sizeof(DEVMODE)); memcpy(&devmodeBW, &d, sizeof(DEVMODE)); devmodeBW.dmPelsWidth = 640; devmodeBW.dmPelsHeight = 480;
printf("\nBroodWar Resolution Changer (by WhuazGoodNjaggah)\n" \ "modified version by Dosbox\n" \ "Press:\n" \ "\t- Alt+F1 if you can't scroll inside BW (See WModeReadme.txt)\n" \ "\t- Alt+Tab, WinKey or Alt+F8 to minimize BW\n" \ "\t- Any key in this window to exit\n\n" \ );
if (FindBW()) printf("BW seems to be active on start.\n");
threadId = khId = 0; hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)CheckForegroundWindow, 0, 0, &threadId); khThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)KeyHandler, 0, 0, &khId);
getchar();
printf("Exiting...\n"); exitThread = TRUE; CloseHandle(hThread); CloseHandle(khThread); ExitProcess(1); }
// GetCurrentDeviceMode DEVMODE GetCurrentDeviceMode() { int devNum = 0; int result = 0; DISPLAY_DEVICE d; DEVMODE devMode;
d.cb = sizeof(DISPLAY_DEVICE); memset(&devMode, 0, sizeof(DEVMODE)); do { result = EnumDisplayDevices(0, devNum, &d, 0); // check if it's the main device if (result && ((d.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0)) { EnumDisplaySettings(d.DeviceName, (DWORD)-1, &devMode); devMode.dmSize = sizeof(DEVMODE); return devMode; } devNum++; } while (result);
// Current Devicemode not found, exiting process return devMode; }
// KeyHandler int KeyHandler() { while(!exitThread) { if (FindBW()) { // try minimizing before the actual ALT+TAB or WinKey actions: // prevent a possible crash on XP / Vista (/ Win7 ?). if (( KEYP(VK_MENU) && (KEYP(VK_F8) || KEYP(VK_TAB))) || KEYP(VK_LWIN) || KEYP(VK_RWIN) ) { ShowWindow(hWndBW, SW_MINIMIZE); if (!isMin) { ChangeDisplaySettings(&lastDevmode, 0); printf("BW Minimized.\n"); isMin = TRUE; } } else { isMin = FALSE; } } // value should be low Sleep(1); } return 0; }
// CheckForegroundWindow int CheckForegroundWindow() { while(!exitThread) { if (FindBW()) { if (!WaitFlag) { printf("BW Found.\n"); WaitFlag = TRUE; } if (IsBroodWarWindow()) { SetWindowPos(hWndBW, 0, BW_FULL_POS_X, BW_FULL_POS_Y, 0, 0, SWP_NOSIZE); if (!isFS) { printf("BW Full Screen.\n"); ChangeDisplaySettings(&devmodeBW, 0); isFS = TRUE; } } else { SetWindowPos(hWndBW, 0, 0, 0, 0, 0, SWP_NOSIZE); if (isFS) { ChangeDisplaySettings(&lastDevmode, 0); isFS = FALSE; } } } else { if (WaitFlag) { printf("Waiting for BW...\n"); ChangeDisplaySettings(&lastDevmode, 0); WaitFlag = FALSE; } } Sleep(100); } return 0; }
// Find BW HWND FindBW(void) { return hWndBW = FindWindow("SWarClass", 0); }
// IsBroodWarWindow BOOL IsBroodWarWindow(void) { char szWindowClass[255]; int cmpSWC; int cmpSDD;
RealGetWindowClass(GetForegroundWindow(), szWindowClass, 255); cmpSWC = strncmp(szWindowClass, "SWarClass", 9); cmpSDD = strncmp(szWindowClass, "#32770", 6); return (cmpSWC == 0) || (cmpSDD == 0); }
(10kb EXE) http://dl.dropbox.com/u/28720954/bw_fixes/win7fixforbw.exe -----
Armathai,
i got confirmation that wmode is a bit slow in win7, but this might be DirectDraw or video card / driver related and therefore not easily fixible in w-mode. it seems playable though from the person who explained to me.
----
cheers
|
Awesome, I already thought about making a standalone exe again, because I just used the inject way to hook the window proc, but as that was bad in itself the injection isn't really needed. I didn't have any time until now as I was on the train and bus and such as I'm traveling through Thailand atm.
I really like your changes, altough I think 2 threads are a bit of an overkill but who cares :D I sure will use it, unfortunately XeNotRoN didn't answer my second email, so still no news on the wmode mouse sluggishness front. It only needs a small fix as the mouse seems not to be sluggish when the cursor is not clipped, but then the scrolling isn't working, I could write a workaround for that but I'd rather have that fix in wmode itself than write yet another ugly workaround.
|
You guys know you could just make a XP VM and run BW on that without any crashes or colour issues ?
|
On August 02 2011 20:56 WhuazGoodJaggah wrote: I sure will use it, unfortunately XeNotRoN didn't answer my second email, so still no news on the wmode mouse sluggishness front. It only needs a small fix as the mouse seems not to be sluggish when the cursor is not clipped, but then the scrolling isn't working, I could write a workaround for that but I'd rather have that fix in wmode itself than write yet another ugly workaround.
i have exchanged some opengl / gfx related emails with him before, but he is usually very busy. parts of my understanding of the how the bnet interface is made comes from him and the author of dxwnd, who both wrote ~3k lines of code (as i presume and mentioned earlier) to cover the "window mode" issue.
but the thing is that the mouse sluggishness in w-mode is not reproducible on all systems, independent of OS, CPU power, mouse clipping.
i've noticed another problem with moving the window around. when the user exits the w-mode window title bar is left outside of the screen, so it cannot be moved until the wmode.ini is modifed/reset. instead of hooking the process WH_CALLWNDPROC and listen for close/quit, i've decided to modify wmode.ini directly after the process has terminated (which is probably a worse design decision).
so here is the mod: // gcc win7fixforbw.c -o win7fixforbw.exe -W -Wall -O3 -lpsapi -s // cl win7fixforbw.c psapi.lib user32.lib advapi32.lib /W4 /O2 /D_CRT_SECURE_NO_WARNINGS http://dl.dropbox.com/u/28720954/bw_fixes/win7fixforbw.c http://dl.dropbox.com/u/28720954/bw_fixes/win7fixforbw.exe
it also locks the console app window (close btn, ctrl+c) until enter is pressed or terminated from taskman.
|
|
|
|