Quantcast
Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
    1. Welcome to GTAForums!

    2. News

    1. Red Dead Redemption 2

      1. News
      2. Red Dead Online
    1. GTA Online

      1. After Hours
      2. Find Lobbies & Players
      3. Guides & Strategies
      4. Vehicles
      5. Content Creator
      6. Help & Support
    2. Crews

      1. Events
      2. Recruitment
    1. Grand Theft Auto Series

    2. GTA Next

    3. GTA V

      1. PC
      2. Guides & Strategies
      3. Help & Support
    4. GTA IV

      1. Episodes from Liberty City
      2. Multiplayer
      3. Guides & Strategies
      4. Help & Support
      5. GTA Mods
    5. GTA Chinatown Wars

    6. GTA Vice City Stories

    7. GTA Liberty City Stories

    8. GTA San Andreas

      1. Guides & Strategies
      2. Help & Support
      3. GTA Mods
    9. GTA Vice City

      1. Guides & Strategies
      2. Help & Support
      3. GTA Mods
    10. GTA III

      1. Guides & Strategies
      2. Help & Support
      3. GTA Mods
    11. Top Down Games

      1. GTA Advance
      2. GTA 2
      3. GTA
    12. Wiki

      1. Merchandising
    1. GTA Modding

      1. GTA V
      2. GTA IV
      3. GTA III, VC & SA
      4. Tutorials
    2. Mod Showroom

      1. Scripts & Plugins
      2. Maps
      3. Total Conversions
      4. Vehicles
      5. Textures
      6. Characters
      7. Tools
      8. Other
      9. Workshop
    3. Featured Mods

      1. DYOM
      2. OpenIV
      3. GTA: Underground
      4. GTA: Liberty City
      5. GTA: State of Liberty
    1. Red Dead Redemption

    2. Rockstar Games

    1. Off-Topic

      1. General Chat
      2. Gaming
      3. Technology
      4. Programming
      5. Movies & TV
      6. Music
      7. Sports
      8. Vehicles
    2. Expression

      1. Graphics / Visual Arts
      2. GFX Requests & Tutorials
      3. Writers' Discussion
      4. Debates & Discussion
    1. Forum Support

    2. Site Suggestions

Seemann

[REL] Sanny Builder

Recommended Posts

Seemann

I've solved the second problem (with local's out of range in mission). Thank you for finding this bug.

I am not sure about optional check. Anyway its ranges should be checked. I see in your All in One Mod (v.1.01) in threads 'INTROSL' and 'INTROSH' local variables with names above 900 are used. tounge.gif Do you want optional check because of them?

Edited by Seemann

Share this post


Link to post
Share on other sites
Y_Less
What language is this written in? And will it be opensource, like Bartons wasn't?

Share this post


Link to post
Share on other sites
Mike

 

@superglitch

I have no free time to make the multibrowsing site, that would be the same under all browsers. Maybe later...

The only problem I can see is some strange characters before the <html> tag. It makes it only show the source :\

 

яю

Share this post


Link to post
Share on other sites
Seemann

@Y_Less

SB is written in Delphi 7.0. I'm not sure about opensource now.

 

@mikechml

I have understood. I'll try to fix it.

Edited by Seemann

Share this post


Link to post
Share on other sites
Demarest
I've solved the second problem (with local's out of range in mission). Thank you for finding this bug.

I am not sure about optional check. Anyway its ranges should be checked. I see in your All in One Mod (v.1.01) in threads 'INTROSL' and 'INTROSH' local variables with names above 900 are used. tounge.gif Do you want optional check because of them?

To me, it doesn't matter WHY. I myself am finding more limitations in Barton's work every day. The average user won't notice and won't know it, but for those trying to do less common acts, some things get in the way. If you kept the checking on by default, but allowed users to turn it off, everybody wins regardless of "why?".

Share this post


Link to post
Share on other sites
spaceeinstein

 

I see in your All in One Mod (v.1.01) in threads 'INTROSL' and 'INTROSH' local variables with names above 900 are used. tounge.gif Do you want optional check because of them?

Yes, but I can change it. That was the Driver Mod Pavel made. He made the locals extremely high. I didn't bother to edit it because it works fine with everyone.

 

EDIT: The builder decompiles some coordinates wrong. It makes some -2.5 to -2.49. It makes almost all -100.0 into -99.99.

Edited by spaceeinstein

Share this post


Link to post
Share on other sites
Y_Less

Seeman: a few things we (Demarest and I) discovered the other day you may like (we may like you to smile.gif) include:

 

1) jumps accept any form of integer for their parameter (BWME can compile jumps using 1 byte integers (data type 04), but crashes on decompile.

 

2) variables in jumps, another thing BWME can compile but not decompile - although the way it doesn't decompile is very odd and I don't see how it can be a by-product, but meh, I'm speculating.

 

3) [email protected] (local variable -1, exists but is unaccessible).

Share this post


Link to post
Share on other sites
Demarest
3) [email protected] (local variable -1, exists but is unaccessible).

Inaccessible for reasons that I believe are beyond the reach of anything short of hacking the EXE.

Share this post


Link to post
Share on other sites
Seemann

 

Seeman: a few things we (Demarest and I) discovered the other day you may like (we may like you to smile.gif) include:

 

1) jumps accept any form of integer for their parameter (BWME can compile jumps using 1 byte integers (data type 04), but crashes on decompile.

 

2) variables in jumps, another thing BWME can compile but not decompile - although the way it doesn't decompile is very odd and I don't see how it can be a by-product, but meh, I'm speculating.

 

3) [email protected] (local variable -1, exists but is unaccessible).

Please, write some code samples for these things that I could see them visually.

 

@spaceeinstein

 

The builder decompiles some coordinates wrong
Thanks, I've corrected it.

 

About locals. I will make the check optionally.

 

Share this post


Link to post
Share on other sites
Demarest

Well, the code we were working with was the code trap at the end off a stripped scm

:MAIN30001: wait  250& ms0002: jump 12?

 

 

That did not work because jumps in MAIN are absolute. However, in missions, jumps are negatively relative. So if you place that loop in a mission, it will jump 12 bytes backwards (Y_Less said 1 byte, but in this case, the integer 250 is 2 bytes and can be 4). Barton's Builder compiles the 12? above as a single byte, but the game will look for a 4 byte label. The game crashes. Y_Less used a hex editor to make the 12? take up 4 bytes and the code ran without issue. It would also be nice to be able to jump with a variable that would contain the bytes.

 

As far as decompiling, for whatever reason, Barton's Builder disregards the datatype and assumes it's a label. So the above code would decompile with jump X where X is the hex address it would assign to the label MAIN3. It would still work as intended, but would actually CHANGE code that was compiled and subsequently decompiled. Still, you can see that this would be unsatisfactory for variables. In fact, the variable being undefined left Mission Builder (still disregarding datatype) unsure of what to put there and just crashed.

 

I hope that answers your question and since Y_Less was the one doing the hexing, he will have to correct me if I've misrepresented anything we worked on. He knows more about this than I do wink.gif

Share this post


Link to post
Share on other sites
Y_Less

