diff options
Diffstat (limited to 'npc/functions/bitwise.txt')
-rw-r--r-- | npc/functions/bitwise.txt | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/npc/functions/bitwise.txt b/npc/functions/bitwise.txt new file mode 100644 index 00000000..fd80024e --- /dev/null +++ b/npc/functions/bitwise.txt @@ -0,0 +1,176 @@ +// The Mana World Script +// Author: Gumi, Jesusalva +/** + * Gets a bitmasked value in from an integer. If the shift is omitted, it will + * be deduced from the mask. + * + * @arg 0 - the variable + * @arg 1 - mask + * @arg 2 - shift */ +function script bitwise_get { + .@shift = getarg(2, 0); + + if (getargcount() < 3) { + // guess the shift from the mask: + for (.@shift = 0; .@shift < 32; ++.@shift) { + if ((getarg(1) & (1 << .@shift)) != 0) { + break; + } + } + } + + return (getarg(0) & getarg(1)) >> .@shift; +} + +/** + * sets a bitmasked value in a variable + * + * @arg 0 - the target variable + * @arg 1 - mask + * @arg 2 - shift + * @arg 3 - new value + * @return a reference to the variable + */ +function script bitwise_set { + if (getargcount() < 4) { + // guess the shift from the mask: + for (.@shift = 0; .@shift < 32; ++.@shift) { + if ((getarg(1) & (1 << .@shift)) != 0) { + break; + } + } + + return set(getarg(0), (getarg(0) & ~(getarg(1))) | (getarg(2, 0) << .@shift)); + } + + return set(getarg(0), (getarg(0) & ~(getarg(1))) | (getarg(3, 0) << getarg(2, 0))); +} + +// bitmask_count(<int>) +// returns the number of bits set in <int> (up to 4096?) +function script bitmask_count { + .@n = getarg(0); // Number evaluated + .@p=0; // Bits set/unset + .@s=0; // Stack and Check + .@m=0; // Memory + + // Loop only as needed + while (.@s < .@n) { + .@s=2**.@m; + if (.@n & .@s) + .@p++; + .@m++; + } + return .@p; +} + +///////////////////////////////////////////////////////////////////////////////// +// A Nibble can go up to 15. There are 7 nibbles. +// get_nibble(VAR, NIBBLEID) +function script get_nibble { + .@v=getarg(0); + switch (getarg(1)) { + case 0: + .@s=0; .@m=0xF; break; + case 1: + .@s=4; .@m=0XF0; break; + case 2: + .@s=8; .@m=0XF00; break; + case 3: + .@s=12; .@m=0XF000; break; + case 4: + .@s=16; .@m=0XF0000; break; + case 5: + .@s=20; .@m=0XF00000; break; + case 6: + .@s=24; .@m=0XF000000; break; + default: + Exception("Invalid Nibble: "+getarg(1), RB_DEFAULT, .@v); + } + + return bitwise_get(.@v, .@m, .@s); +} + +// A Byte can go up to 255. There are 3 bytes. The forth can go up to 127. +// get_nibble(VAR, BYTEID) +function script get_byte { + .@v=getarg(0); + switch (getarg(1)) { + case 0: + .@s=0; .@m=0xFF; break; + case 1: + .@s=8; .@m=0XFF00; break; + case 2: + .@s=16; .@m=0XFF0000; break; + case 3: + .@s=24; .@m=0X7F000000; break; + default: + Exception("Invalid Byte: "+getarg(1), RB_DEFAULT, .@v); + } + + return bitwise_get(.@v, .@m, .@s); +} + +// A Bitword can go up to 65535 and is fixed in position to handle Soul EXP. +// get_bitword(VAR) +function script get_bitword { + .@v=getarg(0); + + return bitwise_get(.@v, 0xFFFF, 0); +} + +///////////////////////////////////////////////////////////////////////////////// +// A Nibble can go up to 15. There are 7 nibbles. +// set_nibble(VAR, VAL, NIBBLEID) +function script set_nibble { + .@v=getarg(0); + switch (getarg(2)) { + case 0: + .@s=0; .@m=0xF; break; + case 1: + .@s=4; .@m=0XF0; break; + case 2: + .@s=8; .@m=0XF00; break; + case 3: + .@s=12; .@m=0XF000; break; + case 4: + .@s=16; .@m=0XF0000; break; + case 5: + .@s=20; .@m=0XF00000; break; + case 6: + .@s=24; .@m=0XF000000; break; + default: + Exception("Invalid SNibble: "+getarg(2), RB_DEFAULT); + } + + return bitwise_set(.@v, .@m, .@s, getarg(1)); +} + +// A Byte can go up to 255. There are 3 bytes. The forth can go up to 127. +// set_nibble(VAR, VAL, BYTEID) +function script set_byte { + .@v=getarg(0); + switch (getarg(2)) { + case 0: + .@s=0; .@m=0xFF; break; + case 1: + .@s=8; .@m=0XFF00; break; + case 2: + .@s=16; .@m=0XFF0000; break; + case 3: + .@s=24; .@m=0X7F000000; break; + default: + Exception("Invalid SByte: "+getarg(2), RB_DEFAULT); + } + + return bitwise_set(.@v, .@m, .@s, getarg(1)); +} + +// A Bitword can go up to 65535 and is fixed in position to handle Soul EXP. +// set_bitword(VAR, VAL) +function script set_bitword { + .@v=getarg(0); + + return bitwise_set(.@v, 0xFFFF, 0, getarg(1)); +} + |