Wognif Posted June 10, 2013 Share Posted June 10, 2013 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. Quisoves Potoo, Car CrazeXVI, Brickulator and 5 others 8 Link to comment Share on other sites More sharing options...
Aokpisz Posted June 10, 2013 Share Posted June 10, 2013 Holy crap. That is a lot of object switching. Nice job. Link to comment Share on other sites More sharing options...
Wognif Posted June 12, 2013 Author Share Posted June 12, 2013 I just figured out that it is possible to replace a plant with a building! Brickulator and Car CrazeXVI 2 Link to comment Share on other sites More sharing options...
Wirza Posted October 8, 2013 Share Posted October 8, 2013 what do you use to swap? can you explain how to do it Link to comment Share on other sites More sharing options...
Wognif Posted October 8, 2013 Author Share Posted October 8, 2013 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 More sharing options...
Wirza Posted October 9, 2013 Share Posted October 9, 2013 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 More sharing options...
TheDoctor Posted October 9, 2013 Share Posted October 9, 2013 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 More sharing options...
Wirza Posted October 9, 2013 Share Posted October 9, 2013 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 Link to comment Share on other sites More sharing options...
Mr. Eight-Three-One Posted October 14, 2013 Share Posted October 14, 2013 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 More sharing options...
jermain2000 Posted October 16, 2013 Share Posted October 16, 2013 Im lucky that i use Windows XP. Link to comment Share on other sites More sharing options...
Noneatme Posted March 22, 2014 Share Posted March 22, 2014 Hello everybody, (Sorry for my bad english ) Reverse-Engineering is fun I disassembled the LEGO1.dll, and found something interesting. (maybe) You can find the import, exports, strings and functions here: http://noneatme.de/LEGO1DLL/ If you are interested in the pseudo-sourcecode, you can find it here: http://noneatme.de/LEGO1DLL/LEGO1.c (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 Car CrazeXVI, Sharkly, Wognif and 3 others 6 Link to comment Share on other sites More sharing options...
Sharkly Posted March 22, 2014 Share Posted March 22, 2014 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! Noneatme 1 Link to comment Share on other sites More sharing options...
Noneatme Posted March 22, 2014 Share Posted March 22, 2014 Thanks 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) le717 1 Link to comment Share on other sites More sharing options...
SchollExpos Posted April 3, 2014 Share Posted April 3, 2014 Problem: Your website is down.... Link to comment Share on other sites More sharing options...
Noneatme Posted April 4, 2014 Share Posted April 4, 2014 Yep, I got too much traffic the last month so they disabled the DNS server Anyway, you can find all the source files here: http://noneatme.schotobi.com/Lego/LEGO1DLL/ Link to comment Share on other sites More sharing options...
SchollExpos Posted April 4, 2014 Share Posted April 4, 2014 LegoGameState::~LegoGameState(void) // constructor (bitwise) Little correction: That's the deconstructor of LegoGameState Link to comment Share on other sites More sharing options...
Noneatme Posted April 5, 2014 Share Posted April 5, 2014 Oh okay, my bad. In some other languages the ~ operator defines an overloaded method Link to comment Share on other sites More sharing options...
Noneatme Posted May 15, 2014 Share Posted May 15, 2014 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: (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) 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; } lol username, Quisoves Potoo, Fluffy Cupcake and 1 other 4 Link to comment Share on other sites More sharing options...
lol username Posted May 15, 2014 Share Posted May 15, 2014 Time to bust out that thumbs up GIF again. Link to comment Share on other sites More sharing options...
dead_name Posted May 15, 2014 Share Posted May 15, 2014 Dude. This is great. I want a list of all the tools you use. Drop me a PM? Link to comment Share on other sites More sharing options...
Noneatme Posted May 15, 2014 Share Posted May 15, 2014 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 Greetings Link to comment Share on other sites More sharing options...
le717 Posted May 15, 2014 Share Posted May 15, 2014 Dude, this is awesome. 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 More sharing options...
Noneatme Posted May 27, 2014 Share Posted May 27, 2014 Here are some informations: The reversing is still going. If you wonder why the game can't be played in a higher resolution: http://noneatme.de/Lego/LEGO1DLL/MoveCursor.html And the MxOmni class is some kind of core class. It contains all the objects like LegoWorld, LegoGameState, LegoEntity dead_name, le717 and Wognif 3 Link to comment Share on other sites More sharing options...
mumboking Posted May 27, 2014 Share Posted May 27, 2014 If you wonder why the game can't be played in a higher resolution: http://noneatme.de/Lego/LEGO1DLL/MoveCursor.html 623x463? But... LI runs in 640x480, doesn't it? Link to comment Share on other sites More sharing options...
Noneatme Posted May 28, 2014 Share Posted May 28, 2014 If you wonder why the game can't be played in a higher resolution: http://noneatme.de/Lego/LEGO1DLL/MoveCursor.html 623x463? But... LI runs in 640x480, doesn't it? Disassemble issue, it does Link to comment Share on other sites More sharing options...
Recommended Posts