This is a framework for making games.

The framework (cmain.c) wants the following things from
game.h:

 * GAMETITLE, defined to be a string for the window title
   bar.
 * SCRWIDTH and SCRHEIGHT, the desired screen resolution.
 * TICS, the number of logical game tics per second. The
   framework will try to draw this many frames a second, but
   it will skip frames if it can't keep up.
 * void game_init(void) for initializing the game state,
   loading data, and so on.
 * int game_run_logic_frame(void) for running a logic frame:
   reading keys, moving stuff, etc. This should return
   nonzero if anything might have visibly changed, or zero
   if there is surely nothing new on the screen and no
   reason to redraw it.
 * void game_draw_frame(BITMAP *target, int paused) for
   drawing an entire frame of the game. If paused is
   nonzero, the game is paused, so you probably want to draw
   a "paused" banner.

Furthermore, the sfx and music playing code (csound.c) wants
two arrays of pointers to C strings, each terminated with a
null pointer:
 * sfxnames should be the full filenames of sound effects to
   load.
 * musicnames should be the full filenames of mod files to
   load.

You have the following routines to use, declared in cmain.h:

 * void abort_with_error(const char *msg, ...) for if you
   have a problem loading some data, etc. You may call this
   from game_init() and sound_init().
 * void toggle_fullscreen(void) -- you should call this if
   the user presses Alt-Enter. (This works automatically
   when the game is paused.)
 * void save_screenshot(const char *filename) saves a
   screenshot.
 * void pause_game(void) -- call this to pause the game.
   While it is paused, no logic frames will be run. Space or
   Escape will unpause.
 * void end_game(void) -- call this when you want the game
   to end. sound_update() and game_draw_frame() will each be
   called one final time, so be ready for that.
 * Also the memory management routines xm and xr and macro
   XPND, and string-duplication function xsd.
 * int rnd(int n) gives you a random number from 0 to n-1,
   inclusive. It's intended for fairly small n. No
   initialization is necessary.
 * double frnd(void) gives a floating-point random number on
   [0.0, 1.0).
 * const char *pathify(const char *basename) prepends the
   SHAREPATH to the filename. Copy the result if you need to
   keep it; future calls will wipe it out.

And these in csound.h:

 * void sound_play(int sample) plays a sample. The number is
   the same as its filename's offset in sfxnames.
 * void sound_playmusic(int music) changes the music. Pass a
   value of -1 to stop the music.
 * void sound_playorder(int order) seeks to another order in
   the mod. Useful for putting multiple songs in one mod,
   thus saving space if they use the same samples.

And these variables, updated each game_run_logic_frame call:
 * extern char thiskey[KEY_MAX], lastkey[KEY_MAX] are like
   the Allegro key array, but set for this logic frame and
   the previous, respectively.
 * extern int thiskey_shifts, lastkey_shifts are likewise.
 * extern char newkey[KEY_MAX] is set for keys held only
   this frame and not the previous frame.
 * extern int newkey_shifts contains only the flags true for
   this frame but not the last.

TODO:

 * Make timing routines give up the CPU on operating systems
   where they can safely do so.
