Drakan patch 445++, solving Alwarren and cutscene

Anything to do with Drakan level editing and modifications, post it here! Also this is the place to tell us about your new levels and get player feedback.

Moderators: Arokhs Twin, yangez93

adventor
Hatchling
Posts: 3
Joined: Fri Feb 04, 2011 12:31 am
Location: Russia

Post by adventor »

Hi everyone.
English is not my native language so it will be a real challenge for you to understand me but I'll do my best to make this obstacle not so hard.
Shelim, I'm glad that you continue making attempts to fix Drakan crashes. Unfortunately the goal is still too far :(
Thank you for publishing bytes your patch changes.
Could you give a little explanation of your patches? If you don't mind to reveal your secrets, of course.
Patch 445+ bypasses 2 identical blocks of code. Why?
Patch 445++ bypasses another one block. For what purpose?
Why does a downloadable version of your patch http://dl.getdropbox.com/u/82366/drakan ... %2B%2B.exe include only "DRAKAN PATCH 445+" staff? Is "DRAKAN PATCH 445++ (second version)" still in alpha state :D and that's why you decided not to include it into your official patch release?

User avatar
Shelim
Dragon
Posts: 189
Joined: Sun Aug 03, 2008 10:55 pm
Location: Poland
Contact:

Post by Shelim »

I do not remember the exact code, but I found something like this in Drakan code (related to 445+):

Code: Select all

// C++ style code, mostly based on guessing
Frame * frame = CopyBackgroundBuffer(); // Noticed that on modern hardware
                                 // we don't have background in menus? :-)

frame->DoSomething(); // Ops, no one check the return value of above
                                 // we have dereferenced null pointer over there!
This "DoSomething" was done two times in code. I did not investigate what this do specifically, but it seems to be non essential for game to run. Guess drawing routines, or something...

As for 445++ I don't remember it even a bit, and I do not have access to my notes at this moment.


And as for next patches, things seemed to slowed for a bit, as I have major personal problems to be handled for now. So, any futher Drakan patches are postponed until I get free time again (which may not happen soon, I am afraid :-( )

adventor
Hatchling
Posts: 3
Joined: Fri Feb 04, 2011 12:31 am
Location: Russia

Post by adventor »

Shelim, thank you for your reply! I even dare not expect it so soon. ;)
Your explanations seem to be clear. Thank you.

Outlaw Wyvern
Dragon
Posts: 402
Joined: Fri Oct 10, 2003 4:20 pm
Location: USA
Contact:

Post by Outlaw Wyvern »

Shelim wrote:
"And as for next patches, things seemed to slowed for a bit, as I have major personal problems to be handled for now. So, any futher Drakan patches are postponed until I get free time again (which may not happen soon, I am afraid :-( )"

Best of luck with all your current challenges.
I trust balance will be restored to your life soon, and with less effort than you anticipate.
Drakan (and it's community) will be here when you're ready 8^)

User avatar
Shelim
Dragon
Posts: 189
Joined: Sun Aug 03, 2008 10:55 pm
Location: Poland
Contact:

Post by Shelim »

Okay, seems I had more luck than brains [:D]

My problems have solved themselves amazingly easy despite looking terrible at first. So, I am once again actively working at my Drakan project.

What is this about? Well, as I mention earlier, I am writing DX 6.1 hooks that will intercept all calls to graphics card, translate them to DX 9.0c, then inject some cool special effects and send them back. This would drastically increase hardware requirements, but not necessary lower the fps count (especially if wisely used). I know for sure that the drakan does internal L&T (yeah, I reach the point when I can confirm Drakon Rider info), so I cannot intercept light source positions (this is required to write some special effects like normal maps or advance shadow techniques), but still I can add things like full scene motion blur, depth-of-field, post-processing effects, pixel- and vertex shaders, stereoscopic 3D rendering and many others. Everything will be packed as single addon, to be installed upon vanilia Drakan 445 and will be fully configurable with graphical launcher.

