Linux game programmingOur prior animation demoDecoupling ‘move’ from ‘draw’Linux provides ‘interval timers’SIGALRMOur signal-handlerMain program-loop “revised”Giving the user control‘Noncanonical’ terminal i/oHandling a key-pressEnabling ‘asynchronous’ I/OProgram-loop revised againEnhancment: more user-controlIn-class exercise #1In-class exercise #2Linux game programmingAn introduction to the use of interval timers and asynchronous input notificationsOur prior animation demo•We achieved the illusion of “smooth” and “flicker-free” animation, by synchronizing drawing-operations with Vertical Retrace •But more is needed in a game that’s “fun” •Some deficiencies in our ‘animate1’ demo:–Ball movements tied to Vertical Retrace–The viewer lacked any real-time control•How can we overcome these limitations?Decoupling ‘move’ from ‘draw’•Our program-loop had used logic like this:do {vsync(); // delay until start of the next retracehide_ball(); // “erase” the ballmove_ball(); // adjust its locationshow_ball(); // “redraw” the ball--count; // decrement a counter}while ( count > 0 );Linux provides ‘interval timers’•#include <sys/time.h>•struct itimerval itval, itold;•itval.it_value.tv_sec = 2; •itval.it_value.tv_usec = 0;•itval.it_interval.tv_sec = 0;•itval.it_interval.tv_usec = 10000;•setitimer( ITIMER_REAL, &itval, &itold );•(See the ‘man’ page for additional details)SIGALRM•When timer “expires” our application gets notified, by being sent a signal from Linux•Normally an application gets terminated if the SIGALRM signal is delivered to it•But we can alter that default behavior, by installing a ‘signal-handler’ that we design•We can ‘move-the-ball’ when SIGALRM is received, regardless of Vertical RetraceOur signal-handler void on_alarm( int signum ){// modify these global variablesball_xcoordinate += xincrement;ball_ycoordinate += yincrement;}// The ‘signal()’ function “installs” our handlersignal( SIGALRM, on_alarm);Main program-loop “revised”•We can now omit ball-movement in main loop:do {vsync(); // delay until start of the next retracehide_ball(); // “erase” the old ball oldx = newx; oldy = newy; // remember new positionshow_ball(); // “redraw” the new ball--count; // decrement a counter}while ( count > 0 );• Ball-movement is managed by ‘signal-handler’Giving the user control•Linux supports “asynchronous” terminal i/o•We can reprogram the terminal console so a SIGIO signal will be sent to our program whenever the user decides to press a key•And we can install a ‘signal-handler’ of our own design that executes if SIGIO arrives •This will allow a user to “control” our game‘Noncanonical’ terminal i/o•We already learned how to reprogram the terminal to allow “raw” keyboard input#include <termios.h>struct termios tty;tcgetattr( 0, &tty ); // get tty settingstty.c_lflag &= ~( ICANON | ECHO | ISIG );tty.c_cc[ VMIN ] = 1; tty.c_cc[ VTIME ] = 0;tcsetattr( 0, TCSAFLUSH, &tty ); // installHandling a key-press•Here’s a ‘simple’ signal-handler that lets a user decide to terminate our program (by hitting the <ESCAPE>-key) instead of the program itself deciding to quit when a counter reaches zerovoid on_input( int signum ){int inch = 0;read( 0, &inch, 4 );if ( inch == ESCAPE_KEY ) done = 1;}Enabling ‘asynchronous’ I/O•Now we need to install our signal-handler, specify which program will receive SIGIO, then enable the delivery of these signals •signal( SIGIO, on_input );•fcntl( 0, F_SETOWN, getpid() );•int flagval = fcntl( 0, F_GETFL, NULL ); •flagval |= O_ASYNC; // turn on flag-bit•fcntl( 0, F_SETFL, flagval );Program-loop revised againdone = 0;do {oldx = xloc, oldy = yloc; // rememberdraw_ball(); // use current locationvsync(); // await next retracehide_ball(); // erase previous ball}while ( !done );// ‘xloc’, ‘yloc’, and ‘done’ get changed by handlersEnhancment: more user-control•In ‘pong’ game the user moves a ‘paddle’•The paddle can only be moved left or right•Lower wall of the playing-court is removed•Ball will “escape” unless it hits the paddle•Keyboard has left and right “arrow keys” •Our input signal-handler could “move” the paddle whenever a user hits an arrow-keyIn-class exercise #1•Before you remove the game-court’s lower wall, see if you can implement the paddle-movements (left or right) in response to a user’s hitting the left-arrow or right-arrow•You will need to investigate the numerical code-sequence that Linux generates when a user hits one of these arrow-keys•Our ‘rawtty.cpp’ application may be useful!In-class exercise #2•For brevity, our ‘animate2’ demo-program removed the capability of users controlling the speed of the ball-movements (with an argument supplied on the command-line)•Can you devise a way for users to exert “real-time” control over the ball’s speed by pressing keys while the program is running (for example, the ‘+’ key and the ‘-’
View Full Document