Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Remove "Loading" image

Junior Spellweaver
Joined
Aug 16, 2009
Messages
148
Reaction score
8
Air Bourne - Remove "Loading" image - RaGEZONE Forums
 
  • Like
Reactions: hua
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
I think your issue is not what you think.

That image is loaded from the resource section of the PE and blitted to the DC assigned to DirectX the same way font based text is rendered.

You can remove the bitblit and then remove the bitmap resource, but that doesn't stop Desktop Composition disabling... that happens because of the methods of lowlevel blit access utilised by PT, and more specifically DirectX APIs below DirectX 7. Most DirectX 3 & 5 applications will do this the moment the number of back buffers exceeds safe limits for running Desktop Composition.

On my system DWM is disabled, during the change from the resource splash to the Priestess Splash, or after character selection / creation, or when I switch maps, sometimes even by walking out of the gate. I is does not happen at any specific time, but will happen at some point during the play. Unless, possibly, I quit before leaving town. XD But I can often see the "Loading" bitmap and not loose DWM effects.

Remember that DWM (Microsofts' Desktop Compositioning system) is implemented by DirectX, and it's safer for Windows to disable DWM than have the system crash to a BSOD every time you try to play Diablo, Quake or Total Annihilation. PT isn't the only pre-DirectX 7 game that people still like to run on their current hardware.

It won't disable DWM at startup because, until you use enough gfx resources it's not a problem. But you can use the Compatibility Options of your launch icon to force DWM to be disabled during the execution of the game, and restore it after you finish playing.

I believe that isn't implemented via DirectX and doesn't disable when running older games or media renderers... but I've not updated my license since Vista as it really doesn't bother me that much.
 
Last edited:
Junior Spellweaver
Joined
Aug 16, 2009
Messages
148
Reaction score
8
Sometimes it loads me in the game so fast it doesn't show the "loading" thingy and I am ingame and it still uses Aero theme and the pixels aren't messed up, however when I go to a new map then the "loading" thingy comes back up and it changes my theme to Basic and messes up the graphic quality.

I think it is, so I just want to try and remove it if someone knows how to do it.
 
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
As I suspected.

I believe switching the rendering engine to something DirectX 9 or OpenGL based would stop the game disabling Desktop Compositioning, but that's a lot of work, and I don't know anyone besides me that is even considering putting that much effort into a client.

If anyone out there does have any good idea how to reverse the display engine, I'm all ears. I have a couple of ideas, but also want to clean up and open up more of the server first.

Stable, secure, fast, capable... then worry about pretty. XD

I don't think you can get DWM to stay running easily, but if you are poking around with the loading bitmap, last time I looked at it I thought that a percentage bar might be nicer. I couldn't easily calculate what would constitute 100% though.
 
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
Okay... what did you do different to Moons and I? :lol:

I'm prepared to admit if I was wrong, but it never worked for me.
 
Junior Spellweaver
Joined
Aug 31, 2009
Messages
119
Reaction score
22
Sometimes the standard Windows theme isn't enabled but when you change field ingame, it will change the theme to normal.
 
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
My experience has been, sometimes loading or changing field will disable DWM (glass effect) themes, sometimes it does not. Sometimes I can change field a couple of times before my screen goes black and comes back with the non-glass theme... but disabling the loading image didn't improve the situation much (if at all) on my system.

I guess it is one more graphic resource for the system to cope with, but only a small one. The splash screens are blitted outside DirectX too I think, and they are more resource hungry. So what did AB do that I didn't. XD
 
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
I know AB solved his problem, but I never saw the solution posted.

I've managed to fix this in KPT 1977... though I'm not sure why, as I suspect that the command is some COM interface to DirectX, so if anyone knows why or how this fix works, I'd appreciate that information.

This is the original code
Code:
0044361C  push eax                                ;  Arg1 => [LOCAL.6]
0044361D  call [<&KERNEL32.SuspendThread>]        ;  kernel32.Wow64SuspendThread
00443623  inc ebp
00443624  push offset 0073D568                    ;  pCriticalSection = 0073D568
00443629  call [<&KERNEL32.EnterCriticalSection>] ;  NTDLL.RtlEnterCriticalSection
0044362F  mov edx,[hWndMain]
00443635  lea ecx,[esp+20]
00443639  push ecx                                ;  Rect => offset LOCAL.3
0044363A  push edx                                ;  hWnd => [73DA1C] = NULL
0044363B  call [<&USER32.GetClientRect>]          ;  USER32.GetClientRect
00443641  mov ecx,[hWndMain]
00443647  lea eax,[esp+18]
0044364B  push eax                                ;  pPoint => offset LOCAL.5
0044364C  push ecx                                ;  hWnd => [73DA1C] = NULL
0044364D  mov [esp+24],edi                        ;
00443651  mov [esp+20],edi                        ;
00443655  call [<&USER32.ClientToScreen>]         ;  USER32.ClientToScreen
0044365B  mov edx,[esp+1C]
0044365F  mov eax,[esp+18]
00443663  push edx                                ;  dY
00443664  push eax                                ;  dX
00443665  lea ecx,[esp+28]                        ;
00443669  push ecx                                ;  pRect => offset LOCAL.3
0044366A  call [<&USER32.OffsetRect>]             ;  USER32.OffsetRect
00443670  mov eax,[1F38620]
00443675  mov edx,[eax]
00443677  lea ecx,[esp+10]
0044367B  push ecx
0044367C  push eax
[COLOR=Red]0044367D  call [edx+44][/COLOR]
00443680  cmp ebp,2
00443683  push offset 00CC0020
And I fixed it to this:-
Code:
0044361C  push eax                                ;  Arg1 => [LOCAL.6]
0044361D  call [<&KERNEL32.SuspendThread>]        ;  kernel32.Wow64SuspendThread
00443623  inc ebp
00443624  push offset 0073D568                    ;  pCriticalSection = 0073D568
00443629  call [<&KERNEL32.EnterCriticalSection>] ;  NTDLL.RtlEnterCriticalSection
0044362F  mov edx,[hWndMain]
00443635  lea ecx,[esp+20]
00443639  push ecx                                ;  Rect => offset LOCAL.3
0044363A  push edx                                ;  hWnd => [73DA1C] = NULL
0044363B  call [<&USER32.GetClientRect>]          ;  USER32.GetClientRect
00443641  mov ecx,[hWndMain]
00443647  lea eax,[esp+18]
0044364B  push eax                                ;  pPoint => offset LOCAL.5
0044364C  push ecx                                ;  hWnd => [73DA1C] = NULL
0044364D  mov [esp+24],edi                        ;
00443651  mov [esp+20],edi                        ;
00443655  call [<&USER32.ClientToScreen>]         ;  USER32.ClientToScreen
0044365B  mov edx,[esp+1C]
0044365F  mov eax,[esp+18]
00443663  push edx                                ;  dY
00443664  push eax                                ;  dX
00443665  lea ecx,[esp+28]                        ;
00443669  push ecx                                ;  pRect => offset LOCAL.3
0044366A  call [<&USER32.OffsetRect>]             ;  USER32.OffsetRect
00443670  mov eax,[1F38620]
00443675  mov edx,[eax]
00443677  lea ecx,[esp+10]
0044367B  push ecx
0044367C  push eax
[COLOR=Red]BREAK_DWM jmp short 00443680                      ; Call [edx+44h]
0044367F  nop[/COLOR]
00443680  cmp ebp,2
00443683  push offset 00CC0020
Now, I only found this instruction following the "IDB_LOADIMG" data flowing around and it's CDC and so on till I found a subroutine that caused DWM to disable.

I don't understand why, or how mov eax,[1F38620] : mov edx,[eax] : call [edx+44] invokes a DDraw function that displays the loading lamp and disables DWM.

All official documentation says don't lock the front buffer, and don't GetDC the front buffer... but PT does that and doesn't affect DWM, and all other DirectX calls are supposed to be fine so... I'm confused.
 
Last edited:
Junior Spellweaver
Joined
Aug 31, 2009
Messages
119
Reaction score
22
This is how I edited it, and it works, everytime ^^

Code:
CPU Disasm
Address   Hex dump          Command                                                Comments
00442292     /0F85 54010000 JNE 004423EC

Code:
CPU Disasm
Address   Hex dump          Command                                                Comments
00442292     /0F85 54010000 [COLOR="Red"]JMP[/COLOR] 004423EC
 
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
That one liner is for 1977 / 1976 / ????

It definitely doesn't apply to the clients I have in use ATM.

1977
Code:
CPU Disasm
Address   Hex dump          Command                                  Comments
0044228A      cmp ebx,7
0044228D      ja 0044234E
00442293      jmp [ebx*4+4423B8]
0044229A      mov eax,[esp+264]                        ; Case 1 of switch KPT1977NoXTrap3.442289
004422A1      imul eax,eax,0D
004422A4      add eax,esi
004422A6      mov ecx,[eax*4+5FB4C8]                   ; ASCII "8�\\"

2428
Code:
CPU Disasm
Address   Hex >Command                                  Comments
0044227C       mov eax,[9110A0]
00442281       mov ecx,[eax+154]
00442287       mov edx,[eax+150]
0044228D       mov eax,[eax+14C]
00442293       push 0                                   ;  Arg5 = 0
00442295       push ecx                                 ;  Arg4
00442296       push edx                                 ;  Arg3
00442297       push eax                                 ;  Arg2
00442298       push 1000                                ;  Arg1 = 1000
0044229D       call 004E6330                            ;  game.exe.004E6330

1920
Code:
CPU Disasm
Address   Hex dump          Command                                  Comments
00442291      99            cdq
00442292      2BC2          sub eax,edx
00442294      D1F8          sar eax,1

QF 1872
Code:
CPU Disasm
Address   Hex >Command                                  Comments
00442291       cdq
00442292       sub eax,edx
00442294       sar eax,1



Ooo... wait. QF1873 has it.
Code:
CPU Disasm
Address   Hex >Command                                  Comments
00442292       jne 004423EC
00442298       push esi
00442299       mov esi,[<&GDI32.BitBlt>]
...
...
...
004423EC       push 1
004423EE       call [<&KERNEL32.ExitThread>]
004423F4       pop edi
004423F5       pop ebp
004423F6       pop ebx

The GDI32.BitBlt could do it if it's acting on the front buffer, not the back buffer.
 
Last edited:
Junior Spellweaver
Joined
Aug 31, 2009
Messages
119
Reaction score
22
I think you should have enough lines to search for a sequence of commands :p
Code:
CPU Disasm
Address   Hex dump          Command                                                     Comments
00442292     /0F85 54010000 [U]JNE 004423EC[/U]
00442298  |. |56            PUSH ESI
00442299  |. |8B35 40A05B00 MOV ESI,DWORD PTR DS:[<&GDI32.BitBlt>]                      ; Entry point
0044229F  |. |90            NOP
004422A0  |> |393D D8BBBC01 /CMP DWORD PTR DS:[1BCBBD8],EDI
004422A6  |. |75 0C         |JNE SHORT 004422B4
004422A8  |. |8B4424 14     |MOV EAX,DWORD PTR SS:[ESP+14]
004422AC  |. |50            |PUSH EAX
004422AD  |. |FF15 A0A05B00 |CALL DWORD PTR DS:[<&KERNEL32.SuspendThread>]
004422B3  |. |45            |INC EBP
004422B4  |> |68 C8BF7000   |PUSH OFFSET lunarpt_3260_beta_GM_unpacked.0070BFC8
004422B9  |. |FF15 FCA15B00 |CALL DWORD PTR DS:[<&KERNEL32.EnterCriticalSection>]
004422BF  |. |8B15 7CC47000 |MOV EDX,DWORD PTR DS:[70C47C]
004422C5  |. |8D4C24 20     |LEA ECX,[ESP+20]
004422C9  |. |51            |PUSH ECX
004422CA  |. |52            |PUSH EDX
004422CB  |. |FF15 E8A25B00 |CALL DWORD PTR DS:[<&USER32.GetClientRect>]
004422D1  |. |8B0D 7CC47000 |MOV ECX,DWORD PTR DS:[70C47C]
004422D7  |. |8D4424 18     |LEA EAX,[ESP+18]
004422DB  |. |50            |PUSH EAX
004422DC  |. |51            |PUSH ECX
004422DD  |. |897C24 24     |MOV DWORD PTR SS:[ESP+24],EDI
004422E1  |. |897C24 20     |MOV DWORD PTR SS:[ESP+20],EDI
004422E5  |. |FF15 E4A25B00 |CALL DWORD PTR DS:[<&USER32.ClientToScreen>]
004422EB  |. |8B5424 1C     |MOV EDX,DWORD PTR SS:[ESP+1C]
004422EF  |. |8B4424 18     |MOV EAX,DWORD PTR SS:[ESP+18]
004422F3  |. |52            |PUSH EDX
004422F4  |. |50            |PUSH EAX
004422F5  |. |8D4C24 28     |LEA ECX,[ESP+28]
004422F9  |. |51            |PUSH ECX
004422FA  |. |FF15 E0A25B00 |CALL DWORD PTR DS:[<&USER32.OffsetRect>]
00442300  |. |A1 B4AFEF01   |MOV EAX,DWORD PTR DS:[1EFAFB4]
00442305  |. |8B10          |MOV EDX,DWORD PTR DS:[EAX]
00442307  |. |8D4C24 10     |LEA ECX,[ESP+10]
0044230B  |. |51            |PUSH ECX
0044230C  |. |50            |PUSH EAX
0044230D  |. |FF52 44       |CALL DWORD PTR DS:[EDX+44]
00442310  |. |83FD 02       |CMP EBP,2
00442313  |. |68 2000CC00   |PUSH OFFSET 00CC0020
 
Custom Title Activated
Loyal Member
Joined
May 26, 2007
Messages
5,545
Reaction score
1,315
Yea... found the matching client in the end. XD

I don't think there is code similar to that in the new clients though.

---- Edit ---

The closest is in the listing I gave earlier. The JNE will avoid only the "Suspend Thread" call, prior to entering the critical section.
Code:
CPU Disasm
Address   Hex >Command                                   Comments
00443610        cmp [1C09210],edi
00443616        jne short [COLOR=Blue]00443624[/COLOR]
00443618        mov eax,[esp+14]
0044361C        push eax                                 ;  Arg1 => [LOCAL.6]
0044361D        call [<&KERNEL32.SuspendThread>]         ;  kernel32.Wow64SuspendThread
00443623        inc ebp
[COLOR=Blue]00443624[/COLOR]        push offset KPT1977NoXTrap3.0073D568     ;  pCriticalSection = 0073D568

--- Edit ---

Tested, this is definitely insufficient in newer clients. I'm going to look to see if there are less severe methods that can be employed in QF1873... that jump skips an awful lot of code. But thanks for the reply, it gives us two methods in two different clients.

Additionally, what it does achieve is that the "Loading" bar continues to flash all the time you are playing the game. XD
Air Bourne - Remove "Loading" image - RaGEZONE Forums

--- EDIT ---
I conclude that even in QF1873 it comes down to that "call [edx+44]" but you can skip the two pushes (it's parameters) beforehand too.
Code:
CPU Disasm
Address   Hex >Command                                   Comments
0044230B       push ecx
0044230C       push eax
0044230D       call [edx+44]
So you can either Assemble "sub ESP,8" at 0044230D or Assemble a "jmp" at 0044230B to below the "call [edx+44]" to achieve the desired result.

I suspect that whatever thread it is which is being disabled at the start could afford to not be started in the first place, as restoring the fix I mention (undo edits at this location) will instantly disable DWM and give you a flashing "Loading" bar while you play. \o/ (hooey for negative results which lead to deeper understanding)

I've checked for similar commands "call [Reg32+44]" throughout the game, and they all lead to an unpublished API in DirectDraw which takes two parameters on the stack and removes them before returning.

I still don't understand what the parameters are or how it works, but I presume they are a COM structure of some form or other. What DDraw.dll does in response to those CALLs is widely varied, as I even found one which (when removed) disabled all the text. XD

I wish I understood COM in x86 assembler better... so much documentation is either in C / C++ or only relates to Assemblers which have Macros provided for COM / ActiveX interfacing. Not reverse code engineering.
 
Last edited:
Back
Top