B-$hep SCR decompiler
Re: SCR decompiler
I'd like to be able to search for coordinates in an SCR file. How do you convert GTA2 coordinates to the hex SCR format?
Can you apply the Redneck crane fix to the kill frenzy fixed ste.scr? It also needs fixing in the multplayer versions res-2p.SCR to res-6p.SCR.
Can you apply the Redneck crane fix to the kill frenzy fixed ste.scr? It also needs fixing in the multplayer versions res-2p.SCR to res-6p.SCR.
Re: SCR decompiler
Sektor.
Maybe i should add this functionality into SCR tool?
About the cranes. I could look at them.
Do you want to say me that in res-2p.SCR to res-6p.SCR. In all of these scripts cranes are not working?
Just like the Rednecks one ?
Maybe i should add this functionality into SCR tool?
About the cranes. I could look at them.
Do you want to say me that in res-2p.SCR to res-6p.SCR. In all of these scripts cranes are not working?
Just like the Rednecks one ?
Last edited by B-$hep on 09 Aug 2011, 20:37, edited 1 time in total.
Re: SCR decompiler
Thanks. Yes all of those have the same problem as ste.scr with the redneck crane. No one uses the cranes in multiplayer anyway, so it doesn't really matter.
Re: SCR decompiler
Never say never.
http://www.gta2madness.co.cc/click.php?id=9
What about other scripts?
Do the cranes work?
http://www.gta2madness.co.cc/click.php?id=9
What about other scripts?
Do the cranes work?
Re: SCR decompiler
I assume cranes work in other scripts, no one has complained about them.
Can you add command line support to SCR Tool? gta2scrtool2.exe Water_Town6p.scr
The browse for folder should let me type a path and it should save the last path I used or start in the gta2scrtool path.
I don't need it to create *.original of all my scr files, maybe just the last one I opened or none at all.
How do I change remap for player 2? It keeps going back to player 1 when I push the remap button.
Can you add command line support to SCR Tool? gta2scrtool2.exe Water_Town6p.scr
The browse for folder should let me type a path and it should save the last path I used or start in the gta2scrtool path.
I don't need it to create *.original of all my scr files, maybe just the last one I opened or none at all.
How do I change remap for player 2? It keeps going back to player 1 when I push the remap button.
- Vike the Hube
- Hitman
- Posts: 145
- Joined: 28 Feb 2010, 22:34
- GH nick: vike
Re: SCR decompiler
Hey I was having a little look at this because TM was asking for a list of the commands supported by miss2. And, as B-Shep previously found, the compiler was written with Visual Parse++. Visual Parse++ was (when it was still around) based on the old Unix tools, Flex (lex) and Bison (yacc). The two files miss2.dfa and miss2.llr supplied with miss2.exe are the Flex state table and the Bison LALR parse state table.
It's theoretically possible to translate these directly into the symbols and grammar supported by miss2, and that should significantly help me understand how miss2 generates the bytecode etc. However I don't have the time and can't be bothered re-reading enough of my compiler construction textbook so I understand LALR parse tables again XD
So, does anyone here know much about compiler construction, parsers, etc? If so this would be worth it because much of the learning curve would be gone, it would be a much quicker process. I managed to download Visual Parse++ off the Web Archive and I've cracked it, so anything we need out of that I can get... but unfortunately it doesn't directly open DFA and LLR files, only uses them for creation of the compiler code.
I guess this isn't necessarily worth the effort, but my point is if someone wants to pick it up I'm willing to help, and there is somewhere to start ;-D
It's theoretically possible to translate these directly into the symbols and grammar supported by miss2, and that should significantly help me understand how miss2 generates the bytecode etc. However I don't have the time and can't be bothered re-reading enough of my compiler construction textbook so I understand LALR parse tables again XD
So, does anyone here know much about compiler construction, parsers, etc? If so this would be worth it because much of the learning curve would be gone, it would be a much quicker process. I managed to download Visual Parse++ off the Web Archive and I've cracked it, so anything we need out of that I can get... but unfortunately it doesn't directly open DFA and LLR files, only uses them for creation of the compiler code.
I guess this isn't necessarily worth the effort, but my point is if someone wants to pick it up I'm willing to help, and there is somewhere to start ;-D
Re: SCR decompiler
Yeah, its not easy and atm i have don't have much motivation for it.
Im busy with optimizing map compression.
Im busy with optimizing map compression.
- Vike the Hube
- Hitman
- Posts: 145
- Joined: 28 Feb 2010, 22:34
- GH nick: vike
Re: SCR decompiler
I've made some progress with this recently. It looks like Occupations (and probably a lot of other things) are compiled directly into the parameters of the function they're used in. For example, ROAD_BLOCK_TANK_MAN is 27h. Also occupations are stored as a 16-bit integer.
In addition, "in-game" functions wind up somewhere in the block starting at offset 2EE0. I bet the block at the start has initilisation data, like parked cars and stuff. And I bet there is a block for things that happen each cycle too. The block at the end has seemingly random data that changes every time you compile the .mis into the .scr as well.
If you open up miss2, a lot of the constants like ROAD_BLOCK_TANK_MAN are referenced in arrays. There are two kinds of arrays.
The first:
In this kind of array, PLAYER will be translated into 00 00, DUMMY will be 03 00, PSYCHO 0E 00...
The second kind of array:
I think it's fairly obvious what these are translated into
I'm not gonna bother listing all the integer values for the constants, but the information is definitely easily available.
In addition, "in-game" functions wind up somewhere in the block starting at offset 2EE0. I bet the block at the start has initilisation data, like parked cars and stuff. And I bet there is a block for things that happen each cycle too. The block at the end has seemingly random data that changes every time you compile the .mis into the .scr as well.
If you open up miss2, a lot of the constants like ROAD_BLOCK_TANK_MAN are referenced in arrays. There are two kinds of arrays.
The first:
Code: Select all
.data:004D55B0 dd offset aPlayer ; "PLAYER"
.data:004D55B4 dd offset aEmpty_0 ; "empty"
.data:004D55B8 dd offset aEmpty_0 ; "empty"
.data:004D55BC dd offset aDummy ; "DUMMY"
.data:004D55C0 dd offset aEmpty_0 ; "empty"
.data:004D55C4 dd offset aDriver ; "DRIVER"
.data:004D55C8 dd offset aEmpty_0 ; "empty"
.data:004D55CC dd offset aEmpty_0 ; "empty"
.data:004D55D0 dd offset aEmpty_0 ; "empty"
.data:004D55D4 dd offset aEmpty_0 ; "empty"
.data:004D55D8 dd offset aEmpty_0 ; "empty"
.data:004D55DC dd offset aEmpty_0 ; "empty"
.data:004D55E0 dd offset aEmpty_0 ; "empty"
.data:004D55E4 dd offset aEmpty_0 ; "empty"
.data:004D55E8 dd offset aPsycho ; "PSYCHO"
.data:004D55EC dd offset aMugger ; "MUGGER"
.data:004D55F0 dd offset aCarthief ; "CARTHIEF"
.data:004D55F4 dd offset aBank_robber ; "BANK_ROBBER"
The second kind of array:
Code: Select all
.data:004D5688 dd offset aNo_obj ; "NO_OBJ"
.data:004D568C dd 0
.data:004D5690 dd offset aFlee_on_foot_t ; "FLEE_ON_FOOT_TILL_SAFE"
.data:004D5694 dd 1
.data:004D5698 dd offset aFlee_char_on_f ; "FLEE_CHAR_ON_FOOT_TILL_SAFE"
.data:004D569C dd 2
.data:004D56A0 dd offset aFlee_char_on_0 ; "FLEE_CHAR_ON_FOOT_ALWAYS"
.data:004D56A4 dd 3
.data:004D56A8 dd offset aFlee_char_any_ ; "FLEE_CHAR_ANY_MEANS_TILL_SAFE"
.data:004D56AC dd 4
.data:004D56B0 dd offset aFlee_char_an_0 ; "FLEE_CHAR_ANY_MEANS_ALWAYS"
.data:004D56B4 dd 5
I'm not gonna bother listing all the integer values for the constants, but the information is definitely easily available.
- Vike the Hube
- Hitman
- Posts: 145
- Joined: 28 Feb 2010, 22:34
- GH nick: vike
Re: SCR decompiler
Also if you have a look at offset .data:004D4B70 (aka EXE offset d4b70) you find this...
(snipped as well)
If that's not a list of the interally used commands and their values when compiled into the .scr I don't know what it is
I have a little test script that Sektor wrote, key line is this:
I looked around where 27h aka RBTM was in the script, and found "4A 01" which looked very much like the command index. So I looked up 14Ah in the above array... and found "CHAR INTO CAR". So yeah. Now we just need to figure out where it stores the number and type of arguments and we'll have the whole command syntax.
Code: Select all
.data:004D4B70 dd offset unk_4C2DC4 ; DATA XREF: WinMain(x,x,x,x)+1E3Dr
.data:004D4B74 dd offset aNull ; "NULL"
.data:004D4B78 dd offset aNull ; "NULL"
.data:004D4B7C dd offset aNull ; "NULL"
.data:004D4B80 dd offset aNull ; "NULL"
.data:004D4B84 dd offset aPlayer_ped_0 ; "PLAYER_PED\t\t"
.data:004D4B88 dd offset aChar_dec ; "CHAR_DEC\t\t"
.data:004D4B8C dd offset aChar_dec_set_2 ; "CHAR_DEC_SET_2D\t"
.data:004D4B90 dd offset aChar_dec_set_3 ; "CHAR_DEC_SET_3D\t"
.data:004D4B94 dd offset aCar_dec ; "CAR_DEC\t\t\t"
.data:004D4B98 dd offset aCar_dec_set_2d ; "CAR_DEC_SET_2D\t"
.data:004D4B9C dd offset aCar_dec_set_3d ; "CAR_DEC_SET_3D\t"
.data:004D4BA0 dd offset aCar_dec_set__0 ; "CAR_DEC_SET_2DST"
.data:004D4BA4 dd offset aCar_dec_set__1 ; "CAR_DEC_SET_3DST"
.data:004D4BA8 dd offset aObj_dec ; "OBJ_DEC\t\t\t"
.data:004D4BAC dd offset aObj_dec_set_2d ; "OBJ_DEC_SET_2D\t"
.data:004D4BB0 dd offset aObj_dec_set_3d ; "OBJ_DEC_SET_3D\t"
.data:004D4BB4 dd offset aObj_dec_set__0 ; "OBJ_DEC_SET_2D_I"
.data:004D4BB8 dd offset aObj_dec_set__1 ; "OBJ_DEC_SET_3D_I"
.data:004D4BBC dd offset aObj_dec_set__2 ; "OBJ_DEC_SET_2D_S"
.data:004D4BC0 dd offset aObj_dec_set__3 ; "OBJ_DEC_SET_3D_S"
.data:004D4BC4 dd offset aCounter_0 ; "COUNTER\t\t\t"
.data:004D4BC8 dd offset aCounter_set ; "COUNTER_SET\t\t"
.data:004D4BCC dd offset aArrow_dec ; "ARROW_DEC\t\t"
.data:004D4BD0 dd offset aThread_id_0 ; "THREAD_ID\t\t"
.data:004D4BD4 dd offset aConveyorDec ; "CONVEYOR DEC\t"
.data:004D4BD8 dd offset aConveyorDecSet ; "CONVEYOR DEC SET"
.data:004D4BDC dd offset aConveyorDecSet ; "CONVEYOR DEC SET"
.data:004D4BE0 dd offset aGeneratorDec ; "GENERATOR DEC\t"
.data:004D4BE4 dd offset aGeneratorDecse ; "GENERATOR DECSET"
.data:004D4BE8 dd offset aGeneratorDecse ; "GENERATOR DECSET"
.data:004D4BEC dd offset aGeneratorDecse ; "GENERATOR DECSET"
.data:004D4BF0 dd offset aGeneratorDecse ; "GENERATOR DECSET"
.data:004D4BF4 dd offset aDestructorDec ; "DESTRUCTOR DEC\t"
.data:004D4BF8 dd offset aDestructDecSet ; "DESTRUCT DEC SET"
.data:004D4BFC dd offset aDestructDecSet ; "DESTRUCT DEC SET"
.data:004D4C00 dd offset aCraneDec ; "CRANE DEC\t\t"
.data:004D4C04 dd offset aCraneBasicDec ; "CRANE BASIC DEC\t"
.data:004D4C08 dd offset aCraneTargetDec ; "CRANE TARGET DEC"
.data:004D4C0C dd offset aCrane2targetDe ; "CRANE2TARGET DEC"
.data:004D4C10 dd offset aCrusherBasic ; "CRUSHER BASIC\t"
.data:004D4C14 dd offset aCreate_char2d ; "CREATE_CHAR2D\t"
.data:004D4C18 dd offset aCreate_char3d ; "CREATE_CHAR3D\t"
.data:004D4C1C dd offset aCreate_car2d ; "CREATE_CAR2D\t"
.data:004D4C20 dd offset aCreate_car3d ; "CREATE_CAR3D\t"
.data:004D4C24 dd offset aCreate_car2dst ; "CREATE_CAR2DSTR\t"
.data:004D4C28 dd offset aCreate_car3dst ; "CREATE_CAR3DSTR\t"
.data:004D4C2C dd offset aCreate_obj2d ; "CREATE_OBJ2D\t"
.data:004D4C30 dd offset aCreate_obj3d ; "CREATE_OBJ3D\t"
.data:004D4C34 dd offset aCreate_obj2d_i ; "CREATE_OBJ2D_I\t"
.data:004D4C38 dd offset aCreate_obj3d_i ; "CREATE_OBJ3D_I\t"
.data:004D4C3C dd offset aCreate_obj2d_s ; "CREATE_OBJ2D_S\t"
.data:004D4C40 dd offset aCreate_obj3d_s ; "CREATE_OBJ3D_S\t"
.data:004D4C44 dd offset aCreateConv2d ; "CREATE CONV 2D\t"
.data:004D4C48 dd offset aCreateConv3d ; "CREATE CONV 3D\t"
.data:004D4C4C dd offset aCreateGen2d ; "CREATE GEN 2D\t"
.data:004D4C50 dd offset aCreateGen3d ; "CREATE GEN 3D\t"
.data:004D4C54 dd offset aCreateDestroy2 ; "CREATE DESTROY2D"
.data:004D4C58 dd offset aCreateDestroy3 ; "CREATE DESTROY3D"
.data:004D4C5C dd offset aLevel_start ; "LEVEL_START\t\t"
.data:004D4C60 dd offset aLevel_end ; "LEVEL_END\t\t"
.data:004D4C64 dd offset aCreate_threa_0 ; "CREATE_THREAD\t"
.data:004D4C68 dd offset aStop_thread_0 ; "STOP_THREAD\t\t"
.data:004D4C6C dd offset aStart_exec ; "START_EXEC\t\t"
.data:004D4C70 dd offset aStop_exec ; "STOP_EXEC\t\t"
.data:004D4C74 dd offset aFor_loop ; "FOR_LOOP\t\t"
.data:004D4C78 dd offset aDo_while ; "DO_WHILE\t\t"
.data:004D4C7C dd offset aFunction ; "FUNCTION\t\t"
.data:004D4C80 dd offset aReturn_0 ; "RETURN\t\t\t"
.data:004D4C84 dd offset aWhile_0 ; "WHILE\t\t\t"
.data:004D4C88 dd offset aWhile_exec_0 ; "WHILE_EXEC\t\t"
.data:004D4C8C dd offset aNot_0 ; "NOT\t\t\t\t"
.data:004D4C90 dd offset aAnd_0 ; "AND\t\t\t\t"
.data:004D4C94 dd offset aOr_0 ; "OR\t\t\t\t"
.data:004D4C98 dd offset aIf_0 ; "IF\t\t\t\t"
.data:004D4C9C dd offset aThen_0 ; "THEN\t\t\t"
.data:004D4CA0 dd offset aElse_1 ; "ELSE\t\t\t"
.data:004D4CA4 dd offset aGoto_0 ; "GOTO\t\t\t"
.data:004D4CA8 dd offset aGosub_0 ; "GOSUB\t\t\t"
.data:004D4CAC dd offset aWordInt ; "WORD + INT\t\t"
.data:004D4CB0 dd offset aIntWord ; "INT + WORD\t\t"
.data:004D4CB4 dd offset aWordWord ; "WORD + WORD\t\t"
.data:004D4CB8 dd offset aWordInt_0 ; "WORD - INT\t\t"
.data:004D4CBC dd offset aIntWord_0 ; "INT - WORD\t\t"
.data:004D4CC0 dd offset aWordWord_0 ; "WORD - WORD\t\t"
.data:004D4CC4 dd offset aSet_0 ; "SET\t\t\t\t"
.data:004D4CC8 dd offset aWordInt_1 ; "WORD < INT\t\t"
.data:004D4CCC dd offset aWordWord_1 ; "WORD < WORD\t\t"
.data:004D4CD0 dd offset aWordInt_2 ; "WORD <=INT\t\t"
.data:004D4CD4 dd offset aWordWord_2 ; "WORD <=WORD\t\t"
.data:004D4CD8 dd offset aWordInt_3 ; "WORD > INT\t\t"
.data:004D4CDC dd offset aWordWord_3 ; "WORD > WORD\t\t"
.data:004D4CE0 dd offset aWordInt_4 ; "WORD >=INT\t\t"
.data:004D4CE4 dd offset aWordWord_4 ; "WORD >=WORD\t\t"
.data:004D4CE8 dd offset aWordInt_5 ; "WORD ==INT\t\t"
.data:004D4CEC dd offset aWordWord_5 ; "WORD ==WORD\t\t"
.data:004D4CF0 dd offset aIncrement ; "INCREMENT\t\t"
.data:004D4CF4 dd offset aDecrement ; "DECREMENT\t\t"
.data:004D4CF8 dd offset aIf_jump ; "IF_JUMP\t\t\t"
.data:004D4CFC dd offset aForwardDeclare ; "FORWARD DECLARE\t"
.data:004D4D00 dd offset aMake_car_dummy ; "MAKE_CAR_DUMMY\t"
If that's not a list of the interally used commands and their values when compiled into the .scr I don't know what it is
I have a little test script that Sektor wrote, key line is this:
Code: Select all
ben = CREATE_CHAR_INSIDE_CAR (tank01) 12 ROAD_BLOCK_TANK_MAN END
- Vike the Hube
- Hitman
- Posts: 145
- Joined: 28 Feb 2010, 22:34
- GH nick: vike
Re: SCR decompiler
If anyone wants this but doesn't have the tools, just ask me to dump all these arrays into a text file for ya
Re: SCR decompiler
Hi Vike.
Im very intersted in this stuff.
I got a new PC and i can continue my work on this stuff.
If you can, please pack all the files into ZIP or RAR and send to me.
TIA.
You have done a good job Vike.
Im very intersted in this stuff.
I got a new PC and i can continue my work on this stuff.
If you can, please pack all the files into ZIP or RAR and send to me.
TIA.
You have done a good job Vike.
Last edited by B-$hep on 16 Jan 2011, 20:15, edited 1 time in total.
- Vike the Hube
- Hitman
- Posts: 145
- Joined: 28 Feb 2010, 22:34
- GH nick: vike
Re: SCR decompiler
I actually exported all the arrays into a bunch of text files the other day but ran out of time to upload them.
So just to clarify, to use these: the numbers (where they're present) are in hex form. Where they appear in a .scr they will be in little endian format, that is least significant byte first, for example 1234FEDh would be ED4F2301 when you read it out of the .scr. Also I'm not sure how big most of the constants are but a lot seem to be 16 bit.
Quick calculations if you want to find the index of one of the arrays that doesn't include its index as part of the array:
.data:004D4C10 dd offset aCrusherBasic ; "CRUSHER BASIC\t"
So you want to look up what CRUSHER BASIC will be converted into. Start with 004D4C10 (line number of it in the array), subtract the start of the array (004D4B70), and then divide that by 4 (size of each element of the array, dd = data DWORD). Windows calculator has a hex mode, very handy. In this case it will give you 28h- so crusher basic is 28h.
Now who wants to do the rest of the legwork and write us a decompiler?
So just to clarify, to use these: the numbers (where they're present) are in hex form. Where they appear in a .scr they will be in little endian format, that is least significant byte first, for example 1234FEDh would be ED4F2301 when you read it out of the .scr. Also I'm not sure how big most of the constants are but a lot seem to be 16 bit.
Quick calculations if you want to find the index of one of the arrays that doesn't include its index as part of the array:
.data:004D4C10 dd offset aCrusherBasic ; "CRUSHER BASIC\t"
So you want to look up what CRUSHER BASIC will be converted into. Start with 004D4C10 (line number of it in the array), subtract the start of the array (004D4B70), and then divide that by 4 (size of each element of the array, dd = data DWORD). Windows calculator has a hex mode, very handy. In this case it will give you 28h- so crusher basic is 28h.
Now who wants to do the rest of the legwork and write us a decompiler?
- Attachments
-
- GTA2 compiler constants.zip
- GTA2 compiler constants- that is, what each command and item in a .mis is translated to in a .scr.
- (20.27 KiB) Downloaded 581 times
Re: SCR decompiler
Many many thanks Vike.
I will investigate the stuff you wrote here.
I will investigate the stuff you wrote here.
Re: SCR decompiler
Vike.
At 2EE0 there is some stuff before main commands begin.
Just create some very simple scr. With one PLAYER_PED and LEVELSTART, LEVELEND.
Compile, open 2EE0 and look the first bytes.
What they could be? Any ideas? They are before LEVELSTART.
Maybe START_EXEC? And the FF FF at the end are: STOP_EXEC?
Yesterday i worked almost whole day on this. I understand the calculations and most of it already.
I believe my SCR tool sourcecode will be also useful. Because i edit the coordinates, remaps, etc with it.
At 2EE0 there is some stuff before main commands begin.
Just create some very simple scr. With one PLAYER_PED and LEVELSTART, LEVELEND.
Compile, open 2EE0 and look the first bytes.
What they could be? Any ideas? They are before LEVELSTART.
Maybe START_EXEC? And the FF FF at the end are: STOP_EXEC?
Yesterday i worked almost whole day on this. I understand the calculations and most of it already.
I believe my SCR tool sourcecode will be also useful. Because i edit the coordinates, remaps, etc with it.
- Vike the Hube
- Hitman
- Posts: 145
- Joined: 28 Feb 2010, 22:34
- GH nick: vike
Re: SCR decompiler
Yeah, I've seen that data. It's weird, I don't really know what it is, but my guess is that it's data. I.e. storage variables for Peds, stuff like that. It seems to get initialised differently when you change a ped. But yeah I don't know what the stuff that's always there is...
Also really good to see you working on it
Also really good to see you working on it
Re: SCR decompiler
Yes, its a interesting challenge. I will keep you informed how it goes.
Re: SCR decompiler
One topic in GTAforums gave me some motivation to take another look on the stuff.
But atm, there is nothing to show.
But atm, there is nothing to show.
Re: SCR decompiler
Because i have nothing better to do atm and we got 4 free days from employer, i decided to work on this tool.
I started today by trying to figure out the numbers at the top of the .SCR file.
1.5 hours of work and i figured them out.
Going away from project for some time and doing other things and then coming back to it really helps.
The info i figured out today really shows even more that these scr files are not meant for decompiling. They just laid off the info in scr in such way that it makes writing decompiler pretty difficult. They don't store much info as constants, almost everything is calculated on the fly and written to SCR.
Game does the same, it calculates almost everything from info the scr header has.
So basically i should start think like GTA2 developers and this way i will dig even more info out.
What i found out today is a method how the NR_OF_COMMANDS, MAX_LINES_IN_SCR etc values are calculated and how to get them from SCR. Basically same info what compiler shows you after compiling .MIS file.
Atm im trying to make some good method to calculate them for almost any scr file.
Because my method atm just is like hardcoded for specific scr.
That's my primary job at this time.
I will let you know how it goes.
I started today by trying to figure out the numbers at the top of the .SCR file.
1.5 hours of work and i figured them out.
Going away from project for some time and doing other things and then coming back to it really helps.
The info i figured out today really shows even more that these scr files are not meant for decompiling. They just laid off the info in scr in such way that it makes writing decompiler pretty difficult. They don't store much info as constants, almost everything is calculated on the fly and written to SCR.
Game does the same, it calculates almost everything from info the scr header has.
So basically i should start think like GTA2 developers and this way i will dig even more info out.
What i found out today is a method how the NR_OF_COMMANDS, MAX_LINES_IN_SCR etc values are calculated and how to get them from SCR. Basically same info what compiler shows you after compiling .MIS file.
Atm im trying to make some good method to calculate them for almost any scr file.
Because my method atm just is like hardcoded for specific scr.
That's my primary job at this time.
I will let you know how it goes.
Re: SCR decompiler
Is this the latest version?