Jump to content

LEGO1.DLL Documentation


Wognif
 Share

Recommended Posts

I did some experimenting with LEGO1.DLL recently, and here's the results.
Only the swaps that did work are listed.

Objects that can be used as hats:


bush (Is really a lamp post)
tree
flwrred
palm
head (this looks rather silly as a hat)
debrick (the Brickster's megaphone/gun thing)
pwrbrik (the power brick!)
2x4grn (2x4 green brick)
2x4red (2x4 red brick)
palmred
Palmyel
Palmblk
palmwht
bushred
bushyel
bushblk
bushwht
treered
treeyel
treeblk
treewht
flwrgrn
flwryel
flwrblk
flwrwht
body (floating torso minions, anyone?) (this can also be used as a plant!)

cavedoor

 

Buildings, which can be hats, (and plants!) :


haus1
haus2
haus3
haus4
haus5
haus6
haus7
gas
infocen

Haven't tried:
Post
Bank
Store
beach
medcntr
races
racej
racef
policsta

 

Head textures:


mustache.gif
black.gif (used on ghosts)
smile.gif
woman.gif
smileshd.gif
womanshd.gif
dogface.gif (Nubby and Studs use this face)
shftface.gif (Brickster!)
infoface.gif (Infomaniac)
noraface.gif (Laura)
nickface.gif (Nick)
papaface.gif (Papa)
mamaface.gif (Mama)
peprface.gif (Pepper)

 

Chest textures:


unkchst.gif (the big "?")
16.gif (unused legondo chest, features a 2x4 brick)
paint.gif (I vaguely remember this)
construct.gif (A worker's chest)
flowers.gif
fruit.gif (swimsuit top of a certain unnamed character that appears during the chopper chase, and jet ski race.)
O.gif (legondo o  )
g.gif (legondo G)
e.gif (legondo E)
l.gif (legondo L)
copchest.gif (Captain D. Rom's chest)
doctor.gif
vest.gif (Nancy's chest)
postchst.gif (Ed Mail's chest)
bowtie.gif
polkadot.gif
mech.gif (Nubby and the four Bill Dings use this)
bth2chst.gif
bth1chst.gif
rac2chst.gif
rac1chst.gif
shftchst.gif (Brickster's chest)
infochst.gif (Infomaniac's chest)
norachst.gif (laura's chest)
nickchst.gif (Nick's chest)
papachst.gif (Papa's tux)
mamachst.gif (Mama's apron)
peprchst.gif (Pepper's chest)

 

Body colors:


bodybrwn
bodygren
bodyblue
bodyyllw
bodywhte
bodyblck
bodyred

 

Hats:


icap (Infomaniac's hat)
phat (Pepper's hat)
sheet (ghost)
capmd (doctor's hat)
capjs (Bill Ding hat)
capch (Bill Ding hat)
caprc (Bill Ding hat)
pizhat (Get that pizza off of your head, silly!)
backbcap
cathat (a cat)
cuphat (_______ to CUPS!)
cboyhat (Cowboy hat)
flower (FLOWERS to ____!)
bald
shrthair (manly hair)
pageboy (long hair)
ponytail (hair in a ponytail)
helmet
cophat
cap
chef (Mama and Papa wear this)
baseball

 

Some interesting things I found while viewing LEGO1.DLL in a program called DLL Export Viewer (not listing all of them, because some I'm uncertain about what they are) :
 

class LegoEntity * __cdecl PickEntity(long,long)    0x1003ddc0    0x0003ddc0    84 (0x54)
class LegoSoundManager * __cdecl SoundManager(void)    0x10015710    0x00015710    112 (0x70)            
class LegoVideoManager * __cdecl VideoManager(void)    0x10015720    0x00015720    123 (0x7b)            
class MxBackgroundAudioManager * __cdecl BackgroundAudioManager(void)    0x10015730    0x00015730    34 (0x22)            
class MxDSObject * __cdecl CreateStreamObject(class MxDSFile *,short)    0x100c0280    0x000c0280    40 (0x28)
class MxEventManager * __cdecl EventManager(void)    0x100acf40    0x000acf40    50 (0x32)        
class MxMusicManager * __cdecl MusicManager(void)    0x100acf30    0x000acf30    77 (0x4d)        
class MxNotificationManager * __cdecl NotificationManager(void)    0x100aceb0    0x000aceb0    78 (0x4e)
class MxTransitionManager * __cdecl TransitionManager(void)    0x10015900    0x00015900    120 (0x78)
public: __thiscall LegoWorld::LegoWorld(void)    0x1001ca40    0x0001ca40    3 (0x3)
public: __thiscall MxDSAction::MxDSAction(void)    0x100ad810    0x000ad810    8 (0x8)        
public: __thiscall MxDSFile::MxDSFile(char const *,unsigned long)    0x100cc4b0    0x000cc4b0    9 (0x9)    
public: static void __cdecl LegoAnimationManager::configureLegoAnimationManager(int)    0x1005eb50    0x0005eb50    124 (0x7c)        
public: static void __cdecl LegoBuildingManager::configureLegoBuildingManager(int)    0x1002f8b0    0x0002f8b0    125 (0x7d)        
public: static void __cdecl LegoModelPresenter::configureLegoModelPresenter(int)    0x1007f660    0x0007f660    126 (0x7e)
public: static void __cdecl MxOmni::DestroyInstance(void)    0x100b0690    0x000b0690    41 (0x29)
public: virtual __thiscall MxDSAction::~MxDSAction(void)    0x100ada80    0x000ada80    25 (0x19)        
public: virtual __thiscall MxDSFile::~MxDSFile(void)    0x100bfed0    0x000bfed0
public: void __thiscall MxDSObject::SetObjectName(char const *)    0x100bf8e0
public: void __thiscall MxTransitionManager::SetWaitIndicator(class MxVideoPresenter *)    0x1004c470    0x0004c470    111 (0x6f)

Some of it seems obvious, such as the Sound and Video Managers.

The MXTrasitionManager seems to be what controls the transitions that occur when entering/exiting a vehicle or building.

I'm not quite sure about the MXDS file(s) it mentions.

Link to comment
Share on other sites

  • 3 months later...

what do you use to swap? can you explain how to do it :?:

To edit, use any hexadecimal editor.

If the name of an object your going to swap is larger than the name of the object you'll replace, it wont work.

However, if the name of the object is shorter than the one that's to be replaced, replace the remaining characters of its name (in the numeric area) with 00.

Its that easy.

And I apologize if this was a bit vague.

Link to comment
Share on other sites

Thank you!

 

 

To edit, use any hexadecimal editor.

 

What is that? And where do you get that?

 

also,are you able to use a hexidecimal editor on a windows 98?

Link to comment
Share on other sites

To edit, use any hexadecimal editor.

 

What is that? And where do you get that?

 

also,are you able to use a hexidecimal editor on a windows 98?

Any amount of amateur googling would net you some useful information. However, I'm going to speed the undoubtedly arduous process for you and just link you to this: http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm It should work just fine.

As for the list of things in the OP, they're some C/++ class and function names. They're really not any use to you unless you know what they are and what you intend to do with this information.

Link to comment
Share on other sites

However, I'm going to speed the undoubtedly arduous process for you and just link you to this

 

thanks so much for saving my time but my 98 is not hooked up to the internet unfortunantly :gasp:

Link to comment
Share on other sites

Mr. Eight-Three-One

Somewhat late to reply, but... you could always burn the program to a CD-R and load it on the 98 machine. Just a thought.

Link to comment
Share on other sites

  • 5 months later...
Hello everybody,
(Sorry for my bad english :D )
 
Reverse-Engineering is fun  :lol:
 
I disassembled the LEGO1.dll, and found something interesting. (maybe)

 

You can find the import, exports, strings and functions here:
 
 
If you are interested in the pseudo-sourcecode, you can find it here:
 
(Open this file in Notepad++ or VS Studio and set the syntax to C++)
There is some awesome pseudostuff going on, so the functions are not documentated yet. 
The variables are some kind of broken, due the 16 bit-limitation.
 
Many of the functions refers to the (MS) Libarys (Input / Output, Music, Sounds)
Anyway, there are some (unknow?) variables I found:
 
 

extern char aScore[6]; // weak
extern char aLegoworld[10]; // weak
extern char aLegoentity[11]; // weak
extern char aMxentity[9]; // weak
extern char aMxcore[7]; // weak
extern char aScorestate[11]; // weak
extern char aBigcube_gif[12]; // weak
extern char aCarracestate[13]; // weak
extern char aJetskiracestat[16]; // weak
extern char aTowtrackmissio[21]; // weak
extern char aPizzamissionst[18]; // weak
extern char aAmbulancemissi[22]; // weak
extern int dword_100F0100; // weak
extern char aIslepathactor[14]; // weak
extern char aLegopathactor[14]; // weak
extern char aLegoactor[10]; // weak
extern char aHelicopter[11]; // weak
extern char aAct3[5]; // weak
extern char aHelicopterstat[16]; // weak
extern char aAct1state[10]; // weak
extern int dword_100F0160; // weak
extern char byte_100F0164; // weak
extern char aGasstation[11]; // weak
extern char aGasstationstat[16]; // weak
extern char aMxstillpresent[17]; // weak
extern char aCapdb_0[]; // idb
extern char aCapdb[]; // idb
extern char aLegostate[10]; // weak
extern char aLegocachesound[15]; // weak
extern char byte_100F01D4; // weak
extern char aRaceskel[9]; // weak
extern char aJailentity[11]; // weak
extern char aCaveentity[11]; // weak
extern char aAct3brickster[14]; // weak
extern char aAct3cop[8]; // weak
extern char aMotocycle[10]; // weak
extern char aAct2genactor[13]; // weak
extern char aAct2actor[10]; // weak
extern char aLegojetskibuil[21]; // weak
extern char aLegodunecarbui[22]; // weak
extern char aLegocopterbuil[21]; // weak
extern char aLegoracecarbui[22]; // weak
extern char aLegoact2[9]; // weak
extern char aLegometerprese[19]; // weak
extern char aJukeboxstate[13]; // weak
extern char aJukebox[8]; // weak
extern char aMxcompositemed[26]; // weak
extern char aJukeboxentity[14]; // weak
extern char aRacestandsenti[17]; // weak
extern char aBeachhouseenti[17]; // weak
extern char aPoliceentity[13]; // weak
extern char aHospitalentity[15]; // weak
extern char aGasstationenti[17]; // weak
extern char aInfocenterenti[17]; // weak
extern char aPizzeriastate[14]; // weak
extern char aPizzeria[9]; // weak
extern char aPizza[6]; // weak
extern char aBumpbouy[9]; // weak
extern char aAct3shark[10]; // weak
extern char aAct3actor[10]; // weak
extern char aTowtrack[9]; // weak
extern char aAmbulance[10]; // weak
extern char aBike[5]; // weak
extern char aJetski[7]; // weak
extern char aRacecar[8]; // weak
extern char aDoors[6]; // weak
extern char aAct3state[10]; // weak
extern char aAct2policestat[18]; // weak
extern char aDunebuggy[10]; // weak
extern char aSkateboard[11]; // weak
extern char aLegoact2state[14]; // weak
extern char aAct2brick[10]; // weak
extern char aPolicestate[12]; // weak
extern char aPolice[7]; // weak
extern char aIsle[5]; // weak
extern char aAnimstate[10]; // weak
extern char aLegoanimmmpres[20]; // weak
extern char aHospitalstate[14]; // weak
extern char aHospital[9]; // weak
extern char aInfocenterdoor[15]; // weak
extern char aElevatorbottom[15]; // weak
extern char aHistorybook[12]; // weak
extern char aRegistrationbo[17]; // weak
extern char aInfocenterstat[16]; // weak
extern char aInfocenter[11]; // weak
extern char aRadiostate[11]; // weak
extern char aLegocarbuild[13]; // weak
extern char aMxcontrolprese[19]; // weak
extern char aCarrace[8]; // weak
extern char aJetskirace[11]; // weak
extern char aLegojetski[11]; // weak
extern char aLegoracecar[12]; // weak
extern char aLegojetskirace[20]; // weak
extern char aLegocarraceact[17]; // weak
extern char aLegoanimactor[14]; // weak
extern char aLego3dwavepres[20]; // weak
extern char aLegoloadcaches[28]; // weak
extern char aLegoactioncont[27]; // weak
extern char aLegopartpresen[18]; // weak
extern char aLegocarbuildan[26]; // weak
extern char aLegoworldprese[19]; // weak
extern char aLegopalettepre[21]; // weak
extern char aLegoflctexture[24]; // weak
extern char aLegophonemepre[21]; // weak
extern char aLegotexturepre[21]; // weak
extern char aLegomodelprese[19]; // weak
extern char aLegopathpresen[18]; // weak
extern char aLegoactorprese[19]; // weak
extern char aLegoentitypres[20]; // weak
extern char aLegohideanimpr[22]; // weak
extern char aLegolocomotion[28]; // weak
extern char aLegoloopingani[25]; // weak
extern char aLegoanimpresen[18]; // weak
extern char aMxobjectfactor[16]; // weak
extern char aMxpresenter[12]; // weak
extern char aMxmediapresent[17]; // weak
extern char aMxvideopresent[17]; // weak
extern char aMxcompositepre[21]; // weak
extern char aMxaudiopresent[17]; // weak
extern char aMxsoundpresent[17]; // weak
extern char aMxwavepresente[16]; // weak
extern char aLegorace[9]; // weak
extern char aRacestate[10]; // weak
extern char aIsleactor[10]; // weak
extern char aBuildingentity[15]; // weak
extern char aSubstHaus1S[]; // idb
extern char aSubstBushSTree[]; // idb
extern char aSubstActor_01S[]; // idb
extern char aHead[]; // idb
extern char aLegocameracont[21]; // weak

 
 
The LegoGameState class:
 

LegoGameState::LegoGameState(void)         // constructor
LegoGameState::Load(ulong)                      // loads the Game
LegoGameState::Save(ulong)                      // saves the Game
LegoGameState::SerializePlayersInfo(short)      // sets the player informations ( person )
LegoGameState::SerializeScoreHistory(short)     // sets the score
LegoGameState::SetSavePath(char *)              // sets the game save path
LegoGameState::~LegoGameState(void)             // constructor (bitwise)
 

 
 
LegoInputManager class:
 
 

LegoInputManager::QueueEvent(NotificationId,uchar,long,long,uchar)                         // handles input event
LegoInputManager::Register(MxCore *) // registers input events
LegoInputManager::UnRegister(MxCore *) // unregisters input events

 
LegoOmni class: (sound class)
 

LegoOmni::CreateBackgroundAudio(void) // creates background music
LegoOmni::CreateInstance(void)         // creates and instance(maybe for every backgroundmusic ingame)
LegoOmni::GetCurrPathInfo(LegoPathBoundary * *,int &)                 // gets the current path informations (for music, where you stand)
LegoOmni::GetInstance(void) // gets the instance
LegoOmni::RemoveWorld(MxAtomId const &,long)         // removes the world (?) undocumentated

 
Anyway, the other classes are some kind of engine classes (rendering, and some other stuff)
 
I will edit the post later to add more informations.
 
I hope it's interesting in some kind :D
Link to comment
Share on other sites

Very nice job Noneatme, I'm not sure how useful this information will actually be in the modding of LEGO Island, but it's very interesting nonetheless. Also, don't apologize for your English, it's great!

Link to comment
Share on other sites

Thanks :D

Well you can see the registers and which function is stored in register xxxxxxx.

(That's how trainers are made)

 

 

Then you can modify each register with third-party software (or selfmade software),to modify or implement things you won't be able to do.

(Incresing limits of polygons, entitys, hook functions and create pointers(...), things like that)

 

For example move buildings and trigger some events in real-time without modifying the game files.

 

The problem is that you can easily crash your game if you don't know the functionality of the game (how the developers did what they did)

Link to comment
Share on other sites

  • 2 weeks later...
SchollExpos

LegoGameState::~LegoGameState(void) // constructor (bitwise)

Little correction: That's the deconstructor of LegoGameState :)

Link to comment
Share on other sites

  • 1 month later...

Sorry for the double post, but I've got some updates,

Some guy I know helped me reversing the lego1.dll, and we finally got something reversed.

 

 

The .SI files will be parsed in this functions:

 

1400196990.png

(The green ones are decompiled)

 

Lego Island / Mindscape uses his own engine, all engine functions have the "Mx"-keyword in their name. (MxFile, MxOmni(Sounds))

 

It seems that the game reads the first 12 bytes of the .SI file in order to get the .SI file version. (It must be 2.2, otherwise the game will exit)

The problem is that it doesn't make sense at all because there is no number in any .si file, so we think theres an archive format located between the files. (RIFF)

 

1400143834.png

 

We managed to decompile some functions, but we are still working on it.

 

signed int __thiscall MxDSFile::Read(MxDSFile *pFileHandle, LPVOID lpBuffer, __int32 lBytes)
{
  MxDSFile *this_; // edi@1
  signed int result; // eax@2

  this_ = pFileHandle;                          // pFileHandle
  if ( CFileHandle::ReadInternal((MxDSFile *)((char *)pFileHandle + 36), lpBuffer, lBytes) == lBytes )
  {
    result = 0;
    this_->currentBytes += lBytes;              // ByteCounter
                                                // 
  }
  else
  {
    result = -1;
  }
  return result;
} 
__int32 __thiscall CFileHandle::ReadInternal(MxDSFile *this, LPVOID lpBuffer, __int32 lBytes)
{
  MxDSFile *this_; // ebx@1
  __int32 bufferBytes; // ebp@2
  unsigned int tempBuffer?; // eax@2
  HFILE hFile; // ecx@12
  __int32 currentBytes; // [sp+10h] [bp-4h]@1

  currentBytes = 0;
  this_ = this;
  if ( this->field_18 )
  {
    bufferBytes = lBytes;
    tempBuffer? = *(_DWORD *)&this->gap_1E[2] - *(_DWORD *)&this->someString_Int;
    do
    {
      if ( bufferBytes <= 0 )
        break;
      if ( (signed int)tempBuffer? > 0 )
      {
        if ( bufferBytes < (signed int)tempBuffer? )
          tempBuffer? = bufferBytes;
        bufferBytes -= tempBuffer?;
        memcpy(lpBuffer, *(const void **)&this_->someString_Int, tempBuffer?);
        *(_DWORD *)&this_->someString_Int += tempBuffer?;
        currentBytes += tempBuffer?;
      }
      if ( bufferBytes <= 0 )
        break;
      if ( sub_100CCF40((int)this_, 0) )
        break;
      tempBuffer? = *(_DWORD *)&this_->gap_1E[2] - *(_DWORD *)&this_->someString_Int;
    }
    while ( *(_DWORD *)&this_->gap_1E[2] - *(_DWORD *)&this_->someString_Int > 0 );
  }
  else
  {
    hFile = *(_DWORD *)&this->gap_29[27];
    if ( hFile && lBytes > 0 )
    {
      currentBytes = hread(hFile, lpBuffer, lBytes);
      if ( currentBytes == -1 )
      {
        currentBytes = 0;
        *(_DWORD *)&this_->gap_29[3] = llseek(*(_DWORD *)&this_->gap_29[27], 0, 1);
      }
      else
      {
        *(_DWORD *)&this_->gap_29[3] += currentBytes;
      }
    }
  }
  return currentBytes;
} 
signed int __thiscall MxDsFile::ReadHeader(MxDSFile *this)
{
  int pFileHandle; // esi@1
  MxDSFile *this_; // edi@1
  signed int result; // eax@2
  char Buffer; // [sp+Ch] [bp-78h]@1
  int someBuffer; // [sp+14h] [bp-70h]@1
  int lpBuffer; // [sp+20h] [bp-64h]@3
  const CHAR Dest; // [sp+34h] [bp-50h]@11

  someBuffer = 1229868367;
  pFileHandle = (int)&this->pFileHandle;
  this_ = this;
  if ( CFileHandle::Read((int)&this->pFileHandle, (int *)&Buffer, 0, 32) )
  {
    result = -1;
  }
  else
  {
    lpBuffer = 1682470989;
    if ( CFileHandle::Read(pFileHandle, &lpBuffer, (int)&Buffer, 0) )
    {
      result = -1;
    }
    else
    {
      CFileHandle::ReadInternal((MxDSFile *)pFileHandle, &this_->majorVersion, 12);// Read the header
      if ( this_->majorVersion != 2 || this_->minorVersion != 2 )
      {
        sprintf((char *)&Dest, "Wrong SI file version. %d.%d expected.", 2, 2);
        MessageBoxA(0, &Dest, 0, MB_ICONERROR);
        result = -1;
      }
      else
      {
        lpBuffer = 0x664F784Du;
        if ( !CFileHandle::Read(pFileHandle, &lpBuffer, (int)&Buffer, 0) )
        {
          CFileHandle::ReadInternal((MxDSFile *)pFileHandle, &this_->lpBuffer, 4);
          exit(4 * this_->lpBuffer);
        }
        result = -1;
      }
    }
  }
  return result;
} 

  • Like 4
Link to comment
Share on other sites

We use IDA Pro 6.1 to disassemble and reverse the dll.

 

Later this day we will debug the game in order to analyze some dwords which we don't know what they are standing for.

 

But thanks everyone :D

 

Greetings

Link to comment
Share on other sites

Dude, this is awesome. :D

You may want to get in touch with Matt Thompson, the creator of LIME (https://github.com/mathom/LIME). He was rewriting it as a general-purpose SI extractor (look at the rewrite branch), and I know he has said stuff in the closed issues about RIFF and the SI archives. He might be able to help you.

Link to comment
Share on other sites

  • 2 weeks later...
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.