@ -0,0 +1,4 @@ | |||
David Ashley | |||
dashxdr@gmail.com | |||
http://www.xdr.com/dash | |||
http://www.linuxmotors.com |
@ -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. | |||
<one line to give the program's name and a brief idea of what it does.> | |||
Copyright (C) 19yy <name of author> | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
Also add information on how to contact you by electronic and paper mail. | |||
If the program is interactive, make it output a short notice like this | |||
when it starts in an interactive mode: | |||
Gnomovision version 69, Copyright (C) 19yy name of author | |||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |||
This is free software, and you are welcome to redistribute it | |||
under certain conditions; type `show c' for details. | |||
The hypothetical commands `show w' and `show c' should show the appropriate | |||
parts of the General Public License. Of course, the commands you use may | |||
be called something other than `show w' and `show c'; they could even be | |||
mouse-clicks or menu items--whatever suits your program. | |||
You should also get your employer (if you work as a programmer) or your | |||
school, if any, to sign a "copyright disclaimer" for the program, if | |||
necessary. Here is a sample; alter the names: | |||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |||
`Gnomovision' (which makes passes at compilers) written by James Hacker. | |||
<signature of Ty Coon>, 1 April 1989 | |||
Ty Coon, President of Vice | |||
This General Public License does not permit incorporating your program into | |||
proprietary programs. If your program is a subroutine library, you may | |||
consider it more useful to permit linking proprietary applications with the | |||
library. If this is what you want to do, use the GNU Library General | |||
Public License instead of this License. |
@ -0,0 +1,43 @@ | |||
Fri Jun 27 16:31:51 EDT 2008 | |||
David Ashley | |||
dashxdr@gmail.com | |||
Turned on -Wall in Makefile, got rid of all the warnings. Made Makefile.osx | |||
for building on OSX. Added some syntax checking for passing the "-m <host>" | |||
command line parameter. Got rid of all the damage lists (rectangles on the | |||
window that need to be updated) and instead just do a full screen update | |||
whenever necessary. | |||
--------------------------------------------------------------------------- | |||
Sun Jul 18 09:56:12 PDT 1999 | |||
Changed secondary control from ALT keys to 'b' key. On win32 the alt has | |||
special meaning and can cause events to be dropped, so a key up event is | |||
lost and the player gets stuck moving in some direction. | |||
Fri Jul 16 08:23:22 PDT 1999 | |||
Finished sdl port, the sockets problem stemmed from windoze not implementing | |||
Berkeley Sockets in a compatible manner. The program must call | |||
WSAStartup and WSACleanup on begin and end. Also instead of close on a | |||
socket you've got to call closesocket. This requires ugly | |||
#if defined(__WIN32__) | |||
... | |||
#endif | |||
sections in the code, which defeats the purpose of a nice platform | |||
indpendent source tree. Blame it on M$. | |||
Thu Jul 15 08:24:18 PDT 1999 | |||
Began converting X code to SDL code for portability. Having trouble with | |||
sockets library under win32. Converted all the graphics rendering routines to | |||
SDL, also dealt with the events translation. Under win32 the alt key can | |||
cause stuck keys. Still no pause() equivalent, ie wait until the timer | |||
interrupt occurs, but stay off the bus without eating cpu cycles. | |||
No sound conversion yet. | |||
Mon Jul 5 13:12:43 PDT 1999 | |||
Finally got around to dealing with old email... As per Christoph Frick's | |||
<ridcully@futurebyte.net> suggestion I added his idea of a | |||
"-m <matcher>" command line argument to | |||
specify at run time the matcher to use. | |||
Thanks Christoph! | |||
I've bumped the version to 101. |
@ -0,0 +1,37 @@ | |||
#DBG = -g | |||
CC = gcc | |||
CFLAGS = -O2 -Wall $(shell sdl-config --cflags) $(DBG) | |||
all: bomber matcher | |||
bomber: bomber.o gfx.o sound.o matcher | |||
gcc -o bomber bomber.o gfx.o sound.o $(shell sdl-config --libs) $(DBG) | |||
matcher: matcher.c | |||
bomber.o: bomber.c bomber.h gfx.h | |||
gfx.o: gfx.c gfx.h bomber.h | |||
sound.o: sound.c | |||
clean: | |||
rm -f *.o matcher bomber | |||
test: all | |||
./bomber | |||
WORK = /ram | |||
VER = 1.0.3 | |||
DDIR = SDL_bomber-$(VER) | |||
package: clean | |||
rm -rf $(WORK)/$(DDIR) | |||
mkdir $(WORK)/$(DDIR) | |||
cp *.c *.h Makefile* README INSTALL COPYING AUTHORS TODO $(WORK)/$(DDIR) | |||
cp -a data $(WORK)/$(DDIR) | |||
cp ChangeLog $(WORK)/$(DDIR) | |||
cd $(WORK) && tar czf $(DDIR).tgz $(DDIR) |
@ -0,0 +1,25 @@ | |||
#DBG += -g | |||
#DBG += -pg | |||
CC = gcc | |||
CFLAGS = -O2 -Wall -I/Library/Frameworks/SDL.framework/Headers $(DBG) | |||
LDFLAGS += -framework SDL -framework Cocoa -o $@ | |||
all: bomber | |||
bomber: gfx.o bomber.o sound.o SDLMain.o | |||
SDLMain.o: SDLmain.m | |||
bomber.o: bomber.c bomber.h gfx.h | |||
gfx.o: gfx.c bomber.h gfx.h | |||
sound.o: sound.c bomber.h | |||
clean: | |||
rm -f *.o bomber | |||
test: all | |||
./bomber | |||
@ -0,0 +1,9 @@ | |||
# Makefile for bomber | |||
# | |||
TARGET = bomber | |||
USEINET = true | |||
include ../GNUmake | |||
$(TARGET): bomber.o gfx.o sound.o |
@ -0,0 +1,94 @@ | |||
David Ashley | |||
dash@xdr.com | |||
990207 11:24 PST | |||
This is work in progress and might be of absolutely no use whatsoever. | |||
This is a Bomberman clone. I bought a game called Atomic Bomberman and found | |||
it awful, there were intolerable delays after each game in network play while | |||
the game was downloading data (what data?) over the network. Really crappy job | |||
they did but I liked the artwork and sound effects. | |||
Atomic Bomberman was a DOS/win95 game. I looked under linux games and found | |||
xblast but it was unusable for various reasons. For example its network | |||
support just relies on xwindows networking--before entering the game you've | |||
got to type in the host:display of each person who will be playing. Only | |||
the main machine gets any sound. Also in the game you kept moving in whatever | |||
direction you had last hit until you hit a wall or hit another direction. | |||
There was no point in using the source as a starting point, there were so | |||
many critical design flaws in that version I decided to write my own game from | |||
scratch. | |||
Currently the game will most likely only be playable on a LAN. | |||
Some machine must run the matcher program. Players register their game with | |||
the matcher machine, and joiners query the matcher machine to get a list of | |||
active games. On xdr.com there is a matcher program running and the bomber.c | |||
mname[] definition points to xdr.com. I tried it and it didn't work on my | |||
own LAN through a firewall. You can try the game as is and it might work using | |||
xdr.com as a matcher. Otherwise you'll have to run your own matcher daemon on | |||
some machine. Assuming you have 3 machines tom, dick and harry and you want | |||
to play a 3 player game, you would modify bomber.c's mname definiton to | |||
be (line 47 of bomber.c) | |||
char mname[]="tom"; | |||
Then on tom run the matcher program as a background task. | |||
Compile and distribute duplicate copies of bomber and data/* files, then | |||
run bomber on each machine. The menus should be self explanatory--one person | |||
selects HOST NETWORK GAME and the other people select JOIN NETWORK GAME. | |||
----------------- How to play --------------------------- | |||
You've got to blow up other players to win. Spacebar drops a bomb. Get away | |||
and hope your enemy gets hit by the flame. The 'b' key is a 2nd control | |||
for when you are lucky enough to pick up the bomb control--looks like a | |||
bomb with a timer on it. When you have that the bomb won't go off until | |||
detonated by another bomb, you are killed, or you press 'b'. | |||
Blowing up bricks might result in prizes, most of which are good. | |||
Skates = speed up | |||
Bomb = allow you to have one more active bomb | |||
flame = Increase bomb strength | |||
turtle = makes you move very slowly | |||
bomb with timer = controlled bomb detonation with 'b' key. | |||
gold flame = Set flame strength to max | |||
There isn't much point in playing the game alone (single player). In that | |||
case the only thing to avoid is accidentally killing yourself. Big deal... | |||
It's really a multiplayer game. | |||
----------------- Left to do: ------------------- | |||
Come up with a better scheme for internet play, as it is any latency will | |||
kill the game playability. Works fine on LAN though. | |||
Figure out why matching doesn't work through a firewall... | |||
[Specific case is 2 machines on my LAN cannot be matched by a machine that | |||
is outside the firewall, and the firewall machine is doing IP masquerading. | |||
Net result is matcher gets remapped IP addresses and these mean nothing | |||
inside the LAN, only make sense when used from the outside world] | |||
Score. | |||
Remap movement keys not implemented. | |||
Allow game hoster to set network game options and have them visible to players | |||
who have joined the game. | |||
Alternate gfx sets. | |||
Better handling of 8 bit mode with limited palette. | |||
Computer controlled things that can kill you. | |||
Other bonus types that can be harmful, such as skull. | |||
Internet play where everything is asynchronous, thus playable with a fixed | |||
latency. As it is now slaves send to master, then master sends back to | |||
slaves, and this data xfer must complete before the game can advance a step. | |||
For internet this would be intolerable. I've never tried though... | |||
Better docs, online explanations, attract mode... | |||
Single player with computer controlled figures that must be killed/avoided. | |||
---------------- | |||
Direct comments, complaints and questions to dash@xdr.com | |||
This code is GPL. |
@ -0,0 +1,11 @@ | |||
/* SDLMain.m - main entry point for our Cocoa-ized SDL app | |||
Initial Version: Darrell Walisser <dwaliss1@purdue.edu> | |||
Non-NIB-Code & other changes: Max Horn <max@quendi.de> | |||
Feel free to customize this file to suit your needs | |||
*/ | |||
#import <Cocoa/Cocoa.h> | |||
@interface SDLMain : NSObject | |||
@end |
@ -0,0 +1,338 @@ | |||
#ifndef BOMBER_H | |||
#define BOMBER_H | |||
#include "SDL.h" | |||
typedef unsigned char uchar; | |||
extern int xcolors[256]; | |||
#define NUMGFX 3 | |||
#define IXSIZE 640 | |||
#define IYSIZE 480 | |||
#define MYF1 0x180 | |||
#define MYF2 0x181 | |||
#define MYF3 0x182 | |||
#define MYF4 0x183 | |||
#define MYF5 0x184 | |||
#define MYF6 0x185 | |||
#define MYF7 0x186 | |||
#define MYF8 0x187 | |||
#define MYF9 0x188 | |||
#define MYF10 0x189 | |||
#define MYLEFT 0x190 | |||
#define MYRIGHT 0x191 | |||
#define MYUP 0x192 | |||
#define MYDOWN 0x193 | |||
#define MYPAGEUP 0x194 | |||
#define MYPAGEDOWN 0x195 | |||
#define MYHOME 0x196 | |||
#define MYEND 0x197 | |||
#define MYALTL 0x198 | |||
#define MYALTR 0x199 | |||
#define MYDELETE 0x7f | |||
#define MYSHIFTED 0x40 | |||
#define MYALTED 0x200 | |||
typedef struct gfxset | |||
{ | |||
uchar gs_colormap[768]; | |||
uchar gs_inout[256]; | |||
uchar *gs_pic; | |||
int gs_xsize; | |||
int gs_ysize; | |||
} gfxset; | |||
typedef struct figure | |||
{ | |||
int xsize,ysize; | |||
int xdelta,ydelta; | |||
uchar *graphics; | |||
} figure; | |||
typedef struct solid | |||
{ | |||
int xsize,ysize; | |||
uchar *graphics; | |||
} solid; | |||
typedef struct player | |||
{ | |||
struct player *next; | |||
int xpos,ypos; | |||
int flags; | |||
int abilities; | |||
int speed; | |||
int bombsused; | |||
int bombsavailable; | |||
int flamelength; | |||
int *at; | |||
int figcount; | |||
int doing; | |||
int action; | |||
int color; | |||
int controller; | |||
int fixx,fixy; | |||
figure *figure; | |||
} player; | |||
#define FLG_CONTROL 1 | |||
#define FLG_DEAD 2 | |||
typedef struct sprite | |||
{ | |||
int flags; | |||
int xpos,ypos; | |||
figure *fig; | |||
} sprite; | |||
typedef struct damage | |||
{ | |||
int xpos,ypos; | |||
int xsize,ysize; | |||
} damage; | |||
typedef struct list | |||
{ | |||
void *next; | |||
} list; | |||
typedef struct bomb | |||
{ | |||
struct bomb *next; | |||
int type; | |||
int xpos,ypos; | |||
int px,py; | |||
int power; | |||
int timer; | |||
int figcount; | |||
player *owner; | |||
} bomb; | |||
#define BOMB_OFF 0 | |||
#define BOMB_NORMAL 1 | |||
#define BOMB_CONTROLLED 2 | |||
#define BOMBLIFE 60 | |||
#define FLAMELIFE 15 | |||
#define DECAYLIFE 15 | |||
typedef struct flame | |||
{ | |||
struct flame *next; | |||
int xpos,ypos; | |||
int px,py; | |||
int timer; | |||
int lurd; | |||
player *owner; | |||
} flame; | |||
#define FL_UP 2 | |||
#define FL_DOWN 8 | |||
#define FL_LEFT 1 | |||
#define FL_RIGHT 4 | |||
typedef struct brickdecay | |||
{ | |||
struct brickdecay *next; | |||
int xpos,ypos; | |||
int px,py; | |||
int timer; | |||
} brickdecay; | |||
typedef struct generic | |||
{ | |||
struct generic *next; | |||
int xpos,ypos; | |||
int px,py; | |||
int timer; | |||
void (*process)(); | |||
void (*draw)(); | |||
void *ptr1,*ptr2; | |||
int data1,data2; | |||
} generic; | |||
typedef struct bonustile | |||
{ | |||
struct bonustile *next; | |||
int xpos,ypos; | |||
int px,py; | |||
int type; | |||
}bonustile; | |||
#define TILE_NONE -1 | |||
#define TILE_BOMB 5 | |||
#define TILE_FLAME 2 | |||
#define TILE_GOLDFLAME 7 | |||
#define TILE_CONTROL 9 | |||
#define TILE_SKATES 4 | |||
#define TILE_TURTLE 14 | |||
#define ACT_INVALID 0x88 | |||
#define ACT_NONE 0 | |||
#define ACT_UP 1 | |||
#define ACT_DOWN 2 | |||
#define ACT_LEFT 3 | |||
#define ACT_RIGHT 4 | |||
#define ACT_ENTER 5 | |||
#define ACT_QUIT 6 | |||
#define ACT_MASK 0x1f | |||
#define ACT_PRIMARY 0x40 | |||
#define ACT_SECONDARY 0x80 | |||
#define FIELD_EMPTY 0 | |||
#define FIELD_BORDER 1 | |||
#define FIELD_BOMB 2 | |||
#define FIELD_BRICK 3 | |||
#define FIELD_FLAME 4 | |||
#define FIELD_EXPLODING 5 | |||
#define FIELD_BONUS 6 | |||
#define CODE_CONT 0 | |||
#define CODE_QUIT 1 | |||
#define CODE_ALLDEAD 2 | |||
#define MAXTHINGS 500 | |||
#define MAXSETS 8 | |||
#define MAXSPRITES 128 | |||
#define MAXDAMAGES 512 | |||
#define MAXBOMBSDETONATED 32 | |||
extern char exitflag; | |||
extern player players[]; | |||
extern sprite sprites[]; | |||
extern gfxset gfxsets[NUMGFX]; | |||
extern uchar needwhole; | |||
extern figure walking[MAXSETS][60]; | |||
extern damage damages[]; | |||
extern bomb bombs[]; | |||
extern void centerx(player *pl); | |||
extern void centery(player *pl); | |||
extern void dropbomb(player *pl,int px,int py,int type); | |||
extern void adddetonate(bomb *bmb); | |||
extern void flameshaft(player *owner,int px,int py,int dx,int dy,int power); | |||
extern void detonatebomb(bomb *bmb); | |||
extern void initlist(void *first,int size,int num); | |||
extern void freeentry(void *entry); | |||
extern void addtail(void *header,void *entry); | |||
extern void delink(void *header,void *entry); | |||
extern void *allocentry(); | |||
extern void adddecay(int px,int py); | |||
extern void trybonus(int px,int py); | |||
extern void addbonus(int px,int py,int type); | |||
extern void deletebonus(bonustile *bonus); | |||
extern void queuesequence(int xpos,int ypos,figure *fig,int count); | |||
extern void playonce(generic *gen); | |||
extern void processgenerics(void); | |||
extern void drawgenerics(void); | |||
extern void drawgeneric(generic *gen); | |||
extern void killplayer(player *pl); | |||
extern void adddeath(player *pl); | |||
extern void drawbigstring(int xpos,int ypos,char *str); | |||
extern void bigscrprintf(char *str, ...); | |||
extern void drawstring(int xpos,int ypos,char *str); | |||
extern void scrprintf(char *str, ...); | |||
extern int textx,texty,fontxsize,fontysize; | |||
extern void texthome(void); | |||
extern unsigned char field[32][32]; | |||
extern void *info[32][32]; | |||
extern unsigned char singleoptions[10]; | |||
extern unsigned char gameoptions[10]; | |||
extern int getmsg(int); | |||
#define GO_DENSITY 0 | |||
#define GO_FLAMES 1 | |||
#define GO_BOMBS 2 | |||
#define GO_GENEROSITY 3 | |||
// network packet types | |||
// slave -> master packets | |||
#define PKT_MYDATA 0 // 4 bytes unique #,4 bytes frame #, 1 byte data | |||
#define PKT_JOIN 1 // 4 bytes unique #,16 bytes name | |||
// master -> slave packets | |||
#define PKT_INVITE 9 // 4 bytes unique #, any # of 1:slot,16:name sets (-1 end) | |||
#define PKT_BEGIN 10 // clone of INVITE | |||
#define PKT_STEP 11 // 4 bytes unique #, 4 bytes frame #, 8 bytes ACT_* | |||
#define PKT_QUIT 12 // 4 bytes unique # | |||
// master -> matcher packets | |||
#define PKT_REGISTER 16 // 4:unique #,4:pword hash,4:version #,16:name, 1:status | |||
// matcher -> master packets | |||
#define PKT_ACK 24 // perfect copy of packet received | |||
// slave -> matcher packets | |||
#define PKT_QUERY 32 // 4 bytes password hash | |||
// matcher -> slave packets | |||
#define PKT_INFO 40 // 4: pword hash, 2: count,#(4:unique,4:IP,2:port,16:name) | |||
// all bytes stored MSB first | |||
/* | |||
game startup: | |||
<master and matcher> | |||
Master: send REGISTER to matcher with optional password, wait for ack. If | |||
timout, resend. | |||
matcher: Wait for REGISTER packet, when received maintain database. respond | |||
to sender with ACK. REGISTER packet can close a game also. The REGISTER | |||
packet sent by the master has a unique word to be used to avoid confusion. | |||
REGISTER packet also contains a game version # | |||
After master registers game and receives ACK, just waits for slaves to contact. | |||
<slave and matcher> | |||
slave: send QUERY to matcher with optional password, wait for INFO, if timeout, | |||
resend. | |||
matcher: respond to QUERY with INFO packet. matcher need not maintain any | |||
database for slave requests. INFO packet contains IP addr and port for each | |||
master machine that matches the QUERY spec (ALL or password). Only a | |||
certain MAX # of entries are sent if there are too many to choose from. | |||
<slave and master> | |||
slave: send JOIN to master, wait for INVITE. If timeout, resend. JOIN packet | |||
contains the unique word the master created. JOIN also contains username. | |||
master: Respond to JOIN with INVITE. INVITE contains unique word from JOIN | |||
packet. INVITE either contains NO meaning game no longer exists or is closed | |||
or player is not invited. IF yes, INVITE contains info on other players | |||
already in the game (username and slot # for each). Master allocates the | |||
slots and avoids confusion based on IP addr and port #. INVITE also contains | |||
game options structure. Whenever a new player JOINS and is admitted, master | |||
sends updated INVITE packets to everyone already in the JOIN list. Whenever | |||
master changes game options, master sends out another set of INVITES | |||
Duplicate JOINS are answered with updated INVITE but nothing changes as far | |||
as allocation. | |||
Master player launches game after he's satisfied everyone has joined. | |||
Master sends BEGIN packet to everyone. BEGIN is identical to INVITE except | |||
that the data is final. Slave must respond with its first MYDATA packet with | |||
frame # of 0. If master times out waiting, master sends duplicate BEGIN to | |||
wayward slaves. Once master has received MYDATA from everyone, game starts. | |||
Within game slave sends MYDATA to master and waits for STEP packet. If | |||
timeout, slave sends duplicate MYDATA. | |||
If master times out waiting for a slave's MYDATA, slave gets dropped. MYDATAs | |||
received will be answered with PKT_QUIT. | |||
*/ | |||
int soundopen(void); | |||
void soundclose(void); | |||
void playsound(int n); | |||
#endif // BOMBER_H | |||
@ -0,0 +1,875 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <ctype.h> | |||
#include "bomber.h" | |||
#include "gfx.h" | |||
#define MAXCOLORS 256 | |||
int usedcolors=0; | |||
SDL_Surface *thescreen; | |||
SDL_Color themap[256]; | |||
uchar *videomem; | |||
int stride; | |||
int mousex,mousey,mouseb; | |||
uchar mustlock=0,locked=0; | |||
uchar *block64; | |||
int buttonstate=0,buttondown=0; | |||
int mxpos,mypos; | |||
int pressedcodes[KEYMAX],downcodes[KEYMAX],numpressed,numdown; | |||
void dumpgfx() | |||
{ | |||
usedcolors = 0; | |||
} | |||
int bestmatch(int red,int green,int blue) | |||
{ | |||
int i; | |||
int bestcolor,bestdelta=0; | |||
int rdelta,gdelta,bdelta; | |||
int delta; | |||
i=0; | |||
bestcolor=-1; | |||
while(i<usedcolors) | |||
{ | |||
rdelta=themap[i].r; | |||
rdelta-=red; | |||
rdelta*=rdelta; | |||
gdelta=themap[i].g; | |||
gdelta-=green; | |||
gdelta*=gdelta; | |||
bdelta=themap[i].b; | |||
bdelta-=blue; | |||
bdelta*=bdelta; | |||
delta=rdelta+gdelta+bdelta; | |||
if(bestcolor<0 || delta<bestdelta) | |||
{ | |||
bestdelta=delta; | |||
bestcolor=i; | |||
} | |||
i++; | |||
} | |||
return bestcolor; | |||
} | |||
void updatemap(void) | |||
{ | |||
SDL_SetColors(thescreen, themap, 0, 256); | |||
} | |||
void createinout(gfxset *gs) | |||
{ | |||
uchar *p; | |||
int i,j,counts[256]; | |||
uchar red,green,blue; | |||
int cnt; | |||
p=gs->gs_pic; | |||
for(i=0;i<256;i++) counts[i]=0; | |||
i=gs->gs_xsize*gs->gs_ysize; | |||
while(i--) | |||
counts[*p++]++; | |||
cnt=0; | |||
gs->gs_inout[0]=0; | |||
for(i=1;i<256;i++) | |||
{ | |||
if(counts[i]) | |||
{ | |||
cnt++; | |||
p=gs->gs_colormap+i+i+i; | |||
red=*p++; | |||
green=*p++; | |||
blue=*p++; | |||
for(j=0;j<usedcolors;j++) | |||
{ | |||
if(red==themap[j].r && | |||
green==themap[j].g && blue==themap[j].b) | |||
{ | |||
gs->gs_inout[i]=j; | |||
break; | |||
} | |||
} | |||
if(j==usedcolors) | |||
{ | |||
if(usedcolors<MAXCOLORS) | |||
{ | |||
themap[j].r=red; | |||
themap[j].g=green; | |||
themap[j].b=blue; | |||
gs->gs_inout[i]=usedcolors; | |||
++usedcolors; | |||
} else | |||
gs->gs_inout[i]=bestmatch(red,green,blue); | |||
} | |||
} | |||
} | |||
updatemap(); | |||
} | |||
uchar *compressfig(uchar *put,gfxset *gs, | |||
int sourcex,int sourcey,int sizex,int sizey) | |||
{ | |||
int j,gswidth; | |||
uchar *p, *p2,pixel,*map1; | |||
int dx,dy; | |||
gswidth=gs->gs_xsize; | |||
map1=gs->gs_inout; | |||
p=gs->gs_pic+sourcex+gswidth*sourcey; | |||
for(dy=0;dy<sizey;dy++) | |||
{ | |||
p2=p; | |||
j=0; | |||
for(dx=0;dx<=sizex;dx++) | |||
{ | |||
if(dx<sizex) pixel=*p2; | |||
else pixel=0; | |||
++p2; | |||
if(pixel) | |||
++j; | |||
else if(j) | |||
{ | |||
*put++=j; | |||
*put++=dx-j; | |||
*put++=dy; | |||
p2-=j+1; | |||
while(j) | |||
*put++=map1[*p2++],--j; | |||
++p2; | |||
} | |||
} | |||
p+=gswidth; | |||
} | |||
*put++=0; | |||
return put; | |||
} | |||
void gfxfetchsingle(figure *fig,gfxset *gs,int sourcex,int sourcey,int sizex,int sizey) | |||
{ | |||
uchar *p,*p2; | |||
int dx,dy; | |||
uchar *map1; | |||
int gswidth; | |||
int minx,miny,maxx,maxy; | |||
int tx,ty; | |||
map1=gs->gs_inout; | |||
gswidth=gs->gs_xsize; | |||
p=gs->gs_pic+sourcex+gswidth*sourcey; | |||
minx=miny=maxx=maxy=-1; | |||
for(dy=0;dy<sizey;dy++) | |||
{ | |||
p2=p; | |||
ty=sourcey+dy; | |||
for(dx=0;dx<sizex;dx++) | |||
{ | |||
if(!*p2++) continue; | |||
if(miny==-1 || ty<miny) miny=ty; | |||
if(maxy==-1 || ty>maxy) maxy=ty; | |||
tx=sourcex+dx; | |||
if(minx==-1 || tx<minx) minx=tx; | |||
if(maxx==-1 || tx>maxx) maxx=tx; | |||
} | |||
p+=gswidth; | |||
} | |||
if(minx==-1) | |||
{ | |||
minx=maxx=sourcex; | |||
miny=maxy=sourcey; | |||
} | |||
fig->xdelta=minx-sourcex; | |||
fig->ydelta=miny-sourcey; | |||
sourcex=minx; | |||
sourcey=miny; | |||
fig->xsize=sizex=maxx-minx+1; | |||
fig->ysize=sizey=maxy-miny+1; | |||
p=compressfig(block64,gs,sourcex,sourcey,sizex,sizey); | |||
fig->graphics=malloc(p-block64); | |||
if(fig->graphics) | |||
memcpy(fig->graphics,block64,p-block64); | |||
} | |||
//(gfxset *gs,figure *fig,int sourcex,int sourcey,int sizex,int sizey) | |||
void gfxfetch(gfxset *gs,figure *fig,int num) | |||
{ | |||
int x,y; | |||
int xsize,ysize; | |||
int fxsize,fysize; | |||
unsigned char *p,*p2; | |||
xsize=gs->gs_xsize; | |||
ysize=gs->gs_ysize; | |||
p2=p=gs->gs_pic+xsize+1; | |||
fxsize=2; | |||
while(*p++==0) ++fxsize; | |||
fysize=2; | |||
while(*p2==0) ++fysize,p2+=xsize; | |||
x=fxsize; | |||
y=0; | |||
while(num--) | |||
{ | |||
gfxfetchsingle(fig,gs,x,y,fxsize,fysize); | |||
x+=fxsize; | |||
if(x>xsize-fxsize) | |||
{ | |||
x=0; | |||
y+=fysize; | |||
if(y>ysize-fysize) | |||
y=0; | |||
} | |||
fig++; | |||
} | |||
} | |||
void solidfetch(gfxset *gs,solid *dest) | |||
{ | |||
int xsize,ysize; | |||
int i; | |||
unsigned char *p,*map; | |||
uchar *gfx; | |||
memset(dest,0,sizeof(solid)); | |||
xsize=gs->gs_xsize; | |||
ysize=gs->gs_ysize; | |||
i=xsize*ysize; | |||
gfx=dest->graphics=malloc(i); | |||
if(!gfx) return; | |||
dest->xsize=xsize; | |||
dest->ysize=ysize; | |||
map=gs->gs_inout; | |||
memcpy(gfx,gs->gs_pic,i); | |||
p=gfx; | |||
while(i--) | |||
{ | |||
if(*p) *p=map[*p]; | |||
++p; | |||
} | |||
} | |||
void solidcopyany(solid *src,solid *dest,int destx,int desty,int sizex,int sizey) | |||
{ | |||
int xmax,ymax; | |||
int j; | |||
uchar *p1,*p2; | |||
int w; | |||
xmax=src->xsize; | |||
ymax=src->ysize; | |||
if(destx>=xmax || desty>=ymax || destx+sizex<=0 || desty+sizey<=0) | |||
return; | |||
if(destx<0) | |||
{ | |||
sizex+=destx; | |||
destx=0; | |||
} | |||
if(desty<0) | |||
{ | |||
sizey+=desty; | |||
desty=0; | |||
} | |||
if(destx+sizex>xmax) | |||
sizex=xmax-destx; | |||
if(desty+sizey>ymax) | |||
sizey=ymax-desty; | |||
if(dest) | |||
{ | |||
w=dest->xsize; | |||
p1=dest->graphics+desty*w+destx; | |||
} else | |||
{ | |||
gfxlock(); | |||
w=stride; | |||
p1=videomem+desty*stride+destx; | |||
} | |||
p2=src->graphics+desty*xmax+destx; | |||
for(j=0;j<sizey;++j) | |||
{ | |||
memcpy(p1,p2,sizex); | |||
p1+=w; | |||
p2+=xmax; | |||
} | |||
} | |||
void solidcopy(solid *solid,int destx,int desty,int sizex,int sizey) | |||
{ | |||
solidcopyany(solid,0,destx,desty,sizex,sizey); | |||
} | |||
void drawfigureany(int x,int y,figure *fig,solid *dest) | |||
{ | |||
int run; | |||
int dx,dy; | |||
int xsize,ysize; | |||
int clipx,clipy,w; | |||
unsigned char *pc,*p,*p2,*take; | |||
take=fig->graphics; | |||
if(dest) | |||
{ | |||
w=clipx=dest->xsize; | |||
clipy=dest->ysize; | |||
pc=dest->graphics; | |||
} else | |||
{ | |||
gfxlock(); | |||
w=stride; | |||
clipx=IXSIZE; | |||
clipy=IYSIZE; | |||
pc=videomem; | |||
} | |||
dx=fig->xdelta; | |||
dy=fig->ydelta; | |||
xsize=fig->xsize; | |||
ysize=fig->ysize; | |||
x+=dx; | |||
y+=dy; | |||
if(x>=0 && y>=0 && x<=clipx-xsize && y<=clipy-ysize) | |||
{ | |||
while((run=*take++)) | |||
{ | |||
dx=*((signed char *)take); ++take; | |||
dy=*((signed char *)take); ++take; | |||
p=pc+w*(y+dy)+x+dx; | |||
while(run--) | |||
*p++=*take++; | |||
} | |||
} else | |||
{ | |||
while((run=*take++)) | |||
{ | |||
dx=*((signed char *)take); ++take; | |||
dy=*((signed char *)take); ++take; | |||
dx+=x; | |||
dy+=y; | |||
p2=take; | |||
take+=run; | |||
if(dy<0 || dy>=clipy) continue; | |||
if(dx>=clipx) continue; | |||
if(dx<0) | |||
{ | |||
p2-=dx; | |||
run+=dx; | |||
dx=0; | |||
} else if(dx+run>clipx) | |||
run=clipx-dx; | |||
p=pc+w*dy+dx; | |||
if(run) | |||
memcpy(p,p2,run); | |||
} | |||
} | |||
} | |||
void drawfigure(int destx,int desty,figure *fig) | |||
{ | |||
drawfigureany(destx,desty,fig,0); | |||
} | |||
void copyup() | |||
{ | |||
gfxunlock(); | |||
SDL_UpdateRect(thescreen, 0, 0, 0, 0); | |||
needwhole=0; | |||
} | |||
void copyupxy(int x,int y) | |||
{ | |||
gfxunlock(); | |||
SDL_UpdateRect(thescreen,x,y,24,24); | |||
} | |||
void copyupxysize(int x,int y,int xsize,int ysize) | |||
{ | |||
gfxunlock(); | |||
SDL_UpdateRect(thescreen,x,y,xsize,ysize); | |||
} | |||
void set_color(int color, int red, int green, int blue) | |||
{ | |||
themap[color].r=red; | |||
themap[color].g=green; | |||
themap[color].b=blue; | |||
} | |||
void opengfx(int argc, char **argv) | |||
{ | |||
unsigned long videoflags; | |||
themap[0].r=0; | |||
themap[0].g=0; | |||
themap[0].b=0; | |||
usedcolors=1; | |||
block64=malloc(65536); | |||
if(!block64) | |||
{ | |||
printf("Couldn't allocate block64\n"); | |||
exit(50); | |||
} | |||
if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0 ) | |||
{ | |||
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); | |||
exit(1); | |||
} | |||
videoflags = SDL_SWSURFACE|SDL_HWPALETTE; //|SDL_FULLSCREEN; | |||
thescreen = SDL_SetVideoMode(IXSIZE, IYSIZE, 8, videoflags); | |||
if ( thescreen == NULL ) | |||
{ | |||
fprintf(stderr, "Couldn't set display mode: %s\n", | |||
SDL_GetError()); | |||
SDL_Quit(); | |||
exit(5); | |||
} | |||
stride=thescreen->pitch; | |||
videomem=thescreen->pixels; | |||
mustlock=SDL_MUSTLOCK(thescreen); | |||
locked=0; | |||
SDL_ShowCursor(0); | |||
} | |||
void closegfx(void) | |||
{ | |||
SDL_Quit(); | |||
} | |||
int checkpressed(int code) | |||
{ | |||
int *p,i; | |||
i=numpressed; | |||
p=pressedcodes; | |||
while(i--) | |||
if(*p++==code) return 1; | |||
return 0; | |||
} | |||
int checkdown(int code) | |||
{ | |||
int *p,i; | |||
i=numdown; | |||
p=downcodes; | |||
while(i--) | |||
if(*p++==code) return 1; | |||
return 0; | |||
} | |||
int checkbutton(int button) | |||
{ | |||
return buttonstate & (1<<button); | |||
} | |||
int checkbuttondown(int button) | |||
{ | |||
return buttondown & (1<<button); | |||
} | |||
int anydown() | |||
{ | |||
return numdown; | |||
} | |||
int takedown(void) | |||
{ | |||
int res=0; | |||
if(numdown) | |||
{ | |||
res=*downcodes; | |||
--numdown; | |||
if(numdown) | |||
memmove(downcodes,downcodes+1,numdown*sizeof(int)); | |||
} | |||
return res; | |||
} | |||
int firstdown(vopid) | |||
{ | |||
return *downcodes; | |||
} | |||
#define ENDMARK 0xaabacada | |||
int sdlinoutnormal[]={ | |||
SDLK_0,'0', | |||
SDLK_1,'1', | |||
SDLK_2,'2', | |||
SDLK_3,'3', | |||
SDLK_4,'4', | |||
SDLK_5,'5', | |||
SDLK_6,'6', | |||
SDLK_7,'7', | |||
SDLK_8,'8', | |||
SDLK_9,'9', | |||
SDLK_a,'a', | |||
SDLK_b,'b', | |||
SDLK_c,'c', | |||
SDLK_d,'d', | |||
SDLK_e,'e', | |||
SDLK_f,'f', | |||
SDLK_g,'g', | |||
SDLK_h,'h', | |||
SDLK_i,'i', | |||
SDLK_j,'j', | |||
SDLK_k,'k', | |||
SDLK_l,'l', | |||
SDLK_m,'m', | |||
SDLK_n,'n', | |||
SDLK_o,'o', | |||
SDLK_p,'p', | |||
SDLK_q,'q', | |||
SDLK_r,'r', | |||
SDLK_s,'s', | |||
SDLK_t,'t', | |||
SDLK_u,'u', | |||
SDLK_v,'v', | |||
SDLK_w,'w', | |||
SDLK_x,'x', | |||
SDLK_y,'y', | |||
SDLK_z,'z', | |||
SDLK_MINUS,'-', | |||
SDLK_EQUALS,'=', | |||
SDLK_LEFTBRACKET,'[', | |||
SDLK_RIGHTBRACKET,']', | |||
SDLK_SEMICOLON,';', | |||
SDLK_QUOTE,'\'', | |||
SDLK_SLASH,'/', | |||
SDLK_PERIOD,'.', | |||
SDLK_COMMA,',', | |||
SDLK_BACKQUOTE,'`', | |||
SDLK_BACKSPACE,8, | |||
SDLK_TAB,9, | |||
SDLK_DELETE,MYDELETE, | |||
SDLK_RETURN,13, | |||
SDLK_F1,MYF1, | |||
SDLK_F2,MYF2, | |||
SDLK_F3,MYF3, | |||
SDLK_F4,MYF4, | |||
SDLK_F5,MYF5, | |||
SDLK_F6,MYF6, | |||
SDLK_F7,MYF7, | |||
SDLK_F8,MYF8, | |||
SDLK_F9,MYF9, | |||
SDLK_F10,MYF10, | |||
SDLK_ESCAPE,0x1b, | |||
SDLK_LEFT,MYLEFT, | |||
SDLK_RIGHT,MYRIGHT, | |||
SDLK_UP,MYUP, | |||
SDLK_DOWN,MYDOWN, | |||
SDLK_PAGEUP,MYPAGEUP, | |||
SDLK_PAGEDOWN,MYPAGEDOWN, | |||
SDLK_SPACE,' ', | |||
SDLK_HOME,MYHOME, | |||
SDLK_END,MYEND, | |||
SDLK_LALT,MYALTL, | |||
SDLK_RALT,MYALTR, | |||
ENDMARK | |||
}; | |||
int sdlinoutshifted[]={ | |||
SDLK_0,')', | |||
SDLK_1,'!', | |||
SDLK_2,'@', | |||
SDLK_3,'#', | |||
SDLK_4,'$', | |||
SDLK_5,'%', | |||
SDLK_6,'^', | |||
SDLK_7,'&', | |||
SDLK_8,'*', | |||
SDLK_9,'(', | |||
SDLK_a,'A', | |||
SDLK_b,'B', | |||
SDLK_c,'C', | |||
SDLK_d,'D', | |||
SDLK_e,'E', | |||
SDLK_f,'F', | |||
SDLK_g,'G', | |||
SDLK_h,'H', | |||
SDLK_i,'I', | |||
SDLK_j,'J', | |||
SDLK_k,'K', | |||
SDLK_l,'L', | |||
SDLK_m,'M', | |||
SDLK_n,'N', | |||
SDLK_o,'O', | |||
SDLK_p,'P', | |||
SDLK_q,'Q', | |||
SDLK_r,'R', | |||
SDLK_s,'S', | |||
SDLK_t,'T', | |||
SDLK_u,'U', | |||
SDLK_v,'V', | |||
SDLK_w,'W', | |||
SDLK_x,'X', | |||
SDLK_y,'Y', | |||
SDLK_z,'Z', | |||
SDLK_MINUS,'_', | |||
SDLK_EQUALS,'+', | |||
SDLK_LEFTBRACKET,'{', | |||
SDLK_RIGHTBRACKET,'}', | |||
SDLK_SEMICOLON,':', | |||
SDLK_QUOTE,'"', | |||
SDLK_SLASH,'?', | |||
SDLK_PERIOD,'>', | |||
SDLK_COMMA,'<', | |||
SDLK_BACKQUOTE,'~', | |||
SDLK_BACKSPACE,8, | |||
SDLK_TAB,9, | |||
SDLK_DELETE,MYDELETE, | |||
SDLK_RETURN,13, | |||
SDLK_F1,MYF1+MYSHIFTED, | |||
SDLK_F2,MYF2+MYSHIFTED, | |||
SDLK_F3,MYF3+MYSHIFTED, | |||
SDLK_F4,MYF4+MYSHIFTED, | |||
SDLK_F5,MYF5+MYSHIFTED, | |||
SDLK_F6,MYF6+MYSHIFTED, | |||
SDLK_F7,MYF7+MYSHIFTED, | |||
SDLK_F8,MYF8+MYSHIFTED, | |||
SDLK_F9,MYF9+MYSHIFTED, | |||
SDLK_F10,MYF10+MYSHIFTED, | |||
SDLK_ESCAPE,0x1b, | |||
SDLK_LEFT,MYLEFT+MYSHIFTED, | |||
SDLK_RIGHT,MYRIGHT+MYSHIFTED, | |||
SDLK_UP,MYUP+MYSHIFTED, | |||
SDLK_DOWN,MYDOWN+MYSHIFTED, | |||
SDLK_PAGEUP,MYPAGEUP, | |||
SDLK_PAGEDOWN,MYPAGEDOWN, | |||
SDLK_SPACE,' ', | |||
SDLK_HOME,MYHOME, | |||
SDLK_END,MYEND, | |||
SDLK_LALT,MYALTL, | |||
SDLK_RALT,MYALTR, | |||
ENDMARK | |||
}; | |||
int looklist(int code,int *list) | |||
{ | |||
while(*list!=ENDMARK) | |||
{ | |||
if(*list==code) | |||
return list[1]; | |||
list+=2; | |||
} | |||
return -1; | |||
} | |||
int mapkey(int code,int qual) | |||
{ | |||
if(qual & KMOD_SHIFT) | |||
code=looklist(code,sdlinoutshifted); | |||
else | |||
code=looklist(code,sdlinoutnormal); | |||
if(code<0) return -1; | |||
if(qual & KMOD_ALT) | |||
code|=MYALTED; | |||
return code; | |||
} | |||
void markkey(int code,int status) | |||
{ | |||
int i; | |||
int *ip; | |||
if(status) | |||
{ | |||
if(numdown<KEYMAX) | |||
downcodes[numdown++]=code; | |||
ip=pressedcodes; | |||
i=numpressed; | |||
while(i) | |||
if(*ip++==code) break; | |||
else i--; | |||
if(!i && numpressed<KEYMAX) | |||
pressedcodes[numpressed++]=code; | |||
} else | |||
{ | |||
i=numpressed; | |||
ip=pressedcodes; | |||
while(i) | |||
if(*ip++==code) | |||
{ | |||
*--ip=pressedcodes[--numpressed]; | |||
break; | |||
} else i--; | |||
} | |||
} | |||
void pollinput(void) | |||
{ | |||
SDL_PollEvent(0); | |||
} | |||
void scaninput(void) | |||
{ | |||
SDL_Event event; | |||
int key,mod; | |||
static int bs=0; | |||
numdown=0; | |||
buttondown=0; | |||
while(SDL_PollEvent(&event)) | |||
{ | |||
switch(event.type) | |||
{ | |||
case SDL_KEYDOWN: | |||
key=event.key.keysym.sym; | |||
mod=event.key.keysym.mod; | |||
markkey(mapkey(key,mod),1); | |||
break; | |||
case SDL_KEYUP: | |||
key=event.key.keysym.sym; | |||
mod=event.key.keysym.mod; | |||
markkey(mapkey(key,mod),0); | |||
break; | |||
case SDL_MOUSEBUTTONUP: | |||
bs&=~(1<<(event.button.button-1)); | |||
mousex=event.button.x>>1; | |||
mousey=event.button.y>>1; | |||
mouseb=bs; | |||
break; | |||
case SDL_MOUSEBUTTONDOWN: | |||
bs|=1<<(event.button.button-1); | |||
mousex=event.button.x>>1; | |||
mousey=event.button.y>>1; | |||
mouseb=bs; | |||
break; | |||
case SDL_MOUSEMOTION: | |||
mousex=event.motion.x>>1; | |||
mousey=event.motion.y>>1; | |||
break; | |||
case SDL_QUIT: | |||
exitflag = 1; | |||
break; | |||
} | |||
} | |||
} | |||
/* | |||
void scaninput() | |||
{ | |||
int i,*ip,code; | |||
numdown=0; | |||
buttondown=0; | |||
while(XCheckMaskEvent(dp,~0,&event)) | |||
switch(event.type) | |||
{ | |||
case KeyPress: | |||
code=XLookupKeysym(keyevent,0); | |||
if(numdown<KEYMAX) | |||
downcodes[numdown++]=code; | |||
ip=pressedcodes; | |||
i=numpressed; | |||
while(i) | |||
if(*ip++==code) break; | |||
else i--; | |||
if(!i && numpressed<KEYMAX) | |||
pressedcodes[numpressed++]=code; | |||