dev icon indicating copy to clipboard operation
dev copied to clipboard

Add `Range(var, min, max)` to Built-in Commands

Open MatiDragon-YT opened this issue 2 years ago • 6 comments

The idea and function of this command would be to limit the value of a variable, keeping it within a specified range. Looking to reduce 6 lines of code to a single line.

Range(0@, 1, 6) // int or float
/** Parameters:
 * 1 - var or lvar
 * 2 - min value
 * 3 - max value 
*/

translate to

if 0@ < 1
then 0@ = 1
end
if 0@ > 6
then 0@ = 6
end

MatiDragon-YT avatar Nov 11 '22 19:11 MatiDragon-YT

This procedure is called Clamp.

I like the idea of adding internal functions to SB like INC or others. But this could potentially conflict or duplicate opcodes that could implement the same action.

wmysterio avatar Nov 11 '22 21:11 wmysterio

Glad to hear your opinion @wmysterio.

There is a library (.cleo) that adds these 2 opcodes for GTA SA:

0EF4: clamp_float 1@ min 2@ max 3@ store_to 4@
0EF7: clamp_int 1@ min 2@ max 3@ store_to 4@

But not for other games. And it would be nice to have this as an alternative for everyone. Plus I don't think it would be too hard to add it as a function that is translated internally, in a pre-processing before compilation (binary translation).

In most modern languages, this is quite easy to implement. In JS just using the remplace() function with a RegExp is enough. However, I don't know the world of the Rust language (the one used by SannyBulder). I don't know if that would be enough to make a "parse"..

@x87 what do you think about it? After all, you are the author of this beautiful IDE.

Pss: the name of the function does not matter. Let's talk about the feature only

MatiDragon-YT avatar Nov 13 '22 15:11 MatiDragon-YT

I like the general idea of macros defined in the code. For example:

macro Range(i,min,max)

if i < min
then i = min
end
if i > max
then i = max
end
    
end

so then you can use Range(0@, 1, 6) and the compiler unwraps the macro into the given code.

x87 avatar Nov 13 '22 15:11 x87

I like the general idea of macros defined in the code

Hmmm, is it then possible to dynamically add a macro as a class member (pseudo class member)?

macro Actor.CreateWithHeading( handle, type, model, x, y, z, heading )
    handle = Actor.Create( type, model, x, y, z )
    Actor( handle ).Angle = heading
end

// ...

Actor.CreateWithHeading( 0@, 4, #WMYDRUG, 0.0, 0.0, 0.0, 180.0 )

wmysterio avatar Nov 16 '22 10:11 wmysterio

Ohh that would be very good, it would also serve to make multiplatform mods faster. In cases where the opcode changes but the function does not.

macro Cleo.SetVar(direction, value)
    if $CompileMode == eFOR_PC
    then 0AAA: set_cleo_shared_var direction value
    else 0BBB: set_cleo_shared_var direction value
    end
end

[...]

Cleo.SetVar(GAME_SPEED, 1.0)

MatiDragon-YT avatar Nov 16 '22 15:11 MatiDragon-YT

Ohh that would be very good, it would also serve to make multiplatform mods faster. In cases where the opcode changes but the function does not.

Hmm, I think that directives would be more suitable for multi-platform code:

macro Cleo.SetVar(direction, value)
    {$if eFOR_PC } // modeSA, modeVC, modeSA_PC, cleo4.0 ...
    0AAA: set_cleo_shared_var direction value
    {$else}
    0BBB: set_cleo_shared_var direction value
    {$end}
end

The compiler needs to know that an opcode exists in order to attempt to compile it or throw an error.

wmysterio avatar Nov 21 '22 22:11 wmysterio