Jump to page: 1 2
Thread overview
Getch() Problem: C vs D
Jan 08, 2017
LouisHK
Jan 09, 2017
Era Scarecrow
Jan 09, 2017
LouisHK
Jan 09, 2017
Adam D. Ruppe
Jan 09, 2017
LouisHK
Jan 09, 2017
Ivan Kazmenko
Jan 09, 2017
LouisHK
Jan 09, 2017
Adam D. Ruppe
Jan 09, 2017
Era Scarecrow
Jan 10, 2017
Adam D. Ruppe
Jan 10, 2017
LouisHK
Jan 10, 2017
Adam D. Ruppe
Jan 10, 2017
LouisHK
Jan 10, 2017
Adam D. Ruppe
Jan 10, 2017
Adam D. Ruppe
Jan 10, 2017
LouisHK
Jan 10, 2017
Adam D. Ruppe
Jan 10, 2017
LouisHK
January 08, 2017
Hello, I minimize the problem to identify the problem:

Here the C version:

#include <stdio.h>
int main(){
   int c;
   while(c != 27){
       printf("%d\n", (c = getch()));
   }
   return 0;
}

And works fine, but the D version below nothing happens when I hit ESCAPE:

import std.stdio;
extern (C) int getch();
int main(){
   int c;
   while(c != 27){
       printf("%d\n", (c = getch()));
   }
   return 0;
}

Is this a bug or there is another approach?

Thanks,

L.



January 09, 2017
On Sunday, 8 January 2017 at 21:19:15 UTC, LouisHK wrote:
> And works fine, but the D version below nothing happens when I hit ESCAPE:
>
> Is this a bug or there is another approach?

Could this be because of maybe somehow it handles the console input? Kinda like how shift and different keys are toggles rather than dedicated to specific codes?

 Regardless, try ^[ ( Ctrl+[ ), which is 27 and ^] is 29.
January 09, 2017
On Monday, 9 January 2017 at 04:31:04 UTC, Era Scarecrow wrote:
> On Sunday, 8 January 2017 at 21:19:15 UTC, LouisHK wrote:
> ...
>  Regardless, try ^[ ( Ctrl+[ ), which is 27 and ^] is 29.

Interesting, I'll try that at home. And maybe it will work.

One more thing: I had tried the C version with gcc compiler, and it worked ok. But with DMC (Digital Mars Compiler) like DMD it does nothing when I hit (ESCAPE, INSERT, DELETE...).

So I think this is a behaviour from Digital Mars compilers.

L.
January 09, 2017
On Sunday, 8 January 2017 at 21:19:15 UTC, LouisHK wrote:
> And works fine, but the D version below nothing happens when I hit ESCAPE:

Different runtimes are free to line buffer data, meaning getch won't actually see anything until you hit enter.

(Actually, the operating system does the buffering unless the runtime specifically asks it not to.)

Looks like your C library (gcc? asks the OS not to buffer, and the D (digital mars or Microsoft, DM on 32 bit, MS on 64 bit) turn it off.

Best solution is to skip those C library functions and do it yourself with the OS-level calls. Then you can turn it off and actually control the buffering behavior.
January 09, 2017
On Monday, 9 January 2017 at 13:10:30 UTC, Adam D. Ruppe wrote:
> ...
> Best solution is to skip those C library functions and do it yourself with the OS-level calls. Then you can turn it off and actually control the buffering behavior.

That's what I was afraid of. I even tried your terminal.d, and it worked for those keys above, but unfortunately it's duplicating the values, one little example (From your source):

if(input.kbhit()){
    auto c = input.getch();
    write(c);
}

As I could see with WinDBG, the condition "input.kbhit()" is true for the first 2 times after I hit a key.

L.


January 09, 2017
On Monday, 9 January 2017 at 17:22:41 UTC, LouisHK wrote:
> On Monday, 9 January 2017 at 13:10:30 UTC, Adam D. Ruppe wrote:
>> ...
>> Best solution is to skip those C library functions and do it yourself with the OS-level calls. Then you can turn it off and actually control the buffering behavior.
>
> That's what I was afraid of. I even tried your terminal.d, and it worked for those keys above, but unfortunately it's duplicating the values, one little example (From your source):
>
> if(input.kbhit()){
>     auto c = input.getch();
>     write(c);
> }
>
> As I could see with WinDBG, the condition "input.kbhit()" is true for the first 2 times after I hit a key.

That's because special keys actually put two characters in the buffer, right?  Otherwise, using that buffer alone, you won't be able to distinguish, for example, arrow keys from capital Latin letters with the same codes.

January 09, 2017
On Monday, 9 January 2017 at 18:09:21 UTC, Ivan Kazmenko wrote:
> That's because special keys actually put two characters in the buffer, right?  Otherwise, using that buffer alone, you won't be able to distinguish, for example, arrow keys from capital Latin letters with the same codes.

No, that duplicate problem occurs even on normal keys, if I press "a" it shows "aa", and through the WinDBG, I saw the kbhit() was always true 2x after a key is pressed.

And I think the kbhit() (Like in many other libraries) would only return true, when a key is pressed.

I even tried to delay using sleep() after a keystroke, but it still duplicates after I press any key.

L.
January 09, 2017
On Monday, 9 January 2017 at 19:11:48 UTC, LouisHK wrote:
> No, that duplicate problem occurs even on normal keys, if I press "a" it shows "aa", and through the WinDBG, I saw the kbhit() was always true 2x after a key is pressed.

I think my lib returns on key *release* as well, since it registers that on Windows.

Probably a bug, though I don't like using the getch function, I usually use the full input stream.
January 09, 2017
On Monday, 9 January 2017 at 20:12:38 UTC, Adam D. Ruppe wrote:
> Probably a bug, though I don't like using the getch function, I usually use the full input stream.

 For direct interactions (a game menu or similar) getting individual characters makes sense; I can't help but think Rogue-likes. However for data input (per line basis) or doing bulk data/processing, it doesn't work well.

 Something to comment on, a while back when I was first getting into C and MS-DOS assembly programming, I did a direct file-copy using only one character input/write at a time. A meg sized file probably took a minute or so while if I did something as small as a 4k buffer it took moments (approx 8000x faster). This was back in 1996 or so, still it's obvious the advantages of working in bulk.
January 10, 2017
On Monday, 9 January 2017 at 20:12:38 UTC, Adam D. Ruppe wrote:
> Probably a bug, though I don't like using the getch function, I usually use the full input stream.

So, I thought a little bit and I changed the terminal.d to check on the KeyEvent if the KeyEvent.bKeyDown is true, otherwise assigns a null event, and it's working fine and now I can get the ESCAPE key. :)

terminal.d is truly amazing, I'm doing a lot of things with it.

Thanks,

L.
« First   ‹ Prev
1 2