[C++] Inkey$ vervanger voor C++

Pagina: 1
Acties:

  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Beste tweakers,

ik ben nu echt zolang bezig met zoeken en google liet me in de steek. Mijn vraag is of er een Inkey$ (van QBasic) functie bestaat in C++. Ik heb een simpel programmatje geschreven in Borland C++ 3.1 (ja oud he, ik gebruik ook wel nieuwere versies, maar deze vind ik gewoon fijn ;) ). Het is een dos-programma, dus heb ik niets aan de windowscalls ed.

Het mooie van Inkey$ is dat je programma niet ophoudt met werken om op een toets te wachten en kan je de waarde gewoon gebruiken om verschillende toetsaanslagen te onderscheiden. Met C++ kan ik niets vinden wat op Inkey$ lijkt. Tuurlijk kennen we allemaal cin, getchar, getch en dat soort dingen, maar deze functies wachten of op de enter toets of op een toetsaanslag, maar dan stopt het programma wel omdat het op een toets wacht. En dat is nou net niet wat ik wil, ik wil graag dat het kijkt of er een toets is ingedrukt en dat hij daar op reageert. En als er op geen toets wordt gedrukt dan moet het gewoon verder gaan met uitvoeren.

Als zoiets niet bestaat, kan ik bijv. inline assembler gebruiken om de keyboard buffer te lezen?

Bij voorbaat dank :)

  • nIghtorius
  • Registratie: Juli 2002
  • Laatst online: 27-04 15:36

nIghtorius

Poef!

kbhit() word non-zero wanneer er een toets is ingedrukt. en degene die zoekt is

getchar(). geeft de waarde terug van welke toets je hebt ingedrukt.

een voorbeeld lusje

C:
1
#include <conio.h>


C:
1
2
3
4
5
char c;
do {
  c = getchar();
  cout >> c;
} while (c != 'Q');


deze blijft hangen bij getchar(). net zoals input$ bij QBasic.

deze

C:
1
2
3
4
5
6
char c;
do {
  c = 0;
  if ( kbhit() ) c = getchar;
  cout >> c;
} while (c != 'Q');


blijft de lus doorlopen.. ook word er geen toets ingedrukt. et voilá je "inkey$"

[ Voor 21% gewijzigd door nIghtorius op 09-02-2005 12:34 ]

Ryzen 9 5900X @ 5.1Ghz | MPG B550 GAMING CARBON | 96GB DDR4-3200 | RTX 4070TI | 2TB + 1TB m.2 SSD | 3x 1TB HDD | 1x 2TB SATA SSD | 32" G3223Q (4K/144Hz)


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
nIghtorius schreef...:
...veel c++ praat om me te helpen :P
[miereneukermode]het is cout << c; ;) [/mierneukermode]

Ehm je code werkt niet bij mij, want als ik je code uitvoer dan krijg ik een fourmelding van windows dat er een verkeerde opdracht is uitgevoerd oid. Maar ik het het stukje:

C:
1
if(kbhit()) c = getchar();


gebruikt, maar het werkt nog steeds niet.
Mijn code (dit stukje zit in een loop):

C:
1
2
3
4
5
6
7
char ch;
if(kbhir()) ch = getchar();
switch (ch) {
     case 'w': blablabla
     case 's': blablabla
     enz enz
}


en dan wacht hij nog steeds op user input zonder door te gaan :X
Op deze site staat dat het inderdaad zou moeten werken, maar bij mij werkt het dus niet :'(

[ Voor 14% gewijzigd door Oguz286 op 09-02-2005 12:57 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:11

Creepy

Tactical Espionage Splatterer

Wat werkt er precies niet? Wat heb je zelf al geprobeerd om het op te lossen? Wat lukte daar niet mee? Welke foutmelding krijg je precies? Op welke regel?

Zie ook P&W FAQ - Leer **** debuggen!!

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Oguz286 schreef op woensdag 09 februari 2005 @ 12:54:
[...]
C:
1
2
3
4
5
6
7
char ch;
if(kbhir()) ch = getchar();
switch (ch) {
     case 'w': blablabla
     case 's': blablabla
     enz enz
}
om te beginnen zou je de if ook om de switch heen kunnen breien, want een ongeinitialiseerde char switchen is per definitie geen goed idee

edit: en kbhit schrijf je met een t op het eind :)

