GetPlayerInput() filtering

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
LilWhiteMouse
Posts: 2270
Joined: Tue Jul 15, 2003 7:00 pm
Location: Maine, US
Contact:

GetPlayerInput() filtering

Post by LilWhiteMouse »

Is there some way to determine if the player is using a certain button, even when holding others as well? The 'USE' key advances dialog in Chibi Rebellion, but if the player is in combat/moving, the extra keys are also detected and the script fails.
User avatar
Isle
Posts: 687
Joined: Fri Nov 21, 2003 1:30 am
Location: Arizona, USA

Re: GetPlayerInput() filtering

Post by Isle »

use a bitwise and operator, "&".
IE: if(GetPlayerInput(-1, INPUT_BUTTONS) & BT_FORWARD) dowhatever();
it'll mask off the other keys in getplayerinput, leaving only the button you want. theres also an example in the wiki.
User avatar
LilWhiteMouse
Posts: 2270
Joined: Tue Jul 15, 2003 7:00 pm
Location: Maine, US
Contact:

Re: GetPlayerInput() filtering

Post by LilWhiteMouse »

Thanks, I've never understood modern programming operators (I've only ever used QuickBasic).

It works, but could it be cleaned up? You have to press and release 'USE' to advance.

Code: Select all

function int UseWait(void) {
	return GetPlayerInput (-1, INPUT_BUTTONS) & BT_USE;
}
script 1 (void) {
.....
.....
int bw = 1;
while (bw == 1)
	{
	if (UseWait()){bw = 0;}
	delay (const:1);
	}

while (UseWait()){delay (const:1);}
....
....
}
User avatar
Isle
Posts: 687
Joined: Fri Nov 21, 2003 1:30 am
Location: Arizona, USA

Re: GetPlayerInput() filtering

Post by Isle »

just change script 1 to

Code: Select all

script 1 (void) {
.....
.....
while(!UseWait()) delay(1);
while(UseWait()) delay(1);
....
....
}
User avatar
Zippy
Posts: 3302
Joined: Wed Mar 23, 2005 5:31 pm
Location: New Jersey

Re: GetPlayerInput() filtering

Post by Zippy »

There are many places you could look up the details, but really quickly on the bitwise operators:

'&' and '|' are the AND and OR bitwise operators, and its their bitwise nature that makes them different from the higher level AND ('&&') and OR ('||') which deal with the overall value of their operands.

'&' and '|' will just do normal AND and OR's but compare the respective bits of the two values you give them. That means that while with '&&' and '||' you only really care about the result of true or false, with the bitwise operators you actually care about the specific number, the specific bits actually, that come out of the operation.

Here's ANDing ('&&') two integers:

Code: Select all

17 && 11
17 in binary: 10001      11 in binary: 01011
&& will compare the two entire values as a whole (17, 11) and return zero (false) if either one, or both, is zero (false).  That is, only two non-zero values (true) will return another non-zero value (true).  Since both 17 and 11 are non-zero, the answer is... anything that ISN'T zero.  This is interpreted as TRUE.  Or in whole TRUE (17) && TRUE (11) == TRUE
What's the difference with the BITWISE '&'? It will work on the individual bits (hence where the numbers in binary come into play):

Code: Select all

17 & 11
17 in binary: 10001      11 in binary: 01011
& will compare respective BITS and return a result whose BITS will be the answer the AND operation asked of them.  A 0 bit is FALSE and a 1 BIT is TRUE.  As normal for ANDing, 1 && 1 == 1 and any other combination == 0.

It's easier to illustrate if you stack them vertically
17       10001
11       01011
         -----
Answer   00001
The last digit is 1 because in the two given numbers THE LAST DIGIT WAS BOTH 1.  1 && 1 == 1.  In all the other cases (in order, from left to right, 1 && 0, 0 && 1, 0 && 0, 0 && 1) the bool result was 0, so those bits became 0 in the answer.

Bitwise | works the same way but ORs the bits; in any spot in either number where there is a 1, there will be a 1 in the answer (or inversely, only two 0's make a 0).
17       10001
11       01011
         -----
Answer   11011
The utility this has in the specific case here with the buttons is that the result from GetPlayerInput is a flag variable. Each BIT in the number you get back represents one button and only one button. That means if you were to look at the binary of one of the button constants on their own it would look something like, "00000100000000000000000000000000"; only a single, solitary 1 in there. If you want to check if that button was held down, just take the answer from GetPlayerInput and & it with the constant for the button of interest. The 0's everywhere else will knock out all the other BITS because it's an AND operation. The only bit its possible to get a 1 result is the button of interest. So the operation, as a whole, only has two possible results here: 0 (false, or button not held) or the EXACT value of BUTTON_WHATEVER (true, the button was held).
Locked

Return to “Editing (Archive)”