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

    1. Red Dead Redemption 2

      1. Gameplay
      2. Missions
      3. Help & Support
    2. Red Dead Online

      1. Gameplay
      2. Find Lobbies & Outlaws
      3. Help & Support
    1. Crews & Posses

      1. Recruitment
    2. Events

    1. GTA Online

      1. Arena War
      2. After Hours
      3. Find Lobbies & Players
      4. Guides & Strategies
      5. Vehicles
      6. Content Creator
      7. Help & Support
    2. Grand Theft Auto Series

    3. GTA Next

    4. GTA V

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

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

    7. GTA Vice City Stories

    8. GTA Liberty City Stories

    9. GTA San Andreas

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

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

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

      1. GTA Advance
      2. GTA 2
      3. GTA
    13. 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. News

    2. Forum Support

    3. Site Suggestions

Opius

Generic SA SCM Documentation

Recommended Posts

Seemann

We could implement a system similar to the objects segment in the scm format. The compiler builds a lookup table for each script command used and compiles a script with relative indices in that table rather than actual opcodes. Consider this example:

 

We have a simple code

 

WAIT 500ADD_SCORE player 100WAIT 250END_CUSTOM_SCRIPT
it would compile to

 

1: 5002: 0 1001: 2503:
with the following lookup table (pseudo code):

 

1=wait2=add_score3=end_custom_script
CLEO when initialised knows all the original opcodes under their names+numbers (wait is 0001, jump is 0002, etc) and all the custom handlers (.cleo plugins). It reads the lookup table and replaces string names with actual opcodes

 

1=00012=01093=0A93
We hook the CRunningScript::Process() and replace an index read from the script with the opcode from the lookup table, so everything works as usual.

So, CLEO plugins must expose custom opcodes with string names instead of indices. And the compiler should be able to read the plugins export before compiling to collect custom opcodes names and number of parameters (if we don't want to manually update the INI).

Share this post


Link to post
Share on other sites
Wesser

Yeah, it's more or less what I was trying to explain but I honestly didn't think about used objects (as of R*' denomination).

 

Modifying the script buffer by overwriting the referenced command numbers would require accessing the lookup table only every time a user-defined command is being used and not when any command is being read by the scripting engine, which can occur multiple times if inside a loop. Nonetheless, even though the way you exposed is slight inefficient it is actually hook-friendly and so recommended: injecting SCM codes into a script featuring new commands would be far less problematic because knowing the table indices would be enough for the hooker, who won't be forced to organize the script such that command numbers get updated manually at runtime.

 

GTA3script compilers will have no issue to handle the script compilation at each command addition since their definition is what matters. Instead, SB compilers and similar should provide support for script dependent lists (enumerating only the new commands) without the need to touch the standard configuration.

 

It's too late here, I apologize for my potential superficiality.

 

 


EDIT: In summary, assuming we would like to take advantage of additional commands, we would have to build a script.lst file holding the new commands list beginning from the last free index, in this human-readable format:

 

[COMMAND]0A51=0,command
Consequently, a compiler's directive should include the aforesaid list by replicating $OPCODE behaviour in this manner:

 

{$NEWOPCODE script.lst}
Its variant can also be enhanced to accomodate the new syntax used for individual command definitions by establishing another directive:

 

{$NEWOPCODE COMMAND 0A51=0,command}
At compilation stage, the compiler will generate a hypotetical script.no (New Opcodes) file containing only the command string names sorted by the command index which must be progressive before compiling. At startup, CLEO will collect the POC (ProcessOneCommand) of each new command in the order they are registered by means of loaded plugins. At script launch, if the associated .no file is present, CLEO will generate a context dependent lookup table by swapping string names with indices and give the task to select the belonging list of the processed command to CRunningScript::ProcessOneCommand, as the following pseudocode demonstrates:

 

class CRunningScript{    struct CommandID    {        short m_sIndex : 7;        short m_bNotFlag : 1;    };    ...    short *m_pNewCommandsAssoc;    ...    void ProcessOneCommand(void);};...void CRunningScript::ProcessOneCommand(void){    ...    CommandID commandID;    short sCommandIndex;    ...    do    {        ...        sCommandIndex = commandID.m_sIndex;    }    while((m_pNewCommandsAssoc && sCommandIndex > 2640         ? g_aNewCommandsArray[m_pNewCommandsAssoc[sCommandIndex - 2641]]         : g_aCommandsPOCArray[sCommandIndex / 100])(sCommandIndex));    ...}
The neat thing is the compatibility of the scripts which won't avail of the questioned feature will never get lost. Edited by Wesser

Share this post


Link to post
Share on other sites
LINK/2012

So, I've been working on a GTA3script compiler for a few months now and would certainly like to implement something along the lines of what has been discussed here.

In fact, I've formalized things a bit up, and would like to listen to divergences, alternatives and suggestions.

So far I have collected lots of insights from Wesser, NTAuthority and Silent. So, the work in those drafts aren't mine by any means, instead they're supposed to be a collection of whatever the community ends up agreeing upon.

Although the features above are the most important ones, there are a few other extensions to the language which I would like to see discussed as well:

  • REQUIRE
  • DEFINE
  • The addition of hexadecimal integer literals.
  • The additional of a semantic (perhaps a command) for a similar purposes as the Sanny Builder's HEX...END blocks.
  • Relaxing REPEAT to allow variables in the times argument.
  • The addition of ELSEIF to complement IF.

And to conclude, a little script to sum things up a bit :)

Edited by LINK/2012

Share this post


Link to post
Share on other sites
fastman92

Contact me and I can tell you something about the GTA LCS and VCS SCM. For which I have made a simple compiler.

Edited by fastman92

Share this post


Link to post
Share on other sites
goodidea82

"Adding custom commands is always carefully considered as it costs a 15-bit command id. And, since command ids are essentially progressive numbers, the risk of collisions is quite high, if not unavoidable."

Do I understand correctly, if I implement a custom opcode with a new unused ID using the cleo library (in a so-called cleo plugin with .cleo extension), then eventually there will be a hash collision and a different opcode will be called instead?

(Background: I have code that generates opcode implementations for new opcodes in the ID range 1000-1FFF and negated versions in the range 9000-9FFF)

 

Suggestion about the code example. Using upper case letters will get very tedious. It would be better to use lower case letter for keywords and known names and let a syntax-aware editor do the visual appealing.

Edited by goodidea82

Share this post


Link to post
Share on other sites
LINK/2012

"Adding custom commands is always carefully considered as it costs a 15-bit command id. And, since command ids are essentially progressive numbers, the risk of collisions is quite high, if not unavoidable."

Do I understand correctly, if I implement a custom opcode with a new unused ID using the cleo library (in a so-called cleo plugin with .cleo extension), then eventually there will be a hash collision and a different opcode will be called instead?

(Background: I have code that generates opcode implementations for new opcodes in the ID range 1000-1FFF and negated versions in the range 9000-9FFF)

You misunderstood it, yes. Command ids are what we currently call opcodes. What I meant is the opcode range 0000-7FFF is too small. Not only that, the way we register opcodes at the moment can very easily make two people to pick the same opcode ids as humans are not good at randomness.

 

Suggestion about the code example. Using upper case letters will get very tedious. It would be better to use lower case letter for keywords and known names and let a syntax-aware editor do the visual appealing.

That's Rockstar Vision :p. Everything is case-insensitive, but a conventional coding style can be observed from R* sources: commands and constants in uppercase and variables in lowercase. See here if you wanna learn further.

Edited by LINK/2012

Share this post


Link to post
Share on other sites
goodidea82

I guess there is still some confusion what we're talking about. "Do I understand correctly" - "You misunderstood it, yes" ?

You mean "...the risk of collisions---with IDs defined by different people---is quite high,.."? Here two people have used the same command ID for defining their custom opcode.

 

Or, you mean that if I define opcode 1ABC, then a hash is created in the SCM engine (let say 123456) and it has a collision with another opcode, e.g., 2ABC (same hash: 123456). When I call 1ABC, then actually 2ABC will be called because the hashes collide?

Edited by goodidea82

Share this post


Link to post
Share on other sites
LINK/2012

No hashes are involved in the current script engine, just command ids (0000 for NOP, 0001 for WAIT, 0002 for SHAKE_CAM...). Indeed, I'm not talking about hash collisions there, perhaps a better term could be used to avoid confusion.

 

The collision I meant is with the opcode number itself, like you register 2ABC and another plugin also registers 2ABC.

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

  • 1 User Currently Viewing
    0 Members, 0 Anonymous, 1 Guest

×

Important Information

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