[ Voor 10% gewijzigd door MLM op 09-02-2005 13:03 ]

-niks-


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Ik heb even de sourcecode hier neergezet. Let verder niet op de andere code, ben nog steeds bezig :P Het stukje waar ik het net over had zit in de mainloop.
Creepy schreef op woensdag 09 februari 2005 @ 13:00:
Wat werkt er precies niet? Wat heb je zelf al geprobeerd om het op te lossen? Wat lukte daar niet mee? Welke foutmelding krijg je precies? Op welke regel?

Zie ook P&W FAQ - Leer **** debuggen!!
Ik wil een stukje van mijn scherm vullen met sprites, deze code komt van QBasic, die ik probeer om te zetten naar C++ Het werkt allemaal wel, maar als ik de code gebruik die me werd aanbevolen, dan wacht hij nog steeds op user input voordat het programma verder gaat met uitvoeren van opdrachten.

[ Voor 4% gewijzigd door Oguz286 op 09-02-2005 13:17 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

kbhit checkt alleen maar of er een character in de buffer zit. Als dat niet zo is retourneert hij false en valt er dus ook geen karakter op te halen. Je moet die kbhit dus in een while zetten. Je kunt ook getch() gebruiken, die, als ik het me goed herinner, zelf wacht totdat er een karakter in de buffer verschijnt.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
drm schreef op woensdag 09 februari 2005 @ 13:38:
kbhit checkt alleen maar of er een character in de buffer zit. Als dat niet zo is retourneert hij false en valt er dus ook geen karakter op te halen. Je moet die kbhit dus in een while zetten. Je kunt ook getch() gebruiken, die, als ik het me goed herinner, zelf wacht totdat er een karakter in de buffer verschijnt.
Nou kijk, mijn code heeft een simpele opbouw.

Main{
Do {
rekenen
als er op een toets is gedrukt, kijk dan welke en voer een actie uit
} while (1 == ) //gewoon constant laten loopen, ik werk dat nog wel uit
}

ik verwacht toch dat het zo zou moeten werken? En Getch() heb ik ook gebruikt, maar hij wacht dus totdat er een karakter is ingetypt, en dat wil ik dus niet. Hij moet gewoon doorgaan met het laten zien van de sprites, en als er een toets in ingedrukt moeten de sprites scrollen.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

ik verwacht toch dat het zo zou moeten werken? En Getch() heb ik ook gebruikt, maar hij wacht dus totdat er een karakter is ingetypt, en dat wil ik dus niet. Hij moet gewoon doorgaan met het laten zien van de sprites, en als er een toets in ingedrukt moeten de sprites scrollen.
Ah ok, dat had ik even verkeerd begrepen.

Zoiets zou dan wel moeten werken:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int quit = 0; // die compiler snapt afaicr nog geen booleans :P
do {
   /* zooi */
   if ( kbhit () ) {
      char ch = getchar ();
      switch ( ch ) {
          case 'a': /* ieps */
             break;
          case 'b': /* knel */
             break;
          case 'q': case 'Q':
             quit = 1; 
             break;
      }       
   }
} while ( !quit );

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Dit is mijn code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
do {
    char far *V_buffer = (char far *)0xA0000000L;
    verticalval = vscroll;

    tilex = hscroll / 10;
    tiley = verticalval /10;
    mapelem = tiley * 20 + tilex;

    spritex = hscroll % 10;
    spritey = vscroll % 10;
    spriteelem = spritey * 10 + spritex;

    waitretrace();

    for (screeny = 60; screeny <= 139; screeny++) {
        long int offset = screeny * 320 + 110;
        for (screenx = 110; screenx <= 209; screenx++) {
            V_buffer[offset] = sprite[world[mapelem]][spriteelem];
            offset = offset + 1;

            spriteelem = spriteelem + 1;
            if (spriteelem % 10 == 0) {
                spriteelem = spriteelem - 10;
                mapelem = mapelem + 1;
            }
            }
        verticalval = verticalval + 1;
        tiley = verticalval / 10;
        mapelem = tiley * 20 + tilex;

        spritey = spritey + 1;
        if (spritey == 10) spritey = 0;
        spriteelem = spritey * 10 + spritex;
        char ch;
        ch = getch();
        switch (ch) {
            case '1': if (vscroll > 0) vscroll = vscroll -1;
            case '2': if (vscroll < 120) vscroll = vscroll + 1;
            case '3': if (hscroll > 0) hscroll = hscroll - 1;
            case '4': if (hscroll < 100) hscroll = hscroll + 1;
                        }
    }
} while (1 == 1);


Is dacht ik hetzelfde als jouw code, toch?

Ow wacht bij jouw code wordt eerst de keyboardbuffer gecontroleerd, en als er iets aanwezig is haalt hij het teken op. Ah, ik zal het even met mijn antieke (maar üb3rl33t3) compiler even proberen. :)