Just one thing, I did actually get the integer jump to work (that was what that final dems2.scm that I said would be interesting if it worked was). The trouble with it was that when you compiled the code, the builder just converted your 12 into a 12, instead of a -12, so it didnt work as a mission jump and jumped to the 12th byte in the code (most probably a nop or variable data as it would be in the 1st segment.

 

We also discovered (if you remember) that mission jumps are relative to the start of the mission, not the jump, so to jump to the first byte of the mission, you would need:

 

0002: jump (-1?)

 

(which should, come to think of it, work in a normal builder to compile - and we proved ran ingame)

 

So the final code compiled would be:

 

02 00 04 FF

 

But Bartons builder will crash on decompiling this.

 

Point 2 - variable jumps are done:

 

:randomlabel

0004: $myjump = ££offsetlabel

$myjump += 8 ;; Increase the bytes by 7

0002: jump $myjump ;; Will jump to 7 bytes after the label :offsetlabel

 

:offsetlabel

0002: jump ££randomlabel

;; The first jump will jump to here (a jump is 7 bytes)

 

Hope you can see whats going on there, I don't actually understand why he cant decompile that, but apparently it cant.

 

Point 3 - ignore that, I mis-understood.

Share this post


Link to post
Share on other sites
Seemann

hmm, I think that jump -1 should be compiled as

 

0200 01 FF FF FF FF

 

then it will be the real 'jump -1' wink.gif All jump's offsets have 4 bytes of length (and type 01 consequently)

 

So, I've done that if you write any integer value instead of @label the builder will compile it as 4-bytes-length value with data type 01.

eg

;-------------Mission 0---------------:Mission_Start0001: wait 0 ms0001: wait 2500 ms0109: player $PLAYER_CHAR money += 1 0002: jump -4;0002: jump 410

 

It works well in missions 'Jump -4' lead to the opcode 'wait 2500' because in missions all offsets are local and negative, you know. To go at start point of mission it is necessary to use global offset from the beginning of the file (410 in my case). Jump 0 lead to game's crashing.

 

To me, I think about this feature. I wanted to make ability to jump through the lines without labels, like

 

 

:MyLoop...0001: wait 2500 ms0109: player $PLAYER_CHAR money += 1 0002: jump -2; two lines backwards...0002: jump +20001: wait 0; this line will be ignored0109: player $PLAYER_CHAR money += 1 ...

Sanny Builder takes the last label's offset (MyLoop), calculates length of the code between :MyLoop and

 

'wait 2500' and inserts this value instead of 'jump -2'. Same for 'jump +2' It would be like as

 

 

:MyLoop....:MyLoop_10001: wait 2500 ms0109: player $PLAYER_CHAR money += 1 0002: jump @MyLoop_1...0002: jump @MyLoop_20001: wait 0:MyLoop_20109: player $PLAYER_CHAR money += 1 ...

 

 

So, what about the variables?

 

 

0001: wait 0 ms0004: $var = @VarLabel; integer values000C: $var -= 7; cause it is a mission:VarLabel0109: player $PLAYER_CHAR money += 10001: wait 2500 ms018C: play_sound 1052 at 0.0 0.0 0.00002: jump $var 

Seems to be allright in game. SB compiled and decompiled it without any issues.

 

And the last. [email protected] exists or does not?

Edited by Seemann

Share this post


Link to post
Share on other sites
Demarest
Exists but is inaccessible. GTA3 has -1 through -5, VC -1 through -7, and SA -1 through -9. But your tool will not be able to access them. Furthermore, I think jumping lines is inappropriate. For starters, the average user would NOT have a need for it. Secondly, those who might be getting into tricky coding would prefer the power of specifying bytes instead of limited to lines.

Share this post


Link to post
Share on other sites
Y_Less

Also, jump +2 wouldn't skip a wait as a wait is 4 bytes.

 

And I know label offsets are 4 bytes normally, but you can use other data types (eg 04) for them and they will work (e.g. 02 00 04 56 (56 being a one byte label) will jump to address 56 (hex)).

 

Edit: btw, jump 0 doesnt (at least in III) crash the game, and shouldnt, its just a jump to the first byte (which wil be a jump instruction) - when dem tested it, he said it just ran all the initiallisation again, which it would.

Edited by Y_Less

Share this post


Link to post
Share on other sites
jonc

Point automatically reduces labels to the smallest int type that can contain them, so I know that works fine in game. It also saves over 100k in the compiled script files.

 

Decompiling jumps-to-variables would be incredibly dangerous since the smallest change in the SCM would change those initial byte offsets. To handle those cases, you would need a full type system and even then it wouldn't be perfect. Point's type system could probably handle it, but because it changes the code so much due to optimizations it makes, it is probable that any "pointer arithmetic" after the initial assignment you did would break anyway. So in summary, don't bother trying to decompile such a script meaningfully.

 

Jumping lines doesn't really make sense, since the jump-to-variable is only valuable if you can calcuate the address at runtime (and you can't know every line's byte offset at runtime). If you are jumping a static number of lines, the user might as well have used a label.

Share this post


Link to post
Share on other sites
Demarest

Also, jump +2 wouldn't skip a wait as a wait is 4 bytes.
He was saying jump +2 as in lines. Which I presume his tool would calculate on compile.

 

 

Edit: btw, jump 0 doesnt (at least in III) crash the game, and shouldnt, its just a jump to the first byte (which wil be a jump instruction) - when dem tested it, he said it just ran all the initiallisation again, which it would.
Actually, the first byte would be the first byte of 0??. It's a miracle the game somehow repeatedly ran past all that. Presumably because the code we were working with had no globals.

 

 

Point automatically reduces labels to the smallest int type that can contain them, so I know that works fine in game. It also saves over 100k in the compiled script files.
While making the SCM proprietary. If a SCM cannot be decompiled by any tool made to do so, your audience shrivels.

 

 

Jumping lines doesn't really make sense, since the jump-to-variable is only valuable if you can calcuate the address at runtime (and you can't know every line's byte offset at runtime).
You only need to know it at compile. It would calculate the weight of that line and the (in this case) 2 lines before it (16) and compile it to jump there. But again, any such compiling would make the decompile untrue to source and its usefulness plummets.

 

I should probably explain WHY this was started in the first place. When writing Lunarbond, I wanted to keep the code compact. Didn't need to, just saw an opportunity to do something I've never done before. I was using this loop (shorthand)

[email protected] = [email protected] +=  1if NOT [email protected] > 16jf label2if garage $PIEG contains needed car [email protected] label3jump label

I was going to use the identity of [email protected] (guaranteed to be from 1 to 16) to set [email protected] (the ID of the car I was going to spawn). Rather than writing out 16 ifs to get a fix on [email protected]'s ID, I wanted to be able to say something like

[email protected] = [email protected]@ *= whateverjump [email protected]

I realize that some car IDs involved were 1 byte while others were 2 and planned on addressing that. Just wanted to display for those that might wonder why jumping bytes would be useful. Obviously at the time, I wasn't aware that jump address were absolute. Pity. Or that the engine can't handle dynamic jumping.

Share this post


Link to post
Share on other sites
jonc

 

Actually, the first byte would be the first byte of 0??. It's a miracle the game somehow repeatedly ran past all that. Presumably because the code we were working with had no globals.

 

As far as I know globals 0 and 4 are never used in the original script so that jump should never be modified.

 

 

You only need to know it at compile. It would calculate the weight of that line and the (in this case) 2 lines before it (16) and compile it to jump there. But again, any such compiling would make the decompile untrue to source and its usefulness plummets.

 

On the contrary, using jump-to-lines, if I say (borrowing some Point syntax to make it shorter):

 

string output;label x = LBL123 + RandomInt(0,10);goto x;LBL123: output = "a";// 8 bytesoutput = "aa";// 9 bytesoutput = "aaa";// 10 bytes// ...

 

 

The compiler would have to know that RandomInt was operating on lines, and then do a switch to convert the random line selection to a byte offset and then add it. No tools have the necessary information to do so right now. And absolutely none could do it efficiently.

 

On the other hand, using byte offsets like your second example wants would work fine the first time, but it makes the code very vulnerable to structural changes (such as if I changed the line to LBL123: output = "aaa";, it would change all future offsets and the calculation wouldn't know that).

 

In my opinion, a better solution to what you were trying would probably be a switch statement.

Share this post


Link to post
Share on other sites
Demarest

Actually, the first byte would be the first byte of 0??. It's a miracle the game somehow repeatedly ran past all that. Presumably because the code we were working with had no globals.
As far as I know globals 0 and 4 are never used in the original script so that jump should never be modified.Oh I wasn't saying it was a good idea. He was just saying that byte 0 is a jump which isn't the case as far as I know it.

 

 

The compiler would have to know that RandomInt was operating on lines
Well I was addressing his use of -2 which is a fixed integer. I already understand that a compiler has to compile one address and that a variable is dynamic. Hence my woe that the engine doesn't support dynamic jumps. It would be cool if understood that the parameter was signified by a variable, evaluate that variable and jump from that point. Shame that it doesn't.

 

 

In my opinion, a better solution to what you were trying would probably be a switch statement.
Absolutely in terms of programming. The compiled code would essentially be the 16 ifs I was already facing, but my goal was shorter code for the sheer accomplishment of it. In SA, you could just use a jump table. Edited by Demarest

Share this post


Link to post
Share on other sites
spaceeinstein

Why does the builder crash when I use this sascm.ini?

 

The interior names file doesn't seem to be any use. It was used for one of Barton's MultiMod's feature.

Edited by spaceeinstein

Share this post


Link to post
Share on other sites
jonc

 

Oh I wasn't saying it was a good idea. He was just saying that byte 0 is a jump which isn't the case as far as I know it.

 

Byte 0 is a jump unless a global at bytes 0 or 4 has been modified, which scripts aren't supposed to do, but a mod author could do I suppose.

 

 

Well I was addressing his use of -2 which is a fixed integer.

 

Ah. The quote you used was me talking about the variable jumps so I was confused.

 

With respect to the variable jumps, I've never tried it but I see absolutely no reason the engine wouldn't support it--the byte addresses are simply int values. Have you tested it or is your statement that it doesn't work purely because MB crashes upon seeing it?

Share this post


Link to post
Share on other sites
Demarest

Byte 0 is a jump unless a global at bytes 0 or 4 has been modified, which scripts aren't supposed to do, but a mod author could do I suppose.
Didn't realize that. Thank you.

 

 

With respect to the variable jumps, I've never tried it but I see absolutely no reason the engine wouldn't support it--the byte addresses are simply int values. Have you tested it or is your statement that it doesn't work purely because MB crashes upon seeing it?
Good question. I'll let Y_Less answer that one. I had the GTA3 and he had the hex editing. So we played a plittle ping pong with the SCM. I THOUGHT he said the variable didn't work but based on his posts today, I'm lead to believe that he did get it to work.

Share this post


Link to post
Share on other sites
jacob.

You could vastly improve conditional jumps:

 

 

:CHECKif (condition) {;; do somethingelse {;; here it will auto-generate an available jump_if_false label;; false, do something else }

 

 

is a lot easier then doing:

 

 

:CHECKif 0(condition)jump_if_false AUTOGEN;; do something:AUTOGEN;; false, do something else

 

 

It doesn't sound difficul to manage, and it'd make things a ton better. How bout it? wink.gif

Share this post


Link to post
Share on other sites
Seemann

 

I should probably explain WHY this was started in the first place. When writing Lunarbond, I wanted to keep the code compact. Didn't need to, just saw an opportunity to do something I've never done before. I was using this loop (shorthand)
[email protected] = [email protected] +=  1if NOT [email protected] > 16jf label2if garage $PIEG contains needed car [email protected] label3jump label

I was going to use the identity of [email protected] (guaranteed to be from 1 to 16) to set [email protected] (the ID of the car I was going to spawn). Rather than writing out 16 ifs to get a fix on [email protected]'s ID, I wanted to be able to say something like

[email protected] = [email protected]@ *= whateverjump [email protected]

I realize that some car IDs involved were 1 byte while others were 2 and planned on addressing that. Just wanted to display for those that might wonder why jumping bytes would be useful. Obviously at the time, I wasn't aware that jump address were absolute. Pity. Or that the engine can't handle dynamic jumping.

yeah, when I made my "VC Car Shop" mod for VC I used such code:

 

0209: [email protected] = random_int 0 71...0012: [email protected] *= 15 ;; integer values (never used in VC or GTA 3)000A: [email protected] += JJCS_Cases ;; integer values0002: jump [email protected]:CS_Cases0004: $CS_CASE_RESULT = 2530 ;; integer values   0 landstalker0002: jump JJCS_Get_Random_Model0004: $CS_CASE_RESULT = 2031 ;; integer values   1 idaho0002: jump JJCS_Get_Random_Model0004: $CS_CASE_RESULT = 3532 ;; integer values   2 stinger...

 

In CS_Cases every line with $CS_CASE_RESULT had 2+1+2+1+2= 8 bytes of length. And with 2+1+4= 7 bytes of

length of line "jump JJCS_Get_Random_Model" every case had 15 bytes of length. I randomly selected one of them, multiplied on 15 and the result led me at line where car's data was stored.

 

Share this post


Link to post
Share on other sites
Seemann

 

Why does the builder crash when I use this sascm.ini?

 

Fixed. Thanks.

 

Edit: oops, double post.

Edited by Seemann

Share this post


Link to post
Share on other sites
Demarest

0209: [email protected] = random_int 0 71...0012: [email protected] *= 15;; integer values (never used in VC or GTA 3)000A: [email protected] += JJCS_Cases;; integer values0050: gosub [email protected]: jump JJCS_Get_Random_Model:CS_Cases0004: $CS_CASE_RESULT = 2530;; integer values   0 landstalker0051: return0004: $CS_CASE_RESULT = 2031;; integer values   1 idaho0051: return0004: $CS_CASE_RESULT = 3532;; integer values   2 stinger0051: return...

 

Would save 343 bytes wink.gif

Share this post


Link to post
Share on other sites
Seemann

 

0012: [email protected] *= 10;; integer values (never used in VC or GTA 3)

 

 

in this case. smile.gif

Edited by Seemann

Share this post


Link to post
Share on other sites
Y_Less

If you know your things are going to be different lengths, use something of set length:

 

 

[email protected] is the value of the car you [email protected] *= 7;; Create the offset from the [email protected] += ££cartable;; Set the labelgosub [email protected];; gosub - importantjump ££somewhere else:cartable;; point the offset is fromjump ££car1;; All standard length jumps, no playing about with 1 byte jumps herejump ££car2;; Point and other 'intelligent' compilers won't decompile theres lines - Jon, sort it out!jump ££car3;; They are jumps after a jump with no discernable label jumping to it - therefore are never executedreturn:car1;; Do whatever you want to here;; With as many bytes as you wantreturn:car2;; same againreturn:car3;; yeahreturn

 

 

I'm not sure what you're asking about variable jumps. I got jumps of different data types to work (04 - short int, 01 - jump, 05 - long int), with the addresses in the right type for them. I also got a jump to address 0 and mission address 0 to work in all types, I never used variables though.

 

Mission builder supports compiling them, but not decompiling them. And jon doing that with jumps wouldn't make the SCM a proprietry format as, as you discovered, MB does decompile jumps of different data types.

Share this post


Link to post
Share on other sites
Seemann

In fact in original SCM datatype 01 is used for LongInt (> 32767) & labels. 04 - SmallInt and 05 - ShortInt.

But seems to be for game it doesn't matter what data type is used for label. But I always compile it with 4 bytes of length. It's too hard to change it now. In future versions I will try to compile with true length and datatype consequently.

 

So, the official English homepage of a Sanny Builder here has created:

 

http://freewebs.com/sannybuilder

 

And latest version of the program (1.1):

 

http://freewebs.com/sannybuilder/sannybuilder11.rar

 

Hope, that it works without any issues. xmas.gif

Edited by Seemann

Share this post


Link to post
Share on other sites
spaceeinstein
If you don't put the FreeWebs things at the bottom of the page, Freewebs might delete your account. Look at bottom of this page. Great site by the way.

Share this post


Link to post
Share on other sites
Seemann

 

If you don't put the FreeWebs things at the bottom of the page, Freewebs might delete your account. Look at bottom of this page. Great site by the way.

Thank you for the information, page it is updated. smile.gif

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.