by Heather Harrison » Sat Jul 17, 2010 4:56 pm
As far as bits of a variable go, it works something like this. Translating a number into binary will show which bits are set. For example, A=5 is binary 00000101 (assuming A is an 8-bit variable). Making use of each bit separately is a very efficient way to use variables when you need a bunch of status flags that are set to either 0 or 1, or when you have variables that have a limited range of values.
ACK supports the logical & operator in IF statements, and this can be used to figure out whether or not a bit is set. On the example above, A&4 will register as true because the third bit from the end is set to 1, but A&2 will register as false because the second-to-last bit is set to 0.
In ACK, one easy way to set a bit is (after making certain that the bit isn't already set) is to do something like SET A=A+128. This will change the first bit to 1 if it isn't already set. (Or use A=A-128 to set that bit to 0 if it is set to 1.) I haven't fully gone through the documentation yet to see how well ACK supports logical operators. If it can do something like SET A=A | 128 or SET A=A & !(128), then it won't be necessary to know beforehand whether a bit is already set.
Since this is binary, the decimal number corresponding to each bit is 2^n. In an 8-bit variable, the highest bit corresponds to 128, and in a 16-bit variable, the highest is 32768.
An example of why this is useful is the magic system in my new version of Ultima II. It only takes two 16-bit variables (S2 and T2) for me to keep track of all of the wizard and cleric training and spells, and I even have a few bits left over in case I decide to add some spells later.
Here is an example.
If S2=29189, then the player has had novice (2^12 = 4096), intermediate (2^13 = 8192), and advanced (2^14 = 16384) wizard training and knows the first (2^0=1), third (2^2=4), and tenth (2^9=512) wizard spells. If you add up all these numbers, you will get 29189. Then, when trying to cast a spell, the game checks whether the player knows the spell. If the player tries to cast the fifth (2^4=16) wizard spell, the game checks S2 & 16. In the example above, this comes out false and the spell cast macro displays a failure message. If the player tries to cast the first wizard spell (2^0=1), the game checks S2 & 1, and this comes out true so the spell casting macro can move to its next step.
Hopefully my explanation hasn't been too long-winded, but since the question was asked I thought I should put in a detailed explanation in case beginners to this way of thinking stumble upon this thread.
I've been doing this for years. Back in my days of programming on a limited 8-bit computer (an Atari 800, which is still in good working order, by the way) I used this method extensively to conserve memory.
I still need to go through the documentation to figure just how well ACK supports the logical operators so that I can possibly avoid doing some things the hard way.
My Ultima II remake is so big that I have to do this where possible in order to get the most out of the available variables. It may seem like ACK has a lot of general-purpose variables available, but it is easy to use them up, especially when there are multiple quests and a complex magic system to keep track of.
Heather
As far as bits of a variable go, it works something like this. Translating a number into binary will show which bits are set. For example, A=5 is binary 00000101 (assuming A is an 8-bit variable). Making use of each bit separately is a very efficient way to use variables when you need a bunch of status flags that are set to either 0 or 1, or when you have variables that have a limited range of values.
ACK supports the logical & operator in IF statements, and this can be used to figure out whether or not a bit is set. On the example above, A&4 will register as true because the third bit from the end is set to 1, but A&2 will register as false because the second-to-last bit is set to 0.
In ACK, one easy way to set a bit is (after making certain that the bit isn't already set) is to do something like SET A=A+128. This will change the first bit to 1 if it isn't already set. (Or use A=A-128 to set that bit to 0 if it is set to 1.) I haven't fully gone through the documentation yet to see how well ACK supports logical operators. If it can do something like SET A=A | 128 or SET A=A & !(128), then it won't be necessary to know beforehand whether a bit is already set.
Since this is binary, the decimal number corresponding to each bit is 2^n. In an 8-bit variable, the highest bit corresponds to 128, and in a 16-bit variable, the highest is 32768.
An example of why this is useful is the magic system in my new version of Ultima II. It only takes two 16-bit variables (S2 and T2) for me to keep track of all of the wizard and cleric training and spells, and I even have a few bits left over in case I decide to add some spells later.
Here is an example.
If S2=29189, then the player has had novice (2^12 = 4096), intermediate (2^13 = 8192), and advanced (2^14 = 16384) wizard training and knows the first (2^0=1), third (2^2=4), and tenth (2^9=512) wizard spells. If you add up all these numbers, you will get 29189. Then, when trying to cast a spell, the game checks whether the player knows the spell. If the player tries to cast the fifth (2^4=16) wizard spell, the game checks S2 & 16. In the example above, this comes out false and the spell cast macro displays a failure message. If the player tries to cast the first wizard spell (2^0=1), the game checks S2 & 1, and this comes out true so the spell casting macro can move to its next step.
Hopefully my explanation hasn't been too long-winded, but since the question was asked I thought I should put in a detailed explanation in case beginners to this way of thinking stumble upon this thread.
I've been doing this for years. Back in my days of programming on a limited 8-bit computer (an Atari 800, which is still in good working order, by the way) I used this method extensively to conserve memory.
I still need to go through the documentation to figure just how well ACK supports the logical operators so that I can possibly avoid doing some things the hard way.
My Ultima II remake is so big that I have to do this where possible in order to get the most out of the available variables. It may seem like ACK has a lot of general-purpose variables available, but it is easy to use them up, especially when there are multiple quests and a complex magic system to keep track of.
Heather