[ Voor 11% gewijzigd door Oguz286 op 09-02-2005 13:52 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Oguz286:
Dit is mijn code:

C:
1
/* sn1pzor */


Is dacht ik hetzelfde als jouw code, toch?
Nee, maar doe gerust een spelletje zoek-de-verschillen ;)
edit:
't Is overigens netter die hele conio.h meuk (kbhit() en consorten) niet te gebruiken en met getchar() te checken of 't EOF is wat je terugkrijgt :)

[ Voor 28% gewijzigd door drm op 09-02-2005 13:54 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
drm schreef op woensdag 09 februari 2005 @ 13:52:
[...]
Nee, maar doe gerust een spelletje zoek-de-verschillen ;)
Hehe, ik heb al een paar manieren gevonden om het wat beter te laten werken ;) Jouw code is wat duidelijker ;)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
showmanyc is tegenwoordig de officiele methode.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

MSalters:
showmanyc is tegenwoordig de officiele methode.
D'r is een hoop onofficieels aan Borland 3.1 / turboc compiler :D

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Ehm ik heb net mijn code herschreven:

C:
1
2
3
4
5
6
7
8
9
do {
          /*blaat*/
          if (kbhit()) {
                    char ch = getchar();
                    switch (ch) {
                              case 'a': /*random blaat*/;
                              }
          }
} while (1 == 1);


Dit zou toch moeten werken? Bij mij niet dus, en zelfs als ik de van de tekenstukken commentaar maak, gaat hij het uitvoeren :X Ik denk dat mijn compiler wat rust nodig heeft na 8 uur compilen :P

Kan iemand me uitleggen waarom dit niet werkt?

  • Gondor
  • Registratie: September 2003
  • Laatst online: 14:57
Zit je wel in de goede file te editten, is hij wel toegevoegd aan je project, ...
Doe eens clean/rebuild/... voor je het opnieuw laat compileren.

"Peace cannot be kept by force. It can only be achieved by understanding"-Albert Einstein-


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Gondor schreef op woensdag 09 februari 2005 @ 14:36:
Zit je wel in de goede file te editten, is hij wel toegevoegd aan je project, ...
Doe eens clean/rebuild/... voor je het opnieuw laat compileren.
Heb ik allemaal gedaan, maar het werkt nog steeds niet. Ik heb maar de code om de ingetoetste letter te laten zien apart geschreven, en dan loopt het programma vast en krijg ik een windows foutmelding. Ik denk dat ik het toch allemaal beter met devc++ kan gaan doen (alleen vind ik die AT&T asm syntax zo ruk, maar ja).

  • Jrz
  • Registratie: Mei 2000
  • Laatst online: 14-05 19:46

Jrz

––––––––––––

Als het voor een spelletje is kan je beter, aangezien je in dos bezig lijkt te zijn, inportb (0x60) lezen / int9h afvangen.

je code is fout:
C:
1
2
3
4
spriteelem = spritey * 10 + spritex; 
        char ch; 
        ch = getch(); 
        switch (ch) { 


je moet er een if (kbhit()) { omheen zetten


Uit de oude doos:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#define KEY_PAD4           0x4b
#define KEY_PAD2           0x50
#define KEY_PAD8           0x48
#define KEY_PAD6           0x4d
// de rest zoek je maar op ;)

byte rawkey;
byte Key[128];

void interrupt (*OldInt9h) (__CPPARGS);
void interrupt NewInt9h (__CPPARGS) {
  byte al;
  asm cli
  asm pusha

  rawkey = inportb (0x60);
  al = inportb (0x61);
  al |= 0x82;
  outportb (0x61, al);
  al &= 0x7F;
  outportb (0x61, al);

  if (rawkey > 128) {
    Key[rawkey - 128] = 0;
  } else Key[rawkey] = 1;

  outportb (0x20, 0x20);
  asm popa
  asm sti
}

void SetKb (void) {
  OldInt9h = getvect(0x9);
  setvect (0x9, NewInt9h);
}

void ResetKb (void) {
  setvect (0x9, OldInt9h);
}


en dan kan je in je loop zetten iets van: if (Key[KEY_PAD6]) { /* naar rechts */}

[ Voor 59% gewijzigd door Jrz op 09-02-2005 15:13 ]

Ennnnnnnnnn laat losssssssss.... https://github.com/jrz/container-shell (instant container met chroot op current directory)


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
En hoe doe ik dat met inportb (0x60) lezen / int9h afvangen? (ik ben echt op, sorry). Trouwens als je naar de code die ik heb gepost hebt gekeken, die is oud, ik heb nu het if(kbhit))-gedoe in de main do loop en buiten de 2 for loops gezet, als je dat bedoelde.

Ah ok, ik zal ernaar kijken, dankjewel!

[ Voor 8% gewijzigd door Oguz286 op 09-02-2005 14:58 ]


  • Jrz
  • Registratie: Mei 2000
  • Laatst online: 14-05 19:46

Jrz

––––––––––––

Oh dat stukje had ik niet gelezen, maar ik denk dat je eerst moet zorgen dat je compiler compiled ;)

Die code van hierboven moet je eerst setkb aanroepen
en als je afsluit resetkb...

Vergeten te vertellen:
De reden dat je liever dit wil gebruiken is omdat getchar() keyrepeats heeft..

[ Voor 54% gewijzigd door Jrz op 09-02-2005 15:18 ]

Ennnnnnnnnn laat losssssssss.... https://github.com/jrz/container-shell (instant container met chroot op current directory)


  • nIghtorius
  • Registratie: Juli 2002
  • Laatst online: 27-04 15:36

nIghtorius

Poef!

Jrz schreef op woensdag 09 februari 2005 @ 15:09:
Oh dat stukje had ik niet gelezen, maar ik denk dat je eerst moet zorgen dat je compiler compiled ;)

Die code van hierboven moet je eerst setkb aanroepen
en als je afsluit resetkb...

Vergeten te vertellen:
De reden dat je liever dit wil gebruiken is omdat getchar() keyrepeats heeft..
hehe.. vergeet vooral die resetkb niet.. toen ik veel in dos progde wou ik wel eens vergeten om m'n keyboard vector terug te zetten naar de BIOS default. :X (komt erop neer dat je niks meer in kon typen)

Ryzen 9 5900X @ 5.1Ghz | MPG B550 GAMING CARBON | 96GB DDR4-3200 | RTX 4070TI | 2TB + 1TB m.2 SSD | 3x 1TB HDD | 1x 2TB SATA SSD | 32" G3223Q (4K/144Hz)


  • Grumsel
  • Registratie: Februari 2004
  • Laatst online: 20:16
Je mist ook nog een aantal breaks in de code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch (ch) {
    case '1': 
        if (vscroll > 0) vscroll = vscroll -1;
        break;
    case '2': 
        if (vscroll < 120) vscroll = vscroll + 1;
        break;
    case '3':
        if (hscroll > 0) hscroll = hscroll - 1;
        break;
    case '4':
        if (hscroll < 100) hscroll = hscroll + 1;
        break;
}


Is dat misschien je probleem?

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 12-05 20:13
Trouwens, als je kbhit wilt gebruiken moet je bij een extended key ( bijv FXX key ) nog een keer getch doen. De eerste getch returned dan 0;

iets als:
code:
1
2
3
4
5
6
7
8
9
if( kbhit() )
{

    int key = getch();

    if( key == 0 )
        key = getch();

}

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Grumsel schreef op woensdag 09 februari 2005 @ 17:15:
Je mist ook nog een aantal breaks in de code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch (ch) {
    case '1': 
        if (vscroll > 0) vscroll = vscroll -1;
        break;
    case '2': 
        if (vscroll < 120) vscroll = vscroll + 1;
        break;
    case '3':
        if (hscroll > 0) hscroll = hscroll - 1;
        break;
    case '4':
        if (hscroll < 100) hscroll = hscroll + 1;
        break;
}


Is dat misschien je probleem?
Ik heb de breaks niet geprobeerd om eerlijk te zijn, maar het lijkt me niet dat dat het probleem is, maar jah proberen kan geen kwaad :P

Hoe doen de proggers die een gameloop maken dit eigenlijk? (als ze geen winapi gebruiken dan)

  • nIghtorius
  • Registratie: Juli 2002
  • Laatst online: 27-04 15:36

nIghtorius

Poef!

Oguz286 schreef op woensdag 09 februari 2005 @ 18:55:
[...]


Ik heb de breaks niet geprobeerd om eerlijk te zijn, maar het lijkt me niet dat dat het probleem is, maar jah proberen kan geen kwaad :P

Hoe doen de proggers die een gameloop maken dit eigenlijk? (als ze geen winapi gebruiken dan)
de post van Jrz is een zeer goede oplossing.

Ryzen 9 5900X @ 5.1Ghz | MPG B550 GAMING CARBON | 96GB DDR4-3200 | RTX 4070TI | 2TB + 1TB m.2 SSD | 3x 1TB HDD | 1x 2TB SATA SSD | 32" G3223Q (4K/144Hz)


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
Ja dat is het zeker, maar ik vind het toch omslachtig (begrijp me niet verkeerd, ik vind het super dat je de code aan me geeft, ik ga het zeker gebruiken :D ), maar is het niet stom dat we als proggers zoveel moeite moeten doen voor zo iets simpels? Wie gaat nu zo'n stuk code schrijven, alleen om keyboard input te lezen, terwijl het in een simpele taal als basic met een simpele opdracht kan... (dit is gewoon mijn mening, ik wil niet ondankbaar overkomen ;) ) Dank jullie wel :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

maar is het niet stom dat we als proggers zoveel moeite moeten doen voor zo iets simpels?
Hallo, je praat wel over 10 jaar terug, vergeet dat niet :). Het een en ander is er een stuk makkelijker op geworden in die 10 jaar.

[ Voor 19% gewijzigd door .oisyn op 09-02-2005 23:51 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 06-05 21:44
.oisyn schreef op woensdag 09 februari 2005 @ 23:50:
[...]


Hallo, je praat wel over 10 jaar terug, vergeet dat niet :). Het een en ander is er een stuk makkelijker op geworden in die 10 jaar.
Ja dat snap ik ook wel ;) Maar als je je bedenkt dat Basic nòg ouder is... :P

  • Jrz
  • Registratie: Mei 2000
  • Laatst online: 14-05 19:46

Jrz

––––––––––––

Oguz286 schreef op woensdag 09 februari 2005 @ 22:40:
Ja dat is het zeker, maar ik vind het toch omslachtig (begrijp me niet verkeerd, ik vind het super dat je de code aan me geeft, ik ga het zeker gebruiken :D ), maar is het niet stom dat we als proggers zoveel moeite moeten doen voor zo iets simpels? Wie gaat nu zo'n stuk code schrijven, alleen om keyboard input te lezen, terwijl het in een simpele taal als basic met een simpele opdracht kan... (dit is gewoon mijn mening, ik wil niet ondankbaar overkomen ;) ) Dank jullie wel :)
De meeste programma's willen graag enkele toetsen ontvangen (om te typen, dus dan krijg je eerst een delay van xxx ms en dan repeat hij yyy/sec), en wil je je ook niet druk maken over shift / keyboard indeling en dat soort ongein.
Bij spellen wil je gewoon weten of een knop ingedrukt is of niet. Er is ook geen andere manier om erachter tekomen of 2 knoppen tegelijk zijn ingedrukt. met getChar() / inkey$ krijg je dan eerst de ene, en dan de andere terug.
Hallo, je praat wel over 10 jaar terug, vergeet dat niet . Het een en ander is er een stuk makkelijker op geworden in die 10 jaar.
Met DirectInput zal je ook eerst moeten lezen waar het nou over gaat :)

Ennnnnnnnnn laat losssssssss.... https://github.com/jrz/container-shell (instant container met chroot op current directory)


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

DirectInput zuigt, en daarnaast zijn window messages vrij straightforward.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1