What happened to boolean(GetAsyncKeyState(VK_NUMPAD8))? lazarus / 21-General ---------------------------------------------------------------------- TBMan · 2025-06-06 02:37 I recompiled a game I wrote after upgrading to the new Lazarus and now the GetAsynckeyState calls are not working. Is it my system or has this happened to others? Here's a code section that no longer executes: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  if boolean(GetAsyncKeyState(VK_NUMPAD4)) or boolean(GetAsyncKeyState(VK_NUMPAD1))     or  boolean(GetAsyncKeyState(VK_NUMPAD7)) or boolean(GetAsyncKeyState(VK_LEFT))     then  // rotate left    begin    degrees := -1;      rotating := true;    end;       It isn't the end of the world, I just added a readkey and a case statement for the fix, but why did this happen? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Key := '-';if keypressed then key := readkey;case Key of'4','2','7':begin               degrees := -1;                 rotating := true;           end;end; ---------------------------------------------------------------------- Fibonacci · 2025-06-06 03:12 Boolean(GetAsyncKeyState(VK_NUMPAD8)) is incorrect. It would work if you cast to WINBOOL, but thats not how GetAsyncKeyState is meant to be used. The correct way is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (GetAsyncKeyState(VK_NUMPAD8) and $8000) <> 0 This checks the high bit which indicates if the key is currently down. ---------------------------------------------------------------------- TBMan · 2025-06-06 04:07 Quote from: Fibonacci on June 06, 2025, 05:12:11 amBoolean(GetAsyncKeyState(VK_NUMPAD8)) is incorrect. It would work if you cast to WINBOOL, but thats not how GetAsyncKeyState is meant to be used. The correct way is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (GetAsyncKeyState(VK_NUMPAD8) and $8000) <> 0 This checks the high bit which indicates if the key is currently down. Thanks, I get it, but it used to work. ---------------------------------------------------------------------- Leledumbo · 2025-06-06 04:36 Quote from: TBMan on June 06, 2025, 06:07:44 amThanks, I get it, but it used to work. Yeap, the typing was loose, it is strict now. In other words, the was allowed typecast was wrong. ---------------------------------------------------------------------- jamie · 2025-06-06 10:18 Quote from: Leledumbo on June 06, 2025, 06:36:06 amQuote from: TBMan on June 06, 2025, 06:07:44 amThanks, I get it, but it used to work. Yeap, the typing was loose, it is strict now. In other words, the was allowed typecast was wrong. They call it retardation of a language campaign ---------------------------------------------------------------------- Martin_fr · 2025-06-06 10:30 Quote from: TBMan on June 06, 2025, 06:07:44 amThanks, I get it, but it used to work. No, it did not. It did just accidentally behave as if it worked. There is a difference between: - "works" which means the code is correct. - exposes the expected behaviour (in a very specific case) The 2nd looks exactly like it works. Even though the code is not correct. But by chance the generated code still deals with all value, the way its desired. Just the important difference is "by chance" => "by random accident". That should not be called "works". (if you want to describe it is correct). "By chance", is like rolling a dice, and once you got 3 times the "6 dots" that you wanted, you say "I can always at will roll a 6", it has worked. "boolean(somevalue)" has always only been guaranteed for somevalue being either exactly 0 or 1. For any other value, that behaviour has always been undefined. In your case this undefined may have just been the way you wanted it. But it was not guaranteed to stay. ---------------------------------------------------------------------- TBMan · 2025-06-06 13:02 Quote from: Martin_fr on June 06, 2025, 12:30:59 pmQuote from: TBMan on June 06, 2025, 06:07:44 amThanks, I get it, but it used to work. No, it did not. It did just accidentally behave as if it worked. There is a difference between: - "works" which means the code is correct. - exposes the expected behaviour (in a very specific case) The 2nd looks exactly like it works. Even though the code is not correct. But by chance the generated code still deals with all value, the way its desired. Just the important difference is "by chance" => "by random accident". That should not be called "works". (if you want to describe it is correct). "By chance", is like rolling a dice, and once you got 3 times the "6 dots" that you wanted, you say "I can always at will roll a 6", it has worked. "boolean(somevalue)" has always only been guaranteed for somevalue being either exactly 0 or 1. For any other value, that behaviour has always been undefined. In your case this undefined may have just been the way you wanted it. But it was not guaranteed to stay. Ah, in other words, it "worked", but it wasn't supposed to. lmao, Thanks. ---------------------------------------------------------------------- Thaddy · 2025-06-06 15:09 The cause was that a Pascal Boolean is either 0 (false) or 1 (true) The compiler previously wrongly assumed it could interpret true as any other value than 0. To mitigate that, indeed use the <> operator, which will translate to Pascal false or true. (0/1) ---------------------------------------------------------------------- TBMan · 2025-06-06 15:30 Quote from: Thaddy on June 06, 2025, 05:09:05 pmThe cause was that a Pascal Boolean is either 0 (false) or 1 (true) The compiler previously wrongly assumed it could interpret true as any other value than 0. To mitigate that, indeed use the <> operator, which will translate to Pascal false or true. (0/1) Thanks Thaddy. ---------------------------------------------------------------------- Remy Lebeau · 2025-06-06 18:03 GetAsyncKeyState() returns a 16-bit bitmask with 2 possible bits set: - the high bit if the key is currently down - the low bit if the key was pressed since the last time GetAsyncKeyState() was called. Your code assumed that any non-zero return value would evaluate as true. The correct way to do that is to use the <> inequality operator instead, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if (GetAsyncKeyState(VK_NUMPAD4) <> 0)    or (GetAsyncKeyState(VK_NUMPAD1) <> 0)    or (GetAsyncKeyState(VK_NUMPAD7) <> 0)    or (GetAsyncKeyState(VK_LEFT) <> 0) then begin    // rotate left    degrees := -1;    rotating := true; end;     If you are only interested if whether the key is currently held down, use the bitwise AND operator instead, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if ((GetAsyncKeyState(VK_NUMPAD4) and $8000) <> 0)    or ((GetAsyncKeyState(VK_NUMPAD1) and $8000) <> 0)    or ((GetAsyncKeyState(VK_NUMPAD7) and $8000) <> 0)    or ((GetAsyncKeyState(VK_LEFT) and $8000) <> 0) then begin    // rotate left    degrees := -1;    rotating := true; end;     Or, you can use the < comparison operator, since the return value is signed, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if (GetAsyncKeyState(VK_NUMPAD4) < 0)    or (GetAsyncKeyState(VK_NUMPAD1) < 0)    or (GetAsyncKeyState(VK_NUMPAD7) < 0)    or (GetAsyncKeyState(VK_LEFT) < 0) then begin    // rotate left    degrees := -1;    rotating := true; end; ---------------------------------------------------------------------- 440bx · 2025-06-06 18:40 when the test is for something being zero or not zero, in general I prefer to typecast the argument to the properly sized BOOL. In the case of GetAsyncKeyState() <> 0, I'd prefer WordBool(GetAsyncKeyState()) which should be equivalent and doesn't run the risk of messing up the equality operator in the comparison. Of course, this also applies when the argument is and-ed. ---------------------------------------------------------------------- jamie · 2025-06-06 23:39 the Boolean(whatever) will focus on the Byte size return which is ok since the first bit will be reflected. However, that function can misbehave in a threaded process whereas if another thread is also using it the bit will be cleared.  Does the now built in debugger poll keys? Jamie