magic/rare DWORD decoding in Classic
#22
CelticHound,Apr 8 2003, 06:21 AM Wrote:What compiler are you using?  I thought even Borland's free compiler supported __int64's.  I'd tested the code I'd linked to above using either Borland C++ 5.02 or MS Visual C++ 6.0.  I forget which - we were switching from one compiler to the other at work around then.

-- CH
Yes, VS definately support the __int64 data type.

Alternatively write the code in assembler :)

Here is some code snipets I once used in a program to simulate the pre expansion item creation. It generate result identical to the one in D2 (since it is identical in function although I trimed some unnessecary stuff out).

There are two functions, one is the standard rnd[x] that returns a value in the 0 to x-1 range. It also takes a paramater that is a pointer to the seed. The other simply returns the seed (after updating it once).

There is two versions of the functions I think (I just copy and paste here). The first uses a data structure with 2 32 bit values (since the game itself pretty much use such a system and you really initialize it that way and use it that way too. It is just a normal structure in at least in VS that I use that structure places those 2 32 bit values right after each other. The other set of functions is basically the same but is set to use a __int64 data type pointer instead. It really doesn't change anything. I think it is commented out in the file I copied from.

Finally there seem to be a few variants on how the function is set up for initialization code and such things (naked and non naked and such use which one you feel most comfortable with). The header file is for the non comented case only though!

Code:
// random.cpp

#include "stdafx.h"

#pragma warning( disable : 4035 )    // avoids warning for not returning any value
__declspec( naked ) unsigned int __fastcall d2rnd(struct seeddata *ptseed, unsigned int x)
{
    __asm
    {
 push edi;
 push esi;
 push ebx;
 mov edi,edx;
 mov esi,ecx;      // no check on pointer!!
 test edi,edi;      // check if x>0
 jg OK;
&nbsp;xor eax,eax; &nbsp;    // return 0 if x <= 0
&nbsp;jmp END;
OK:
&nbsp;mov eax, [esi]; &nbsp;    // get seed_lo
&nbsp;mov ecx, 0x6ac690c5;    // rndmult
&nbsp;mul ecx;
&nbsp;mov ecx,[esi+4]; &nbsp;// get seed_hi
&nbsp;xor ebx,ebx;
&nbsp;add eax,ecx;
&nbsp;adc edx,ebx;
&nbsp;mov [esi],eax; &nbsp;    // store away new seed
&nbsp;mov [esi+4],edx;
&nbsp;xor edx,edx;
&nbsp;div edi; &nbsp; &nbsp;// calculate random number based on seed_lo
&nbsp;mov eax,edx; &nbsp;    // return reminder
END:
&nbsp;pop ebx;
&nbsp;pop esi;
&nbsp;pop edi;
&nbsp;ret
    }
    // returns random value in eax
} // d2rnd
#pragma warning( default : 4035 )


#pragma warning( disable : 4035 )    // avoids warning for not returning any value
__declspec( naked ) unsigned int __fastcall d2seed(struct seeddata *ptseed)
// same as above but no division at end, returns lo_seed instead
{
    __asm
    {
&nbsp;push esi;
&nbsp;push ebx;
&nbsp;mov esi,ecx; &nbsp;    // no check on pointer!!
&nbsp;mov eax, [esi]; &nbsp;    // get seed_lo
&nbsp;mov ecx, 0x6ac690c5;    // rndmult
&nbsp;mul ecx;
&nbsp;mov ecx,[esi+4]; &nbsp;// get seed_hi
&nbsp;xor ebx,ebx;
&nbsp;add eax,ecx;
&nbsp;adc edx,ebx;
&nbsp;mov [esi],eax; &nbsp;    // store away new seed
&nbsp;mov [esi+4],edx;
&nbsp;pop ebx;
&nbsp;pop esi;
&nbsp;ret
    }
    // returns value in eax (new lo_seed)
} // d2seed
#pragma warning( default : 4035 )



/*
#pragma warning( disable : 4035 )    // avoids warning for not returning any value
int d2rnd(__int64 *ptseed, int x)
{
    __asm
    {
&nbsp;mov edi,x;
&nbsp;mov esi,ptseed; &nbsp;    // no check on pointer!!
&nbsp;test edi,edi; &nbsp;    // check if x>0
&nbsp;jg OK;
&nbsp;xor eax,eax; &nbsp;    // return 0 if x <= 0
&nbsp;jmp END;
OK:
&nbsp;mov eax, [esi]; &nbsp;    // get seed_lo
&nbsp;mov ecx, 0x6ac690c5;    // rndmult
&nbsp;mul ecx;
&nbsp;mov ecx,[esi+4]; &nbsp;// get seed_hi
&nbsp;xor ebx,ebx;
&nbsp;add eax,ecx;
&nbsp;adc edx,ebx;
&nbsp;mov [esi],eax; &nbsp;    // store away new seed
&nbsp;mov [esi+4],edx;
&nbsp;xor edx,edx;
&nbsp;div edi; &nbsp; &nbsp;// calculate random number based on seed_lo
&nbsp;mov eax,edx; &nbsp;    // return reminder
END:
    }
    // returns value in eax
} // d2rnd
#pragma warning( default : 4035 )


#pragma warning( disable : 4035 )    // avoids warning for not returning any value
int d2seed(__int64 *ptseed)
// same as above but no division at end, returns seed instead
{
    __asm
    {
&nbsp;mov esi,ptseed; &nbsp;    // no check on pointer!!
&nbsp;mov eax, [esi]; &nbsp;    // get seed_lo
&nbsp;mov ecx, 0x6ac690c5;    // rndmult
&nbsp;mul ecx;
&nbsp;mov ecx,[esi+4]; &nbsp;// get seed_hi
&nbsp;xor ebx,ebx;
&nbsp;add eax,ecx;
&nbsp;adc edx,ebx;
&nbsp;mov [esi],eax; &nbsp;    // store away new seed
&nbsp;mov [esi+4],edx;
    }
    // returns value in eax (new lo_seed)
} // d2seed
#pragma warning( default : 4035 )




#pragma warning( disable : 4035 )    // avoids warning for not returning any value
__declspec( naked ) int __fastcall d2rnd(__int64 *ptseed, int x)
{
    __asm
    {
&nbsp;push edi;
&nbsp;push esi;
&nbsp;push ebx;
&nbsp;mov edi,edx;
&nbsp;mov esi,ecx; &nbsp;    // no check on pointer!!
&nbsp;test edi,edi; &nbsp;    // check if x>0
&nbsp;jg OK;
&nbsp;xor eax,eax; &nbsp;    // return 0 if x <= 0
&nbsp;jmp END;
OK:
&nbsp;mov eax, [esi]; &nbsp;    // get seed_lo
&nbsp;mov ecx, 0x6ac690c5;    // rndmult
&nbsp;mul ecx;
&nbsp;mov ecx,[esi+4]; &nbsp;// get seed_hi
&nbsp;xor ebx,ebx;
&nbsp;add eax,ecx;
&nbsp;adc edx,ebx;
&nbsp;mov [esi],eax; &nbsp;    // store away new seed
&nbsp;mov [esi+4],edx;
&nbsp;xor edx,edx;
&nbsp;div edi; &nbsp; &nbsp;// calculate random number based on seed_lo
&nbsp;mov eax,edx; &nbsp;    // return reminder
END:
&nbsp;pop ebx;
&nbsp;pop esi;
&nbsp;pop edi;
    }
    // returns value in eax
} // d2rnd
#pragma warning( default : 4035 )



// random.h

extern unsigned int __fastcall d2rnd(struct seeddata *ptseed, unsigned int x);
extern unsigned int __fastcall d2seed(struct seeddata *ptseed);

struct seeddata {
    unsigned int    seed;
    unsigned int    mod;
};
There are three types of people in the world. Those who can count and those who can't.
Reply


Messages In This Thread
magic/rare DWORD decoding in Classic - by ldw - 02-23-2003, 12:37 PM
magic/rare DWORD decoding in Classic - by Jarulf - 02-24-2003, 09:21 AM
magic/rare DWORD decoding in Classic - by Jarulf - 02-28-2003, 09:15 AM
magic/rare DWORD decoding in Classic - by FoxBat - 03-13-2003, 04:33 PM
magic/rare DWORD decoding in Classic - by Ruvanal - 03-13-2003, 09:44 PM
magic/rare DWORD decoding in Classic - by aurikan - 03-28-2003, 02:42 AM
magic/rare DWORD decoding in Classic - by Jarulf - 03-28-2003, 09:21 AM
magic/rare DWORD decoding in Classic - by Jarulf - 03-30-2003, 08:00 PM
magic/rare DWORD decoding in Classic - by Jarulf - 04-08-2003, 09:08 PM
magic/rare DWORD decoding in Classic - by Jarulf - 04-18-2003, 08:46 AM
magic/rare DWORD decoding in Classic - by Jarulf - 04-18-2003, 06:20 PM
magic/rare DWORD decoding in Classic - by Jarulf - 04-21-2003, 07:56 AM
magic/rare DWORD decoding in Classic - by Jarulf - 03-19-2005, 12:27 PM

Forum Jump:


Users browsing this thread: 7 Guest(s)