1 / 15

Linux game programming

Linux game programming. An introduction to the use of interval timers and asynchronous input notifications. Our prior animation demo. We achieved the illusion of “smooth” and “flicker-free” animation, by synchronizing drawing-operations with Vertical Retrace

marly
Download Presentation

Linux game programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux game programming An introduction to the use of interval timers and asynchronous input notifications

  2. Our 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?

  3. Decoupling ‘move’ from ‘draw’ • Our program-loop had used logic like this: do { vsync(); // delay until start of the next retrace hide_ball(); // “erase” the ball move_ball(); // adjust its location show_ball(); // “redraw” the ball --count; // decrement a counter } while ( count > 0 );

  4. 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)

  5. 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 Retrace

  6. Our signal-handler void on_alarm( int signum ) { // modify these global variables ball_xcoordinate += xincrement; ball_ycoordinate += yincrement; } // The ‘signal()’ function “installs” our handler signal( SIGALRM, on_alarm);

  7. Main program-loop “revised” • We can now omit ball-movement in main loop: do { vsync(); // delay until start of the next retrace hide_ball(); // “erase” the old ball oldx = newx; oldy = newy; // remember new position show_ball(); // “redraw” the new ball --count; // decrement a counter } while ( count > 0 ); • Ball-movement is managed by ‘signal-handler’

  8. 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

  9. ‘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 settings tty.c_lflag &= ~( ICANON | ECHO | ISIG ); tty.c_cc[ VMIN ] = 1; tty.c_cc[ VTIME ] = 0; tcsetattr( 0, TCSAFLUSH, &tty ); // install

  10. Handling 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 zero void on_input( int signum ) { int inch = 0; read( 0, &inch, 4 ); if ( inch == ESCAPE_KEY ) done = 1; }

  11. 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 );

  12. Program-loop revised again done = 0; do { oldx = xloc, oldy = yloc; // remember draw_ball(); // use current location vsync(); // await next retrace hide_ball(); // erase previous ball } while ( !done ); // ‘xloc’, ‘yloc’, and ‘done’ get changed by handlers

  13. Enhancment: 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-key

  14. In-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!

  15. 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 ‘-’ key)?

More Related