Initial revision
authorBill Kendrick <nbs@sonic.net>
Wed, 9 Apr 2003 05:45:33 +0000 (05:45 +0000)
committerBill Kendrick <nbs@sonic.net>
Wed, 9 Apr 2003 05:45:33 +0000 (05:45 +0000)
SVN-Revision: 4

176 files changed:
AUTHORS.txt [new file with mode: 0644]
CHANGES.txt [new file with mode: 0644]
COPYING.txt [new file with mode: 0644]
INSTALL.txt [new file with mode: 0644]
Makefile [new file with mode: 0644]
README.txt [new file with mode: 0644]
TODO.txt [new file with mode: 0644]
data/images/icon.png [new file with mode: 0644]
data/images/intro/beam.png [new file with mode: 0644]
data/images/intro/copter-squish.png [new file with mode: 0644]
data/images/intro/copter-stretch.png [new file with mode: 0644]
data/images/intro/copter1.png [new file with mode: 0644]
data/images/intro/copter2.png [new file with mode: 0644]
data/images/intro/gown-lookup.png [new file with mode: 0644]
data/images/intro/gown-sit.png [new file with mode: 0644]
data/images/intro/gown-upset.png [new file with mode: 0644]
data/images/intro/intro-old.png [new file with mode: 0644]
data/images/intro/intro.png [new file with mode: 0644]
data/images/intro/tux-mad.png [new file with mode: 0644]
data/images/intro/tux-sit.png [new file with mode: 0644]
data/images/intro/tux-upset.png [new file with mode: 0644]
data/images/level1/bkgd-00.png [new file with mode: 0644]
data/images/level1/bkgd-01.png [new file with mode: 0644]
data/images/level1/bkgd-02.png [new file with mode: 0644]
data/images/level1/bkgd-03.png [new file with mode: 0644]
data/images/level1/bkgd-10.png [new file with mode: 0644]
data/images/level1/bkgd-11.png [new file with mode: 0644]
data/images/level1/bkgd-12.png [new file with mode: 0644]
data/images/level1/bkgd-13.png [new file with mode: 0644]
data/images/level1/brick0.png [new file with mode: 0644]
data/images/level1/brick1.png [new file with mode: 0644]
data/images/level1/solid0.png [new file with mode: 0644]
data/images/level1/solid1.png [new file with mode: 0644]
data/images/level1/solid2.png [new file with mode: 0644]
data/images/level1/solid3.png [new file with mode: 0644]
data/images/map/map.png [new file with mode: 0644]
data/images/shared/bag-left-0.png [new file with mode: 0644]
data/images/shared/bag-left-1.png [new file with mode: 0644]
data/images/shared/bag-right-0.png [new file with mode: 0644]
data/images/shared/bag-right-1.png [new file with mode: 0644]
data/images/shared/bigcape-left-0.png [new file with mode: 0644]
data/images/shared/bigcape-left-1.png [new file with mode: 0644]
data/images/shared/bigcape-right-0.png [new file with mode: 0644]
data/images/shared/bigcape-right-1.png [new file with mode: 0644]
data/images/shared/bigtux-left-0.png [new file with mode: 0644]
data/images/shared/bigtux-left-1.png [new file with mode: 0644]
data/images/shared/bigtux-left-2.png [new file with mode: 0644]
data/images/shared/bigtux-left-jump.png [new file with mode: 0644]
data/images/shared/bigtux-right-0.png [new file with mode: 0644]
data/images/shared/bigtux-right-1.png [new file with mode: 0644]
data/images/shared/bigtux-right-2.png [new file with mode: 0644]
data/images/shared/bigtux-right-jump.png [new file with mode: 0644]
data/images/shared/box-empty.png [new file with mode: 0644]
data/images/shared/box-full.png [new file with mode: 0644]
data/images/shared/bsod-falling-left.png [new file with mode: 0644]
data/images/shared/bsod-falling-right.png [new file with mode: 0644]
data/images/shared/bsod-left-0.png [new file with mode: 0644]
data/images/shared/bsod-left-1.png [new file with mode: 0644]
data/images/shared/bsod-left-2.png [new file with mode: 0644]
data/images/shared/bsod-left-3.png [new file with mode: 0644]
data/images/shared/bsod-right-0.png [new file with mode: 0644]
data/images/shared/bsod-right-1.png [new file with mode: 0644]
data/images/shared/bsod-right-2.png [new file with mode: 0644]
data/images/shared/bsod-right-3.png [new file with mode: 0644]
data/images/shared/bsod-squished-left.png [new file with mode: 0644]
data/images/shared/bsod-squished-right.png [new file with mode: 0644]
data/images/shared/bullet.png [new file with mode: 0644]
data/images/shared/cape-left-0.png [new file with mode: 0644]
data/images/shared/cape-left-1.png [new file with mode: 0644]
data/images/shared/cape-right-0.png [new file with mode: 0644]
data/images/shared/cape-right-1.png [new file with mode: 0644]
data/images/shared/cloud-00.png [new file with mode: 0644]
data/images/shared/cloud-01.png [new file with mode: 0644]
data/images/shared/cloud-02.png [new file with mode: 0644]
data/images/shared/cloud-03.png [new file with mode: 0644]
data/images/shared/cloud-10.png [new file with mode: 0644]
data/images/shared/cloud-11.png [new file with mode: 0644]
data/images/shared/cloud-12.png [new file with mode: 0644]
data/images/shared/cloud-13.png [new file with mode: 0644]
data/images/shared/coffee.png [new file with mode: 0644]
data/images/shared/distro-0.png [new file with mode: 0644]
data/images/shared/distro-1.png [new file with mode: 0644]
data/images/shared/distro-2.png [new file with mode: 0644]
data/images/shared/distro-3.png [new file with mode: 0644]
data/images/shared/ducktux-left.png [new file with mode: 0644]
data/images/shared/ducktux-right.png [new file with mode: 0644]
data/images/shared/flag-0.png [new file with mode: 0644]
data/images/shared/flag-1.png [new file with mode: 0644]
data/images/shared/golden-herring.png [new file with mode: 0644]
data/images/shared/laptop-falling-left.png [new file with mode: 0644]
data/images/shared/laptop-falling-right.png [new file with mode: 0644]
data/images/shared/laptop-flat-left.png [new file with mode: 0644]
data/images/shared/laptop-flat-right.png [new file with mode: 0644]
data/images/shared/laptop-left-0.png [new file with mode: 0644]
data/images/shared/laptop-left-1.png [new file with mode: 0644]
data/images/shared/laptop-left-2.png [new file with mode: 0644]
data/images/shared/laptop-right-0.png [new file with mode: 0644]
data/images/shared/laptop-right-1.png [new file with mode: 0644]
data/images/shared/laptop-right-2.png [new file with mode: 0644]
data/images/shared/mints.png [new file with mode: 0644]
data/images/shared/pole.png [new file with mode: 0644]
data/images/shared/poletop.png [new file with mode: 0644]
data/images/shared/red-glow.png [new file with mode: 0644]
data/images/shared/skidtux-left.png [new file with mode: 0644]
data/images/shared/skidtux-right.png [new file with mode: 0644]
data/images/shared/super-bkgd.png [new file with mode: 0644]
data/images/shared/tux-left-0.png [new file with mode: 0644]
data/images/shared/tux-left-1.png [new file with mode: 0644]
data/images/shared/tux-left-2.png [new file with mode: 0644]
data/images/shared/tux-right-0.png [new file with mode: 0644]
data/images/shared/tux-right-1.png [new file with mode: 0644]
data/images/shared/tux-right-2.png [new file with mode: 0644]
data/images/shared/water.png [new file with mode: 0644]
data/images/shared/waves-0.png [new file with mode: 0644]
data/images/shared/waves-1.png [new file with mode: 0644]
data/images/shared/waves-2.png [new file with mode: 0644]
data/images/status/letters-black.png [new file with mode: 0644]
data/images/status/letters-blue.png [new file with mode: 0644]
data/images/status/letters-gold.png [new file with mode: 0644]
data/images/status/letters-red.png [new file with mode: 0644]
data/images/status/lives.png [new file with mode: 0644]
data/images/status/numbers.png [new file with mode: 0644]
data/images/status/score.png [new file with mode: 0644]
data/images/title/title-anim1.png [new file with mode: 0644]
data/images/title/title-anim2.png [new file with mode: 0644]
data/images/title/title.png [new file with mode: 0644]
data/levels/level1.dat [new file with mode: 0644]
data/levels/level1.dat-old [new file with mode: 0644]
data/music/SALCON.MOD [new file with mode: 0644]
data/music/ji_turn.it [new file with mode: 0644]
data/sounds/bigjump.wav [new file with mode: 0644]
data/sounds/brick.wav [new file with mode: 0644]
data/sounds/bump-upgrade.wav [new file with mode: 0644]
data/sounds/coffee.wav [new file with mode: 0644]
data/sounds/distro.wav [new file with mode: 0644]
data/sounds/excellent.wav [new file with mode: 0644]
data/sounds/fall.wav [new file with mode: 0644]
data/sounds/herring.wav [new file with mode: 0644]
data/sounds/hurt.wav [new file with mode: 0644]
data/sounds/jump.wav [new file with mode: 0644]
data/sounds/old/bigjump.wav [new file with mode: 0644]
data/sounds/old/brick.wav [new file with mode: 0644]
data/sounds/old/bump-upgrade.wav [new file with mode: 0644]
data/sounds/old/coffee.wav [new file with mode: 0644]
data/sounds/old/distro.wav [new file with mode: 0644]
data/sounds/old/excellent.wav [new file with mode: 0644]
data/sounds/old/fall.wav [new file with mode: 0644]
data/sounds/old/herring.wav [new file with mode: 0644]
data/sounds/old/hurt.wav [new file with mode: 0644]
data/sounds/old/jump.wav [new file with mode: 0644]
data/sounds/old/ricochet.wav [new file with mode: 0644]
data/sounds/old/shoot.wav [new file with mode: 0644]
data/sounds/old/skid.wav [new file with mode: 0644]
data/sounds/old/squish.wav [new file with mode: 0644]
data/sounds/old/upgrade.wav [new file with mode: 0644]
data/sounds/ricochet.wav [new file with mode: 0644]
data/sounds/shoot.wav [new file with mode: 0644]
data/sounds/skid.wav [new file with mode: 0644]
data/sounds/squish.wav [new file with mode: 0644]
data/sounds/upgrade.wav [new file with mode: 0644]
obj/.empty-file [new file with mode: 0644]
src/defines.h [new file with mode: 0644]
src/gameloop.c [new file with mode: 0644]
src/gameloop.h [new file with mode: 0644]
src/globals.h [new file with mode: 0644]
src/intro.c [new file with mode: 0644]
src/intro.h [new file with mode: 0644]
src/screen.c [new file with mode: 0644]
src/screen.h [new file with mode: 0644]
src/setup.c [new file with mode: 0644]
src/setup.h [new file with mode: 0644]
src/sound.c [new file with mode: 0644]
src/sound.h [new file with mode: 0644]
src/supertux.c [new file with mode: 0644]
src/title.c [new file with mode: 0644]
src/title.h [new file with mode: 0644]

