From: Bill Kendrick Date: Wed, 9 Apr 2003 05:45:33 +0000 (+0000) Subject: Initial revision X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=de11b13419f0f5ab58bbdbbfe7d4d1769696ab9a;p=supertux.git Initial revision SVN-Revision: 4 --- de11b13419f0f5ab58bbdbbfe7d4d1769696ab9a diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 000000000..ec5b85fe8 --- /dev/null +++ b/AUTHORS.txt @@ -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, + http://www.newbreedsoftware.com/bill/ + + Graphics: Bill Kendrick, using The GIMP + http://www.gimp.org/ + + Original Tux created by Larry Ewing + http://www.isc.tamu.edu/~lewing/linux/ + + Most Tux images for Super Tux + created by Wesley Poole + http://members.xoom.com/kokido + + Titlescreen Composed by Eric Windisch + + Concept: Gown (Tux's Girlfriend) from + "Tux: A Quest For Herring" + by Steve Baker + 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 + Robert S Dubinski + Brian Stentzel diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 000000000..6e4526c6e --- /dev/null +++ b/CHANGES.txt @@ -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 + + * 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 + + * Makefile fixes + Ian + + +INITIAL RELEASE 0.0.0 - April 11, 2000 +-------------------------------------- + * Initial alpha release. diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 000000000..60549be51 --- /dev/null +++ b/COPYING.txt @@ -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. + + 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.) + +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. + + 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. + + 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 + + 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. + + + Copyright (C) 19yy + + 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. + + , 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 index 000000000..55c882132 --- /dev/null +++ b/INSTALL.txt @@ -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 index 000000000..05dd31942 --- /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 index 000000000..ed4321b4e --- /dev/null +++ b/README.txt @@ -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 diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 000000000..f73b8c4b4 --- /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 index 000000000..46a1ef78d 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 index 000000000..3b884a531 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 index 000000000..25f6b2bb1 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 index 000000000..754fa392f 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 index 000000000..3db63a8e2 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 index 000000000..69991acd9 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 index 000000000..9c253312d 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 index 000000000..dbfcead92 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 index 000000000..cd7d17021 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 index 000000000..dfb0f72c4 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 index 000000000..b2c6c895f 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 index 000000000..a0edd5b4e 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 index 000000000..d025fe5b4 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 index 000000000..79219fb1b 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 index 000000000..2ee9e5028 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 index 000000000..115a18148 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 index 000000000..375223957 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 index 000000000..04c90db23 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 index 000000000..dd069b44a 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 index 000000000..e50a041c8 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 index 000000000..dd0762f03 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 index 000000000..48a7136f1 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 index 000000000..48697590d 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 index 000000000..bbec5b400 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 index 000000000..47b2daf6c 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 index 000000000..7f315e0c6 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 index 000000000..ea5640492 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 index 000000000..75d94f0f1 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 index 000000000..0623ccc4d 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 index 000000000..0526564ef 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 index 000000000..dca7cc94e 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 index 000000000..2ee021e36 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 index 000000000..53c0563ba 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 index 000000000..38d437ce0 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 index 000000000..4f8974b25 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 index 000000000..daa81e142 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 index 000000000..219df6c0d 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 index 000000000..b59eb3c6f 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 index 000000000..390eb7bee 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 index 000000000..0215c0b03 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 index 000000000..e532161d4 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 index 000000000..76319651d 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 index 000000000..1ed6b1f28 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 index 000000000..e31f961ec 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 index 000000000..d9c59d4f6 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 index 000000000..814ed5773 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 index 000000000..ae480f55e 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 index 000000000..f902b6e97 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 index 000000000..d9ded9381 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 index 000000000..39a1e1edd 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 index 000000000..52c7e10ab 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 index 000000000..f043ccd1e 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 index 000000000..0db8bfd37 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 index 000000000..7d0aa101d 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 index 000000000..5a22480e5 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 index 000000000..b25d674d3 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 index 000000000..8b4fc919e 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 index 000000000..608ed33a5 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 index 000000000..4a474d376 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 index 000000000..f0f92ee47 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 index 000000000..4d9c20e6d 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 index 000000000..f595d162e 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 index 000000000..7af7be8fa 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 index 000000000..3c2c91eac 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 index 000000000..9b21e6496 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 index 000000000..b18b61ddd 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 index 000000000..77dc7f924 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 index 000000000..14d94b493 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 index 000000000..02dccb43c 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 index 000000000..022dff968 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 index 000000000..ac6b45417 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 index 000000000..aedec4d50 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 index 000000000..e36b81305 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 index 000000000..38b304d4c 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 index 000000000..dbd0604a8 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 index 000000000..c4dcaf586 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 index 000000000..b6a950ddc 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 index 000000000..a9adf4d7f 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 index 000000000..7c56def98 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 index 000000000..f753a1bdf 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 index 000000000..c8b6b3e37 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 index 000000000..1bcf2580b 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 index 000000000..2b41f6341 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 index 000000000..b001b07bf 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 index 000000000..8efb709cb 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 index 000000000..147f785b0 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 index 000000000..3edd809e5 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 index 000000000..08647defe 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 index 000000000..18356100a 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 index 000000000..fdec34c15 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 index 000000000..3f0ad3637 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 index 000000000..a8c604167 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 index 000000000..f69193cca 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 index 000000000..64e87ebe3 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 index 000000000..0307773b2 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 index 000000000..23d0c6f2a 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 index 000000000..4948158fe 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 index 000000000..4592c3794 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 index 000000000..ad0c7e78d 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 index 000000000..89c792c70 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 index 000000000..c736096a3 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 index 000000000..edd7ff42f 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 index 000000000..7702c8ca0 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 index 000000000..1e899e390 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 index 000000000..5972823d3 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 index 000000000..8895554da 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 index 000000000..7cff2217d 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 index 000000000..7625ea714 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 index 000000000..004759545 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 index 000000000..71159263c 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 index 000000000..f8e7c0263 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 index 000000000..98ca4b939 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 index 000000000..6ef2b1f5c 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 index 000000000..218e7e20b 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 index 000000000..8ac308387 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 index 000000000..be07b5f48 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 index 000000000..4d861c54c 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 index 000000000..16e6ce645 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 index 000000000..1fb66a176 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 index 000000000..63c915eb4 --- /dev/null +++ b/data/levels/level1.dat @@ -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 index 000000000..b6a073d54 --- /dev/null +++ b/data/levels/level1.dat-old @@ -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 index 000000000..1fdb3c303 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 index 000000000..ad5e03dc5 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 index 000000000..634d23d3c 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 index 000000000..83de10ded 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 index 000000000..524b8e225 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 index 000000000..2e2be45eb 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 index 000000000..5741f232b 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 index 000000000..cadcc5ee7 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 index 000000000..f38d63548 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 index 000000000..96f3871c1 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 index 000000000..20537c36e 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 index 000000000..24240eae0 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 index 000000000..ab03fcbb9 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 index 000000000..fc186f648 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 index 000000000..00bfb9d7d 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 index 000000000..2e2be45eb 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 index 000000000..5741f232b 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 index 000000000..cadcc5ee7 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 index 000000000..292e5c36e 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 index 000000000..96f3871c1 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 index 000000000..b8e95caca 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 index 000000000..d89819ea6 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 index 000000000..016c7bf61 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 index 000000000..48696ef62 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 index 000000000..3abd9c7eb 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 index 000000000..a3f86c2ac 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 index 000000000..95edf4735 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 index 000000000..016c7bf61 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 index 000000000..9546ffc57 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 index 000000000..8576153ef 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 index 000000000..b6cc06131 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 index 000000000..95edf4735 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 index 000000000..8b1378917 --- /dev/null +++ b/obj/.empty-file @@ -0,0 +1 @@ + diff --git a/src/defines.h b/src/defines.h new file mode 100644 index 000000000..1e56b1fed --- /dev/null +++ b/src/defines.h @@ -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 index 000000000..11be5ade3 --- /dev/null +++ b/src/gameloop.c @@ -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 +#include +#include +#include +#include +#include +#include + +#ifndef NOSOUND +#include +#endif + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..813a07710 --- /dev/null +++ b/src/gameloop.h @@ -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 index 000000000..c25c85ff3 --- /dev/null +++ b/src/globals.h @@ -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 +#include + +#ifndef NOSOUND +#include +#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 index 000000000..47de7260e --- /dev/null +++ b/src/intro.c @@ -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 +#include +#include +#include +#include +#include +#include + +#ifndef NOSOUND +#include +#endif + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..0080138e8 --- /dev/null +++ b/src/intro.h @@ -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 index 000000000..5f0be628b --- /dev/null +++ b/src/screen.c @@ -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 +#include +#include +#include +#include +#include +#include + +#ifndef NOSOUND +#include +#endif + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..600004a01 --- /dev/null +++ b/src/screen.h @@ -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 + +#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 index 000000000..0c09c085e --- /dev/null +++ b/src/setup.c @@ -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 +#include +#include +#include +#include +#include +#include + +#ifndef NOSOUND +#include +#endif + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..3174d6007 --- /dev/null +++ b/src/setup.h @@ -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 index 000000000..69c980bc1 --- /dev/null +++ b/src/sound.c @@ -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 +#include +#include +#include +#include +#include +#include + +#include + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..52c8eadf8 --- /dev/null +++ b/src/sound.h @@ -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 index 000000000..105b5bdb7 --- /dev/null +++ b/src/supertux.c @@ -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 +#include +#include +#include +#include +#include +#include + +#ifndef NOSOUND +#include +#endif + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..831a2d95f --- /dev/null +++ b/src/title.c @@ -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 +#include +#include +#include +#include +#include +#include + +#ifndef NOSOUND +#include +#endif + +#ifdef LINUX +#include +#include +#include +#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 index 000000000..c7b05586f --- /dev/null +++ b/src/title.h @@ -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);