JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Initial Import of rockdodger 0.4.2 source
authorJoshua Grams <josh@qualdan.com>
Mon, 13 Dec 2004 15:14:49 +0000 (15:14 +0000)
committerJoshua Grams <josh@qualdan.com>
Mon, 13 Dec 2004 15:14:49 +0000 (15:14 +0000)
(as modified by Jason and Josh).

35 files changed:
COPYING [new file with mode: 0644]
Makefile [new file with mode: 0644]
SFont.c [new file with mode: 0644]
SFont.h [new file with mode: 0644]
data/banners/dodgers.png [new file with mode: 0644]
data/banners/game.png [new file with mode: 0644]
data/banners/over.png [new file with mode: 0644]
data/banners/rock.png [new file with mode: 0644]
data/fonts/score.png [new file with mode: 0644]
data/icons/rockdodger.xpm [new file with mode: 0644]
data/icons/spacerocks.xpm [new file with mode: 0644]
data/indicators/life.png [new file with mode: 0644]
data/music/4est_fulla3s.mod [new file with mode: 0644]
data/music/getzznew.mod [new file with mode: 0644]
data/music/magic.mod [new file with mode: 0644]
data/sounds/boom.wav [new file with mode: 0644]
data/sounds/booom.wav [new file with mode: 0644]
data/sounds/bzboom.wav [new file with mode: 0644]
data/sounds/cboom.wav [new file with mode: 0644]
data/sprites/.xvpics/ship.png [new file with mode: 0644]
data/sprites/deadrock0.png [new file with mode: 0644]
data/sprites/deadrock1.png [new file with mode: 0644]
data/sprites/deadrock2.png [new file with mode: 0644]
data/sprites/deadrock3.png [new file with mode: 0644]
data/sprites/deadrock4.png [new file with mode: 0644]
data/sprites/deadrock5.png [new file with mode: 0644]
data/sprites/rock0.png [new file with mode: 0644]
data/sprites/rock1.png [new file with mode: 0644]
data/sprites/rock2.png [new file with mode: 0644]
data/sprites/rock3.png [new file with mode: 0644]
data/sprites/rock4.png [new file with mode: 0644]
data/sprites/rock5.png [new file with mode: 0644]
data/sprites/ship.png [new file with mode: 0644]
main.c [new file with mode: 0644]
sound.c [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..2c04a71
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,86 @@
+#   Rock Dodger! Avoid the rocks as long as you can!
+#   Copyright (C) 2001  Paul Holt <pad@pcholt.com>
+
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+VERSION=0.4.2
+PACKAGENAME=rockdodger
+NEWD=$(PACKAGENAME)-$(VERSION)
+TMP=/tmp
+OPTIONS=-DVERSION=\"$(VERSION)\"
+SOUNDSOURCE=sound
+
+SOUNDLIBRARIES=-lSDL_mixer
+
+LIBRARIES=`sdl-config --libs` -lSDL_image $(SOUNDLIBRARIES)
+
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL) -o games -g games
+INSTALL_DATA = $(INSTALL) -m 644
+
+DATA_PREFIX = /usr/share/rockdodger
+PROGRAM_PREFIX = /usr/games/bin
+
+all:   rd
+
+.c.o:
+       cc -c -g $? `sdl-config --cflags` $(OPTIONS)
+
+rd:    SFont.o $(SOUNDSOURCE).o main.o
+       cc -o rd $+ $(LIBRARIES)
+
+clean:
+       rm -f *.o rd
+
+install:       all
+       if [ ! -d $(DATA_PREFIX) ]; then mkdir $(DATA_PREFIX); fi
+       if [ ! -d $(DATA_PREFIX)/banners ]; then mkdir $(DATA_PREFIX)/banners; fi
+       if [ ! -d $(DATA_PREFIX)/fonts ]; then mkdir $(DATA_PREFIX)/fonts; fi
+       if [ ! -d $(DATA_PREFIX)/icons ]; then mkdir $(DATA_PREFIX)/icons; fi
+       if [ ! -d $(DATA_PREFIX)/indicators ]; then mkdir $(DATA_PREFIX)/indicators; fi
+       if [ ! -d $(DATA_PREFIX)/music ]; then mkdir $(DATA_PREFIX)/music; fi
+       if [ ! -d $(DATA_PREFIX)/sounds ]; then mkdir $(DATA_PREFIX)/sounds; fi
+       if [ ! -d $(DATA_PREFIX)/sprites ]; then mkdir $(DATA_PREFIX)/sprites; fi
+
+       $(INSTALL_PROGRAM) ./rd $(PROGRAM_PREFIX)
+       $(INSTALL_DATA) ./data/banners/* $(DATA_PREFIX)/banners/
+       $(INSTALL_DATA) ./data/fonts/* $(DATA_PREFIX)/fonts/
+       $(INSTALL_DATA) ./data/icons/* $(DATA_PREFIX)/icons/
+       $(INSTALL_DATA) ./data/indicators/* $(DATA_PREFIX)/indicators/
+       $(INSTALL_DATA) ./data/music/* $(DATA_PREFIX)/music/
+       $(INSTALL_DATA) ./data/sounds/* $(DATA_PREFIX)/sounds/
+       $(INSTALL_DATA) ./data/sprites/* $(DATA_PREFIX)/sprites/
+       touch $(DATA_PREFIX)/.highscore
+       chmod a+rw $(DATA_PREFIX)/.highscore
+
+uninstall:
+       rm -f $(PROGRAM_PREFIX)/rd
+       rm -f $(DATA_PREFIX)/banners/*
+       rm -f $(DATA_PREFIX)/fonts/*
+       rm -f $(DATA_PREFIX)/icons/*
+       rm -f $(DATA_PREFIX)/indicators/*
+       rm -f $(DATA_PREFIX)/music/*
+       rm -f $(DATA_PREFIX)/sounds/*
+       rm -f $(DATA_PREFIX)/sprites/*
+       rm -f $(DATA_PREFIX)/.highscore
+
+       if [ -d $(DATA_PREFIX)/banners ]; then rmdir $(DATA_PREFIX)/banners; fi
+       if [ -d $(DATA_PREFIX)/fonts ]; then rmdir $(DATA_PREFIX)/fonts; fi
+       if [ -d $(DATA_PREFIX)/icons ]; then rmdir $(DATA_PREFIX)/icons; fi
+       if [ -d $(DATA_PREFIX)/indicators ]; then rmdir $(DATA_PREFIX)/indicators; fi
+       if [ -d $(DATA_PREFIX)/music ]; then rmdir $(DATA_PREFIX)/music; fi
+       if [ -d $(DATA_PREFIX)/sounds ]; then rmdir $(DATA_PREFIX)/sounds; fi
+       if [ -d $(DATA_PREFIX)/sprites ]; then rmdir $(DATA_PREFIX)/sprites; fi
+       if [ -d $(DATA_PREFIX) ]; then rmdir $(DATA_PREFIX); fi
diff --git a/SFont.c b/SFont.c
new file mode 100644 (file)
index 0000000..e03be40
--- /dev/null
+++ b/SFont.c
@@ -0,0 +1,282 @@
+#include <SDL/SDL.h>
+#include "SFont.h"
+#include "string.h"
+
+SFont_FontInfo InternalFont;
+int alpha=127;
+int font_height;
+
+Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
+{
+
+   Uint8  *bits;
+   Uint32 Bpp;
+
+   if (X<0) puts("SFONT ERROR: x too small in GetPixel. Report this to <karlb@gmx.net>");
+   if (X>=Surface->w) puts("SFONT ERROR: x too big in GetPixel. Report this to <karlb@gmx.net>");
+   
+   Bpp = Surface->format->BytesPerPixel;
+
+   bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
+
+   // Paint the walls with the fresh blood of your enemies
+
+   // Get the pixel
+   switch(Bpp) {
+      case 1:
+         return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
+         break;
+      case 2:
+         return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
+         break;
+      case 3: { // Format/endian independent 
+         Uint8 r, g, b;
+         r = *((bits)+Surface->format->Rshift/8);
+         g = *((bits)+Surface->format->Gshift/8);
+         b = *((bits)+Surface->format->Bshift/8);
+         return SDL_MapRGB(Surface->format, r, g, b);
+         }
+         break;
+      case 4:
+         return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
+         break;
+   }
+
+    return -1;
+}
+
+void InitFont2(SFont_FontInfo *Font)
+{
+    int x = 0, i = 0;
+
+    if ( Font->Surface==NULL ) {
+       printf("The font has not been loaded!\n");
+       exit(1);
+    }
+
+    while ( x < Font->Surface->w ) {
+       if(GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) { 
+           Font->CharPos[i++]=x;
+           while (( x < Font->Surface->w-1) && (GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)))
+               x++;
+           Font->CharPos[i++]=x;
+       }
+       x++;
+    }
+
+    Font->h=Font->Surface->h;
+    font_height = Font->h;
+    SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, GetPixel(Font->Surface, 0, Font->Surface->h-1));
+}
+
+void InitFont(SDL_Surface *Font)
+{
+    InternalFont.Surface=Font;
+    InitFont2(&InternalFont);
+}
+
+int SFont_wide(char *text) {
+    int i=0,xwide=0;
+    int ofs;
+    SFont_FontInfo *Font = &InternalFont;
+
+    while (text[i]) {
+        if (text[i]==' ') {
+            xwide += (int)(Font->CharPos[2]-Font->CharPos[1]);
+       }
+       else {
+           ofs = (text[i]-33)*2+1;
+            xwide += (int)(Font->CharPos[ofs+1]-Font->CharPos[ofs]);
+       }
+       i++;
+    }
+    return xwide;
+}
+
+int SFont_height() {
+    return InternalFont.Surface->h-1;
+}
+
+void PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text)
+{
+    int ofs;
+    int i=0;
+    SDL_Rect srcrect,dstrect; 
+
+    while (text[i]) {
+        if (text[i]==' ') {
+            x+=Font->CharPos[2]-Font->CharPos[1];
+       }
+       else {
+//         printf("-%c- %c - %u\n",228,text[i],text[i]);
+           ofs=(text[i]-33)*2+1;
+           //printf("printing %c %d\n",text[i],ofs);
+            srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
+            srcrect.h = dstrect.h = Font->Surface->h-1;
+            srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
+            srcrect.y = 1;
+           dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
+           dstrect.y = y;
+
+           //SDL_SetAlpha ( Font->Surface, SDL_SRCALPHA, 127);
+           SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect); 
+
+            x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
+        }
+        i++;
+    }
+}
+
+// Return a new surface, with the text on it.
+// This surface is new, fresh, and must eventually be freed.
+// Create the new surface with the same colour system as a parent surface.
+SDL_Surface *new_Surface_PutString(SDL_Surface *parent, char *text) {
+
+     Uint32 rmask = parent->format->Rmask;
+     Uint32 gmask = parent->format->Gmask;
+     Uint32 bmask = parent->format->Bmask;
+     Uint32 amask = parent->format->Amask;
+     Uint32 bytesperpixel = parent->format->BytesPerPixel;
+
+     return SDL_CreateRGBSurface(
+       SDL_SWSURFACE, 
+       SFont_wide(text), 
+       SFont_height(), 
+       bytesperpixel, rmask, gmask, bmask, amask
+    );
+}
+
+void PutString(SDL_Surface *Surface, int x, int y, char *text) {
+    PutString2(Surface, &InternalFont, x, y, text);
+}
+
+int TextWidth2(SFont_FontInfo *Font, char *text)
+{
+    int x=0,i=0;
+    unsigned char ofs = 0;
+    while (text[i]!='\0') {
+        if (text[i]==' ') {
+           x+=Font->CharPos[2]-Font->CharPos[1];
+           i++;
+       }
+       else {
+           ofs=(text[i]-33)*2+1;
+           x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
+           i++;
+       }
+    }
+    return x+Font->CharPos[ofs+2]-Font->CharPos[ofs+1];
+}
+
+int TextWidth(char *text)
+{
+    return TextWidth2(&InternalFont, text);
+}
+
+void TextAlpha(int a) {
+    alpha = a;
+}
+
+void XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text)
+{
+    PutString2(Surface, &InternalFont, Surface->w/2-TextWidth(text)/2, y, text);
+}
+
+void XCenteredString(SDL_Surface *Surface, int y, char *text)
+{
+    XCenteredString2(Surface, &InternalFont, y, text);
+}
+
+SDL_Surface *Back;
+char tmp[1024];
+
+void clearBuffer() {
+    SDL_Event event;
+
+    // Delete the event buffer
+    while (SDL_PollEvent(&event))
+       ;
+    // start input
+    SDL_EnableUNICODE(1);
+}
+
+int SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
+{
+    SDL_Event event;
+    int ch;
+    SDL_Rect rect;
+    int ofs=(text[0]-33)*2+1;
+    int leftshift;
+
+    if (ofs<0) {
+       leftshift = 0;
+    }
+    else {
+       leftshift = (Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
+    }
+
+    rect.x=x-leftshift;
+    rect.y=y;
+    rect.w=PixelWidth;
+    rect.h=Font->Surface->h;
+
+    //SDL_SetAlpha (Dest, SDL_SRCALPHA, 127);
+
+    SDL_BlitSurface(Dest, &rect, Back, NULL);
+    sprintf(tmp,"%s_",text);
+    PutString2(Dest,Font,x,y,tmp);
+    SDL_UpdateRect(Dest, x-leftshift, y, PixelWidth, Font->h);
+
+    while (SDL_PollEvent(&event) && event.type==SDL_KEYDOWN) {
+
+       // Find the character pressed
+       ch=event.key.keysym.unicode;
+
+       // If backspace and the length of the text > 0, reduce the string by 1 character
+       if (ch=='\b') {
+           if (strlen(text)>0) {
+               text[strlen(text)-1]='\0';
+           }
+       }
+       else {
+           sprintf(text,"%s%c",text,ch);
+       }
+
+       // If the new character would exceed the allowed width
+       if (TextWidth2(Font,text)>PixelWidth) {
+           text[strlen(text)-1]='\0';
+       }
+
+       //SDL_SetAlpha (Back, SDL_SRCALPHA, 127);
+       SDL_BlitSurface( Back, NULL, Dest, &rect);
+       PutString2(Dest, Font, x, y, text);
+       if (ofs>0) {
+           SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h);
+       }
+
+    }
+    //text[strlen(text)-1]='\0';
+    if (ch==SDLK_RETURN) {
+       SDL_FreeSurface(Back);
+       return 1;
+    }
+    else
+       return 0;
+}
+
+int SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text)
+{
+    
+    Back = SDL_AllocSurface(Dest->flags,
+                           PixelWidth,
+                           InternalFont.h,
+                           Dest->format->BitsPerPixel,
+                           Dest->format->Rmask,
+                           Dest->format->Gmask,
+                           Dest->format->Bmask, 0);
+
+    return SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text);
+    // ph:
+    // Returns 1 when the return key is pressed
+    // Returns 0 when nothing exceptional happened
+}
diff --git a/SFont.h b/SFont.h
new file mode 100644 (file)
index 0000000..69454cf
--- /dev/null
+++ b/SFont.h
@@ -0,0 +1,47 @@
+/************************************************************************ 
+*    SFONT - SDL Font Library by Karl Bartel <karlb@gmx.net>           *
+*                                                                       *
+*  All functions are explained below. There are two versions of each    *
+*  funtction. The first is the normal one, the function with the        *
+*  2 at the end can be used when you want to handle more than one font  *
+*  in your program.                                                     *
+*                                                                       *
+************************************************************************/
+
+#include <SDL/SDL.h>
+
+// Delcare one variable of this type for each font you are using.
+// To load the fonts, load the font image into YourFont->Surface
+// and call InitFont( YourFont );
+typedef struct {
+       SDL_Surface *Surface;   
+       int CharPos[512];
+       int h;
+} SFont_FontInfo;
+
+// Initializes the font
+// Font: this contains the suface with the font.
+//       The font must be loaded before using this function.
+void InitFont (SDL_Surface *Font);
+void InitFont2(SFont_FontInfo *Font);
+
+// Blits a string to a surface
+// Destination: the suface you want to blit to
+// text: a string containing the text you want to blit.
+void PutString (SDL_Surface *Surface, int x, int y, char *text);
+void PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text);
+
+// Returns the width of "text" in pixels
+int TextWidth(char *text);
+int TextWidth2(SFont_FontInfo *Font, char *text);
+
+// Blits a string to with centered x position
+void XCenteredString (SDL_Surface *Surface, int y, char *text);
+void XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text);
+
+// Allows the user to enter text
+// Width: What is the maximum width of the text (in pixels)
+// text: This string contains the text which was entered by the user
+// ph: nonblocking
+int SFont_Input ( SDL_Surface *Destination, int x, int y, int Width, char *text);
+int SFont_Input2( SDL_Surface *Destination, SFont_FontInfo *Font, int x, int y, int Width, char *text);
diff --git a/data/banners/dodgers.png b/data/banners/dodgers.png
new file mode 100644 (file)
index 0000000..9f083e9
Binary files /dev/null and b/data/banners/dodgers.png differ
diff --git a/data/banners/game.png b/data/banners/game.png
new file mode 100644 (file)
index 0000000..d12a809
Binary files /dev/null and b/data/banners/game.png differ
diff --git a/data/banners/over.png b/data/banners/over.png
new file mode 100644 (file)
index 0000000..0daf7fa
Binary files /dev/null and b/data/banners/over.png differ
diff --git a/data/banners/rock.png b/data/banners/rock.png
new file mode 100644 (file)
index 0000000..4a1ff45
Binary files /dev/null and b/data/banners/rock.png differ
diff --git a/data/fonts/score.png b/data/fonts/score.png
new file mode 100644 (file)
index 0000000..eecd4e5
Binary files /dev/null and b/data/fonts/score.png differ
diff --git a/data/icons/rockdodger.xpm b/data/icons/rockdodger.xpm
new file mode 100644 (file)
index 0000000..efff34b
--- /dev/null
@@ -0,0 +1,465 @@
+/* XPM */
+static char * rockdodger_xpm[] = {
+"64 64 398 2",
+"      c None",
+".     c #00FF00",
+"+     c #000000",
+"@     c #383869",
+"#     c #1D1DA3",
+"$     c #1D1DA1",
+"%     c #2121B7",
+"&     c #2424C7",
+"*     c #2525CE",
+"=     c #2525CF",
+"-     c #2626CF",
+";     c #2727CC",
+">     c #2727CA",
+",     c #2E2EA7",
+"'     c #39396B",
+")     c #42425D",
+"!     c #434348",
+"~     c #24249E",
+"{     c #2626D1",
+"]     c #2626D0",
+"^     c #2424C5",
+"/     c #2525BB",
+"(     c #343493",
+"_     c #414160",
+":     c #2A2A8C",
+"<     c #2121B5",
+"[     c #2323C0",
+"}     c #2424C6",
+"|     c #2525CD",
+"1     c #2E2EAB",
+"2     c #42425B",
+"3     c #404055",
+"4     c #262677",
+"5     c #1B1B87",
+"6     c #29297E",
+"7     c #2A2A95",
+"8     c #2828B6",
+"9     c #2828C0",
+"0     c #2525C3",
+"a     c #2525CB",
+"b     c #2323C1",
+"c     c #2020B2",
+"d     c #3E3E63",
+"e     c #474747",
+"f     c #3E3E68",
+"g     c #353583",
+"h     c #2222BD",
+"i     c #2525CC",
+"j     c #2323C3",
+"k     c #1F1F77",
+"l     c #3D3D58",
+"m     c #3B3B69",
+"n     c #353592",
+"o     c #443FA0",
+"p     c #746597",
+"q     c #736F78",
+"r     c #494D57",
+"s     c #353942",
+"t     c #43434A",
+"u     c #3A3A67",
+"v     c #38387F",
+"w     c #5F4E7C",
+"x     c #D9939A",
+"y     c #FEC2C2",
+"z     c #F3BEC0",
+"A     c #B99099",
+"B     c #B9949E",
+"C     c #F29FA0",
+"D     c #B8717B",
+"E     c #222141",
+"F     c #161B3D",
+"G     c #2B2846",
+"H     c #1F2B46",
+"I     c #5D5555",
+"J     c #F09393",
+"K     c #FFACAC",
+"L     c #FEB7B7",
+"M     c #FFC6C6",
+"N     c #C098A1",
+"O     c #303250",
+"P     c #30314F",
+"Q     c #BF737C",
+"R     c #B86E78",
+"S     c #13193C",
+"T     c #001035",
+"U     c #011035",
+"V     c #081538",
+"W     c #2A303E",
+"X     c #E8A9BA",
+"Y     c #EEB6C4",
+"Z     c #F2C6D0",
+"`     c #F7B7BD",
+" .    c #FEBBBC",
+"..    c #FF9B9B",
+"+.    c #E48387",
+"@.    c #855365",
+"#.    c #845264",
+"$.    c #E07E82",
+"%.    c #EB7E7F",
+"&.    c #9E5663",
+"*.    c #432D48",
+"=.    c #171A3B",
+"-.    c #021136",
+";.    c #031136",
+">.    c #604557",
+",.    c #EFC089",
+"'.    c #EFC372",
+").    c #EE9888",
+"!.    c #E08383",
+"~.    c #D27B7B",
+"{.    c #DC8282",
+"].    c #3F3FCE",
+"^.    c #9488DD",
+"/.    c #BAACE4",
+"(.    c #B4A5E2",
+"_.    c #B497D1",
+":.    c #9B7BB8",
+"<.    c #CC95BC",
+"[.    c #D592B0",
+"}.    c #CA859F",
+"|.    c #CF819A",
+"1.    c #E47784",
+"2.    c #EE6466",
+"3.    c #EE5B5B",
+"4.    c #E85657",
+"5.    c #BC4C54",
+"6.    c #703548",
+"7.    c #6F394D",
+"8.    c #CF8263",
+"9.    c #FAE26D",
+"0.    c #FDE672",
+"a.    c #F8A17B",
+"b.    c #F57E7E",
+"c.    c #F37777",
+"d.    c #F67F7F",
+"e.    c #FA8A8A",
+"f.    c #FD8DA1",
+"g.    c #FD86C8",
+"h.    c #FC78C2",
+"i.    c #F8869B",
+"j.    c #FD9090",
+"k.    c #FF9191",
+"l.    c #E08888",
+"m.    c #19197E",
+"n.    c #1A1A7D",
+"o.    c #1E1E7D",
+"p.    c #282889",
+"q.    c #3131C2",
+"r.    c #3535CD",
+"s.    c #3333CA",
+"t.    c #3232C9",
+"u.    c #3232C5",
+"v.    c #2E2EC9",
+"w.    c #2828CF",
+"x.    c #2424D3",
+"y.    c #2C2CD1",
+"z.    c #2F2FC6",
+"A.    c #2D2CAC",
+"B.    c #8A4194",
+"C.    c #CC4351",
+"D.    c #DD4343",
+"E.    c #EC4444",
+"F.    c #ED4949",
+"G.    c #E84B4B",
+"H.    c #E94D4D",
+"I.    c #EE7543",
+"J.    c #FBD637",
+"K.    c #FBD639",
+"L.    c #F07846",
+"M.    c #EC4D4D",
+"N.    c #ED4C4C",
+"O.    c #EE4B4B",
+"P.    c #EE4F4F",
+"Q.    c #F24A6B",
+"R.    c #FC3EA9",
+"S.    c #FC40AA",
+"T.    c #F44466",
+"U.    c #F24343",
+"V.    c #F24242",
+"W.    c #F14141",
+"X.    c #F24141",
+"Y.    c #6A6AA1",
+"Z.    c #6D6D9F",
+"`.    c #6E6E9E",
+" +    c #717199",
+".+    c #676799",
+"++    c #68689A",
+"@+    c #656290",
+"#+    c #725A8A",
+"$+    c #7C5182",
+"%+    c #7F558C",
+"&+    c #764E98",
+"*+    c #6C4FA0",
+"=+    c #6548A7",
+"-+    c #4F43BF",
+";+    c #413CCB",
+">+    c #4938B8",
+",+    c #5C4394",
+"'+    c #5F3A43",
+")+    c #CF4040",
+"!+    c #E94141",
+"~+    c #ED4141",
+"{+    c #EF4141",
+"]+    c #F2693D",
+"^+    c #FACA31",
+"/+    c #F1693D",
+"(+    c #ED4242",
+"_+    c #EE4141",
+":+    c #F33D61",
+"<+    c #FC33A7",
+"[+    c #F43D61",
+"}+    c #F14140",
+"|+    c #EF3E3C",
+"1+    c #EB3A35",
+"2+    c #732222",
+"3+    c #790F0F",
+"4+    c #900909",
+"5+    c #9A0707",
+"6+    c #9B0606",
+"7+    c #970A0A",
+"8+    c #95080C",
+"9+    c #860A1A",
+"0+    c #860C1E",
+"a+    c #9D0C1A",
+"b+    c #AE1216",
+"c+    c #B31919",
+"d+    c #DD3737",
+"e+    c #F04141",
+"f+    c #F4763C",
+"g+    c #FDDE35",
+"h+    c #F5763D",
+"i+    c #EC4141",
+"j+    c #F43D60",
+"k+    c #F93198",
+"l+    c #F62F8F",
+"m+    c #EE3856",
+"n+    c #E53B37",
+"o+    c #E13831",
+"p+    c #E6372F",
+"q+    c #E23228",
+"r+    c #D52819",
+"s+    c #C21C0D",
+"t+    c #1B1700",
+"u+    c #8F0202",
+"v+    c #9B0202",
+"w+    c #9F0202",
+"x+    c #A20202",
+"y+    c #A00303",
+"z+    c #A10303",
+"A+    c #BE1919",
+"B+    c #E93A3A",
+"C+    c #E53737",
+"D+    c #EF3F3F",
+"E+    c #EF4040",
+"F+    c #F06B35",
+"G+    c #EEC621",
+"H+    c #E7BF18",
+"I+    c #D85311",
+"J+    c #C61F0B",
+"K+    c #B71E09",
+"L+    c #BF1D0D",
+"M+    c #C01A0E",
+"N+    c #BE1413",
+"O+    c #C40B14",
+"P+    c #C60A13",
+"Q+    c #BB110D",
+"R+    c #B71606",
+"S+    c #B91905",
+"T+    c #AE1A03",
+"U+    c #AB1402",
+"V+    c #B11102",
+"W+    c #A60601",
+"X+    c #720000",
+"Y+    c #890101",
+"Z+    c #A30303",
+"`+    c #A20404",
+" @    c #A30404",
+".@    c #B91616",
+"+@    c #B71313",
+"@@    c #CD2116",
+"#@    c #CB1F0B",
+"$@    c #CC4003",
+"%@    c #D38D00",
+"&@    c #D59500",
+"*@    c #CA3E00",
+"=@    c #B71000",
+"-@    c #AF0B00",
+";@    c #AD0A00",
+">@    c #A40500",
+",@    c #A30400",
+"'@    c #A30300",
+")@    c #A40400",
+"!@    c #A50500",
+"~@    c #AA0700",
+"{@    c #AC0800",
+"]@    c #A30500",
+"^@    c #2A0000",
+"/@    c #740303",
+"(@    c #980303",
+"_@    c #9E0202",
+":@    c #B40303",
+"<@    c #A20303",
+"[@    c #A30505",
+"}@    c #A00404",
+"|@    c #AF0A00",
+"1@    c #B61702",
+"2@    c #CC4E03",
+"3@    c #D28300",
+"4@    c #D28700",
+"5@    c #C24200",
+"6@    c #A40900",
+"7@    c #2D2D00",
+"8@    c #302000",
+"9@    c #5E0803",
+"0@    c #820A0A",
+"a@    c #890707",
+"b@    c #9E0303",
+"c@    c #950202",
+"d@    c #840000",
+"e@    c #A30401",
+"f@    c #AE1303",
+"g@    c #C93E03",
+"h@    c #202003",
+"i@    c #1D1C0B",
+"j@    c #221C09",
+"k@    c #282001",
+"l@    c #3B2710",
+"m@    c #640B0A",
+"n@    c #9B0505",
+"o@    c #990303",
+"p@    c #A20808",
+"q@    c #A00505",
+"r@    c #A10707",
+"s@    c #A00606",
+"t@    c #950505",
+"u@    c #9E0707",
+"v@    c #990B01",
+"w@    c #232302",
+"x@    c #0F0F53",
+"y@    c #0A0A5A",
+"z@    c #0B0B5D",
+"A@    c #0A0A57",
+"B@    c #080837",
+"C@    c #151434",
+"D@    c #1D1522",
+"E@    c #211226",
+"F@    c #21132D",
+"G@    c #39170A",
+"H@    c #441C05",
+"I@    c #451C02",
+"J@    c #46464A",
+"K@    c #343462",
+"L@    c #272796",
+"M@    c #252599",
+"N@    c #191964",
+"O@    c #0D0D3D",
+"P@    c #0A0A3A",
+"Q@    c #0A0A54",
+"R@    c #0B0B62",
+"S@    c #0C0C63",
+"T@    c #0C0C62",
+"U@    c #0C0C61",
+"V@    c #070745",
+"W@    c #252501",
+"X@    c #3B3B5C",
+"Y@    c #181886",
+"Z@    c #2424C8",
+"`@    c #2222C2",
+" #    c #1C1CA7",
+".#    c #101071",
+"+#    c #0B0B5E",
+"@#    c #080851",
+"##    c #090952",
+"$#    c #18182B",
+"%#    c #313161",
+"&#    c #1C1C9A",
+"*#    c #2525C9",
+"=#    c #191998",
+"-#    c #0D0D68",
+";#    c #0D0D66",
+">#    c #08084E",
+",#    c #0A0A56",
+"'#    c #09092D",
+")#    c #1E1E16",
+"!#    c #404050",
+"~#    c #1A1A6E",
+"{#    c #1D1D9D",
+"]#    c #1E1EA7",
+"^#    c #2222BC",
+"/#    c #2222BA",
+"(#    c #131380",
+"_#    c #080849",
+":#    c #000021",
+"<#    c #10101E",
+"[#    c #17170D",
+"}#    c #1C1C05",
+"|#    c #212100",
+"1#    c #2B2B00",
+"                                                                                                                                ",
+"                                                    . . . . . . . . . . . .                                                     ",
+"                                            . . . . . . . . . . . . . . . . . . . .                                             ",
+"                                        . . . . . . . . . . . . . . . . . . . . . . . .                                         ",
+"                                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                   ",
+"                                . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                 ",
+"                            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                             ",
+"                          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                           ",
+"                      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                       ",
+"                    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                     ",
+"                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                   ",
+"                . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                 ",
+"              . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               ",
+"            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             ",
+"            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             ",
+"          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           ",
+"        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         ",
+"        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         ",
+"      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       ",
+"      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       ",
+"    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     ",
+"    . . . . . . . . . . . + + + + + + + + + + + + + + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     ",
+"    . . . . . . . . . . . + @ # $ % & * * = - - ; > , ' ) ! + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     ",
+"  . . . . . . . . . . . . + ~ - - { { { { { { { ] ] - ^ / ( _ + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"  . . . . . . . . . . . . + : < [ } ] ] - ] * | ] ] { { ] | 1 2 + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"  . . . . . . . . . . . . + 3 4 5 6 7 8 9 0 ] ] { a b ^ - - c d e + . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"  . . . . . . . . . . . . . + + + + + + f g h i j k l m n o p q r s + + . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+". . . . . . . . . . . . . . . . . . . . + t u v w x y z A B C D E F G H + + . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . + I J K K L M N O P Q R S T U T V W + + + + + + . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . + X Y Z `  ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.+ + + + + + + + . . . . . . . . . . . . ",
+". . . . . . . . . . . . . + + + + + + + ].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.+ + . . . . . . . . . . ",
+". . . . . . . . . . . . . + m.n.o.p.q.r.s.t.u.v.w.{ x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.W.+ . . . . . . . . . ",
+". . . . . . . . . . . . . + Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+!+!+~+{+]+^+^+/+{+(+(+_+:+<+<+[+W.X.X.}+|+1++ . . . . . . . . ",
+". . . . . . . . . . . . . + + + + + + + 2+3+4+5+6+7+8+9+0+a+b+c+d+e+e+X.X.f+g+g+h+{+e+i+W.j+k+l+m+n+o+p+q+r+s+s+t+. . . . . . . ",
+". . . . . . . . . . . . . . . . . . . + u+v+w+w+w+w+w+x+x+y+z+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W++ . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . + X+Y+v+w+w+w+Z+x+`+ @y+y+`+.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@,@!@~@{@)@]@+ . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . + ^@/@(@_@w+:@<@z+z+<@[@z+}@ @|@1@2@3@4@5@6@+ + + + + + + + + + + + . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . + 7@8@9@0@a@ @w+b@z+y+[@`+c@d@e@f@g@3@+ + + . . . . . . . . . . . . . . . . . . . . . . ",
+"  . . . . . . . . . . . . . . . . . . . + h@i@j@k@l@m@n@o@p@q@r@s@t@u@v@+ + + . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"  . . . . . . . . . . . . . + + + + + + w@x@y@z@A@B@C@D@E@F@G@H@I@+ + + . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"  . . . . . . . . . . . . + J@K@L@M@N@O@P@Q@R@S@S@T@S@U@T@T@V@W@+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"  . . . . . . . . . . . . + X@Y@Z@i `@ #.#S@+#y@@###U@U@T@+#$#+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   ",
+"    . . . . . . . . . . . + %#&#| Z@Z@*#=#-#;#S@z@>#,#V@'#)#+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     ",
+"    . . . . . . . . . . . + !#~#{#]#^#/#c (#_#:#<#[#}#|#1#+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     ",
+"    . . . . . . . . . . . + + + + + + + + + + + + + + + + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     ",
+"      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       ",
+"      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       ",
+"        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         ",
+"        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         ",
+"          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           ",
+"            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             ",
+"            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .             ",
+"              . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .               ",
+"                . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                 ",
+"                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                   ",
+"                    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                     ",
+"                      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                       ",
+"                          . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                           ",
+"                            . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                             ",
+"                                . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                 ",
+"                                  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                   ",
+"                                        . . . . . . . . . . . . . . . . . . . . . . . .                                         ",
+"                                            . . . . . . . . . . . . . . . . . . . .                                             ",
+"                                                    . . . . . . . . . . . .                                                     "};
diff --git a/data/icons/spacerocks.xpm b/data/icons/spacerocks.xpm
new file mode 100644 (file)
index 0000000..aebeefc
--- /dev/null
@@ -0,0 +1,424 @@
+/* XPM */
+static char * spacerocks_xpm[] = {
+"44 24 397 2",
+"      c None",
+".     c #000000",
+"+     c #383869",
+"@     c #1D1DA3",
+"#     c #1D1DA1",
+"$     c #2121B7",
+"%     c #2424C7",
+"&     c #2525CE",
+"*     c #2525CF",
+"=     c #2626CF",
+"-     c #2727CC",
+";     c #2727CA",
+">     c #2E2EA7",
+",     c #39396B",
+"'     c #42425D",
+")     c #434348",
+"!     c #24249E",
+"~     c #2626D1",
+"{     c #2626D0",
+"]     c #2424C5",
+"^     c #2525BB",
+"/     c #343493",
+"(     c #414160",
+"_     c #2A2A8C",
+":     c #2121B5",
+"<     c #2323C0",
+"[     c #2424C6",
+"}     c #2525CD",
+"|     c #2E2EAB",
+"1     c #42425B",
+"2     c #404055",
+"3     c #262677",
+"4     c #1B1B87",
+"5     c #29297E",
+"6     c #2A2A95",
+"7     c #2828B6",
+"8     c #2828C0",
+"9     c #2525C3",
+"0     c #2525CB",
+"a     c #2323C1",
+"b     c #2020B2",
+"c     c #3E3E63",
+"d     c #474747",
+"e     c #3E3E68",
+"f     c #353583",
+"g     c #2222BD",
+"h     c #2525CC",
+"i     c #2323C3",
+"j     c #1F1F77",
+"k     c #3D3D58",
+"l     c #3B3B69",
+"m     c #353592",
+"n     c #443FA0",
+"o     c #746597",
+"p     c #736F78",
+"q     c #494D57",
+"r     c #353942",
+"s     c #43434A",
+"t     c #3A3A67",
+"u     c #38387F",
+"v     c #5F4E7C",
+"w     c #D9939A",
+"x     c #FEC2C2",
+"y     c #F3BEC0",
+"z     c #B99099",
+"A     c #B9949E",
+"B     c #F29FA0",
+"C     c #B8717B",
+"D     c #222141",
+"E     c #161B3D",
+"F     c #2B2846",
+"G     c #1F2B46",
+"H     c #5D5555",
+"I     c #F09393",
+"J     c #FFACAC",
+"K     c #FEB7B7",
+"L     c #FFC6C6",
+"M     c #C098A1",
+"N     c #303250",
+"O     c #30314F",
+"P     c #BF737C",
+"Q     c #B86E78",
+"R     c #13193C",
+"S     c #001035",
+"T     c #011035",
+"U     c #081538",
+"V     c #2A303E",
+"W     c #E8A9BA",
+"X     c #EEB6C4",
+"Y     c #F2C6D0",
+"Z     c #F7B7BD",
+"`     c #FEBBBC",
+" .    c #FF9B9B",
+"..    c #E48387",
+"+.    c #855365",
+"@.    c #845264",
+"#.    c #E07E82",
+"$.    c #EB7E7F",
+"%.    c #9E5663",
+"&.    c #432D48",
+"*.    c #171A3B",
+"=.    c #021136",
+"-.    c #031136",
+";.    c #604557",
+">.    c #EFC089",
+",.    c #EFC372",
+"'.    c #EE9888",
+").    c #E08383",
+"!.    c #D27B7B",
+"~.    c #DC8282",
+"{.    c #3F3FCE",
+"].    c #9488DD",
+"^.    c #BAACE4",
+"/.    c #B4A5E2",
+"(.    c #B497D1",
+"_.    c #9B7BB8",
+":.    c #CC95BC",
+"<.    c #D592B0",
+"[.    c #CA859F",
+"}.    c #CF819A",
+"|.    c #E47784",
+"1.    c #EE6466",
+"2.    c #EE5B5B",
+"3.    c #E85657",
+"4.    c #BC4C54",
+"5.    c #703548",
+"6.    c #6F394D",
+"7.    c #CF8263",
+"8.    c #FAE26D",
+"9.    c #FDE672",
+"0.    c #F8A17B",
+"a.    c #F57E7E",
+"b.    c #F37777",
+"c.    c #F67F7F",
+"d.    c #FA8A8A",
+"e.    c #FD8DA1",
+"f.    c #FD86C8",
+"g.    c #FC78C2",
+"h.    c #F8869B",
+"i.    c #FD9090",
+"j.    c #FF9191",
+"k.    c #E08888",
+"l.    c #19197E",
+"m.    c #1A1A7D",
+"n.    c #1E1E7D",
+"o.    c #282889",
+"p.    c #3131C2",
+"q.    c #3535CD",
+"r.    c #3333CA",
+"s.    c #3232C9",
+"t.    c #3232C5",
+"u.    c #2E2EC9",
+"v.    c #2828CF",
+"w.    c #2424D3",
+"x.    c #2C2CD1",
+"y.    c #2F2FC6",
+"z.    c #2D2CAC",
+"A.    c #8A4194",
+"B.    c #CC4351",
+"C.    c #DD4343",
+"D.    c #EC4444",
+"E.    c #ED4949",
+"F.    c #E84B4B",
+"G.    c #E94D4D",
+"H.    c #EE7543",
+"I.    c #FBD637",
+"J.    c #FBD639",
+"K.    c #F07846",
+"L.    c #EC4D4D",
+"M.    c #ED4C4C",
+"N.    c #EE4B4B",
+"O.    c #EE4F4F",
+"P.    c #F24A6B",
+"Q.    c #FC3EA9",
+"R.    c #FC40AA",
+"S.    c #F44466",
+"T.    c #F24343",
+"U.    c #F24242",
+"V.    c #F14141",
+"W.    c #F24141",
+"X.    c #6A6AA1",
+"Y.    c #6D6D9F",
+"Z.    c #6E6E9E",
+"`.    c #717199",
+" +    c #676799",
+".+    c #68689A",
+"++    c #656290",
+"@+    c #725A8A",
+"#+    c #7C5182",
+"$+    c #7F558C",
+"%+    c #764E98",
+"&+    c #6C4FA0",
+"*+    c #6548A7",
+"=+    c #4F43BF",
+"-+    c #413CCB",
+";+    c #4938B8",
+">+    c #5C4394",
+",+    c #5F3A43",
+"'+    c #CF4040",
+")+    c #E94141",
+"!+    c #ED4141",
+"~+    c #EF4141",
+"{+    c #F2693D",
+"]+    c #FACA31",
+"^+    c #F1693D",
+"/+    c #ED4242",
+"(+    c #EE4141",
+"_+    c #F33D61",
+":+    c #FC33A7",
+"<+    c #F43D61",
+"[+    c #F14140",
+"}+    c #EF3E3C",
+"|+    c #EB3A35",
+"1+    c #732222",
+"2+    c #790F0F",
+"3+    c #900909",
+"4+    c #9A0707",
+"5+    c #9B0606",
+"6+    c #970A0A",
+"7+    c #95080C",
+"8+    c #860A1A",
+"9+    c #860C1E",
+"0+    c #9D0C1A",
+"a+    c #AE1216",
+"b+    c #B31919",
+"c+    c #DD3737",
+"d+    c #F04141",
+"e+    c #F4763C",
+"f+    c #FDDE35",
+"g+    c #F5763D",
+"h+    c #EC4141",
+"i+    c #F43D60",
+"j+    c #F93198",
+"k+    c #F62F8F",
+"l+    c #EE3856",
+"m+    c #E53B37",
+"n+    c #E13831",
+"o+    c #E6372F",
+"p+    c #E23228",
+"q+    c #D52819",
+"r+    c #C21C0D",
+"s+    c #1B1700",
+"t+    c #8F0202",
+"u+    c #9B0202",
+"v+    c #9F0202",
+"w+    c #A20202",
+"x+    c #A00303",
+"y+    c #A10303",
+"z+    c #BE1919",
+"A+    c #E93A3A",
+"B+    c #E53737",
+"C+    c #EF3F3F",
+"D+    c #EF4040",
+"E+    c #F06B35",
+"F+    c #EEC621",
+"G+    c #E7BF18",
+"H+    c #D85311",
+"I+    c #C61F0B",
+"J+    c #B71E09",
+"K+    c #BF1D0D",
+"L+    c #C01A0E",
+"M+    c #BE1413",
+"N+    c #C40B14",
+"O+    c #C60A13",
+"P+    c #BB110D",
+"Q+    c #B71606",
+"R+    c #B91905",
+"S+    c #AE1A03",
+"T+    c #AB1402",
+"U+    c #B11102",
+"V+    c #A60601",
+"W+    c #720000",
+"X+    c #890101",
+"Y+    c #A30303",
+"Z+    c #A20404",
+"`+    c #A30404",
+" @    c #B91616",
+".@    c #B71313",
+"+@    c #CD2116",
+"@@    c #CB1F0B",
+"#@    c #CC4003",
+"$@    c #D38D00",
+"%@    c #D59500",
+"&@    c #CA3E00",
+"*@    c #B71000",
+"=@    c #AF0B00",
+"-@    c #AD0A00",
+";@    c #A40500",
+">@    c #A30400",
+",@    c #A30300",
+"'@    c #A40400",
+")@    c #A50500",
+"!@    c #AA0700",
+"~@    c #AC0800",
+"{@    c #A30500",
+"]@    c #2A0000",
+"^@    c #740303",
+"/@    c #980303",
+"(@    c #9E0202",
+"_@    c #B40303",
+":@    c #A20303",
+"<@    c #A30505",
+"[@    c #A00404",
+"}@    c #AF0A00",
+"|@    c #B61702",
+"1@    c #CC4E03",
+"2@    c #D28300",
+"3@    c #D28700",
+"4@    c #C24200",
+"5@    c #A40900",
+"6@    c #2D2D00",
+"7@    c #302000",
+"8@    c #5E0803",
+"9@    c #820A0A",
+"0@    c #890707",
+"a@    c #9E0303",
+"b@    c #950202",
+"c@    c #840000",
+"d@    c #A30401",
+"e@    c #AE1303",
+"f@    c #C93E03",
+"g@    c #202003",
+"h@    c #1D1C0B",
+"i@    c #221C09",
+"j@    c #282001",
+"k@    c #3B2710",
+"l@    c #640B0A",
+"m@    c #9B0505",
+"n@    c #990303",
+"o@    c #A20808",
+"p@    c #A00505",
+"q@    c #A10707",
+"r@    c #A00606",
+"s@    c #950505",
+"t@    c #9E0707",
+"u@    c #990B01",
+"v@    c #232302",
+"w@    c #0F0F53",
+"x@    c #0A0A5A",
+"y@    c #0B0B5D",
+"z@    c #0A0A57",
+"A@    c #080837",
+"B@    c #151434",
+"C@    c #1D1522",
+"D@    c #211226",
+"E@    c #21132D",
+"F@    c #39170A",
+"G@    c #441C05",
+"H@    c #451C02",
+"I@    c #46464A",
+"J@    c #343462",
+"K@    c #272796",
+"L@    c #252599",
+"M@    c #191964",
+"N@    c #0D0D3D",
+"O@    c #0A0A3A",
+"P@    c #0A0A54",
+"Q@    c #0B0B62",
+"R@    c #0C0C63",
+"S@    c #0C0C62",
+"T@    c #0C0C61",
+"U@    c #070745",
+"V@    c #252501",
+"W@    c #3B3B5C",
+"X@    c #181886",
+"Y@    c #2424C8",
+"Z@    c #2222C2",
+"`@    c #1C1CA7",
+" #    c #101071",
+".#    c #0B0B5E",
+"+#    c #080851",
+"@#    c #090952",
+"##    c #18182B",
+"$#    c #313161",
+"%#    c #1C1C9A",
+"&#    c #2525C9",
+"*#    c #191998",
+"=#    c #0D0D68",
+"-#    c #0D0D66",
+";#    c #08084E",
+">#    c #0A0A56",
+",#    c #09092D",
+"'#    c #1E1E16",
+")#    c #404050",
+"!#    c #1A1A6E",
+"~#    c #1D1D9D",
+"{#    c #1E1EA7",
+"]#    c #2222BC",
+"^#    c #2222BA",
+"/#    c #131380",
+"(#    c #080849",
+"_#    c #000021",
+":#    c #10101E",
+"<#    c #17170D",
+"[#    c #1C1C05",
+"}#    c #212100",
+"|#    c #2B2B00",
+". . . . . . . . . . . . . . . . .                                                       ",
+". + @ # $ % & & * = = - ; > , ' ) .                                                     ",
+". ! = = ~ ~ ~ ~ ~ ~ ~ { { = ] ^ / ( .                                                   ",
+". _ : < [ { { = { & } { { ~ ~ { } | 1 .                                                 ",
+". 2 3 4 5 6 7 8 9 { { ~ 0 a ] = = b c d .                                               ",
+"  . . . . . . e f g h i j k l m n o p q r . .                                           ",
+"              . s t u v w x y z A B C D E F G . .                                       ",
+"              . H I J J K L M N O P Q R S T S U V . . . . . .                           ",
+"              . W X Y Z `  ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.. . . . . . . .           ",
+". . . . . . . {.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.. .       ",
+". l.m.n.o.p.q.r.s.t.u.v.~ w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.V..     ",
+". X.Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+)+!+~+{+]+]+^+~+/+/+(+_+:+:+<+V.W.W.[+}+|+.   ",
+". . . . . . . 1+2+3+4+5+6+7+8+9+0+a+b+c+d+d+W.W.e+f+f+g+~+d+h+V.i+j+k+l+m+n+o+p+q+r+r+s+",
+"            . t+u+v+v+v+v+v+w+w+x+y+y+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+.   ",
+"            . W+X+u+v+v+v+Y+w+Z+`+x+x+Z+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@>@)@!@~@'@{@.     ",
+"              . ]@^@/@(@v+_@:@y+y+:@<@y+[@`+}@|@1@2@3@4@5@. . . . . . . . . . . .       ",
+"              . 6@7@8@9@0@`+v+a@y+x+<@Z+b@c@d@e@f@2@. . .                               ",
+"              . g@h@i@j@k@l@m@n@o@p@q@r@s@t@u@. . .                                     ",
+"  . . . . . . v@w@x@y@z@A@B@C@D@E@F@G@H@. . .                                           ",
+". I@J@K@L@M@N@O@P@Q@R@R@S@R@T@S@S@U@V@.                                                 ",
+". W@X@Y@h Z@`@ #R@.#x@+#@#T@T@S@.###.                                                   ",
+". $#%#} Y@Y@&#*#=#-#R@y@;#>#U@,#'#.                                                     ",
+". )#!#~#{#]#^#b /#(#_#:#<#[#}#|#.                                                       ",
+". . . . . . . . . . . . . . . .                                                         "};
diff --git a/data/indicators/life.png b/data/indicators/life.png
new file mode 100644 (file)
index 0000000..269ebad
Binary files /dev/null and b/data/indicators/life.png differ
diff --git a/data/music/4est_fulla3s.mod b/data/music/4est_fulla3s.mod
new file mode 100644 (file)
index 0000000..f84b409
Binary files /dev/null and b/data/music/4est_fulla3s.mod differ
diff --git a/data/music/getzznew.mod b/data/music/getzznew.mod
new file mode 100644 (file)
index 0000000..533f882
Binary files /dev/null and b/data/music/getzznew.mod differ
diff --git a/data/music/magic.mod b/data/music/magic.mod
new file mode 100644 (file)
index 0000000..46c7b02
Binary files /dev/null and b/data/music/magic.mod differ
diff --git a/data/sounds/boom.wav b/data/sounds/boom.wav
new file mode 100644 (file)
index 0000000..60226fd
Binary files /dev/null and b/data/sounds/boom.wav differ
diff --git a/data/sounds/booom.wav b/data/sounds/booom.wav
new file mode 100644 (file)
index 0000000..def49aa
Binary files /dev/null and b/data/sounds/booom.wav differ
diff --git a/data/sounds/bzboom.wav b/data/sounds/bzboom.wav
new file mode 100644 (file)
index 0000000..e6f4859
Binary files /dev/null and b/data/sounds/bzboom.wav differ
diff --git a/data/sounds/cboom.wav b/data/sounds/cboom.wav
new file mode 100644 (file)
index 0000000..cd162fc
Binary files /dev/null and b/data/sounds/cboom.wav differ
diff --git a/data/sprites/.xvpics/ship.png b/data/sprites/.xvpics/ship.png
new file mode 100644 (file)
index 0000000..cfc098a
Binary files /dev/null and b/data/sprites/.xvpics/ship.png differ
diff --git a/data/sprites/deadrock0.png b/data/sprites/deadrock0.png
new file mode 100644 (file)
index 0000000..62cca53
Binary files /dev/null and b/data/sprites/deadrock0.png differ
diff --git a/data/sprites/deadrock1.png b/data/sprites/deadrock1.png
new file mode 100644 (file)
index 0000000..8ab09d6
Binary files /dev/null and b/data/sprites/deadrock1.png differ
diff --git a/data/sprites/deadrock2.png b/data/sprites/deadrock2.png
new file mode 100644 (file)
index 0000000..a449c4b
Binary files /dev/null and b/data/sprites/deadrock2.png differ
diff --git a/data/sprites/deadrock3.png b/data/sprites/deadrock3.png
new file mode 100644 (file)
index 0000000..8f8c943
Binary files /dev/null and b/data/sprites/deadrock3.png differ
diff --git a/data/sprites/deadrock4.png b/data/sprites/deadrock4.png
new file mode 100644 (file)
index 0000000..f8dcbac
Binary files /dev/null and b/data/sprites/deadrock4.png differ
diff --git a/data/sprites/deadrock5.png b/data/sprites/deadrock5.png
new file mode 100644 (file)
index 0000000..2e9d22a
Binary files /dev/null and b/data/sprites/deadrock5.png differ
diff --git a/data/sprites/rock0.png b/data/sprites/rock0.png
new file mode 100644 (file)
index 0000000..809aab2
Binary files /dev/null and b/data/sprites/rock0.png differ
diff --git a/data/sprites/rock1.png b/data/sprites/rock1.png
new file mode 100644 (file)
index 0000000..7cb937d
Binary files /dev/null and b/data/sprites/rock1.png differ
diff --git a/data/sprites/rock2.png b/data/sprites/rock2.png
new file mode 100644 (file)
index 0000000..23b2e8c
Binary files /dev/null and b/data/sprites/rock2.png differ
diff --git a/data/sprites/rock3.png b/data/sprites/rock3.png
new file mode 100644 (file)
index 0000000..e233668
Binary files /dev/null and b/data/sprites/rock3.png differ
diff --git a/data/sprites/rock4.png b/data/sprites/rock4.png
new file mode 100644 (file)
index 0000000..51f9a89
Binary files /dev/null and b/data/sprites/rock4.png differ
diff --git a/data/sprites/rock5.png b/data/sprites/rock5.png
new file mode 100644 (file)
index 0000000..b70f502
Binary files /dev/null and b/data/sprites/rock5.png differ
diff --git a/data/sprites/ship.png b/data/sprites/ship.png
new file mode 100644 (file)
index 0000000..be23002
Binary files /dev/null and b/data/sprites/ship.png differ
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..04f6503
--- /dev/null
+++ b/main.c
@@ -0,0 +1,1477 @@
+/*
+    Space Rocks! Avoid the rocks as long as you can! {{{
+    Copyright (C) 2001  Paul Holt <pad@pcholt.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    }}}
+*/
+#undef DEBUG
+
+extern int font_height;
+void clearBuffer();
+
+// includes {{{
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdarg.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "SFont.h"
+// }}}
+// constants {{{
+#define XSIZE 640
+#define YSIZE 480
+#define NROCKS 6    // Number of rock image files, not number of rocks visible
+#define MAXROCKS 120 // MAX Rocks
+#define MAXROCKHEIGHT 100
+#define ROCKRATE 2
+#define MAXBLACKPOINTS 500
+#define MAXENGINEDOTS 5000
+#define MAXBANGDOTS 50000
+#define MAXSPACEDOTS 2000
+#define W 100
+#define M 255
+#define BIG_FONT_FILE "fonts/score.png"
+// }}}
+// macros {{{
+#define CONDERROR(a) if ((a)) {initerror=strdup(SDL_GetError());return 1;}
+#define NULLERROR(a) CONDERROR((a)==NULL)
+// }}}
+
+// ************************************* STRUCTS
+struct rock_struct {/*{{{*/
+    // Array of black pixel coordinates. This is scanned 
+    // every frame to see if it's still black, and as
+    // soon as it isn't we BLOW UP
+    float x,y,xvel,yvel;
+    int active;
+    SDL_Surface *image;
+    int type_number;
+    float heat;
+}; /*}}}*/
+struct black_point_struct {/*{{{*/
+    int x,y;
+};/*}}}*/
+struct bangdots {/*{{{*/
+    // Bang dots have the same colour as shield dots.
+    // Bang dots get darker as they age.
+    // Some are coloured the same as the ex-ship.
+    float x,y,dx,dy;
+    Uint16 c; // when zero, use heatcolor[bangdotlife]
+    float life;        // When reduced to 0, set active=0
+    int active;
+    float decay;// Amount by which to reduce life each time dot is drawn
+};/*}}}*/
+struct enginedots {/*{{{*/
+    // Engine dots stream out the back of the ship, getting darker as they go.
+    int active;
+    float x,y,dx,dy;
+    // The life of an engine dot 
+    // is a number starting at between 0 and 50 and counting backward.
+    float life;        // When reduced to 0, set active=0
+};/*}}}*/
+struct spacedot {/*{{{*/
+    // Space dots are harmless background items
+    // All are active. When one falls off the edge, another is created at the start.
+    float x,y,dx;
+    Uint16 color;
+};/*}}}*/
+// High score table {{{
+struct highscore {
+    int score;
+    char *name;
+    int allocated;
+} high[] = {
+    {13000,"Pad",0},
+    {12500,"Pad",0},
+    {6500,"Pad",0},
+    {5000,"Pad",0},
+    {3000,"Pad",0},
+    {2500,"Pad",0},
+    {2000,"Pad",0},
+    {1500,"Pad",0}
+};
+// }}}
+
+// ************************************* VARS
+// SDL_Surface global variables {{{
+SDL_Surface 
+    *surf_screen,      // Screen
+    *surf_b_rock,      // Title element "rock"
+    *surf_b_dodgers,   // Title element "dodgers"
+    *surf_b_game,      // Title element "game"
+    *surf_b_over,      // Title element "over"
+    *surf_ship,                // Spaceship element
+    *surf_life,        // Indicator of number of ships remaining
+    *surf_rock[NROCKS],        // THE ROCKS
+    *surf_deadrock[NROCKS],    // THE DEAD ROCKS
+    *surf_font_big;    // The big font
+// }}}
+// Structure global variables {{{
+struct enginedots edot[MAXENGINEDOTS], *dotptr=edot;
+struct rock_struct rock[MAXROCKS], *rockptr=rock;
+struct black_point_struct black_point[MAXBLACKPOINTS], *blackptr=black_point;
+struct bangdots bdot[MAXBANGDOTS], *bdotptr=bdot;
+struct spacedot sdot[MAXSPACEDOTS];
+// }}}
+// Other global variables {{{
+char topline[1024];
+char *initerror = "";
+char name[1024], debug1[1024];
+
+float xship,yship = 240.0;     // X position, 0..XSIZE
+float xvel,yvel;       // Change in X position per tick.
+float rockrate,rockspeed;
+float movementrate;
+float shieldlevel, shieldpulse=0;
+float yscroll;
+
+int nships,score,initticks,ticks_since_last, last_ticks;
+int initialshield, gameover, fast;
+int countdown=0;
+int maneuver = 0;
+int laser = 0;
+int shieldsup=0;
+int oss_sound_flag=0;
+int tail_plume=0;  // display big engine at the back?
+int friction=0;    // should there be friction?
+int scorerank;
+float fadetimer=0,faderate;
+
+int pausedown=0,paused=0;
+
+// bangdot start (bd1) and end (bd2) position:
+int bd1=0, bd2=0;
+
+int xoffset[NROCKS][MAXROCKHEIGHT];
+
+enum states {/*{{{*/
+    TITLE_PAGE,
+    GAMEPLAY,
+    DEAD_PAUSE,
+    GAME_OVER,
+    HIGH_SCORE_ENTRY,
+    HIGH_SCORE_DISPLAY,
+    DEMO
+};/*}}}*/
+enum states state=TITLE_PAGE;
+float state_timeout = 600.0;
+
+const int fakesin[] = {0,1,0,-1};
+const int fakecos[] = {1,0,-1,0};
+#define NSEQUENCE 5
+char *sequence[] = {
+    "Press SPACE to start",
+    "http://spacerocks.sourceforge.net",
+    "G'day tesmako",
+    "G'day overcode",
+    "S=shield D=laser"
+};
+
+int bangdotlife, nbangdots;
+Uint16 heatcolor[W*3];
+
+char *data_dir;
+extern char *optarg;
+extern int optind, opterr, optopt;
+// }}}
+
+// ************************************* FUNCS
+#ifdef DOTCOLLISION
+int dotcollision(SDL_Surface *s) {/*{{{*/
+    int i,j,m;
+    Uint16 *rawpixel, *r;
+
+    /*
+     * Kill all the dots which collide with other objects.
+     * This does not work, it's probably in the wrong place or something.
+     */
+    SDL_LockSurface(s);
+    rawpixel = (Uint16 *) s->pixels;
+    if (bangdotlife > 0 && bangdotlife<80) {
+       for (i=0; i<nbangdots; i++) {
+           if (bdot[i].x>0 && bdot[i].x<XSIZE && bdot[i].y>0 && bdot[i].y<YSIZE) {
+               r = &rawpixel[(int)(s->pitch/2*(int)(bdot[i].y))+(int)(bdot[i].x)];
+               if (*r != (bdot[i].c ? bdot[i].c : heatcolor[bangdotlife*2]))
+                   bdot[i].active=0;
+           }
+       }
+    }
+    SDL_UnlockSurface(s);
+
+    return;
+}/*}}}*/
+#endif
+
+FILE *hs_fopen(char *mode) {/*{{{*/
+    FILE *f;
+    mode_t mask;
+    mask = umask(0111);
+    if (f=fopen("/usr/share/rockdodger/.highscore",mode)) {
+       umask(mask);
+       return f;
+    }
+    else {
+       char s[1024];
+       umask(0177);
+       sprintf(s,"%s/.rockdodger_high",getenv("HOME"));
+       if (f=fopen(s,mode)) {
+           umask(mask);
+           return f;
+       }
+       else {
+           umask(mask);
+           return 0;
+       }
+    }
+}/*}}}*/
+void read_high_score_table() {/*{{{*/
+    FILE *f;
+    int i;
+    if (f=hs_fopen("r")) {
+       // If the file exists, read from it
+       for (i=0; i<8; i++) {
+           char s[1024];
+           int highscore;
+           if (fscanf (f, "%d %[^\n]", &highscore, s)!=2)
+               break;
+           if (high[i].allocated)
+               free(high[i].name);
+           high[i].name = strdup(s);
+           high[i].score = highscore;
+           high[i].allocated = 1;
+       }
+       fclose(f);
+    }
+}/*}}}*/
+void write_high_score_table() {/*{{{*/
+    FILE *f;
+    int i;
+    if (f=hs_fopen("w")) {
+       // If the file exists, write to it
+       for (i=0; i<8; i++) {
+           fprintf (f, "%d %s\n", high[i].score, high[i].name);
+       }
+       fclose(f);
+    }
+}/*}}}*/
+void snprintscore(char *s, size_t n, int score) {/*{{{*/
+       int min = score/60000;
+       int sec = score/1000%60;
+       int tenths = score%1000/100;
+       if(min) {
+               snprintf(s, n, "%2d:%.2d.%d", min, sec, tenths);
+       } else {
+               snprintf(s, n, "   %2d.%d", sec, tenths);
+       }
+}/*}}}*/
+float rnd() {/*{{{*/
+    return (float)random()/(float)RAND_MAX;
+}/*}}}*/
+void init_engine_dots() {/*{{{*/
+    int i;
+    for (i=0; i<MAXENGINEDOTS; i++) {
+       edot[i].active=0;
+    }
+}/*}}}*/
+void init_space_dots() {/*{{{*/
+    int i,intensity;
+    for (i=0; i<MAXSPACEDOTS; i++) {
+       float r;
+
+       sdot[i].x = rnd()*(XSIZE-5);
+       sdot[i].y = rnd()*(YSIZE-5);
+
+       r = rnd()*rnd();
+
+       sdot[i].dx = -r*4;
+       // -1/((1-r)+.3);
+       intensity = (int)(r*180+70);
+       sdot[i].color = SDL_MapRGB(surf_screen->format,intensity,intensity,intensity);
+
+    }
+}/*}}}*/
+
+int drawlaser() {/*{{{*/
+    int i,xc,hitrock;
+    Uint16 c, *rawpixel;
+
+    hitrock = -1;
+    xc = XSIZE;
+    // let xc = x coordinate of the collision between the laser and a space rock
+    // 1. Calculate xc and determine the asteroid that was hit
+    for (i=0; i<MAXROCKS; i++) {
+       if (rock[i].active) {
+           if (yship+12>rock[i].y && yship+12<rock[i].y+rock[i].image->h && xship+32<rock[i].x+(rock[i].image->w/2) && rock[i].x+(rock[i].image->w/2) < xc) {
+               xc = rock[i].x+(rock[i].image->w/2);
+               hitrock = i;
+           }
+       }
+    }
+
+    if (hitrock>=0) {
+       rock[hitrock].heat += movementrate*3;
+    }
+
+    // Plot a number of random dots between xship and XSIZE
+    SDL_LockSurface(surf_screen);
+    rawpixel = (Uint16 *) surf_screen->pixels;
+    c = SDL_MapRGB(surf_ship->format,rnd()*128,128+rnd()*120,rnd()*128);
+
+    for (i=0; i<(xc-xship)*5; i+=10) {
+       int x,y;
+       x = rnd()*(xc-(xship+32))+xship+32;
+       y = yship+12+(rnd()-0.5)*1.5;
+       rawpixel[surf_screen->pitch/2*y+x]=c;
+    }
+
+    SDL_UnlockSurface(surf_screen);
+}/*}}}*/
+
+
+int makebangdots(int xbang, int ybang, int xvel, int yvel, SDL_Surface *s, int power) {/*{{{*/
+
+    // TODO - stop generating dots after a certain amount of time has passed, to cope with slower CPUs.
+    // TODO - generate and display dots in a circular buffer
+
+    int i,x,y,n,endcount;
+    Uint16 *rawpixel,c;
+    double theta,r,dx,dy;
+    int begin_generate;
+
+    begin_generate = SDL_GetTicks();
+
+    SDL_LockSurface(s);
+    rawpixel = (Uint16 *) s->pixels;
+
+    //for (n=0; n<=power/2; n++) {
+
+    endcount = 0;
+    while (endcount<3) {
+
+       for (x=0; x<s->w; x++) {
+           for (y=0; y<s->h; y++) {
+               c = rawpixel[s->pitch/2*y+x];
+               if (c && c != SDL_MapRGB(s->format,0,255,0)) {
+
+                   theta = rnd()*M_PI*2;
+
+                   r = 1-(rnd()*rnd());
+
+                   bdot[bd2].dx = (power/50.0)*45.0*cos(theta)*r+xvel;
+                   bdot[bd2].dy = (power/50.0)*45.0*sin(theta)*r+yvel;
+                   bdot[bd2].x = x+xbang;
+                   bdot[bd2].y = y+ybang;
+
+                   // Replace the last few bang dots with the pixels from the exploding object
+                   bdot[bd2].c = (endcount>0)?c:0;
+                   bdot[bd2].life = 100;
+                   bdot[bd2].decay = rnd()*3+1;
+                   bdot[bd2].active = 1;
+
+                   bd2++;
+                   bd2 %= MAXBANGDOTS;
+
+                   // If the circular buffer is filled, who cares? They've had their chance.
+                   //if (bd2==bd1-1) goto exitloop;
+
+               }
+           }
+       }
+
+       if (SDL_GetTicks() - begin_generate > 7) endcount++;
+
+    }
+exitloop:
+
+    SDL_UnlockSurface(s);
+
+}/*}}}*/
+
+void draw_bang_dots(SDL_Surface *s) {/*{{{*/
+    int i;
+    int first_i, last_i;
+    Uint16 *rawpixel;
+    rawpixel = (Uint16 *) s->pixels;
+
+    first_i = -1;
+
+    for (i=bd1; (bd1<=bd2)?(i<bd2):(i>=bd1 && i<bd2); last_i = ++i) {
+
+       i %= MAXBANGDOTS;
+
+       if (bdot[i].x<=0 || bdot[i].x>=XSIZE || bdot[i].y<=0 || bdot[i].y>=YSIZE) {
+           // If the dot has drifted outside the perimeter, kill it
+           bdot[i].active = 0;
+       }
+
+       if (bdot[i].active) {
+
+           //printf("%d %d\n",bd1,bd2);
+
+           if (first_i < 0)
+               first_i = i;
+           //last_i = i+1;
+           rawpixel[(int)(s->pitch/2*(int)(bdot[i].y))+(int)(bdot[i].x)] 
+               = bdot[i].c ? bdot[i].c : heatcolor[(int)(bdot[i].life*3)];
+           bdot[i].life-=bdot[i].decay;
+           bdot[i].x += bdot[i].dx*movementrate;
+           bdot[i].y += bdot[i].dy*movementrate + yscroll;
+
+           if (bdot[i].life<0)
+               bdot[i].active = 0;
+       }
+
+       //printf("/n");
+       //exit(0);
+
+    }
+
+    if (first_i>=0) {
+       bd1 = first_i;
+       bd2 = last_i;
+       //printf("new %d %d\n",bd1,bd2);
+       //fprintf (stderr,"%d - %d\n", bd1,bd2);
+    }
+    else {
+       bd1 = 0;
+       bd2 = 0;
+       //fprintf (stderr,"reset\n");
+    }
+
+}/*}}}*/
+
+
+void draw_space_dots(SDL_Surface *s) {/*{{{*/
+    int i;
+    Uint16 *rawpixel;
+    rawpixel = (Uint16 *) s->pixels;
+
+    for (i=0; i<MAXSPACEDOTS; i++) {
+       if (sdot[i].y<0) sdot[i].y=0;
+       rawpixel[(int)(s->pitch/2*(int)sdot[i].y)+(int)(sdot[i].x)] = sdot[i].color;
+       sdot[i].x += sdot[i].dx*movementrate;
+       sdot[i].y += yscroll;
+       if(sdot[i].y > YSIZE) {
+               sdot[i].y -= YSIZE;
+       } else if(sdot[i].y < 0) {
+               sdot[i].y += YSIZE;
+       }
+       if (sdot[i].x<0)
+           sdot[i].x=XSIZE;
+    }
+}/*}}}*/
+void draw_engine_dots(SDL_Surface *s) {/*{{{*/
+    int i;
+    Uint16 *rawpixel;
+    rawpixel = (Uint16 *) s->pixels;
+
+    for (i=0; i<MAXENGINEDOTS; i++) {
+       if (edot[i].active) {
+           edot[i].x += edot[i].dx*movementrate;
+           edot[i].y += edot[i].dy*movementrate + yscroll;
+           if ((edot[i].life-=movementrate*3)<0 || edot[i].y<0 || edot[i].y>YSIZE)
+               edot[i].active=0;
+           else
+               if (edot[i].x<0 || edot[i].x>XSIZE) {
+                   edot[i].active=0;
+               }
+               else {
+                   int heatindex;
+                   heatindex = edot[i].life * 6;
+                   //rawpixel[(int)(s->pitch/2*(int)(edot[i].y))+(int)(edot[i].x)] = lifecolor[(int)(edot[i].life)];
+                   rawpixel[(int)(s->pitch/2*(int)(edot[i].y))+(int)(edot[i].x)] = heatindex>3*W ? heatcolor[3*W-1] : heatcolor[heatindex];
+               }
+       }
+    }
+}/*}}}*/
+
+void create_engine_dots(int newdots) {
+    int i;
+    double theta,r,dx,dy;
+
+       if(!tail_plume) return;
+
+    if (state==GAMEPLAY)
+       for (i=0; i<newdots*movementrate; i++) {
+           if (dotptr->active==0) {
+
+               theta = rnd()*M_PI*2;
+               r = rnd();
+               dx = cos(theta)*r;
+               dy = sin(theta)*r;
+
+               dotptr->active=1;
+               dotptr->x=xship+surf_ship->w/2-14;
+               dotptr->y=yship+surf_ship->h/2+(rnd()-0.5)*5-1;
+               dotptr->dx=10*(dx-1.5)+xvel;
+               dotptr->dy=1*dy+yvel;
+               dotptr->life=45+rnd(1)*5;
+
+               dotptr++;
+               if (dotptr-edot>=MAXENGINEDOTS) dotptr = edot;
+
+           }
+       }
+}
+
+void create_engine_dots2(int newdots, int m) {
+    int i;
+    double theta, theta2, dx, dy, adx, ady;
+
+    // Don't create fresh engine dots when
+    // the game is not being played and a demo is not beng shown
+    if (state!=GAMEPLAY && state!=DEMO) return;
+
+    for (i=0; i<newdots; i++) {
+       if (dotptr->active==0) {
+
+           theta = rnd()*M_PI*2;
+           theta2 = rnd()*M_PI*2;
+
+       dx = cos(theta) * fabs(cos(theta2));
+           dy = sin(theta) * fabs(cos(theta2));
+           adx = fabs(dx);
+           ady = fabs(dy);
+
+
+           dotptr->active=1;
+           dotptr->x=xship+surf_ship->w/2+(rnd()-0.5)*3;
+           dotptr->y=yship+surf_ship->h/2+(rnd()-0.5)*3;
+
+           switch(m) {
+               case 0:
+                   dotptr->x-=14;
+                   dotptr->dx=-20*adx + xvel;
+                   dotptr->dy=2*dy+yvel;
+                   dotptr->life = 60 * adx;
+                   break;
+               case 1:
+                   dotptr->dx=2*dx+xvel;
+                   dotptr->dy=-20*ady + yvel;
+                   dotptr->life = 60 * ady;
+                   break;
+               case 2:
+                   dotptr->x+=14;
+                   dotptr->dx=20*adx + xvel;
+                   dotptr->dy=2*dy+yvel;
+                   dotptr->life = 60 * adx;
+                   break;
+               case 3:
+                   dotptr->dx=2*dx+xvel;
+                   dotptr->dy=20*ady + yvel;
+                   dotptr->life = 60 * ady;
+                   break;
+           }
+           //dotptr->life *= 0.5 + rnd(0.5);
+           //dotptr->life=45+rnd(1)*20;
+           dotptr++;
+           if (dotptr-edot>=MAXENGINEDOTS)
+               dotptr = edot;
+       }
+    }
+}
+
+int drawdots(SDL_Surface *s) {/*{{{*/
+    int m, scorepos, n;
+
+    SDL_LockSurface(s);
+    // Draw the background stars aka space dots
+    draw_space_dots(s);
+
+    // Draw the score when playing the game or whn the game is freshly over
+    if (1 || state==GAMEPLAY || state==DEAD_PAUSE || state==GAME_OVER ) {
+
+       SDL_UnlockSurface(s);
+
+       scorepos = XSIZE-250;
+       n = snprintf(topline, 50, "Time: ");
+       snprintscore(topline+n, 50-n, score);
+       PutString(s,scorepos,0,topline);
+
+       SDL_LockSurface(s);
+
+    }
+
+    // Draw all the engine dots
+    draw_engine_dots(s);
+
+    // Create more engine dots comin out da back
+    if (!gameover)
+       create_engine_dots(200);
+
+    // Create engine dots out the side we're moving from
+    for (m=0; m<4; m++)
+       if (maneuver & 1<<m) // 'maneuver' is a bit field
+           create_engine_dots2(80,m);
+
+    // Draw all outstanding bang dots
+    //if (bangdotlife-- > 0) 
+       draw_bang_dots(s);
+
+    SDL_UnlockSurface(s);
+}/*}}}*/
+char * load_file(char *s) {/*{{{*/
+    static char retval[1024];
+    snprintf(retval, 1024, "%s/%s", data_dir, s);
+    return retval;
+}
+/*}}}*/
+int missing(char *dirname) {/*{{{*/
+    struct stat buf;
+    stat(dirname, &buf);
+    return (!S_ISDIR(buf.st_mode));
+}/*}}}*/
+
+int init(int fullscreen) {/*{{{*/
+
+    int i,j;
+    SDL_Surface *temp;
+    Uint16 *raw_pixels;
+    Uint32 flag;
+
+    read_high_score_table();
+
+    // Where are our data files?
+    // default: ./data
+    // second alternative: RD_DATADIR
+    // final alternative: /usr/share/rockdodger
+    data_dir = strdup("./data");
+    if (missing(data_dir)) {
+       char *env;
+       env = getenv("RD_DATADIR");
+       if (env != NULL) {
+           data_dir = strdup(env);
+           if (missing(data_dir)) {
+               fprintf (stderr,"Cannot find data directory $RD_DATADIR\n");
+               exit(-1);
+           }
+       }
+       else {
+           data_dir = strdup("/usr/share/rockdodger");
+           if (missing(data_dir)) {
+               fprintf (stderr,"Cannot find data in %s\n", data_dir);
+               exit(-2);
+           }
+       }
+    }
+
+    if (oss_sound_flag) {
+
+       // Initialise SDL with audio and video
+       if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)!=0) {
+           oss_sound_flag=0;
+           printf ("Can't open sound, starting without it\n");
+           atexit(SDL_Quit);
+       }
+       else {
+           atexit(SDL_Quit);
+           atexit(SDL_CloseAudio);
+           oss_sound_flag = init_sound();
+       }
+
+    }
+    else {
+       // Initialise with video only
+       CONDERROR(SDL_Init(SDL_INIT_VIDEO)!=0);
+       atexit(SDL_Quit);
+    }
+
+    if (oss_sound_flag)
+       play_tune(0);
+
+    // Attempt to get the required video size
+    flag = SDL_DOUBLEBUF | SDL_HWSURFACE;
+    if (fullscreen) flag |= SDL_FULLSCREEN;
+    surf_screen = SDL_SetVideoMode(XSIZE,YSIZE,16,flag);
+
+    // Set the title bar text
+    SDL_WM_SetCaption("Rock Dodgers", "rockdodgers");
+
+    NULLERROR(surf_screen);
+
+    // Set the heat color from the range 0 (cold) to 300 (blue-white)
+    for (i=0; i<W*3; i++)
+       heatcolor[i] = SDL_MapRGB(
+           surf_screen->format,
+           (i<W)?(i*M/W):(M),(i<W)?0:(i<2*W)?((i-W)*M/W):M,(i<2*W)?0:((i-W)*M/W) // Got that?
+       );
+
+    // Load the banners
+    NULLERROR(temp = IMG_Load(load_file("banners/rock.png")));
+    NULLERROR(surf_b_rock = SDL_DisplayFormat(temp));
+
+    NULLERROR(temp = IMG_Load(load_file("banners/dodgers.png")));
+    NULLERROR(surf_b_dodgers = SDL_DisplayFormat(temp));
+
+    NULLERROR(temp = IMG_Load(load_file("banners/game.png")));
+    NULLERROR(surf_b_game = SDL_DisplayFormat(temp));
+
+    NULLERROR(temp = IMG_Load(load_file("banners/over.png")));
+    NULLERROR(surf_b_over = SDL_DisplayFormat(temp));
+
+    surf_font_big = IMG_Load(load_file(BIG_FONT_FILE));
+    InitFont(surf_font_big);
+
+    // Load the spaceship graphic.
+       NULLERROR(temp = IMG_Load(load_file("sprites/ship.png")));
+       NULLERROR(surf_ship = SDL_DisplayFormat(temp));
+
+    // Load the life indicator (small ship) graphic.
+       NULLERROR(temp = IMG_Load(load_file("indicators/life.png")));
+       NULLERROR(surf_life = SDL_DisplayFormat(temp));
+
+    // Create the array of black points;
+    SDL_LockSurface(surf_ship);
+    raw_pixels = (Uint16 *) surf_ship->pixels;
+    for (i=0; i<surf_ship->w; i++)
+       for (j=0; j<surf_ship->h; j++)
+           if (raw_pixels[j*(surf_ship->pitch)/2+i] == 0) {
+               blackptr->x = i;
+               blackptr->y = j;
+               blackptr++;
+           }
+    SDL_UnlockSurface(surf_ship);
+
+    init_engine_dots();
+    init_space_dots();
+
+    // Load all our lovely rocks
+    for (i=0; i<NROCKS; i++) {
+               char a[100];
+
+               sprintf(a,load_file("sprites/rock%d.png"),i);
+               NULLERROR(temp = IMG_Load(a));
+               NULLERROR(surf_rock[i] = SDL_DisplayFormat(temp));
+
+               sprintf(a,load_file("sprites/deadrock%d.png"),i);
+               NULLERROR(temp = IMG_Load(a));
+               NULLERROR(surf_deadrock[i] = SDL_DisplayFormat(temp));
+    }
+
+    // Remove the mouse cursor
+#ifdef SDL_DISABLE
+    SDL_ShowCursor(SDL_DISABLE);
+#endif
+
+    return 0;
+}/*}}}*/
+int draw() {/*{{{*/
+    int i,n;
+    SDL_Rect src,dest;
+    struct black_point_struct *p;
+    Uint16 *raw_pixels;
+    int bang, offset, x;
+    char *text;
+    float fadegame,fadeover;
+
+    char *statedisplay, buf[1024];
+    
+    bang=0;
+
+    src.x=0;
+    src.y=0;
+    dest.x=0;
+    dest.y=0;
+
+    // Draw a fully black background
+    SDL_FillRect(surf_screen,NULL,0);
+
+
+#ifdef DEBUG
+    // DEBUG {{{
+    // Show the current state
+    switch (state) {
+       case TITLE_PAGE:
+           statedisplay = "title_page";
+           break;
+       case GAMEPLAY:
+           statedisplay = "gameplay";
+           break;
+       case DEAD_PAUSE:
+           statedisplay = "dead_pause";
+           break;
+       case GAME_OVER:
+           statedisplay = "game_over";
+           break;
+       case HIGH_SCORE_ENTRY:
+           statedisplay = "high_score_entry";
+           break;
+       case HIGH_SCORE_DISPLAY:
+           statedisplay = "high_score_display";
+           break;
+       case DEMO:
+           statedisplay = "demo";
+           break;
+    }
+    snprintf(buf,1024, "mode=%s", statedisplay);
+    PutString(surf_screen,0,YSIZE-50,buf);
+    // }}}
+#endif
+    
+    // Draw the background dots
+    drawdots(surf_screen);
+
+    // If it's firing, draw the laser
+    if (laser)
+       drawlaser();
+
+    // Draw ship
+    if (!gameover && (state==GAMEPLAY || state==DEMO) )  {
+       src.w = surf_ship->w;
+       src.h = surf_ship->h;
+       dest.w = src.w;
+       dest.h = src.h;
+       dest.x = (int)xship;
+       dest.y = (int)yship;
+       SDL_BlitSurface(surf_ship,&src,surf_screen,&dest);
+    }
+
+    // Draw all the rocks, in all states
+    for (i=0; i<MAXROCKS; i++) {
+       if (rock[i].active) {
+
+           src.w = rock[i].image->w;
+           src.h = rock[i].image->h;
+           dest.w = src.w;
+           dest.h = src.h;
+           dest.x = (int) rock[i].x;
+           dest.y = (int) rock[i].y;
+
+           // Draw the rock
+           SDL_BlitSurface(rock[i].image,&src,surf_screen,&dest);
+
+           // Draw the heated part of the rock, in an alpha which reflects the
+           // amount of heat in the rock.
+           if (rock[i].heat>0) {
+               SDL_Surface *deadrock;
+               deadrock = surf_deadrock[rock[i].type_number];
+               SDL_SetAlpha(deadrock,SDL_SRCALPHA,rock[i].heat*255/rock[i].image->h);
+               dest.x = (int) rock[i].x;   // kludge
+               SDL_BlitSurface(deadrock,&src,surf_screen,&dest);
+               if (rnd()<0.3) rock[i].heat-=movementrate;
+           }
+
+           // If the rock is heated past a certain point, the water content of
+           // the rock flashes to steam, releasing enough energy to destroy
+           // the rock in spectacular fashion.
+           if (rock[i].heat>rock[i].image->h) {
+               rock[i].active=0;
+               play_sound(1+(int)(rnd()*3));
+               makebangdots(rock[i].x,rock[i].y,rock[i].xvel,rock[i].yvel,rock[i].image,10);
+           }
+
+       }
+    }
+
+    // If it's game over, show the game over graphic in the dead centre
+    switch (state) {
+
+       case GAME_OVER:
+
+           if (fadetimer<3.0/faderate) 
+               fadegame=fadetimer/(3.0/faderate);
+           else
+               fadegame=1.0;
+
+           if (fadetimer<3.0/faderate) 
+               fadeover=0.0;
+           else 
+               if (fadetimer<6.0/faderate)
+                   fadeover = ((3.0/faderate)-fadetimer)/(6.0/faderate);
+               else
+                   fadeover = 1.0;
+
+           src.w = surf_b_game->w;
+           src.h = surf_b_game->h;
+           dest.w = src.w;
+           dest.h = src.h;
+           dest.x = (XSIZE-src.w)/2;
+           dest.y = (YSIZE-src.h)/2-40;
+           SDL_SetAlpha(surf_b_game, SDL_SRCALPHA, (int)(fadegame*(200+55*cos(fadetimer+=movementrate/1.0))));
+           SDL_BlitSurface(surf_b_game,&src,surf_screen,&dest);
+
+           src.w = surf_b_over->w;
+           src.h = surf_b_over->h;
+           dest.w = src.w;
+           dest.h = src.h;
+           dest.x = (XSIZE-src.w)/2;
+           dest.y = (YSIZE-src.h)/2+40;
+           SDL_SetAlpha(surf_b_over, SDL_SRCALPHA, (int)(fadeover*(200+55*sin(fadetimer))));
+           SDL_BlitSurface(surf_b_over,&src,surf_screen,&dest);
+           break;
+
+       case TITLE_PAGE:
+           src.w = surf_b_rock->w;
+           src.h = surf_b_rock->h;
+           dest.w = src.w;
+           dest.h = src.h;
+           dest.x = (XSIZE-src.w)/2 + cos(fadetimer/6.5)*10;
+           dest.y = (YSIZE/2-src.h)/2 + sin(fadetimer/5)*10;
+           SDL_SetAlpha(surf_b_rock, SDL_SRCALPHA, (int)(200+55*sin(fadetimer+=movementrate/2.0)));
+           SDL_BlitSurface(surf_b_rock,&src,surf_screen,&dest);
+           src.w = surf_b_dodgers->w;
+           src.h = surf_b_dodgers->h;
+           dest.w = src.w;
+           dest.h = src.h;
+           dest.x = (XSIZE-src.w)/2+sin(fadetimer/6.5)*10;
+           dest.y = (YSIZE/2-src.h)/2 + surf_b_rock->h + 20 + sin((fadetimer+1)/5)*10;
+           SDL_SetAlpha(surf_b_dodgers, SDL_SRCALPHA, (int)(200+55*sin(fadetimer-1.0)));
+           SDL_BlitSurface(surf_b_dodgers,&src,surf_screen,&dest);
+
+           text = "Version " VERSION;
+           x = (XSIZE-SFont_wide(text))/2 + sin(fadetimer/4.5)*10;
+           PutString(surf_screen,x,YSIZE-50+sin(fadetimer/2)*5,text);
+
+           text = sequence[(int)(fadetimer/40)%NSEQUENCE];
+           //text = "Press SPACE to start!";
+           x = (XSIZE-SFont_wide(text))/2 + cos(fadetimer/4.5)*10;
+           PutString(surf_screen,x,YSIZE-100+cos(fadetimer/3)*5,text);
+           break;
+
+       case HIGH_SCORE_ENTRY:
+
+           if (score >= high[7].score) {
+               play_tune(2);
+               if (SFont_Input (surf_screen, 330, 50+(scorerank+2)*font_height, 300, name)) {
+                   // Insert name into high score table
+
+                   // Lose the lowest name forever (loser!)
+                   //if (high[7].allocated)
+                   //  free(high[7].name);                 // THIS WAS CRASHING SO I REMOVED IT
+
+                   // Insert new high score
+                   high[scorerank].score = score;
+                   high[scorerank].name = strdup(name);    // MEMORY NEVER FREED!
+                   high[scorerank].allocated = 1;
+    
+                   // Set the global name string to "", ready for the next winner
+                   name[0]=0;
+    
+                   // Change state to briefly show high scores page
+                   state = HIGH_SCORE_DISPLAY;
+                   state_timeout=200;
+
+                   // Write the high score table to the file
+                   write_high_score_table();
+    
+                   // Play the title page tune
+                   play_tune(0);
+               }
+           }
+           else {
+               state = HIGH_SCORE_DISPLAY;
+               state_timeout=400;
+           }
+
+       case HIGH_SCORE_DISPLAY:
+           // Display de list o high scores mon.
+           PutString(surf_screen,180,50,"High scores");
+           for (i=0; i<8; i++) {
+               char s[1024];
+               sprintf(s, "#%1d",i+1);
+               PutString(surf_screen, 150, 50+(i+2)*font_height,s);
+               snprintscore(s, 1024, high[i].score);
+               PutString(surf_screen, 200, 50+(i+2)*font_height,s);
+               sprintf(s, "%3s", high[i].name);
+               PutString(surf_screen, 330, 50+(i+2)*font_height,s);
+           }
+
+    }
+
+    if (!gameover && state==GAMEPLAY) {
+       // Show the freaky shields
+       SDL_LockSurface(surf_screen);
+       raw_pixels = (Uint16 *) surf_screen->pixels;
+       if (initialshield>0 || shieldsup && shieldlevel>0) {
+           int x,y,l;
+           Uint16 c;
+
+           if (initialshield>0) {
+               initialshield-=movementrate;
+               c = SDL_MapRGB(surf_screen->format,0,255,255);
+           }
+           else {
+               c = heatcolor[(int)shieldlevel];
+               shieldlevel-=movementrate;
+           }
+
+           shieldpulse += 0.2;
+           for (p=black_point; p<blackptr; p++) { 
+               x = p->x + (int)xship + (rnd()+rnd()-1)*sin(shieldpulse)*4 + 1;
+               y = p->y + (int)yship + (rnd()+rnd()-1)*sin(shieldpulse)*4 + 1;
+               if (x>0 && y>0 && x<XSIZE && y<YSIZE) {
+                   offset = surf_screen->pitch/2 * y + x;
+                   raw_pixels[offset] = c;
+               }
+           }
+       }
+       else {
+           // When the shields are off, check that the black points 
+           // on the ship are still black, and not covered up by rocks
+           for (p=black_point; p<blackptr; p++) { 
+               offset = surf_screen->pitch/2 * (p->y + (int)yship) + p->x + (int)xship;
+               if (raw_pixels[offset]) {
+                   // Set the bang flag
+                   bang = 1;
+               }
+           }
+       }
+       SDL_UnlockSurface(surf_screen);
+    }
+
+#ifdef DOTCOLLISION
+    dotcollision(surf_screen); // Kill dots that are not on their spots
+#endif
+
+    // Draw all the little ships
+    if (state==GAMEPLAY || state==DEAD_PAUSE || state==GAME_OVER)
+       for (i=0; i<nships-1; i++) {
+           src.w = surf_life->w;
+           src.h = surf_life->h;
+           dest.w = src.w;
+           dest.h = src.h;
+           dest.x = (i+1)*(src.w+10);
+           dest.y = 20;
+           SDL_BlitSurface(surf_life,&src,surf_screen,&dest);
+       }
+
+
+    // Update the score
+    /*
+    n=SDL_GetTicks()-initticks;
+    if (score)
+       ticks_since_last = n-score;
+    score = n;
+    */
+
+    ticks_since_last = SDL_GetTicks()-last_ticks;
+    last_ticks = SDL_GetTicks();
+    if (ticks_since_last>200 || ticks_since_last<0) {
+       movementrate = 0;
+    }
+    else {
+       movementrate = ticks_since_last/50.0;
+       if (state==GAMEPLAY)
+           score += ticks_since_last;
+    }
+
+    // Update the surface
+    SDL_Flip(surf_screen);
+
+
+    return bang;
+}/*}}}*/
+int gameloop() {/*{{{*/
+    int i=0;
+    Uint8 *keystate;
+
+
+    for(;;) {
+
+       if (!paused) {
+           // Count down the game loop timer, and change state when it gets to zero or less;
+
+           if ((state_timeout -= movementrate*3) < 0) {
+               switch(state) {
+                   case DEAD_PAUSE:
+                       // Create a new ship and start all over again
+                       state = GAMEPLAY;
+                       play_tune(1);
+                       initialshield = 150;
+                       xship = 10;
+                       yship = YSIZE/2;
+                       xvel=2;
+                       yvel=0;
+                       shieldlevel = 3*W;
+                       break;
+                   case GAME_OVER:
+                       state = HIGH_SCORE_ENTRY;
+                       clearBuffer();
+                       name[0]=0;
+                       state_timeout=5.0e6;
+
+                       if (score>=high[7].score) {
+                           // Read the high score table from the storage file
+                           read_high_score_table();
+
+                           // Find ranking of this score, store as scorerank
+                           for (i=0; i<8; i++) {
+                               if (high[i].score <= score) {
+                                   scorerank = i;
+                                   break;
+                               }
+                           }
+
+                           // Move all lower scores down a notch
+                           for (i=7; i>=scorerank; i--)
+                               high[i] = high[i-1];
+
+                           // Insert blank high score
+                           high[scorerank].score = score;
+                           high[scorerank].name = "";
+                           high[scorerank].allocated = 0;
+                       }
+
+                       break;
+                   case HIGH_SCORE_DISPLAY:
+                       state = TITLE_PAGE;
+                       state_timeout=500.0;
+                       break;
+                   case HIGH_SCORE_ENTRY:
+                       // state = TITLE_PAGE;
+                       // play_tune(1);
+                       // state_timeout=100.0;
+                       break;
+#ifdef DEMO_ENABLED
+                   case TITLE_PAGE:
+                       state = DEMO;
+                       state_timeout=100.0;
+                       break;
+                   case DEMO:
+                       state = HIGH_SCORE_DISPLAY;
+                       state_timeout=100.0;
+                       break;
+#else
+                   case TITLE_PAGE:
+                       state = HIGH_SCORE_DISPLAY;
+                       state_timeout=200.0;
+                       break;
+#endif
+               }
+           }
+
+           if (--countdown<=0 && (rnd()*100.0<(rockrate+=0.025))) {
+               // Create a rock
+               rockptr++;
+               if (rockptr-rock>=MAXROCKS)
+                   rockptr=rock;
+               if (!rockptr->active) {
+                   rockptr->x = (float)XSIZE;
+                   rockptr->xvel = -(rockspeed)*(1+rnd());
+                   rockptr->yvel = rnd()-0.5;
+                   rockptr->type_number = random() % NROCKS;
+                   rockptr->heat = 0;
+                   rockptr->image = surf_rock[rockptr->type_number];// [random()%NROCKS];
+                   rockptr->active = 1;
+                   rockptr->y = rnd()*(YSIZE + rockptr->image->h);
+               }
+               if (movementrate>0.1)
+                   countdown = (int)(ROCKRATE/movementrate);
+               else
+                   countdown=0;
+           }
+
+           // FRICTION?
+               if(friction) {
+                       xvel *= pow((double)0.9,(double)movementrate);
+                       yvel *= pow((double)0.9,(double)movementrate);
+                       // if (abs(xvel)<0.00001) xvel=0;
+                       // if (abs(yvel)<0.00001) yvel=0;
+               }
+
+           // INERTIA
+           xship += xvel*movementrate;
+           yship += yvel*movementrate;
+
+           // SCROLLING
+           yscroll = yship - (YSIZE / 2);
+           yscroll /= -15;
+           yscroll = yscroll*movementrate;
+           yship += yscroll;
+           
+           // Move all the rocks
+           for (i=0; i<MAXROCKS; i++) if (rock[i].active) {
+               rock[i].x += rock[i].xvel*movementrate;
+               rock[i].y += rock[i].yvel*movementrate + yscroll;
+               if(rock[i].y > YSIZE) {
+                       rock[i].y -= YSIZE;
+                       rock[i].y -= rock[i].image->w;
+               } else if(rock[i].y < -rock[i].image->w) {
+                       rock[i].y += YSIZE;
+                       rock[i].y += rock[i].image->w;
+               }
+               if (rock[i].x<-32.0)
+                   rock[i].active=0;
+           }
+
+
+           // BOUNCE X
+           if (xship<0 || xship>XSIZE-surf_ship->w) {
+               // BOUNCE from left and right wall
+               xship -= xvel*movementrate;
+               xvel *= -0.99;
+           }
+
+           // BOUNCE Y
+           if (yship<0 || yship>YSIZE-surf_ship->h) {
+               // BOUNCE from top and bottom wall
+               yship -= yvel;
+               yvel *= -0.99;
+           }
+
+
+           if (draw() && state==GAMEPLAY)  {
+               if (oss_sound_flag) {
+                   // Play the explosion sound
+                   play_sound(0);
+               }
+               makebangdots(xship,yship,xvel,yvel,surf_ship,30);
+               if (--nships<=0) {
+                   gameover=1;
+                   state=GAME_OVER;
+                   state_timeout = 200.0;
+                   fadetimer=0.0;
+                   faderate=movementrate;
+               }
+               else {
+                   state=DEAD_PAUSE;
+                   state_timeout = 100.0;
+               }
+           }
+
+           SDL_PumpEvents();
+           keystate = SDL_GetKeyState(NULL);
+
+           if (state!=HIGH_SCORE_ENTRY && (keystate[SDLK_q] || keystate[SDLK_ESCAPE]))
+               return 0;
+
+           if (keystate[SDLK_SPACE] && (state==HIGH_SCORE_DISPLAY || state==TITLE_PAGE || state==DEMO)) {
+
+                       for (i=0; i<MAXROCKS; i++) rock[i].active=0;
+
+                       rockrate=54.0;
+                       rockspeed=5.0;
+
+                       nships = 4;
+                       score = 0;
+
+                       state = GAMEPLAY;
+                       play_tune(1);
+
+                       xvel=-1;
+                       gameover=0;
+                       yvel=0;
+                       xship=0;
+                       yship=YSIZE/2;
+                       shieldlevel = 3*W;
+                       initialshield = 0;
+
+           }
+
+           maneuver=0;
+           laser=0;
+       }
+       else {
+           SDL_PumpEvents();
+           keystate = SDL_GetKeyState(NULL);
+       }
+
+       if (state==GAMEPLAY) {
+           if (!gameover) {
+
+               if (!paused) {
+                   if (keystate[SDLK_UP])          { yvel -= 1.5*movementrate; maneuver|=1<<3;}
+                   if (keystate[SDLK_DOWN])        { yvel += 1.5*movementrate; maneuver|=1<<1;}
+                   if (keystate[SDLK_LEFT])        { xvel -= 1.5*movementrate; maneuver|=1<<2;}
+                   if (keystate[SDLK_RIGHT])       { xvel += 1.5*movementrate; maneuver|=1;}
+                   if (keystate[SDLK_d])           { laser=1; }
+                   if (keystate[SDLK_1])           { fast=1; }
+                   if (keystate[SDLK_2])           { fast=0; }
+                   if (keystate[SDLK_3])           { SDL_SaveBMP(surf_screen, "snapshot.bmp"); }
+                   shieldsup = keystate[SDLK_s];
+               }
+
+               if (keystate[SDLK_p])   {
+                   if (!pausedown) {
+                       paused = !paused;
+                       if (paused) {
+                           SDL_Rect src,dest;
+                           src.w = surf_b_rock->w;
+                           src.h = surf_b_rock->h;
+                           dest.w = src.w;
+                           dest.h = src.h;
+                           dest.x = (XSIZE-src.w)/2;
+                           dest.y = (YSIZE-src.h)/2;
+                           SDL_BlitSurface(surf_b_rock,&src,surf_screen,&dest);
+                           // Update the surface
+                           SDL_Flip(surf_screen);
+                           printf("paused\n");
+                       }
+                       else {
+                           printf ("not paused\n");
+                       }
+                       pausedown=1;
+                   }
+               }
+               else {
+                   pausedown=0;
+               }
+
+           }
+           else {
+               shieldsup = 0;
+               paused = 0;
+               pausedown = 0;
+           }
+       }
+
+       // DEBUG mode to slow down the action, and see if this game is playable on a 486
+       if (fast)
+           SDL_Delay (100);
+    }
+}/*}}}*/
+main(int argc, char **argv) {/*{{{*/
+    int i, x, fullscreen;
+
+    fullscreen=0;
+       tail_plume=0;
+       friction=0;
+    oss_sound_flag=1;
+
+    while ((x=getopt(argc,argv,"efhsp"))>=0)
+       switch(x) {
+               case 'e':  // engine
+                       tail_plume = 1;
+                       break;
+               case 'f':  // fullscreen
+                       fullscreen = 1;
+                       break;
+           case 'h':  // help
+                       printf ("Rock Dodgers\n"
+                               "  -e Big tail [E]ngine\n"
+                               "  -f [F]ull screen\n"
+                               "  -h This [H]elp message\n"
+                               "  -p Stupid original [P]hysics (friction)\n"
+                               "  -s [S]ilent (no sound)\n");
+                       exit(0);
+                       break;
+               case 'p':  // physics
+                       friction = 1;
+                       break;
+           case 's':  // silent
+                       oss_sound_flag = 0;
+                       break;
+       }
+
+    if (init(fullscreen)) {
+       printf ("ta: '%s'\n",initerror);
+       return 1;
+    }
+
+    while(1) {
+       for (i=0; i<MAXROCKS; i++)
+           rock[i].active=0;
+       rockrate=54.0;
+       rockspeed=5.0;
+       initticks = SDL_GetTicks();
+       if (gameloop()==0) break;
+       printf ("score=%d\n",score);
+       SDL_Delay(1000);
+    }
+
+    return 0;
+}/*}}}*/
+
+/*
+ * $Id: main.c,v 1.22 2002/02/15 20:26:45 pad Exp $
+ * $Log: main.c,v $
+ * Revision 1.22  2002/02/15 20:26:45  pad
+ * Update - explosion time limits (ergh) and stuff
+ *
+ * Revision 1.21  2002/01/26 14:13:27  pad
+ * Released to pcholt.com as 0.4.0a
+ *
+ * Revision 1.20  2002/01/20 22:24:41  pad
+ * No longer crashes on space bar in high score table
+ * Rocks make a random noise when they explode
+ *
+ * Revision 1.19  2002/01/17 19:38:45  pad
+ * Bang noise (must add more noises)
+ *
+ * Revision 1.18  2002/01/16 01:34:28  pad
+ * Rocks now change colour smoothly while being heated.
+ *
+ * Revision 1.17  2002/01/15 21:56:51  pad
+ * Lasers work, and rocks blow up, but unspectacularly.
+ *
+ * Revision 1.16  2001/10/21 22:08:41  pad
+ * Moving title screen,
+ * New game-over graphics
+ * High scores entered on the line of the new high score
+ *
+ * Revision 1.15  2001/10/11 22:25:10  pad
+ * High scores are saved!
+ * /usr/share/rockdodger/.highscore or, if this is impossible,
+ * $HOME/.rockdodger_high
+ *
+ * Revision 1.14  2001/10/09 22:29:38  pad
+ * Excellent! The game works, highscores are good, sound.c plays tunes,
+ * the SFont.c has been revamped, and the game looks good to go.
+ *
+ * Revision 1.13  2001/10/07 19:23:28  pad
+ * SDL_mixer, music and sound added
+ *
+ * Revision 1.12  2001/09/29 23:28:27  pad
+ * 0.1.8b release
+ * {{{
+ * Revision 1.11  2001/09/25 21:34:58  pad
+ * Test for SDL_DISABLE
+ * Something in sound.c I can't think what.
+ *
+ * Revision 1.10  2001/09/21 21:37:06  pad
+ * Donno. I canged something. Download it, it still works.
+ * The laser doesn't do anything, but you can fire it by pressing "d".
+ *
+ * Revision 1.9  2001/09/18 22:41:22  pad
+ * The score stays on the screen no matter what the game mode.
+ *
+ * Revision 1.7  2001/09/09 21:57:54  pad
+ * Starting to add sound.  There will be a background Ogg Vorbis soudtrack,
+ * with a sample-driven sound effects engine.
+ *
+ * Revision 1.6  2001/09/08 23:01:02  pad
+ * Version number on start screen, from Makefile
+ * Makefile 'make package' works
+ *
+ * Revision 1.5  2001/09/08 00:13:03  pad
+ * State table
+ * Title screen
+ * Revamped scoring system
+ * Looks nice!
+ *
+ * Revision 1.4  2001/09/06 21:42:05  pad
+ * Score is displayed using the lovely SFont library.
+ *
+ * Revision 1.3  2001/09/03 22:50:34  pad
+ * Functions cut back, larger number of space rocks.
+ * Now it's an actual challenge.
+ *
+ * Functions normalised - aim should be to have each function perform
+ * one action and one action alone. This is not yet complete.
+ *
+ * The high-speed movementrate error is fixed, but there are still
+ * unexplained crashes. I must find out how to let SDL give me a core
+ * dump to work with..
+ *
+ }}}
+ */
diff --git a/sound.c b/sound.c
new file mode 100644 (file)
index 0000000..0b8a046
--- /dev/null
+++ b/sound.c
@@ -0,0 +1,115 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_mixer.h>
+
+#define CONDERROR(a) if ((a)) {fprintf(stderr,"Error: %s\n",SDL_GetError());exit(1);}
+#define NULLERROR(a) CONDERROR((a)==NULL)
+
+#define TUNE_TITLE_PAGE                0
+#define TUNE_GAMEPLAY          1
+#define TUNE_HIGH_SCORE_ENTRY  2
+#define NUM_TUNES              3
+
+#define SOUND_BANG             0
+#define NUM_SOUNDS             4
+
+static Mix_Music *music[NUM_TUNES];
+static int music_volume[NUM_TUNES] = {128,128,128};
+static Mix_Chunk *wav[NUM_SOUNDS];
+
+int audio_rate;
+Uint16 audio_format;
+int audio_channels;
+
+char *load_file(char *);
+char *wav_file[] = {
+    "sounds/booom.wav",
+       "sounds/cboom.wav",
+       "sounds/boom.wav",
+       "sounds/bzboom.wav"
+};
+
+char *tune_file[] = {/*{{{*/
+    "music/magic.mod",
+    "music/getzznew.mod",
+    "music/4est_fulla3s.mod"
+};/*}}}*/
+
+int init_sound() {/*{{{*/
+    // Return 1 if the sound is ready to roll, and 0 if not.
+
+    int i;
+#ifdef DEBUG
+    printf ("Initialise sound\n");
+#endif
+
+    // Initialise output with SDL_mixer
+    if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16, MIX_DEFAULT_CHANNELS, 4096) < 0) {
+       fprintf(stderr, "Couldn't open SDL_mixer audio: %s\n", SDL_GetError());
+       return 0;
+    }
+
+#ifdef DEBUG
+    // What kind of sound did we get?  Ah who cares. As long as it can play
+    // some basic bangs and simple music.
+    Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
+    printf("Opened audio at %d Hz %d bit %s\n", audio_rate,
+           (audio_format&0xFF),
+           (audio_channels > 1) ? "stereo" : "mono");
+#endif
+
+    // Preload all the tunes into memory
+    for (i=0; i<NUM_TUNES; i++) {
+       if (!(music[i] = Mix_LoadMUS(load_file(tune_file[i])))) {
+           printf ("Failed to load %s\n",load_file(tune_file[i]));
+       }
+    }
+
+    // Preload all the wav files into memory
+    for (i=0; i<NUM_SOUNDS; i++) {
+       wav[i] = Mix_LoadWAV(load_file(wav_file[i]));
+    }
+
+    return 1;
+}/*}}}*/
+
+void play_sound(int i)  {/*{{{*/
+#ifdef DEBUG
+    printf ("play sound %d on first free channel\n",i);
+#endif
+    Mix_PlayChannel(-1, wav[i], 0);
+}/*}}}*/
+
+int playing=-1;
+
+
+#undef DEBUG
+
+void play_tune(int i) {/*{{{*/
+    if (playing==i)
+       return;
+    if (playing) {
+       Mix_FadeOutMusic(1500);
+#ifdef DEBUG
+       printf("Stop playing %d\n",playing);
+#endif
+    }
+#ifdef DEBUG
+    printf ("Play music %d\n",i);
+    printf ("volume %d\n",music_volume[i]);
+#endif
+    Mix_FadeInMusic(music[i],-1,2000);
+    Mix_VolumeMusic(music_volume[i]);
+
+    playing = i;
+}/*}}}*/
+
+/*
+ *
+ * The init_sound() routine is called first.
+ * The play_sound() routine is called with the index number of the sound we wish to play.
+ * The play_tune() routine is called with the index number of the tune we wish to play.
+ *
+ */