diff --git a/AUTHORS.txt b/AUTHORS.txt
new file mode 100644 (file)
index 0000000..ec5b85f
--- /dev/null
@@ -0,0 +1,50 @@
+AUTHORS.txt for Super Tux
+
+by Bill Kendrick
+bill@newbreedsoftware.com
+http://www.newbreedsoftware.com/supertux/
+
+Version 0.0.2
+
+August 6, 2001
+
+
+CREDITS
+-------
+  Game Software:      Bill Kendrick, <bill@newbreedsoftware.com>
+                      http://www.newbreedsoftware.com/bill/
+
+  Graphics:           Bill Kendrick, using The GIMP
+                      http://www.gimp.org/
+
+                      Original Tux created by Larry Ewing <lewing@isc.tamu.edu>
+                      http://www.isc.tamu.edu/~lewing/linux/
+
+                      Most Tux images for Super Tux
+                      created by Wesley Poole <kokido@postmark.net>
+                      http://members.xoom.com/kokido
+
+                      Titlescreen Composed by Eric Windisch <raptor@bwbohh.net>
+
+  Concept:            Gown (Tux's Girlfriend) from
+                      "Tux: A Quest For Herring"
+                      by Steve Baker <sjbaker1@airmail.net>
+                      http://tuxaqfh.sourceforge.net/
+
+                      Originally from "xTux"
+                      by Dave Lawrence & James Andrews
+                      http://xtux.sourceforge.net/
+
+                      Idea to play as Gown also from Steve Baker.
+
+                      "Mints" upgrade based on Penguin Mints.
+                      http://powermint.safeshopper.com/1/3.htm?63
+
+  Sound Effects:      Royalty free sound effects CDROMs and FTP sites.
+
+  Miscellaneous:      See CHANGES.txt for bug fixers, etc.
+                      Also, comments, suggestions and praise from:
+
+                      James Harr <jharr@mad.scientist.com>
+                     Robert S Dubinski <dubinski@mscs.mu.edu>
+                      Brian Stentzel <brian.stentzel@operamail.com>
diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644 (file)
index 0000000..6e4526c
--- /dev/null
@@ -0,0 +1,56 @@
+CHANGES.txt for Super Tux
+
+by Bill Kendrick
+bill@newbreedsoftware.com
+http://www.newbreedsoftware.com/supertux/
+
+0.0.5 - ???
+-----------
+  * Added high score feature.
+    Adam Czachorowski <gislan@o2.pl>
+
+  * Surfaces converted to display format for speed.
+    (Thanks to SDL_DisplayFormatAlpha() - wasn't around a few years ago!)
+
+  * Sped up FPS (throttle)
+
+
+0.0.4 - July 15, 2002
+---------------------
+  * Fixed source so that "nosound" target would actually compile and build.
+
+
+0.0.3 - May 27, 2002
+--------------------
+  * Redid level 1.
+  * Coin bricks can be hit multiple times.
+  * You lose shooting (coffee) power-up if you get hurt.
+  * Jump bug fixed.
+  * Added "distros" counter to screen.
+  * Added new enemy: Evil Money Bags
+  * Game aborted if sounds/music couldn't be loaded.  Fixed.
+
+
+0.0.2 - November 8, 2001
+------------------------
+  * Added "--version" and skeleton "--help" displays
+  * More sound effects.
+  * Laptop bad-guy fixed.
+  * Skidding images created.
+  * Initial music code added.
+  * Bullets kill enemies.
+  * Golden Herring (invincibility) upgrade added.
+
+
+0.0.1 - December 3, 2000
+------------------------
+  * New title screen
+    Eric Windish <raptor@bwbohh.net>
+
+  * Makefile fixes
+    Ian <brooke@jump.net>
+
+
+INITIAL RELEASE 0.0.0 - April 11, 2000
+--------------------------------------
+  * Initial alpha release.
diff --git a/COPYING.txt b/COPYING.txt
new file mode 100644 (file)
index 0000000..60549be
--- /dev/null
@@ -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) 19yy  <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) 19yy 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/INSTALL.txt b/INSTALL.txt
new file mode 100644 (file)
index 0000000..55c8821
--- /dev/null
@@ -0,0 +1,122 @@
+INSTALL.txt for Super Tux
+
+by Bill Kendrick
+bill@newbreedsoftware.com
+http://www.newbreedsoftware.com/supertux/
+
+Version 0.0.2
+
+August 6, 2001
+
+
+REQUIREMENTS
+------------
+
+  CONTROLS
+  --------
+    The game is controlled using a mouse.  It can be played with either
+    a mouse or a joystick.
+
+  SDL
+  ---
+    "Super Tux" was programed using the "Simple Direct Media" layer
+    libraries by Sam Lantinga.  This means that the game can
+    theoretically run under any environment that the SDL libraries support.
+
+    (As of this program's release, this includes: Linux X11/DGA,
+    Win32 WinDIB/DirectX, BeOS BWindow, and Solaris X11, as well
+    as unofficually supported: Linux SVGAlib, IRIX 6.x X11,
+    FreeBSD 3.x X11, and MacOS.)
+
+    The Simple DirectMedia Layer is required to compile this game.
+
+    You can download the SDL libraries from:
+      http://www.libsdl.org/
+
+  SDL_image
+  ---------
+    SDL_image is also required.  (It is used to load the PNG format images
+    that come with Super Tux!)
+
+  SDL_mixer
+  ---------
+    Sound and music are available, but are not required (see below).
+    You will need the "SDL_mixer" library compiled and installed if
+    you want sound.
+
+
+INSTALLING UNDER LINUX/UNIX
+---------------------------
+  -----------------------------------------------------------------
+  Note: Read this entire section before you start issuing commands!
+  -----------------------------------------------------------------
+
+  First make sure SDL, SDL_image and, optionally, SDL_mixer, are
+  installed on your system.
+
+  The "Makefile" that comes with "Super Tux" assumes a number
+  of defaults about your system.  You can edit their values in
+  the "Makefile" itself, or specify their values when you run
+  the "make" command (ie, "make VARIABLE=value").
+
+  The things you will wish to edit are:
+
+    SDL_PREFIX=/usr/local
+
+      This defines the base location where the "include/SDL/"
+      and "lib/SDL/" directories will be found.  (They contain
+      the C header files and compiled object files for SDL,
+      respectively.)
+
+
+    DATA_PREFIX=$(PWD)/data/
+
+      This defines where "Super Tux"'s "data/" directory is
+      to be found.  The default assumes that you wish to leave
+      it where it is right now ("$(PWD)" expands to become the
+      current direcotry.
+
+      This variable is useful if you plan on moving the "data/"
+      directory elsewhere, say a globally-accessible
+      "/usr/local/games/supertux-data/".
+
+    JOY=YES
+
+      This causes "Super Tux" to be compiled with joystick
+      support.  If you don't have a version of SDL that supports
+      joystick, or just don't want joystick support, set this to "NO".
+
+
+  To compile the game, type the command:
+
+    make           [ with whatever variable changes you want, if any ]
+
+  If you decided that you wanted the data somewhere else, make sure
+  to move it there.  If you wanted it to be accessible to others
+  (ie, you're an administrator installing a new game for your users),
+  make sure to set the permissions for the files!  (You'll also want
+  to move the "supertux" binary to somewhere globally accessible,
+  and set its permissions, as well, of course!)
+
+  Note: If you do not have the SDL_mixer library, or wish to not
+  compile sound support into the game, you can compile it like this:
+
+    make nosound   [ with whatever variable changes you want, if any ]
+
+  If you wish to return the directory to its distribution state,
+  (remove the ".o" object files, and the "supertux" executable program
+  file), you can run:
+
+    make clean
+
+
+ICON FILE
+---------
+  A 32x32, XPM-format icon file (using the standard 23-color "cmap.xpm"
+  color palette) is available if you wish to use an icon for this game.
+
+  The file is "supertux-icon.xpm", and installed in Super Tux's
+  "data/images/" directory.
+
+
+The End!
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..05dd319
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,101 @@
+# Makefile for supertux
+
+# by Bill Kendrick
+# bill@newbreedsoftware.com
+# http://www.newbreedsoftware.com/
+
+# Version 0.0.0
+
+# April 11, 2000 - December 26, 2000
+
+
+# User-definable stuff:
+
+DATA_PREFIX=$(PWD)/data
+JOY=YES
+
+
+# Defaults for Linux:
+
+TARGET=supertux
+TARGET_DEF=LINUX
+
+
+CFLAGS=-Wall -O2 $(SDL_CFLAGS) -DDATA_PREFIX=\"$(DATA_PREFIX)\" \
+       -D$(NOSOUNDFLAG) -D$(TARGET_DEF) -DJOY_$(JOY)
+
+
+# Other definitions:
+
+SDL_MIXER=-lSDL_mixer
+SDL_IMAGE=-lSDL_image
+NOSOUNDFLAG=__SOUND
+SDL_LIB=$(SDL_LDFLAGS) $(SDL_MIXER) $(SDL_IMAGE)
+SDL_CFLAGS := $(shell sdl-config --cflags)
+SDL_LDFLAGS := $(shell sdl-config --libs)
+installbin = install -g root -o root -m 755 
+installdat = install -g root -o root -m 644
+
+
+OBJECTS=obj/supertux.o obj/setup.o obj/intro.o obj/title.o obj/gameloop.o \
+       obj/screen.o obj/sound.o
+
+# Make commands:
+
+all:   $(TARGET)
+
+#install: $(TARGET)
+#      -$(installdat) data $(DESTDIR)/usr/share/games/$(TARGET)/data
+#      -$(installbin) $(TARGET) $(DESTDIR)/usr/games/
+
+
+nosound:
+       make supertux SDL_MIXER= NOSOUNDFLAG=NOSOUND
+
+win32:
+       make TARGET_DEF=WIN32 TARGET=supertux.exe \
+               DATA_PREFIX=data
+       cp /usr/local/cross-tools/i386-mingw32/lib/SDL*.dll .
+       chmod 644 SDL*.dll
+
+clean:
+       -rm supertux supertux.exe
+       -rm obj/*.o
+       -rm SDL*.dll
+
+
+# Main executable:
+
+$(TARGET):     $(OBJECTS)
+       $(CC) $(CFLAGS) $(OBJECTS) -o $(TARGET) $(SDL_LIB)
+
+
+# Objects:
+
+obj/supertux.o:        src/supertux.c src/defines.h src/globals.h \
+               src/setup.h src/intro.h src/title.h src/gameloop.h \
+               src/screen.h src/sound.h
+       $(CC) $(CFLAGS) src/supertux.c -c -o obj/supertux.o
+
+obj/setup.o:   src/setup.c src/setup.h \
+               src/defines.h src/globals.h src/screen.h
+       $(CC) $(CFLAGS) src/setup.c -c -o obj/setup.o
+
+obj/intro.o:   src/intro.c src/intro.h \
+               src/defines.h src/globals.h src/screen.h
+       $(CC) $(CFLAGS) src/intro.c -c -o obj/intro.o
+
+obj/title.o:   src/title.c src/title.h \
+               src/defines.h src/globals.h src/screen.h
+       $(CC) $(CFLAGS) src/title.c -c -o obj/title.o
+
+obj/gameloop.o:        src/gameloop.c src/gameloop.h \
+               src/defines.h src/globals.h src/screen.h src/sound.h \
+               src/setup.h
+       $(CC) $(CFLAGS) src/gameloop.c -c -o obj/gameloop.o
+
+obj/screen.o:  src/screen.c src/defines.h src/globals.h src/screen.h
+       $(CC) $(CFLAGS) src/screen.c -c -o obj/screen.o
+
+obj/sound.o:   src/sound.c src/defines.h src/globals.h src/sound.h
+       $(CC) $(CFLAGS) src/sound.c -c -o obj/sound.o
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..ed4321b
--- /dev/null
@@ -0,0 +1,181 @@
+README.txt for Super Tux
+
+by Bill Kendrick
+bill@newbreedsoftware.com
+http://www.newbreedsoftware.com/supertux/
+
+Version 0.0.3
+
+November 14, 2001
+
+
+NOTICE!  THIS GAME IS UNDER CONSTRUCTION!
+Things you'll notice:
+
+  Bugs
+  Documentation is quite incomplete
+  Only one level
+
+
+DESCRIPTION
+-----------
+  "Super Tux" is a game similar to Nintendo's "Super Mario Bros."(tm)
+  Run and jump through multiple worlds, fighting off enemies by jumping
+  on them or bumping them from below.  Grab power-ups and Linux distributions
+  on the way.
+
+
+STORY
+-----
+  Tux and Gown are having a picnic in Antarctica, when suddenly Gown is
+  abducted!  Tux must follow the path of clues across the globe to find
+  his girlfriend and save her!
+
+
+DOCUMENTATION
+-------------
+  Important documentation for "Super Tux" is contained in multiple files.
+  Please see them:
+
+    AUTHORS.txt    - Credits for who made this game.
+    CHANGES.txt    - Changes since the previous versions of "Super Tux"
+    COPYING.txt    - The GNU Public License, which "Super Tux" is under.
+    INSTALL.txt    - Instructions on requirements, compiling and installing.
+    README.txt     - (This file.)  Game story, usage, rules and controls.
+    TODO.txt       - A wish-list for this version of "Super Tux"
+
+
+RUNNING THE GAME
+----------------
+  Just type "./supertux" to get started.
+
+  The program accepts some options:
+
+UNDER CONSTRUCTION
+
+    --disable-sound     - If sound support was compiled in, this will
+                          disable it for this session of the game.
+
+    --fullscreen        - Run in fullscreen mode.
+
+    --help              - Display a help message summarizing command-line
+                          options, copyright, and game controls.
+
+    --usage             - Display a brief message summarizing command-line
+                          options.
+
+    --version           - Display the version of Super Tux you're running.
+
+
+TITLE SCREEN
+------------
+  Press [RETURN] or a joystick firebutton to begin a game.
+
+  Press [ESCAPE] to quit.
+
+  Note: If you're playing Super Tux in a window, you can also use
+  your window manager's close option (usually an "X" button on the window's
+  title bar) to quit.  This works at ANY time.
+
+
+SCREEN LAYOUT
+-------------
+  UNDER CONSTRUCTION
+
+    +----------------------------------------+
+    |SCORE 1230    TIME 128     DISTROS 93   |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    |                                        |
+    +----------------------------------------+
+
+
+  Status
+  ------
+    Your score is displayed at the upper left.
+
+    The amount of time you have left to complete this level is displayed in
+    the center at the top of the screen.  (Note: Time is NOT in seconds!)
+
+    The number of distros (CDs) you have collected is displayed at the upper
+    right.
+
+
+PLAYING THE GAME
+----------------
+  Controls
+  --------
+    Joystick        Keyboard     Purpose
+    --------        --------     -------
+      Left            Left         Face/Move Left
+      Right           Right        Face/Move Right
+      Button-A        Up           Jump
+      Button-B        Control      Run/Fire
+      Down            Down         Duck
+
+  Pausing
+  -------
+    NOT IMPLEMENTED
+
+    To pause the game, you can press either the [TAB] or [P] key.
+    To unpause, press one of those keys again.
+
+  Quitting
+  --------
+    To quit the current game, you can press [ESCAPE].  This forfeits your game
+    (as though you ran out of lives).
+
+    To quit Super Tux altogether, you can use your window manager's
+    close command.  See the note in the "Title Screen" section, above.
+
+
+SCORING
+-------
+  Enemies
+  -------
+    If you get more than one enemy at a time without landing on the ground,
+    each enemy is worth more points.  For example, if there are three in a
+    row and you jump on the first, it's worth 50 points.  If you bounce off
+    the first and onto the second, it's worth 100 points.  If you also get
+    the third, it's worth 150 points.
+
+
+GAME OVER SCREEN
+----------------
+  NOT IMPLEMENTED
+
+
+OPTIONS FILE
+------------
+  NOT IMPLEMENTED
+
+  When Super Tux starts up, it looks for an options file.
+
+  Under Linux, this file is ".supertux" in your home directory ($HOME).
+  Under Windows, this file is "supertux.dat" in the Super Tux folder.
+
+  This file records high score scores and initials, and volume settings.
+
+
+THE END
+-------
+  Thanks for trying out Super Tux.
+
+  If you like Super Tux, please rate and review it at the
+  Linux Game Tome:
+
+    http://www.happypenguin.org/
+
+  Search for "Super Tux"!
+
+
+  Thanks!
+
+  Bill Kendrick  <bill@newbreedsoftware.com>
diff --git a/TODO.txt b/TODO.txt
new file mode 100644 (file)
index 0000000..f73b8c4
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,21 @@
+TODO.txt for Super Tux
+
+by Bill Kendrick
+bill@newbreedsoftware.com
+http://www.newbreedsoftware.com/supertux/
+
+Version 0.0.3
+
+November 25, 2001
+
+
+TO DO
+-----
+  Different, better and more music
+  One-ups
+  More enemies
+  Redo laptop enemy graphics
+  More levels
+  Play as Gown, resucing Tux
+  Game over
+  High score
diff --git a/data/images/icon.png b/data/images/icon.png
new file mode 100644 (file)
index 0000000..46a1ef7
Binary files /dev/null and b/data/images/icon.png differ
diff --git a/data/images/intro/beam.png b/data/images/intro/beam.png
new file mode 100644 (file)
index 0000000..3b884a5
Binary files /dev/null and b/data/images/intro/beam.png differ
diff --git a/data/images/intro/copter-squish.png b/data/images/intro/copter-squish.png
new file mode 100644 (file)
index 0000000..25f6b2b
Binary files /dev/null and b/data/images/intro/copter-squish.png differ
diff --git a/data/images/intro/copter-stretch.png b/data/images/intro/copter-stretch.png
new file mode 100644 (file)
index 0000000..754fa39
Binary files /dev/null and b/data/images/intro/copter-stretch.png differ
diff --git a/data/images/intro/copter1.png b/data/images/intro/copter1.png
new file mode 100644 (file)
index 0000000..3db63a8
Binary files /dev/null and b/data/images/intro/copter1.png differ
diff --git a/data/images/intro/copter2.png b/data/images/intro/copter2.png
new file mode 100644 (file)
index 0000000..69991ac
Binary files /dev/null and b/data/images/intro/copter2.png differ
diff --git a/data/images/intro/gown-lookup.png b/data/images/intro/gown-lookup.png
new file mode 100644 (file)
index 0000000..9c25331
Binary files /dev/null and b/data/images/intro/gown-lookup.png differ
diff --git a/data/images/intro/gown-sit.png b/data/images/intro/gown-sit.png
new file mode 100644 (file)
index 0000000..dbfcead
Binary files /dev/null and b/data/images/intro/gown-sit.png differ
diff --git a/data/images/intro/gown-upset.png b/data/images/intro/gown-upset.png
new file mode 100644 (file)
index 0000000..cd7d170
Binary files /dev/null and b/data/images/intro/gown-upset.png differ
diff --git a/data/images/intro/intro-old.png b/data/images/intro/intro-old.png
new file mode 100644 (file)
index 0000000..dfb0f72
Binary files /dev/null and b/data/images/intro/intro-old.png differ
diff --git a/data/images/intro/intro.png b/data/images/intro/intro.png
new file mode 100644 (file)
index 0000000..b2c6c89
Binary files /dev/null and b/data/images/intro/intro.png differ
diff --git a/data/images/intro/tux-mad.png b/data/images/intro/tux-mad.png
new file mode 100644 (file)
index 0000000..a0edd5b
Binary files /dev/null and b/data/images/intro/tux-mad.png differ
diff --git a/data/images/intro/tux-sit.png b/data/images/intro/tux-sit.png
new file mode 100644 (file)
index 0000000..d025fe5
Binary files /dev/null and b/data/images/intro/tux-sit.png differ
diff --git a/data/images/intro/tux-upset.png b/data/images/intro/tux-upset.png
new file mode 100644 (file)
index 0000000..79219fb
Binary files /dev/null and b/data/images/intro/tux-upset.png differ
diff --git a/data/images/level1/bkgd-00.png b/data/images/level1/bkgd-00.png
new file mode 100644 (file)
index 0000000..2ee9e50
Binary files /dev/null and b/data/images/level1/bkgd-00.png differ
diff --git a/data/images/level1/bkgd-01.png b/data/images/level1/bkgd-01.png
new file mode 100644 (file)
index 0000000..115a181
Binary files /dev/null and b/data/images/level1/bkgd-01.png differ
diff --git a/data/images/level1/bkgd-02.png b/data/images/level1/bkgd-02.png
new file mode 100644 (file)
index 0000000..3752239
Binary files /dev/null and b/data/images/level1/bkgd-02.png differ
diff --git a/data/images/level1/bkgd-03.png b/data/images/level1/bkgd-03.png
new file mode 100644 (file)
index 0000000..04c90db
Binary files /dev/null and b/data/images/level1/bkgd-03.png differ
diff --git a/data/images/level1/bkgd-10.png b/data/images/level1/bkgd-10.png
new file mode 100644 (file)
index 0000000..dd069b4
Binary files /dev/null and b/data/images/level1/bkgd-10.png differ
diff --git a/data/images/level1/bkgd-11.png b/data/images/level1/bkgd-11.png
new file mode 100644 (file)
index 0000000..e50a041
Binary files /dev/null and b/data/images/level1/bkgd-11.png differ
diff --git a/data/images/level1/bkgd-12.png b/data/images/level1/bkgd-12.png
new file mode 100644 (file)
index 0000000..dd0762f
Binary files /dev/null and b/data/images/level1/bkgd-12.png differ
diff --git a/data/images/level1/bkgd-13.png b/data/images/level1/bkgd-13.png
new file mode 100644 (file)
index 0000000..48a7136
Binary files /dev/null and b/data/images/level1/bkgd-13.png differ
diff --git a/data/images/level1/brick0.png b/data/images/level1/brick0.png
new file mode 100644 (file)
index 0000000..4869759
Binary files /dev/null and b/data/images/level1/brick0.png differ
diff --git a/data/images/level1/brick1.png b/data/images/level1/brick1.png
new file mode 100644 (file)
index 0000000..bbec5b4
Binary files /dev/null and b/data/images/level1/brick1.png differ
diff --git a/data/images/level1/solid0.png b/data/images/level1/solid0.png
new file mode 100644 (file)
index 0000000..47b2daf
Binary files /dev/null and b/data/images/level1/solid0.png differ
diff --git a/data/images/level1/solid1.png b/data/images/level1/solid1.png
new file mode 100644 (file)
index 0000000..7f315e0
Binary files /dev/null and b/data/images/level1/solid1.png differ
diff --git a/data/images/level1/solid2.png b/data/images/level1/solid2.png
new file mode 100644 (file)
index 0000000..ea56404
Binary files /dev/null and b/data/images/level1/solid2.png differ
diff --git a/data/images/level1/solid3.png b/data/images/level1/solid3.png
new file mode 100644 (file)
index 0000000..75d94f0
Binary files /dev/null and b/data/images/level1/solid3.png differ
diff --git a/data/images/map/map.png b/data/images/map/map.png
new file mode 100644 (file)
index 0000000..0623ccc
Binary files /dev/null and b/data/images/map/map.png differ
diff --git a/data/images/shared/bag-left-0.png b/data/images/shared/bag-left-0.png
new file mode 100644 (file)
index 0000000..0526564
Binary files /dev/null and b/data/images/shared/bag-left-0.png differ
diff --git a/data/images/shared/bag-left-1.png b/data/images/shared/bag-left-1.png
new file mode 100644 (file)
index 0000000..dca7cc9
Binary files /dev/null and b/data/images/shared/bag-left-1.png differ
diff --git a/data/images/shared/bag-right-0.png b/data/images/shared/bag-right-0.png
new file mode 100644 (file)
index 0000000..2ee021e
Binary files /dev/null and b/data/images/shared/bag-right-0.png differ
diff --git a/data/images/shared/bag-right-1.png b/data/images/shared/bag-right-1.png
new file mode 100644 (file)
index 0000000..53c0563
Binary files /dev/null and b/data/images/shared/bag-right-1.png differ
diff --git a/data/images/shared/bigcape-left-0.png b/data/images/shared/bigcape-left-0.png
new file mode 100644 (file)
index 0000000..38d437c
Binary files /dev/null and b/data/images/shared/bigcape-left-0.png differ
diff --git a/data/images/shared/bigcape-left-1.png b/data/images/shared/bigcape-left-1.png
new file mode 100644 (file)
index 0000000..4f8974b
Binary files /dev/null and b/data/images/shared/bigcape-left-1.png differ
diff --git a/data/images/shared/bigcape-right-0.png b/data/images/shared/bigcape-right-0.png
new file mode 100644 (file)
index 0000000..daa81e1
Binary files /dev/null and b/data/images/shared/bigcape-right-0.png differ
diff --git a/data/images/shared/bigcape-right-1.png b/data/images/shared/bigcape-right-1.png
new file mode 100644 (file)
index 0000000..219df6c
Binary files /dev/null and b/data/images/shared/bigcape-right-1.png differ
diff --git a/data/images/shared/bigtux-left-0.png b/data/images/shared/bigtux-left-0.png
new file mode 100644 (file)
index 0000000..b59eb3c
Binary files /dev/null and b/data/images/shared/bigtux-left-0.png differ
diff --git a/data/images/shared/bigtux-left-1.png b/data/images/shared/bigtux-left-1.png
new file mode 100644 (file)
index 0000000..390eb7b
Binary files /dev/null and b/data/images/shared/bigtux-left-1.png differ
diff --git a/data/images/shared/bigtux-left-2.png b/data/images/shared/bigtux-left-2.png
new file mode 100644 (file)
index 0000000..0215c0b
Binary files /dev/null and b/data/images/shared/bigtux-left-2.png differ
diff --git a/data/images/shared/bigtux-left-jump.png b/data/images/shared/bigtux-left-jump.png
new file mode 100644 (file)
index 0000000..e532161
Binary files /dev/null and b/data/images/shared/bigtux-left-jump.png differ
diff --git a/data/images/shared/bigtux-right-0.png b/data/images/shared/bigtux-right-0.png
new file mode 100644 (file)
index 0000000..7631965
Binary files /dev/null and b/data/images/shared/bigtux-right-0.png differ
diff --git a/data/images/shared/bigtux-right-1.png b/data/images/shared/bigtux-right-1.png
new file mode 100644 (file)
index 0000000..1ed6b1f
Binary files /dev/null and b/data/images/shared/bigtux-right-1.png differ
diff --git a/data/images/shared/bigtux-right-2.png b/data/images/shared/bigtux-right-2.png
new file mode 100644 (file)
index 0000000..e31f961
Binary files /dev/null and b/data/images/shared/bigtux-right-2.png differ
diff --git a/data/images/shared/bigtux-right-jump.png b/data/images/shared/bigtux-right-jump.png
new file mode 100644 (file)
index 0000000..d9c59d4
Binary files /dev/null and b/data/images/shared/bigtux-right-jump.png differ
diff --git a/data/images/shared/box-empty.png b/data/images/shared/box-empty.png
new file mode 100644 (file)
index 0000000..814ed57
Binary files /dev/null and b/data/images/shared/box-empty.png differ
diff --git a/data/images/shared/box-full.png b/data/images/shared/box-full.png
new file mode 100644 (file)
index 0000000..ae480f5
Binary files /dev/null and b/data/images/shared/box-full.png differ
diff --git a/data/images/shared/bsod-falling-left.png b/data/images/shared/bsod-falling-left.png
new file mode 100644 (file)
index 0000000..f902b6e
Binary files /dev/null and b/data/images/shared/bsod-falling-left.png differ
diff --git a/data/images/shared/bsod-falling-right.png b/data/images/shared/bsod-falling-right.png
new file mode 100644 (file)
index 0000000..d9ded93
Binary files /dev/null and b/data/images/shared/bsod-falling-right.png differ
diff --git a/data/images/shared/bsod-left-0.png b/data/images/shared/bsod-left-0.png
new file mode 100644 (file)
index 0000000..39a1e1e
Binary files /dev/null and b/data/images/shared/bsod-left-0.png differ
diff --git a/data/images/shared/bsod-left-1.png b/data/images/shared/bsod-left-1.png
new file mode 100644 (file)
index 0000000..52c7e10
Binary files /dev/null and b/data/images/shared/bsod-left-1.png differ
diff --git a/data/images/shared/bsod-left-2.png b/data/images/shared/bsod-left-2.png
new file mode 100644 (file)
index 0000000..f043ccd
Binary files /dev/null and b/data/images/shared/bsod-left-2.png differ
diff --git a/data/images/shared/bsod-left-3.png b/data/images/shared/bsod-left-3.png
new file mode 100644 (file)
index 0000000..0db8bfd
Binary files /dev/null and b/data/images/shared/bsod-left-3.png differ
diff --git a/data/images/shared/bsod-right-0.png b/data/images/shared/bsod-right-0.png
new file mode 100644 (file)
index 0000000..7d0aa10
Binary files /dev/null and b/data/images/shared/bsod-right-0.png differ
diff --git a/data/images/shared/bsod-right-1.png b/data/images/shared/bsod-right-1.png
new file mode 100644 (file)
index 0000000..5a22480
Binary files /dev/null and b/data/images/shared/bsod-right-1.png differ
diff --git a/data/images/shared/bsod-right-2.png b/data/images/shared/bsod-right-2.png
new file mode 100644 (file)
index 0000000..b25d674
Binary files /dev/null and b/data/images/shared/bsod-right-2.png differ
diff --git a/data/images/shared/bsod-right-3.png b/data/images/shared/bsod-right-3.png
new file mode 100644 (file)
index 0000000..8b4fc91
Binary files /dev/null and b/data/images/shared/bsod-right-3.png differ
diff --git a/data/images/shared/bsod-squished-left.png b/data/images/shared/bsod-squished-left.png
new file mode 100644 (file)
index 0000000..608ed33
Binary files /dev/null and b/data/images/shared/bsod-squished-left.png differ
diff --git a/data/images/shared/bsod-squished-right.png b/data/images/shared/bsod-squished-right.png
new file mode 100644 (file)
index 0000000..4a474d3
Binary files /dev/null and b/data/images/shared/bsod-squished-right.png differ
diff --git a/data/images/shared/bullet.png b/data/images/shared/bullet.png
new file mode 100644 (file)
index 0000000..f0f92ee
Binary files /dev/null and b/data/images/shared/bullet.png differ
diff --git a/data/images/shared/cape-left-0.png b/data/images/shared/cape-left-0.png
new file mode 100644 (file)
index 0000000..4d9c20e
Binary files /dev/null and b/data/images/shared/cape-left-0.png differ
diff --git a/data/images/shared/cape-left-1.png b/data/images/shared/cape-left-1.png
new file mode 100644 (file)
index 0000000..f595d16
Binary files /dev/null and b/data/images/shared/cape-left-1.png differ
diff --git a/data/images/shared/cape-right-0.png b/data/images/shared/cape-right-0.png
new file mode 100644 (file)
index 0000000..7af7be8
Binary files /dev/null and b/data/images/shared/cape-right-0.png differ
diff --git a/data/images/shared/cape-right-1.png b/data/images/shared/cape-right-1.png
new file mode 100644 (file)
index 0000000..3c2c91e
Binary files /dev/null and b/data/images/shared/cape-right-1.png differ
diff --git a/data/images/shared/cloud-00.png b/data/images/shared/cloud-00.png
new file mode 100644 (file)
index 0000000..9b21e64
Binary files /dev/null and b/data/images/shared/cloud-00.png differ
diff --git a/data/images/shared/cloud-01.png b/data/images/shared/cloud-01.png
new file mode 100644 (file)
index 0000000..b18b61d
Binary files /dev/null and b/data/images/shared/cloud-01.png differ
diff --git a/data/images/shared/cloud-02.png b/data/images/shared/cloud-02.png
new file mode 100644 (file)
index 0000000..77dc7f9
Binary files /dev/null and b/data/images/shared/cloud-02.png differ
diff --git a/data/images/shared/cloud-03.png b/data/images/shared/cloud-03.png
new file mode 100644 (file)
index 0000000..14d94b4
Binary files /dev/null and b/data/images/shared/cloud-03.png differ
diff --git a/data/images/shared/cloud-10.png b/data/images/shared/cloud-10.png
new file mode 100644 (file)
index 0000000..02dccb4
Binary files /dev/null and b/data/images/shared/cloud-10.png differ
diff --git a/data/images/shared/cloud-11.png b/data/images/shared/cloud-11.png
new file mode 100644 (file)
index 0000000..022dff9
Binary files /dev/null and b/data/images/shared/cloud-11.png differ
diff --git a/data/images/shared/cloud-12.png b/data/images/shared/cloud-12.png
new file mode 100644 (file)
index 0000000..ac6b454
Binary files /dev/null and b/data/images/shared/cloud-12.png differ
diff --git a/data/images/shared/cloud-13.png b/data/images/shared/cloud-13.png
new file mode 100644 (file)
index 0000000..aedec4d
Binary files /dev/null and b/data/images/shared/cloud-13.png differ
diff --git a/data/images/shared/coffee.png b/data/images/shared/coffee.png
new file mode 100644 (file)
index 0000000..e36b813
Binary files /dev/null and b/data/images/shared/coffee.png differ
diff --git a/data/images/shared/distro-0.png b/data/images/shared/distro-0.png
new file mode 100644 (file)
index 0000000..38b304d
Binary files /dev/null and b/data/images/shared/distro-0.png differ
diff --git a/data/images/shared/distro-1.png b/data/images/shared/distro-1.png
new file mode 100644 (file)
index 0000000..dbd0604
Binary files /dev/null and b/data/images/shared/distro-1.png differ
diff --git a/data/images/shared/distro-2.png b/data/images/shared/distro-2.png
new file mode 100644 (file)
index 0000000..c4dcaf5
Binary files /dev/null and b/data/images/shared/distro-2.png differ
diff --git a/data/images/shared/distro-3.png b/data/images/shared/distro-3.png
new file mode 100644 (file)
index 0000000..b6a950d
Binary files /dev/null and b/data/images/shared/distro-3.png differ
diff --git a/data/images/shared/ducktux-left.png b/data/images/shared/ducktux-left.png
new file mode 100644 (file)
index 0000000..a9adf4d
Binary files /dev/null and b/data/images/shared/ducktux-left.png differ
diff --git a/data/images/shared/ducktux-right.png b/data/images/shared/ducktux-right.png
new file mode 100644 (file)
index 0000000..7c56def
Binary files /dev/null and b/data/images/shared/ducktux-right.png differ
diff --git a/data/images/shared/flag-0.png b/data/images/shared/flag-0.png
new file mode 100644 (file)
index 0000000..f753a1b
Binary files /dev/null and b/data/images/shared/flag-0.png differ
diff --git a/data/images/shared/flag-1.png b/data/images/shared/flag-1.png
new file mode 100644 (file)
index 0000000..c8b6b3e
Binary files /dev/null and b/data/images/shared/flag-1.png differ
diff --git a/data/images/shared/golden-herring.png b/data/images/shared/golden-herring.png
new file mode 100644 (file)
index 0000000..1bcf258
Binary files /dev/null and b/data/images/shared/golden-herring.png differ
diff --git a/data/images/shared/laptop-falling-left.png b/data/images/shared/laptop-falling-left.png
new file mode 100644 (file)
index 0000000..2b41f63
Binary files /dev/null and b/data/images/shared/laptop-falling-left.png differ
diff --git a/data/images/shared/laptop-falling-right.png b/data/images/shared/laptop-falling-right.png
new file mode 100644 (file)
index 0000000..b001b07
Binary files /dev/null and b/data/images/shared/laptop-falling-right.png differ
diff --git a/data/images/shared/laptop-flat-left.png b/data/images/shared/laptop-flat-left.png
new file mode 100644 (file)
index 0000000..8efb709
Binary files /dev/null and b/data/images/shared/laptop-flat-left.png differ
diff --git a/data/images/shared/laptop-flat-right.png b/data/images/shared/laptop-flat-right.png
new file mode 100644 (file)
index 0000000..147f785
Binary files /dev/null and b/data/images/shared/laptop-flat-right.png differ
diff --git a/data/images/shared/laptop-left-0.png b/data/images/shared/laptop-left-0.png
new file mode 100644 (file)
index 0000000..3edd809
Binary files /dev/null and b/data/images/shared/laptop-left-0.png differ
diff --git a/data/images/shared/laptop-left-1.png b/data/images/shared/laptop-left-1.png
new file mode 100644 (file)
index 0000000..08647de
Binary files /dev/null and b/data/images/shared/laptop-left-1.png differ
diff --git a/data/images/shared/laptop-left-2.png b/data/images/shared/laptop-left-2.png
new file mode 100644 (file)
index 0000000..1835610
Binary files /dev/null and b/data/images/shared/laptop-left-2.png differ
diff --git a/data/images/shared/laptop-right-0.png b/data/images/shared/laptop-right-0.png
new file mode 100644 (file)
index 0000000..fdec34c
Binary files /dev/null and b/data/images/shared/laptop-right-0.png differ
diff --git a/data/images/shared/laptop-right-1.png b/data/images/shared/laptop-right-1.png
new file mode 100644 (file)
index 0000000..3f0ad36
Binary files /dev/null and b/data/images/shared/laptop-right-1.png differ
diff --git a/data/images/shared/laptop-right-2.png b/data/images/shared/laptop-right-2.png
new file mode 100644 (file)
index 0000000..a8c6041
Binary files /dev/null and b/data/images/shared/laptop-right-2.png differ
diff --git a/data/images/shared/mints.png b/data/images/shared/mints.png
new file mode 100644 (file)
index 0000000..f69193c
Binary files /dev/null and b/data/images/shared/mints.png differ
diff --git a/data/images/shared/pole.png b/data/images/shared/pole.png
new file mode 100644 (file)
index 0000000..64e87eb
Binary files /dev/null and b/data/images/shared/pole.png differ
diff --git a/data/images/shared/poletop.png b/data/images/shared/poletop.png
new file mode 100644 (file)
index 0000000..0307773
Binary files /dev/null and b/data/images/shared/poletop.png differ
diff --git a/data/images/shared/red-glow.png b/data/images/shared/red-glow.png
new file mode 100644 (file)
index 0000000..23d0c6f
Binary files /dev/null and b/data/images/shared/red-glow.png differ
diff --git a/data/images/shared/skidtux-left.png b/data/images/shared/skidtux-left.png
new file mode 100644 (file)
index 0000000..4948158
Binary files /dev/null and b/data/images/shared/skidtux-left.png differ
diff --git a/data/images/shared/skidtux-right.png b/data/images/shared/skidtux-right.png
new file mode 100644 (file)
index 0000000..4592c37
Binary files /dev/null and b/data/images/shared/skidtux-right.png differ
diff --git a/data/images/shared/super-bkgd.png b/data/images/shared/super-bkgd.png
new file mode 100644 (file)
index 0000000..ad0c7e7
Binary files /dev/null and b/data/images/shared/super-bkgd.png differ
diff --git a/data/images/shared/tux-left-0.png b/data/images/shared/tux-left-0.png
new file mode 100644 (file)
index 0000000..89c792c
Binary files /dev/null and b/data/images/shared/tux-left-0.png differ
diff --git a/data/images/shared/tux-left-1.png b/data/images/shared/tux-left-1.png
new file mode 100644 (file)
index 0000000..c736096
Binary files /dev/null and b/data/images/shared/tux-left-1.png differ
diff --git a/data/images/shared/tux-left-2.png b/data/images/shared/tux-left-2.png
new file mode 100644 (file)
index 0000000..edd7ff4
Binary files /dev/null and b/data/images/shared/tux-left-2.png differ
diff --git a/data/images/shared/tux-right-0.png b/data/images/shared/tux-right-0.png
new file mode 100644 (file)
index 0000000..7702c8c
Binary files /dev/null and b/data/images/shared/tux-right-0.png differ
diff --git a/data/images/shared/tux-right-1.png b/data/images/shared/tux-right-1.png
new file mode 100644 (file)
index 0000000..1e899e3
Binary files /dev/null and b/data/images/shared/tux-right-1.png differ
diff --git a/data/images/shared/tux-right-2.png b/data/images/shared/tux-right-2.png
new file mode 100644 (file)
index 0000000..5972823
Binary files /dev/null and b/data/images/shared/tux-right-2.png differ
diff --git a/data/images/shared/water.png b/data/images/shared/water.png
new file mode 100644 (file)
index 0000000..8895554
Binary files /dev/null and b/data/images/shared/water.png differ
diff --git a/data/images/shared/waves-0.png b/data/images/shared/waves-0.png
new file mode 100644 (file)
index 0000000..7cff221
Binary files /dev/null and b/data/images/shared/waves-0.png differ
diff --git a/data/images/shared/waves-1.png b/data/images/shared/waves-1.png
new file mode 100644 (file)
index 0000000..7625ea7
Binary files /dev/null and b/data/images/shared/waves-1.png differ
diff --git a/data/images/shared/waves-2.png b/data/images/shared/waves-2.png
new file mode 100644 (file)
index 0000000..0047595
Binary files /dev/null and b/data/images/shared/waves-2.png differ
diff --git a/data/images/status/letters-black.png b/data/images/status/letters-black.png
new file mode 100644 (file)
index 0000000..7115926
Binary files /dev/null and b/data/images/status/letters-black.png differ
diff --git a/data/images/status/letters-blue.png b/data/images/status/letters-blue.png
new file mode 100644 (file)
index 0000000..f8e7c02
Binary files /dev/null and b/data/images/status/letters-blue.png differ
diff --git a/data/images/status/letters-gold.png b/data/images/status/letters-gold.png
new file mode 100644 (file)
index 0000000..98ca4b9
Binary files /dev/null and b/data/images/status/letters-gold.png differ
diff --git a/data/images/status/letters-red.png b/data/images/status/letters-red.png
new file mode 100644 (file)
index 0000000..6ef2b1f
Binary files /dev/null and b/data/images/status/letters-red.png differ
diff --git a/data/images/status/lives.png b/data/images/status/lives.png
new file mode 100644 (file)
index 0000000..218e7e2
Binary files /dev/null and b/data/images/status/lives.png differ
diff --git a/data/images/status/numbers.png b/data/images/status/numbers.png
new file mode 100644 (file)
index 0000000..8ac3083
Binary files /dev/null and b/data/images/status/numbers.png differ
diff --git a/data/images/status/score.png b/data/images/status/score.png
new file mode 100644 (file)
index 0000000..be07b5f
Binary files /dev/null and b/data/images/status/score.png differ
diff --git a/data/images/title/title-anim1.png b/data/images/title/title-anim1.png
new file mode 100644 (file)
index 0000000..4d861c5
Binary files /dev/null and b/data/images/title/title-anim1.png differ
diff --git a/data/images/title/title-anim2.png b/data/images/title/title-anim2.png
new file mode 100644 (file)
index 0000000..16e6ce6
Binary files /dev/null and b/data/images/title/title-anim2.png differ
diff --git a/data/images/title/title.png b/data/images/title/title.png
new file mode 100644 (file)
index 0000000..1fb66a1
Binary files /dev/null and b/data/images/title/title.png differ
diff --git a/data/levels/level1.dat b/data/levels/level1.dat
new file mode 100644 (file)
index 0000000..63c915e
--- /dev/null
@@ -0,0 +1,18 @@
+128
+192
+255
+......cdef......2.........................................cdef.........................................................CDEF.....................................cdedef..........................................................CDEF........................................................................cdef..............cf....................................................cde
+.......................................................................................................................cdef.....................................................................................................cdef...................................................................................................................................................
+......................CDEF........................................CDEF.......................................................................CDEF....................................CDEF.......................................................................................................CDEDEF................................................................[.........*......
+......................cdef........................................cdef.......................................................................cdef.............................$......cdef.......................................................................................................cdedef...............................................................[#........\|......
+....................................CDEDEF.................................................................................................................................$....$.............................................................................................CDEF.....................................................0............................[##.........|......
+....................................cdedef...................................................CDEF................0..............................................................CDEF............................................................CDEF..........................cdef............................................###.###..#...........................[###.........|......
+...........................A.................................................................cdef............YYYYYYYY...YYYYYA....................A....................$........cdef............................................................cdef....................................A.....................................#...#.#..#..........................[####.........|.....C
+....................................................................................................................................................................$...0.........$...........................................................................................................................................#.#.#.#............................[#####.........|.....c
+.................................................................................................................................................................$...0###.....................................................................................................................................................#.#.#.#.CDEF......................[######EF.......|......
+..............................................................................................................................................................$...0######...............................[==]................[==...]...........................................................................................###.###.c#ef.....................[#######ef.......|......
+.....................A...XBXAX...........................................[=].................[=]..........XBX................x.........A!......A..A..A.........0#########...........$..................[####]..............[###...#].................XAXXBX....................................$.$.$.$1.......................................................[########.........|......
+............................................................[=]..........###.................###.............................................................############.............................[######]............[####...##]...........###...........###......................[=]....#########....[=]...............................................[#########.........|......
+.....................................GHJ..........[=]......G###..........###....GHIJ.........###.............................................................############............................[########]HIJ.......[#####...###]..........###...........###......................###.................###................GHIJ.......................GHI[##########.........|......
+..GHIJ...........................0...ghj..........###......g###..GHIJ 0..###....ghij.0.0.0...###.......................GHIJ.........0.0..1.........0.0.......############.............$....0.0.0....[##########]ij......[######...####]...GHIJ..###........0.0###HIJ......1....0.0.0...###...0.0.0.........###................ghij.......................gh[###########==========]^^^^^
+===================================================================================================]...[=====########..g######===============================############^^^^^^^^^^#######=============================]#######...#####[=================================================]#################[===============================================#######################&&&&&
diff --git a/data/levels/level1.dat-old b/data/levels/level1.dat-old
new file mode 100644 (file)
index 0000000..b6a073d
--- /dev/null
@@ -0,0 +1,18 @@
+64
+96
+255
+ef.....................................................................cdef................................................................................................................................................................................................................[===============].........cdef.............................................................
+............................................................................................................................................................................................................................................................................................#################DEF.......................................................................
+........CDEF....................................................................................................CDEF........................................................................................................................................................................#################def.......................................................................
+........cdef..............................$.$.$.................................................................cdef....CDEF........................................................................................CDEF.....................................CDEF...........................#################..........................................................................
+............................................................................................CDEF........................cdef............................CDEF........................................................cdef.....................................cdef...........................#################..........................................................................
+.........................................YYYYYYy............................................cdef........................................................cdef............................................................................................................CDEF................#################..........................................................................
+......................................................................................................................................................................................................Y.................................................................cdef................#################..........................................................................
+......................................................CDEF..........................................................!.......................................................CDEF.............CDEF.........Y.................................................................................#################................CDEF......................................................
+........YAYBY........................YYYyXX.........[===]f.......................0.0.....................................................................................[====]f.............cdef....Y...............................=....................................................CD#################................cdef......................................................
+....................................................#####..................YYYYAYBYYY...................................................................................[######]...........................y.........................#DEF.................................................cd#################..........................................................................
+....................................................#####........................................[=]...........................###.....................................[########]...................Y..............................=.#def......................YYYYYY.......................#################..........................................................................
+.....YYYXXXXXYYY.................YYYYXXX...........[#####............0.0.0.......................###.........[=].........[=]...###...............=....................[##########]..........................Y......................#.#...........YYAYAYAYY.....XXXXXX..................................................................................................................
+...................YYY====YYYY.....................#######################==]....................###...[=]...###.........###...###...............#...................[############]..............................................=.#.#.........................XXXXXX.......................#################..........................................................................
+...................................0.0.0...........######...................#################....###...###...###...[=]...###...###....###........#...0.0.0..........[##############]..................................0.0........#.#.#.........................XXXXXX.................0.0...#################..........................................................................
+===================================================######^^^^^^^^^^^^^^^^^^^#################====###===###===###===###...###...###.........======#==================################==========####################################.#.#========================================]...[====================================================================================================
diff --git a/data/music/SALCON.MOD b/data/music/SALCON.MOD
new file mode 100644 (file)
index 0000000..1fdb3c3
Binary files /dev/null and b/data/music/SALCON.MOD differ
diff --git a/data/music/ji_turn.it b/data/music/ji_turn.it
new file mode 100644 (file)
index 0000000..ad5e03d
Binary files /dev/null and b/data/music/ji_turn.it differ
diff --git a/data/sounds/bigjump.wav b/data/sounds/bigjump.wav
new file mode 100644 (file)
index 0000000..634d23d
Binary files /dev/null and b/data/sounds/bigjump.wav differ
diff --git a/data/sounds/brick.wav b/data/sounds/brick.wav
new file mode 100644 (file)
index 0000000..83de10d
Binary files /dev/null and b/data/sounds/brick.wav differ
diff --git a/data/sounds/bump-upgrade.wav b/data/sounds/bump-upgrade.wav
new file mode 100644 (file)
index 0000000..524b8e2
Binary files /dev/null and b/data/sounds/bump-upgrade.wav differ
diff --git a/data/sounds/coffee.wav b/data/sounds/coffee.wav
new file mode 100644 (file)
index 0000000..2e2be45
Binary files /dev/null and b/data/sounds/coffee.wav differ
diff --git a/data/sounds/distro.wav b/data/sounds/distro.wav
new file mode 100644 (file)
index 0000000..5741f23
Binary files /dev/null and b/data/sounds/distro.wav differ
diff --git a/data/sounds/excellent.wav b/data/sounds/excellent.wav
new file mode 100644 (file)
index 0000000..cadcc5e
Binary files /dev/null and b/data/sounds/excellent.wav differ
diff --git a/data/sounds/fall.wav b/data/sounds/fall.wav
new file mode 100644 (file)
index 0000000..f38d635
Binary files /dev/null and b/data/sounds/fall.wav differ
diff --git a/data/sounds/herring.wav b/data/sounds/herring.wav
new file mode 100644 (file)
index 0000000..96f3871
Binary files /dev/null and b/data/sounds/herring.wav differ
diff --git a/data/sounds/hurt.wav b/data/sounds/hurt.wav
new file mode 100644 (file)
index 0000000..20537c3
Binary files /dev/null and b/data/sounds/hurt.wav differ
diff --git a/data/sounds/jump.wav b/data/sounds/jump.wav
new file mode 100644 (file)
index 0000000..24240ea
Binary files /dev/null and b/data/sounds/jump.wav differ
diff --git a/data/sounds/old/bigjump.wav b/data/sounds/old/bigjump.wav
new file mode 100644 (file)
index 0000000..ab03fcb
Binary files /dev/null and b/data/sounds/old/bigjump.wav differ
diff --git a/data/sounds/old/brick.wav b/data/sounds/old/brick.wav
new file mode 100644 (file)
index 0000000..fc186f6
Binary files /dev/null and b/data/sounds/old/brick.wav differ
diff --git a/data/sounds/old/bump-upgrade.wav b/data/sounds/old/bump-upgrade.wav
new file mode 100644 (file)
index 0000000..00bfb9d
Binary files /dev/null and b/data/sounds/old/bump-upgrade.wav differ
diff --git a/data/sounds/old/coffee.wav b/data/sounds/old/coffee.wav
new file mode 100644 (file)
index 0000000..2e2be45
Binary files /dev/null and b/data/sounds/old/coffee.wav differ
diff --git a/data/sounds/old/distro.wav b/data/sounds/old/distro.wav
new file mode 100644 (file)
index 0000000..5741f23
Binary files /dev/null and b/data/sounds/old/distro.wav differ
diff --git a/data/sounds/old/excellent.wav b/data/sounds/old/excellent.wav
new file mode 100644 (file)
index 0000000..cadcc5e
Binary files /dev/null and b/data/sounds/old/excellent.wav differ
diff --git a/data/sounds/old/fall.wav b/data/sounds/old/fall.wav
new file mode 100644 (file)
index 0000000..292e5c3
Binary files /dev/null and b/data/sounds/old/fall.wav differ
diff --git a/data/sounds/old/herring.wav b/data/sounds/old/herring.wav
new file mode 100644 (file)
index 0000000..96f3871
Binary files /dev/null and b/data/sounds/old/herring.wav differ
diff --git a/data/sounds/old/hurt.wav b/data/sounds/old/hurt.wav
new file mode 100644 (file)
index 0000000..b8e95ca
Binary files /dev/null and b/data/sounds/old/hurt.wav differ
diff --git a/data/sounds/old/jump.wav b/data/sounds/old/jump.wav
new file mode 100644 (file)
index 0000000..d89819e
Binary files /dev/null and b/data/sounds/old/jump.wav differ
diff --git a/data/sounds/old/ricochet.wav b/data/sounds/old/ricochet.wav
new file mode 100644 (file)
index 0000000..016c7bf
Binary files /dev/null and b/data/sounds/old/ricochet.wav differ
diff --git a/data/sounds/old/shoot.wav b/data/sounds/old/shoot.wav
new file mode 100644 (file)
index 0000000..48696ef
Binary files /dev/null and b/data/sounds/old/shoot.wav differ
diff --git a/data/sounds/old/skid.wav b/data/sounds/old/skid.wav
new file mode 100644 (file)
index 0000000..3abd9c7
Binary files /dev/null and b/data/sounds/old/skid.wav differ
diff --git a/data/sounds/old/squish.wav b/data/sounds/old/squish.wav
new file mode 100644 (file)
index 0000000..a3f86c2
Binary files /dev/null and b/data/sounds/old/squish.wav differ
diff --git a/data/sounds/old/upgrade.wav b/data/sounds/old/upgrade.wav
new file mode 100644 (file)
index 0000000..95edf47
Binary files /dev/null and b/data/sounds/old/upgrade.wav differ
diff --git a/data/sounds/ricochet.wav b/data/sounds/ricochet.wav
new file mode 100644 (file)
index 0000000..016c7bf
Binary files /dev/null and b/data/sounds/ricochet.wav differ
diff --git a/data/sounds/shoot.wav b/data/sounds/shoot.wav
new file mode 100644 (file)
index 0000000..9546ffc
Binary files /dev/null and b/data/sounds/shoot.wav differ
diff --git a/data/sounds/skid.wav b/data/sounds/skid.wav
new file mode 100644 (file)
index 0000000..8576153
Binary files /dev/null and b/data/sounds/skid.wav differ
diff --git a/data/sounds/squish.wav b/data/sounds/squish.wav
new file mode 100644 (file)
index 0000000..b6cc061
Binary files /dev/null and b/data/sounds/squish.wav differ
diff --git a/data/sounds/upgrade.wav b/data/sounds/upgrade.wav
new file mode 100644 (file)
index 0000000..95edf47
Binary files /dev/null and b/data/sounds/upgrade.wav differ
diff --git a/obj/.empty-file b/obj/.empty-file
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/src/defines.h b/src/defines.h
new file mode 100644 (file)
index 0000000..1e56b1f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+  defines.h
+  
+  Super Tux
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - August 29, 2002
+*/
+
+
+/* Version: */
+
+#define VERSION "0.0.5"
+
+
+/* Frames per second: */
+
+#define FPS (1000 / 25)
+
+
+/* Joystick buttons and axes: */
+
+#define JOY_A 0
+#define JOY_B 1
+
+#define JOY_X 0
+#define JOY_Y 1
+
+
+/* Booleans: */
+
+#define NO 0
+#define YES 1
+
+
diff --git a/src/gameloop.c b/src/gameloop.c
new file mode 100644 (file)
index 0000000..11be5ad
--- /dev/null
@@ -0,0 +1,3418 @@
+/*
+  gameloop.c
+  
+  Super Tux - Game Loop!
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - July 15, 2002
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "gameloop.h"
+#include "screen.h"
+#include "sound.h"
+#include "setup.h"
+
+
+/* Sound files: */
+
+enum {
+  SND_JUMP,
+  SND_BIGJUMP,
+  SND_SKID,
+  SND_DISTRO,
+  SND_HERRING,
+  SND_BRICK,
+  SND_HURT,
+  SND_SQUISH,
+  SND_FALL,
+  SND_RICOCHET,
+  SND_BUMP_UPGRADE,
+  SND_UPGRADE,
+  SND_EXCELLENT,
+  SND_COFFEE,
+  SND_SHOOT,
+  NUM_SOUNDS
+};
+
+char * soundfilenames[NUM_SOUNDS] = {
+  DATA_PREFIX "/sounds/jump.wav",
+  DATA_PREFIX "/sounds/bigjump.wav",
+  DATA_PREFIX "/sounds/skid.wav",
+  DATA_PREFIX "/sounds/distro.wav",
+  DATA_PREFIX "/sounds/herring.wav",
+  DATA_PREFIX "/sounds/brick.wav",
+  DATA_PREFIX "/sounds/hurt.wav",
+  DATA_PREFIX "/sounds/squish.wav",
+  DATA_PREFIX "/sounds/fall.wav",
+  DATA_PREFIX "/sounds/ricochet.wav",
+  DATA_PREFIX "/sounds/bump-upgrade.wav",
+  DATA_PREFIX "/sounds/upgrade.wav",
+  DATA_PREFIX "/sounds/excellent.wav",
+  DATA_PREFIX "/sounds/coffee.wav",
+  DATA_PREFIX "/sounds/shoot.wav"
+};
+
+
+/* Level names: */
+
+char * levelnames[] = {
+  "Antarctica",
+  "Australia",
+  "India",
+  "Egypt",
+  "Greece",
+  "Spain",
+  "Brazil",
+  "America",
+  "Redmond"
+};
+
+
+/* Local variables: */
+
+int score, distros, level, lives, scroll_x,
+  tux_dir, tux_size, tux_duck, tux_x, tux_xm, tux_y, tux_ym,
+  tux_dying, tux_safe, jumping, jump_counter, frame, score_multiplier,
+  tux_frame_main, tux_frame, tux_got_coffee, tux_skidding,
+  super_bkgd_time, time_left, tux_invincible_time,
+  counting_distros, distro_counter;
+int bkgd_red, bkgd_green, bkgd_blue;
+int left, right, up, down, fire, old_fire;
+SDL_Surface * img_brick[2], * img_solid[4], * img_distro[4],
+  * img_waves[3], * img_water, * img_pole, * img_poletop, * img_flag[2];
+SDL_Surface * img_bkgd[2][4];
+SDL_Surface * img_golden_herring;
+SDL_Surface * img_bsod_left[4], * img_bsod_right[4],
+  * img_laptop_left[3], * img_laptop_right[3],
+  * img_money_left[2], * img_money_right[2];
+SDL_Surface * img_bsod_squished_left, * img_bsod_squished_right,
+  * img_bsod_falling_left, * img_bsod_falling_right,
+  * img_laptop_flat_left, * img_laptop_flat_right,
+  * img_laptop_falling_left, * img_laptop_falling_right;
+SDL_Surface * img_box_full, * img_box_empty, * img_mints, * img_coffee,
+  * img_super_bkgd, * img_bullet, * img_red_glow;
+SDL_Surface * img_cloud[2][4];
+SDL_Surface * tux_right[3], * tux_left[3],
+  * bigtux_right[3], * bigtux_left[3],
+  * bigtux_right_jump, * bigtux_left_jump,
+  * cape_right[2], * cape_left[2],
+  * bigcape_right[2], * bigcape_left[2],
+  * ducktux_right, * ducktux_left,
+  * skidtux_right, * skidtux_left;
+#ifndef NOSOUND
+Mix_Chunk * sounds[NUM_SOUNDS];
+Mix_Music * song;
+#endif
+unsigned char tiles[15][LEVEL_WIDTH + 5];
+bouncy_distro_type bouncy_distros[NUM_BOUNCY_DISTROS];
+broken_brick_type broken_bricks[NUM_BROKEN_BRICKS];
+bouncy_brick_type bouncy_bricks[NUM_BOUNCY_BRICKS];
+bad_guy_type bad_guys[NUM_BAD_GUYS];
+floating_score_type floating_scores[NUM_FLOATING_SCORES];
+upgrade_type upgrades[NUM_UPGRADES];
+bullet_type bullets[NUM_BULLETS];
+
+
+/* Local function prototypes: */
+
+void initgame(void);
+void loadlevel(void);
+void loadlevelgfx(void);
+void loadlevelsong(void);
+void unloadlevelgfx(void);
+void unloadlevelsong(void);
+void loadshared(void);
+void unloadshared(void);
+void drawshape(int x, int y, unsigned char c);
+unsigned char shape(int x, int y, int sx);
+int issolid(int x, int y, int sx);
+int isbrick(int x, int y, int sx);
+int isice(int x, int y, int sx);
+int isfullbox(int x, int y, int sx);
+void change(int x, int y, int sx, unsigned char c);
+void trybreakbrick(int x, int y, int sx);
+void bumpbrick(int x, int y, int sx);
+void tryemptybox(int x, int y, int sx);
+void trygrabdistro(int x, int y, int sx, int bounciness);
+void add_bouncy_distro(int x, int y);
+void add_broken_brick(int x, int y);
+void add_broken_brick_piece(int x, int y, int xm, int ym);
+void add_bouncy_brick(int x, int y);
+void add_bad_guy(int x, int y, int kind);
+void add_score(int x, int y, int s);
+void trybumpbadguy(int x, int y, int sx);
+void add_upgrade(int x, int y, int kind);
+void killtux(int mode);
+void add_bullet(int x, int y, int dir, int xm);
+
+
+/* --- GAME LOOP! --- */
+
+int gameloop(void)
+{
+  int done, quit, x, y, i, j;
+  SDL_Event event;
+  SDL_Rect src, dest;
+  SDLKey key;
+  Uint32 last_time, now_time;
+  char str[10];
+  
+  
+  /* Clear screen: */
+  
+  clearscreen(0, 0, 0);
+  updatescreen();
+  
+  
+  /* Init the game: */
+
+  initgame();
+  loadshared();
+  loadlevel();
+  loadlevelgfx();
+  loadlevelsong();
+  
+  
+  /* --- MAIN GAME LOOP!!! --- */
+  
+  done = 0;
+  quit = 0;
+  frame = 0;
+  tux_frame_main = 0;
+  tux_frame = 0;
+  
+  do
+    {
+      last_time = SDL_GetTicks();
+      frame++;
+      
+      
+      /* Handle events: */
+
+      old_fire = fire;
+      
+      while (SDL_PollEvent(&event))
+       {
+         if (event.type == SDL_QUIT)
+           {
+             /* Quit event - quit: */
+             
+             quit = 1;
+           }
+         else if (event.type == SDL_KEYDOWN)
+           {
+              /* A keypress! */
+              
+              key = event.key.keysym.sym;
+              
+              if (key == SDLK_ESCAPE)
+                {
+                  /* Escape: Quit the game and return to main menu: */
+                  
+                  done = 1;
+                }
+             else if (key == SDLK_RIGHT)
+               {
+                 right = DOWN;
+               }
+             else if (key == SDLK_LEFT)
+               {
+                 left = DOWN;
+               }
+             else if (key == SDLK_UP)
+               {
+                 up = DOWN;
+               }
+             else if (key == SDLK_DOWN)
+               {
+                 down = DOWN;
+               }
+             else if (key == SDLK_LCTRL)
+               {
+                 fire = DOWN;
+               }
+           }
+         else if (event.type == SDL_KEYUP)
+           {
+              /* A keyrelease! */
+              
+              key = event.key.keysym.sym;
+              
+             if (key == SDLK_RIGHT)
+               {
+                 right = UP;
+               }
+             else if (key == SDLK_LEFT)
+               {
+                 left = UP;
+               }
+             else if (key == SDLK_UP)
+               {
+                 up = UP;
+               }
+             else if (key == SDLK_DOWN)
+               {
+                 down = UP;
+               }
+             else if (key == SDLK_LCTRL)
+               {
+                 fire = UP;
+               }
+             else if (key == SDLK_TAB)
+               {
+                 tux_size = !tux_size;
+               }
+           }
+#ifdef JOY_YES
+         else if (event.type == SDL_JOYAXISMOTION)
+           {
+             if (event.jaxis.axis == JOY_X)
+               {
+                 if (event.jaxis.value < -256)
+                   left = DOWN;
+                 else
+                   left = UP;
+
+                 if (event.jaxis.value > 256)
+                   right = DOWN;
+                 else
+                   right = UP;
+               }
+             else if (event.jaxis.axis == JOY_Y)
+               {
+                 if (event.jaxis.value > 256)
+                   down = DOWN;
+                 else
+                   down = UP;
+               }
+           }
+         else if (event.type == SDL_JOYBUTTONDOWN)
+           {
+             if (event.jbutton.button == JOY_A)
+               up = DOWN;
+             else if (event.jbutton.button == JOY_B)
+               fire = DOWN;
+           }
+         else if (event.type == SDL_JOYBUTTONUP)
+           {
+             if (event.jbutton.button == JOY_A)
+               up = UP;
+             else if (event.jbutton.button == JOY_B)
+               fire = UP;
+           }
+#endif
+       }
+      
+      
+      /* --- HANDLE TUX! --- */
+      
+      /* Handle key and joystick state: */
+      
+      if (!tux_dying)
+       {
+         if (right == DOWN && left == UP)
+           {
+             if (jumping == NO)
+               {
+                 if (tux_xm < -SKID_XM && !tux_skidding &&
+                     tux_dir == LEFT)
+                   {
+                     tux_skidding = SKID_TIME;
+#ifndef NOSOUND
+                     playsound(sounds[SND_SKID]);
+#endif
+                   }
+                 tux_dir = RIGHT;
+               }
+             
+             if (tux_xm < 0 && !isice(tux_x, tux_y + 32, scroll_x) &&
+                 !tux_skidding)
+               {
+                 tux_xm = 0;
+               }
+             
+             if (!tux_duck)
+               {
+                 if (tux_dir == RIGHT)
+                   {
+                     /* Facing the direction we're jumping?  Go full-speed: */
+                     
+                     if (fire == UP)
+                       {
+                         tux_xm = tux_xm + WALK_SPEED;
+                         
+                         if (tux_xm > MAX_WALK_XM)
+                           tux_xm = MAX_WALK_XM;
+                       }
+                     else if (fire == DOWN)
+                       {
+                         tux_xm = tux_xm + RUN_SPEED;
+                         
+                         if (tux_xm > MAX_RUN_XM)
+                           tux_xm = MAX_RUN_XM;
+                       }
+                   }
+                 else
+                   {
+                     /* Not facing the direction we're jumping? 
+                        Go half-speed: */
+                     
+                     tux_xm = tux_xm + WALK_SPEED / 2;
+                     
+                     if (tux_xm > MAX_WALK_XM / 2)
+                       tux_xm = MAX_WALK_XM / 2;
+                   }
+               }
+           }
+         else if (left == DOWN && right == UP)
+           {
+             if (jumping == NO)
+               {
+                 if (tux_xm > SKID_XM && !tux_skidding &&
+                     tux_dir == RIGHT)
+                   {
+                     tux_skidding = SKID_TIME;
+#ifndef NOSOUND
+                     playsound(sounds[SND_SKID]);
+#endif
+                   }
+                 tux_dir = LEFT;
+               }
+             
+             if (tux_xm > 0 && !isice(tux_x, tux_y + 32, scroll_x) &&
+                 !tux_skidding)
+               {
+                 tux_xm = 0;
+               }
+             
+             if (!tux_duck)
+               {
+                 if (tux_dir == LEFT)
+                   {
+                     /* Facing the direction we're jumping?  Go full-speed: */
+                     
+                     if (fire == UP)
+                       {
+                         tux_xm = tux_xm - WALK_SPEED;
+                         
+                         if (tux_xm < -MAX_WALK_XM)
+                           tux_xm = -MAX_WALK_XM;
+                       }
+                     else if (fire == DOWN)
+                       {
+                         tux_xm = tux_xm - RUN_SPEED;
+                         
+                         if (tux_xm < -MAX_RUN_XM)
+                           tux_xm = -MAX_RUN_XM;
+                       }
+                   }
+                 else
+                   {
+                     /* Not facing the direction we're jumping?
+                        Go half-speed: */
+                     
+                     tux_xm = tux_xm - WALK_SPEED / 2;
+                     
+                     if (tux_xm < -MAX_WALK_XM / 2)
+                       tux_xm = -MAX_WALK_XM / 2;
+                   }
+               }
+           }
+         
+         
+         /* Jump/jumping? */
+         
+         if (up == DOWN)
+           {
+             if (jump_counter == 0)
+               {
+                 /* Taking off? */
+                 
+                 if (!issolid(tux_x, tux_y + 32, scroll_x) ||
+                     tux_ym != 0)
+                   {
+                     /* If they're not on the ground, or are currently moving
+                        vertically, don't jump! */
+                     
+                     jump_counter = MAX_JUMP_COUNT;
+                   }
+                 else
+                   {
+                     /* Make sure we're not standing back up into a solid! */
+                     
+                     if (tux_size == SMALL || tux_duck == NO ||
+                         !issolid(tux_x, tux_y, scroll_x))
+                       {
+                         jumping = YES;
+                        
+#ifndef NOSOUND
+                         if (tux_size == SMALL)
+                           playsound(sounds[SND_JUMP]);
+                         else
+                           playsound(sounds[SND_BIGJUMP]);
+#endif
+                       }
+                   }
+               }
+             
+             
+             /* Keep jumping for a while: */
+             
+             if (jump_counter < MAX_JUMP_COUNT)
+               {
+                 tux_ym = tux_ym - JUMP_SPEED;
+                 jump_counter++;
+               }
+           }
+         else
+           jump_counter = 0;
+         
+         
+         /* Shoot! */
+         
+         if (fire == DOWN && old_fire == UP && tux_got_coffee)
+           {
+             add_bullet(tux_x + scroll_x, tux_y, tux_dir, tux_xm);
+           }
+         
+         
+         /* Duck! */
+         
+         if (down == DOWN)
+           {
+             if (tux_size == BIG)
+               tux_duck = YES;
+           }
+         else
+           {
+             if (tux_size == BIG && tux_duck == YES)
+               {
+                 /* Make sure we're not standing back up into a solid! */
+                 
+                 if (!issolid(tux_x, tux_y - 32, scroll_x))
+                   tux_duck = NO;
+               }
+             else
+               tux_duck = NO;
+           }
+       } /* !tux_dying */
+      else
+       {
+         tux_ym = tux_ym + GRAVITY;
+         
+         if (tux_y >= 480)
+           {
+#ifndef NOSOUND
+             if (use_sound)
+               {
+                 if (Mix_PlayingMusic())
+                   Mix_HaltMusic();
+               }
+#endif
+             
+             lives--;
+             loadlevel();
+           }
+       }
+      
+      
+      /* Move tux: */
+      
+      tux_x = tux_x + tux_xm;
+      tux_y = tux_y + tux_ym;
+      
+      
+      /* Keep tux in bounds: */
+      
+      if (tux_x < 0)
+       tux_x = 0;
+      else if (tux_x > 320 && scroll_x < ((LEVEL_WIDTH * 32) - 640))
+       {
+         /* Scroll the screen in past center: */
+         
+         scroll_x = scroll_x + (tux_x - 320);
+         tux_x = 320;
+         
+         if (scroll_x > ((LEVEL_WIDTH * 32) - 640))
+           scroll_x = ((LEVEL_WIDTH * 32) - 640);
+       }
+      else if (tux_x > 608)
+       {
+         /* ... unless there's no more to scroll! */
+         
+         tux_x = 608;
+       }
+      
+      
+      /* Land: */
+      
+      if (!tux_dying)
+       {
+         if (issolid(tux_x, tux_y + 31, scroll_x) &&
+             !issolid(tux_x - tux_xm, tux_y + 31, scroll_x))
+           {
+             while (issolid(tux_x, tux_y + 31, scroll_x))
+               {
+                 if (tux_xm < 0)
+                   tux_x++;
+                 else if (tux_xm > 0)
+                   tux_x--;
+               }
+             
+             tux_xm = 0;
+           }
+         
+         if (issolid(tux_x, tux_y, scroll_x) &&
+             !issolid(tux_x - tux_xm, tux_y, scroll_x))
+           {
+             while (issolid(tux_x, tux_y, scroll_x))
+               {
+                 if (tux_xm < 0)
+                   tux_x++;
+                 else if (tux_xm > 0)
+                   tux_x--;
+               }
+             
+             tux_xm = 0;
+           }
+         
+         if (issolid(tux_x, tux_y + 31, scroll_x))
+           {
+             /* Set down properly: */
+             
+             while (issolid(tux_x, tux_y + 31, scroll_x))
+               {
+                 if (tux_ym < 0)
+                   tux_y++;
+                 else if (tux_ym > 0)
+                   tux_y--;
+               }
+             
+             
+             /* Reset score multiplier (for mutli-hits): */
+             
+             if (tux_ym > 0)
+               score_multiplier = 1;
+             
+             
+             /* Stop jumping! */
+             
+             tux_ym = 0;
+             jumping = NO;
+           }
+         
+         
+         /* Bump into things: */
+         
+         if (issolid(tux_x, tux_y, scroll_x) ||
+             (tux_size == BIG && !tux_duck &&
+              (issolid(tux_x, tux_y - 32, scroll_x))))
+           {
+             if (!issolid(tux_x - tux_xm, tux_y, scroll_x) &&
+                 (tux_size == SMALL || tux_duck ||
+                  !issolid(tux_x - tux_xm, tux_y - 32, scroll_x)))
+               {
+                 tux_x = tux_x - tux_xm;
+                 tux_xm = 0;
+               }
+             else if (!issolid(tux_x, tux_y - tux_ym, scroll_x) &&
+                      (tux_size == SMALL || tux_duck ||
+                       !issolid(tux_x, tux_y - 32 - tux_ym, scroll_x)))
+               {
+                 if (tux_ym <= 0)
+                   {
+                     /* Jumping up? */
+                     
+                     if (tux_size == BIG)
+                       {
+                         /* Break bricks and empty boxes: */
+                         
+                         if (!tux_duck)
+                           {
+                             if (isbrick(tux_x, tux_y - 32, scroll_x) ||
+                                 isfullbox(tux_x, tux_y - 32, scroll_x))
+                               {
+                                 trygrabdistro(tux_x, tux_y - 64, scroll_x,
+                                               BOUNCE);
+                                 trybumpbadguy(tux_x, tux_y - 96, scroll_x);
+
+                                 if (isfullbox(tux_x, tux_y - 32,
+                                               scroll_x))
+                                   {
+                                     bumpbrick(tux_x, tux_y - 32,
+                                               scroll_x);
+                                   }
+
+                                 trybreakbrick(tux_x, tux_y - 32, scroll_x);
+                                 tryemptybox(tux_x, tux_y - 32, scroll_x);
+                               }
+                             
+                             if (isbrick(tux_x + 31, tux_y - 32, scroll_x) ||
+                                 isfullbox(tux_x + 31, tux_y - 32, scroll_x))
+                               {
+                                 trygrabdistro(tux_x + 31,
+                                               tux_y - 64,
+                                               scroll_x,
+                                               BOUNCE);
+                                 trybumpbadguy(tux_x + 31,
+                                               tux_y - 96,
+                                               scroll_x);
+                                 
+                                 if (isfullbox(tux_x + 31, tux_y - 32,
+                                               scroll_x))
+                                   {
+                                     bumpbrick(tux_x + 31, tux_y - 32,
+                                               scroll_x);
+                                   }
+                                 
+                                 trybreakbrick(tux_x + 31,
+                                               tux_y - 32,
+                                               scroll_x);
+                                 tryemptybox(tux_x + 31,
+                                             tux_y - 32,
+                                             scroll_x);
+                               }
+                           }
+                         else /* ducking */
+                           {
+                             if (isbrick(tux_x, tux_y, scroll_x) ||
+                                 isfullbox(tux_x, tux_y, scroll_x))
+                               {
+                                 trygrabdistro(tux_x, tux_y - 32, scroll_x,
+                                               BOUNCE);
+                                 trybumpbadguy(tux_x, tux_y - 64, scroll_x);
+                                 if (isfullbox(tux_x, tux_y, scroll_x))
+                                   bumpbrick(tux_x, tux_y, scroll_x);
+                                 trybreakbrick(tux_x, tux_y, scroll_x);
+                                 tryemptybox(tux_x, tux_y, scroll_x);
+                               }
+                             
+                             if (isbrick(tux_x + 31, tux_y, scroll_x) ||
+                                 isfullbox(tux_x + 31, tux_y, scroll_x))
+                               {
+                                 trygrabdistro(tux_x + 31,
+                                               tux_y - 32,
+                                               scroll_x,
+                                               BOUNCE);
+                                 trybumpbadguy(tux_x + 31,
+                                               tux_y - 64,
+                                               scroll_x);
+                                 if (isfullbox(tux_x + 31, tux_y, scroll_x))
+                                   bumpbrick(tux_x + 31, tux_y, scroll_x);
+                                 trybreakbrick(tux_x + 31, tux_y, scroll_x);
+                                 tryemptybox(tux_x + 31, tux_y, scroll_x);
+                               }
+                           }
+                       }
+                     else
+                       {
+                         /* It's a brick and we're small, make the brick
+                            bounce, and grab any distros above it: */
+                         
+                         if (isbrick(tux_x, tux_y, scroll_x) ||
+                             isfullbox(tux_x, tux_y, scroll_x))
+                           {
+                             trygrabdistro(tux_x, tux_y - 32, scroll_x,
+                                           BOUNCE);
+                             trybumpbadguy(tux_x, tux_y - 64, scroll_x);
+                             bumpbrick(tux_x, tux_y, scroll_x);
+                             tryemptybox(tux_x, tux_y, scroll_x);
+                           }
+                         
+                         if (isbrick(tux_x + 31, tux_y, scroll_x) ||
+                             isfullbox(tux_x + 31, tux_y, scroll_x))
+                           {
+                             trygrabdistro(tux_x + 31, tux_y - 32, scroll_x,
+                                           BOUNCE);
+                             trybumpbadguy(tux_x + 31, tux_y - 64, scroll_x);
+                             bumpbrick(tux_x + 31, tux_y, scroll_x);
+                             tryemptybox(tux_x + 31, tux_y, scroll_x);
+                           }
+
+
+                         /* Get a distro from a brick? */
+                         
+                         if (shape(tux_x, tux_y, scroll_x) == 'x' ||
+                             shape(tux_x, tux_y, scroll_x) == 'y')
+                           {
+                             add_bouncy_distro(((tux_x + scroll_x + 1)
+                                                / 32) * 32,
+                                               (tux_y / 32) * 32);
+                            
+                             if (counting_distros == NO)
+                             {
+                               counting_distros = YES;
+                               distro_counter = 100;
+                             }
+
+                             if (distro_counter <= 0)
+                               change(tux_x, tux_y, scroll_x, 'a');
+                             
+#ifndef NOSOUND
+                             playsound(sounds[SND_DISTRO]);
+#endif
+                             score = score + SCORE_DISTRO;
+                             distros++;
+                           }
+                         else if (shape(tux_x + 31, tux_y, scroll_x) == 'x' ||
+                             shape(tux_x + 31, tux_y, scroll_x) == 'y')
+                           {
+                             add_bouncy_distro(((tux_x + scroll_x + 1 + 31)
+                                                / 32) * 32,
+                                               (tux_y / 32) * 32);
+                             
+                             if (counting_distros == NO)
+                             {
+                               counting_distros = YES;
+                               distro_counter = 100;
+                             }
+
+                             if (distro_counter <= 0)
+                               change(tux_x + 31, tux_y, scroll_x, 'a');
+                             
+#ifndef NOSOUND
+                             playsound(sounds[SND_DISTRO]);
+#endif
+                             score = score + SCORE_DISTRO;
+                             distros++;
+                           }
+                       }
+                     
+                     
+                     /* Bump head: */
+                     
+                     tux_y = (tux_y / 32) * 32 + 30;
+                   }
+                 else
+                   {
+                     /* Land on feet: */
+                     
+                     tux_y = (tux_y / 32) * 32 - 32;
+                   }
+                 
+                 tux_ym = 0;
+                 jumping = NO;
+                 jump_counter = MAX_JUMP_COUNT;
+               }
+           }
+       }
+      
+      
+      /* Grab distros: */
+      
+      if (!tux_dying)
+       {
+         trygrabdistro(tux_x, tux_y, scroll_x, NO_BOUNCE);
+         trygrabdistro(tux_x + 31, tux_y, scroll_x, NO_BOUNCE);
+         
+         if (tux_size == BIG && !tux_duck)
+           {
+             trygrabdistro(tux_x, tux_y - 32, scroll_x, NO_BOUNCE);
+             trygrabdistro(tux_x + 31, tux_y - 32, scroll_x, NO_BOUNCE);
+           }
+       }
+     
+
+      /* Keep in-bounds, vertically: */
+      
+      if (tux_y < 0)
+       tux_y = 0;
+      else if (tux_y > 480)
+       {
+         killtux(KILL);
+       }
+      
+      
+      /* Slow down horizontally: */
+      
+      if (!tux_dying)
+       {
+         if (right == UP && left == UP)
+           {
+             if (isice(tux_x, tux_y + 32, scroll_x) ||
+                 !issolid(tux_x, tux_y + 32, scroll_x))
+               {
+                 /* Slowly on ice or in air: */
+                 
+                 if (tux_xm > 0)
+                   tux_xm--;
+                 else if (tux_xm < 0)
+                   tux_xm++;
+               }
+             else
+               {
+                 /* Quickly, otherwise: */
+                 
+                 tux_xm = tux_xm / 2;
+               }
+           }
+         
+         
+         /* Drop vertically: */
+         
+         if (!issolid(tux_x, tux_y + 32, scroll_x))
+           {
+             tux_ym = tux_ym + GRAVITY;
+             
+             if (tux_ym > MAX_YM)
+               tux_ym = MAX_YM;
+           }
+       }
+      
+      
+      if (tux_safe > 0)
+       tux_safe--;
+      
+      
+      /* ---- DONE HANDLING TUX! --- */
+      
+      
+      /* Handle bouncy distros: */
+      
+      for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
+       {
+         if (bouncy_distros[i].alive)
+           {
+             bouncy_distros[i].y = bouncy_distros[i].y + bouncy_distros[i].ym;
+             
+             bouncy_distros[i].ym++;
+             
+             if (bouncy_distros[i].ym >= 0)
+               bouncy_distros[i].alive = NO;
+           }
+       }
+      
+      
+      /* Handle broken bricks: */
+      
+      for (i = 0; i < NUM_BROKEN_BRICKS; i++)
+       {
+         if (broken_bricks[i].alive)
+           {
+             broken_bricks[i].x = broken_bricks[i].x + broken_bricks[i].xm;
+             broken_bricks[i].y = broken_bricks[i].y + broken_bricks[i].ym;
+             
+             broken_bricks[i].ym++;
+             
+             if (broken_bricks[i].ym >= 0)
+               broken_bricks[i].alive = NO;
+           }
+       }
+
+
+      /* Handle distro counting: */
+
+      if (counting_distros == YES)
+      {
+       distro_counter--;
+
+       if (distro_counter <= 0)
+          counting_distros = -1;
+      }
+
+      
+      /* Handle bouncy bricks: */
+      
+      for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
+       {
+         if (bouncy_bricks[i].alive)
+           {
+             bouncy_bricks[i].offset = (bouncy_bricks[i].offset +
+                                        bouncy_bricks[i].offset_m);
+             
+             /* Go back down? */
+             
+             if (bouncy_bricks[i].offset < -BOUNCY_BRICK_MAX_OFFSET)
+               bouncy_bricks[i].offset_m = BOUNCY_BRICK_SPEED;
+             
+             
+             /* Stop bouncing? */
+             
+             if (bouncy_bricks[i].offset == 0)
+               bouncy_bricks[i].alive = NO;
+           }
+       }
+
+      
+      /* Handle floating scores: */
+      
+      for (i = 0; i < NUM_FLOATING_SCORES; i++)
+       {
+         if (floating_scores[i].alive)
+           {
+             floating_scores[i].y = floating_scores[i].y - 2;
+             floating_scores[i].timer--;
+             
+             if (floating_scores[i].timer <= 0)
+               floating_scores[i].alive = NO;
+           }
+       }
+      
+      
+      /* Handle bullets: */
+      
+      for (i = 0; i < NUM_BULLETS; i++)
+       {
+         if (bullets[i].alive)
+           {
+             bullets[i].x = bullets[i].x + bullets[i].xm;
+             bullets[i].y = bullets[i].y + bullets[i].ym;
+             
+             if (issolid(bullets[i].x, bullets[i].y, 0))
+               {
+                 if (issolid(bullets[i].x, bullets[i].y - bullets[i].ym, 0))
+                   bullets[i].alive = NO;
+                 else
+                   {
+                     if (bullets[i].ym >= 0)
+                       {
+                         bullets[i].y = (bullets[i].y / 32) * 32 - 8;
+                       }
+                     bullets[i].ym = -bullets[i].ym;
+                   }
+               }
+             
+             bullets[i].ym = bullets[i].ym + GRAVITY;
+             
+             if (bullets[i].x < scroll_x ||
+                 bullets[i].x > scroll_x + 640)
+               {
+                 bullets[i].alive = NO;
+               }
+           }
+         
+         
+         if (bullets[i].alive)
+           {
+             for (j = 0; j < NUM_BAD_GUYS; j++)
+               {
+                 if (bad_guys[j].alive && !bad_guys[j].dying)
+                   {
+                     if (bullets[i].x >= bad_guys[j].x - 4 &&
+                         bullets[i].x <= bad_guys[j].x + 32 + 4 &&
+                         bullets[i].y >= bad_guys[j].y - 4 &&
+                         bullets[i].y <= bad_guys[j].y + 32 + 4)
+                       {
+                         bullets[i].alive = 0;
+                         bad_guys[j].dying = FALLING;
+                         bad_guys[j].ym = -8;
+#ifndef NOSOUND
+                         playsound(sounds[SND_FALL]);
+#endif
+                       }
+                   }
+               }
+           }
+       }
+      
+      
+      /* Handle background timer: */
+      
+      if (super_bkgd_time)
+       super_bkgd_time--;
+      
+      
+      /* Handle invincibility timer: */
+      
+      if (tux_invincible_time)
+       tux_invincible_time--;
+      
+      
+      /* Handle upgrades: */
+      
+      for (i = 0; i < NUM_UPGRADES; i++)
+       {
+         if (upgrades[i].alive)
+           {
+             if (upgrades[i].height < 32)
+               {
+                 /* Rise up! */
+                 
+                 upgrades[i].height++;
+               }
+             else
+               {
+                 /* Move around? */
+                 
+                 if (upgrades[i].kind == UPGRADE_MINTS ||
+                     upgrades[i].kind == UPGRADE_HERRING)
+                   {
+                     upgrades[i].x = upgrades[i].x + upgrades[i].xm;
+                     upgrades[i].y = upgrades[i].y + upgrades[i].ym;
+                     
+                     if (issolid(upgrades[i].x, upgrades[i].y + 31, 0) ||
+                         issolid(upgrades[i].x + 31, upgrades[i].y + 31, 0))
+                       {
+                         if (upgrades[i].ym > 0)
+                           {
+                             if (upgrades[i].kind == UPGRADE_MINTS)
+                               {
+                                 upgrades[i].ym = 0;
+                               }
+                             else if (upgrades[i].kind == UPGRADE_HERRING)
+                               {
+                                 upgrades[i].ym = -24;
+                               }
+                             
+                             upgrades[i].y = (upgrades[i].y / 32) * 32;
+                           }
+                       }
+                     else
+                       upgrades[i].ym = upgrades[i].ym + GRAVITY;
+                     
+                     if (issolid(upgrades[i].x, upgrades[i].y, 0))
+                       {
+                         upgrades[i].xm = -upgrades[i].xm;
+                       }
+                   }
+                 
+                 
+                 /* Off the screen?  Kill it! */
+                 
+                 if (upgrades[i].x < scroll_x)
+                   upgrades[i].alive = NO;
+                 
+                 
+                 /* Did the player grab it? */
+                 
+                 if (tux_x + scroll_x >= upgrades[i].x - 32 &&
+                     tux_x + scroll_x <= upgrades[i].x + 32 &&
+                     tux_y >= upgrades[i].y - 32 &&
+                     tux_y <= upgrades[i].y + 32)
+                   {
+                     /* Remove the upgrade: */
+                     
+                     upgrades[i].alive = NO;
+                     
+                     
+                     /* Affect the player: */
+                     
+                     if (upgrades[i].kind == UPGRADE_MINTS)
+                       {
+#ifndef NOSOUND
+                          playsound(sounds[SND_EXCELLENT]);
+#endif
+                         tux_size = BIG;
+                         super_bkgd_time = 8;
+                       }
+                     else if (upgrades[i].kind == UPGRADE_COFFEE)
+                       {
+#ifndef NOSOUND
+                         playsound(sounds[SND_COFFEE]);
+#endif
+                         tux_got_coffee = YES;
+                         super_bkgd_time = 4;
+                       }
+                     else if (upgrades[i].kind == UPGRADE_HERRING)
+                       {
+#ifndef NOSOUND
+                         playsound(sounds[SND_HERRING]);
+#endif
+                         tux_invincible_time = 200;
+                         super_bkgd_time = 4;
+                       }
+                   }
+               }
+           }
+       }
+      
+      
+      /* Handle bad guys: */
+      
+      for (i = 0; i < NUM_BAD_GUYS; i++)
+       {
+         if (bad_guys[i].alive)
+           {
+             if (bad_guys[i].seen)
+               {
+                 if (bad_guys[i].kind == BAD_BSOD)
+                   {
+                     /* --- BLUE SCREEN OF DEATH MONSTER: --- */
+                     
+                     /* Move left/right: */
+                     
+                     if (bad_guys[i].dying == NO ||
+                         bad_guys[i].dying == FALLING)
+                       {
+                         if (bad_guys[i].dir == RIGHT)
+                           bad_guys[i].x = bad_guys[i].x + 4;
+                         else if (bad_guys[i].dir == LEFT)
+                           bad_guys[i].x = bad_guys[i].x - 4;
+                       }
+                     
+                     
+                     /* Move vertically: */
+                     
+                     bad_guys[i].y = bad_guys[i].y + bad_guys[i].ym;
+                     
+                     
+                     /* Bump into things horizontally: */
+                     
+                     if (!bad_guys[i].dying)
+                       {
+                         if (issolid(bad_guys[i].x, bad_guys[i].y, 0))
+                           bad_guys[i].dir = !bad_guys[i].dir;
+                       }
+                     
+                     
+                     /* Bump into other bad guys: */
+                     
+                     for (j = 0; j < NUM_BAD_GUYS; j++)
+                       {
+                         if (j != i && bad_guys[j].alive &&
+                             !bad_guys[j].dying && !bad_guys[i].dying &&
+                             bad_guys[i].x >= bad_guys[j].x - 32 &&
+                             bad_guys[i].x <= bad_guys[j].x + 32 &&
+                             bad_guys[i].y >= bad_guys[j].y - 32 &&
+                             bad_guys[i].y <= bad_guys[j].y + 32)
+                           {
+                             bad_guys[i].dir = !bad_guys[i].dir;
+                           }
+                       }
+                     
+                     
+                     /* Fall if we get off the ground: */
+                     
+                     if (bad_guys[i].dying != FALLING)
+                       {
+                         if (!issolid(bad_guys[i].x, bad_guys[i].y + 32, 0) &&
+                             bad_guys[i].ym < MAX_YM)
+                           {
+                             bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
+                           }
+                         else
+                           {
+                             /* Land: */
+                             
+                             if (bad_guys[i].ym > 0)
+                               {
+                                 bad_guys[i].y = (bad_guys[i].y / 32) * 32;
+                                 bad_guys[i].ym = 0;
+                               }
+                           }
+                       }
+                     else
+                       bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
+                     
+                     if (bad_guys[i].y > 480)
+                       bad_guys[i].alive = NO;
+                   }
+                 else if (bad_guys[i].kind == BAD_LAPTOP)
+                   {
+                     /* --- LAPTOP MONSTER: --- */
+                     
+                     /* Move left/right: */
+                     
+                     if (bad_guys[i].mode != FLAT && bad_guys[i].mode != KICK)
+                       {
+                         if (bad_guys[i].dying == NO ||
+                             bad_guys[i].dying == FALLING)
+                           {
+                             if (bad_guys[i].dir == RIGHT)
+                               bad_guys[i].x = bad_guys[i].x + 4;
+                             else if (bad_guys[i].dir == LEFT)
+                               bad_guys[i].x = bad_guys[i].x - 4;
+                           }
+                       }
+                     else if (bad_guys[i].mode == KICK)
+                       {
+                         if (bad_guys[i].dir == RIGHT)
+                           bad_guys[i].x = bad_guys[i].x + 16;
+                         else if (bad_guys[i].dir == LEFT)
+                           bad_guys[i].x = bad_guys[i].x - 16;
+                       }
+                     
+                     
+                     /* Move vertically: */
+                     
+                     bad_guys[i].y = bad_guys[i].y + bad_guys[i].ym;
+                     
+                     
+                     /* Bump into things horizontally: */
+                     
+                     if (!bad_guys[i].dying)
+                       {
+                         if (issolid(bad_guys[i].x, bad_guys[i].y, 0))
+                           {
+                             bad_guys[i].dir = !bad_guys[i].dir;
+                            
+#ifndef NOSOUND
+                             if (bad_guys[i].mode == KICK)
+                               playsound(sounds[SND_RICOCHET]);
+#endif
+                           }
+                       }
+                     
+                     
+                     /* Bump into other bad guys: */
+                     
+                     for (j = 0; j < NUM_BAD_GUYS; j++)
+                       {
+                         if (j != i && bad_guys[j].alive &&
+                             !bad_guys[j].dying && !bad_guys[i].dying &&
+                             bad_guys[i].x >= bad_guys[j].x - 32 &&
+                             bad_guys[i].x <= bad_guys[j].x + 32 &&
+                             bad_guys[i].y >= bad_guys[j].y - 32 &&
+                             bad_guys[i].y <= bad_guys[j].y + 32)
+                           {
+                             if (bad_guys[i].mode != KICK)
+                               bad_guys[i].dir = !bad_guys[i].dir;
+                             else
+                               {
+                                 /* We're in kick mode, kill the other guy: */
+                                 
+                                 bad_guys[j].dying = FALLING;
+                                 bad_guys[j].ym = -8;
+#ifndef NOSOUND
+                                 playsound(sounds[SND_FALL]);
+#endif
+
+                                 add_score(bad_guys[i].x - scroll_x,
+                                           bad_guys[i].y, 100);
+                               }
+                           }
+                       }
+                     
+                     
+                     /* Fall if we get off the ground: */
+                     
+                     if (bad_guys[i].dying != FALLING)
+                       {
+                         if (!issolid(bad_guys[i].x, bad_guys[i].y + 32, 0) &&
+                             bad_guys[i].ym < MAX_YM)
+                           {
+                             bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
+                           }
+                         else
+                           {
+                             /* Land: */
+                             
+                             if (bad_guys[i].ym > 0)
+                               {
+                                 bad_guys[i].y = (bad_guys[i].y / 32) * 32;
+                                 bad_guys[i].ym = 0;
+                               }
+                           }
+                       }
+                     else
+                       bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
+                     
+                     if (bad_guys[i].y > 480)
+                       bad_guys[i].alive = NO;
+                   }
+                 else if (bad_guys[i].kind == BAD_MONEY)
+                   {
+                     /* --- MONEY BAGS: --- */
+                    
+                     
+                     /* Move vertically: */
+                     
+                     bad_guys[i].y = bad_guys[i].y + bad_guys[i].ym;
+
+
+                     /* Fall if we get off the ground: */
+                     
+                     if (bad_guys[i].dying != FALLING)
+                       {
+                         if (!issolid(bad_guys[i].x, bad_guys[i].y + 32, 0))
+                         {
+                           if (bad_guys[i].ym < MAX_YM)
+                             {
+                               bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
+                             }
+                         }
+                         else
+                           {
+                             /* Land: */
+                             
+                             if (bad_guys[i].ym > 0)
+                               {
+                                 bad_guys[i].y = (bad_guys[i].y / 32) * 32;
+                                 bad_guys[i].ym = -MAX_YM;
+                               }
+                           }
+                       }
+                     else
+                       bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
+                     
+                     if (bad_guys[i].y > 480)
+                       bad_guys[i].alive = NO;
+                   }
+                 else if (bad_guys[i].kind == -1)
+                   {
+                   }
+                 
+                 
+                 /* Kill it if the player jumped on it: */
+                 
+                 if (!bad_guys[i].dying && !tux_dying && !tux_safe &&
+                     tux_x + scroll_x >= bad_guys[i].x - 32 &&
+                     tux_x + scroll_x <= bad_guys[i].x + 32 &&
+                     tux_y >= bad_guys[i].y - 32 &&
+                     tux_y <= bad_guys[i].y - 8
+                     /* &&
+                        tux_ym >= 0 */)
+                   {
+                     if (bad_guys[i].kind == BAD_BSOD)
+                       {
+                         bad_guys[i].dying = SQUISHED;
+                         bad_guys[i].timer = 16;
+                         tux_ym = -KILL_BOUNCE_YM;
+                         
+                         add_score(bad_guys[i].x - scroll_x, bad_guys[i].y,
+                                   50 * score_multiplier);
+                         
+#ifndef NOSOUND
+                         playsound(sounds[SND_SQUISH]);
+#endif
+                       }
+                     else if (bad_guys[i].kind == BAD_LAPTOP)
+                       {
+                         if (bad_guys[i].mode != FLAT)
+                           {
+                             /* Flatten! */
+                             
+                             bad_guys[i].mode = FLAT;
+                             
+                             bad_guys[i].timer = 64;
+                             
+                             tux_y = tux_y - 32;
+                           }
+                         else
+                           {
+                             /* Kick! */
+                             
+                             bad_guys[i].mode = KICK;
+                             
+                             if (tux_x + scroll_x <= bad_guys[i].x)
+                               bad_guys[i].dir = RIGHT;
+                             else
+                               bad_guys[i].dir = LEFT;
+                             
+                             bad_guys[i].timer = 8;
+                           }
+                         
+                         tux_ym = -KILL_BOUNCE_YM;
+                         
+                         add_score(bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   25 * score_multiplier);
+                        
+#ifndef NOSOUND
+                         /* playsound(sounds[SND_SQUISH]); */
+#endif
+                       }
+                     else if (bad_guys[i].kind == -1)
+                       {
+                       }
+                     
+                     score_multiplier++;
+                   }
+                 
+                 
+                 /* Hurt the player if he just touched it: */
+                 
+                 if (!bad_guys[i].dying && !tux_dying &&
+                     !tux_safe &&
+                     tux_x + scroll_x >= bad_guys[i].x - 32 &&
+                     tux_x + scroll_x <= bad_guys[i].x + 32 &&
+                     tux_y >= bad_guys[i].y - 32 &&
+                     tux_y <= bad_guys[i].y + 32)
+                   {
+                     if (bad_guys[i].mode == FLAT)
+                       {
+                         /* Kick: */
+                         
+                         bad_guys[i].mode = KICK;
+                         
+                         if (tux_x < bad_guys[i].x)
+                           {
+                             bad_guys[i].dir = RIGHT;
+                             bad_guys[i].x = bad_guys[i].x + 16;
+                           }
+                         else
+                           {
+                             bad_guys[i].dir = LEFT;
+                             bad_guys[i].x = bad_guys[i].x - 16;
+                           }
+                         
+                         bad_guys[i].timer = 8;
+                       }
+                     else if (bad_guys[i].mode == KICK)
+                       {
+                         if (tux_y < bad_guys[i].y - 16 &&
+                             bad_guys[i].timer == 0)
+                           {
+                             /* Step on (stop being kicked) */
+                             
+                             bad_guys[i].mode = FLAT;
+                             bad_guys[i].timer = 64;
+                           }
+                         else
+                           {
+                             /* Hurt if you get hit by kicked laptop: */
+                             
+                             if (bad_guys[i].timer == 0)
+                               {
+                                 if (tux_invincible_time == 0)
+                                   {
+                                     killtux(SHRINK);
+                                   }
+                                 else
+                                   {
+                                     bad_guys[i].dying = FALLING;
+                                     bad_guys[i].ym = -8;
+#ifndef NOSOUND
+                                     playsound(sounds[SND_FALL]);
+#endif
+                                   }
+                               }
+                           }
+                       }
+                     else
+                       {
+                         if (tux_invincible_time == 0)
+                           {
+                             killtux(SHRINK);
+                           }
+                         else
+                           {
+                             bad_guys[i].dying = FALLING;
+                             bad_guys[i].ym = -8;
+#ifndef NOSOUND
+                             playsound(sounds[SND_FALL]);
+#endif
+                           }
+                       }
+                   }
+                 
+                 
+                 /* Handle mode timer: */
+                 
+                 if (bad_guys[i].mode == FLAT)
+                   {
+                     bad_guys[i].timer--;
+                     
+                     if (bad_guys[i].timer <= 0)
+                       bad_guys[i].mode = NORMAL;
+                   }
+                 else if (bad_guys[i].mode == KICK)
+                   {
+                     if (bad_guys[i].timer > 0)
+                       bad_guys[i].timer--;
+                   }
+                 
+                 
+                 /* Handle dying timer: */
+                 
+                 if (bad_guys[i].dying == SQUISHED)
+                   {
+                     bad_guys[i].timer--;
+                     
+                     
+                     /* Remove it if time's up: */
+                     
+                     if (bad_guys[i].timer <= 0)
+                       bad_guys[i].alive = NO;
+                   }
+                 
+                 
+                 /* Remove if it's far off the screen: */
+                 
+                 if (bad_guys[i].x < scroll_x - OFFSCREEN_DISTANCE)
+                   bad_guys[i].alive = NO;
+               }
+             else /* !seen */
+               {
+                 /* Once it's on screen, it's activated! */
+                 
+                 if (bad_guys[i].x <= scroll_x + 640 + OFFSCREEN_DISTANCE)
+                   bad_guys[i].seen = YES;
+               }
+           }
+       }
+      
+      
+      /* Handle skidding: */
+      
+      if (tux_skidding > 0)
+       {
+         tux_skidding--;
+       }
+      
+      
+      /* Draw screen: */
+      
+      if (tux_dying && (frame % 4) == 0)
+       clearscreen(255, 255, 255);
+      else
+       {
+         if (super_bkgd_time == 0)
+           clearscreen(bkgd_red, bkgd_green, bkgd_blue);
+         else
+           drawimage(img_super_bkgd, 0, 0, NO_UPDATE);
+       }
+      
+      
+      /* Draw background: */
+      
+      for (y = 0; y < 15; y++)
+       {
+         for (x = 0; x < 21; x++)
+           {
+             drawshape(x * 32 - (scroll_x % 32), y * 32,
+                       tiles[y][x + (scroll_x / 32)]);
+           }
+       }
+
+
+      /* (Bouncy bricks): */
+      
+      for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
+       {
+         if (bouncy_bricks[i].alive)
+           {
+             if (bouncy_bricks[i].x >= scroll_x - 32 &&
+                 bouncy_bricks[i].x <= scroll_x + 640)
+               {
+                 dest.x = bouncy_bricks[i].x - scroll_x;
+                 dest.y = bouncy_bricks[i].y;
+                 dest.w = 32;
+                 dest.h = 32;
+                 
+                 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format,
+                                                        bkgd_red,
+                                                        bkgd_green,
+                                                        bkgd_blue));
+                 
+                 drawshape(bouncy_bricks[i].x - scroll_x,
+                           bouncy_bricks[i].y + bouncy_bricks[i].offset,
+                           bouncy_bricks[i].shape);
+               }
+           }
+       }
+      
+      
+      /* (Bad guys): */
+      
+      for (i = 0; i < NUM_BAD_GUYS; i++)
+       {
+         if (bad_guys[i].alive &&
+             bad_guys[i].x > scroll_x - 32 &&
+             bad_guys[i].x < scroll_x + 640)
+           {
+             if (bad_guys[i].kind == BAD_BSOD)
+               {
+                 /* --- BLUE SCREEN OF DEATH MONSTER: --- */
+                 
+                 if (bad_guys[i].dying == NO)
+                   {
+                     /* Alive: */
+                     
+                     if (bad_guys[i].dir == LEFT)
+                       {
+                         drawimage(img_bsod_left[(frame / 5) % 4],
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   NO_UPDATE);
+                       }
+                     else
+                       {
+                         drawimage(img_bsod_right[(frame / 5) % 4],
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   NO_UPDATE);
+                       }
+                   }
+                 else if (bad_guys[i].dying == FALLING)
+                   {
+                     /* Falling: */
+                     
+                     if (bad_guys[i].dir == LEFT)
+                       {
+                         drawimage(img_bsod_falling_left,
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   NO_UPDATE);
+                       }
+                     else
+                       {
+                         drawimage(img_bsod_falling_right,
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   NO_UPDATE);
+                       }
+                   }
+                 else if (bad_guys[i].dying == SQUISHED)
+                   {
+                     /* Dying - Squished: */
+                     
+                     if (bad_guys[i].dir == LEFT)
+                       {
+                         drawimage(img_bsod_squished_left,
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y + 24,
+                                   NO_UPDATE);
+                       }
+                     else
+                       {
+                         drawimage(img_bsod_squished_right,
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y + 24,
+                                   NO_UPDATE);
+                       }
+                   }
+               }
+             else if (bad_guys[i].kind == BAD_LAPTOP)
+               {
+                 /* --- LAPTOP MONSTER: --- */
+                 
+                 if (bad_guys[i].dying == NO)
+                   {
+                     /* Alive: */
+                     
+                     if (bad_guys[i].mode == NORMAL)
+                       {
+                         /* Not flat: */
+                         
+                         if (bad_guys[i].dir == LEFT)
+                           {
+                             drawimage(img_laptop_left[(frame / 5) % 3],
+                                       bad_guys[i].x - scroll_x,
+                                       bad_guys[i].y,
+                                       NO_UPDATE);
+                           }
+                         else
+                           {
+                             drawimage(img_laptop_right[(frame / 5) % 3],
+                                       bad_guys[i].x - scroll_x,
+                                       bad_guys[i].y,
+                                       NO_UPDATE);
+                           }
+                       }
+                     else
+                       {
+                         /* Flat: */
+                         
+                         if (bad_guys[i].dir == LEFT)
+                           {
+                             drawimage(img_laptop_flat_left,
+                                       bad_guys[i].x - scroll_x,
+                                       bad_guys[i].y,
+                                       NO_UPDATE);
+                           }
+                         else
+                           {
+                             drawimage(img_laptop_flat_right,
+                                       bad_guys[i].x - scroll_x,
+                                       bad_guys[i].y,
+                                       NO_UPDATE);
+                           }
+                       }
+                   }
+                 else if (bad_guys[i].dying == FALLING)
+                   {
+                     /* Falling: */
+                     
+                     if (bad_guys[i].dir == LEFT)
+                       {
+                         drawimage(img_laptop_falling_left,
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   NO_UPDATE);
+                       }
+                     else
+                       {
+                         drawimage(img_laptop_falling_right,
+                                   bad_guys[i].x - scroll_x,
+                                   bad_guys[i].y,
+                                   NO_UPDATE);
+                       }
+                   }
+               }
+             else if (bad_guys[i].kind == BAD_MONEY)
+               {
+                 if (bad_guys[i].ym > -16)
+                 {
+                   if (bad_guys[i].dir == LEFT)
+                   {
+                     drawimage(img_money_left[0],
+                               bad_guys[i].x - scroll_x,
+                               bad_guys[i].y,
+                               NO_UPDATE);
+                   }
+                   else
+                   {
+                     drawimage(img_money_right[0],
+                               bad_guys[i].x - scroll_x,
+                               bad_guys[i].y,
+                               NO_UPDATE);
+                   }
+                 }
+                 else
+                 {
+                   if (bad_guys[i].dir == LEFT)
+                   {
+                     drawimage(img_money_left[1],
+                               bad_guys[i].x - scroll_x,
+                               bad_guys[i].y,
+                               NO_UPDATE);
+                   }
+                   else
+                   {
+                     drawimage(img_money_right[1],
+                               bad_guys[i].x - scroll_x,
+                               bad_guys[i].y,
+                               NO_UPDATE);
+                   }
+                 }
+               }
+             else if (bad_guys[i].kind == -1)
+               {
+               }
+           }
+       }
+      
+      
+      /* (Tux): */
+      
+      if (right == UP && left == UP)
+       {
+         tux_frame_main = 1;
+         tux_frame = 1;
+       }
+      else
+       {
+         if ((fire == DOWN && (frame % 2) == 0) ||
+             (frame % 4) == 0)
+           tux_frame_main = (tux_frame_main + 1) % 4;
+         
+         tux_frame = tux_frame_main;
+         
+         if (tux_frame == 3)
+           tux_frame = 1;
+       }
+      
+      
+      if (tux_got_coffee && (frame % 2) == 1)
+       {
+         /* Coffee glow: */
+         
+         drawimage(img_red_glow, tux_x - 8, tux_y - 32, NO_UPDATE);
+       }
+      
+
+      if (tux_safe == 0 || (frame % 2) == 0)
+       {
+         if (tux_size == SMALL)
+           {
+             if (tux_invincible_time)
+               {
+                 /* Draw cape: */
+                 
+                 if (tux_dir == RIGHT)
+                   {
+                     drawimage(cape_right[frame % 2],
+                               tux_x, tux_y,
+                               NO_UPDATE);
+                   }
+                 else
+                   {
+                     drawimage(cape_left[frame % 2],
+                               tux_x, tux_y,
+                               NO_UPDATE);
+                   }
+               }
+             
+             
+             if (tux_dir == RIGHT)
+               {
+                 drawimage(tux_right[tux_frame], tux_x, tux_y, NO_UPDATE);
+               }
+             else
+               {
+                 drawimage(tux_left[tux_frame], tux_x, tux_y, NO_UPDATE);
+               }
+           }
+         else
+           {
+             if (tux_invincible_time)
+               {
+                 /* Draw cape: */
+                 
+                 if (tux_dir == RIGHT)
+                   {
+                     drawimage(bigcape_right[frame % 2],
+                               tux_x - 8 - 16, tux_y - 32,
+                               NO_UPDATE);
+                   }
+                 else
+                   {
+                     drawimage(bigcape_left[frame % 2],
+                               tux_x - 8, tux_y - 32,
+                               NO_UPDATE);
+                   }
+               }
+             
+             if (!tux_duck)
+               {
+                  if (!tux_skidding)
+                   {
+                     if (!jumping || tux_ym > 0)
+                       {
+                         if (tux_dir == RIGHT)
+                           {
+                             drawimage(bigtux_right[tux_frame],
+                                       tux_x - 8, tux_y - 32,
+                                       NO_UPDATE);
+                           }
+                         else
+                           {
+                             drawimage(bigtux_left[tux_frame],
+                                       tux_x - 8, tux_y - 32,
+                                       NO_UPDATE);
+                           }
+                       }
+                     else
+                       {
+                         if (tux_dir == RIGHT)
+                           {
+                             drawimage(bigtux_right_jump,
+                                       tux_x - 8, tux_y - 32,
+                                       NO_UPDATE);
+                           }
+                         else
+                           {
+                             drawimage(bigtux_left_jump,
+                                       tux_x - 8, tux_y - 32,
+                                       NO_UPDATE);
+                           }
+                       }
+                   }
+                 else
+                   {
+                     if (tux_dir == RIGHT)
+                       {
+                         drawimage(skidtux_right,
+                                   tux_x - 8, tux_y - 32,
+                                   NO_UPDATE);
+                       }
+                     else
+                       {
+                         drawimage(skidtux_left,
+                                   tux_x - 8, tux_y - 32,
+                                   NO_UPDATE);
+                       }
+                   }
+               }
+             else
+               {
+                 if (tux_dir == RIGHT)
+                   {
+                     drawimage(ducktux_right, tux_x - 8, tux_y - 16,
+                               NO_UPDATE);
+                   }
+                 else
+                   {
+                     drawimage(ducktux_left, tux_x - 8, tux_y - 16,
+                               NO_UPDATE);
+                   }
+               }
+           }
+       }
+      
+      
+      /* (Bullets): */
+      
+      for (i = 0; i < NUM_BULLETS; i++)
+       {
+         if (bullets[i].alive &&
+             bullets[i].x >= scroll_x - 4 &&
+             bullets[i].x <= scroll_x + 640)
+           {
+             drawimage(img_bullet, bullets[i].x - scroll_x, bullets[i].y,
+                       NO_UPDATE);
+           }
+       }
+
+
+      /* (Floating scores): */
+      
+      for (i = 0; i < NUM_FLOATING_SCORES; i++)
+       {
+         if (floating_scores[i].alive)
+           {
+             sprintf(str, "%d", floating_scores[i].value);
+             drawtext(str,
+                      floating_scores[i].x + 16 - strlen(str) * 8,
+                      floating_scores[i].y,
+                      letters_gold, NO_UPDATE);
+           }
+       }
+      
+      
+      /* (Upgrades): */
+      
+      for (i = 0; i < NUM_UPGRADES; i++)
+       {
+         if (upgrades[i].alive)
+           {
+             if (upgrades[i].height < 32)
+               {
+                 /* Rising up... */
+                 
+                 dest.x = upgrades[i].x - scroll_x;
+                 dest.y = upgrades[i].y + 32 - upgrades[i].height;
+                 dest.w = 32;
+                 dest.h = upgrades[i].height;
+                 
+                 src.x = 0;
+                 src.y = 0;
+                 src.w = 32;
+                 src.h = upgrades[i].height;
+                 
+                 if (upgrades[i].kind == UPGRADE_MINTS)
+                   SDL_BlitSurface(img_mints, &src, screen, &dest);
+                 else if (upgrades[i].kind == UPGRADE_COFFEE)
+                   SDL_BlitSurface(img_coffee, &src, screen, &dest);
+                 else if (upgrades[i].kind == UPGRADE_HERRING)
+                   SDL_BlitSurface(img_golden_herring, &src, screen, &dest);
+               }
+             else
+               {
+                 if (upgrades[i].kind == UPGRADE_MINTS)
+                   {
+                     drawimage(img_mints,
+                               upgrades[i].x - scroll_x, upgrades[i].y,
+                               NO_UPDATE);
+                   }
+                 else if (upgrades[i].kind == UPGRADE_COFFEE)
+                   {
+                     drawimage(img_coffee,
+                               upgrades[i].x - scroll_x, upgrades[i].y,
+                               NO_UPDATE);
+                   }
+                 else if (upgrades[i].kind == UPGRADE_HERRING)
+                   {
+                     drawimage(img_golden_herring,
+                               upgrades[i].x - scroll_x, upgrades[i].y,
+                               NO_UPDATE);
+                   }
+               }
+           }
+       }
+      
+      
+      /* (Bouncy distros): */
+      
+      for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
+       {
+         if (bouncy_distros[i].alive)
+           {
+             drawimage(img_distro[0],
+                       bouncy_distros[i].x - scroll_x,
+                       bouncy_distros[i].y,
+                       NO_UPDATE);
+           }
+       }
+
+      
+      /* (Broken bricks): */
+      
+      for (i = 0; i < NUM_BROKEN_BRICKS; i++)
+       {
+         if (broken_bricks[i].alive)
+           {
+             src.x = rand() % 16;
+             src.y = rand() % 16;
+             src.w = 16;
+             src.h = 16;
+             
+             dest.x = broken_bricks[i].x - scroll_x;
+             dest.y = broken_bricks[i].y;
+             dest.w = 16;
+             dest.h = 16;
+             
+             SDL_BlitSurface(img_brick[0], &src, screen, &dest);
+           }
+       }
+      
+      
+      /* (Status): */
+      
+      sprintf(str, "%d", score);
+      drawtext("SCORE", 0, 0, letters_blue, NO_UPDATE);
+      drawtext(str, 96, 0, letters_gold, NO_UPDATE);
+      
+      if (time_left >= 50 || (frame % 10) < 5)
+       {
+         sprintf(str, "%d", time_left);
+         drawtext("TIME", 224, 0, letters_blue, NO_UPDATE);
+         drawtext(str, 304, 0, letters_gold, NO_UPDATE);
+       }
+
+      sprintf(str, "%d", distros);
+      drawtext("DISTROS", 480, 0, letters_blue, NO_UPDATE);
+      drawtext(str, 608, 0, letters_gold, NO_UPDATE);
+      
+      
+      /* (Update it all!) */
+      
+      updatescreen();
+      
+      
+      /* Keep playing music: */
+    
+#ifndef NOSOUND
+      if (use_sound)
+        {
+          if (!Mix_PlayingMusic())
+           {
+             Mix_PlayMusic(song, 1);
+           }
+        }
+#endif
+      
+      
+      /* Pause til next frame: */
+      
+      now_time = SDL_GetTicks();
+      if (now_time < last_time + FPS)
+       SDL_Delay(last_time + FPS - now_time);
+      
+      
+      /* Handle time: */
+      
+      if ((frame % 10) == 0 && time_left > 0)
+       {
+         time_left--;
+         
+         if (time_left <= 0)
+           killtux(KILL);
+       }
+    }
+  while (!done && !quit);
+#ifndef NOSOUND
+  if (use_sound)
+    {
+      if (Mix_PlayingMusic())
+        Mix_HaltMusic();
+    }
+#endif
+  
+  unloadlevelgfx();
+  unloadlevelsong();
+  unloadshared();
+  
+  return(quit);
+}
+
+
+/* Initialize the game stuff: */
+
+void initgame(void)
+{
+  level = 0;
+  score = 0;
+  distros = 0;
+  lives = 3;
+}
+
+
+/* Load data for this level: */
+
+void loadlevel(void)
+{
+  int i, x, y;
+  FILE * fi;
+  char * filename;
+  char str[80];
+  char line[LEVEL_WIDTH + 5];
+  
+  
+  /* Reset arrays: */
+
+  for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
+    bouncy_distros[i].alive = NO;
+
+  for (i = 0; i < NUM_BROKEN_BRICKS; i++)
+    broken_bricks[i].alive = NO;
+
+  for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
+    bouncy_bricks[i].alive = NO;
+
+  for (i = 0; i < NUM_BAD_GUYS; i++)
+    bad_guys[i].alive = NO;
+
+  for (i = 0; i < NUM_FLOATING_SCORES; i++)
+    floating_scores[i].alive = NO;
+  
+  for (i = 0; i < NUM_UPGRADES; i++)
+    upgrades[i].alive = NO;
+
+  for (i = 0; i < NUM_BULLETS; i++)
+    bullets[i].alive = NO;
+
+
+  /* Load data file: */
+  
+  filename = strdup(DATA_PREFIX "/levels/level1.dat");
+  fi = fopen(filename, "r");
+  if (fi == NULL)
+    {
+      perror(filename);
+      st_shutdown();
+    }
+  free(filename);
+  
+  fgets(line, 10, fi);
+  bkgd_red = atoi(line);
+  fgets(line, 10, fi);
+  bkgd_green= atoi(line);
+  fgets(line, 10, fi);
+  bkgd_blue = atoi(line);
+  
+  for (y = 0; y < 15; y++)
+    {
+      fgets(line, LEVEL_WIDTH + 5, fi);
+      line[strlen(line) - 1] = '\0';
+      strcpy(tiles[y], line);
+    }
+  
+  fclose(fi);
+  
+  
+  /* Activate bad guys: */
+  
+  for (y = 0; y < 15; y++)
+    {
+      for (x = 0; x < LEVEL_WIDTH; x++)
+       {
+         if (tiles[y][x] >= '0' && tiles[y][x] <= '9')
+           {
+             add_bad_guy(x * 32, y * 32, tiles[y][x] - '0');
+             tiles[y][x] = '.';
+           }
+       }
+    }
+  
+  
+  /* Set defaults: */
+  
+  tux_x = 0;
+  tux_xm = 0;
+  tux_y = 240;
+  tux_ym = 0;
+  tux_dir = RIGHT;
+  tux_size = SMALL;
+  tux_got_coffee = NO;
+  tux_invincible_time = 0;
+  tux_duck = NO;
+  
+  tux_dying = NO;
+  tux_safe = TUX_SAFE_TIME;
+  
+  jumping = NO;
+  jump_counter = 0;
+  
+  tux_skidding = 0;
+  
+  scroll_x = 0;
+  
+  right = UP;
+  left = UP;
+  up = UP;
+  down = UP;
+  fire = UP;
+  old_fire = UP;
+  
+  score_multiplier = 1;
+  super_bkgd_time = 0;
+  
+  time_left = 255;
+
+  counting_distros = NO;
+  distro_counter = 0;
+  
+  
+  /* Level Intro: */
+  
+  clearscreen(0, 0, 0);
+  
+  sprintf(str, "LEVEL %d", level + 1);
+  drawcenteredtext(str, 200, letters_red, NO_UPDATE);
+  
+  sprintf(str, "%s", levelnames[level]);
+  drawcenteredtext(str, 224, letters_gold, NO_UPDATE);
+  
+  sprintf(str, "TUX x %d", lives);
+  drawcenteredtext(str, 256, letters_blue, NO_UPDATE);
+
+  SDL_Flip(screen);
+  
+  SDL_Delay(1000);
+}
+
+
+/* Load graphics: */
+
+void loadlevelgfx(void)
+{
+  img_brick[0] = load_image(DATA_PREFIX "/images/level1/brick0.png",
+                           IGNORE_ALPHA);
+  img_brick[1] = load_image(DATA_PREFIX "/images/level1/brick1.png",
+                           IGNORE_ALPHA);
+  
+  img_solid[0] = load_image(DATA_PREFIX "/images/level1/solid0.png",
+                           USE_ALPHA);
+  img_solid[1] = load_image(DATA_PREFIX "/images/level1/solid1.png",
+                           USE_ALPHA);
+  img_solid[2] = load_image(DATA_PREFIX "/images/level1/solid2.png",
+                           USE_ALPHA);
+  img_solid[3] = load_image(DATA_PREFIX "/images/level1/solid3.png",
+                           USE_ALPHA);
+
+  img_bkgd[0][0] = load_image(DATA_PREFIX "/images/level1/bkgd-00.png",
+                              USE_ALPHA);
+  img_bkgd[0][1] = load_image(DATA_PREFIX "/images/level1/bkgd-01.png",
+                              USE_ALPHA);
+  img_bkgd[0][2] = load_image(DATA_PREFIX "/images/level1/bkgd-02.png",
+                              USE_ALPHA);
+  img_bkgd[0][3] = load_image(DATA_PREFIX "/images/level1/bkgd-03.png",
+                              USE_ALPHA);
+
+  img_bkgd[1][0] = load_image(DATA_PREFIX "/images/level1/bkgd-10.png",
+                              USE_ALPHA);
+  img_bkgd[1][1] = load_image(DATA_PREFIX "/images/level1/bkgd-11.png",
+                              USE_ALPHA);
+  img_bkgd[1][2] = load_image(DATA_PREFIX "/images/level1/bkgd-12.png",
+                              USE_ALPHA);
+  img_bkgd[1][3] = load_image(DATA_PREFIX "/images/level1/bkgd-13.png",
+                              USE_ALPHA);
+}
+
+
+/* Load music: */
+
+void loadlevelsong(void)
+{
+#ifndef NOSOUND
+  song = load_song(DATA_PREFIX "/music/ji_turn.it");
+#endif
+}
+
+
+/* Free graphics data for this level: */
+
+void unloadlevelgfx(void)
+{
+  int i;
+  
+  for (i = 0; i < 2; i++)
+    {
+      SDL_FreeSurface(img_brick[i]);
+    }
+  for (i = 0; i < 4; i++)
+    {
+      SDL_FreeSurface(img_solid[i]);
+      SDL_FreeSurface(img_bkgd[0][i]);
+      SDL_FreeSurface(img_bkgd[1][i]);
+    }
+}
+
+
+/* Free music data for this level: */
+
+void unloadlevelsong(void)
+{
+#ifndef NOSOUND
+  if (use_sound)
+    {
+      Mix_FreeMusic(song);
+    }
+#endif
+}
+
+
+/* Load graphics shared between all levels: */
+
+void loadshared(void)
+{
+#ifndef NOSOUND
+  int i;
+#endif
+  
+  
+  /* Tuxes: */
+  
+  tux_right[0] = load_image(DATA_PREFIX "/images/shared/tux-right-0.png",
+                           USE_ALPHA);
+
+  tux_right[1] = load_image(DATA_PREFIX "/images/shared/tux-right-1.png",
+                           USE_ALPHA);
+
+  tux_right[2] = load_image(DATA_PREFIX "/images/shared/tux-right-2.png",
+                           USE_ALPHA);
+
+  tux_left[0] = load_image(DATA_PREFIX "/images/shared/tux-left-0.png",
+                          USE_ALPHA);
+
+  tux_left[1] = load_image(DATA_PREFIX "/images/shared/tux-left-1.png",
+                          USE_ALPHA);
+
+  tux_left[2] = load_image(DATA_PREFIX "/images/shared/tux-left-2.png",
+                          USE_ALPHA);
+
+  cape_right[0] = load_image(DATA_PREFIX "/images/shared/cape-right-0.png",
+                            USE_ALPHA);
+
+  cape_right[1] = load_image(DATA_PREFIX "/images/shared/cape-right-1.png",
+                            USE_ALPHA);
+
+  cape_left[0] = load_image(DATA_PREFIX "/images/shared/cape-left-0.png",
+                           USE_ALPHA);
+
+  cape_left[1] = load_image(DATA_PREFIX "/images/shared/cape-left-1.png",
+                           USE_ALPHA);
+
+  bigtux_right[0] = load_image(DATA_PREFIX "/images/shared/bigtux-right-0.png",
+                              USE_ALPHA);
+
+  bigtux_right[1] = load_image(DATA_PREFIX "/images/shared/bigtux-right-1.png",
+                              USE_ALPHA);
+
+  bigtux_right[2] = load_image(DATA_PREFIX "/images/shared/bigtux-right-2.png",
+                              USE_ALPHA);
+
+  bigtux_right_jump =
+    load_image(DATA_PREFIX "/images/shared/bigtux-right-jump.png", USE_ALPHA);
+
+  bigtux_left[0] = load_image(DATA_PREFIX "/images/shared/bigtux-left-0.png",
+                             USE_ALPHA);
+
+  bigtux_left[1] = load_image(DATA_PREFIX "/images/shared/bigtux-left-1.png",
+                             USE_ALPHA);
+
+  bigtux_left[2] = load_image(DATA_PREFIX "/images/shared/bigtux-left-2.png",
+                             USE_ALPHA);
+  
+  bigtux_left_jump =
+    load_image(DATA_PREFIX "/images/shared/bigtux-left-jump.png", USE_ALPHA);
+  
+  bigcape_right[0] =
+    load_image(DATA_PREFIX "/images/shared/bigcape-right-0.png",
+              USE_ALPHA);
+
+  bigcape_right[1] =
+    load_image(DATA_PREFIX "/images/shared/bigcape-right-1.png",
+              USE_ALPHA);
+
+  bigcape_left[0] =
+    load_image(DATA_PREFIX "/images/shared/bigcape-left-0.png",
+              USE_ALPHA);
+
+  bigcape_left[1] =
+    load_image(DATA_PREFIX "/images/shared/bigcape-left-1.png",
+              USE_ALPHA);
+
+  ducktux_right = load_image(DATA_PREFIX
+                            "/images/shared/ducktux-right.png",
+                            USE_ALPHA);
+
+  ducktux_left = load_image(DATA_PREFIX
+                           "/images/shared/ducktux-left.png",
+                           USE_ALPHA);
+  
+  skidtux_right = load_image(DATA_PREFIX
+                            "/images/shared/skidtux-right.png",
+                            USE_ALPHA);
+
+  skidtux_left = load_image(DATA_PREFIX
+                           "/images/shared/skidtux-left.png",
+                           USE_ALPHA);
+  
+  
+  /* Boxes: */
+  
+  img_box_full = load_image(DATA_PREFIX "/images/shared/box-full.png",
+                           IGNORE_ALPHA);
+  img_box_empty = load_image(DATA_PREFIX "/images/shared/box-empty.png",
+                            IGNORE_ALPHA);
+  
+  
+  /* Water: */
+  
+
+  img_water = load_image(DATA_PREFIX "/images/shared/water.png", IGNORE_ALPHA);
+
+  img_waves[0] = load_image(DATA_PREFIX "/images/shared/waves-0.png",
+                           USE_ALPHA);
+  
+  img_waves[1] = load_image(DATA_PREFIX "/images/shared/waves-1.png",
+                           USE_ALPHA);
+  
+  img_waves[2] = load_image(DATA_PREFIX "/images/shared/waves-2.png",
+                           USE_ALPHA);
+  
+  
+  /* Pole: */
+  
+  img_pole = load_image(DATA_PREFIX "/images/shared/pole.png", USE_ALPHA);
+  img_poletop = load_image(DATA_PREFIX "/images/shared/poletop.png",
+                          USE_ALPHA);
+  
+  
+  /* Flag: */
+  
+  img_flag[0] = load_image(DATA_PREFIX "/images/shared/flag-0.png",
+                          USE_ALPHA);
+  img_flag[1] = load_image(DATA_PREFIX "/images/shared/flag-1.png",
+                          USE_ALPHA);
+
+  
+  /* Cloud: */
+  
+  img_cloud[0][0] = load_image(DATA_PREFIX "/images/shared/cloud-00.png",
+                              USE_ALPHA);
+  
+  img_cloud[0][1] = load_image(DATA_PREFIX "/images/shared/cloud-01.png",
+                              USE_ALPHA);
+  
+  img_cloud[0][2] = load_image(DATA_PREFIX "/images/shared/cloud-02.png",
+                              USE_ALPHA);
+  
+  img_cloud[0][3] = load_image(DATA_PREFIX "/images/shared/cloud-03.png",
+                              USE_ALPHA);
+  
+  
+  img_cloud[1][0] = load_image(DATA_PREFIX "/images/shared/cloud-10.png",
+                              USE_ALPHA);
+  
+  img_cloud[1][1] = load_image(DATA_PREFIX "/images/shared/cloud-11.png",
+                              USE_ALPHA);
+  
+  img_cloud[1][2] = load_image(DATA_PREFIX "/images/shared/cloud-12.png",
+                              USE_ALPHA);
+  
+  img_cloud[1][3] = load_image(DATA_PREFIX "/images/shared/cloud-13.png",
+                              USE_ALPHA);
+  
+  
+  /* Bad guys: */
+  
+  /* (BSOD) */
+  
+  img_bsod_left[0] = load_image(DATA_PREFIX
+                               "/images/shared/bsod-left-0.png",
+                               USE_ALPHA);
+  
+  img_bsod_left[1] = load_image(DATA_PREFIX
+                               "/images/shared/bsod-left-1.png",
+                               USE_ALPHA);
+  
+  img_bsod_left[2] = load_image(DATA_PREFIX
+                               "/images/shared/bsod-left-2.png",
+                               USE_ALPHA);
+  
+  img_bsod_left[3] = load_image(DATA_PREFIX
+                               "/images/shared/bsod-left-3.png",
+                               USE_ALPHA);
+  
+  img_bsod_right[0] = load_image(DATA_PREFIX
+                                "/images/shared/bsod-right-0.png",
+                                USE_ALPHA);
+  
+  img_bsod_right[1] = load_image(DATA_PREFIX
+                                "/images/shared/bsod-right-1.png",
+                                USE_ALPHA);
+  
+  img_bsod_right[2] = load_image(DATA_PREFIX
+                                "/images/shared/bsod-right-2.png",
+                                USE_ALPHA);
+  
+  img_bsod_right[3] = load_image(DATA_PREFIX
+                                "/images/shared/bsod-right-3.png",
+                                USE_ALPHA);
+  
+  img_bsod_squished_left = load_image(DATA_PREFIX
+                                 "/images/shared/bsod-squished-left.png",
+                                 USE_ALPHA);
+  
+  img_bsod_squished_right = load_image(DATA_PREFIX
+                                  "/images/shared/bsod-squished-right.png",
+                                  USE_ALPHA);
+  
+  img_bsod_falling_left = load_image(DATA_PREFIX
+                                 "/images/shared/bsod-falling-left.png",
+                                 USE_ALPHA);
+  
+  img_bsod_falling_right = load_image(DATA_PREFIX
+                                  "/images/shared/bsod-falling-right.png",
+                                  USE_ALPHA);
+  
+  
+  /* (Laptop) */
+  
+  img_laptop_left[0] = load_image(DATA_PREFIX
+                                 "/images/shared/laptop-left-0.png",
+                                 USE_ALPHA);
+  
+  img_laptop_left[1] = load_image(DATA_PREFIX
+                                 "/images/shared/laptop-left-1.png",
+                                 USE_ALPHA);
+  
+  img_laptop_left[2] = load_image(DATA_PREFIX
+                                 "/images/shared/laptop-left-2.png",
+                                 USE_ALPHA);
+  
+  img_laptop_right[0] = load_image(DATA_PREFIX
+                                 "/images/shared/laptop-right-0.png",
+                                 USE_ALPHA);
+  
+  img_laptop_right[1] = load_image(DATA_PREFIX
+                                 "/images/shared/laptop-right-1.png",
+                                 USE_ALPHA);
+  
+  img_laptop_right[2] = load_image(DATA_PREFIX
+                                 "/images/shared/laptop-right-2.png",
+                                 USE_ALPHA);
+
+  img_laptop_flat_left = load_image(DATA_PREFIX
+                                   "/images/shared/laptop-flat-left.png",
+                                   USE_ALPHA);
+  
+  img_laptop_flat_right = load_image(DATA_PREFIX
+                                    "/images/shared/laptop-flat-right.png",
+                                    USE_ALPHA);
+  
+  img_laptop_falling_left = 
+    load_image(DATA_PREFIX
+              "/images/shared/laptop-falling-left.png",
+              USE_ALPHA);
+  
+  img_laptop_falling_right =
+    load_image(DATA_PREFIX
+              "/images/shared/laptop-falling-right.png",
+              USE_ALPHA);
+
+
+  /* (Money) */
+  
+  img_money_left[0] = load_image(DATA_PREFIX
+                                "/images/shared/bag-left-0.png",
+                                USE_ALPHA);
+  
+  img_money_left[1] = load_image(DATA_PREFIX
+                                "/images/shared/bag-left-1.png",
+                                USE_ALPHA);
+  
+  img_money_right[0] = load_image(DATA_PREFIX
+                                 "/images/shared/bag-right-0.png",
+                                 USE_ALPHA);
+  
+  img_money_right[1] = load_image(DATA_PREFIX
+                                 "/images/shared/bag-right-1.png",
+                                 USE_ALPHA);
+  
+  
+  
+  /* Upgrades: */
+  
+  img_mints = load_image(DATA_PREFIX "/images/shared/mints.png", USE_ALPHA);
+  img_coffee = load_image(DATA_PREFIX "/images/shared/coffee.png", USE_ALPHA);
+
+  
+  /* Weapons: */
+  
+  img_bullet = load_image(DATA_PREFIX "/images/shared/bullet.png", USE_ALPHA);
+
+  img_red_glow = load_image(DATA_PREFIX "/images/shared/red-glow.png",
+                           USE_ALPHA);
+  
+  
+  /* Distros: */
+  
+  img_distro[0] = load_image(DATA_PREFIX "/images/shared/distro-0.png",
+                            USE_ALPHA);
+  
+  img_distro[1] = load_image(DATA_PREFIX "/images/shared/distro-1.png",
+                            USE_ALPHA);
+  
+  img_distro[2] = load_image(DATA_PREFIX "/images/shared/distro-2.png",
+                            USE_ALPHA);
+  
+  img_distro[3] = load_image(DATA_PREFIX "/images/shared/distro-3.png",
+                            USE_ALPHA);
+  
+  
+  /* Herring: */
+  
+  img_golden_herring =
+    load_image(DATA_PREFIX "/images/shared/golden-herring.png",
+              USE_ALPHA);
+
+  
+  /* Super background: */
+  
+  img_super_bkgd = load_image(DATA_PREFIX "/images/shared/super-bkgd.png",
+                             IGNORE_ALPHA);
+  
+  
+  /* Sound effects: */
+  
+#ifndef NOSOUND
+  if (use_sound)
+    {
+      for (i = 0; i < NUM_SOUNDS; i++)
+       sounds[i] = load_sound(soundfilenames[i]);
+    }
+#endif
+}
+
+
+/* Free shared data: */
+
+void unloadshared(void)
+{
+  int i;
+  
+  for (i = 0; i < 3; i++)
+    {
+      SDL_FreeSurface(tux_right[i]);
+      SDL_FreeSurface(tux_left[i]);
+      SDL_FreeSurface(bigtux_right[i]);
+      SDL_FreeSurface(bigtux_left[i]);
+    }
+  
+  SDL_FreeSurface(bigtux_right_jump);
+  SDL_FreeSurface(bigtux_left_jump);
+  
+  for (i = 0; i < 2; i++)
+    {
+      SDL_FreeSurface(cape_right[i]);
+      SDL_FreeSurface(cape_left[i]);
+      SDL_FreeSurface(bigcape_right[i]);
+      SDL_FreeSurface(bigcape_left[i]);
+    }
+  
+  SDL_FreeSurface(ducktux_left);
+  SDL_FreeSurface(ducktux_right);
+
+  SDL_FreeSurface(skidtux_left);
+  SDL_FreeSurface(skidtux_right);
+  
+  for (i = 0; i < 4; i++)
+    {
+      SDL_FreeSurface(img_bsod_left[i]);
+      SDL_FreeSurface(img_bsod_right[i]);
+    }
+
+  SDL_FreeSurface(img_bsod_squished_left);
+  SDL_FreeSurface(img_bsod_squished_right);
+
+  SDL_FreeSurface(img_bsod_falling_left);
+  SDL_FreeSurface(img_bsod_falling_right);
+
+  for (i = 0; i < 3; i++)
+    {
+      SDL_FreeSurface(img_laptop_left[i]);
+      SDL_FreeSurface(img_laptop_right[i]);
+    }
+  
+  SDL_FreeSurface(img_laptop_flat_left);
+  SDL_FreeSurface(img_laptop_flat_right);
+
+  SDL_FreeSurface(img_laptop_falling_left);
+  SDL_FreeSurface(img_laptop_falling_right);
+  
+  for (i = 0; i < 2; i++)
+    {
+      SDL_FreeSurface(img_money_left[i]);
+      SDL_FreeSurface(img_money_right[i]);
+    }
+
+  SDL_FreeSurface(img_box_full);
+  SDL_FreeSurface(img_box_empty);
+  
+  SDL_FreeSurface(img_water);
+  for (i = 0; i < 3; i++)
+    SDL_FreeSurface(img_waves[i]);
+  
+  SDL_FreeSurface(img_pole);
+  SDL_FreeSurface(img_poletop);
+  
+  for (i = 0; i < 2; i++)
+    SDL_FreeSurface(img_flag[i]);
+  
+  SDL_FreeSurface(img_mints);
+  SDL_FreeSurface(img_coffee);
+  
+  for (i = 0; i < 4; i++)
+    {
+      SDL_FreeSurface(img_distro[i]);
+      SDL_FreeSurface(img_cloud[0][i]);
+      SDL_FreeSurface(img_cloud[1][i]);
+    }
+  
+  SDL_FreeSurface(img_golden_herring);
+
+#ifndef NOSOUND
+  if (use_sound)
+    {
+      for (i = 0; i < NUM_SOUNDS; i++)
+        Mix_FreeChunk(sounds[i]);
+    }
+#endif
+}
+
+
+/* Draw a tile on the screen: */
+
+void drawshape(int x, int y, unsigned char c)
+{
+  int z;
+  
+  if (c == 'X' || c == 'x')
+    drawimage(img_brick[0], x, y, NO_UPDATE);
+  else if (c == 'Y' || c == 'y')
+    drawimage(img_brick[1], x, y, NO_UPDATE);
+  else if (c == 'A' || c =='B' || c == '!')
+    drawimage(img_box_full, x, y, NO_UPDATE);
+  else if (c == 'a')
+    drawimage(img_box_empty, x, y, NO_UPDATE);
+  else if (c >= 'C' && c <= 'F')
+    drawimage(img_cloud[0][c - 'C'], x, y, NO_UPDATE);
+  else if (c >= 'c' && c <= 'f')
+    drawimage(img_cloud[1][c - 'c'], x, y, NO_UPDATE);
+  else if (c >= 'G' && c <= 'J')
+    drawimage(img_bkgd[0][c - 'G'], x, y, NO_UPDATE);
+  else if (c >= 'g' && c <= 'j')
+    drawimage(img_bkgd[1][c - 'g'], x, y, NO_UPDATE);
+  else if (c == '#')
+    drawimage(img_solid[0], x, y, NO_UPDATE);
+  else if (c == '[')
+    drawimage(img_solid[1], x, y, NO_UPDATE);
+  else if (c == '=')
+    drawimage(img_solid[2], x, y, NO_UPDATE);
+  else if (c == ']')
+    drawimage(img_solid[3], x, y, NO_UPDATE);
+  else if (c == '$')
+    {
+      z = (frame / 2) % 6;
+      
+      if (z < 4)
+       drawimage(img_distro[z], x, y, NO_UPDATE);
+      else if (z == 4)
+       drawimage(img_distro[2], x, y, NO_UPDATE);
+      else if (z == 5)
+       drawimage(img_distro[1], x, y, NO_UPDATE);
+    }
+  else if (c == '^')
+    {
+      z = (frame / 3) % 3;
+      
+      drawimage(img_waves[z], x, y, NO_UPDATE);
+    }
+  else if (c == '*')
+    drawimage(img_poletop, x, y, NO_UPDATE);
+  else if (c == '|')
+    drawimage(img_pole, x, y, NO_UPDATE);
+  else if (c == '\\')
+    {
+      z = (frame / 3) % 2;
+      
+      drawimage(img_flag[z], x + 16, y, NO_UPDATE);
+    }
+  else if (c == '&')
+    drawimage(img_water, x, y, NO_UPDATE);
+}
+
+
+/* What shape is at some position? */
+
+unsigned char shape(int x, int y, int sx)
+{
+  int xx, yy;
+  unsigned char c;
+  
+  yy = (y / 32);
+  xx = ((x + sx) / 32);
+  
+  if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= LEVEL_WIDTH)
+    c = tiles[yy][xx];
+  else
+    c = '.';
+  
+  return(c);
+}
+
+
+/* Is is ground? */
+
+int issolid(int x, int y, int sx)
+{
+  int v;
+  
+  v = 0;
+  
+  if (isbrick(x, y, sx) ||
+      isbrick(x + 31, y, sx) ||
+      isice(x, y, sx) ||
+      isice(x + 31, y, sx) ||
+      (shape(x, y, sx) == '[' ||
+       shape(x + 31, y, sx) == '[') ||
+      (shape(x, y, sx) == '=' ||
+       shape(x + 31, y, sx) == '=') ||
+      (shape(x, y, sx) == ']' ||
+       shape(x + 31, y, sx) == ']') ||
+      (shape(x, y, sx) == 'A' ||
+       shape(x + 31, y, sx) == 'A') ||
+      (shape(x, y, sx) == 'B' ||
+       shape(x + 31, y, sx) == 'B') ||
+      (shape(x, y, sx) == '!' ||
+       shape(x + 31, y, sx) == '!') ||
+      (shape(x, y, sx) == 'a' ||
+       shape(x + 31, y, sx) == 'a'))
+    {
+      v = 1;
+    }
+
+  return(v);
+}
+
+
+/* Is it a brick? */
+
+int isbrick(int x, int y, int sx)
+{
+  int v;
+  
+  v = 0;
+  
+  if (shape(x, y, sx) == 'X' ||
+      shape(x, y, sx) == 'x' ||
+      shape(x, y, sx) == 'Y' ||
+      shape(x, y, sx) == 'y')
+    {
+      v = 1;
+    }
+  
+  return(v);
+}
+
+
+/* Is it ice? */
+
+int isice(int x, int y, int sx)
+{
+  int v;
+  
+  v = 0;
+  
+  if (shape(x, y, sx) == '#')
+    {
+      v = 1;
+    }
+  
+  return(v);
+}
+
+
+/* Is it a full box? */
+
+int isfullbox(int x, int y, int sx)
+{
+  int v;
+  
+  v = 0;
+  
+  if (shape(x, y, sx) == 'A' ||
+      shape(x, y, sx) == 'B' ||
+      shape(x, y, sx) == '!')
+    {
+      v = 1;
+    }
+  
+  return(v);
+}
+
+
+/* Edit a piece of the map! */
+
+void change(int x, int y, int sx, unsigned char c)
+{
+  int xx, yy;
+  
+  yy = (y / 32);
+  xx = ((x + sx) / 32);
+  
+  if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= LEVEL_WIDTH)
+    tiles[yy][xx] = c;
+}
+
+
+/* Break a brick: */
+
+void trybreakbrick(int x, int y, int sx)
+{
+  if (isbrick(x, y, sx))
+    {
+      if (shape(x, y, sx) == 'x' || shape(x, y, sx) == 'y')
+       {
+         /* Get a distro from it: */
+         
+         add_bouncy_distro(((x + sx + 1) / 32) * 32,
+                           (y / 32) * 32);
+
+          if (counting_distros == NO)
+            {
+             counting_distros = YES;
+             distro_counter = 50;
+           }
+
+         if (distro_counter <= 0)
+          change(x, y, sx, 'a');
+        
+#ifndef NOSOUND
+         playsound(sounds[SND_DISTRO]);
+#endif
+         score = score + SCORE_DISTRO;
+         distros++;
+       }
+      else
+      {
+        /* Get rid of it: */
+      
+        change(x, y, sx, '.');
+      }
+      
+      
+      /* Replace it with broken bits: */
+      
+      add_broken_brick(((x + sx + 1) / 32) * 32,
+                      (y / 32) * 32);
+      
+      
+      /* Get some score: */
+      
+#ifndef NOSOUND
+      playsound(sounds[SND_BRICK]);
+#endif
+      score = score + SCORE_BRICK;
+    }
+}
+
+
+/* Bounce a brick: */
+
+void bumpbrick(int x, int y, int sx)
+{
+  add_bouncy_brick(((x + sx + 1) / 32) * 32,
+                  (y / 32) * 32);
+  
+#ifndef NOSOUND
+  playsound(sounds[SND_BRICK]);
+#endif
+}
+
+
+/* Empty a box: */
+
+void tryemptybox(int x, int y, int sx)
+{
+  if (isfullbox(x, y, sx))
+    {
+      if (shape(x, y, sx) == 'A')
+       {
+         /* Box with a distro! */
+         
+         add_bouncy_distro(((x + sx + 1) / 32) * 32,
+                           (y / 32) * 32 - 32);
+         
+#ifndef NOSOUND
+         playsound(sounds[SND_DISTRO]);
+#endif
+         score = score + SCORE_DISTRO;
+         distros++;
+       }
+      else if (shape(x, y, sx) == 'B')
+       {
+         /* Add an upgrade! */
+         
+         if (tux_size == SMALL)
+           {
+             /* Tux is small, add mints! */
+             
+             add_upgrade(((x + sx + 1) / 32) * 32,
+                         (y / 32) * 32 - 32,
+                         UPGRADE_MINTS);
+           }
+         else
+           {
+             /* Tux is big, add coffee: */
+             
+             add_upgrade(((x + sx + 1) / 32) * 32,
+                         (y / 32) * 32 - 32,
+                         UPGRADE_COFFEE);
+           }
+         
+#ifndef NOSOUND
+         playsound(sounds[SND_UPGRADE]);
+#endif
+       }
+      else if (shape(x, y, sx) == '!')
+       {
+         /* Add a golden herring */
+         
+         add_upgrade(((x + sx + 1) / 32) * 32,
+                     (y / 32) * 32 - 32,
+                     UPGRADE_HERRING);
+       }
+      
+      /* Empty the box: */
+      
+      change(x, y, sx, 'a');
+    }
+}
+
+
+/* Try to grab a distro: */
+
+void trygrabdistro(int x, int y, int sx, int bounciness)
+{
+  if (shape(x, y, sx) == '$')
+    {
+      change(x, y, sx, '.');
+#ifndef NOSOUND
+      playsound(sounds[SND_DISTRO]);
+#endif
+      
+      if (bounciness == BOUNCE)
+       {
+         add_bouncy_distro(((x + sx + 1) / 32) * 32,
+                           (y / 32) * 32);
+       }
+      
+      score = score + SCORE_DISTRO;
+      distros++;
+    }
+}
+
+
+/* Add a bouncy distro: */
+
+void add_bouncy_distro(int x, int y)
+{
+  int i, found;
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_BOUNCY_DISTROS && found == -1; i++)
+    {
+      if (!bouncy_distros[i].alive)
+       found = i;
+    }
+  
+  if (found != -1)
+    {
+      bouncy_distros[found].alive = YES;
+      bouncy_distros[found].x = x;
+      bouncy_distros[found].y = y;
+      bouncy_distros[found].ym = -6;
+    }
+}
+
+
+/* Add broken brick pieces: */
+
+void add_broken_brick(int x, int y)
+{
+  add_broken_brick_piece(x, y, -4, -16);
+  add_broken_brick_piece(x, y + 16, -6, -12);
+
+  add_broken_brick_piece(x + 16, y, 4, -16);
+  add_broken_brick_piece(x + 16, y + 16, 6, -12);
+}
+
+
+/* Add a broken brick piece: */
+
+void add_broken_brick_piece(int x, int y, int xm, int ym)
+{
+  int i, found;
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_BROKEN_BRICKS && found == -1; i++)
+    {
+      if (!broken_bricks[i].alive)
+       found = i;
+    }
+  
+  if (found != -1)
+    {
+      broken_bricks[found].alive = YES;
+      broken_bricks[found].x = x;
+      broken_bricks[found].y = y;
+      broken_bricks[found].xm = xm;
+      broken_bricks[found].ym = ym;
+    }
+}
+
+
+/* Add a bouncy brick piece: */
+
+void add_bouncy_brick(int x, int y)
+{
+  int i, found;
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_BOUNCY_BRICKS && found == -1; i++)
+    {
+      if (!bouncy_bricks[i].alive)
+       found = i;
+    }
+  
+  if (found != -1)
+    {
+      bouncy_bricks[found].alive = YES;
+      bouncy_bricks[found].x = x;
+      bouncy_bricks[found].y = y;
+      bouncy_bricks[found].offset = 0;
+      bouncy_bricks[found].offset_m = -BOUNCY_BRICK_SPEED;
+      bouncy_bricks[found].shape = shape(x, y, 0);
+    }
+}
+
+
+/* Add a bad guy: */
+
+void add_bad_guy(int x, int y, int kind)
+{
+  int i, found;
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_BAD_GUYS && found == -1; i++)
+    {
+      if (!bad_guys[i].alive)
+       found = i;
+    }
+  
+  if (found != -1)
+    {
+      bad_guys[found].alive = YES;
+      bad_guys[found].mode = NORMAL;
+      bad_guys[found].dying = NO;
+      bad_guys[found].timer = 0;
+      bad_guys[found].kind = kind;
+      bad_guys[found].x = x;
+      bad_guys[found].y = y;
+      bad_guys[found].xm = 0;
+      bad_guys[found].ym = 0;
+      bad_guys[found].dir = LEFT;
+      bad_guys[found].seen = NO;
+    }
+}
+
+
+/* Add score: */
+
+void add_score(int x, int y, int s)
+{
+  int i, found;
+  
+  
+  /* Add the score: */
+  
+  score = score + s;
+  
+  
+  /* Add a floating score thing to the game: */
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_FLOATING_SCORES && found == -1; i++)
+    {
+      if (!floating_scores[i].alive)
+       found = i;
+    }
+  
+  
+  if (found != -1)
+    {
+      floating_scores[found].alive = YES;
+      floating_scores[found].x = x;
+      floating_scores[found].y = y - 16;
+      floating_scores[found].timer = 8;
+      floating_scores[found].value = s;
+    }
+}
+
+
+/* Try to bump a bad guy from below: */
+
+void trybumpbadguy(int x, int y, int sx)
+{
+  int i;
+  
+  
+  /* Bad guys: */
+  
+  for (i = 0; i < NUM_BAD_GUYS; i++)
+    {
+      if (bad_guys[i].alive &&
+         bad_guys[i].x >= x + sx - 32 && bad_guys[i].x <= x + sx + 32 &&
+         bad_guys[i].y >= y - 16 && bad_guys[i].y <= y + 16)
+       {
+         if (bad_guys[i].kind == BAD_BSOD ||
+             bad_guys[i].kind == BAD_LAPTOP)
+           {
+             bad_guys[i].dying = FALLING;
+             bad_guys[i].ym = -8;
+#ifndef NOSOUND
+             playsound(sounds[SND_FALL]);
+#endif
+           }
+       }
+    }
+  
+  
+  /* Upgrades: */
+  
+  for (i = 0; i < NUM_UPGRADES; i++)
+    {
+      if (upgrades[i].alive && upgrades[i].height == 32 &&
+         upgrades[i].x >= x + sx - 32 && upgrades[i].x <= x + sx + 32 &&
+         upgrades[i].y >= y - 16 && upgrades[i].y <= y + 16)
+       {
+         upgrades[i].xm = -upgrades[i].xm;
+         upgrades[i].ym = -8;
+#ifndef NOSOUND
+         playsound(sounds[SND_BUMP_UPGRADE]);
+#endif
+       }
+    }
+}
+
+
+/* Add an upgrade: */
+
+void add_upgrade(int x, int y, int kind)
+{
+  int i, found;
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_UPGRADES && found == -1; i++)
+    {
+      if (!upgrades[i].alive)
+       found = i;
+    }
+
+  if (found != -1)
+    {
+      upgrades[found].alive = YES;
+      upgrades[found].kind = kind;
+      upgrades[found].x = x;
+      upgrades[found].y = y;
+      upgrades[found].xm = 4;
+      upgrades[found].ym = -4;
+      upgrades[found].height = 0;
+    }
+}
+
+
+/* Kill tux! */
+
+void killtux(int mode)
+{
+  tux_ym = -16;
+#ifndef NOSOUND
+  playsound(sounds[SND_HURT]);
+#endif
+  if (tux_dir == RIGHT)
+    tux_xm = -8;
+  else if (tux_dir == LEFT)
+    tux_xm = 8;
+  
+  if (mode == SHRINK && tux_size == BIG)
+    {
+      if (tux_got_coffee)
+       tux_got_coffee = NO;
+
+      tux_size = SMALL;
+      
+      tux_safe = TUX_SAFE_TIME;
+    }
+  else
+    {
+      tux_dying = 1;
+    }
+}
+
+
+/* Add a bullet: */
+
+void add_bullet(int x, int y, int dir, int xm)
+{
+  int i, found;
+  
+  found = -1;
+  
+  for (i = 0; i < NUM_BULLETS && found == -1; i++)
+    {
+      if (!bullets[i].alive)
+       found = i;
+    }
+
+  if (found != -1)
+    {
+      bullets[found].alive = YES;
+      
+      if (dir == RIGHT)
+       {
+         bullets[found].x = x + 32;
+         bullets[found].xm = BULLET_XM + xm;
+       }
+      else
+       {
+         bullets[found].x = x;
+         bullets[found].xm = -BULLET_XM + xm;
+       }
+      
+      bullets[found].y = y;
+      bullets[found].ym = BULLET_STARTING_YM;
+      
+#ifndef NOSOUND
+      playsound(sounds[SND_SHOOT]);
+#endif
+    }
+}
diff --git a/src/gameloop.h b/src/gameloop.h
new file mode 100644 (file)
index 0000000..813a077
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+  gameloop.h
+  
+  Super Tux - Game Loop!
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - November 7, 2001
+*/
+
+
+/* Direction (keyboard/joystick) states: */
+
+#define UP 0
+#define DOWN 1
+
+
+/* Directions: */
+
+#define LEFT 0
+#define RIGHT 1
+
+
+/* Sizes: */
+
+#define SMALL 0
+#define BIG 1
+
+
+/* Bounciness of distros: */
+
+#define NO_BOUNCE 0
+#define BOUNCE 1
+
+
+/* Dying types: */
+
+/* ---- NO 0 */
+#define SQUISHED 1
+#define FALLING 2
+
+
+/* Enemy modes: */
+
+#define NORMAL 0
+#define FLAT 1
+#define KICK 2
+
+
+/* Hurt modes: */
+
+#define KILL 0
+#define SHRINK 1
+
+
+/* Upgrade types: */
+
+enum {
+  UPGRADE_MINTS,
+  UPGRADE_COFFEE,
+  UPGRADE_HERRING
+};
+
+
+/* Bad guy kinds: */
+
+enum {
+  BAD_BSOD,
+  BAD_LAPTOP,
+  BAD_MONEY
+};
+
+
+/* Speed constraints: */
+
+#define MAX_WALK_XM 16
+#define MAX_RUN_XM 24
+#define MAX_YM 24
+#define MAX_JUMP_COUNT 3
+
+#define WALK_SPEED 2
+#define RUN_SPEED 4
+#define JUMP_SPEED 8
+#define BULLET_STARTING_YM 8
+#define BULLET_XM 16
+
+#define GRAVITY 2
+#define YM_FOR_JUMP 40
+#define KILL_BOUNCE_YM 8
+
+#define SKID_XM 8
+#define SKID_TIME 8
+
+
+#define BOUNCY_BRICK_MAX_OFFSET 8
+#define BOUNCY_BRICK_SPEED 4
+
+
+/* Times: */
+
+#define TUX_SAFE_TIME 16
+
+
+/* Size constraints: */
+
+#define OFFSCREEN_DISTANCE 256
+
+#define LEVEL_WIDTH 375
+
+
+/* Array sizes: */
+
+#define NUM_BOUNCY_DISTROS 8
+#define NUM_BROKEN_BRICKS 32
+#define NUM_BOUNCY_BRICKS 4
+#define NUM_BAD_GUYS 128
+#define NUM_FLOATING_SCORES 6
+#define NUM_UPGRADES 2
+#define NUM_BULLETS 3
+
+
+/* Scores: */
+
+#define SCORE_BRICK 5
+#define SCORE_DISTRO 25
+
+
+/* Types: */
+
+typedef struct bouncy_distro_type {
+  int alive, x, y, ym;
+} bouncy_distro_type;
+
+typedef struct broken_brick_type {
+  int alive, x, y, xm, ym;
+} broken_brick_type;
+
+typedef struct bouncy_brick_type {
+  int alive, x, y, offset, offset_m, shape;
+} bouncy_brick_type;
+
+typedef struct bad_guy_type {
+  int alive, mode, dying, timer, kind, seen, dir, x, y, xm, ym;
+} bad_guy_type;
+
+typedef struct floating_score_type {
+  int alive, timer, x, y, value;
+} floating_score_type;
+
+typedef struct upgrade_type {
+  int alive, kind, height, x, y, xm, ym;
+} upgrade_type;
+
+typedef struct bullet_type {
+  int alive, x, y, xm, ym;
+} bullet_type;
+
+
+/* Function prototypes: */
+
+int gameloop(void);
diff --git a/src/globals.h b/src/globals.h
new file mode 100644 (file)
index 0000000..c25c85f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+  globals.h
+  
+  Super Tux - Global Variabls
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 21, 2000
+*/
+
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+SDL_Surface * screen;
+SDL_Surface * letters_black, * letters_gold, * letters_blue, * letters_red;
+
+int use_joystick, use_sound, use_fullscreen;
+
+#ifdef JOY_YES
+SDL_Joystick * js;
+#endif
+
+#endif /* GLOBALS_H */
diff --git a/src/intro.c b/src/intro.c
new file mode 100644 (file)
index 0000000..47de726
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+  intro.c
+  
+  Super Tux - Intro Screen
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 23, 2000
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "intro.h"
+#include "screen.h"
+
+
+char * intro_text[] = {
+  "Tux and Gown were having a nice picnic..",
+  "when suddenly...",
+  "Gown is beamed away!!!",
+  "This looks like a job for ---"
+};
+
+
+/* --- INTRO --- */
+
+int intro(void)
+{
+  SDL_Event event;
+  SDL_Surface * bkgd, * copter_squish, * copter_stretch, * beam,
+    * gown_sit, * gown_lookup, * gown_upset,
+    * tux_sit, * tux_upset, * tux_mad;
+  SDL_Surface * copter[2];
+  SDL_Rect src, dest;
+  int done, i, quit, j;
+  int * height, * height_speed;
+  
+  
+  /* Load sprite images: */
+  
+  bkgd = load_image(DATA_PREFIX "/images/intro/intro.png", IGNORE_ALPHA);
+  
+  gown_sit = load_image(DATA_PREFIX "/images/intro/gown-sit.png", USE_ALPHA);
+  gown_lookup = load_image(DATA_PREFIX "/images/intro/gown-lookup.png",
+                          USE_ALPHA);
+  gown_upset = load_image(DATA_PREFIX "/images/intro/gown-upset.png",
+                         USE_ALPHA);
+  tux_sit = load_image(DATA_PREFIX "/images/intro/tux-sit.png", USE_ALPHA);
+  tux_upset = load_image(DATA_PREFIX "/images/intro/tux-upset.png",
+                        USE_ALPHA);
+  tux_mad = load_image(DATA_PREFIX "/images/intro/tux-mad.png", USE_ALPHA);
+  copter[0] = load_image(DATA_PREFIX "/images/intro/copter1.png", USE_ALPHA);
+  copter[1] = load_image(DATA_PREFIX "/images/intro/copter2.png", USE_ALPHA);
+
+  copter_squish = load_image(DATA_PREFIX "/images/intro/copter-squish.png",
+                            USE_ALPHA);
+  copter_stretch = load_image(DATA_PREFIX "/images/intro/copter-stretch.png",
+                             USE_ALPHA);
+  beam = load_image(DATA_PREFIX "/images/intro/beam.png", USE_ALPHA);
+  
+  
+  /* Allocate buffer for height array: */
+  
+  height = malloc(sizeof(int) * (gown_upset -> w));
+  height_speed = malloc(sizeof(int) * (gown_upset -> w));
+  
+  
+  /* Initialize height arrays: */
+  
+  for (j = 0; j < (gown_upset -> w); j++)
+    {
+      height[j] = 400;
+      height_speed[j] = (rand() % 10) + 1;
+    }
+  
+  
+  /* Display background: */
+  
+  drawimage(bkgd, 0, 0, UPDATE);
+  
+  
+  /* Animation: */
+  
+  done = 0;
+  quit = 0;
+  
+  for (i = 0; i < (10000 / FPS) && !done && !quit; i++)
+    {
+      /* Handle events: */
+      
+      while (SDL_PollEvent(&event))
+        {
+         if (event.type == SDL_QUIT)
+           {
+             /* Quit event - quit: */
+             
+             quit = 1;
+           }
+         else if (event.type == SDL_KEYDOWN)
+           {
+             /* Keypress - skip intro: */
+             
+             done = 1;
+           }
+#ifdef JOY_YES
+         else if (event.type == SDL_JOYBUTTONDOWN)
+           {
+             /* Fire button - skip intro: */
+             
+             done = 1;
+           }
+#endif
+       }
+      
+      
+      /* Draw things: */
+      
+      if (i == 0)
+       {
+         /* Gown and tux sitting: */
+         
+         drawimage(tux_sit, 270, 400, UPDATE);
+         drawimage(gown_sit, 320, 400, UPDATE);
+         
+         drawcenteredtext(intro_text[0], 456, letters_blue, UPDATE);
+       }
+      
+      
+      if (i == (2000 / FPS))
+       {
+         /* Helicopter begins to fly in: */
+         
+         erasecenteredtext(intro_text[0], 456, bkgd, UPDATE);
+         drawcenteredtext(intro_text[1], 456, letters_red, UPDATE);
+       }
+
+      
+      if (i > (2000 / FPS) && i < (4000 / FPS))
+       {
+         /* Helicopter flying in: */
+         
+         drawpart(bkgd, 0, 32, 640, (copter[0] -> h), NO_UPDATE);
+         
+         drawimage(copter[i % 2],
+                   (i - (2000 / FPS)) * (FPS / 5) - (copter[0] -> w), 32,
+                   NO_UPDATE);
+         
+         SDL_UpdateRect(screen, 0, 32, 640, (copter[0] -> h));
+       }
+
+      
+      if (i == (2500 / FPS))
+       {
+         /* Gown notices something... */
+         
+         drawimage(gown_lookup, 320, 400, UPDATE);
+       }
+
+      
+      if (i == (3500 / FPS))
+       {
+         /* Gown realizes it's bad! */
+         
+         drawimage(gown_upset, 320, 400, UPDATE);
+       }
+
+      
+      if (i > (4000 / FPS) && i < (8000 / FPS))
+       {
+         /* Helicopter sits: */
+         
+         drawpart(bkgd, 0, 32, 640, (copter[0] -> h), NO_UPDATE);
+         
+         drawimage(copter[i % 2], 400 - (copter[0] -> w), 32, NO_UPDATE);
+
+         SDL_UpdateRect(screen, 0, 32, 640, (copter[0] -> h));
+       }
+
+      
+      if (i == (5000 / FPS))
+       {
+         /* Tux realizes something's happening: */
+         
+         drawimage(tux_upset, 270, 400, UPDATE);
+         
+         
+         erasecenteredtext(intro_text[1], 456, bkgd, UPDATE);
+         drawcenteredtext(intro_text[2], 456, letters_red, UPDATE);
+       }
+      
+      
+      if (i > (5000 / FPS))
+       {
+         /* Beam gown up! */
+         
+         drawpart(bkgd,
+                  320,
+                  32 + (copter[0] -> h),
+                  (gown_upset -> w),
+                  368 + (gown_upset -> h) - (copter[0] -> h), NO_UPDATE);
+         
+         
+         for (j = 0; j < (gown_upset -> w); j++)
+           {
+             drawimage(beam, 320 + j - ((beam -> w) / 2), height[j],
+                       NO_UPDATE);
+             
+             src.x = j;
+             src.y = 0;
+             src.w = 1;
+             src.h = (gown_upset -> h);
+             
+             dest.x = 320 + j;
+             dest.y = height[j];
+             dest.w = src.w;
+             dest.h = src.h;
+             
+             SDL_BlitSurface(gown_upset, &src, screen, &dest);
+             
+             height[j] = height[j] - height_speed[j];
+             
+             if ((i % 2) == 0)
+               height_speed[j]++;
+           }
+         
+         SDL_UpdateRect(screen,
+                        320,
+                        32 + (copter[0] -> h),
+                        (gown_upset -> w),
+                        400 + (gown_upset -> h) - (copter[0] -> h));
+       }
+      
+      
+      if (i == (8000 / FPS))
+       {
+         /* Tux gets mad! */
+         
+         drawimage(tux_mad, 270, 400, UPDATE);
+         
+         erasecenteredtext(intro_text[2], 456, bkgd, UPDATE);
+         drawcenteredtext(intro_text[3], 456, letters_gold, UPDATE);
+       }
+      
+      
+      if (i > (8000 / FPS) && i < (8250 / FPS))
+       {
+         /* Helicopter starting to speed off: */
+         
+         drawpart(bkgd, 0, 32, 640, (copter_squish -> h), NO_UPDATE);
+         
+         drawimage(copter_squish,
+                   400 - (copter[0] -> w), 32,
+                   NO_UPDATE);
+         
+         SDL_UpdateRect(screen, 0, 32, 640, (copter_squish -> h));
+       }      
+
+
+      if (i > (8250 / FPS))
+       {
+         /* Helicopter speeding off: */
+         
+         drawpart(bkgd, 0, 32, 640, (copter_stretch -> h), NO_UPDATE);
+         
+         drawimage(copter_stretch,
+                   (i - (8250 / FPS)) * 30 + 400 - (copter[0] -> w),
+                   32,
+                   NO_UPDATE);
+         
+         SDL_UpdateRect(screen, 0, 32, 640, (copter_stretch -> h));
+       }      
+      
+      /* Pause: */
+      
+      SDL_Delay(FPS);
+    }
+
+  
+  /* Free surfaces: */
+  
+  SDL_FreeSurface(bkgd);
+  
+  SDL_FreeSurface(gown_sit);
+  SDL_FreeSurface(gown_lookup);
+  SDL_FreeSurface(gown_upset);
+  
+  SDL_FreeSurface(tux_sit);
+  SDL_FreeSurface(tux_upset);
+  SDL_FreeSurface(tux_mad);
+  
+  SDL_FreeSurface(copter[0]);
+  SDL_FreeSurface(copter[1]);
+
+  SDL_FreeSurface(copter_squish);
+  SDL_FreeSurface(copter_stretch);
+
+  SDL_FreeSurface(beam);
+  
+  
+  /* Free array buffers: */
+  
+  free(height);
+  free(height_speed);
+  
+  
+  /* Return to main! */
+  
+  return(quit);
+}
diff --git a/src/intro.h b/src/intro.h
new file mode 100644 (file)
index 0000000..0080138
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+  intro.h
+  
+  Super Tux - Intro Screen
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 11, 2000
+*/
+
+int intro(void);
diff --git a/src/screen.c b/src/screen.c
new file mode 100644 (file)
index 0000000..5f0be62
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+  screen.c
+  
+  Super Tux - Screen Functions
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 22, 2000
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "screen.h"
+#include "setup.h"
+
+
+/* --- LOAD AND DISPLAY AN IMAGE --- */
+
+void load_and_display_image(char * file)
+{
+  SDL_Surface * img;
+  
+  img = load_image(file, IGNORE_ALPHA);
+  SDL_BlitSurface(img, NULL, screen, NULL);
+  SDL_FreeSurface(img);
+}
+
+
+/* --- CLEAR SCREEN --- */
+
+void clearscreen(int r, int g, int b)
+{
+  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
+}
+
+
+/* --- UPDATE SCREEN --- */
+
+void updatescreen(void)
+{
+  SDL_UpdateRect(screen, 0, 0, 640, 480);
+}
+
+
+/* --- LOAD AN IMAGE --- */
+
+SDL_Surface * load_image(char * file, int use_alpha)
+{
+  SDL_Surface * temp, * surf;
+  
+  temp = IMG_Load(file);
+  if (temp == NULL)
+    st_abort("Can't load", file);
+  
+  surf = SDL_DisplayFormatAlpha(temp);
+
+  if (surf == NULL)
+    st_abort("Can't covert to display format", file);
+
+  if (use_alpha == IGNORE_ALPHA)
+    SDL_SetAlpha(surf, 0, 0);
+  
+  SDL_FreeSurface(temp);
+
+  return(surf);
+}
+
+
+/* --- DRAW AN IMAGE ONTO THE SCREEN --- */
+
+void drawimage(SDL_Surface * surf, int x, int y, int update)
+{
+  SDL_Rect dest;
+  
+  dest.x = x;
+  dest.y = y;
+  dest.w = surf->w;
+  dest.h = surf->h;
+  
+  SDL_BlitSurface(surf, NULL, screen, &dest);
+  
+  if (update == UPDATE)
+    SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+}
+
+
+/* --- DRAW PART OF AN IMAGE ONTO THE SCREEN --- */
+
+void drawpart(SDL_Surface * surf, int x, int y, int w, int h, int update)
+{
+  SDL_Rect src, dest;
+  
+  src.x = x;
+  src.y = y;
+  src.w = w;
+  src.h = h;
+
+  dest.x = x;
+  dest.y = y;
+  dest.w = w;
+  dest.h = h;
+  
+  SDL_BlitSurface(surf, &src, screen, &dest);
+  
+  if (update == UPDATE)
+    SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+}
+
+
+/* --- DRAW TEXT ONTO THE SCREEN --- */
+
+void drawtext(char * text, int x, int y, SDL_Surface * surf, int update)
+{
+  int i;
+  char c;
+  SDL_Rect src, dest;
+  
+  
+  /* For each letter in the string... */
+  
+  for (i = 0; i < strlen(text); i++)
+    {
+      /* Set source rectangle: */
+      
+      c = text[i];
+      
+      if (c >= 'A' && c <= 'Z')
+       {
+         /* Capital letter - first row: */
+         
+         src.x = (c - 'A') * 16;
+         src.y = 0;
+       }
+      else if (c >= 'a' && c <= 'z')
+       {
+         /* Lowercase letter - first row: */
+         
+         src.x = (c - 'a') * 16;
+         src.y = 16;
+       }
+      else if (c >= '!' && c <= '9')
+       {
+         /* Punctuation (except '?') or number - third row: */
+         
+         src.x = (c - '!') * 16;
+         src.y = 32;
+       }
+      else if (c == '?')
+       {
+         /* Question mark - third row, last character: */
+         
+         src.x = 400;
+         src.y = 24;
+       }
+      else
+       src.x = -1;
+      
+      src.w = 16;
+      src.h = 16;
+      
+
+      /* Draw character: */
+      
+      if (src.x != -1)
+       {
+         /* Set destination rectangle for shadow: */
+         
+         dest.x = x + (i * 16) + 1;
+         dest.y = y + 1;
+         dest.w = src.w;
+         dest.h = src.h;
+         
+         
+         /* Shadow: */
+         
+         SDL_BlitSurface(letters_black, &src, screen, &dest);
+         
+         
+         /* Set destination rectangle for text: */
+         
+         dest.x = x + (i * 16);
+         dest.y = y;
+         dest.w = src.w;
+         dest.h = src.h;
+         
+         
+         /* Shadow: */
+         
+         SDL_BlitSurface(surf, &src, screen, &dest);
+       }
+    }
+  
+  
+  /* Update */
+  
+  if (update == UPDATE)
+    {
+      dest.w = strlen(text) * 16 + 1;
+      
+      if (dest.w > 640)
+       dest.w = 640;
+      
+      SDL_UpdateRect(screen, x, y, dest.w, 17);
+    }
+}
+
+
+/* --- DRAW HORIZONTALLY-CENTERED TEXT: --- */
+
+void drawcenteredtext(char * text, int y, SDL_Surface * surf, int update)
+{
+  drawtext(text, 320 - (strlen(text) * 8), y, surf, update);
+}
+
+
+/* --- ERASE TEXT: --- */
+
+void erasetext(char * text, int x, int y, SDL_Surface * surf, int update)
+{
+  SDL_Rect dest;
+  
+  
+  dest.x = x;
+  dest.y = y;
+  dest.w = strlen(text) * 16 + 1;
+  dest.h = 17;
+  
+  if (dest.w > 640)
+    dest.w = 640;
+  
+  SDL_BlitSurface(surf, &dest, screen, &dest);
+  
+  if (update == UPDATE)
+    SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
+}
+
+
+/* --- ERASE CENTERED TEXT: --- */
+
+void erasecenteredtext(char * text, int y, SDL_Surface * surf, int update)
+{
+  erasetext(text, 320 - (strlen(text) * 8), y, surf, update);
+}
diff --git a/src/screen.h b/src/screen.h
new file mode 100644 (file)
index 0000000..600004a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  screen.h
+  
+  Super Tux - Screen Functions
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 21, 2000
+*/
+
+#include <SDL.h>
+
+#define NO_UPDATE 0
+#define UPDATE 1
+#define USE_ALPHA 0
+#define IGNORE_ALPHA 1
+
+void load_and_display_image(char * file);
+void clearscreen(int r, int g, int b);
+void updatescreen(void);
+SDL_Surface * load_image(char * file, int use_alpha);
+void drawimage(SDL_Surface * surf, int x, int y, int update);
+void drawpart(SDL_Surface * surf, int x, int y, int w, int h, int update);
+void drawtext(char * text, int x, int y, SDL_Surface * surf, int update);
+void drawcenteredtext(char * text, int y, SDL_Surface * surf, int update);
+void erasetext(char * text, int x, int y, SDL_Surface * surf, int update);
+void erasecenteredtext(char * text, int y, SDL_Surface * surf, int update);
diff --git a/src/setup.c b/src/setup.c
new file mode 100644 (file)
index 0000000..0c09c08
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+  setup.c
+  
+  Super Tux - Setup
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - November 7, 2001
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "setup.h"
+#include "screen.h"
+
+
+/* Local function prototypes: */
+
+void seticon(void);
+void usage(char * prog, int ret);
+
+
+/* --- SETUP --- */
+
+void st_setup(void)
+{
+  /* Seed random number generator: */
+  
+  srand(SDL_GetTicks());
+  
+  
+  /* Init SDL Video: */
+  
+  if (SDL_Init(SDL_INIT_VIDEO) < 0)
+    {
+      fprintf(stderr,
+              "\nError: I could not initialize video!\n"
+              "The Simple DirectMedia error that occured was:\n"
+              "%s\n\n", SDL_GetError());
+      exit(1);
+    }
+
+
+  /* Init Joystick: */
+  
+#ifdef JOY_YES
+  use_joystick = YES;
+  
+  if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
+    {
+      fprintf(stderr, "Warning: I could not initialize joystick!\n"
+              "The Simple DirectMedia error that occured was:\n"
+              "%s\n\n", SDL_GetError());
+      
+      use_joystick = NO;
+    }
+  else
+    {
+      /* Open joystick: */
+      
+      if (SDL_NumJoysticks() <= 0)
+        {
+          fprintf(stderr, "Warning: No joysticks are available.\n");
+          
+          use_joystick = NO;
+        }
+      else
+        {
+          js = SDL_JoystickOpen(0);
+          
+          if (js == NULL)
+            {
+              fprintf(stderr, "Warning: Could not open joystick 1.\n"
+                      "The Simple DirectMedia error that occured was:\n"
+                      "%s\n\n", SDL_GetError());
+              
+              use_joystick = NO;
+            }
+          else
+            {
+              /* Check for proper joystick configuration: */
+              
+              if (SDL_JoystickNumAxes(js) < 2)
+                {
+                  fprintf(stderr,
+                          "Warning: Joystick does not have enough axes!\n");
+                  
+                  use_joystick = NO;
+                }
+              else
+                {
+                  if (SDL_JoystickNumButtons(js) < 2)
+                    {
+                      fprintf(stderr,
+                              "Warning: "
+                              "Joystick does not have enough buttons!\n");
+                      
+                      use_joystick = NO;
+                    }
+                }
+            }
+        }
+    }
+#endif
+  
+  
+  /* Init SDL Audio: */
+  
+  if (use_sound == YES)
+    {
+      if (SDL_Init(SDL_INIT_AUDIO) < 0)
+        {
+          fprintf(stderr,
+                  "\nWarning: I could not initialize audio!\n"
+                  "The Simple DirectMedia error that occured was:\n"
+                  "%s\n\n", SDL_GetError());
+          use_sound = NO;
+        }
+    }
+  
+  
+  /* Open sound: */
+  
+#ifndef NOSOUND
+  if (use_sound == YES)
+    {
+      if (Mix_OpenAudio(11025, AUDIO_S16, 2, 512) < 0)
+        {
+          fprintf(stderr,
+                  "\nWarning: I could not set up audio for 11025 Hz "
+                  "16-bit stereo.\n"
+                  "The Simple DirectMedia error that occured was:\n"
+                  "%s\n\n", SDL_GetError());
+          use_sound = 0;
+        }
+    }
+#endif
+
+
+  /* Open display: */
+  
+  if (use_fullscreen == YES)
+    {
+      screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN) ; /* | SDL_HWSURFACE); */
+      if (screen == NULL)
+        {
+          fprintf(stderr,
+                  "\nWarning: I could not set up fullscreen video for "
+                  "640x480 mode.\n"
+                  "The Simple DirectMedia error that occured was:\n"
+                  "%s\n\n", SDL_GetError());
+          use_fullscreen = NO;
+        }
+    }
+  
+  if (use_fullscreen == NO)
+    {
+      screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
+      
+      if (screen == NULL)
+        {
+          fprintf(stderr,
+                  "\nError: I could not set up video for 640x480 mode.\n"
+                  "The Simple DirectMedia error that occured was:\n"
+                  "%s\n\n", SDL_GetError());
+          exit(1);
+        }
+    }
+  
+  
+  /* Load global images: */
+  
+  letters_black = load_image(DATA_PREFIX "/images/status/letters-black.png",
+                            USE_ALPHA);
+
+  letters_gold = load_image(DATA_PREFIX "/images/status/letters-gold.png",
+                            USE_ALPHA);
+
+  letters_blue = load_image(DATA_PREFIX "/images/status/letters-blue.png",
+                            USE_ALPHA);
+
+  letters_red = load_image(DATA_PREFIX "/images/status/letters-red.png",
+                          USE_ALPHA);
+  
+  
+  /* Set icon image: */
+  
+  seticon();
+  
+  
+  /* Set window manager stuff: */
+  
+  SDL_WM_SetCaption("Super Tux", "Super Tux");
+}
+
+
+/* --- SHUTDOWN --- */
+
+void st_shutdown(void)
+{
+  SDL_Quit();
+}
+
+
+/* --- ABORT! --- */
+
+void st_abort(char * reason, char * details)
+{
+  fprintf(stderr, "\nError: %s\n%s\n\n", reason, details);
+  st_shutdown();
+  exit(1);
+}
+
+
+/* Set Icon (private) */
+
+void seticon(void)
+{
+  int masklen;
+  Uint8 * mask;
+  SDL_Surface * icon;
+  
+  
+  /* Load icon into a surface: */
+  
+  icon = IMG_Load(DATA_PREFIX "/images/icon.png");
+  if (icon == NULL)
+    {
+      fprintf(stderr,
+              "\nError: I could not load the icon image: %s\n"
+              "The Simple DirectMedia error that occured was:\n"
+              "%s\n\n", DATA_PREFIX "images/icon.png", SDL_GetError());
+      exit(1);
+    }
+  
+  
+  /* Create mask: */
+  
+  masklen = (((icon -> w) + 7) / 8) * (icon -> h);
+  mask = malloc(masklen * sizeof(Uint8));
+  memset(mask, 0xFF, masklen);
+  
+  
+  /* Set icon: */
+  
+  SDL_WM_SetIcon(icon, mask);
+  
+  
+  /* Free icon surface & mask: */
+  
+  free(mask);
+  SDL_FreeSurface(icon);
+}
+
+
+/* Parse command-line arguments: */
+
+void parseargs(int argc, char * argv[])
+{
+  int i;
+  
+  
+  /* Set defaults: */
+  
+  use_fullscreen = NO;
+  use_sound = YES;
+  
+  
+  /* Parse arguments: */
+  
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp(argv[i], "--fullscreen") == 0 ||
+         strcmp(argv[i], "-f") == 0)
+       {
+         /* Use full screen: */
+         
+         use_fullscreen = YES;
+       }
+      else if (strcmp(argv[i], "--usage") == 0)
+       {
+         /* Show usage: */
+         
+         usage(argv[0], 0);
+       }
+      else if (strcmp(argv[i], "--version") == 0)
+       {
+         /* Show version: */
+         
+         printf("Super Tux - version " VERSION "\n");
+         exit(0);
+       }
+      else if (strcmp(argv[i], "--help") == 0)
+       {
+         /* Show version: */
+         
+         printf("Super Tux - Help summary\n");
+         printf("[ under construction ]\n");
+         exit(0);
+       }
+      else
+       {
+         /* Unknown - complain! */
+         
+         usage(argv[0], 1);
+       }
+    }
+}
+
+
+/* Display usage: */
+
+void usage(char * prog, int ret)
+{
+  FILE * fi;
+  
+  
+  /* Determine which stream to write to: */
+  
+  if (ret == 0)
+    fi = stdout;
+  else
+    fi = stderr;
+  
+  
+  /* Display the usage message: */
+  
+  fprintf(fi, "Usage: %s [--fullscreen] | [--usage | --help | --version]\n",
+         prog);
+  
+  
+  /* Quit! */
+
+  exit(ret);
+}
diff --git a/src/setup.h b/src/setup.h
new file mode 100644 (file)
index 0000000..3174d60
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+  setup.h
+  
+  Super Tux - Setup
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 13, 2000
+*/
+
+void st_setup(void);
+void st_shutdown(void);
+void st_abort(char * reason, char * details);
+void parseargs(int argc, char * argv[]);
diff --git a/src/sound.c b/src/sound.c
new file mode 100644 (file)
index 0000000..69c980b
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+  sound.c
+  
+  Super Tux - Audio Functions
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  April 22, 2000 - July 15, 2002
+*/
+
+#ifndef NOSOUND
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#include <SDL_mixer.h>
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "sound.h"
+#include "setup.h"
+
+
+/* --- LOAD A SOUND --- */
+
+Mix_Chunk * load_sound(char * file)
+{
+  Mix_Chunk * snd;
+  
+  if (use_sound)
+  {
+    snd = Mix_LoadWAV(file);
+  
+    if (snd == NULL)
+      st_abort("Can't load", file);
+  }
+  else
+    snd = NULL;
+
+  return(snd);
+}
+
+
+/* --- PLAY A SOUND --- */
+
+void playsound(Mix_Chunk * snd)
+{
+  Mix_PlayChannel(-1, snd, 0);
+}
+
+
+/* --- LOAD A SONG --- */
+
+Mix_Music * load_song(char * file)
+{
+  Mix_Music * sng;
+
+  if (use_sound)
+  {
+    sng = Mix_LoadMUS(file);
+
+    if (sng == NULL)
+      st_abort("Can't load", file);
+  }
+  else
+    sng = NULL;
+
+  return (sng);
+}
+
+#endif
diff --git a/src/sound.h b/src/sound.h
new file mode 100644 (file)
index 0000000..52c8ead
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+  sound.h
+  
+  Super Tux - Audio Functions
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 22, 2000 - July 15, 2002
+*/
+
+
+#ifndef NOSOUND
+
+Mix_Chunk * load_sound(char * file);
+void playsound(Mix_Chunk * snd);
+Mix_Music * load_song(char * file);
+
+#endif
diff --git a/src/supertux.c b/src/supertux.c
new file mode 100644 (file)
index 0000000..105b5bd
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+  supertux.c
+  
+  Super Tux
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 12, 2000
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "setup.h"
+#include "intro.h"
+#include "title.h"
+#include "gameloop.h"
+#include "screen.h"
+
+
+/* --- MAIN --- */
+
+#ifdef WIN32
+main(int argc, char * argv[])
+#else
+int main(int argc, char * argv[])
+#endif
+{
+  int done;
+  
+  parseargs(argc, argv);
+  
+  st_setup();
+  
+  done = intro();
+  
+  while (!done)
+    {
+      done = title();
+      if (!done)
+       done = gameloop();
+    }
+  
+  clearscreen(0, 0, 0);
+  updatescreen();
+  
+  st_shutdown();
+  
+  return(0);
+}
diff --git a/src/title.c b/src/title.c
new file mode 100644 (file)
index 0000000..831a2d9
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+  title.c
+  
+  Super Tux - Title Screen
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 12, 2000
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <SDL.h>
+#include <SDL_image.h>
+
+#ifndef NOSOUND
+#include <SDL_mixer.h>
+#endif
+
+#ifdef LINUX
+#include <pwd.h>
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "defines.h"
+#include "globals.h"
+#include "title.h"
+#include "screen.h"
+
+
+/* --- TITLE SCREEN --- */
+
+int title(void)
+{
+  SDL_Surface * title, * anim1, * anim2;
+  SDL_Event event;
+  SDLKey key;
+  int done, quit, frame, pict;
+  
+  
+  /* Clear screen: */
+  
+  clearscreen(0, 0, 0);
+  updatescreen();
+  
+  
+  /* Load images: */
+  
+  title = load_image(DATA_PREFIX "/images/title/title.png", IGNORE_ALPHA);
+  anim1 = load_image(DATA_PREFIX "/images/title/title-anim2.png",
+                    IGNORE_ALPHA);
+  anim2 = load_image(DATA_PREFIX "/images/title/title-anim1.png",
+                    IGNORE_ALPHA);
+  
+  
+  /* Draw the title background: */
+  
+  drawimage(title, 0, 0, UPDATE);
+  
+  
+  /* --- Main title loop: --- */
+  
+  done = 0;
+  quit = 0;
+  
+  frame = 0;
+  
+  do
+    {
+      frame++;
+      
+      
+      /* Handle events: */
+      
+      while (SDL_PollEvent(&event))
+       {
+         if (event.type == SDL_QUIT)
+           {
+             /* Quit event - quit: */
+             
+             quit = 1;
+           }
+         else if (event.type == SDL_KEYDOWN)
+           {
+             /* Keypress... */
+             
+             key = event.key.keysym.sym;
+             
+             if (key == SDLK_ESCAPE)
+               {
+                 /* Escape: Quit: */
+                 
+                 quit = 1;
+               }
+             else if (key == SDLK_SPACE || key == SDLK_RETURN)
+               {
+                 /* Space / Return: Continue: */
+                 
+                 done = 1;
+               }
+           }
+#ifdef JOY_YES
+         else if (event.type == SDL_JOYBUTTONDOWN)
+           {
+             /* Joystick button: Continue: */
+             
+             done = 1;
+           }
+#endif
+       }
+      
+      
+      /* Animate title screen: */
+      
+      pict = (frame / 5) % 3;
+      
+      if (pict == 0)
+       drawpart(title, 560, 270, 80, 75, UPDATE);
+      else if (pict == 1)
+       drawimage(anim1, 560, 270, UPDATE);
+      else if (pict == 2)
+       drawimage(anim2, 560, 270, UPDATE);
+      
+      
+      /* Pause: */
+      
+      SDL_Delay(50);
+    }
+  while (!done && !quit);
+  
+  
+  /* Free surfaces: */
+  
+  SDL_FreeSurface(title);
+  SDL_FreeSurface(anim1);
+  SDL_FreeSurface(anim2);
+  
+  
+  /* Return to main! */
+  
+  return(quit);
+}
diff --git a/src/title.h b/src/title.h
new file mode 100644 (file)
index 0000000..c7b0558
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+  title.h
+  
+  Super Tux - Title Screen
+  
+  by Bill Kendrick
+  bill@newbreedsoftware.com
+  http://www.newbreedsoftware.com/supertux/
+  
+  April 11, 2000 - April 11, 2000
+*/
+
+int title(void);