As for currently progress, I have completed about 40% of 1st stage of code where entire addon require three stages of work. 1st stage is about implementing all DX 6.1 interfaces and this is mostly copy&paste work, a bit annoying and time consuming. 2nd stage will consist of implementing DX 9.0c driver and this will be the hardest one. 3rd one will be equal to beta status and will consist of injecting everything I want to add to Drakan code.


@Drakon Rider:
What 445SP1 patch changes? I diffed files and found few parts of file has been no-op'ed, some flags were changed and some function rewritten... I wonder how this work internally and prefer not to do additional reverse engineering :) Do you have some documentation, notes, or anything? I wish to merge this with addon but I would feel better if I know something about those fixes first :)

Drakon Rider
Dragon
Posts: 87
Joined: Sun Jul 29, 2001 2:35 am
Location: Russia
Contact:

Post by Drakon Rider »

445SP1 was designed mostly for NoWhere level and 2 additional special attack animations.

What it changes:
1. Removed special camera rotation mode from 'left' special combo (left-forward-attack) and from 'back' special combo (forward-backward-attack).

2. For 'left' special attack added 2 active 'hitting intervals' (as the new animation has 2 visual 'physical' slashes). Engine do not only calculates objects (bounding spheres for weapon) intersection to detect attack hit but also makes it only at the special 'hittable intervals', that are unic for every attack (in retail Drakan:OOTF).

3. Removed 'stuck in block' bug.

Unfortunately no notes from may years ago. I have IDA disassembler database with some my notes inside, though a few.

adventor
Hatchling
Posts: 3
Joined: Fri Feb 04, 2011 12:31 am
Location: Russia

Post by adventor »

Shelim, that's great news! Though I've just completed Drakan (just a couple days ago ;) ), but there're so much things left unexplored :D
I'll be glad to give you any assistance since I'm familiar with C a bit ^_^

User avatar
Shelim
Dragon
Posts: 189
Joined: Sun Aug 03, 2008 10:55 pm
Location: Poland
Contact:

Post by Shelim »

I would never dream that I could say so so early, but...
The first stage is done :)

Complete implementation of all DX 6.1 graphical interfaces hooked to Drakan is ready and as far as I know it's fully working. I am running beta tests with my collegues here in Poland, and I am scheduled for begin second stage (DX 9.0c implementation) next week or the week after.

The addon will be completely independent of game executable, so it will work with either 445, 445++, or 445SP1.

As for help, thanks for proposition, but presently I do not need C/C++ programmer. But I may need shader artist in future (programmer who knows HLSL and will be willing to implement some cool special effects for DirectX 9.0c and Shader Model 3.0 [;)] )

Nikoomba
Hatchling
Posts: 7
Joined: Tue Mar 22, 2011 4:44 pm
Location: Netherlands
Contact:

Post by Nikoomba »

Wait, so from what I understand from skimming through this thread, you can somehow access Drakan's source code?

If you do somehow have access to the source code, or have any other means of editing the software, please tell me more about it. I'm an experienced(though sadly not professional) programmer looking to serve the Drakan community somehow. If you could help me on my way as to how you have devised these patches, I would be much obliged. I already know you don't need a programmer, so I won't bother you about that. Still, I'd like to be able to devise my own contributions to Drakan. I'm not familiar with HLSL, unfortunately, so I won't be able to help you out with that either. Sorry.

I would also like to report a side effect the patch has; unfortunately the multiplayer component will upon initiating the hosting of a game report that the network settings are incorrect. This does not occur in an unpatched version of Drakan. I have yet to confirm whether it does this in 445, or 445+, but I will do so.
It seems LogMeIn's Hamachi LAN emulation software provides a workaround to this problem, as the message doesn't show up whenever this software is active and connected to a network.

Thanks for the patch, and have a good one!

User avatar
Shelim
Dragon
Posts: 189
Joined: Sun Aug 03, 2008 10:55 pm
Location: Poland
Contact:

Post by Shelim »

