Tutorials

 Reply to this postStart new topic

[SA]Set Bit - Test Bit - Clear Bit

Deji
post Apr 12 2010, 12:58 AM
Post #1


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Bits


Now it's time to learn some stuff about how computers work and the whole binary system. This is actually quite an annoying thing to learn and you may skip this if you already know about it.

However, I don't recommend skipping it if you don't know how to turn a binary number into a decimal, using your head wink.gif


You may already know that computers work in 1's and 0's only. There is no such thing as "2" to a computer.

QUOTE
But then how did you just write 2 up there?


Yeah, yeah... Smartass.

Basically, the 1's and 0's follow each other in sequence and eventually tell the computer what decimal number (like 2) it wants. Well, actually.. It's still all 1's and 0's to the computer. But to us:

CODE
10


Is the same as:

CODE
2



And

CODE
100101


Is the same as:

CODE
37


QUOTE
How can 10 be 2? It's TEN!


Not ten. One and zero. This is binary, which is the core of all computer language. Closer to human understanding is hexadecimal, then decimal; which is just like the numbers we use every day.

QUOTE
How do you know what numbers these are?


I split the 1's and 0's up, from right to left... Then figure out which number each 1 is assigned to and add up those numbers...

To figure out the assigned numbers, I just have to remember it all as a table, like so:

CODE
32   16  8   4   2   1
1     0    0   1   0   1


Notice how the numbers double from right to left? 1, 2, 4, 8, 16, 32... Childs play.

So since 1/on is written under 1, we start off with the number 1.

Next, a 1/on is written under 4, so we can add 4 to our number 1. We have 5.

Now we move along even more to find 32, which has another one under it.

32 + 5 = 37.

Which is how I (or anyone else) can figure out what the heck a sequence of 1's and 0's actually means in human language.


Notice how the number sequence is written backwards (1 is at the end) - Well in San Andreas, it's written forwards. So it's the same principle, except the first number is 1, the second is 2, the third is 4, the fourth is 8 etc...

END OF BINARY COMPUTERY LECTURE


Now it's time to start the bit>byte lecture...

There are 8 bits (a bit is a binary 1 or 0) in a byte.

There are 1024 bytes in a kilobyte... And that's the start to why files take up space on a hard drive. A hard drive is filled with 1's and 0's. Well, that's the simplified, reasonable explanation that I'm going for.


But we only need to worry about bits and bytes. There are 8 bits in a byte. 16 bits in 2 bytes.

A common variable in San Andreas is 4 bytes, which is equal to 32 bits. And that's where the San Andreas "bit" opcodes come in!


But remember: Each bit is a binary 1 or 0. These, in sequence, make up a number. So since a byte is 8 bits, a byte is a number made up of bits.


In a byte, there are a maximum of 8 of those binary numbers. Anything higher and it takes up 2 bytes.

A bit confusing? Don't worry. There are also plenty of online web pages that will teach all this.

END OF BIT>BYTE LECTURE


So now we know how to make a number out of a binary number... We can do the same in San Andreas:

CODE
08BD: set 0@ bit 1


What this does is goes into the variable 0@ and sets it's binary digits. They are all 0 by default, but when we use the set opcode, we are changing one of them to 1.

The second parameter controls which bit we are setting. We are setting the second one. And if you remember how our bit table goes:

12345
124816
01000


Here we've set the second bit (2) to 1. Meaning the result of our variable is now 2. If we now set bit 4 to 1, we'd be adding 8 because that is the 4th bit. The result would now be 10.

Remember, the maximum we can add is 32 bits. Which can make a pretty large number.


Why would we want to use this method to set numbers? Well we could also use it for other things. Each one of 32 bits in a single variable can either be 1 or 0. So we could use this to store up to 32 booleans... Just like setting variables to 1 or 0 in order to make the code switch what it's doing.

To test if a bit is on, we do something like this:

SANNY
08BD: set 4@ bit 10  // The value of 4@ is now 1024.
if
    08B7:   test 4@ bit 10
then
    0485: return_true
end


This will always return true. We can also set bits to 0, by using the clear_bit opcode:

CODE
08C3: clear 4@ bit 10  // If the other bits are also 0, the value of 4@ is now 0.



There are various other opcodes for setting the bits of different kinds of variables. Make sure you use the right opcode for each one!


That's really just about it. But let me give you an example of a use where bit setting is really handy.



We have an opcode that can set any actors immunities, meaning that we can make him fireproof, bulletproof, collision proof etc.

But what if we wanted to use the memory address instead of the opcode?


The memory address is CPed+0x42. If you don't know what that means you may want to read a memory tutorial, but it's not too important at the moment.

The problem with simply writing is that this method uses an 8 bit integer... One single byte. All the immunities are in one number, instead of being separate addresses. So how do we set each one?

Well each one of 8 bits is like a boolean, that can be set to 1 and 0 to turn each immunity on and off.

Works with the same 1, 2, 4, 8, 16 etc. principal... In this instance, 4 is the bulletproof flag, 8 is the fireproof flag and 64 is the collision proof flag. There are more, but I got this information from GTAModding and, well...


What the game expects you to do is turn each individual bit on or off, then write the result. So if we set 8 to 1 and 64 to 1, the result would be 72. Write that to the memory and the player is fireproof and collision proof.

SANNY
0A96: 0@ = actor $PLAYER_ACTOR struct      // 0@ is now "CPed".
000A: 0@ += 0x42   // Get to the immunities flag.
0006: 1@ = 0   // clear all bits.
08BD: set 1@ bit 8    // 8  = fireproof.
08BD: set 1@ bit 64  // 16 = collision proof.
0A8C: write_memory 0@ size 1 value 1@ virtual_protect 0


Now the player has those immunities. Unbelievably simple!



And those are some basic uses for setting bits. You could also use the test bit opcode to check which immunities the player has, which is an opcode that doesn't exist in San Andreas wink.gif


--------------------
Go to the top of the page
 
+Quote Post
Reply to this postStart new topic

1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members: