11 Replies - 10928 Views - Last Post: 20 January 2011 - 09:48 AM Rate Topic: -----

#1 bloodzdevil  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 56
  • Joined: 12-June 10

How to track arrow keys in c++

Posted 17 January 2011 - 08:14 AM

Hi
Im designing a game that moves the character around as per user wants.
I want to ask you guys that how can we check if the user has entered which arrow key???
I cant find it in any ascii chart. Is there any other way to do so??
Is This A Good Question/Topic? 0
  • +

Replies To: How to track arrow keys in c++

#2 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3093
  • View blog
  • Posts: 19,139
  • Joined: 14-September 07

Re: How to track arrow keys in c++

Posted 17 January 2011 - 08:18 AM

Platform?
Was This Post Helpful? 0
  • +
  • -

#3 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: How to track arrow keys in c++

Posted 17 January 2011 - 08:19 AM

This greatly depends upon your platform. i.e. windows/linux etc.

Is this a GUI application? (i.e. running in a window with graphics) -- or a console application -- or a old TurboC++ graphics.h application?
Was This Post Helpful? 0
  • +
  • -

#4 bloodzdevil  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 56
  • Joined: 12-June 10

Re: How to track arrow keys in c++

Posted 17 January 2011 - 08:32 AM

platform : Windows (XP to be more specific)

a TC v3.0 application (cant help :( )


no graphics, only text mode

This post has been edited by bloodzdevil: 17 January 2011 - 08:33 AM

Was This Post Helpful? 0
  • +
  • -

#5 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3093
  • View blog
  • Posts: 19,139
  • Joined: 14-September 07

Re: How to track arrow keys in c++

Posted 17 January 2011 - 08:36 AM

http://msdn.microsof...28VS.85%29.aspx
Was This Post Helpful? 0
  • +
  • -

#6 bloodzdevil  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 56
  • Joined: 12-June 10

Re: How to track arrow keys in c++

Posted 17 January 2011 - 09:35 AM

how to use them??
Was This Post Helpful? 0
  • +
  • -

#7 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: How to track arrow keys in c++

Posted 17 January 2011 - 11:35 AM

Ah the old TurboC -- well you really should upgrade to a modern compiler as TC is about 20years old or more.

I would actually suggest sticking with conio.h methods if you are using TurboC -- note that in a modern compiler this WOULD NOT be the recommeded way to do this, but since you are using an ancient compiler you will probably need to use the ancient method for dealing with keystrokes.

so lets start out with this dumb little program:
#include <conio.h>
#include <stdio.h>

int main() {
    unsigned char ch;
    while ((ch = getch()) != 27) {
        printf("%02X\n", ch);
    }
    return 0;
}


when you run this program it will print out the HEX value for the char that you input. If you press 'a' it will output 61, 'b' 62 etc.

now watch carefully what happens when you press an arrow key...

you get
00
4D

for the right arrow... there are two points here... Firstly you get TWO chars and not just one! secondly the first byte is 00 -- the second contains some data.

if your play around with this program a bit you can become familiar with what happens when different keys are pressed.

the above program uses getch() which will pause until the user enters some data... this is not very responsive for games. However in borland's conio.h there is another function kbhit() which will tell you if the user has pressed a key since the last input read... so we can use the two function together to look for keys here is one example:

#include <conio.h>
#include <stdio.h>

#define ARROW_UP    0x48
#define ARROW_LEFT  0x4B
#define ARROW_RIGHT 0x4D
#define ARROW_DOWN  0x50
#define ARROW_NONE  0x00
#define ESC_KEY     0x1B

unsigned char getArrow();

int main() {
    int pos_row = 1, pos_col = 1;
    int offset_row = 0, offset_col = 0;
    unsigned char arrow; 
    gotoxy(pos_col, pos_row);
    putchar(254);
    while ((arrow = getArrow()) != ESC_KEY) {
        if (arrow != ARROW_NONE) {
            switch(arrow) {
                case ARROW_UP:
                    offset_row = -1;
                    break;
                case ARROW_LEFT:
                    offset_col = -1;
                    break;
                case ARROW_RIGHT:
                    offset_col = 1;
                    break;
                case ARROW_DOWN:
                    offset_row = 1;
                    break;
            }
            gotoxy(pos_col, pos_row);
            putchar(32);
            pos_row += offset_row;
            pos_col += offset_col;
            if (pos_row < 1) { pos_row = 1; }
            if (pos_row > 25) { pos_row = 25; }
            if (pos_col < 1) { pos_col = 1; }
            if (pos_col > 80) { pos_col = 80; }
            gotoxy(pos_col, pos_row);
            putchar(254);
            offset_row = 0; offset_col = 0;
        }

    }

    return 0;
}

unsigned char getArrow() {
    if (kbhit()) {
        //we only want to get here if a key has been pressed...
        unsigned char ch = getch();
        if (ch == 0x00) {
            //first char is a zero so lets look at the next char....
            ch = getch();
            switch(ch) {
                case ARROW_UP:
                    return ch;
                case ARROW_LEFT:
                    return ch;
                case ARROW_RIGHT:
                    return ch;
                case ARROW_DOWN:
                    return ch;
                default:
                    return ARROW_NONE;
            }
        }
        return ch;
    }
    return ARROW_NONE;
}

Was This Post Helpful? 3
  • +
  • -

#8 bloodzdevil  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 56
  • Joined: 12-June 10

Re: How to track arrow keys in c++

Posted 18 January 2011 - 02:16 AM

are these values for arrow keys machine dependent i.e. if 2 computers are having win XP , do they also have these same values???
Was This Post Helpful? 0
  • +
  • -

#9 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: How to track arrow keys in c++

Posted 18 January 2011 - 08:17 AM

They *should* have the same values for any normal Windows XP computer, and since you are using ancient technology you really don't have much room to worry as your program will probably only run on a subset of modern computers anyway. If you are worried about it, you can test it on a few other computers using that first program I showed you.

If you are really worried about supporting different users on different computers you should really ditch TurboC and get a modern compiler and use modern techniques (as KYA suggested using windows virtual-keys which is an event-based approach).

TurboC is VERY old. There are a number of free modern compilers that you can download and use so that your programs can run on modern computers and you can learn modern programming techniques (rather than old TurboC techniques that have not really been used since the late last century (ok, late 1990's).

I would suggest looking into getting Visual Studio Express (free) or Code::Blocks (free ide come with MinGW a free compiler), or just the MinGW compiler or is you really want to stick with just C (and not a C++ compiler) you can use PellesC -- all of these are free and would allow you to do modern programming.
Was This Post Helpful? 0
  • +
  • -

#10 Munawwar  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 162
  • View blog
  • Posts: 457
  • Joined: 20-January 10

Re: How to track arrow keys in c++

Posted 18 January 2011 - 08:42 AM

I believe, these are 'scan codes' that were present in DOS systems. Google 'dos scan codes' or get this PDF, which is a list of all the keyboard scan codes.
Example: the code for Enter key is 0x1C0D where 0D is the ASCII (carriage return) value and 1C is the scan code.

For up arrow key it is 0x4800. When you use getch for arrow keys, the first call to getch gives you the lower byte (that's 00) and the second call gives you the scan code (that's 48).

So an easier way to get these codes without using getch, is by using bioskey.
#include <iostream.h>
#include <bios.h>
#include <conio.h>
int main() {
  int key=bioskey(0);
  cout<<hex<<key<<endl;
  getch();
  return 0;
}



Anyway, this is old stuff. If you are moving to a modern compiler on windows, let me make the transition easier...
Ahem, *Story begins*
Long ago (2-3 years back :P), I translated many of the common turbo/borland functions to Windows API. This day I make them open source and free (not bug-free <- disclaimer) to use and explore:
#include <windows.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
//EDIT: Removed conio.h. It isn't needed.
using namespace std;

struct time {
  unsigned char  ti_min;   /* minutes */
  unsigned char  ti_hour;  /* hours */
  unsigned char  ti_hund;  /* hundredths of seconds */
  unsigned char  ti_sec;   /* seconds */
};
void gettime( struct time *t)
{
  SYSTEMTIME st;
  GetSystemTime(&st);
  t->ti_min=st.wMinute;
  t->ti_hour=st.wHour;
  t->ti_hund=st.wMilliseconds;
  t->ti_sec=st.wSecond;
}
char RetChar(INPUT_RECORD &InRec)
{
 	 return InRec.Event.KeyEvent.uChar.AsciiChar;
}

UINT bioskey(int num)
{
 	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD InRec;
    DWORD NumRead;
 	ReadConsoleInput(hIn,&InRec,1,&NumRead);
 	if(num==0)
 	{
 	  while(InRec.EventType!=KEY_EVENT || InRec.Event.KeyEvent.bKeyDown==FALSE)
 	  ReadConsoleInput(hIn,&InRec,1,&NumRead);
 	  return MAKEWORD((BYTE)InRec.Event.KeyEvent.uChar.AsciiChar,(BYTE)InRec.Event.KeyEvent.wVirtualScanCode);
    }
    else
    if(num==1)
    {
       if(InRec.EventType==KEY_EVENT)
       return MAKEWORD((BYTE)InRec.Event.KeyEvent.uChar.AsciiChar,(BYTE)InRec.Event.KeyEvent.wVirtualScanCode);
       else
       return FALSE;
    }
    else
    return FALSE;
}
int Getch()
{
 	return bioskey(0);
}
void clrscr()
{
    system("cls"); //lazy me :P/>
}
int wherex()
{
  	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO ccinfo;
   GetConsoleScreenBufferInfo(hOut,&ccinfo);
	return ccinfo.dwCursorPosition.X+1;
}
int wherey()
{
  	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO ccinfo;
   GetConsoleScreenBufferInfo(hOut,&ccinfo);
	return ccinfo.dwCursorPosition.Y+1;
}
void gotoxy(int x,int y)
{
	COORD coord = {x-1,y-1};
	SetConsoleCursorPosition( GetStdHandle(STD_OUTPUT_HANDLE),coord);
}

void textcolor(int color)
{
 	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  	SetConsoleTextAttribute(hOut,color);
}
enum {_NOCURSOR=0,_NORMALCURSOR,_SOLIDCURSOR};
void _setcursortype(int Type)
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO ccinfo;
	if(Type==0)
	  ccinfo.bVisible=false;
	else
	{
	  ccinfo.bVisible=true;
	  if(Type==1)
	  ccinfo.dwSize=1;
	  else
	  ccinfo.dwSize=100;
	}
	SetConsoleCursorInfo(hOut,&ccinfo);
}
int getmouseinfo(int &x,int &y,int &mousebutton)
{
   	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD InRec;
    DWORD NumRead;
 	ReadConsoleInput(hIn,&InRec,1,&NumRead);
	if(InRec.EventType==MOUSE_EVENT)
	{
	   x=InRec.Event.MouseEvent.dwMousePosition.X;
	   y=InRec.Event.MouseEvent.dwMousePosition.Y;
	   if(InRec.Event.MouseEvent.dwButtonState==RIGHTMOST_BUTTON_PRESSED)
	     mousebutton=0x02;
	   else
	   if(InRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED)
	   	 mousebutton=0x01;
	   else
         mousebutton=InRec.Event.MouseEvent.dwButtonState;
	   return 1;
	}
	else
	{
	   x=0,y=0,mousebutton=0;
	   WriteConsoleInput(hIn,&InRec,1,&NumRead);
	   return 0;
	}
}
int random(int num)
{
    return rand()%num;
}
int cprintf(char str[])
{
   HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
   DWORD NumberOfCharsWritten;
   WriteConsole(hOut,(void*)str,strlen(str),&NumberOfCharsWritten,NULL);
   return NumberOfCharsWritten;
}
bool Kbhit()
{
   HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
   INPUT_RECORD InRec;
   DWORD NumRead;
   PeekConsoleInput(hIn,&InRec,1,&NumRead);
   if(InRec.EventType==KEY_EVENT)
	 return true;
   else
   {
   	 //WriteConsoleInput(hIn,&InRec,1,&NumRead);
	 return false;
   }
}
void Delay(int millisec)
{
    Sleep(millisec);
}
void textmode(int type)
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SMALL_RECT sr={0,0,79,49};
 	SetConsoleWindowInfo(hOut,true,&sr);
	SetConsoleScreenBufferSize(hOut,(COORD){80,50});
}


Some of the function are well written and others aren't. I quit the project since like many other projects of mine I lost interest *sigh*.
*End of story*

This post has been edited by Munawwar: 18 January 2011 - 09:01 AM

Was This Post Helpful? 3
  • +
  • -

#11 bloodzdevil  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 56
  • Joined: 12-June 10

Re: How to track arrow keys in c++

Posted 20 January 2011 - 08:30 AM

I would love to move up the ladder in the compiler area. But im bound by the rules of my course. the people up there dont *want* us students to be advanced...theyve made Turbo C++ v3.0 compulsory
Was This Post Helpful? 0
  • +
  • -

#12 Aphex19  Icon User is offline

  • Born again Pastafarian.
  • member icon

Reputation: 614
  • View blog
  • Posts: 1,873
  • Joined: 02-August 09

Re: How to track arrow keys in c++

Posted 20 January 2011 - 09:48 AM

View Postbloodzdevil, on 20 January 2011 - 08:30 AM, said:

I would love to move up the ladder in the compiler area. But im bound by the rules of my course. the people up there dont *want* us students to be advanced...theyve made Turbo C++ v3.0 compulsory


The worst thing is that some of the newest, up to date compilers are free, they don't cost a thing. They have no excuse for denying you better technology.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1