No, I do not have access to Drakan source code, although I tried to contact Surreal few times :)

Original patch is basically disassembly work, when I took the compiled code and analyzed it in IDA (it's very efficient for debugging crash points)

The new one is based on mechanism called Windows hook. Basically the hook is function that replace other function from dynamic linked library (DLL). IE. when game calls WinAPI function SetWindowTextA( ), you can intercept this call and inject there your own function with same argument set. You can do something like this:

BOOL WINAPI SetWindowTextA(HWND hWnd, LPCTSTR lpString)
{
return origFuncTable->pSetWindowTextA(hWnd, _T("Drakan: 10th Anniversy")); // caption changed :-)
}

The same goes for every DX function. You can intercept all methods the game send to DX and inject any code there :)

There is MSDN article about this technique over here: http://msdn.microsoft.com/en-us/library ... 85%29.aspx

User avatar
Shelim
Dragon
Posts: 189
Joined: Sun Aug 03, 2008 10:55 pm
Location: Poland
Contact:

Post by Shelim »

News from battle front [:D]

Major part of DX 9.0c renderer for Drakan is now ready, and the only things left are missing textures plus some minor enhancement and overall optimization. When I finish this part, I'll begin adding post effects. Currently I know for sure that I'll be able to add full scene motion blur and/or depth of field, fake normal maps (light position will depend on camera movement, so they won't look THAT good) and perhaps other crazy stuff I am considering right now :)

First screen from DX 9.0c renderer (as I said, no textures are in place yet, I just put some placeholder): http://img713.imageshack.us/img713/2336/tekstura.png

(the artifact on the grounds is in fact shadow, and that curtain in the background is outer layer of fog - don't worry about 11 FPS, that's because engine saves 4-5 debug .png files per frame, which won't happen in final)

Drakon Rider
Dragon
Posts: 87
Joined: Sun Jul 29, 2001 2:35 am
Location: Russia
Contact:

Post by Drakon Rider »

About stuck in block bug -

// Human specific flags
#define HF_BLOCKING 0x00000080
#define HF_ATTBUFFERED 0x00000200
#define HF_HOLDBLOCK 0x00004000
#define HF_ALTATTBUFFERED 0x00010000
#define HF_GRUNTED 0x00020000

There is a function of the HumanContol class:
void HumanControl::EndAttack()
{
int idRootAnim;
int idCurAnim;
int iUpperBody;
REVAL rRootTimer;
REVAL rTransTime;

at the very end of this function a lot of human state flags got cleared in 1 line/operation:

dwFlags &= ~(HF_GRUNTED | HF_ATTBUFFERED | HF_ALTATTBUFFERED | HF_BLOCKING);

Most probably I simply add clearing HF_HOLDBLOCK flag at this point too. So it is mostly 1 bit change in the argument of some AND operation. The exact bit corresponding to position of 1 in 0x00004000 number.

Drakon Rider
Dragon
Posts: 87
Joined: Sun Jul 29, 2001 2:35 am
Location: Russia
Contact:

Post by Drakon Rider »

Also found my old note that describes how 'engine performance patch' acts:

>The memory handling does sound very stupid, though - when Drakan came out, 128MB was a pretty normal spec for most machines.

as you know Drakan's minimum hardware is 16 Mb RAM ... ask Surreal or Psygnosis why it is so...

look at this subroutine - it is a part of render code that manage memory :

Code: Select all

...
.text:0043C7D0 ; --------------- S U B R O U T I N E ---------------------------------------
.text:0043C7D0 
.text:0043C7D0 
.text:0043C7D0 sub_43C7D0      proc near               ; CODE XREF: sub_446A30+258p
.text:0043C7D0                                         ; sub_446E70+6B0p
.text:0043C7D0 
.text:0043C7D0 arg_0           = dword ptr  10h
.text:0043C7D0 arg_4           = dword ptr  14h
.text:0043C7D0 arg_8           = dword ptr  18h
.text:0043C7D0 
.text:0043C7D0                 push    ebx
.text:0043C7D1                 push    ebp
.text:0043C7D2                 push    esi
.text:0043C7D3                 mov     esi, ecx
.text:0043C7D5                 push    edi
.text:0043C7D6                 mov     eax, [esi+1B8h]
.text:0043C7DC                 mov     ecx, [esi+1BCh]
.text:0043C7E2                 cmp     ecx, eax         ; test if allocated memory still enough
.text:0043C7E4                 jl      short loc_43C848 ; jump if everything still OK for render
.text:0043C7E6                 mov     ecx, [esi+1B4h]
.text:0043C7EC                 add     eax, 100h        ; prepare to allocate more memory
.text:0043C7F1                 test    ecx, ecx         ; test if ReAllocating required
.text:0043C7F3                 mov     [esi+1B8h], eax
.text:0043C7F9                 jz      short loc_43C82C  ;   jump to Allocating
.text:0043C7FB                 mov     edi, ds:GlobalHandle
.text:0043C801                 push    ecx             ; pMem
.text:0043C802                 call    edi ; GlobalHandle
.text:0043C804                 push    eax             ; hMem
.text:0043C805                 call    ds:GlobalUnlock
.text:0043C80B                 mov     eax, [esi+1B8h]
.text:0043C811                 mov     ecx, [esi+1B4h]
.text:0043C817                 push    2               ; uFlags
.text:0043C819                 lea     eax, [eax+eax*4]
.text:0043C81C                 shl     eax, 2
.text:0043C81F                 push    eax             ; dwBytes
.text:0043C820                 push    ecx             ; pMem
.text:0043C821                 call    edi ; GlobalHandle
.text:0043C823                 push    eax             ; hMem
.text:0043C824                 call    ds:GlobalReAlloc        ; DAMN SLOW function :(
.text:0043C82A                 jmp     short loc_43C83B
.text:0043C82C ; ---------------------------------------------------------------------------
.text:0043C82C 
.text:0043C82C loc_43C82C:                             ; CODE XREF: sub_43C7D0+29j
.text:0043C82C                 lea     edx, [eax+eax*4]
.text:0043C82F                 shl     edx, 2
.text:0043C832                 push    edx             ; dwBytes
.text:0043C833                 push    0               ; uFlags
.text:0043C835                 call    ds:GlobalAlloc
.text:0043C83B 
.text:0043C83B loc_43C83B:                             ; CODE XREF: sub_43C7D0+5Aj
.text:0043C83B                 push    eax             ; hMem
.text:0043C83C                 call    ds:GlobalLock
.text:0043C842                 mov     [esi+1B4h], eax
.text:0043C848 
.text:0043C848 loc_43C848:                             ; CODE XREF: sub_43C7D0+14j
.text:0043C848                 mov     eax, [esi+1BCh]
.text:0043C84E                 xor     ecx, ecx
.text:0043C850                 mov     edi, [esp+4+arg_4]
.text:0043C854                 lea     edx, [eax+eax*4]
.text:0043C857                 mov     eax, [esi+1B4h]
.text:0043C85D                 lea     edx, [eax+edx*4]
.text:0043C860                 mov     [edx], ecx
.text:0043C862                 mov     [edx+4], ecx
.text:0043C865                 mov     [edx+8], ecx
.text:0043C868                 mov     [edx+0Ch], ecx
.text:0043C86B                 mov     [edx+10h], ecx
.text:0043C86E                 mov     eax, [esi+1BCh]
.text:0043C874                 mov     edx, [esp+4+arg_8]
.text:0043C878                 inc     eax
.text:0043C879                 mov     [esi+1BCh], eax
.text:0043C87F                 mov     ecx, [esi+1B4h]
.text:0043C885                 lea     eax, [eax+eax*4]
.text:0043C888                 lea     ebp, [ecx+eax*4-14h]
.text:0043C88C                 mov     [ebp+0], edx
.text:0043C88F                 mov     [ebp+8], edi
.text:0043C892                 mov     eax, [esi+1C8h]
.text:0043C898                 mov     [ebp+0Ch], eax
.text:0043C89B                 mov     ecx, [esi+164h]
.text:0043C8A1                 mov     [ebp+4], ecx
.text:0043C8A4                 mov     ebx, [esi+1C8h]
.text:0043C8AA                 mov     ecx, [esi+1C4h]
.text:0043C8B0                 mov     eax, ebx
.text:0043C8B2                 lea     edx, [eax+edi]
.text:0043C8B5                 cmp     edx, ecx         ; <== test if enough memory
.text:0043C8B7                 jle     short loc_43C92A ; <== jump if everything still OK for render
.text:0043C8B9                 sub     eax, ecx
.text:0043C8BB                 lea     eax, [eax+edi-1]
.text:0043C8BF                 cdq
.text:0043C8C0                 and     edx, 1FFh ; >
.text:0043C8C6                 add     eax, edx  ; >
.text:0043C8C8                 sar     eax, 9    ; > < == prepare to allocate more memory 
.text:0043C8CB                 inc     eax       ; > 
.text:0043C8CC                 shl     eax, 9    ; >
.text:0043C8CF                 add     eax, ecx
.text:0043C8D1                 mov     ecx, [esi+1C0h]
.text:0043C8D7                 test    ecx, ecx ;    < == test if ReAllocating required
.text:0043C8D9                 mov     [esi+1C4h], eax
.text:0043C8DF                 jz      short loc_43C911 ; < == jump for Allocating
.text:0043C8E1                 push    ecx             ; pMem
.text:0043C8E2                 call    ds:GlobalHandle
.text:0043C8E8                 push    eax             ; hMem
.text:0043C8E9                 call    ds:GlobalUnlock
.text:0043C8EF                 mov     eax, [esi+1C4h]
.text:0043C8F5                 mov     ecx, [esi+1C0h]
.text:0043C8FB                 shl     eax, 5
.text:0043C8FE                 push    2               ; uFlags
.text:0043C900                 push    eax             ; dwBytes
.text:0043C901                 push    ecx             ; pMem
.text:0043C902                 call    ds:GlobalHandle
.text:0043C908                 push    eax             ; hMem
.text:0043C909                 call    ds:GlobalReAlloc        ; DAMN SLOW function :(
.text:0043C90F                 jmp     short loc_43C91D
...
i.e. you can patch byte 09H at offset 3C8CEH in Drakan.exe to 0FH to get about +40% performance at Paradise level and about +190% performance at Atlantis level ... but it would make almost zero difference at retail low-enough-poly levels ... the more POP/POR you have in a frame the more advantage you will get ...

also recommended to patch memory allocation routine at 3C7ECH - we have not place there but we can replace it with a jump to free place at the end of .text section - i make it to 78500H

so changes in the tweaked version:

Code: Select all

.text:0043C7EC			jmp 478500

.text:0043C8CC			shl eax, 0FH

.text:00478500			or eax,100H
.text:00478505			shl eax,05H
.text:00478508			jmp 43C7F1H
You can add it in your patch too.

I think it is part of 'dynamic arrays' which Riot Engine uses to fits in very small RAM machines, but for some design reason it can not reallocates the exact new amount of memory in 1 OS call and makes a number of sequential calls that takes much more time. The point of that patch was to increase the memory allocation step - so reduce a number of calls to reallocating OS subroutine. Yes - it will ends in not optimal memory usage but now we usually have significally more memory in user's PCs.

Also I found some backup of my IDA database with my comments from that years when I searching via Drakan:OOTF binaries:
ftp://fauser:[email protected]/pub ... n_idbs.zip
May it would be useful too. Do not remember what IDA version I use though.

User avatar
Shelim
Dragon
Posts: 189
Joined: Sun Aug 03, 2008 10:55 pm
Location: Poland
Contact:

Post by Shelim »

Magnificent, Drakon Rider!

Much thanks for that, I'll add this to upcomming patch :)

Post Reply