Codebase list amphetamine / HEAD
Import Debian changes 0.8.10-20 amphetamine (0.8.10-20) unstable; urgency=medium * Team upload. * Switch to compat level 11. * wrap-and-sort -sa. * Declare compliance with Debian Policy 4.1.4. * Update homepage address and point to tracker.debian.org because the old one is gone. * Move the package to Git and salsa.debian.org. * Drop deprecated amphetamine.menu file. * Add a comment in German to desktop file. * Remove 000_gcc_m68k.diff because it is unused. Markus Koschany 5 years ago
76 changed file(s) with 13014 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
0 KNOWN PROBLEMS
1
2 - Clipping sometimes fails, i.e. you can walk through walls or get stuck
3 - There's a problem with flying monsters. They sometimes get stuck
4 in the wall or will stick at the top of the screen an won't go
5 away until a new level is entered. Sometimes, the game gets completely
6 corrupted; the player may end up in the wall with the monster and die.
7 - There is a problem with C++ destructors not being called because they
8 are not declared "virtual" when the actually should. E.g. in
9 CApplication::UnloadLevelData(), instances of different subclasses of
10 CThing are deleted through a CThing pointer; as a result only
11 CThing::~CThing() is actually called, but not the destructor of the
12 actual subclasses. Unfortunately, there seem to be bugs in some of those
13 destructors. When just declaring CThings's of even CObject's destructor
14 virtual, the game becomes very unstable and crashes on changing between
15 different levels.
0 GNU GENERAL PUBLIC LICENSE
1 Version 2, June 1991
2
3 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
4 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The licenses for most software are designed to take away your
11 freedom to share and change it. By contrast, the GNU General Public
12 License is intended to guarantee your freedom to share and change free
13 software--to make sure the software is free for all its users. This
14 General Public License applies to most of the Free Software
15 Foundation's software and to any other program whose authors commit to
16 using it. (Some other Free Software Foundation software is covered by
17 the GNU Library General Public License instead.) You can apply it to
18 your programs, too.
19
20 When we speak of free software, we are referring to freedom, not
21 price. Our General Public Licenses are designed to make sure that you
22 have the freedom to distribute copies of free software (and charge for
23 this service if you wish), that you receive source code or can get it
24 if you want it, that you can change the software or use pieces of it
25 in new free programs; and that you know you can do these things.
26
27 To protect your rights, we need to make restrictions that forbid
28 anyone to deny you these rights or to ask you to surrender the rights.
29 These restrictions translate to certain responsibilities for you if you
30 distribute copies of the software, or if you modify it.
31
32 For example, if you distribute copies of such a program, whether
33 gratis or for a fee, you must give the recipients all the rights that
34 you have. You must make sure that they, too, receive or can get the
35 source code. And you must show them these terms so they know their
36 rights.
37
38 We protect your rights with two steps: (1) copyright the software, and
39 (2) offer you this license which gives you legal permission to copy,
40 distribute and/or modify the software.
41
42 Also, for each author's protection and ours, we want to make certain
43 that everyone understands that there is no warranty for this free
44 software. If the software is modified by someone else and passed on, we
45 want its recipients to know that what they have is not the original, so
46 that any problems introduced by others will not reflect on the original
47 authors' reputations.
48
49 Finally, any free program is threatened constantly by software
50 patents. We wish to avoid the danger that redistributors of a free
51 program will individually obtain patent licenses, in effect making the
52 program proprietary. To prevent this, we have made it clear that any
53 patent must be licensed for everyone's free use or not licensed at all.
54
55 The precise terms and conditions for copying, distribution and
56 modification follow.
57
58 GNU GENERAL PUBLIC LICENSE
59 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
60
61 0. This License applies to any program or other work which contains
62 a notice placed by the copyright holder saying it may be distributed
63 under the terms of this General Public License. The "Program", below,
64 refers to any such program or work, and a "work based on the Program"
65 means either the Program or any derivative work under copyright law:
66 that is to say, a work containing the Program or a portion of it,
67 either verbatim or with modifications and/or translated into another
68 language. (Hereinafter, translation is included without limitation in
69 the term "modification".) Each licensee is addressed as "you".
70
71 Activities other than copying, distribution and modification are not
72 covered by this License; they are outside its scope. The act of
73 running the Program is not restricted, and the output from the Program
74 is covered only if its contents constitute a work based on the
75 Program (independent of having been made by running the Program).
76 Whether that is true depends on what the Program does.
77
78 1. You may copy and distribute verbatim copies of the Program's
79 source code as you receive it, in any medium, provided that you
80 conspicuously and appropriately publish on each copy an appropriate
81 copyright notice and disclaimer of warranty; keep intact all the
82 notices that refer to this License and to the absence of any warranty;
83 and give any other recipients of the Program a copy of this License
84 along with the Program.
85
86 You may charge a fee for the physical act of transferring a copy, and
87 you may at your option offer warranty protection in exchange for a fee.
88
89 2. You may modify your copy or copies of the Program or any portion
90 of it, thus forming a work based on the Program, and copy and
91 distribute such modifications or work under the terms of Section 1
92 above, provided that you also meet all of these conditions:
93
94 a) You must cause the modified files to carry prominent notices
95 stating that you changed the files and the date of any change.
96
97 b) You must cause any work that you distribute or publish, that in
98 whole or in part contains or is derived from the Program or any
99 part thereof, to be licensed as a whole at no charge to all third
100 parties under the terms of this License.
101
102 c) If the modified program normally reads commands interactively
103 when run, you must cause it, when started running for such
104 interactive use in the most ordinary way, to print or display an
105 announcement including an appropriate copyright notice and a
106 notice that there is no warranty (or else, saying that you provide
107 a warranty) and that users may redistribute the program under
108 these conditions, and telling the user how to view a copy of this
109 License. (Exception: if the Program itself is interactive but
110 does not normally print such an announcement, your work based on
111 the Program is not required to print an announcement.)
112
113 These requirements apply to the modified work as a whole. If
114 identifiable sections of that work are not derived from the Program,
115 and can be reasonably considered independent and separate works in
116 themselves, then this License, and its terms, do not apply to those
117 sections when you distribute them as separate works. But when you
118 distribute the same sections as part of a whole which is a work based
119 on the Program, the distribution of the whole must be on the terms of
120 this License, whose permissions for other licensees extend to the
121 entire whole, and thus to each and every part regardless of who wrote it.
122
123 Thus, it is not the intent of this section to claim rights or contest
124 your rights to work written entirely by you; rather, the intent is to
125 exercise the right to control the distribution of derivative or
126 collective works based on the Program.
127
128 In addition, mere aggregation of another work not based on the Program
129 with the Program (or with a work based on the Program) on a volume of
130 a storage or distribution medium does not bring the other work under
131 the scope of this License.
132
133 3. You may copy and distribute the Program (or a work based on it,
134 under Section 2) in object code or executable form under the terms of
135 Sections 1 and 2 above provided that you also do one of the following:
136
137 a) Accompany it with the complete corresponding machine-readable
138 source code, which must be distributed under the terms of Sections
139 1 and 2 above on a medium customarily used for software interchange; or,
140
141 b) Accompany it with a written offer, valid for at least three
142 years, to give any third party, for a charge no more than your
143 cost of physically performing source distribution, a complete
144 machine-readable copy of the corresponding source code, to be
145 distributed under the terms of Sections 1 and 2 above on a medium
146 customarily used for software interchange; or,
147
148 c) Accompany it with the information you received as to the offer
149 to distribute corresponding source code. (This alternative is
150 allowed only for noncommercial distribution and only if you
151 received the program in object code or executable form with such
152 an offer, in accord with Subsection b above.)
153
154 The source code for a work means the preferred form of the work for
155 making modifications to it. For an executable work, complete source
156 code means all the source code for all modules it contains, plus any
157 associated interface definition files, plus the scripts used to
158 control compilation and installation of the executable. However, as a
159 special exception, the source code distributed need not include
160 anything that is normally distributed (in either source or binary
161 form) with the major components (compiler, kernel, and so on) of the
162 operating system on which the executable runs, unless that component
163 itself accompanies the executable.
164
165 If distribution of executable or object code is made by offering
166 access to copy from a designated place, then offering equivalent
167 access to copy the source code from the same place counts as
168 distribution of the source code, even though third parties are not
169 compelled to copy the source along with the object code.
170
171 4. You may not copy, modify, sublicense, or distribute the Program
172 except as expressly provided under this License. Any attempt
173 otherwise to copy, modify, sublicense or distribute the Program is
174 void, and will automatically terminate your rights under this License.
175 However, parties who have received copies, or rights, from you under
176 this License will not have their licenses terminated so long as such
177 parties remain in full compliance.
178
179 5. You are not required to accept this License, since you have not
180 signed it. However, nothing else grants you permission to modify or
181 distribute the Program or its derivative works. These actions are
182 prohibited by law if you do not accept this License. Therefore, by
183 modifying or distributing the Program (or any work based on the
184 Program), you indicate your acceptance of this License to do so, and
185 all its terms and conditions for copying, distributing or modifying
186 the Program or works based on it.
187
188 6. Each time you redistribute the Program (or any work based on the
189 Program), the recipient automatically receives a license from the
190 original licensor to copy, distribute or modify the Program subject to
191 these terms and conditions. You may not impose any further
192 restrictions on the recipients' exercise of the rights granted herein.
193 You are not responsible for enforcing compliance by third parties to
194 this License.
195
196 7. If, as a consequence of a court judgment or allegation of patent
197 infringement or for any other reason (not limited to patent issues),
198 conditions are imposed on you (whether by court order, agreement or
199 otherwise) that contradict the conditions of this License, they do not
200 excuse you from the conditions of this License. If you cannot
201 distribute so as to satisfy simultaneously your obligations under this
202 License and any other pertinent obligations, then as a consequence you
203 may not distribute the Program at all. For example, if a patent
204 license would not permit royalty-free redistribution of the Program by
205 all those who receive copies directly or indirectly through you, then
206 the only way you could satisfy both it and this License would be to
207 refrain entirely from distribution of the Program.
208
209 If any portion of this section is held invalid or unenforceable under
210 any particular circumstance, the balance of the section is intended to
211 apply and the section as a whole is intended to apply in other
212 circumstances.
213
214 It is not the purpose of this section to induce you to infringe any
215 patents or other property right claims or to contest validity of any
216 such claims; this section has the sole purpose of protecting the
217 integrity of the free software distribution system, which is
218 implemented by public license practices. Many people have made
219 generous contributions to the wide range of software distributed
220 through that system in reliance on consistent application of that
221 system; it is up to the author/donor to decide if he or she is willing
222 to distribute software through any other system and a licensee cannot
223 impose that choice.
224
225 This section is intended to make thoroughly clear what is believed to
226 be a consequence of the rest of this License.
227
228 8. If the distribution and/or use of the Program is restricted in
229 certain countries either by patents or by copyrighted interfaces, the
230 original copyright holder who places the Program under this License
231 may add an explicit geographical distribution limitation excluding
232 those countries, so that distribution is permitted only in or among
233 countries not thus excluded. In such case, this License incorporates
234 the limitation as if written in the body of this License.
235
236 9. The Free Software Foundation may publish revised and/or new versions
237 of the General Public License from time to time. Such new versions will
238 be similar in spirit to the present version, but may differ in detail to
239 address new problems or concerns.
240
241 Each version is given a distinguishing version number. If the Program
242 specifies a version number of this License which applies to it and "any
243 later version", you have the option of following the terms and conditions
244 either of that version or of any later version published by the Free
245 Software Foundation. If the Program does not specify a version number of
246 this License, you may choose any version ever published by the Free Software
247 Foundation.
248
249 10. If you wish to incorporate parts of the Program into other free
250 programs whose distribution conditions are different, write to the author
251 to ask for permission. For software which is copyrighted by the Free
252 Software Foundation, write to the Free Software Foundation; we sometimes
253 make exceptions for this. Our decision will be guided by the two goals
254 of preserving the free status of all derivatives of our free software and
255 of promoting the sharing and reuse of software generally.
256
257 NO WARRANTY
258
259 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
260 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
261 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
262 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
263 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
264 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
265 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
266 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
267 REPAIR OR CORRECTION.
268
269 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
270 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
271 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
272 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
273 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
274 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
275 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
276 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGES.
278
279 END OF TERMS AND CONDITIONS
0 March 25th, 2002:
1
2 Shape.cpp, Surface.cpp:
3 - included <memory.h>
4
5 System.hpp, Makefile:
6 Endianness is now autodetected through SDL_BYTEORDER, so there is
7 no need for the BYTE_ORDER variable in the Makefile anymore.
8
9 Object.cpp, Things.cpp, Monster.cpp, Monstrxx.cpp:
10 Initialize some more member variables in the constructors, especially in
11 Monstrxx.cpp. Some of the variables where indeed uninitialized, e.g.
12 "lastShoot", "currentShootDelay", and "nextShootTime". These changes
13 fix the bug where mosters just seem to freeze and don't move
14 and shoot despite being "alive".
15
16 September 17th, 2001:
17
18 Level.cpp:
19 - included <string.h>.
20 Amphetamine should now compile under Linux Mandrake 8.0.
21
22 March 27th, 2001:
23
24 Endianess is now controlled by a seperate variable "BYTE_ORDER", which can
25 be set to either "LITTLE_ENDIAN" (the default) or "BIG_ENDIAN".
26
27 --------------------------------------------------------------------------
28
29 CMaskedShape::Encode(),
30 CMaskedShape::RenderShapeClipped()
31 CMaskedShape::RenderShapeUnclipped()
32
33 These functions make must read/write 4-byte words at unaligned memory
34 locations. To avoid problems on architectures that require strict
35 alignment, the macros SET_LONG and GET_LONG perform slow byte-wise
36 access by default. If you are on IA-32 and "make" detects this, the
37 macro __OPT_MEM_ACCESS__ will be defined to enable faster versions of
38 SET_LONG and GET_LONG.
39
40 --------------------------------------------------------------------------
41
42 Surface.cpp: CGraphicSurface::PaintGraphic()
43 - replaced alignment dependent memory copy code by a call to "memcpy",
44 because it's fast enough and simpler this way
45
46 Shape.cpp: CTexture::RenderShape() and CBackground::RenderShape()
47 - replaced alignment dependent memory copy code by a call to "memcpy",
48 because it's fast enough and simpler this way
49
50 System.cpp/.hpp:
51 - removed support for libsge
0 1. Make sure SDL is installed correctly.
1
2 2. Have a look at the 'Makefile' and edit it where appropriate.
3 - 'USE_LIB_XPM=FALSE' if you don't have libXpm
4
5 3. Type 'make'. This should build the Amphetamine binary. You can safely
6 ignore the numerous warnings. If the compilation fails, you are in
7 in trouble. Try to tweak the 'Makefile'. You have to delete
8 '-funroll-loops' if you are still using gcc 2.7.2.3
9
10 4. Become root and type 'make install'. This will install the binary to
11 the directory specified in the makefile (default is '/usr/local/games/amph').
12 It will also create a symbolic link.
13
14 5. You have managed the difficult bit. Now, you have to install the data files
15 required by the game. Get 'amphetamine-${VERSION}.tar.bz' an do:
16 - cd /usr/local/games
17 - bzip2 -cd ~/amphetamine-data-0.8.tar.bz | tar xv
18
19 (Note: the exact commands depend on your syste configuration)
20
21 6. type 'amph' in order to run the game and have fun!
0 #===============
1 # User settings
2 #===============
3
4 # Install Paths
5 PREFIX := /usr/local
6 INSTALL_DIR := ${PREFIX}/games/amph
7
8 # Libraries
9 USE_LIB_XPM := TRUE
10
11 SDL_CONFIG := sdl-config
12 SDL_HEADERS := $(shell $(SDL_CONFIG) --cflags)
13 SDL_LIBS := $(shell $(SDL_CONFIG) --libs)
14
15 #=======================================================
16 # You should not have to change anything below
17
18 # Useful directories
19
20 MYCODEDIR := ./src
21
22 # Directories to search for header files
23
24 SEARCHDIRS := -I${MYCODEDIR} ${SDL_HEADERS}
25
26 # makemake variables
27
28 LINKER := g++
29 DEPENDFLAGS := -g ${SEARCHDIRS}
30 TOUCHHEADERS := ${MYCODEDIR}/*.h
31
32 # C
33
34 CC := gcc
35 CFLAGS = ${DEPENDFLAGS}
36
37 # C++
38
39 CXX := g++
40 CXXFLAGS = ${DEPENDFLAGS} -O9 -funroll-loops -fomit-frame-pointer -ffast-math -Wcast-align
41
42 %.o : %.cpp
43 ${CXX} ${CPPFLAGS} -c $< ${CXXFLAGS} -o $@
44
45 %.o : %.cxx
46 ${CXX} ${CPPFLAGS} -c $< ${CXXFLAGS}
47
48 # C preprocessor (C, C++, FORTRAN)
49 CPPFLAGS = -DINSTALL_DIR="\"${INSTALL_DIR}\""
50
51 ifeq ($(USE_LIB_XPM), TRUE)
52 CPPFLAGS := $(CPPFLAGS) -D_USE_LIB_XPM
53 endif
54
55 # Allow unaligned memory access on IA-32
56 ifeq ($(HOSTTYPE),i386)
57 CPPFLAGS := $(CPPFLAGS) -D__OPT_MEM_ACCESS__
58 endif
59
60 # linker
61
62 LOADLIBES := -lm $(SDL_LIBS)
63
64 ifeq ($(USE_LIB_XPM),TRUE)
65 LOADLIBES := $(LOADLIBES) -lXpm -lXt
66 endif
67
68 LDFLAGS = -L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib
69
70 .PHONY : default
71 default : amph
72
73 .PHONY : install
74 install: amph
75 @./mkinstalldirs ${INSTALL_DIR}
76 @install -c ./amph ${INSTALL_DIR}
77 @strip ${INSTALL_DIR}/amph
78 @ln -s ${INSTALL_DIR}/amph ${PREFIX}/bin/amph
79
80 # This is what makemake added
81
82
83 # amph
84
85 amph : ./src/Element.o ./src/File.o ./src/Gifload.o ./src/Graphfil.o ./src/Gui.o ./src/Appl.o ./src/Bullet.o ./src/Clut.o ./src/ConstVal.o ./src/Creeper.o ./src/Item.o ./src/Level.o ./src/Main.o ./src/Monster.o ./src/Monstrxx.o ./src/Object.o ./src/ObjInfo.o ./src/Player.o ./src/Pltform.o ./src/Shape.o ./src/ShapeLd.o ./src/Surface.o ./src/Thing.o ./src/Weapon.o ./src/System.o ./src/SndSys.o ./src/SoundList.o
86 ${LINKER} ${LDFLAGS} -o $@ ${filter-out %.a %.so, $^} ${LOADLIBES}
87
88
89 # target for making everything
90
91 .PHONY : all
92 all: amph
93
94
95 # target for removing all object files
96
97 .PHONY : tidy
98 tidy::
99 @${RM} core ./src/Appl.o ./src/Bullet.o ./src/Clut.o ./src/ConstVal.o ./src/Creeper.o ./src/Element.o ./src/File.o ./src/Gifload.o ./src/Graphfil.o ./src/Gui.o ./src/Item.o ./src/Level.o ./src/Main.o ./src/Monster.o ./src/Monstrxx.o ./src/ObjInfo.o ./src/Object.o ./src/Player.o ./src/Pltform.o ./src/Shape.o ./src/ShapeLd.o ./src/SndSys.o ./src/SoundList.o ./src/Surface.o ./src/System.o ./src/Thing.o ./src/Weapon.o
100
101 # target for removing all object files
102
103 .PHONY : clean
104 clean:: tidy
105 @${RM} amph
106
107 # list of all source files
108
109 MM_ALL_SOURCES := ./src/Appl.cpp ./src/Bullet.cpp ./src/Clut.cpp ./src/ConstVal.cpp ./src/Creeper.cpp ./src/Element.cpp ./src/File.cpp ./src/Gifload.cpp ./src/Graphfil.cpp ./src/Gui.cpp ./src/Item.cpp ./src/Level.cpp ./src/Main.cpp ./src/Monster.cpp ./src/Monstrxx.cpp ./src/ObjInfo.cpp ./src/Object.cpp ./src/Player.cpp ./src/Pltform.cpp ./src/Shape.cpp ./src/ShapeLd.cpp ./src/SndSys.cpp ./src/SoundList.cpp ./src/Surface.cpp ./src/System.cpp ./src/Thing.cpp ./src/Weapon.cpp
110
111
112 # target for checking a source file
113
114 CHECKSYNTAXFILE := ${basename ${filter %${CHECKSTRING}, ${MM_ALL_SOURCES}}}
115
116 .PHONY : checksyntax
117 checksyntax:
118 ifneq (${CHECKSYNTAXFILE},)
119 @${MAKE} ${addsuffix .o, ${CHECKSYNTAXFILE}}
120 else
121 @echo No target to make ${CHECKSTRING}
122 endif
123
124
125 # target for touching appropriate source files
126
127 .PHONY : touch
128 touch:
129 @echo
130 @echo Please ignore \"file arguments missing\" errors
131 @echo
132 @echo `grep -l ${TOUCHSTRING} ${MM_ALL_SOURCES}`
133 @-touch `grep -l ${TOUCHSTRING} ${MM_ALL_SOURCES}`
134 @echo
135 @echo `grep -l ${TOUCHSTRING} ${TOUCHHEADERS}`
136 @-touch `grep -l ${TOUCHSTRING} ${TOUCHHEADERS}`
137
138
139 # target for calculating dependencies
140
141 .PHONY : jdepend
142 jdepend:
143 @makemake -depend Makefile -- ${DEPENDFLAGS} -- ./src/Appl.cpp ./src/Appl.o ./src/Bullet.cpp ./src/Bullet.o ./src/Clut.cpp ./src/Clut.o ./src/ConstVal.cpp ./src/ConstVal.o ./src/Creeper.cpp ./src/Creeper.o ./src/Element.cpp ./src/Element.o ./src/File.cpp ./src/File.o ./src/Gifload.cpp ./src/Gifload.o ./src/Graphfil.cpp ./src/Graphfil.o ./src/Gui.cpp ./src/Gui.o ./src/Item.cpp ./src/Item.o ./src/Level.cpp ./src/Level.o ./src/Main.cpp ./src/Main.o ./src/Monster.cpp ./src/Monster.o ./src/Monstrxx.cpp ./src/Monstrxx.o ./src/ObjInfo.cpp ./src/ObjInfo.o ./src/Object.cpp ./src/Object.o ./src/Player.cpp ./src/Player.o ./src/Pltform.cpp ./src/Pltform.o ./src/Shape.cpp ./src/Shape.o ./src/ShapeLd.cpp ./src/ShapeLd.o ./src/SndSys.cpp ./src/SndSys.o ./src/SoundList.cpp ./src/SoundList.o ./src/Surface.cpp ./src/Surface.o ./src/System.cpp ./src/System.o ./src/Thing.cpp ./src/Thing.o ./src/Weapon.cpp ./src/Weapon.o
144
145
146 # DO NOT DELETE THIS LINE -- makemake depends on it.
147
148 ./src/Appl.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Gui.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
149
150 ./src/Bullet.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
151
152 ./src/Clut.o: ./src/AmpHead.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
153
154 ./src/ConstVal.o: ./src/AmpHead.hpp ./src/ConstVal.hpp ./src/System.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h
155
156 ./src/Creeper.o: ./src/AmpHead.hpp ./src/Creeper.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Shape.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
157
158 ./src/Element.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Gui.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
159
160 ./src/File.o: ./src/AmpHead.hpp ./src/File.hpp ./src/System.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
161
162 ./src/Gifload.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h
163
164 ./src/Graphfil.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h
165
166 ./src/Gui.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Gui.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
167
168 ./src/Item.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Item.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
169
170 ./src/Level.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Gui.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/time.h
171
172 ./src/Main.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Gui.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
173
174 ./src/Monster.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
175
176 ./src/Monstrxx.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/Monster.hpp ./src/Monstrxx.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
177
178 ./src/ObjInfo.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Item.hpp ./src/Level.hpp ./src/Monster.hpp ./src/Monstrxx.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeDes.hpp ./src/ShapeLd.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
179
180 ./src/Object.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
181
182 ./src/Player.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Gui.hpp ./src/Item.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeDes.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
183
184 ./src/Pltform.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/Monster.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Player.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
185
186 ./src/Shape.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
187
188 ./src/ShapeLd.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeDes.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
189
190 ./src/SndSys.o: ./src/AmpHead.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
191
192 ./src/SoundList.o: ./src/AmpHead.hpp ./src/SoundList.hpp ./src/System.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
193
194 ./src/Surface.o: ./src/AmpHead.hpp ./src/Clut.hpp ./src/ConstVal.hpp ./src/Graphfil.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
195
196 ./src/System.o: ./src/AmpHead.hpp ./src/Graphfil.hpp ./src/System.hpp /usr/include/X11/xpm.h /usr/include/fcntl.h /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/sys/types.h /usr/include/unistd.h
197
198 ./src/Thing.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
199
200 ./src/Weapon.o: ./src/AmpHead.hpp ./src/Appl.hpp ./src/Bullet.hpp ./src/ConstVal.hpp ./src/Element.hpp ./src/File.hpp ./src/Graphfil.hpp ./src/Level.hpp ./src/ObjInfo.hpp ./src/Object.hpp ./src/Pltform.hpp ./src/Shape.hpp ./src/ShapeLd.hpp ./src/SndSys.hpp ./src/SoundList.hpp ./src/Surface.hpp ./src/System.hpp ./src/Thing.hpp ./src/Weapon.hpp /usr/include/limits.h /usr/include/math.h /usr/include/stdio.h /usr/include/stdlib.h
201
0 March 25th, 2002, 0.8.10
1 - Fixed the bug where monsters just froze after playing
2 a while.
3 - Endianness autodetected by SDL
4 - Minor bugfixes
5
6 September 17th, 2001, 0.8.9
7 - Fixed compilation bug under Linux Mandrake 8.0 (gcc 2.96)
8 - Simplified configuration of the build process
9
10 February 27th, 2000, 0.8.8
11 - Compiles smoother with SDL 1.0
12 - Using sdl-config in the Makefile
13 - Minor bugfixes
14
15 November 18th, 1999, 0.8.7
16 - An old version of ObjInfo.cpp was included with
17 version 0.8.6, that prevented the game from running
18 on big-endian machines.
19
20 November 11th, 1999: 0.8.6
21 - Compiles and works under SPARC/Solaris
22 Check the TARGET_ARCH variable in the Makefile!
23
24 October 30th, 1999: 0.8.5
25 - Compiles without libXpm (no icon)
26
27 October 18th, 1999: 0.8.4
28 - Even cleaner sound system :)
29
30 September 4th, 1999: 0.8.3
31 - Fixed a bug that crashed the game in some situations if you
32 had no sound card.
33
34 September 3rd, 1999: 0.8.2
35 - Fixed some bugs in ObjInfo.cpp and ShapeLd.cpp that prevented
36 compilation with gcc 2.95 (thanks to Ralph Giles and Bernhard Trummer)).
37 - More fixes to the sound system
38 - New command line options (try --help)
39 - DGA support (option --fullscreen)
40
41 July 16th, 1999: 0.8.1
42 - Fixed some bug in the sound system
43 - Added some cheats (unsupported)
44 - Added an icon
0 AUTHORS
1
2 Amphetamine was created by Jonas Spillmann <jsp@stutent.ethz.ch>.
3
4 The Unix/SDL version is maintained by Lukas Loehrer <loehrerl@bigfoot.com>
5
6 REQUIREMENTS
7
8 SDL (Simple DirectMedia Layer) version >= 1.0
9 Get it from:
10 http://www.devolution.com/~slouken/projects/SDL/index.html
11
12 CONTROLS
13
14 left/right arrows move
15 left control fire
16 space bar jump
17 tab action (press buttons)
18 ESC menu
19
20 ALT+s screenshot
21
22 You can customize most controls by copying the file user.conf
23 from the Amphetamine data directory to your ~/.amph directory.
24 Modify it to suit your needs.
25
26 GAMEPLAY
27
28 Many aspect of the gameplay are controlled by the file amph.conf
29 in the main Amphetamine directory. Of most interest are the options
30 right at the beginning of the file that control the physics. If the
31 game seems to slow/fast to you, changing some of those values may help.
32
33 DGA MODE
34
35 Use the option --fullscreen to enable DGA fullscreen support. I cannot test
36 this myself, because my X Server does not support it properly. I am grateful
37 for any feedback regarding this option.
38
39 SPARC/Solaris
40
41 I was told that Amphetamine runs very slow on some SPARC machines.
42
43 LICENCE
44
45 This program is licensed under the terms of the GNU GPL, a copy
46 of which you should have received with this package.
47
48 PLANS
49
50 - Fixing the clipping bugs
51 - Fixing the strange bug involving flying monsters
0 /* XPM */
1 static char * amph_xpm[] = {
2 "48 48 66 1",
3 " c None",
4 ". c #FFCC66",
5 "+ c #FFCC99",
6 "@ c #FF9966",
7 "# c #CC9966",
8 "$ c #CC9933",
9 "% c #996633",
10 "& c #663333",
11 "* c #996666",
12 "= c #666633",
13 "- c #555555",
14 "; c #993333",
15 "> c #FFCC33",
16 ", c #FF9933",
17 "' c #444444",
18 ") c #CCCC66",
19 "! c #666666",
20 "~ c #220000",
21 "{ c #FFFF66",
22 "] c #330000",
23 "^ c #111111",
24 "/ c #CC6633",
25 "( c #110000",
26 "_ c #222222",
27 ": c #FFFF99",
28 "< c #CC6666",
29 "[ c #993366",
30 "} c #333300",
31 "| c #663300",
32 "1 c #333333",
33 "2 c #CC9900",
34 "3 c #996600",
35 "4 c #66FFCC",
36 "5 c #66FFFF",
37 "6 c #66CCCC",
38 "7 c #000000",
39 "8 c #CCFFFF",
40 "9 c #DDDDDD",
41 "0 c #336600",
42 "a c #004400",
43 "b c #003300",
44 "c c #666600",
45 "d c #005500",
46 "e c #006600",
47 "f c #CC3333",
48 "g c #007700",
49 "h c #999999",
50 "i c #CC9999",
51 "j c #66CC66",
52 "k c #999966",
53 "l c #99FFFF",
54 "m c #FFCCCC",
55 "n c #002200",
56 "o c #BBBBBB",
57 "p c #001100",
58 "q c #CCCC99",
59 "r c #CCCCCC",
60 "s c #888888",
61 "t c #CC99CC",
62 "u c #996699",
63 "v c #EEEEEE",
64 "w c #FFFFFF",
65 "x c #440000",
66 "y c #AAAAAA",
67 "z c #FF9999",
68 "A c #CC3366",
69 ".+................@@@.#.@#$$%&&*&=&-;-&&%*;%*%-;",
70 ".......+.+.+.+......>....,#@%'=*%*&%-&=*;=%;%;%%",
71 "..............)@).@.@.@$,#,$%&*%*%!;%*~~~~~%*%*%",
72 "+......+.+{+....+.....,@@,$@#*%*%%%*]~-&^~^~~%;*",
73 "....++........+.$$/$#)@#,$//$/*;%;*~~~~(_~~(~~*%",
74 "..+++{+.+.+.+:..@@#$@,,$<%<*%%%%[&;]]}|]|1~~~~%;",
75 "....+.+........#/%/<$</*/%%<%[*%%%%~|23%/|}_]_~%",
76 ".+++...+.+..)4)@%%#/<5*/*<*%*%;*%[%]32233|&(}]~*",
77 "+.+..+...)...445//<655<%<%;%*%*%;*%]|||||3|}_~~%",
78 ":+).+..@..@#@#665*655<%*%**%;*/*%%;|733773||7]]<",
79 ".+.....$###/##<48855*%<<</*<%*;*<%*33233333|-]];",
80 "+.+.+..@@#//</%98858/*<*%**%<*/*%*%%3232|33%%]%%",
81 ".+.....@$$/<<%6555855<%%%<%<%<%*%<%*||||33%3|<%*",
82 "+.+..@#$<<<#/*55%<<65%*<<%*;;%*/*%[%323333%|0%*/",
83 ".+...#,#$</*</*<<*%<%<%*%</*%*%*/*/*|2|%|abab000",
84 "+..@#$##<%</<*/*%/[%<*/%[%*<%<<;*;*00ababa_5a}|0",
85 "+.###<#<%#/**%<*/*%*%;%[/%*%*;%*%%00c}d0050aa5ae",
86 "..#</</%#/*/*<*/*%*/[*%<%*f*/**;5[000505d5d5a|ag",
87 "+.##*<*/<%*%<%<%*f*%%%;*<%*5[5/*<53|505555505bga",
88 "..@##<*<#h#iiiii#*/*<<<%;5;%%55555555588885b38j0",
89 "+..@i#ik*<**<%<#iiih%%%<**[%5%5;;535555585l8jj3a",
90 "..+i#ih%<*<%%**h<%i#*i*%*/%<%*5*5335505l5l5j3||a",
91 ".+i#<*i*/*<*<<ii<%***#i<%*<%;%;%335%=50585555|b}",
92 "m.#/<#i#hikihki#hh<%<*<ih;%*<*&;333&a008885c_5-}",
93 ".//**i#ii#ii#iiii#ih<%**##*/*%*%;&=;5da888d5an}7",
94 ";$iki#iiiiiiiioi#iiih<ik*kh*%<%*%*%dd5nn8cdpnan%",
95 "#<##iiio+ooiimqoii##k***%<#*<%[%*%[a5aa5n&d==pa|",
96 "<#i#iiiqr+momrmmmooi<s***<*i<*/*;*5ddnn5*=&daa%|",
97 "#i<iimqrmrrrq99mrmiiqi#h*;/h#<*;*%%ddaaa%[%;a|/|",
98 "iiiioqmm9mmmm999roqtii#uk**/h*%*%[%3|3||%*;%*3||",
99 "#oqm+r9rv9999v9r9rrrqiiiii*<*h;*%%[33/||*/&;%3%3",
100 "#i+rrm999vvv9vv999rroqoi#k%*<ih;*;%3/|||%*;*;%|3",
101 "iiom9999vvvvvvvv9v9rroii<iiihi<%;%%%|%||<*%%%%3%",
102 "imrrmvvvvvvvvvvvv999roiiiii#i#i&%@|/|||%;%&%|%%%",
103 "o+rm99vvvvvwvwvvvv99rrrrooih**#*&%&%&;%[%&&%%&%*",
104 "orrmvvvvvwwwwwwvvvv999roi#ik<*<&&&&&&;*%****&x;*",
105 "qr999vvvwwwwwwwvvvvv9rryoiii*%*&&%&&;*%[%;%;&1&/",
106 "orr9vvvvwwwwwwwwwvvv9rooiii*;&*&=&&&%*%*%*;&%&x&",
107 "qo99vvvwwwwwwwwwvvv9rrrqii#*&=*&&%&&%*%[%%*%&%&&",
108 "orr9vvvvwwwwwwwwvvvv99tqiiik*;*=&&&&;;*%;&&;&&&%",
109 "zrrm9vvvwwwwwwvvvvvv999roi#****&%&&%%*%;&&&_&&%;",
110 "oqrr9vvvvwwwwwwwvv99mmrrqoi#hk*%&;&%[%;;1&&|&%[%",
111 "mr9999vvvvvwwwvvvv9rrrmoi#i**h*&=*;&%*%&&&%*;*&;",
112 "q+mr999vvvvvvvvvvv99roqii<k*%*i;&=&&&;%&&;<;%%;%",
113 "ioqrrm9vvvvvvvvv9999rihs#i*%*u*&&;=&&&&&&%;%<;*%",
114 "iit+rr999vvvv9vvm999roi*****;#*%%&&&%&&&&%*%*%/A",
115 "kiiqor99rr9v99m99mmooti**!&;***;&&=;-&=;*<%</*;%",
116 "#iioroorrr99mr9mmqmiyih**!&&<*%;%&&&&&;%%;*;;;%;"};
1919 Try to run in DGA fullscreen mode. For this to work, you must be root.
2020 .TP
2121 .B \-v, \-\-version
22 Display version infomation and exit.
22 Display version information and exit.
2323 .SH AUTHOR
2424 This manual page was written by Joey Hess,
2525 for the Debian GNU/Linux system.
00 [Desktop Entry]
11 Name=Amphetamine
22 GenericName=Jump and Run game
3 Comment=Fight evil monsters with your magic weapons.
3 Comment=Fight evil monsters with your magic weapons
4 Comment[de]=Bekämpfe böse Monster mit deinen magischen Waffen
45 Type=Application
56 Exec=amph
67 Icon=amph
78 Terminal=false
89 Categories=Game;ActionGame;
9 Keywords=Games
10 Keywords=jump;run;action;
0 NEWS
01 README
1 NEWS
22 changelog
0 amph /usr/games
1 debian/amph.xpm /usr/share/pixmaps
02 debian/amphetamine.desktop /usr/share/applications
1 debian/amph.xpm /usr/share/pixmaps
2 amph /usr/games
+0
-3
debian/amphetamine.menu less more
0 ?package(amphetamine):needs="x11" section="Games/Action" \
1 title="Amphetamine" command="/usr/games/amph" \
2 icon="/usr/share/pixmaps/amph.xpm"
0 amphetamine (0.8.10-20) unstable; urgency=medium
1
2 * Team upload.
3 * Switch to compat level 11.
4 * wrap-and-sort -sa.
5 * Declare compliance with Debian Policy 4.1.4.
6 * Update homepage address and point to tracker.debian.org because the old one
7 is gone.
8 * Move the package to Git and salsa.debian.org.
9 * Drop deprecated amphetamine.menu file.
10 * Add a comment in German to desktop file.
11 * Remove 000_gcc_m68k.diff because it is unused.
12
13 -- Markus Koschany <apo@debian.org> Thu, 17 May 2018 13:11:39 +0200
14
015 amphetamine (0.8.10-19) unstable; urgency=low
116
217 [ Ansgar Burchardt ]
3247
3348 amphetamine (0.8.10-16) unstable; urgency=low
3449
35 * build-depend on libc6-dev-i386 (closes: #640554).
50 * build-depend on libc6-dev-i386 (closes: #640554).
3651 * use -iquote and -Wno-write-strings build flags.
3752 * bump standards version to 3.9.2.
3853
288303
289304 * Rebuilt with libsdl1.0, fixes missing libsdl dependancy, Closes: #55350
290305 * Hm, this bug seems vaguly important to me, but the submitter did not
291 flag it as such. Uploading to frozen, at the release manager's
306 flag it as such. Uploading to frozen, at the release manager's
292307 discretion -- I have no strong feelings either way, but a few people on
293308 IRC think it should go in.
294309
11 Section: games
22 Priority: optional
33 Build-Depends:
4 debhelper (>= 9),
5 libxpm-dev,
4 debhelper (>= 11),
65 imagemagick,
76 libsdl1.2-dev (>= 1.2.2-3.1),
7 libxpm-dev
88 Maintainer: Debian Games Team <pkg-games-devel@lists.alioth.debian.org>
9 Uploaders:
9 Uploaders:
1010 Sam Hocevar (Debian packages) <sam+deb@zoy.org>,
1111 Barry deFreese <bddebian@comcast.net>,
1212 Michael Gilbert <mgilbert@debian.org>
13 Standards-Version: 3.9.5
14 Homepage: http://homepage.hispeed.ch/loehrer/amph/amph.html
15 Vcs-Git: git://anonscm.debian.org/pkg-games/amphetamine.git
16 Vcs-Browser: http://anonscm.debian.org/viewvc/pkg-games/packages/trunk/amphetamine/
13 Standards-Version: 4.1.4
14 Homepage: https://tracker.debian.org/pkg/amphetamine
15 Vcs-Git: https://salsa.debian.org/games-team/amphetamine.git
16 Vcs-Browser: https://salsa.debian.org/games-team/amphetamine
1717
1818 Package: amphetamine
1919 Architecture: any
2020 Depends:
2121 amphetamine-data (>= 0.8.7-12),
22 ${shlibs:Depends},
23 ${misc:Depends}
22 ${misc:Depends},
23 ${shlibs:Depends}
2424 Description: jump'n run game with unique visual effects
2525 Amphetamine is an exciting jump'n run game that offers some unique visual
2626 effects like colored lighting, fogging and coronas. You must fight eleven
27 evil monsters with your magic weapons.
27 evil monsters with your magic weapons.
4444 ** GNU General Public License for more details.
4545
4646 The remainder of amphetamine was written by Jonas Spillmann
47 <jsp@stutent.ethz.ch>, and is is GPL'd.
47 <jsp@stutent.ethz.ch>, and is is GPL'd.
4848
4949 On Debian systems, the full text of the GPL can be found in
5050 /usr/share/common-licenses/GPL-2.
+0
-36
debian/patches/000_gcc_m68k.diff less more
0 description: use gcc 4.1 for m68k build
1 Index: amphetamine-0.8.10/Makefile
2 ===================================================================
3 --- amphetamine-0.8.10.orig/Makefile 2006-05-15 19:26:37.000000000 +0200
4 +++ amphetamine-0.8.10/Makefile 2006-05-15 19:34:04.000000000 +0200
5 @@ -13,6 +13,12 @@
6 SDL_HEADERS := $(shell $(SDL_CONFIG) --cflags)
7 SDL_LIBS := $(shell $(SDL_CONFIG) --libs)
8
9 +ifeq ($(shell uname -m), m68k)
10 +GXX = g++-4.1
11 +else
12 +GXX = g++
13 +endif
14 +
15 #=======================================================
16 # You should not have to change anything below
17
18 @@ -26,7 +32,7 @@
19
20 # makemake variables
21
22 -LINKER := g++
23 +LINKER := $(GXX)
24 DEPENDFLAGS := -g ${SEARCHDIRS}
25 TOUCHHEADERS := ${MYCODEDIR}/*.h
26
27 @@ -37,7 +43,7 @@
28
29 # C++
30
31 -CXX := g++
32 +CXX := $(GXX)
33 CXXFLAGS = ${DEPENDFLAGS} -O9 -funroll-loops -fomit-frame-pointer -ffast-math -Wcast-align
34
35 %.o : %.cpp
0 description: append to build flags
1 Index: amphetamine/Makefile
2 ===================================================================
3 --- amphetamine.orig/Makefile 2014-04-06 04:25:09.713627611 +0000
4 +++ amphetamine/Makefile 2014-04-06 04:28:04.057623123 +0000
5 @@ -34,12 +34,12 @@
6 # C
7
8 CC := gcc
9 -CFLAGS = ${DEPENDFLAGS}
10 +CFLAGS += ${DEPENDFLAGS}
11
12 # C++
13
14 CXX := g++
15 -CXXFLAGS = ${DEPENDFLAGS} -O9 -funroll-loops -fomit-frame-pointer -ffast-math -Wcast-align
16 +CXXFLAGS += ${DEPENDFLAGS} -O9 -funroll-loops -fomit-frame-pointer -ffast-math -Wcast-align
17
18 %.o : %.cpp
19 ${CXX} ${CPPFLAGS} -c $< ${CXXFLAGS} -o $@
20 @@ -48,7 +48,7 @@
21 ${CXX} ${CPPFLAGS} -c $< ${CXXFLAGS}
22
23 # C preprocessor (C, C++, FORTRAN)
24 -CPPFLAGS = -DINSTALL_DIR="\"${INSTALL_DIR}\""
25 +CPPFLAGS += -DINSTALL_DIR="\"${INSTALL_DIR}\""
26
27 ifeq ($(USE_LIB_XPM), TRUE)
28 CPPFLAGS := $(CPPFLAGS) -D_USE_LIB_XPM
29 @@ -67,7 +67,7 @@
30 LOADLIBES := $(LOADLIBES) -lXpm
31 endif
32
33 -LDFLAGS = -L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib
34 +LDFLAGS += -L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib
35
36 .PHONY : default
37 default : amph
0 description: fix a format string issue
1 --- a/src/AmpHead.hpp
2 +++ b/src/AmpHead.hpp
3 @@ -183,6 +183,6 @@ typedef struct {
4 #define SWAP(a, b, _t) (a) = (_t)((long)a ^ (long)(b)); (b) = (_t)((long)(a) ^ (long)(b)); (a) = (_t)((long)(a) ^ (long)(b));
5 #define NZ(a, b) ((a) == 0 ? (b) : (a))
6
7 -#define MSG(message) if (logFile) fprintf(logFile, message); fflush(logFile)
8 +#define MSG(message) if (logFile) fprintf(logFile, "%s", message); fflush(logFile)
9
10 #endif
0 amph
1 src/Appl.o
2 src/Bullet.o
3 src/Clut.o
4 src/ConstVal.o
5 src/Creeper.o
6 src/Element.o
7 src/File.o
8 src/Gifload.o
9 src/Graphfil.o
10 src/Gui.o
11 src/Item.o
12 src/Level.o
13 src/Main.o
14 src/Monster.o
15 src/Monstrxx.o
16 src/ObjInfo.o
17 src/Object.o
18 src/Player.o
19 src/Pltform.o
20 src/Shape.o
21 src/ShapeLd.o
22 src/SndSys.o
23 src/SoundList.o
24 src/Surface.o
25 src/System.o
26 src/Thing.o
27 src/Weapon.o
0 #! /bin/sh
1 # mkinstalldirs --- make directory hierarchy
2 # Author: Noah Friedman <friedman@prep.ai.mit.edu>
3 # Created: 1993-05-16
4 # Public domain
5
6 # $Id: mkinstalldirs,v 1.10 1996/05/03 07:37:52 friedman Exp $
7
8 errstatus=0
9
10 for file
11 do
12 set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
13 shift
14
15 pathcomp=
16 for d
17 do
18 pathcomp="$pathcomp$d"
19 case "$pathcomp" in
20 -* ) pathcomp=./$pathcomp ;;
21 esac
22
23 if test ! -d "$pathcomp"; then
24 echo "mkdir $pathcomp" 1>&2
25
26 mkdir "$pathcomp" || lasterr=$?
27
28 if test ! -d "$pathcomp"; then
29 errstatus=$lasterr
30 fi
31 fi
32
33 pathcomp="$pathcomp/"
34 done
35 done
36
37 exit $errstatus
38
39 # mkinstalldirs ends here
0 #ifndef __AMP_HEADER__
1 #define __AMP_HEADER__
2
3 #include "limits.h"
4 #include "float.h"
5
6 const long kVersionNumber = 0x0090;
7 const char kVersionString[] = "0.8.10"; // by LL
8 const long kVersionKey = 10835;
9 const char kMyName1[6] = "JONAS";
10 const char kMyName2[10] = "SPILLMANN";
11 const char kParFileName[] = "amph.conf"; // by LL
12 const char kLogFileName[] = "logfile";
13
14 enum {
15 // Gameplane
16 kGamePlaneWidth = 480,
17 kGamePlaneHeight = 480,
18 kUserPlaneWidth = 160,
19
20 // Num and size of level elements
21 kElementSize = 32,
22 kLevelWidth = 100,
23 kLevelHeight = 20,
24
25 // Screen resolution
26 kScreenWidth = 1280,
27 kScreenHeight = 1024,
28 kScreenDepth = 8,
29
30 kNumOfLevels = 15,
31
32
33 // Monster classes
34 kClassPlayer = 0,
35 kClassCreeper = 1,
36 kClassJumper = 2,
37 kClassFlyer = 3,
38 kClassWalker = 4,
39 kClassWarg = 5,
40
41 // Item classes
42 kClassBackgroundItem = 0,
43 kClassUnpassableItem = 1,
44 kClassMovableItem = 2,
45 kClassPortableItem = 3,
46
47 // Flags for flags field in item info
48 kItemUnpassableMask = 32768,
49 kItemPortableMask = 16384,
50 kItemHurtMask = 8192,
51 kItemExplodesMask = 4096,
52
53
54 // Flags for data field
55 kPassiveLightMask = 1,
56 kPassivePlatformMask = 2,
57 kRightDriftMask = 4,
58 kLeftDriftMask = 8,
59 kIceMask = 16,
60 kFlickeringMask = 32,
61 kInfotextMask = 64,
62 kHurtMask = 128,
63 kFogMask = 256,
64 kWaterMask = 512,
65 kLavaMask = 1024,
66 kTeleportMask = 2048,
67 kExitMask = 4096,
68 kSaveMask = 8192,
69 kLightSwitchMask = 16384,
70 kPlatformSwitchMask = 32768,
71
72 // Collision codes
73 kNoCollision = 0,
74 kCollisionOnTop = 1,
75 kCollisionOnLeft = 2,
76 kCollisionOnRight = 4,
77 kCollisionOnBottom = 8,
78 kCollisionWithPushing = 16,
79 kCollisionWithLevelBorders = 32,
80
81 // Return codes for ::Think and ::Move
82 kNoEvent = 0,
83 kDestroyMe = 1,
84
85 kCameraNo = 12
86 };
87
88 // Type IDs
89 enum {
90 kObject = 1,
91 kElement = 1 << 1,
92 kBackgroundElement =1 << 2,
93 kThing = 1 << 3,
94 kMonster = 1 << 4,
95 kPlayer = 1 << 5,
96 kItem = 1 << 6,
97 kStaticItem = 1 << 7,
98 kBackgroundItem = 1 << 8,
99 kMovableItem = 1 << 9,
100 kPortableItem = 1 << 10,
101 kPlatform = 1 << 11,
102 kBullet = 1 << 12,
103 kSorceryBullet = 1 << 13,
104 kBombBullet = 1 << 14,
105 kSineBullet = 1 << 15,
106 kGuidedBullet = 1 << 16,
107 kCreeper = 1 << 17,
108 kWalker = 1 << 18,
109 kJumper = 1 << 19,
110 kFlyer = 1 << 20,
111 kWarg = 1 << 21,
112 kCamera = 1 << 22
113 };
114
115 // Modi for drawing a shape
116 enum {
117 kShapemodusNormal = 0,
118 kShapemodusTransparent1,
119 kShapemodusTransparent2,
120 kShapemodusTransparent3,
121 kShapemodusRandom,
122 kShapemodusWater,
123 kShapemodusLava,
124 kShapemodusFog,
125 kShapemodusShadow,
126 kShapemodusBackwardFlag = 32768 // when set, the shape is drawn horizontally inverted
127 };
128
129 enum {
130 kWeaponNormal = 0,
131 kWeaponSorcery,
132 kWeaponMultibullet,
133 kWeaponBomb,
134 kWeaponStaff,
135 kWeaponInHand,
136 kWeaponSine,
137 kWeaponGuided,
138 kWeaponHasWeight
139 };
140
141 // Weapon stati
142 enum {
143 kWeaponDoesntExist,
144 kWeaponOutOfMunition,
145 kWeaponReady
146 };
147
148
149 enum { // Portable Items
150 kItemSword = 0,
151 kItemPhiol,
152 kItemSorcery,
153 kItemBow,
154 kItemScie,
155 kItemHands,
156 kItemBomb,
157 kItemStaff,
158 kItemPhiolmun,
159 kItemSorcerymun,
160 kItemBowmun,
161 kItemSciemun, // not used
162 kItemHandsmun,
163 kItemBombmun,
164 kItemStaffmun,
165 kItemOxygen,
166 kItemHelppacket
167 };
168
169 struct tRect {
170 short left, top, right, bottom;
171 };
172
173 typedef struct {
174 unsigned char red, green, blue;
175 } RGBcolor;
176
177
178 #define MIN(a, b) ((a) < (b) ? (a) : (b))
179 #define MAX(a, b) ((a) > (b) ? (a) : (b))
180 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
181 #define SIGN(a) ((a) >= 0 ? 1 : -1)
182 #define SWAP(a, b, _t) (a) = (_t)((long)a ^ (long)(b)); (b) = (_t)((long)(a) ^ (long)(b)); (a) = (_t)((long)(a) ^ (long)(b));
183 #define NZ(a, b) ((a) == 0 ? (b) : (a))
184
185 #define MSG(message) if (logFile) fprintf(logFile, message); fflush(logFile)
186
187 #endif
0 #include "Appl.hpp"
1 #include "System.hpp"
2 #include "Clut.hpp"
3 #include "Gui.hpp"
4 #include "SndSys.hpp"
5 #include <stdio.h>
6
7 extern CSystem *gSystem;
8 extern CLevel *gLevel;
9 extern CObjInfo *gObjInfo;
10 extern CShapeManager *gShapeManager;
11 extern CClutManager *gClutManager;
12 extern tConstValues *gConst;
13 extern CGUI *gGUI;
14 extern tGUIConstants *gGUIConst;
15 extern tConfigData *gConfigData;
16 extern CSoundSystem *gSoundSystem;
17
18 FILE *logFile;
19
20 void LoadParameters();
21 void LoadGUIParameters(); // in GUI.cpp
22 void StartupSoundSystem();
23 void ShutdownSoundSystem();
24
25 CApplication::CApplication()
26 {
27 MSG("new CSystem\n");
28 gSystem = new CSystem("Amphetamine");
29
30 MSG("LoadParameters()\n");
31 LoadParameters();
32
33 gSystem->NewWindow(0, 0, gConfigData->screenWidth, gConfigData->screenHeight);
34
35 MSG("LoadGUIParameters\n");
36 LoadGUIParameters();
37
38 MSG("new CSoundSystem\n");
39 gSoundSystem = new CSoundSystem(gSystem->workingSound);
40 }
41
42 CApplication::~CApplication()
43 {
44 delete gSoundSystem;
45
46 delete gConst;
47 delete gGUIConst;
48 delete gConfigData;
49
50 gSystem->DisposeWindow();
51 delete gSystem;
52
53 fclose(logFile);
54 }
55
56
57 void CApplication::InitGraphics()
58 {
59 MSG("gSystem->AllocateScreen\n");
60 gSystem->AllocateScreen(gConfigData->screenWidth, gConfigData->screenHeight, kScreenDepth);
61
62 MSG("gSystem->LoadPalette\n");
63 gSystem->LoadPalette(gConst->kFilePalette);
64 }
65
66 void CApplication::LoadData()
67 {
68 long startupTime;
69
70 MSG("new CClutManager\n");
71 gClutManager = new CClutManager();
72 MSG("Loading Palette\n");
73 gClutManager->LoadPalette(gSystem->palColors);
74 MSG("Building Luminosity Table\n");
75 gClutManager->BuildLuminosityTable();
76
77 MSG("new CGraphicsSurface (startup)\n");
78 startup = new CGraphicSurface(kGamePlaneWidth + kUserPlaneWidth, kGamePlaneHeight);
79 MSG("startup->Insert Graphic\n");
80 startup->InsertGraphic(gSystem->QualifyDataDir(gConst->kFileStartup), 0L, 0L); // by LL
81 MSG("startup->PaintGraphic\n");
82 startup->PaintGraphic(0, 0, 0, kShapemodusNormal);
83 MSG("startup->FlipToScreen\n");
84 startup->FlipToScreen(0, 0);
85 MSG("set startupTime\n");
86 startupTime = gSystem->GetTicks() + gConst->kStartupTime;
87
88
89
90 MSG("new CShapeManager\n");
91 gShapeManager = new CShapeManager();
92 MSG("new gShapeManager->LoadShapes\n");
93 gShapeManager->LoadShapes();
94 MSG("new gShapeManager->LoadBackground\n");
95 gShapeManager->LoadBackground(gConst->kFileBackground1);
96 lastBackground = 1;
97
98 MSG("creating plane (new CGraphicSurface\n");
99 plane = new CGraphicSurface(kGamePlaneWidth, kGamePlaneHeight);
100
101 while (gSystem->GetTicks() < startupTime && !gSystem->KeyPressed(kKeySpace)) { gSystem->ProcessEvents(); }
102 delete startup;
103
104 MSG("new CGUI\n");
105 gGUI = new CGUI(plane);
106
107 MSG("new CObjInfo\n");
108 gObjInfo = new CObjInfo(0);
109
110 command = kCmdNewGameLevel2;
111
112
113 }
114
115 void CApplication::LoadLevelData(short levelNumber)
116 {
117 thingList = 0L;
118 collisionThingList = 0L;
119 bulletList = 0L;
120 preRenderQueue = 0L;
121 postRenderQueue = 0L;
122 renderQueue = 0L;
123
124
125 gObjInfo->LoadPlatforms(levelNumber);
126
127 MSG("new CLevel\n");
128 if (command >= kLoadGameSlot0 && command <= kLoadGameSlot5) {
129 char *fileName = gSystem->QualifyHomeDir(gGUIConst->kSavedGames[command - kLoadGameSlot0]);
130 gLevel = new CLevel(levelNumber, fileName); // by LL
131 delete [] fileName;
132 } else
133 gLevel = new CLevel(levelNumber, 0L);
134
135 gGUI->SetFocus((CPlayer *)gLevel->focus);
136 }
137
138 void CApplication::Run()
139 {
140 levelNumber = 0;
141
142 while (command != kCmdQuit) {
143
144 if (command >= kCmdNewGameLevel1 && command <= kCmdNewGameLevel4) {
145 difficulty = command - kCmdNewGameLevel1;
146 levelNumber = 0;
147 }
148
149 currentWeaponSF = gConst->kWeaponSF[difficulty];
150 currentHealthSF = gConst->kHealthSF[difficulty];
151 currentSpeedSF = gConst->kSpeedSF[difficulty];
152
153 LoadLevelData(levelNumber);
154
155 if (command == kCmdNextLevel) {
156 if (gLevel->player->typeID & kPlayer) ((CPlayer *)gLevel->player)->RestoreDataFromNextLevel(&savedData);
157 gClutManager->FadeToColor(kFadeFromColor, kWhiteCoronaTable, plane);
158 }
159
160 MSG("--- RunLevel() --- \n");
161 RunLevel();
162
163 if (command == kCmdNextLevel) {
164 levelNumber ++;
165 gClutManager->FadeToColor(kFadeToColor, kWhiteCoronaTable, plane);
166 }else if (command == kCmdPrevLevel) levelNumber --;
167
168 UnloadLevelData();
169
170 }
171 }
172
173 void CApplication::RunLevel()
174 {
175 char fps[5];
176 long savedTicks = 0, ticks = 0, ttmp;
177 long frameCount = 0, saveFrameCount = 0;
178 tThingList *currentEntry, *tmp;
179 short message;
180 CThing *tmpThing;
181 char* fileName;
182
183 firstPlayRound = 1;
184 command = kCmdNoCommand;
185 syncTime = gSystem->GetTicks();
186 aveTime = 20;
187
188 while (command == kCmdNoCommand) {
189 frameCount ++;
190 //usleep(1000);
191
192 time = gSystem->GetTicks();
193 deltaTime = time - syncTime;
194 aveTime = (aveTime + deltaTime) / 2;
195 syncTime = time;
196
197 currentEntry = thingList;
198 while (currentEntry) {
199 message = kNoEvent;
200
201 message |= currentEntry->thing->Think();
202
203 if (message == kDestroyMe) {
204 tmp = currentEntry->next;
205 tmpThing = currentEntry->thing;
206 tmpThing->UnlinkInLists();
207 delete tmpThing;
208 currentEntry = tmp;
209 } else
210 currentEntry = currentEntry->next;
211 }
212
213 currentEntry = thingList;
214 while (currentEntry) {
215 message = kNoEvent;
216
217 message |= currentEntry->thing->Forces();
218
219 if (message == kDestroyMe) {
220 tmp = currentEntry->next;
221 tmpThing = currentEntry->thing;
222 tmpThing->UnlinkInLists();
223 delete tmpThing;
224 currentEntry = tmp;
225 } else
226 currentEntry = currentEntry->next;
227 }
228
229 currentEntry = thingList;
230 while (currentEntry) {
231 currentEntry->thing->Move();
232 currentEntry = currentEntry->next;
233 }
234
235
236 gLevel->PaintLevel();
237 gGUI->DisplayMessages();
238
239 plane->FlipToScreen(0, 0);
240 firstPlayRound = 0;
241
242 gGUI->Update();
243
244 ticks = gSystem->GetTicks();
245 if (gConst->kShowFPS && ticks - savedTicks > kTicksPerSecond) {
246 sprintf(fps, "%02d", saveFrameCount);
247 gSystem->PaintString(fps, 500, 20, 0);
248
249 sprintf(fps, "%02d", frameCount);
250 gSystem->PaintString(fps, 500, 20, 255);
251 saveFrameCount = frameCount;
252 frameCount = 0;
253 savedTicks = ticks;
254 }
255
256 if (gSystem->KeyPressed(kKeyEscape)) {
257 command = gGUI->RunUserInterface(kMainPage);
258 syncTime = gSystem->GetTicks();
259 }
260
261 if (command >= kSaveGameSlot0 && command <= kSaveGameSlot5) {
262 fileName = gSystem->QualifyHomeDir(gGUIConst->kSavedGames[command - kSaveGameSlot0]);
263 gLevel->WriteLevel(fileName); // by LL
264 delete [] fileName;
265 command = kCmdNoCommand;
266 }
267 if ((command == kCmdNextLevel) && (gLevel->player->typeID & kPlayer))
268 ((CPlayer *)(gLevel->player))->SaveDataToNextLevel(&savedData);
269 }
270 }
271
272 void CApplication::UnloadLevelData()
273 {
274 CThing *tmp;
275
276 while (thingList) {
277 tmp = thingList->thing;
278 tmp->UnlinkInLists();
279 delete tmp;
280 }
281
282 delete gLevel;
283 }
284
285 void CApplication::UnloadData()
286 {
287 delete gObjInfo;
288 delete gGUI;
289 gShapeManager->UnloadBackground();
290 gShapeManager->UnloadShapes();
291 delete gShapeManager;
292 delete gClutManager;
293 }
294
295 void CApplication::Quit()
296 {
297 delete plane;
298 gSystem->DisposeScreen();
299 }
300
301 void CApplication::Enqueue(tThingList **list, CThing *newThing)
302 {
303 tThingList *tmp;
304
305 if (!newThing) return;
306
307 tmp = new tThingList;
308 tmp->next = *list;
309 tmp->prev = 0L;
310 tmp->thing = newThing;
311
312 if (*list) (*list)->prev = tmp;
313
314 *list = tmp;
315 }
316
317 // INVARIANT: *list->prev is always 0L, i.e. *list points to the first valid entry in the list
318 void CApplication::Dequeue(tThingList **list, CThing *remove)
319 {
320 tThingList *tmp = *list;
321
322 if (remove) {
323 while (tmp) {
324 if (tmp->thing == remove) {
325 if (tmp == *list) *list = tmp->next;
326 if (tmp->next) tmp->next->prev = tmp->prev;
327 if (tmp->prev) tmp->prev->next = tmp->next;
328 delete tmp;
329
330 return;
331 }
332 tmp = tmp->next;
333 }
334 }
335 }
336
337
338 /*void CApplication::InsertCollisionThing(CThing *newThing)
339 {
340 if (!newThing) return;
341
342 if (!collisionThingList) {
343 newThing->nextCollisionThing = 0L;
344 newThing->prevCollisionThing = 0L;
345 collisionThingList = newThing;
346 } else {
347 newThing->prevCollisionThing = 0L;
348 newThing->nextCollisionThing = collisionThingList;
349 collisionThingList->prevCollisionThing = newThing;
350 collisionThingList = newThing;
351 }
352 }
353
354 void CApplication::RemoveCollisionThing(CThing *remove)
355 {
356 if (collisionThingList == remove) collisionThingList = collisionThingList->nextCollisionThing;
357 if (remove->nextCollisionThing) remove->nextCollisionThing->prevCollisionThing = remove->prevCollisionThing;
358 if (remove->prevCollisionThing) remove->prevCollisionThing->nextCollisionThing = remove->nextCollisionThing;
359 }
360
361 void CApplication::InsertBullet(CBullet *newBullet)
362 {
363 if (!newBullet) return;
364
365 if (!bulletList) {
366 newBullet->nextBullet = 0L;
367 newBullet->prevBullet = 0L;
368 bulletList = newBullet;
369 } else {
370 newBullet->prevBullet = 0L;
371 newBullet->nextBullet = bulletList;
372 bulletList->prevBullet = newBullet;
373 bulletList = newBullet;
374 }
375 }
376
377 void CApplication::RemoveBullet(CBullet *remove)
378 {
379 if (bulletList == remove) bulletList = bulletList->nextBullet;
380 if (remove->nextBullet) remove->nextBullet->prevBullet = remove->prevBullet;
381 if (remove->prevBullet) remove->prevBullet->nextBullet = remove->nextBullet;
382 }
383
384
385 void CApplication::InsertPreRenderThing(CThing *newThing)
386 {
387 if (!newThing) return;
388
389 if (!preRenderQueue) {
390 newThing->nextPreRenderThing = 0L;
391 newThing->prevPreRenderThing = 0L;
392 collisionThingList = newThing;
393 } else {
394 newThing->prevPreRenderThing = 0L;
395 newThing->nextPreRenderThing = preRenderQueue;
396 preRenderQueue->prevPreRenderThing = newThing;
397 preRenderQueue = newThing;
398 }
399 }
400
401 void CApplication::RemovePreRenderThing(CThing *remove)
402 {
403 if (preRenderQueue == remove) bulletList = bulletList->nextBullet;
404 if (remove->nextBullet) remove->nextBullet->prevBullet = remove->prevBullet;
405 if (remove->prevBullet) remove->prevBullet->nextBullet = remove->nextBullet;
406 }*/
0 #ifndef __AMP_APPL__
1 #define __AMP_APPL__
2
3 #include "AmpHead.hpp"
4 #include "System.hpp"
5 #include "Level.hpp"
6 #include "ObjInfo.hpp"
7 #include "Bullet.hpp"
8 #include "ConstVal.hpp"
9
10 enum { // commands
11 kCmdNoCommand,
12 kCmdNextLevel,
13 kCmdPrevLevel,
14 kCmdQuit,
15 kCmdNewGameLevel1,
16 kCmdNewGameLevel2,
17 kCmdNewGameLevel3,
18 kCmdNewGameLevel4,
19 kSaveGameSlot0,
20 kSaveGameSlot1,
21 kSaveGameSlot2,
22 kSaveGameSlot3,
23 kSaveGameSlot4,
24 kSaveGameSlot5,
25
26 kLoadGameSlot0,
27 kLoadGameSlot1,
28 kLoadGameSlot2,
29 kLoadGameSlot3,
30 kLoadGameSlot4,
31 kLoadGameSlot5
32 };
33
34 struct tThingList {
35 tThingList *next, *prev;
36 CThing *thing;
37 };
38
39 struct tPlayerData {
40 short munition[8];
41 short weaponStatus[8];
42
43 short currentWeapon;
44 short oxygen;
45 short health;
46 };
47
48 class CApplication {
49 protected:
50 tPlayerData savedData;
51 CGraphicSurface *startup;
52
53 public:
54 tThingList *thingList;
55 tThingList *collisionThingList;
56 tThingList *bulletList;
57 tThingList *preRenderQueue;
58 tThingList *postRenderQueue;
59 tThingList *renderQueue;
60
61 CGraphicSurface *plane;
62
63 CPlatform *platformTable[kNumPlatforms];
64 short lastBackground;
65
66 short firstPlayRound;
67 long syncTime; // current time in ticks, but only once each play round measured
68 short command;
69 short difficulty;
70 double currentWeaponSF, currentHealthSF, currentSpeedSF;
71 short levelNumber;
72 long time;
73 long deltaTime;
74 long aveTime;
75
76 CApplication();
77 ~CApplication();
78
79 void InitGraphics();
80 void LoadData();
81 void LoadLevelData(short levelNumber);
82 void Run();
83 void RunLevel();
84 void UnloadLevelData();
85 void UnloadData();
86 void Quit();
87
88 void Enqueue(tThingList **list, CThing *newThing);
89 void Dequeue(tThingList **list, CThing *remove);
90
91 /*void InsertThing(CThing *newThing);
92 void RemoveThing(CThing *remove);
93 void InsertCollisionThing(CThing *newThing);
94 void RemoveCollisionThing(CThing *remove);
95 void InsertBullet(CBullet *newBullet);
96 void RemoveBullet(CBullet *remove);
97 void InsertPreRenderThing(CThing *newThing);
98 void RemovePreRenderThing(CThing *remove);
99 void InsertPostRenderThing(CThing *newThing);
100 void RemovePostRenderThing(CThing *remove);*/
101
102 };
103
104 #endif
0 #include "Bullet.hpp"
1 #include "Monster.hpp"
2 #include <math.h>
3 #include "ShapeLd.hpp"
4 #include "Appl.hpp"
5 #include "Clut.hpp"
6 #include "SndSys.hpp"
7
8 extern CShapeManager *gShapeManager;
9 extern CApplication *gApplication;
10 extern CSystem *gSystem;
11 extern tConstValues *gConst;
12 extern CLevel *gLevel;
13 extern CClutManager *gClutManager;
14 extern CObjInfo *gObjInfo;
15 extern CSoundSystem *gSoundSystem;
16
17 CBullet::CBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *source, double targetpos) : CThing(initx, inity, width, height, number)
18 {
19 typeID |= kBullet;
20 LinkInLists();
21
22 if (weaponInfo) {
23 info = weaponInfo;
24 weight = info->art == kWeaponHasWeight ? 10 : 0;
25 weightless = 0;
26 background = 0;
27 /*xs = xm - gConst->kBulletWidth / 2;
28 ys = ym - gConst->kBulletWidth / 2;
29 xe = xm + gConst->kBulletWidth / 2;
30 ye = ym + gConst->kBulletWidth / 2;*/
31
32 OnAllocate();
33
34 shooter = source;
35 targetposition = targetpos;
36
37 if (projectile2) {
38 for (short n = 0; n < gConst->kBulletTailLength; n ++) {
39 tailX[n] = -1;
40 tailY[n] = -1;
41 }
42 tailStep = 0;
43 }
44
45 directionUnitx = directionx * gConst->kVelocityUnit / sqrt(directionx * directionx + directiony * directiony);
46 directionUnity = directiony * gConst->kVelocityUnit / sqrt(directionx * directionx + directiony * directiony);
47
48 action = kInFlight;
49
50 forceVectorX = 0;
51 forceVectorY = 0;
52 resForceX = resForceY = 0;
53
54 lastTime = gSystem->GetTicks();
55 deltaTime = 0;
56 }
57 }
58
59 void CBullet::OnAllocate()
60 {
61 projectile1 = gShapeManager->FindShape(info->projectileShapes[0], 0);
62 projectile2 = gShapeManager->FindShape(info->projectileShapes[1], 0);
63
64 if (projectile2) {
65 tailX = new short [gConst->kBulletTailLength];
66 tailY = new short [gConst->kBulletTailLength];
67 }else{
68 tailX = tailY = 0L;
69 }
70
71 currentDetonationShape = 0L;
72
73 for (short n = 0; n < 5; n ++) detonation[n] = gShapeManager->FindShape(info->detonationShapes[n], 0);
74 }
75
76 CBullet::~CBullet()
77 {
78 if (projectile2) {
79 delete [] tailX;
80 delete [] tailY;
81 }
82 }
83
84 void CBullet::LinkInLists()
85 {
86 gApplication->Enqueue(&gApplication->thingList, this);
87 gApplication->Enqueue(&gApplication->bulletList, this);
88 gApplication->Enqueue(&gApplication->renderQueue, this);
89 }
90
91 void CBullet::UnlinkInLists()
92 {
93 gApplication->Dequeue(&gApplication->thingList, this);
94 gApplication->Dequeue(&gApplication->bulletList, this);
95 gApplication->Dequeue(&gApplication->renderQueue, this);
96 }
97
98 short CBullet::Think()
99 {
100 CObject::Think();
101
102 Gravitation();
103
104 if (directionUnitx) forceVectorX = directionUnitx * info->speed * deltaTime;
105 if (directionUnity) forceVectorY = directionUnity * info->speed * deltaTime;
106
107 return kNoEvent;
108 }
109
110 short CBullet::Forces()
111 {
112 short collisionCode, collisionObject;
113 tThingList *entry;
114 CElement *element;
115
116 if (action == kInFlight) {
117 CObject::Forces();
118 //collisionCode = ExertForce(resForceX, resForceY, collisionObject, &obstacle);
119
120 if (xm < 0 || ym < 0 || xm > kLevelWidth * kElementSize + kElementSize || ym > kLevelHeight * kElementSize + kElementSize) {
121 Detonate(kCollisionWithLevelBorders, 0L);
122 return kNoEvent;
123 }
124
125 element = gLevel->GetElement(xm, ym);
126 if (element && !element->background) {
127 Detonate(0, 0L);
128 return kNoEvent;
129 }
130
131 entry = gApplication->collisionThingList;
132 while (entry) {
133 if (entry->thing != this && entry->thing != shooter && !(entry->thing->typeID & (kBullet | kStaticItem | kPortableItem)) && entry->thing->CollisionPossible(xm, ym)) {
134 Detonate(0, entry->thing);
135 entry = 0L;
136 }else entry = entry->next;
137 }
138
139 return kNoEvent;
140
141 }else if (action == kInDetonation) {
142 return DetonationAnimation();
143 }
144
145 return kNoEvent;
146 }
147
148
149 void CBullet::Detonate(short collisionCode, CObject *victim)
150 {
151 action = kInDetonation;
152 detonationStartTime = lastTime;
153
154 noDetonation = collisionCode == kCollisionWithLevelBorders;
155
156 Damage(victim);
157
158 gSoundSystem->Play(gSoundSystem->weaponHitSounds[thingNumber], xm, ym);
159
160 if (shooter && !(shooter->typeID & kPlayer)) {
161 if ((directionUnitx > 0 && xe >= targetposition) || (directionUnitx < 0 && xs <= targetposition))
162 ((CMonster *)shooter)->OnShootSuccessful();
163 else ((CMonster *)shooter)->OnShootNotSuccessful();
164 }
165 }
166
167
168 short CBullet::DetonationAnimation()
169 {
170 long frame = (long)((double)(lastTime - detonationStartTime) * gConst->kDetonationFrameTime);
171
172 if (frame > 4 || noDetonation) {
173 currentDetonationShape = 0L;
174 return kDestroyMe;
175
176 }else{
177 currentDetonationShape = detonation[frame];
178 return kNoEvent;
179 }
180 }
181
182 // ---------------------------------------
183 void CBullet::Damage(CObject *victim)
184 // called from CBullet::DetonationAnimation
185 // sends a TestForDamage-Event to all collision objects
186 {
187 if (info->rad) {
188 tThingList *currentEntry = gApplication->collisionThingList;
189
190 while (currentEntry) {
191 if (currentEntry->thing != this) currentEntry->thing->TestForDamage(xs, ys, info->rad, info->damage);
192 currentEntry = currentEntry->next;
193 }
194 }else{
195 if (victim && victim != shooter && victim->typeID & kThing) ((CThing *)victim)->OnDamage(info->damage);
196 }
197 }
198
199
200 void CBullet::Move()
201 {
202 if (action == kInFlight) CThing::Move();
203
204 if (projectile2) {
205 if (tailStep > gConst->kBulletTailDistance) {
206 for (short n = gConst->kBulletTailLength -2; n >= 0; n --) {
207 tailX[n + 1] = tailX[n];
208 tailY[n + 1] = tailY[n];
209 }
210 tailX[0] = (short)xs;
211 tailY[0] = (short)ys;
212 tailStep = 0;
213 }else tailStep += gConst->kVelocityUnit * info->speed * deltaTime;
214 }
215 }
216
217 void CBullet::Render(short planeX, short planeY, tRect *clipRect)
218 {
219 short tailMode;
220 if (info->effect != kLightningNoEffect) gClutManager->DrawLightning(xm, ym, info->effect, gApplication->plane);
221
222 if (action == kInFlight) {
223 if (resForceX < 0) modus |= kShapemodusBackwardFlag;
224 if (projectile1) projectile1->RenderShape(xs - planeX, ys - planeY, clipRect,
225 modus, 0, gApplication->plane);
226 }else{
227 if (currentDetonationShape) currentDetonationShape->RenderShape(xs - planeX, ys - planeY, clipRect,
228 modus, 0, gApplication->plane);
229 }
230 if (projectile2) {
231 for (short n = 0; n < gConst->kBulletTailLength; n ++) {
232 if (n < gConst->kBulletTailLength / 3) tailMode = kShapemodusTransparent1;
233 else if (n > gConst->kBulletTailLength * 2 / 3) tailMode = kShapemodusTransparent3;
234 else tailMode = kShapemodusTransparent2;
235
236 if (tailX[n] != -1) projectile2->RenderShape(tailX[n] + (short)xs - tailX[0] - planeX, tailY[n] + (short)ys - tailY[0] - planeY, clipRect, tailMode, 0, gApplication->plane);
237 }
238 }
239 }
240
241 short CBullet::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject)
242 {
243 if (action != kInDetonation &&
244 ((top >= ys && top <= ye) || (bottom >= ys && bottom <= ye)) &&
245 sender != shooter && !(sender->typeID & kBullet)) {
246 if (left >= xs && left <= xe) Detonate(kCollisionOnRight, sender);
247 if (right >= xs && right <= xe) Detonate(kCollisionOnLeft, sender);
248 }
249 return kNoCollision;
250 }
251
252
253 short CBullet::AmIATreatment(double victimxs, double victimys, double victimxe, double victimye, double &fx, double &fy)
254 {
255 double coll;
256
257 if ((xm - victimxs) * (xm - victimxs) + (ym - victimys) * (ym - victimys) < gConst->kTreatDistance * gConst->kTreatDistance &&
258 SIGN(victimxs - xs) == SIGN(resForceX)) {
259 fx = resForceX; fy = resForceY;
260
261 if (ABS(resForceX) > ABS(resForceY)) {
262 coll = ym + resForceY * (victimxs - xm) / resForceX;
263 if (coll > victimys - (ye - ys) && coll < victimye + (ye - ys)) return 1; else return 0;
264 }else{
265 coll = xm + resForceX * (victimys - ym) / resForceY;
266 if (coll > victimxs - (xe - xs) && coll < victimxe + (xe - xs)) return 1; else return 0;
267 }
268 }else return 0;
269 }
270
271
272 CSorceryBullet::CSorceryBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *source, double targetpos) : CBullet(initx, inity, width, height, number, weaponInfo, directionx, directiony, source, targetpos)
273 {
274 typeID |= kSorceryBullet;
275 numBounces = 0;
276 }
277
278 CSorceryBullet::~CSorceryBullet() {}
279
280 short CSorceryBullet::Forces()
281 {
282 short collisionCode, collisionObject;
283 double savedForcex = forceVectorX, savedForcey = forceVectorY;
284 CObject *collObj;
285
286 if (action == kInFlight) {
287 CObject::Forces();
288
289 collisionCode = ExertForce(resForceX, resForceY, collisionObject, &collObj);
290 if (collisionCode && collObj != shooter) {
291 if (collisionObject & (kElement | kItem | kPlatform) || collObj == shooter) {
292
293 if (numBounces < gConst->kNumOfBounces) {
294
295 numBounces ++;
296
297 if (collisionCode & kCollisionOnTop || collisionCode & kCollisionOnBottom) {
298 forceVectorY = -savedForcey;
299 directionUnity *= -1.0;
300 }
301 if (collisionCode & kCollisionOnLeft || collisionCode & kCollisionOnRight) {
302 forceVectorX = -savedForcex;
303 directionUnitx *= -1.0;
304 }
305 }else{
306 Detonate(collisionCode, collObj);
307 }
308 }else{
309 Detonate(collisionCode, collObj);
310 }
311 }
312 }else if (action == kInDetonation) {
313 return DetonationAnimation();
314 }
315
316 return kNoEvent;
317 }
318
319
320 CBombBullet::CBombBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *source, double targetpos) : CBullet(initx, inity, width, height, number, weaponInfo, directionx, directiony, source, targetpos)
321 {
322 weight = 5;
323 action = kInFlight;
324 detonate = 0;
325 }
326
327 CBombBullet::~CBombBullet() {}
328
329 short CBombBullet::Forces()
330 {
331 short collisionObject, returnCode, collisionCode;
332 CObject *obstacle;
333 short dx, dy;
334
335 if (action != kInDetonation) {
336 CObject::Forces();
337
338 collisionCode = ExertForce(resForceX, resForceY, collisionObject, &obstacle);
339 if (collisionCode) {
340 if (collisionObject == kMonster) detonate = 1;
341 }
342 if (detonate == 1) {
343 Detonate(collisionCode, obstacle);
344 if (detonation[0]) detonation[0]->AllowPixelAccess(dx, dy);
345 ys = ye - dy; ye = ys + dy; ym = (ye - ys) / 2;
346 detonate = 2;
347 }
348 }else return DetonationAnimation();
349
350 return kNoEvent;
351 }
352
353 CSineBullet::CSineBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *source, double targetpos, short rad, short per) : CBullet(initx, inity, width, height, number, weaponInfo, directionx, directiony, source, targetpos)
354 {
355 typeID |= kSineBullet;
356
357 distance = 0;
358 radius = rad;
359 period = 2.0 * 3.141 / (double)per;
360 }
361
362 CSineBullet::~CSineBullet() {}
363
364 short CSineBullet::Think()
365 {
366 CObject::Think();
367
368 Gravitation();
369
370 forceVectorX = gConst->kVelocityUnit * info->speed * deltaTime * SIGN(directionUnitx);
371 distance += forceVectorX;
372 forceVectorY = -radius * period * cos(distance * period);
373
374 return kNoEvent;
375 }
376
377
378 CGuidedBullet::CGuidedBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *source, double targetpos, CThing *tg) : CBullet(initx, inity, width, height, number, weaponInfo, directionx, directiony, source, targetpos)
379 {
380 typeID |= kGuidedBullet;
381
382 target = tg;
383
384 if (target) {
385 initAbstSign = SIGN(target->xs - xs);
386
387 lastfx = target->xs - xs;
388 lastfy = target->ys - ys;
389 lastf = sqrt(lastfx * lastfx + lastfy * lastfy);
390 }
391 }
392
393 CGuidedBullet::~CGuidedBullet() {}
394
395 short CGuidedBullet::Think()
396 {
397 double abstx, absty, abst;
398 double alpha, tmp;
399 double a, b, phi1, phi2, dPhi;
400
401 CObject::Think();
402
403 if (target) {
404 abstx = target->xs - xs;
405 absty = target->ys - ys;
406
407 a = sqrt(lastfx * lastfx + lastfy * lastfy);
408 b = sqrt(abstx*abstx+absty*absty);
409 phi1=asin(lastfy / a); if (lastfx<0) phi1=phi1*(-1.0);
410 phi2=asin(absty/b); if (abstx<0) phi2=phi2*(-1.0);
411 dPhi=phi2-phi1;
412 if (fabs(dPhi)>gConst->kMaxTurnAngle) dPhi=SIGN(dPhi)*gConst->kMaxTurnAngle;
413
414 tmp=cos(dPhi)*lastfx-sin(dPhi)*lastfy;
415 lastfy=sin(dPhi)*lastfx+cos(dPhi)*lastfy;
416 lastfx = tmp;
417 }
418
419 forceVectorX = lastfx * gConst->kVelocityUnit * info->speed * deltaTime / lastf;
420 forceVectorY = lastfy * gConst->kVelocityUnit * info->speed * deltaTime / lastf;
421
422 return kNoEvent;
423 }
424
425 CStaffBullet::CStaffBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *source, double targetpos, CThing *tg) : CGuidedBullet(initx, inity, width, height, number, weaponInfo, directionx, directiony, source, targetpos, tg)
426 {
427 lastMonsterScanTime = 0;
428 }
429
430 const double kStaffBulletRad = 40.0;
431 const long kMonsterScanTime = 200;
432
433 short CStaffBullet::Think()
434 {
435 tThingList *currentEntry;
436
437 if (!target && lastMonsterScanTime < lastTime) {
438
439 currentEntry = gApplication->collisionThingList;
440 while (currentEntry) {
441 if (currentEntry->thing->typeID & kMonster && currentEntry->thing != shooter) {
442 if ((currentEntry->thing->xm - xm) * (currentEntry->thing->xm - xm) * 0.5 +
443 (currentEntry->thing->ym - ym) * (currentEntry->thing->ym - ym) < kStaffBulletRad * kStaffBulletRad) {
444 target = currentEntry->thing;
445 }
446 }
447 currentEntry = currentEntry->next;
448 }
449 lastMonsterScanTime = lastTime + kMonsterScanTime;
450
451 return CBullet::Think();
452 } else if (target)
453 return CGuidedBullet::Think();
454 else
455 return kNoEvent;
456 }
457
458
459 short CBullet::Write(FILE *f)
460 {
461 long size = 0;
462
463 WRITEDATA(size);
464 WRITEDATA(typeID);
465 WRITEDATA(thingNumber);
466
467 size += CThing::Write(f);
468
469 if (tailX) {
470 for (short n = 0; n < gConst->kBulletTailLength; n ++) {
471 WRITEDATA(tailX[n]);
472 WRITEDATA(tailY[n]);
473 }
474 }
475
476 WRITEDATA(tailStep);
477 WRITEDATA(targetposition);
478 WRITEDATA(directionUnitx);
479 WRITEDATA(directionUnity);
480 WRITEDATA(action);
481 WRITEDATA(detonationStartTime);
482 WRITEDATA(noDetonation);
483
484 FINISHWRITE;
485
486 return size;
487 }
488
489 void CBullet::Read(FILE *f)
490 {
491 long size = 0;
492
493 READDATA(size);
494 READDATA(typeID);
495 READDATA(thingNumber);
496
497 CThing::Read(f);
498
499 info = gObjInfo->FindWeapon(thingNumber);
500 shooter = 0L;
501
502 OnAllocate();
503
504 if (projectile2) {
505 for (short n = 0; n < gConst->kBulletTailLength; n ++) {
506 READDATA(tailX[n]);
507 READDATA(tailY[n]);
508 }
509 }
510
511 READDATA(tailStep);
512 READDATA(targetposition);
513 READDATA(directionUnitx);
514 READDATA(directionUnity);
515 READDATA(action);
516 READDATA(detonationStartTime);
517 READDATA(noDetonation);
518 }
519
520
521 short CSorceryBullet::Write(FILE *f)
522 {
523 long size = 0;
524
525 WRITEDATA(size);
526 WRITEDATA(typeID);
527 WRITEDATA(thingNumber);
528
529 size += CBullet::Write(f);
530
531 WRITEDATA(numBounces);
532
533 FINISHWRITE;
534
535 return size;
536 }
537
538 void CSorceryBullet::Read(FILE *f)
539 {
540 long size = 0;
541
542 READDATA(size);
543 READDATA(typeID);
544 READDATA(thingNumber);
545
546 CBullet::Read(f);
547
548 READDATA(numBounces);
549 }
550
551 short CBombBullet::Write(FILE *f)
552 {
553 long size = 0;
554
555 WRITEDATA(size);
556 WRITEDATA(typeID);
557 WRITEDATA(thingNumber);
558
559 size += CBullet::Write(f);
560
561 WRITEDATA(detonate);
562
563 FINISHWRITE;
564
565 return size;
566 }
567
568 void CBombBullet::Read(FILE *f)
569 {
570 long size = 0;
571
572 READDATA(size);
573 READDATA(typeID);
574 READDATA(thingNumber);
575
576 CBullet::Read(f);
577
578 READDATA(detonate);
579 }
580
581 short CSineBullet::Write(FILE *f)
582 {
583 long size = 0;
584
585 WRITEDATA(size);
586 WRITEDATA(typeID);
587 WRITEDATA(thingNumber);
588
589 size += CBullet::Write(f);
590
591 WRITEDATA(distance);
592 WRITEDATA(radius);
593 WRITEDATA(period);
594
595 FINISHWRITE;
596
597 return size;
598 }
599
600 void CSineBullet::Read(FILE *f)
601 {
602 long size = 0;
603
604 READDATA(size);
605 READDATA(typeID);
606 READDATA(thingNumber);
607
608 CBullet::Read(f);
609
610 READDATA(distance);
611 READDATA(radius);
612 READDATA(period);
613 }
614
615 short CGuidedBullet::Write(FILE *f)
616 {
617 long size = 0;
618
619 WRITEDATA(size);
620 WRITEDATA(typeID);
621 WRITEDATA(thingNumber);
622
623 size += CBullet::Write(f);
624
625 WRITEDATA(initAbstSign);
626 WRITEDATA(lastfx);
627 WRITEDATA(lastfy);
628 WRITEDATA(lastf);
629
630 FINISHWRITE;
631
632 return size;
633 }
634
635 void CGuidedBullet::Read(FILE *f)
636 {
637 long size = 0;
638
639 READDATA(size);
640 READDATA(typeID);
641 READDATA(thingNumber);
642
643 CBullet::Read(f);
644
645 READDATA(initAbstSign);
646 READDATA(lastfx);
647 READDATA(lastfy);
648 READDATA(lastf);
649 }
0 #ifndef __AMP_BULLET__
1 #define __AMP_BULLET__
2
3 #include "Thing.hpp"
4 #include "ObjInfo.hpp"
5 #include "Shape.hpp"
6
7 enum {
8 kInFlight,
9 kInDetonation,
10 kWaitForDetonation // only for bombs
11 };
12
13 class CBullet : public CThing {
14 protected:
15 CShape *projectile1;
16 CShape *projectile2;
17 CShape *detonation[5];
18
19 short *tailX, *tailY;
20 double tailStep;
21
22 CThing *shooter;
23 double targetposition;
24
25 tWeaponInfo *info;
26 double directionUnitx;
27 double directionUnity;
28
29 short action;
30 CShape *currentDetonationShape;
31 long detonationStartTime;
32 short noDetonation;
33
34 void Detonate(short collisionCode, CObject *);
35 short DetonationAnimation();
36 void Damage(CObject *);
37
38 public:
39 CBullet *nextBullet, *prevBullet;
40
41 CBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *shooter, double targetpos);
42 ~CBullet();
43
44 void OnAllocate();
45 void LinkInLists();
46 void UnlinkInLists();
47
48 virtual short Think();
49 void Move();
50 short Forces();
51 void Render(short planeX, short planeY, tRect *clipRect);
52 short AmIATreatment(double victimxs, double victimys, double victimxe, double victimye, double &fx, double &fy);
53 short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
54
55 virtual short Write(FILE *f);
56 virtual void Read(FILE *f);
57 };
58
59
60 class CSorceryBullet : public CBullet {
61 protected:
62 short numBounces;
63
64 public:
65 CSorceryBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *shooter, double targetpos);
66 ~CSorceryBullet();
67
68 short Forces();
69 short Write(FILE *f);
70 void Read(FILE *f);
71 };
72
73 class CBomb;
74
75 class CBombBullet : public CBullet {
76 friend class CBomb;
77
78 protected:
79 short detonate;
80
81 public:
82 CBombBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *shooter, double targetpos);
83 ~CBombBullet();
84
85 short Forces();
86 short Write(FILE *f);
87 void Read(FILE *f);
88 };
89
90 class CSineBullet : public CBullet {
91 protected:
92 double distance;
93 double radius;
94 double period;
95
96 public:
97 CSineBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *shooter, double targetpos, short rad, short period);
98 ~CSineBullet();
99
100 short Think();
101 short Write(FILE *f);
102 void Read(FILE *f);
103 };
104
105
106 class CGuidedBullet : public CBullet {
107 protected:
108 CThing *target;
109 double initAbstSign;
110 double lastfx, lastfy, lastf;
111
112 public:
113 CGuidedBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *shooter, double targetpos, CThing *tg);
114 ~CGuidedBullet();
115
116 virtual short Think();
117 short Write(FILE *f);
118 void Read(FILE *f);
119 };
120
121 class CStaffBullet : public CGuidedBullet {
122 protected:
123 long lastMonsterScanTime;
124
125 public:
126 CStaffBullet(short initx, short inity, short width, short height, short number, tWeaponInfo *weaponInfo, double directionx, double directiony, CThing *shooter, double targetpos, CThing *tg);
127 ~CStaffBullet();
128
129 short Think();
130 };
131
132
133 #endif
0 #include "Clut.hpp"
1 #include "System.hpp"
2 #include "ConstVal.hpp"
3 #include "Level.hpp"
4 #include "ShapeLd.hpp"
5
6 extern tConstValues *gConst;
7 extern tConfigData *gConfigData;
8 extern CLevel *gLevel;
9 extern CSystem *gSystem;
10 extern CShapeManager *gShapeManager;
11 extern FILE *logFile;
12
13 const short kWaterTransparence = 60; // percent of blue
14 const short kLavaTransparence = 80; // percent of red and *3 percent of green
15 const double kFogFactor = 0.8;
16
17 short WeightenedRandom(short anz);
18
19 CClutManager::CClutManager()
20 {
21 long maxRadiant, radiant;
22 short j, k, val;
23
24 for (short n = 0; n < kMaxLuminosityLevel * 2; n ++) {
25 luminosityTable[n] = new unsigned char [256];
26 }
27
28 transparentTable1 = new unsigned char * [256];
29 transparentTable2 = new unsigned char * [256];
30 transparentTable3 = new unsigned char * [256];
31 for (j = 0; j < 256; j ++) {
32 transparentTable1[j] = new unsigned char [256];
33 transparentTable2[j] = new unsigned char [256];
34 transparentTable3[j] = new unsigned char [256];
35 }
36
37 blueLightningTable = new unsigned char * [gConst->kLightningRadiant];
38 redLightningTable = new unsigned char * [gConst->kLightningRadiant];
39 greenLightningTable = new unsigned char * [gConst->kLightningRadiant];
40 yellowLightningTable = new unsigned char * [gConst->kLightningRadiant];
41 purpleLightningTable = new unsigned char * [gConst->kLightningRadiant];
42
43 whiteCoronaTable = new unsigned char * [gConst->kLightningRadiant];
44 yellowCoronaTable = new unsigned char * [gConst->kLightningRadiant];
45 blueCoronaTable = new unsigned char * [gConst->kLightningRadiant];
46
47 for (j = 0; j < gConst->kLightningRadiant; j ++) {
48 blueLightningTable[j] = new unsigned char [256];
49 redLightningTable[j] = new unsigned char [256];
50 greenLightningTable[j] = new unsigned char [256];
51 yellowLightningTable[j] = new unsigned char [256];
52 purpleLightningTable[j] = new unsigned char [256];
53
54 whiteCoronaTable[j] = new unsigned char [256];
55 yellowCoronaTable[j] = new unsigned char [256];
56 blueCoronaTable[j] = new unsigned char [256];
57 }
58 radiantTable = new unsigned char [gConst->kLightningRadiant * gConst->kLightningRadiant];
59 maxRadiant = gConst->kLightningRadiant * gConst->kLightningRadiant;
60
61 for (j = 0; j < gConst->kLightningRadiant; j ++) {
62 for (k = 0; k < gConst->kLightningRadiant; k ++) {
63 radiant = j * j + k * k;
64 if (radiant > maxRadiant)
65 radiantTable [j * gConst->kLightningRadiant + k] = gConst->kLightningRadiant -1;
66 else {
67 val = radiant * gConst->kLightningRadiant / maxRadiant + WeightenedRandom(5) - 1;
68 radiantTable [j * gConst->kLightningRadiant + k] = MIN(val, gConst->kLightningRadiant - 1);
69 }
70 }
71 }
72 coronas[0].values = coronas[1].values = coronas[2].values = 0L;
73 }
74
75 CClutManager::~CClutManager()
76 {
77 short n;
78
79 if (coronas[0].values) delete [] coronas[0].values;
80 if (coronas[1].values) delete [] coronas[1].values;
81 if (coronas[2].values) delete [] coronas[2].values;
82
83 for (n = 0; n < kMaxLuminosityLevel * 2; n ++) {
84 delete [] luminosityTable[n];
85 }
86 for (n = 0; n < gConst->kLightningRadiant; n ++) {
87 delete [] blueLightningTable[n];
88 delete [] redLightningTable[n];
89 delete [] greenLightningTable[n];
90 delete [] yellowLightningTable[n];
91 delete [] purpleLightningTable[n];
92
93 delete [] whiteCoronaTable[n];
94 delete [] yellowCoronaTable[n];
95 delete [] blueCoronaTable[n];
96 }
97 delete [] blueLightningTable;
98 delete [] redLightningTable;
99 delete [] greenLightningTable;
100 delete [] yellowLightningTable;
101 delete [] purpleLightningTable;
102
103 delete [] whiteCoronaTable;
104 delete [] yellowCoronaTable;
105 delete [] blueCoronaTable;
106
107 delete [] radiantTable;
108 }
109
110
111 // --------------------------------------
112 short WeightenedRandom(short anz)
113 // Returns a number which the possibility that the number is 1 is 1/2, for 2 is 1 / 3, for 3 is 1/4 etc.
114 {
115 long maxSum = 0, n;
116 long randValue;
117
118 for (n = 1; n <= anz; n ++) maxSum += 100 / n;
119
120 randValue = rand() * maxSum / RAND_MAX;
121 maxSum = 0;
122 for (n = 1; n <= anz; n ++) {
123 if (randValue >= maxSum && randValue < maxSum + 100 / n) return n;
124 maxSum += 100 / n;
125 }
126 return 1;
127 }
128
129 // ----------------------------------------------
130 void CClutManager::LoadPalette(RGBcolor *pal)
131 // Writing the palette from the AmpGraf.gif file into the color manager
132 {
133 short j, k;
134
135 for (short n = 0; n < 256; n ++) {
136 palette[n].red = pal[n].red;
137 palette[n].green = pal[n].green;
138 palette[n].blue = pal[n].blue;
139 }
140 SWAP(palette[0].red, palette[255].red, unsigned char);
141 SWAP(palette[0].green, palette[255].green, unsigned char);
142 SWAP(palette[0].blue, palette[255].blue, unsigned char);
143 }
144
145
146 // --------------------------------------------------------
147 void CClutManager::BuildLuminosityTable()
148 // Builds the luminosity and the color tables
149 {
150 unsigned char color;
151 short j, k;
152 FILE *fClut = fopen(gSystem->QualifyDataDir(gConst->kFileCluts), "rb"); // by LL
153 short index, index2;
154 short mode = 0;
155
156 if (!fClut) {
157 fClut = fopen(gSystem->QualifyDataDir(gConst->kFileCluts), "wb"); // by LL
158 if (!fClut) MSG("!!! File not found: "); MSG(gConst->kFileCluts); MSG("\n");
159 mode = 1;
160 }
161
162 fseek(fClut, 0, SEEK_SET);
163
164 for (short n = -kMaxLuminosityLevel; n < kMaxLuminosityLevel; n ++) {
165 for (short j = 0; j < 256; j ++) {
166 if (mode) {
167 color = ChangeColorValues(j, SIGN(n) * gConst->kBrightnessLevels[ABS(n)],
168 SIGN(n) * gConst->kBrightnessLevels[ABS(n)],
169 SIGN(n) * gConst->kBrightnessLevels[ABS(n)]);
170
171 luminosityTable[kMaxLuminosityLevel + n][j] = color;
172 fputc(color, fClut);
173 }else{
174 luminosityTable[kMaxLuminosityLevel + n][j] = (unsigned char)fgetc(fClut);
175 }
176 }
177 }
178
179 for (j = 0; j < 256; j ++) {
180 for (k = 0; k < 256; k ++) {
181 if (mode) {
182 transparentTable1[j][k] = ChangeColorValues(j, (palette[k].red - palette[j].red) / 4 * 100 / 256, (palette[k].green - palette[j].green) / 4 * 100 / 256, (palette[k].blue - palette[j].blue) / 4 * 100 / 256);
183 fputc(transparentTable1[j][k], fClut);
184 transparentTable2[j][k] = ChangeColorValues(j, (palette[k].red - palette[j].red) / 2 * 100 / 256, (palette[k].green - palette[j].green) / 2 * 100 / 256, (palette[k].blue - palette[j].blue) / 2 * 100 / 256);
185 fputc(transparentTable2[j][k], fClut);
186 transparentTable3[j][k] = ChangeColorValues(j, (palette[k].red - palette[j].red) * 3 / 4 * 100 / 256, (palette[k].green - palette[j].green) * 3 / 4 * 100 / 256, (palette[k].blue - palette[j].blue) * 3 / 4 * 100 / 256);
187 fputc(transparentTable3[j][k], fClut);
188 }else{
189 transparentTable1[j][k] = (unsigned char)fgetc(fClut);
190 transparentTable2[j][k] = (unsigned char)fgetc(fClut);
191 transparentTable3[j][k] = (unsigned char)fgetc(fClut);
192 }
193
194 }
195 }
196
197 // Calculating the lightning tables which are used to calculate the lightning around bullets
198 for (j = 0; j < gConst->kLightningRadiant; j ++) {
199 for (k = 0; k < 256; k ++) {
200 if (mode) {
201 blueLightningTable[j][k] = ChangeColorValues(k, 0, 0, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant);
202 fputc(blueLightningTable[j][k], fClut);
203
204 redLightningTable[j][k] = ChangeColorValues(k, (gConst->kLightningRadiant - j) * 70 / gConst->kLightningRadiant, 0, 0);
205 fputc(redLightningTable[j][k], fClut);
206
207 greenLightningTable[j][k] = ChangeColorValues(k, 0, (gConst->kLightningRadiant - j) * 60 / gConst->kLightningRadiant, 0);
208 fputc(greenLightningTable[j][k], fClut);
209
210 yellowLightningTable[j][k] = ChangeColorValues(k, (gConst->kLightningRadiant - j) * 40 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 40 / gConst->kLightningRadiant, 0);
211 fputc(yellowLightningTable[j][k], fClut);
212
213 purpleLightningTable[j][k] = ChangeColorValues(k, (gConst->kLightningRadiant - j) * 40 / gConst->kLightningRadiant, 0, (gConst->kLightningRadiant - j) * 40 / gConst->kLightningRadiant);
214 fputc(purpleLightningTable[j][k], fClut);
215
216 whiteCoronaTable[j][k] = ChangeColorValues(k, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant);
217 fputc(whiteCoronaTable[j][k], fClut);
218
219 yellowCoronaTable[j][k] = ChangeColorValues(k, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 80 / gConst->kLightningRadiant);
220 fputc(yellowCoronaTable[j][k], fClut);
221
222 blueCoronaTable[j][k] = ChangeColorValues(k, (gConst->kLightningRadiant - j) * 40 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 40 / gConst->kLightningRadiant, (gConst->kLightningRadiant - j) * 100 / gConst->kLightningRadiant);
223 }else{
224 blueLightningTable[j][k] = (unsigned char)fgetc(fClut);
225 redLightningTable[j][k] = (unsigned char)fgetc(fClut);
226 greenLightningTable[j][k] = (unsigned char)fgetc(fClut);
227 yellowLightningTable[j][k] = (unsigned char)fgetc(fClut);
228 purpleLightningTable[j][k] = (unsigned char)fgetc(fClut);
229 whiteCoronaTable[j][k] = (unsigned char)fgetc(fClut);
230 yellowCoronaTable[j][k] = (unsigned char)fgetc(fClut);
231 //blueCoronaTable[j][k] = (unsigned char)fgetc(fClut);
232 }
233 }
234 }
235
236 for (j = 0; j < 256; j ++) {
237 if (mode) {
238 waterColorTable[j] = ChangeColorValues(j, 0, 0, kWaterTransparence);
239 fputc(waterColorTable[j], fClut);
240 lavaColorTable[j] = ChangeColorValues(j, kLavaTransparence, kLavaTransparence / 3, 0);
241 fputc(lavaColorTable[j], fClut);
242 shadowTable[j] = ChangeColorValues(j, -gConst->kShadowmodeDarkening, -gConst->kShadowmodeDarkening, -gConst->kShadowmodeDarkening);
243 fputc(shadowTable[j], fClut);
244 fogTable[j] = FindClosestColor(palette[j].red + (short)(double(128 - palette[j].red) * kFogFactor), palette[j].green + (short)(double(128 - palette[j].green) * kFogFactor), palette[j].blue + (short)(double(128 - palette[j].blue) * kFogFactor));
245 fputc(fogTable[j], fClut);
246 }else{
247 waterColorTable[j] = (unsigned char)fgetc(fClut);
248 lavaColorTable[j] = (unsigned char)fgetc(fClut);
249 shadowTable[j] = (unsigned char)fgetc(fClut);
250 fogTable[j] = (unsigned char)fgetc(fClut);
251 }
252 }
253
254 fclose(fClut);
255 }
256
257 void CClutManager::CalculateCoronas(unsigned char *bmp, short width)
258 {
259 unsigned char *tmp;
260 short coronaColor;
261 short value;
262 unsigned char *bitmap;
263
264 for (short n = 0; n < kNumOfCoronas; n ++) {
265 coronas[n].dx = kCoronaDescriptor[n][3];
266 coronas[n].dy = kCoronaDescriptor[n][4];
267
268 coronas[n].values = new unsigned char [coronas[n].dx * coronas[n].dy];
269
270 coronas[n].table = 0L;
271
272 bitmap = bmp + kCoronaDescriptor[n][2] * width + kCoronaDescriptor[n][1];
273 for (short j = 0; j < coronas[n].dy; j ++) {
274 for (short k = 0; k < coronas[n].dx; k ++) {
275 if (bitmap[k] == 255) bitmap[k] = kBlackColor;
276 else if (bitmap[k] == 0) bitmap[k] = kWhiteColor;
277
278 value = (palette[bitmap[k]].red + palette[bitmap[k]].green + palette[bitmap[k]].blue) / 3;
279
280 coronas[n].values[j * coronas[n].dx + k] = (unsigned char)(value * gConst->kLightningRadiant / 256);
281 }
282 bitmap += width;
283 }
284 }
285 }
286
287
288 // --------------------------------------------------
289 short CClutManager::FindClosestColor(unsigned char red, unsigned char green, unsigned char blue)
290 /* In: an exact color value
291 Out: color index to a color in the palette which matches the color value the exactest
292 */
293 {
294 long distance, minDistance = LONG_MAX;
295 short n, minn = -1;
296
297 for (n = 0; n < 256; n ++) {
298 distance = (long)(palette[n].red - red) * (long)(palette[n].red - red) +
299 (long)(palette[n].green - green) * (long)(palette[n].green - green) +
300 (long)(palette[n].blue - blue) * (long)(palette[n].blue - blue);
301 if (distance < minDistance) {
302 minDistance = distance;
303 minn = n;
304 }
305 }
306
307 return minn;
308 }
309
310 // --------------------------------------------------------------
311 unsigned char CClutManager::ChangeColorValues(unsigned char color, short percentageRed, short percentageGreen, short percentageBlue)
312 /* In: color which red, green and blue parts are to change
313 How many percent each color has to change 100% <= x <= -100%
314 Out: changed color
315 */
316 {
317 if (color == 0) color = kWhiteColor;
318 if (color == 255) color = kBlackColor;
319
320 short red = palette[color].red, green = palette[color].green, blue = palette[color].blue;
321
322 if (percentageRed > 0)
323 red += (unsigned char)((long)(255 - (long)palette[color].red) * percentageRed / 100);
324 else red -= (unsigned char)((long)(palette[color].red) * ABS(percentageRed) / 100);
325 red = MAX(0, red); red = MIN(255, red);
326
327 if (percentageGreen > 0)
328 green += (unsigned char)((long)(255 - (long)palette[color].green) * percentageGreen / 100);
329 else green -= (unsigned char)((long)(palette[color].green) * ABS(percentageGreen) / 100);
330 green = MAX(0, green); green = MIN(255, green);
331
332 if (percentageBlue > 0)
333 blue += (unsigned char)((long)(255 - (long)palette[color].blue) * percentageBlue / 100);
334 else blue -= (unsigned char)((long)(palette[color].blue) * ABS(percentageBlue) / 100);
335 blue = MAX(0, blue); blue = MIN(255, blue);
336
337 return (unsigned char)FindClosestColor((unsigned char)red, (unsigned char)green, (unsigned char)blue);
338 }
339
340
341 void CClutManager::SetPixel(unsigned char *source, unsigned char *dest, short modus, short luminosity)
342 {
343 switch (modus) {
344 case kShapemodusNormal:
345 *dest = luminosityTable[kMaxLuminosityLevel + luminosity][*source];
346 break;
347 case kShapemodusRandom:
348 *dest = rand() & 255;
349 break;
350 case kShapemodusWater:
351 *dest = waterColorTable[luminosityTable[kMaxLuminosityLevel + luminosity][*source]];
352 break;
353 case kShapemodusLava:
354 *dest = lavaColorTable[luminosityTable[kMaxLuminosityLevel + luminosity][*source]];
355 break;
356 case kShapemodusShadow:
357 *dest = shadowTable[luminosityTable[kMaxLuminosityLevel + luminosity][*dest]];
358 break;
359 case kShapemodusFog:
360 *dest = fogTable[luminosityTable[kMaxLuminosityLevel + luminosity][*source]];
361 break;
362 case kShapemodusTransparent1:
363 *dest = transparentTable1[*source][*dest];
364 break;
365 case kShapemodusTransparent2:
366 *dest = transparentTable2[*source][*dest];
367 break;
368 case kShapemodusTransparent3:
369 *dest = transparentTable3[*source][*dest];
370 break;
371 default:
372 *dest = *source;
373 }
374 }
375
376
377 unsigned char **CClutManager::EffectToTable(short effect)
378 {
379 switch (effect) {
380 case kLightningBlueEffect:
381 return blueLightningTable;
382 break;
383 case kLightningRedEffect:
384 return redLightningTable;
385 break;
386 case kLightningGreenEffect:
387 return greenLightningTable;
388 break;
389 case kLightningYellowEffect:
390 return yellowLightningTable;
391 break;
392 case kLightningPurpleEffect:
393 return purpleLightningTable;
394 break;
395 case kWhiteCoronaTable:
396 return whiteCoronaTable;
397 break;
398 case kYellowCoronaTable:
399 return yellowCoronaTable;
400 break;
401 case kBlueCoronaTable:
402 return blueCoronaTable;
403 break;
404 default:
405 return 0L;
406 }
407 }
408
409
410 // ------------------------------------------------------------------------
411 void CClutManager::DrawLightning(double xm, double ym, short effect, CGraphicSurface *surface)
412 // Draws a gConst->kLightningRadinant * 2 - sqare on the screen which illuminates
413 // the background in the color effect
414 {
415 short planeX, planeY;
416 long startx, starty, endx, endy, midx, midy;
417 unsigned char *baseAddr;
418 short pitch;
419 short j, k;
420 CElement *element;
421 unsigned char **table;
422
423 if (gConfigData->disableLightning) return;
424
425 table = EffectToTable(effect);
426
427 gLevel->focus->CalcPlaneOffsets(planeX, planeY);
428 midx = xm - planeX;
429 midy = ym - planeY;
430
431 startx = midx - gConst->kLightningRadiant;
432 startx = MAX(startx, 0);
433 startx = MIN(startx, kGamePlaneWidth);
434
435 starty = midy - gConst->kLightningRadiant;
436 starty = MAX(starty, 0);
437 starty = MIN(starty, kGamePlaneHeight);
438
439 endx = midx + gConst->kLightningRadiant;
440 endx = MAX(endx, 0);
441 endx = MIN(endx, kGamePlaneWidth);
442
443 endy = midy + gConst->kLightningRadiant;
444 endy = MAX(endy, 0);
445 endy = MIN(endy, kGamePlaneHeight);
446
447 baseAddr = surface->GetSurfacePtr(&pitch);
448 baseAddr += starty * pitch;
449
450 for (j = starty + 1; j < endy; j ++) {
451 for (k = startx + 1; k < endx; k ++) {
452 element = gLevel->level[(j + planeY) / kElementSize][(k + planeX) / kElementSize];
453 if (element->background && !(element->typeID & kBackgroundElement))
454 baseAddr[k] = table[radiantTable[ABS(j - midy) * gConst->kLightningRadiant + ABS(k - midx)]][baseAddr[k]];
455 }
456 baseAddr += pitch;
457 }
458
459 surface->ReleaseSurface();
460 }
461
462 void CClutManager::PrepareCorona(double xm, double ym, CGraphicSurface *surface)
463 {
464 short planeX, planeY;
465 short midx, midy;
466 short pitch;
467 unsigned char *baseAddr;
468
469 gLevel->focus->CalcPlaneOffsets(planeX, planeY);
470 midx = xm - planeX;
471 midy = ym - planeY;
472
473 if (midx >= 0 && midx < kGamePlaneWidth && midy >= 0 && midy < kGamePlaneHeight) {
474 baseAddr = surface->GetSurfacePtr(&pitch);
475 baseAddr += midy * pitch + midx;
476
477 *baseAddr = (unsigned char)kWhiteColor;
478
479 surface->ReleaseSurface();
480 }
481 }
482
483
484
485 void CClutManager::DrawCorona(double xm, double ym, short coronaNum, short effect, CGraphicSurface *surface, double &coronaFader, long deltaTime)
486 {
487 // Draws a gConst->kLightningRadinant * 2 - sqare on the screen which illuminates
488 // the background in the color effect
489 short planeX, planeY;
490 long startx, starty, endx, endy, midx, midy;
491 short smidx, smidy;
492 unsigned char *baseAddr, *origBaseAddr;
493 short pitch;
494 short j, k;
495
496 if (gConfigData->disableCoronas) return;
497
498 tCorona *corona = &coronas[coronaNum];
499 unsigned char **table = EffectToTable(effect);
500
501 gLevel->focus->CalcPlaneOffsets(planeX, planeY);
502 midx = xm - planeX;
503 midy = ym - planeY;
504
505 smidx = corona->dx / 2;
506 startx = midx - smidx;
507 startx = MAX(startx, 0);
508 startx = MIN(startx, kGamePlaneWidth);
509
510 smidy = corona->dy / 2;
511 starty = midy - smidy;
512 starty = MAX(starty, 0);
513 starty = MIN(starty, kGamePlaneHeight);
514
515 endx = midx + corona->dx / 2;
516 endx = MAX(endx, 0);
517 endx = MIN(endx, kGamePlaneWidth);
518
519 endy = midy + corona->dy / 2;
520 endy = MAX(endy, 0);
521 endy = MIN(endy, kGamePlaneHeight);
522
523 origBaseAddr = surface->GetSurfacePtr(&pitch);
524 baseAddr = origBaseAddr + midy * pitch + midx;
525
526 if (midx >= 0 && midy >= 0 && midx < kGamePlaneWidth && midy < kGamePlaneHeight && *(unsigned char *)baseAddr == kWhiteColor) {
527 coronaFader += gConst->kCoronaFadeSpeed * deltaTime;
528 coronaFader = MIN(1.0, coronaFader);
529 }else{
530 coronaFader -= gConst->kCoronaFadeSpeed * deltaTime;
531 coronaFader = MAX(0, coronaFader);
532 }
533
534 baseAddr = origBaseAddr + starty * pitch;
535
536 for (j = starty + 1; j < endy; j ++) {
537 for (k = startx + 1; k < endx; k ++) {
538 baseAddr[k] = table[gConst->kLightningRadiant - 1 - (short)((double)corona->values[(smidy + (midy - j)) * corona->dx + smidx + midx - k] * coronaFader)][baseAddr[k]];
539 }
540 baseAddr += pitch;
541 }
542
543 surface->ReleaseSurface();
544 }
545
546
547 void SwapBlackWhite(Graphic_file *gf)
548 {
549 for (long n = 0; n < gf->width * gf->height; n ++)
550 if (gf->bitmap[n] == 0) gf->bitmap[n] = kWhiteColor; else if (gf->bitmap[n] == 255) gf->bitmap[n] = kBlackColor;
551 }
552
553 void CClutManager::FadeToColor(short direction, short effect, CGraphicSurface *surface)
554 {
555 short fadeCounter = 0;
556 long lastFadeTime = 0;
557 short pitch, height;
558 unsigned char *baseAddr;
559 long size;
560 unsigned char **table = EffectToTable(effect);
561 short j, k;
562 short border, step;
563
564 if (direction == kFadeFromColor) {
565 border = gConst->kLightningRadiant;
566 fadeCounter = 0;
567 step = 1;
568 }else{
569 border = -1;
570 fadeCounter = gConst->kLightningRadiant -1;
571 step = -1;
572 }
573
574 while (fadeCounter != border) {
575 if (lastFadeTime < gSystem->GetTicks()) {
576 lastFadeTime = gSystem->GetTicks() + gConst->kFadeTime / gConst->kLightningRadiant;
577
578 gLevel->PaintLevel();
579
580 baseAddr = surface->GetSurfacePtr(&pitch);
581
582 size = surface->width * surface->height;
583 for (j = 0; j < surface->height; j ++) {
584 for (k = 0; k < surface->width; k ++) {
585 baseAddr[k] = table[fadeCounter][baseAddr[k]];
586 }
587 baseAddr += pitch;
588 }
589 surface->ReleaseSurface();
590 surface->FlipToScreen(0, 0);
591
592 fadeCounter += step;
593 }
594 }
595 }
596
597
598
599
0 #ifndef __AMP_CLUTMANAGER__
1 #define __AMP_CLUTMANAGER__
2
3 #include "AmpHead.hpp"
4 #include "Surface.hpp"
5
6 const short kMaxLuminosityLevel = 4;
7 const short kNumOfCoronas = 3;
8 const short kCoronaIDs[kNumOfCoronas] = {10000, 10001, 10002};
9
10 static short kCoronaDescriptor[kNumOfCoronas][5] = {
11 {10000, 317, 543, 94, 92},
12 {10001, 382, 806, 126, 126},
13 {10002, 322, 802, 40, 40}
14 };
15
16 enum {
17 kLightningNoEffect,
18 kLightningBlueEffect,
19 kLightningRedEffect,
20 kLightningGreenEffect,
21 kLightningYellowEffect,
22 kLightningPurpleEffect,
23 kYellowCoronaTable,
24 kWhiteCoronaTable,
25 kBlueCoronaTable
26 };
27
28 enum {
29 kFadeToColor,
30 kFadeFromColor
31 };
32
33 struct tCorona {
34 unsigned char *values;
35 unsigned char **table;
36 short dx, dy;
37 };
38
39 class CClutManager {
40 protected:
41 RGBcolor palette[256];
42 unsigned char *luminosityTable[256];
43 unsigned char waterColorTable[256];
44 unsigned char lavaColorTable[256];
45 unsigned char shadowTable[256];
46 unsigned char fogTable[256];
47
48 unsigned char **transparentTable1;
49 unsigned char **transparentTable2;
50 unsigned char **transparentTable3;
51
52 unsigned char **blueLightningTable;
53 unsigned char **redLightningTable;
54 unsigned char **greenLightningTable;
55 unsigned char **yellowLightningTable;
56 unsigned char **purpleLightningTable;
57
58 unsigned char **whiteCoronaTable;
59 unsigned char **yellowCoronaTable;
60 unsigned char **blueCoronaTable;
61
62 unsigned char *radiantTable;
63
64 tCorona coronas[kNumOfCoronas];
65
66 unsigned char **EffectToTable(short effect);
67
68 public:
69 CClutManager();
70 ~CClutManager();
71
72 short FindClosestColor(unsigned char red, unsigned char green, unsigned char blue);
73 void LoadPalette(RGBcolor *pal);
74 void BuildLuminosityTable();
75 void CalculateCoronas(unsigned char *, short);
76 unsigned char ChangeColorValues(unsigned char color, short percentageRed, short percentageGreen, short percentageBlue);
77 void SetPixel(unsigned char *source, unsigned char *dest, short modus, short luminosity);
78 void DrawLightning(double xm, double ym, short effect, CGraphicSurface *surface);
79 void PrepareCorona(double xm, double ym, CGraphicSurface *surface);
80 void DrawCorona(double xm, double ym, short corona, short effect, CGraphicSurface *surface, double &coronaFade, long deltaTime);
81 void FadeToColor(short direction, short effect, CGraphicSurface *surface);
82 };
83
84 void SwapBlackWhite(Graphic_file *gf);
85
86 #endif
0 #include "ConstVal.hpp"
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <System.hpp>
5
6 extern tConstValues *gConst;
7 extern tConfigData *gConfigData;
8 extern FILE *logFile;
9 extern CSystem *gSystem;
10
11 long GetLongConstant(FILE *f, char *constName);
12 double GetDoubleConstant(FILE *f, char *constName);
13 void GetStringConstant(FILE *f, char *constName, char *buffer);
14
15 // ------------------------------------------
16 void LoadParameters()
17 // Loads the general constants from the *.par file
18 {
19 char levelSetString[11] = "xxLevelSet";
20 char levelBkgndString[13] = "xxLevelBkgnd";
21 FILE *paramFile = fopen(gSystem->QualifyDataDir(kParFileName), "r"); // by LL
22
23 gConst = new tConstValues;
24
25 gConst->kVelocityUnit = GetDoubleConstant(paramFile, "kVelocityUnit");
26 gConst->kPlayerAcceleration = GetDoubleConstant(paramFile, "kPlayerAcceleration");
27 gConst->kPlayerLiquidAccel = GetDoubleConstant(paramFile, "kPlayerLiquidAccel");
28 gConst->kRunScaleFactor = GetDoubleConstant(paramFile, "kRunScaleFactor");
29 gConst->kJumpVelocity = GetDoubleConstant(paramFile, "kJumpVelocity");
30 gConst->kJumpAccelerationTime = GetLongConstant(paramFile, "kJumpAccelerationTime");
31 gConst->kTeleportTime = GetLongConstant(paramFile, "kTeleportTime");
32 gConst->kPlayerWidth = GetLongConstant(paramFile, "kPlayerWidth");
33 gConst->kBulletWidth = GetLongConstant(paramFile, "kBulletWidth");
34 gConst->kFirehandNumOfBullets = GetLongConstant(paramFile, "kFirehandNumOfBullets");
35 gConst->kFirehandAngle = (double)GetLongConstant(paramFile, "kFirehandAngle") * 3.141 / 180;
36 gConst->kStaffLoadTime = GetLongConstant(paramFile, "kStaffLoadTime");
37 gConst->kInitialOxygen = GetLongConstant(paramFile, "kInitialOxygen");
38 gConst->kOxygenDecrease = GetDoubleConstant(paramFile, "kOxygenDecrease");
39 gConst->kLavaDamage = GetLongConstant(paramFile, "kLavaDamage");
40 gConst->kPlayersFirstWeaponShape = GetLongConstant(paramFile, "kPlayersFirstWeaponShape");
41 gConst->kPickupTime = GetLongConstant(paramFile, "kPickupTime");
42
43 gConst->kBulletTailLength = GetLongConstant(paramFile, "kBulletTailLength");
44 gConst->kBulletTailDistance = GetLongConstant(paramFile, "kBulletTailDistance");
45 gConst->kDetonationFrameTime = GetDoubleConstant(paramFile, "kDetonationFrameTime");
46 gConst->kWalkFrameTime = GetLongConstant(paramFile, "kWalkFrameTime");
47 gConst->kShootFrameTime = GetLongConstant(paramFile, "kShootFrameTime");
48 gConst->kWeaponChangeTime = GetLongConstant(paramFile, "kWeaponChangeTime");
49 gConst->kActionDelayTime = GetLongConstant(paramFile, "kActionDelayTime");
50 gConst->kDieFrameTime = GetLongConstant(paramFile, "kDieFrameTime");
51 gConst->kDriftSpeed = GetLongConstant(paramFile, "kDriftSpeed");
52 gConst->kWeaponCarryHeight = GetLongConstant(paramFile, "kWeaponCarryHeight");
53
54 gConst->kTeleportBlinkTime = GetLongConstant(paramFile, "kTeleportBlinkTime");
55 gConst->kSavePortBlinkTime = GetLongConstant(paramFile, "kSavePortBlinkTime");
56 gConst->kExitPortBlinkTime = GetLongConstant(paramFile, "kExitPortBlinkTime");
57
58 gConst->kGravitation = GetDoubleConstant(paramFile, "kGravitation");
59 gConst->kNormalFriction = GetDoubleConstant(paramFile, "kNormalFriction");
60 gConst->kLiquidFriction = GetDoubleConstant(paramFile, "kLiquidFriction");
61 gConst->kMaxFallingSpeed = GetDoubleConstant(paramFile, "kMaxFallingSpeed");
62
63 gConst->kJumperJumpAcceleration = GetDoubleConstant(paramFile, "kJumperJumpAcceleration");
64
65 gConst->kNumOfBounces = GetLongConstant(paramFile, "kNumOfBounces");
66 gConst->kSineWeaponRad = GetLongConstant(paramFile, "kSineWeaponRad");
67 gConst->kMaxTurnAngle = (double)GetLongConstant(paramFile, "kMaxTurnAngle") * 3.141 / 180.0;
68 gConst->kWargFastSpeedup = (double)GetLongConstant(paramFile, "kWargFastSpeedup");
69 gConst->kWargNearWeaponRadix = GetLongConstant(paramFile, "kWargNearWeaponRadix");
70 gConst->kWargJumpAcceleration = GetDoubleConstant(paramFile, "kWargJumpAcceleration");
71 gConst->kDelayAfterWargDeath = GetLongConstant(paramFile, "kDelayAfterWargDeath");
72
73 gConst->kActivateDistance = GetLongConstant(paramFile, "kActivateDistance");
74 gConst->kTreatDistance = GetLongConstant(paramFile, "kTreatDistance");
75 gConst->kBrightnessLevels[0] = GetLongConstant(paramFile, "kLight");
76 gConst->kBrightnessLevels[1] = GetLongConstant(paramFile, "kMedium");
77 gConst->kBrightnessLevels[2] = GetLongConstant(paramFile, "kDark");
78 gConst->kBrightnessLevels[3] = GetLongConstant(paramFile, "kVeryDark");
79
80 gConst->kWeaponSF[0] = GetDoubleConstant(paramFile, "kWeaponSF1");
81 gConst->kWeaponSF[1] = GetDoubleConstant(paramFile, "kWeaponSF2");
82 gConst->kWeaponSF[2] = GetDoubleConstant(paramFile, "kWeaponSF3");
83 gConst->kWeaponSF[3] = GetDoubleConstant(paramFile, "kWeaponSF4");
84 gConst->kHealthSF[0] = GetDoubleConstant(paramFile, "kHealthSF1");
85 gConst->kHealthSF[1] = GetDoubleConstant(paramFile, "kHealthSF2");
86 gConst->kHealthSF[2] = GetDoubleConstant(paramFile, "kHealthSF3");
87 gConst->kHealthSF[3] = GetDoubleConstant(paramFile, "kHealthSF4");
88 gConst->kSpeedSF[0] = GetDoubleConstant(paramFile, "kSpeedSF1");
89 gConst->kSpeedSF[1] = GetDoubleConstant(paramFile, "kSpeedSF2");
90 gConst->kSpeedSF[2] = GetDoubleConstant(paramFile, "kSpeedSF3");
91 gConst->kSpeedSF[3] = GetDoubleConstant(paramFile, "kSpeedSF4");
92
93 gConst->kFlickeringPeriod = GetLongConstant(paramFile, "kFlickeringPeriod");
94 gConst->kLightningRadiant = GetLongConstant(paramFile, "kLightningRadiant");
95 gConst->kBkgndScrollFactor = GetDoubleConstant(paramFile, "kBkgndScrollFactor");
96 gConst->kCoronaFadeSpeed = GetDoubleConstant(paramFile, "kCoronaFadeSpeed");
97
98 gConst->kBlessureInvulnerabilityTime = GetLongConstant(paramFile, "kBlessureInvulnerabilityTime");
99 gConst->kMonsterTouchBlessure = GetLongConstant(paramFile, "kMonsterTouchBlessure");
100 gConst->kItemExplosionRad = GetLongConstant(paramFile, "kItemExplosionRad");
101 gConst->kItemExplosionStartShape = GetLongConstant(paramFile, "kItemExplosionStartShape");
102
103 gConst->kHealthPanelColor = GetLongConstant(paramFile, "kHealthPanelColor");
104 gConst->kOxygenPanelColor = GetLongConstant(paramFile, "kOxygenPanelColor");
105 gConst->kShadowmodeDarkening = GetLongConstant(paramFile, "kShadowmodeDarkening");
106 gConst->kFadeTime = GetLongConstant(paramFile, "kFadeTime");
107 gConst->kStartupTime = GetLongConstant(paramFile, "kStartupTime");
108
109 gConst->kTextYDistance = GetLongConstant(paramFile, "kTextYDistance");
110 gConst->kCameraSpeed = GetLongConstant(paramFile, "kCameraSpeed");
111
112 gConst->kSoundMaxDistance = GetLongConstant(paramFile, "kSoundMaxDistance");
113 gConst->kSoundMinDistance = GetLongConstant(paramFile, "kSoundMinDistance");
114
115 GetStringConstant(paramFile, "kFilePalette", gConst->kFilePalette);
116 GetStringConstant(paramFile, "kFileLevel", gConst->kFileLevel);
117 GetStringConstant(paramFile, "kFileMonster", gConst->kFileMonster);
118 GetStringConstant(paramFile, "kFileWeapon", gConst->kFileWeapon);
119 GetStringConstant(paramFile, "kFileInfo", gConst->kFileInfo);
120 GetStringConstant(paramFile, "kFilePlatform", gConst->kFilePlatform);
121 GetStringConstant(paramFile, "kFileObjects", gConst->kFileObjects);
122 GetStringConstant(paramFile, "kFileShapes", gConst->kFileShapes);
123 GetStringConstant(paramFile, "kFileBackground1", gConst->kFileBackground1);
124 GetStringConstant(paramFile, "kFileBackground2", gConst->kFileBackground2);
125 GetStringConstant(paramFile, "kFileCluts", gConst->kFileCluts);
126 GetStringConstant(paramFile, "kFileGUIs", gConst->kFileGUIs);
127 GetStringConstant(paramFile, "kFileConfig", gConst->kFileConfig);
128 GetStringConstant(paramFile, "kFileStartup", gConst->kFileStartup);
129
130
131 GetStringConstant(paramFile, "kMonsterName1", gConst->kMonsterNames[0]);
132 GetStringConstant(paramFile, "kMonsterName2", gConst->kMonsterNames[1]);
133 GetStringConstant(paramFile, "kMonsterName3", gConst->kMonsterNames[2]);
134 GetStringConstant(paramFile, "kMonsterName4", gConst->kMonsterNames[3]);
135 GetStringConstant(paramFile, "kMonsterName5", gConst->kMonsterNames[4]);
136 GetStringConstant(paramFile, "kMonsterName6", gConst->kMonsterNames[5]);
137 GetStringConstant(paramFile, "kMonsterName7", gConst->kMonsterNames[6]);
138 GetStringConstant(paramFile, "kMonsterName8", gConst->kMonsterNames[7]);
139 GetStringConstant(paramFile, "kMonsterName9", gConst->kMonsterNames[8]);
140 GetStringConstant(paramFile, "kMonsterName10", gConst->kMonsterNames[9]);
141 GetStringConstant(paramFile, "kMonsterName11", gConst->kMonsterNames[10]);
142
143 gConst->kMonsterNameSpeed = GetLongConstant(paramFile, "kMonsterNameSpeed");
144 gConst->kMonsterNameX = GetLongConstant(paramFile, "kMonsterNameX");
145
146
147 gConst->kShowFPS = GetLongConstant(paramFile, "kShowFPS");
148
149 for (short n = 1; n <= kNumOfLevels; n ++) {
150 levelSetString[0] = (char)(n / 10) + '0';
151 levelSetString[1] = (char)(n % 10) + '0';
152 levelBkgndString[0] = (char)(n / 10) + '0';
153 levelBkgndString[1] = (char)(n % 10) + '0';
154 gConst->kShapeSets[n -1] = GetLongConstant(paramFile, levelSetString) -1;
155 gConst->kBackgrounds[n -1] = GetLongConstant(paramFile, levelBkgndString);
156 }
157
158 fclose(paramFile);
159
160 // Hier sollte auch im Home Directory gesucht werden...
161 paramFile = gSystem->FindFile(gConst->kFileConfig); // by LL
162
163 gConfigData->leftKey = GetLongConstant(paramFile, "LeftKey");
164 GetStringConstant(paramFile, "LeftKeyText", gConfigData->leftKeyText);
165 gConfigData->rightKey = GetLongConstant(paramFile, "RightKey");
166 GetStringConstant(paramFile, "RightKeyText", gConfigData->rightKeyText);
167 gConfigData->jumpKey = GetLongConstant(paramFile, "JumpKey");
168 GetStringConstant(paramFile, "JumpKeyText", gConfigData->jumpKeyText);
169 gConfigData->runKey = GetLongConstant(paramFile, "RunKey");
170 GetStringConstant(paramFile, "RunKeyText", gConfigData->runKeyText);
171 gConfigData->shootKey = GetLongConstant(paramFile, "ShootKey");
172 GetStringConstant(paramFile, "ShootKeyText", gConfigData->shootKeyText);
173 gConfigData->nextWeaponKey = GetLongConstant(paramFile, "NextWeaponKey");
174 GetStringConstant(paramFile, "NextWeaponKeyText", gConfigData->nextWeaponKeyText);
175 gConfigData->prevWeaponKey = GetLongConstant(paramFile, "PrevWeaponKey");
176 GetStringConstant(paramFile, "PrevWeaponKeyText", gConfigData->prevWeaponKeyText);
177 gConfigData->activateKey = GetLongConstant(paramFile, "ActivateKey");
178 GetStringConstant(paramFile, "ActivateKeyText", gConfigData->activateKeyText);
179
180 gConfigData->weapon1Key = GetLongConstant(paramFile, "Weapon1Key");
181 gConfigData->weapon2Key = GetLongConstant(paramFile, "Weapon2Key");
182 gConfigData->weapon3Key = GetLongConstant(paramFile, "Weapon3Key");
183 gConfigData->weapon4Key = GetLongConstant(paramFile, "Weapon4Key");
184 gConfigData->weapon5Key = GetLongConstant(paramFile, "Weapon5Key");
185 gConfigData->weapon6Key = GetLongConstant(paramFile, "Weapon6Key");
186 gConfigData->weapon7Key = GetLongConstant(paramFile, "Weapon7Key");
187 gConfigData->weapon8Key = GetLongConstant(paramFile, "Weapon8Key");
188
189 gConfigData->soundVolume = GetLongConstant(paramFile, "SoundVolume");
190
191 gConfigData->screenWidth = GetLongConstant(paramFile, "ScreenWidth");
192 gConfigData->screenHeight = GetLongConstant(paramFile, "ScreenHeight");
193
194 gConfigData->disableCoronas = GetLongConstant(paramFile, "DisableCoronas");
195 gConfigData->disableLightning = GetLongConstant(paramFile, "DisableLightning");
196 gConfigData->disableShapeModes = GetLongConstant(paramFile, "DisableShapeModes");
197
198 fclose(paramFile);
199 }
200
201
202
203
204
205
206 #define CATCHSPACES while (c == (unsigned char)' ') {c = fgetc(f); }
207
208 short GetValue(FILE *f, char *constName, char *value)
209 {
210 char key[30];
211 char c = 0;
212 short n;
213
214 fseek(f, 0, SEEK_SET);
215
216 while (strcmp(key, constName)) {
217 c = fgetc(f);
218 n = 1;
219 if (c == (unsigned char)'#') { // comment
220 while (fgetc(f) != (unsigned char)'\n') {}
221 }else if (c == (unsigned char)'@') {
222 value[0] = '\0';
223 return 0;
224 }else{
225 key[0] = c;
226 while (c != (unsigned char)' ' && c != (unsigned char)'=') {
227 c = fgetc(f);
228 key[n] = c; n ++;
229 }
230 key[n - 1] = '\0';
231 CATCHSPACES
232 if (c != (unsigned char)'=') return 0;
233 c = fgetc(f); n = 1;
234 CATCHSPACES
235 value[0] = c;
236 while (c != (unsigned char)' ' && c != (unsigned char)'\n') {
237 c = fgetc(f);
238 value[n] = c; n ++;
239 }
240 value[n - 1] = '\0';
241 while (c != (unsigned char)'\n') {c = fgetc(f); }
242 }
243 }
244 if (key[0] == '@') return 0;
245 else return 1;
246 }
247
248 long GetLongConstant(FILE *f, char *constName)
249 {
250 char val[30];
251
252 if (GetValue(f, constName, val))
253 return atoi(val);
254 else{
255 return 0;
256 }
257 }
258
259 double GetDoubleConstant(FILE *f, char *constName)
260 {
261 char val[30];
262
263 if (GetValue(f, constName, val))
264 return atof(val);
265 else{
266 return 0;
267 }
268 }
269
270 void GetStringConstant(FILE *f, char *constName, char *buffer)
271 {
272 GetValue(f, constName, buffer);
273 }
0 #ifndef __AMP_CONSTVAL__
1 #define __AMP_CONSTVAL__
2
3 #include "AmpHead.hpp"
4
5 const short kFilenameLength = 12;
6 const short kKeyDescriptionLength = 20;
7
8 struct tConstValues {
9 // The accelerations and velocities are measured
10 // in pixel / (second * 1000)
11 double kVelocityUnit;
12 double kPlayerAcceleration;
13 double kPlayerLiquidAccel;
14 double kJumpVelocity;
15 double kRunScaleFactor;
16 short kJumpAccelerationTime;
17 short kTeleportTime; // Time for a teleport process
18 short kPlayerWidth; // Width of player used for collisions
19 short kBulletWidth; // Width of bullets used for collisions
20 short kFirehandNumOfBullets; // Num of bullets shots when used firehands
21 double kFirehandAngle; // angle between two shoot directions
22 short kStaffLoadTime; // Time to load the staff weapon
23 short kInitialOxygen; // Inital amound of oxygen
24 double kOxygenDecrease; // Decrease of oxygen in one second
25 short kLavaDamage; // Damage caused by lava per tick
26 short kPlayersFirstWeaponShape; // Players first weapon shape
27 long kPickupTime; // Time the pickup shape is drawn
28
29 short kBulletTailLength; // How many shapes are to be drawn at the tail of a bullet
30 short kBulletTailDistance; // Distance of two shapes
31 double kDetonationFrameTime; // Every 1/2 second a new detonation frame
32 short kWalkFrameTime; // in ticks
33 short kShootFrameTime; // Time for one shoot animation frame
34 short kWeaponChangeTime; // Time between changing a weapon (Pressing x or y)
35 short kActionDelayTime; // Time between two actions the player performs
36 short kDieFrameTime; // Time between two die frames
37
38 short kWeaponCarryHeight; // Height of carrying a weapon
39
40 double kDriftSpeed;
41 // Blinking times for player ports
42 short kTeleportBlinkTime;
43 short kSavePortBlinkTime;
44 short kExitPortBlinkTime;
45
46 // general physics constants
47 double kGravitation;
48 double kNormalFriction;
49 double kLiquidFriction;
50 double kMaxFallingSpeed; // max. velocity when falling
51
52 // Monster movement constants
53 double kJumperJumpAcceleration;
54 // How often the sorcery bullet bounces off
55 short kNumOfBounces;
56 short kSineWeaponRad;
57 double kMaxTurnAngle; // max angle a guided bullet can turn
58 short kWargNearWeaponRadix;
59 double kWargFastSpeedup;
60 double kWargJumpAcceleration;
61
62 long kDelayAfterWargDeath; // Delay before level switch after killed warg
63
64 // At which distance a bullet becomes a treat for a monster
65 short kTreatDistance;
66 short kBrightnessLevels[4];
67 long kFlickeringPeriod;
68
69 short kActivateDistance; // Distance from the player a monster starts to move
70
71 double kWeaponSF[4];
72 double kHealthSF[4];
73 double kSpeedSF[4];
74
75 short kLightningRadiant; // Radius of lightning of a bullet
76 double kBkgndScrollFactor; // Background scrolling speed in percent of foreground scrolling speed
77 double kCoronaFadeSpeed; // How many percent of 1 the corona fades every tick
78
79 short kBlessureInvulnerabilityTime; // How long is a monster invulnerable after a hurt
80 short kMonsterTouchBlessure; // Blessure when touching a monster
81
82 short kItemExplosionRad;
83 short kItemExplosionStartShape;
84
85 short kHealthPanelColor;
86 short kOxygenPanelColor;
87 short kShadowmodeDarkening; // Percent of darkness of shaded bodies
88 short kFadeTime; // Time for entirely fading the screen
89 short kStartupTime; // Time for displaying the startup screen
90
91 short kSoundMaxDistance; // At which distance a sound can be heard
92 short kSoundMinDistance; // At which distance a sound is maximal loud
93
94 short kTextYDistance; // Distance between two lines of text displayed
95 short kCameraSpeed; // Speed of camera
96
97 short kShowFPS; // Indicates whether the FPS is displayed
98
99 char kFilePalette[kFilenameLength];
100 char kFileLevel[kFilenameLength];
101 char kFileMonster[kFilenameLength];
102 char kFileWeapon[kFilenameLength];
103 char kFileInfo[kFilenameLength];
104 char kFilePlatform[kFilenameLength];
105 char kFileObjects[kFilenameLength];
106 char kFileShapes[kFilenameLength];
107 char kFileBackground1[kFilenameLength];
108 char kFileBackground2[kFilenameLength];
109 char kFileCluts[kFilenameLength];
110 char kFileGUIs[kFilenameLength];
111 char kFileConfig[kFilenameLength];
112 char kFileStartup[kFilenameLength];
113
114 char kMonsterNames[11][kFilenameLength];
115 short kMonsterNameSpeed; // Scrollspeed of monstername
116 short kMonsterNameX; // x-pos on screen
117
118 short kShapeSets[kNumOfLevels];
119 short kBackgrounds[kNumOfLevels];
120 };
121
122
123 struct tConfigData {
124 short leftKey;
125 char leftKeyText[kKeyDescriptionLength];
126 short rightKey;
127 char rightKeyText[kKeyDescriptionLength];
128 short jumpKey;
129 char jumpKeyText[kKeyDescriptionLength];
130 short runKey;
131 char runKeyText[kKeyDescriptionLength];
132 short shootKey;
133 char shootKeyText[kKeyDescriptionLength];
134 short nextWeaponKey;
135 char nextWeaponKeyText[kKeyDescriptionLength];
136 short prevWeaponKey;
137 char prevWeaponKeyText[kKeyDescriptionLength];
138 short activateKey;
139 char activateKeyText[kKeyDescriptionLength];
140
141 short weapon1Key;
142 short weapon2Key;
143 short weapon3Key;
144 short weapon4Key;
145 short weapon5Key;
146 short weapon6Key;
147 short weapon7Key;
148 short weapon8Key;
149
150 short soundVolume;
151 short haveSound; // by LL
152
153 short screenWidth;
154 short screenHeight;
155 short tryFullScreen; // by LL
156
157 short disableCoronas;
158 short disableLightning;
159 short disableShapeModes;
160 };
161
162 #endif
0 #include "Creeper.hpp"
0 #ifndef __AMP_CREEPER__
1 #define __AMP_CREEPER__
2
3 #include "Monster.hpp"
4
5
6 #endif
0 #include "Element.hpp"
1 #include "Appl.hpp"
2 #include "Gui.hpp"
3 #include "SndSys.hpp"
4
5 extern CApplication *gApplication;
6 extern CShapeManager *gShapeManager;
7 extern CSystem *gSystem;
8 extern tConstValues *gConst;
9 extern CLevel *gLevel;
10 extern CGUI *gGUI;
11 extern CSoundSystem *gSoundSystem;
12
13 CElement::CElement(short initx, short inity, short width, short height, tLevelElement *levelElement) : CObject(initx, inity, width, height)
14 {
15 typeID |= kElement;
16
17 if (levelElement) {
18 brightness = 3 - LOBYTE(levelElement->light);
19 brightness2 = 3 - HIBYTE(levelElement->light);
20 iconID = levelElement->iconID;
21 bitData = levelElement->bitData;
22 lastState = 0;
23
24 refNum = LOBYTE(levelElement->refNum);
25 key = HIBYTE(levelElement->refNum);
26 data = HIBYTE(levelElement->kind);
27
28 OnAllocate();
29
30 weight = SHRT_MAX;
31 background = levelElement->kind;
32 }
33 }
34
35 void CElement::OnAllocate()
36 {
37 if (iconID > 0) {
38 shape = gShapeManager->FindShape(iconID, brightness);
39 shape2 = gShapeManager->FindShape(iconID, brightness2);
40 }
41
42 // If there's something on that element, allocate the struct which holds the several shapes
43 if (bitData & (kPlatformSwitchMask | kLightSwitchMask | kTeleportMask | kSaveMask | kExitMask | kPassiveLightMask | kPassivePlatformMask | kRightDriftMask | kLeftDriftMask | kInfotextMask)) {
44 elementThings = new tElementThings;
45
46 if (bitData & kPlatformSwitchMask) {
47 elementThings->platformSwitchInactive = gShapeManager->FindShape(kPlatformSwitchInactiveID, 0);
48 elementThings->platformSwitchActive = gShapeManager->FindShape(kPlatformSwitchActiveID, 0);
49 elementThings->referencedPlatform = gApplication->platformTable[refNum];
50 }else{
51 elementThings->platformSwitchInactive = elementThings->platformSwitchActive = 0L;
52 elementThings->referencedPlatform = 0L;
53 }
54 if (bitData & kPassivePlatformMask) {
55 elementThings->referencedPlatform = gApplication->platformTable[refNum];
56 elementThings->passiveHasChanged = 0;
57 }
58
59 if (bitData & kLightSwitchMask) {
60 elementThings->lightSwitch = gShapeManager->FindShape(kLightSwitchInactiveID, 0);
61 elementThings->lightSwitch2 = gShapeManager->FindShape(kLightSwitchActiveID, 0);
62 }else{
63 elementThings->lightSwitch = elementThings->lightSwitch2 = 0L;
64 }
65
66 if (bitData & kTeleportMask) {
67 elementThings->teleporter = gShapeManager->FindShape(kTeleportStateOne, 0);
68 elementThings->teleporter2 = gShapeManager->FindShape(kTeleportStateTwo, 0);
69 }else{
70 elementThings->teleporter = elementThings->teleporter2 = 0L;
71 }
72 elementThings->teleportBlinkTime = 0;
73
74 if (bitData & kSaveMask) {
75 elementThings->savePort = gShapeManager->FindShape(kSavePortStateOne, 0);
76 elementThings->savePort2 = gShapeManager->FindShape(kSavePortStateTwo, 0);
77 }else{
78 elementThings->savePort = elementThings->savePort2 = 0L;
79 }
80 elementThings->savePortBlinkTime = 0;
81
82 if (bitData & kExitMask) {
83 elementThings->exitPort = gShapeManager->FindShape(kExitStateOne, 0);
84 elementThings->exitPort2 = gShapeManager->FindShape(kExitStateTwo, 0);
85 }else{
86 elementThings->exitPort = elementThings->exitPort2 = 0L;
87 }
88 elementThings->exitPortBlinkTime = 0;
89
90 elementThings->passiveHasChanged = 0;
91
92 elementThings->drift = 0L;
93 if (bitData & kLeftDriftMask) elementThings->drift = gShapeManager->FindShape (kDriftLeftID, 0);
94 if (bitData & kRightDriftMask) elementThings->drift = gShapeManager->FindShape(kDriftRightID, 0);
95
96 if (bitData & kInfotextMask) {
97 elementThings->infoPort = gShapeManager->FindShape(kInfotextStateOne, 0);
98 elementThings->infoPort2 = gShapeManager->FindShape(kInfotextStateTwo, 0);
99 }else{
100 elementThings->infoPort = elementThings->infoPort2 = 0L;
101 }
102 elementThings->infoPortBlinkTime = 0;
103
104 }else elementThings = 0L;
105 }
106
107
108 CElement::~CElement()
109 {
110 if (elementThings) delete elementThings;
111 }
112
113
114 void CElement::LinkPlatforms()
115 {
116 if (elementThings) {
117 if (bitData & kPlatformSwitchMask) {
118 elementThings->referencedPlatform = gApplication->platformTable[refNum];
119 }else{
120 elementThings->referencedPlatform = 0L;
121 }
122 if (bitData & kPassivePlatformMask) {
123 elementThings->referencedPlatform = gApplication->platformTable[refNum];
124 elementThings->passiveHasChanged = 0;
125 }
126 }
127 }
128
129
130 void CElement::PaintElementThings(short planeX, short planeY, tRect *clipRect)
131 {
132 CShape *tmp;
133
134 if (bitData & kPlatformSwitchMask && elementThings->referencedPlatform)
135 elementThings->referencedPlatform->GetCurrentState(elementThings->platformSwitchActive, elementThings->platformSwitchInactive)->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
136
137 if (elementThings->lightSwitch) elementThings->lightSwitch->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
138
139 if (elementThings->teleporter) {
140 elementThings->teleporter->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
141 if (elementThings->teleportBlinkTime < gSystem->GetTicks()) {
142 tmp = elementThings->teleporter; elementThings->teleporter = elementThings->teleporter2; elementThings->teleporter2 = tmp;
143 elementThings->teleportBlinkTime = gSystem->GetTicks() + gConst->kTeleportBlinkTime;
144 }
145 }
146 if (elementThings->savePort) {
147 elementThings->savePort->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
148 if (elementThings->savePortBlinkTime < gSystem->GetTicks()) {
149 tmp = elementThings->savePort; elementThings->savePort = elementThings->savePort2; elementThings->savePort2 = tmp;
150 elementThings->savePortBlinkTime = gSystem->GetTicks() + gConst->kSavePortBlinkTime;
151 }
152 }
153
154 if (elementThings->exitPort) {
155 elementThings->exitPort->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
156 if (elementThings->exitPortBlinkTime < gSystem->GetTicks()) {
157 tmp = elementThings->exitPort; elementThings->exitPort = elementThings->exitPort2; elementThings->exitPort2 = tmp;
158 elementThings->exitPortBlinkTime = gSystem->GetTicks() + gConst->kExitPortBlinkTime;
159 }
160 }
161 if (elementThings->drift) elementThings->drift->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
162
163 if (elementThings->infoPort) {
164 elementThings->infoPort->RenderShape(xs - planeX, ys - planeY, clipRect, kShapemodusNormal, 0, gApplication->plane);
165 if (elementThings->infoPortBlinkTime < gSystem->GetTicks()) {
166 tmp = elementThings->infoPort; elementThings->infoPort = elementThings->infoPort2; elementThings->infoPort2 = tmp;
167 elementThings->infoPortBlinkTime = gSystem->GetTicks() + gConst->kExitPortBlinkTime;
168 }
169 }
170 }
171
172 void CElement::PaintElement(short planeX, short planeY, tRect *clipRect)
173 {
174 long timeStamp;
175
176 if (shape) shape->RenderShape(xs - planeX, ys - planeY, clipRect, 0, 0, gApplication->plane);
177
178 if (bitData & kFlickeringMask) {
179 timeStamp = (gApplication->syncTime / gConst->kFlickeringPeriod) & 1;
180 if ((long)(timeStamp) != lastState) {
181 SwapLights();
182 lastState = timeStamp;
183 }
184 }
185
186 if (elementThings) PaintElementThings(planeX, planeY, clipRect);
187 }
188
189
190 short CElement::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject)
191 {
192 short returnValue;
193 double driftSpeed = 0;
194 double friction = bitData & kIceMask ? 0 : gConst->kNormalFriction;
195
196 if ((returnValue = CObject::Collision(sender, left, top, right, bottom, forcex, forcey, pfx, pfy, sourceWeight, collisionObject)) & kCollisionOnBottom) {
197 if (bitData & kRightDriftMask) driftSpeed = gConst->kDriftSpeed;
198 if (bitData & kLeftDriftMask) driftSpeed = -gConst->kDriftSpeed;
199 sender->CollisionEvent(friction, driftSpeed);
200
201 }
202 return returnValue;
203 }
204
205 // -----------------------------------------
206 short CElement::Action()
207 // Is called from CPlayer::Think, when the player performs an action on that element
208 // Looks if there is some action possible, and do it
209 {
210 if (elementThings) { // is there any action possible?
211 if(elementThings->referencedPlatform) {
212 elementThings->referencedPlatform->Switch();
213 }
214
215 if (bitData & kLightSwitchMask) {
216 SWAP(elementThings->lightSwitch, elementThings->lightSwitch2, CShape *)
217 gLevel->SwitchLight(refNum);
218 }
219
220 if (bitData & kSaveMask) gApplication->command = gGUI->RunUserInterface(kSaveGamePage);
221
222 if (bitData & kInfotextMask) gGUI->DisplayInfotext(data);
223 }
224
225 return bitData;
226 }
227
228 void CElement::PassiveAction()
229 {
230 if (elementThings) {
231 if ((bitData & kPassiveLightMask) && !elementThings->passiveHasChanged) {
232 gLevel->SwitchLight(refNum);
233 elementThings->passiveHasChanged = 1;
234 }
235 if ((bitData & kPassivePlatformMask) && !elementThings->passiveHasChanged && elementThings->referencedPlatform) {
236 elementThings->referencedPlatform->Switch();
237 elementThings->passiveHasChanged = 1;
238 }
239 }
240 }
241
242 // --------------------------------
243 void CElement::SwapLights()
244 // Swaps the light textures for that element
245 {
246 SWAP(shape, shape2, CShape *);
247 SWAP(brightness, brightness2, short);
248 }
249
250 // --------------------------------
251 void CElement::Teleport(double &xp, double &yp)
252 // Moves the coordinates to this element
253 {
254 if (background) {
255 xp = xs;
256 yp = ys;
257 }
258 }
259
260
261 // ---------------------------------------------
262 short CElement::GetElementLiquid()
263 // Returns the liquid on this element, expressed by the shape drawing modus
264 {
265 if (bitData & kLavaMask) return kShapemodusLava;
266 if (bitData & kWaterMask) return kShapemodusWater;
267 if (bitData & kFogMask) return kShapemodusFog;
268 return kShapemodusNormal;
269 }
270
271 CBackgroundElement::CBackgroundElement(short initx, short inity, short width, short height, tLevelElement *levelElement) : CElement(initx, inity, width, height, levelElement)
272 {
273 typeID |= kBackgroundElement;
274
275 if (levelElement) OnAllocate();
276 brightness = 0;
277 }
278
279 void CBackgroundElement::OnAllocate()
280 {
281 short params[5] = {-1, xs, ys, xe - xs, ye - ys};
282 unsigned char *tmpBmp;
283
284 tmpBmp = gShapeManager->GetBackground(params[1], params[2]);
285 shape = new CBackground(tmpBmp, params, 0);
286 }
287
288
289 CBackgroundElement::~CBackgroundElement()
290 {
291 delete shape;
292 }
293
294 void CBackgroundElement::PaintElement(short planeX, short planeY, tRect *clipRect)
295 {
296 long timeStamp;
297
298 if (shape) shape->RenderShape(xs - planeX, ys - planeY, clipRect, planeX * gConst->kBkgndScrollFactor, 0, gApplication->plane);
299
300 if (elementThings) PaintElementThings(planeX, planeY, clipRect);
301 }
302
303
304
305 short CElement::Write(FILE *f)
306 {
307 long size = 0;
308
309 WRITEDATA(size);
310 WRITEDATA(typeID);
311
312 size += CObject::Write(f);
313
314 WRITEDATA(bitData);
315 WRITEDATA(lastState);
316 WRITEDATA(iconID);
317 WRITEDATA(brightness);
318 WRITEDATA(brightness2);
319 WRITEDATA(key);
320 WRITEDATA(refNum);
321 WRITEDATA(data);
322
323 WRITEDATA(elementThings);
324 if (elementThings) {
325 WRITEDATA(elementThings->teleportBlinkTime);
326 WRITEDATA(elementThings->savePortBlinkTime);
327 WRITEDATA(elementThings->exitPortBlinkTime);
328 WRITEDATA(elementThings->passiveHasChanged);
329 }
330
331
332
333 FINISHWRITE;
334
335 return size;
336 }
337
338 void CElement::Read(FILE *f)
339 {
340 long size = 0;
341 long elemThings;
342
343 READDATA(size);
344 READDATA(typeID);
345
346 CObject::Read(f);
347
348 READDATA(bitData);
349 READDATA(lastState);
350 READDATA(iconID);
351 READDATA(brightness);
352 READDATA(brightness2);
353 READDATA(key);
354 READDATA(refNum);
355 READDATA(data);
356
357 OnAllocate();
358
359 READDATA(elemThings);
360 if (elementThings) {
361 READDATA(elementThings->teleportBlinkTime);
362 READDATA(elementThings->savePortBlinkTime);
363 READDATA(elementThings->exitPortBlinkTime);
364 READDATA(elementThings->passiveHasChanged);
365 }
366
367
368 }
369
370 void CBackgroundElement::Read(FILE *f)
371 {
372 CElement::Read(f);
373
374 OnAllocate();
375 }
0 #ifndef __AMP_ELEMENT__
1 #define __AMP_ELEMENT__
2
3 #include "Object.hpp"
4 #include "File.hpp"
5 #include "Pltform.hpp"
6
7 // Added by Luke
8 #define LOBYTE(x) ((unsigned char)((x) & 0xff))
9 #define HIBYTE(x) ((unsigned char)((unsigned short)(x) >> 8))
10
11 enum {
12 kPlatformSwitchInactiveID = 200,
13 kPlatformSwitchActiveID = 201,
14 kLightSwitchInactiveID = 208,
15 kLightSwitchActiveID = 209,
16 kInfotextStateOne = 210,
17 kInfotextStateTwo = 211,
18 kSavePortStateOne = 202,
19 kSavePortStateTwo = 203,
20 kExitStateOne = 204,
21 kExitStateTwo = 205,
22 kTeleportStateOne = 206,
23 kTeleportStateTwo = 207,
24 kDriftLeftID = 4015,
25 kDriftRightID = 4016
26 };
27
28 struct tElementThings {
29 CShape *lightSwitch;
30 CShape *lightSwitch2;
31 CShape *platformSwitchActive;
32 CShape *platformSwitchInactive;
33 CPlatform *referencedPlatform;
34 CShape *drift;
35
36 CShape *teleporter;
37 CShape *teleporter2;
38 long teleportBlinkTime;
39 CShape *savePort;
40 CShape *savePort2;
41 long savePortBlinkTime;
42 CShape *exitPort;
43 CShape *exitPort2;
44 long exitPortBlinkTime;
45 CShape *infoPort;
46 CShape *infoPort2;
47 long infoPortBlinkTime;
48
49 short passiveHasChanged;
50 };
51
52 class CPlayer;
53
54 class CElement : public CObject {
55 friend class CPlayer;
56 protected:
57 CShape *shape;
58 CShape *shape2;
59 short bitData;
60 short lastState;
61 short iconID;
62
63 tElementThings *elementThings;
64
65 public:
66 short brightness;
67 short brightness2;
68 short key;
69 short refNum;
70 short data;
71
72 CElement(short initx, short inity, short width, short height, tLevelElement *element);
73 ~CElement();
74
75 void OnAllocate();
76 void LinkPlatforms();
77
78 virtual void PaintElement(short planeLeft, short planeTop, tRect *clipRect);
79 void PaintElementThings(short planeLeft, short planeTop, tRect *clipRect);
80 virtual short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
81
82 short Action();
83 void PassiveAction();
84 void SwapLights();
85 void Teleport(double &xs, double &ys);
86 short GetElementLiquid();
87
88 virtual short Write(FILE *f);
89 virtual void Read(FILE *f);
90 };
91
92 class CBackgroundElement : public CElement {
93 public:
94 CBackgroundElement(short initx, short inity, short width, short height, tLevelElement *element);
95 ~CBackgroundElement();
96
97 void OnAllocate();
98
99 void PaintElement(short planeLeft, short planeTop, tRect *clipRect);
100
101 void Read(FILE *f);
102 };
103
104 #endif
0 #include "File.hpp"
1
2 CFile::CFile()
3 {}
4
5 CFile::~CFile()
6 {}
7
8 boolVar CFile::OpenDataFile(char *name)
9 {
10 fileRef = fopen(name, "rb");
11 return fileRef != NULL;
12 }
13
14
15 void CFile::CloseDataFile()
16 {
17 fclose(fileRef);
18 }
19
20 void CFile::SetFilePos(long offset)
21 {
22 fseek(fileRef, offset, SEEK_SET);
23 }
24
25 long CFile::ReadData(void *data, long size)
26 {
27 return fread(data, size, 1, fileRef);
28 }
0 #ifndef __AMP_FILES__
1 #define __AMP_FILES__
2
3 #include <stdio.h>
4 #include "System.hpp"
5
6 // Basic types for file input/output. Size of variable is very important
7 typedef unsigned char Var1Byte;
8 typedef short Var2Bytes;
9 typedef long Var4Bytes ;
10 typedef double Var8Bytes;
11
12 /* Macros used to convert big endian to little endian and back. Data in the
13 Amphetamine data files is stored in big endian (PowerPC)
14 */
15
16 #define SWAP_SHORT(x) ((x << 8) | (((unsigned short)x) >> 8))
17 #define SWAP_LONG(x) ( \
18 (x << 24) | \
19 (((unsigned long)x) >> 24) | \
20 ((x & 0x0000FF00) << 8) | \
21 ((x & 0x00FF0000) >> 8) \
22 )
23
24 #define SWAP_PUT_SHORT(x) ((x) = (x << 8) | (((unsigned short)x) >> 8))
25 #define SWAP_PUT_LONG(x) ((x) = (x << 24) | (((unsigned long)x) >> 24) | \
26 ((x & 0x0000FF00) << 8) | ((x & 0x00FF0000) >> 8))
27
28 #define TRANS_NUM(x) ( \
29 (sizeof(x) == sizeof(short)) ? SWAP_SHORT(x) : \
30 (sizeof(x) == sizeof(long)) ? SWAP_LONG(x) : (x)\
31 )
32
33 #ifndef __BIG_ENDIAN__
34
35 #define TRANS_PUT_NUM(x) ((sizeof(x) == sizeof(short)) ? SWAP_PUT_SHORT(x) : \
36 (sizeof(x) == sizeof(long)) ? SWAP_PUT_LONG(x) : (x))
37 #define TRANS_PUT_NUM2(x) x
38
39 #else
40
41 #define TRANS_PUT_NUM(x) x
42
43 #define TRANS_PUT_NUM2(x) ((sizeof(x) == sizeof(short)) ? SWAP_PUT_SHORT(x) : \
44 (sizeof(x) == sizeof(long)) ? SWAP_PUT_LONG(x) : (x))
45
46 #endif
47
48
49 class CFile {
50 protected:
51 FILE *fileRef;
52 short levelNumber;
53
54 boolVar OpenDataFile(char *name);
55 void SetFilePos(long offset);
56 long ReadData(void *buffer, long size);
57 void CloseDataFile();
58
59 public:
60
61 CFile();
62 ~CFile();
63 };
64
65
66 // Datastructure of level element
67 struct tLevelElement {
68 Var2Bytes kind; // kWall = 0, kBackground = 1
69 Var2Bytes iconID;
70 Var2Bytes light;
71 Var2Bytes refNum; // LoByte: Platform switch, HiByte: Light Index
72 Var2Bytes bitData;
73 Var2Bytes monsterRef;
74 Var2Bytes itemRef;
75 };
76
77 #endif
0
1 /*
2 * xgifload.c - based strongly on...
3 *
4 * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
5 *
6 * Copyright (c) 1988, 1989 by Patrick J. Naughton
7 *
8 * Author: Patrick J. Naughton
9 * naughton@wind.sun.com
10 *
11 * Permission to use, copy, modify, and distribute this software and its
12 * documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation.
16 *
17 * This file is provided AS IS with no warranties of any kind. The author
18 * shall have no liability with respect to the infringement of copyrights,
19 * trade secrets or any patents by this file or any part thereof. In no
20 * event will the author be liable for any lost revenue or profits or
21 * other special, indirect and consequential damages.
22 *
23 *
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 //#include "wt.h"
31 //#include "gApplication->system->Error.h"
32 //#include "wtmem.h"
33 #include "Graphfil.hpp"
34 #include "Appl.hpp"
35
36 extern CApplication *gApplication;
37 extern CSystem *gSystem;
38
39
40 #define mfputc fputc
41 #define mfgetc fgetc
42 #define mfopen fopen
43 #define mfclose fclose
44 #define mfread fread
45 #define mfseek fseek
46 #define mftell ftell
47 #define mrewind rewind
48 #define mfprintf fprintf
49
50 /* malloc or die . . . */
51 void *wtmalloc(size_t size)
52 {
53 void *news;
54
55 if ((news = malloc(size)) == NULL)
56 gSystem->Error("could not allocate %x bytes", size);
57
58 return news;
59 }
60
61
62 /* realloc or die . . . */
63 void *wtrealloc(void *v, size_t size)
64 {
65 void *news;
66
67 if ((news = realloc(v, size)) == NULL)
68 gSystem->Error("could not reallocate %x bytes", size);
69
70 return news;
71 }
72
73
74 void wtfree(void *v)
75 {
76 if (v == NULL)
77 gSystem->Error("wtfree(NULL)", 0);
78 else
79 free(v);
80 }
81
82
83
84 typedef int gBOOLean;
85 typedef unsigned char byte;
86
87 #define NEXTBYTE (*ptr++)
88 #define IMAGESEP 0x2c
89 #define GRAPHIC_EXT 0xf9
90 #define PLAINTEXT_EXT 0x01
91 #define APPLICATION_EXT 0xff
92 #define COMMENT_EXT 0xfe
93 #define START_EXTENSION 0x21
94 #define INTERLACEMASK 0x40
95 #define COLORMAPMASK 0x80
96
97 int BitOffset = 0, /* Bit Offset of next code */
98 XC = 0, YC = 0, /* Output X and Y coords of current pixel */
99 Pass = 0, /* Used by output routine if interlaced pic */
100 OutCount = 0, /* Decompressor output 'stack count' */
101 RWidth, RHeight, /* screen dimensions */
102 Width, Height, /* image dimensions */
103 LeftOfs, TopOfs, /* image offset */
104 BitsPerPixel, /* Bits per pixel, read from GIF header */
105 BytesPerScanline, /* bytes per scanline in output raster */
106 ColorMapSize, /* number of colors */
107 Background, /* background color */
108 CodeSize, /* Code size, read from GIF header */
109 InitCodeSize, /* Starting code size, used during Clear */
110 Code, /* Value returned by ReadCode */
111 MaxCode, /* limiting value for current code size */
112 ClearCode, /* GIF clear code */
113 EOFCode, /* GIF end-of-information code */
114 CurCode, OldCode, InCode, /* Decompressor variables */
115 FirstFree, /* First free code, generated per GIF spec */
116 FreeCode, /* Decompressor, next free slot in hash table*/
117 FinChar, /* Decompressor variable */
118 BitMask, /* AND mask for data size */
119 ReadMask; /* Code AND mask for current code size */
120
121 gBOOLean Interlace, HasColormap;
122 gBOOLean Verbose = 0;
123
124 byte *Image; /* The result array */
125 byte *RawGIF; /* The heap array to hold it, raw */
126 byte *Raster; /* The raster data stream, unblocked */
127
128 /* The hash table used by the decompressor */
129 short Prefix[4096];
130 short Suffix[4096];
131
132 /* An output array used by the decompressor */
133 int OutCode[1025];
134
135 /* The color map, read from the GIF header */
136 byte Red[256], Green[256], Blue[256], used[256];
137 int numused;
138
139 char *id87 = "GIF87a";
140 char *id89 = "GIF89a";
141
142 int ReadCode( void );
143 int log2( int );
144 void AddToPixel( byte );
145
146
147 Graphic_file *LoadGIF(FILE *fp, char *fname )
148 {
149 Graphic_file *gfile;
150 int filesize, numcols;
151 register unsigned char ch, ch1;
152 register byte *ptr, *ptr1;
153 register int i;
154 short transparency = -1;
155
156 BitOffset = 0;
157 XC = YC = 0;
158 Pass = 0;
159 OutCount = 0;
160
161 /* find the size of the file */
162 mfseek(fp, 0L, 2);
163 filesize = mftell(fp);
164 mfseek(fp, 0L, 0);
165
166 if (!(ptr = RawGIF = (byte *) malloc(filesize)))
167 gSystem->Error("not enough memory to read gif file",0);
168
169 if (!(Raster = (byte *) malloc(filesize))) {
170 free( ptr );
171 gSystem->Error("not enough memory to read gif file",0);
172 }
173
174 if (mfread(ptr, filesize, 1, fp) != 1)
175 gSystem->Error("GIF data read failed",0);
176
177 if (strncmp((char *) ptr, id87, 6))
178 if (strncmp((char *) ptr, id89, 6))
179 gSystem->Error("not a GIF file",0);
180
181 ptr += 6;
182
183 /* Get variables from the GIF screen descriptor */
184
185 ch = NEXTBYTE;
186 RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */
187 ch = NEXTBYTE;
188 RHeight = ch + 0x100 * NEXTBYTE;
189
190 if (Verbose)
191 mfprintf(stderr, "screen dims: %dx%d.\n", RWidth, RHeight);
192
193 ch = NEXTBYTE;
194 HasColormap = ((ch & COLORMAPMASK) ? 1 : 0);
195
196 BitsPerPixel = (ch & 7) + 1;
197 numcols = ColorMapSize = 1 << BitsPerPixel;
198 BitMask = ColorMapSize - 1;
199
200 Background = NEXTBYTE; /* background color... not used. */
201
202 if (NEXTBYTE) /* supposed to be NULL */
203 gSystem->Error("corrupt GIF file (bad screen descriptor)",0);
204
205 /* Read in global colormap. */
206
207 if (HasColormap) {
208 if (Verbose)
209 mfprintf(stderr, "%s is %dx%d, %d bits per pixel, (%d colors).\n",
210 fname, RWidth,RHeight,BitsPerPixel, ColorMapSize);
211
212 for (i = 0; i < ColorMapSize; i++) {
213 Red[i] = NEXTBYTE;
214 Green[i] = NEXTBYTE;
215 Blue[i] = NEXTBYTE;
216 used[i] = 0;
217 }
218
219 numused = 0;
220 } /* else no colormap in GIF file */
221
222 /* look for image separator */
223
224 for (ch = NEXTBYTE ; ch != IMAGESEP ; ch = NEXTBYTE) {
225 i = ch;
226 mfprintf(stderr, "EXTENSION CHARACTER: %x\n", i);
227 if (ch != START_EXTENSION)
228 gSystem->Error("corrupt GIF89a file",0);
229
230 /* handle image extensions */
231 switch (ch = NEXTBYTE) {
232 case GRAPHIC_EXT:
233 ch = NEXTBYTE;
234 if (ptr[0] & 0x1) {
235 transparency = ptr[3]; /* transparent color index */
236 mfprintf(stderr, "transparency index: %i\n", transparency);
237 }
238 ptr += ch;
239 break;
240 case PLAINTEXT_EXT:
241 break;
242 case APPLICATION_EXT:
243 break;
244 case COMMENT_EXT:
245 break;
246 default:
247 gSystem->Error("invalid GIF89 extension",0);
248 }
249
250 while ((ch = NEXTBYTE))
251 ptr += ch;
252 }
253
254 /* Now read in values from the image descriptor */
255
256 ch = NEXTBYTE;
257 LeftOfs = ch + 0x100 * NEXTBYTE;
258 ch = NEXTBYTE;
259 TopOfs = ch + 0x100 * NEXTBYTE;
260 ch = NEXTBYTE;
261 Width = ch + 0x100 * NEXTBYTE;
262 ch = NEXTBYTE;
263 Height = ch + 0x100 * NEXTBYTE;
264 Interlace = ((NEXTBYTE & INTERLACEMASK) ? 1 : 0);
265
266 if (Verbose)
267 mfprintf(stderr, "Reading a %d by %d %sinterlaced image...",
268 Width, Height, (Interlace) ? "" : "non-");
269
270 gfile = new_graphic_file();
271 gfile->palette = (RGBcolor *)wtmalloc(sizeof(RGBcolor) * ColorMapSize);
272 for (i = 0; i < ColorMapSize; i++) {
273 gfile->palette[i].red = Red[i];
274 gfile->palette[i].green = Green[i];
275 gfile->palette[i].blue = Blue[i];
276 }
277 gfile->bitmap = (unsigned char *)wtmalloc(Width * Height);
278 gfile->type = gfPaletted;
279 gfile->width = Width;
280 gfile->height = Height;
281 gfile->transparent_entry = transparency;
282
283 /* Note that I ignore the possible existence of a local color map.
284 * I'm told there aren't many files around that use them, and the spec
285 * says it's defined for future use. This could lead to an gApplication->system->Error
286 * reading some files.
287 */
288
289 /* Start reading the raster data. First we get the intial code size
290 * and compute decompressor constant values, based on this code size.
291 */
292
293 CodeSize = NEXTBYTE;
294 ClearCode = (1 << CodeSize);
295 EOFCode = ClearCode + 1;
296 FreeCode = FirstFree = ClearCode + 2;
297
298 /* The GIF spec has it that the code size is the code size used to
299 * compute the above values is the code size given in the file, but the
300 * code size used in compression/decompression is the code size given in
301 * the file plus one. (thus the ++).
302 */
303
304 CodeSize++;
305 InitCodeSize = CodeSize;
306 MaxCode = (1 << CodeSize);
307 ReadMask = MaxCode - 1;
308
309 /* Read the raster data. Here we just transpose it from the GIF array
310 * to the Raster array, turning it from a series of blocks into one long
311 * data stream, which makes life much easier for ReadCode().
312 */
313
314 ptr1 = Raster;
315 do {
316 ch = ch1 = NEXTBYTE;
317 while (ch--) *ptr1++ = NEXTBYTE;
318 if ((ptr1 - Raster) > filesize)
319 gSystem->Error("corrupt GIF file (unblock)",0);
320 } while(ch1);
321
322 free(RawGIF); /* We're done with the raw data now... */
323
324 if (Verbose) {
325 mfprintf(stderr, "done.\n");
326 mfprintf(stderr, "Decompressing...");
327 }
328
329 Image = gfile->bitmap;
330 BytesPerScanline = Width;
331
332
333 /* Decompress the file, continuing until you see the GIF EOF code.
334 * One obvious enhancement is to add checking for corrupt files here.
335 */
336
337 Code = ReadCode();
338 while (Code != EOFCode) {
339
340 /* Clear code sets everything back to its initial value, then reads the
341 * immediately subsequent code as uncompressed data.
342 */
343
344 if (Code == ClearCode) {
345 CodeSize = InitCodeSize;
346 MaxCode = (1 << CodeSize);
347 ReadMask = MaxCode - 1;
348 FreeCode = FirstFree;
349 CurCode = OldCode = Code = ReadCode();
350 FinChar = CurCode & BitMask;
351 AddToPixel(FinChar);
352 }
353 else {
354
355 /* If not a clear code, then must be data: save same as CurCode and InCode */
356
357 CurCode = InCode = Code;
358
359 /* If greater or equal to FreeCode, not in the hash table yet;
360 * repeat the last character decoded
361 */
362
363 if (CurCode >= FreeCode) {
364 CurCode = OldCode;
365 OutCode[OutCount++] = FinChar;
366 }
367
368 /* Unless this code is raw data, pursue the chain pointed to by CurCode
369 * through the hash table to its end; each code in the chain puts its
370 * associated output code on the output queue.
371 */
372
373 while (CurCode > BitMask) {
374 if (OutCount > 1024) {
375 gSystem->Error("Corrupt GIF file (OutCount)!", 0);
376 // mfprintf(stderr,"\nCorrupt GIF file (OutCount)!\n");
377 // _exit(-1); /* calling 'exit(-1)' dumps core, so I don't */
378 }
379 OutCode[OutCount++] = Suffix[CurCode];
380 CurCode = Prefix[CurCode];
381 }
382
383 /* The last code in the chain is treated as raw data. */
384
385 FinChar = CurCode & BitMask;
386 OutCode[OutCount++] = FinChar;
387
388 /* Now we put the data out to the Output routine.
389 * It's been stacked LIFO, so deal with it that way...
390 */
391
392 for (i = OutCount - 1; i >= 0; i--)
393 AddToPixel(OutCode[i]);
394 OutCount = 0;
395
396 /* Build the hash table on-the-fly. No table is stored in the file. */
397
398 Prefix[FreeCode] = OldCode;
399 Suffix[FreeCode] = FinChar;
400 OldCode = InCode;
401
402 /* Point to the next slot in the table. If we exceed the current
403 * MaxCode value, increment the code size unless it's already 12. If it
404 * is, do nothing: the next code decompressed better be CLEAR
405 */
406
407 FreeCode++;
408 if (FreeCode >= MaxCode) {
409 if (CodeSize < 12) {
410 CodeSize++;
411 MaxCode *= 2;
412 ReadMask = (1 << CodeSize) - 1;
413 }
414 }
415 }
416 Code = ReadCode();
417 }
418
419 free(Raster);
420
421 if (Verbose)
422 mfprintf(stderr, "done.\n");
423 //else
424 //mfprintf(stderr,"(of which %d are used)\n",numused);
425
426
427 return gfile;
428 }
429
430
431 /* Fetch the next code from the raster data stream. The codes can be
432 * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
433 * maintain our location in the Raster array as a BIT Offset. We compute
434 * the byte Offset into the raster array by dividing this by 8, pick up
435 * three bytes, compute the bit Offset into our 24-bit chunk, shift to
436 * bring the desired code to the bottom, then mask it off and return it.
437 */
438 int
439 ReadCode( void )
440 {
441 int RawCode, ByteOffset;
442
443 ByteOffset = BitOffset / 8;
444 RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
445
446 if (CodeSize >= 8)
447 RawCode += (0x10000 * Raster[ByteOffset + 2]);
448
449 RawCode >>= (BitOffset % 8);
450 BitOffset += CodeSize;
451
452 return(RawCode & ReadMask);
453 }
454
455 void
456 AddToPixel(byte Index)
457 {
458 if (YC<Height)
459 *(Image + YC * BytesPerScanline + XC) = Index;
460
461 if (!used[Index]) { used[Index]=1; numused++; }
462
463 /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
464
465 if (++XC == Width) {
466
467 /* If a non-interlaced picture, just increment YC to the next scan line.
468 * If it's interlaced, deal with the interlace as described in the GIF
469 * spec. Put the decoded scan line out to the screen if we haven't gone
470 * past the bottom of it
471 */
472
473 XC = 0;
474 if (!Interlace) YC++;
475 else {
476 switch (Pass) {
477 case 0:
478 YC += 8;
479 if (YC >= Height) {
480 Pass++;
481 YC = 4;
482 }
483 break;
484 case 1:
485 YC += 8;
486 if (YC >= Height) {
487 Pass++;
488 YC = 2;
489 }
490 break;
491 case 2:
492 YC += 4;
493 if (YC >= Height) {
494 Pass++;
495 YC = 1;
496 }
497 break;
498 case 3:
499 YC += 2;
500 break;
501 default:
502 break;
503 }
504 }
505 }
506 }
507
0
1 /*
2 ** MacWT -- a 3d game engine for the Macintosh
3 ** © 1995, Bill Hayden and Nikol Software
4 **
5 ** On the Internet:
6 ** bmoc1@aol.com (my personal address)
7 ** nikolsw@grove.ufl.edu (my school address)
8 ** MacWT anonymous FTP site: ftp.circa.ufl.edu/pub/software/ufmug/mirrors/LocalSW/Hayden/
9 ** http://grove.ufl.edu:80/~nikolsw (my WWW page, containing MacWT info)
10 **
11 ** based on wt, by Chris Laurel (claurel@mr.net)
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18
19
20 #include <stdio.h>
21 #include <string.h>
22 //#include "wt.h"
23 //#include "gApplication->system->Error.h"
24 //#include "wtmem.h"
25 //#include "color.h"
26 #include "Graphfil.hpp"
27 #include "Appl.hpp"
28
29 extern CApplication *gApplication;
30 extern CSystem *gSystem;
31
32 #define mfputc fputc
33 #define mfgetc fgetc
34 #define mfopen fopen
35 #define mfclose fclose
36 #define mfread fread
37 #define mfseek fseek
38 #define mftell ftell
39 #define mrewind rewind
40 #define mfprintf fprintf
41
42 /* MAGIC_LENGTH must be the length of the longest MAGIC string. */
43 #define MAGIC_LENGTH 5
44 #define GIF_MAGIC "GIF87"
45 #define GIF89_MAGIC "GIF89"
46
47
48 extern Graphic_file *LoadGIF(FILE *fp, char *filename);
49
50 static Graphic_file_format check_format(FILE *fp, char *filename);
51
52
53 Graphic_file *new_graphic_file()
54 {
55 Graphic_file *gf = (Graphic_file *)wtmalloc(sizeof(Graphic_file));
56
57 gf->transparent_entry = -1;
58
59 return gf;
60 }
61
62
63 void free_graphic_file(Graphic_file *gfile)
64 {
65 if (gfile != NULL) {
66 if (gfile->palette != NULL)
67 wtfree(gfile->palette);
68 if (gfile->bitmap != NULL)
69 wtfree(gfile->bitmap);
70 }
71 wtfree(gfile);
72 }
73
74
75 /* Return 0 if the pixel is transparent, 1 if it is opaque. In any
76 ** case, stuff dest with the pixel RGB value.
77 */
78 short graphic_file_pixel(Graphic_file *gfile, int x, int y, RGBcolor *rgb)
79 {
80 if (gfile->type == gfPaletted)
81 {
82 int index;
83
84 index = gfile->bitmap[y * gfile->width + x];
85 if (index == gfile->transparent_entry)
86 return 0;
87 else
88 {
89 *rgb = gfile->palette[index];
90 return 1;
91 }
92 }
93 else
94 {
95 unsigned char *pixel = gfile->bitmap + (y * gfile->width + x) * 3;
96
97 rgb->red = *pixel++;
98 rgb->green = *pixel++;
99 rgb->blue = *pixel;
100
101 /* For now, let pure cyan be the transparent color for 1 color images. */
102 if (rgb->red == 0 && rgb->green == 255 && rgb->blue == 255)
103 return 0;
104 else
105 return 1;
106 }
107 }
108
109
110 Graphic_file *read_graphic_file(char *filename)
111 {
112 FILE *fp;
113 Graphic_file_format format;
114 Graphic_file *gfile = 0L;
115
116
117 if ((fp = mfopen(filename, "rb")) == NULL)
118 gSystem->Error("Could not open texture", 0);
119
120 format = check_format(fp, filename);
121 mrewind(fp);
122
123 switch (format)
124 {
125 case formatGIF89:
126 case formatGIF87:
127 gfile = LoadGIF(fp, filename);
128 break;
129
130 case formatUnknown:
131 gSystem->Error("Unknown graphic file format.", 0);
132 break;
133
134 default:
135 gSystem->Error("The graphic file reading code is really broken.", 0);
136 break;
137 }
138
139 if (gfile == NULL)
140 gSystem->Error("gApplication->system->Error reading texture", 0);
141
142 mfclose(fp);
143
144 return gfile;
145 }
146
147
148 static Graphic_file_format check_format(FILE *fp, char *filename)
149 {
150 char magic[MAGIC_LENGTH];
151
152 #if __MWERKS__ || __THINKC__
153 // to read PICT or PICTR files, which are further along on the
154 // evolutionary chain than to need MagicCookies or the like.
155 mfread(magic, 1, MAGIC_LENGTH, fp);
156 #else
157 if (mfread(magic, 1, MAGIC_LENGTH, fp) != MAGIC_LENGTH)
158 gSystem->Error("gApplication->system->Error reading texture", 0);
159 #endif
160
161 if (strncmp(magic, GIF_MAGIC, sizeof(GIF_MAGIC) - 1) == 0)
162 return formatGIF87;
163 else if (strncmp(magic, GIF89_MAGIC, sizeof(GIF89_MAGIC) - 1) == 0)
164 return formatGIF89;
165 else
166 return formatPICTR;
167
168 // return formatUnknown;
169 }
0 /*
1 ** wt -- a 3d game engine
2 **
3 ** Copyright (C) 1994 by Chris Laurel
4 ** email: claurel@mr.net
5 ** snail mail: Chris Laurel, 5700 W Lake St #208, St. Louis Park, MN 55416
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 2 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 #include "AmpHead.hpp"
22 #include "System.hpp"
23
24 #ifndef __GRAPHFIL__
25 #define __GRAPHFIL__
26
27 typedef enum { formatGIF87, formatGIF89, formatPPM, formatPICTR, formatUnknown }
28 Graphic_file_format;
29
30 typedef enum { gfTrueColor, gfPaletted } Graphic_file_type;
31
32 typedef struct {
33 Graphic_file_type type;
34 int height, width;
35 int palette_entries;
36 long transparent_entry;
37 RGBcolor *palette;
38 unsigned char *bitmap;
39 } Graphic_file;
40
41 void *wtmalloc(size_t size);
42 void *wtrealloc(void *v, size_t size);
43 void wtfree(void *v);
44 void FatalerFehler(char *errorStr, long error);
45
46
47 extern Graphic_file *new_graphic_file(void);
48 extern void free_graphic_file(Graphic_file *gfile);
49 extern short graphic_file_pixel(Graphic_file *gfile, int x, int y, RGBcolor *rgb);
50 extern Graphic_file *read_graphic_file(char *filename);
51
52 Graphic_file *LoadPPM(FILE *fp, char *filename);
53 Graphic_file *LoadGIF(FILE *fp, char *fname );
54 Graphic_file *LoadPICTR(FILE *fp, char *fname );
55
56 #endif
0 #include "Gui.hpp"
1 #include "AmpHead.hpp"
2 #include "ConstVal.hpp"
3 #include "ShapeLd.hpp"
4 #include "Appl.hpp"
5 #include "Clut.hpp"
6 #include "SndSys.hpp"
7
8 extern CSystem *gSystem;
9 extern tConstValues *gConst;
10 extern CShapeManager *gShapeManager;
11 extern CLevel *gLevel;
12 extern CClutManager *gClutManager;
13 extern tConfigData *gConfigData;
14 extern CSoundSystem *gSoundSystem;
15
16 tGUIConstants *gGUIConst;
17
18 const short kHealthCurveY[10] = {0, 48, -48, 15, -15, 25, -15, 0, 0, 0};
19 const short kHealthCurveX = 5;
20 const double kOxygenCurveY = 25.0;
21 const double kOxygenCurveX = 2.0;
22
23 short kMunitionStatusColors[3] = {220, 100, 220};
24
25 const short kKeyHitDelay = 300;
26
27 const short kTitleTabulator = -30;
28 const short kNameTabulator1 = 30;
29 const short kNameTabulator2 = 20;
30
31 double XLineCut(double r0x, double r0y, double r1x, double r1y, double x);
32 void SwapBlackWhite(Graphic_file *gf);
33
34 CGUI::CGUI(CGraphicSurface *curMainScreen)
35 {
36 tRect position;
37
38 LoadMessages();
39
40 guis = read_graphic_file(gSystem->QualifyDataDir(gConst->kFileGUIs)); // by LL
41 if (!guis) gSystem->Error("Error while reading the file kFileGUIs", 0);
42 SwapBlackWhite(guis);
43
44 healthPanel = new CGraphicSurface(gGUIConst->kHealthPanelWidth, gGUIConst->kHealthPanelHeight);
45 oxygenPanel = new CGraphicSurface(gGUIConst->kOxygenPanelWidth, gGUIConst->kOxygenPanelHeight);
46 weaponPanel = new CGraphicSurface(gGUIConst->kWeaponPanelWidth, gGUIConst->kWeaponPanelHeight);
47 backgroundPanel = new CGraphicSurface(kUserPlaneWidth, kGamePlaneHeight);
48 if (!(healthPanel && oxygenPanel && weaponPanel && backgroundPanel)) gSystem->Error("Cannot allocate panels", 0);
49
50 currentMainScreen = curMainScreen;
51 currentMessage = 0L;
52 msgDisplayTime = 0;
53
54 position.left = kGUIsPositions[3][0];
55 position.top = kGUIsPositions[3][1];
56 position.right = kGUIsPositions[3][2];
57 position.bottom = kGUIsPositions[3][3];
58 backgroundPanel->InsertGraphic(0L, guis, &position);
59 backgroundPanel->PaintGraphic(0, 0, 0, kShapemodusNormal);
60 backgroundPanel->FlipToScreen(kGamePlaneWidth, 0);
61
62 position.left = kGUIsPositions[0][0];
63 position.top = kGUIsPositions[0][1];
64 position.right = kGUIsPositions[0][2];
65 position.bottom = kGUIsPositions[0][3];
66 healthPanel->InsertGraphic(0L, guis, &position);
67
68 position.left = kGUIsPositions[1][0];
69 position.top = kGUIsPositions[1][1];
70 position.right = kGUIsPositions[1][2];
71 position.bottom = kGUIsPositions[1][3];
72 oxygenPanel->InsertGraphic(0L, guis, &position);
73
74 for (short n = 0; n <= 7; n ++) {
75 position.left = kGUIsPositions[2][0];
76 position.top = kGUIsPositions[2][1] + n * (kGUIsPositions[2][3]);
77 position.right = kGUIsPositions[2][2];
78 position.bottom = kGUIsPositions[2][3] + n * (kGUIsPositions[2][3]);
79 weaponPanel->InsertGraphic(0L, guis, &position);
80 }
81
82 position.left = kGUIsPositions[4][0];
83 position.top = kGUIsPositions[4][1];
84 position.right = kGUIsPositions[4][2];
85 position.bottom = kGUIsPositions[4][3];
86 curMainScreen->InsertGraphic(0L, guis, &position);
87
88 position.left = kGUIsPositions[5][0];
89 position.top = kGUIsPositions[5][1];
90 position.right = kGUIsPositions[5][2];
91 position.bottom = kGUIsPositions[5][3];
92 curMainScreen->InsertGraphic(0L, guis, &position);
93
94 lastHealthPanelRefresh = 0;
95 healthCurveStart = 0;
96 lastOxygenPanelRefresh = 0;
97 oxygenCurveStart = 0;
98 }
99
100 CGUI::~CGUI()
101 {
102 free_graphic_file(guis);
103 delete healthPanel;
104 delete oxygenPanel;
105 delete backgroundPanel;
106 delete messages;
107 }
108
109 void CGUI::SetFocus(CPlayer *focus)
110 {
111 player = focus;
112 }
113
114
115 void CGUI::Update()
116 {
117 long time = gSystem->GetTicks();
118 if (player->typeID & kPlayer && lastHealthPanelRefresh < time) {
119 DrawHealthPanel();
120 lastHealthPanelRefresh = time + gGUIConst->kHealthPanelRefreshRate;
121 }
122 if (player->typeID & kPlayer && lastOxygenPanelRefresh < time) {
123 DrawOxygenPanel();
124 lastOxygenPanelRefresh = time + gGUIConst->kOxygenPanelRefreshRate;
125 }
126 }
127
128 void CGUI::UpdateWeapon()
129 {
130 short drawStart = gGUIConst->kWeaponPanelHeight - player->weapons[player->currentWeapon]->munition * gGUIConst->kWeaponPanelHeight / player->weapons[player->currentWeapon]->info->munition;
131 short drawEnd = gGUIConst->kWeaponPanelHeight;
132 short color;
133
134 weaponPanel->PaintGraphic(player->currentWeapon, 0, 0, kShapemodusNormal);
135
136 for (short n = drawStart; n < drawEnd; n ++) {
137 color = gClutManager->FindClosestColor(kMunitionStatusColors[0] - kMunitionStatusColors[0] * n / 100,
138 kMunitionStatusColors[1] - kMunitionStatusColors[1] * n / 100,
139 kMunitionStatusColors[2] - kMunitionStatusColors[2] * n / 100);
140
141 weaponPanel->DrawAntialiasedLine(gGUIConst->kWeaponPanelWidth - gGUIConst->kWeaponStatusWidth, n, gGUIConst->kWeaponPanelWidth -1, n, (unsigned char)color, kShapemodusNormal);
142 }
143 weaponPanel->FlipToScreen(gGUIConst->kWeaponPanelPosX, gGUIConst->kWeaponPanelPosY);
144 }
145
146 #define ADDHEALTH(curvePoint) curvePoint == 9 ? 0 : curvePoint +1
147 #define SUBHEALTH(curvePoint) curvePoint == 0 ? 9 : curvePoint -1
148
149 // ---------------------------------------------------
150 void CGUI::DrawHealthPanel()
151 // Draws the health curve panel and blits it to the screen
152 {
153 double ptx, pty, cury1, cury2;
154 short curvePoint = 0;
155 double fak;
156
157 healthCurveStart --;
158 if (healthCurveStart < -gGUIConst->kHealthPanelWidth) healthCurveStart = 0;
159 ptx = healthCurveStart;
160
161 //healthPanel->PaintRect(0, 0, kHealthPanelWidth, kHealthPanelHeight, kBlackColor);
162 healthPanel->PaintGraphic(0, 0, 0, kShapemodusNormal);
163
164 while (ptx < gGUIConst->kHealthPanelWidth) {
165 fak = player->health <= 0 ? SHRT_MAX : (double)player->info->energy / (double)player->health;
166 cury1 = kHealthCurveY[curvePoint] / fak;
167 cury2 = kHealthCurveY[ADDHEALTH(curvePoint)] / fak;
168
169 if (ptx <= 0 && ptx + kHealthCurveX > 0) {
170 pty = XLineCut(ptx, cury1, ptx + kHealthCurveX, cury2, 0);
171 healthPanel->DrawAntialiasedLine(0, pty + gGUIConst->kHealthPanelHeight / 2,
172 ptx + kHealthCurveX,
173 cury2 + gGUIConst->kHealthPanelHeight / 2,
174 gConst->kHealthPanelColor, kShapemodusNormal);
175
176 }else if (ptx < gGUIConst->kHealthPanelWidth && ptx + kHealthCurveX >= gGUIConst->kHealthPanelWidth) {
177 pty = XLineCut(ptx, cury1, ptx + kHealthCurveX, cury2, gGUIConst->kHealthPanelWidth);
178 healthPanel->DrawAntialiasedLine(ptx, cury1 + gGUIConst->kHealthPanelHeight / 2,
179 gGUIConst->kHealthPanelWidth, pty + gGUIConst->kHealthPanelHeight / 2,
180 gConst->kHealthPanelColor, kShapemodusNormal);
181
182 }else if (ptx > 0 && ptx + kHealthCurveX < gGUIConst->kHealthPanelWidth) {
183 healthPanel->DrawAntialiasedLine(ptx, cury1 + gGUIConst->kHealthPanelHeight / 2,
184 ptx + kHealthCurveX, cury2 + gGUIConst->kHealthPanelHeight / 2,
185 gConst->kHealthPanelColor, kShapemodusNormal);
186 }
187 curvePoint = ADDHEALTH(curvePoint);
188 ptx += kHealthCurveX;
189 }
190 healthPanel->FlipToScreen(gGUIConst->kHealthPanelPosX, gGUIConst->kHealthPanelPosY);
191 }
192
193
194 void CGUI::DrawOxygenPanel()
195 {
196 double ptx, pty1, pty2;
197 double oxygenFactor = (double)player->oxygen / (double)gConst->kInitialOxygen;
198
199 if (oxygenFactor > 1.0) oxygenFactor = 1.0;
200
201 //oxygenPanel->PaintRect(0, 0, kOxygenPanelWidth, kOxygenPanelHeight, kBlackColor);
202 oxygenPanel->PaintGraphic(0, 0, 0, kShapemodusNormal);
203
204 oxygenCurveStart += 10.0 / 180.0 * 3.141;
205 ptx = oxygenCurveStart;
206
207 pty1 = kOxygenCurveY * sin(oxygenCurveStart);
208 for (ptx = 0; ptx < 100; ptx += kOxygenCurveX) {
209
210 pty2 = kOxygenCurveY * oxygenFactor * sin(ptx / 180 * 3.141 * 5.0 + oxygenCurveStart) +
211 kOxygenCurveY * oxygenFactor / 1.5 * cos(ptx / 180 * 3.141 * 15.0 + oxygenCurveStart * 3.0);
212 oxygenPanel->DrawAntialiasedLine(ptx, pty1 + gGUIConst->kOxygenPanelHeight / 2, ptx + kOxygenCurveX, pty2 + gGUIConst->kOxygenPanelHeight / 2, gConst->kOxygenPanelColor, kShapemodusNormal);
213 pty1 = pty2;
214 }
215
216 oxygenPanel->FlipToScreen(gGUIConst->kOxygenPanelPosX, gGUIConst->kOxygenPanelPosY);
217 }
218
219
220
221 /* XLineCut
222
223 Hinein: r0x, r0y: Anfangskoordinaten einer Linie
224 r1x, r1y: Endkoordinaten einer Linie
225 x: X-Abst einer zur Y-Achse parallelen Gerade
226
227 Hinaus: Y-Abst des Schnittpunktes der Linie mit der Geraden
228 */
229 double XLineCut(double r0x, double r0y, double r1x, double r1y, double x)
230 {
231 return (r0y + ((x - r0x) * (r1y - r0y)) / (r1x - r0x));
232 }
233
234
235
236 short CGUI::ProcessKeyStrokes()
237 {
238 //gSystem->ProcessEvents();
239
240 if (lastKeyHit < gSystem->GetTicks() && gSystem->KeyPressed(kKeyUp) && currentNumOfItems) {
241 lastKeyHit = gSystem->GetTicks() + gGUIConst->kKeyHitDelay;
242 lastItem = currentItem;
243 currentItem --;
244 if (currentItem < 0) currentItem = currentNumOfItems;
245 gSoundSystem->Play(gSoundSystem->selMenu, player->xm, player->ym);
246
247 return kKeyUp;
248 }
249
250 if (lastKeyHit < gSystem->GetTicks() && gSystem->KeyPressed(kKeyDown) && currentNumOfItems) {
251 lastKeyHit = gSystem->GetTicks() + gGUIConst->kKeyHitDelay;
252 lastItem = currentItem;
253 currentItem ++;
254 if (currentItem > currentNumOfItems) currentItem = 0;
255 gSoundSystem->Play(gSoundSystem->selMenu, player->xm, player->ym);
256
257 return kKeyDown;
258 }
259
260 if (lastKeyHit < gSystem->GetTicks() && gSystem->KeyPressed(kKeyReturn) && currentNumOfItems) {
261 lastKeyHit = gSystem->GetTicks() + gGUIConst->kKeyHitDelay;
262 gSoundSystem->Play(gSoundSystem->openMenu, player->xm, player->ym);
263 return kKeyReturn;
264 }
265 if (lastKeyHit < gSystem->GetTicks() && gSystem->KeyPressed(kKeyEscape)) {
266 lastKeyHit = gSystem->GetTicks() + gGUIConst->kKeyHitDelay;
267 gSoundSystem->Play(gSoundSystem->openMenu, player->xm, player->ym);
268 return kKeyEscape;
269 }
270 return 0;
271 }
272
273
274 short CGUI::NewGamePageEvents()
275 {
276 switch (currentItem) {
277 case 0: // New Game
278 return kCmdNewGameLevel1;
279 break;
280
281 case 1:
282 return kCmdNewGameLevel2;
283 break;
284
285 case 2:
286 return kCmdNewGameLevel3;
287 break;
288
289 case 3:
290 return kCmdNewGameLevel4;
291 break;
292
293 default:
294 return kNoCmdEvent;
295 break;
296 }
297 }
298
299 short CGUI::QuitPageEvents()
300 {
301 switch (currentItem) {
302 case 0:
303 return kCmdQuit;
304 break;
305 case 1:
306 OnOpenMainPage();
307 return kNoCmdEvent;
308 default:
309 return kNoCmdEvent;
310 }
311 }
312
313 short CGUI::MainPageEvents()
314 {
315 switch (currentItem) {
316 case 0: // New Game
317 OnOpenNewGamePage();
318 return kNoCmdEvent;
319 break;
320
321 case 1:
322 OnOpenLoadPage(kLoadGamePage);
323 return kNoCmdEvent;
324 break;
325
326 case 2:
327 OnOpenHelpPage();
328 return kNoCmdEvent;
329 break;
330 case 3:
331 OnOpenCreditsPage();
332 return kNoCmdEvent;
333 break;
334
335 case 4:
336 OnOpenQuitPage();
337 return kNoCmdEvent;
338 break;
339
340 default:
341 return kNoCmdEvent;
342 break;
343 }
344 }
345
346
347 short CGUI::LoadGamePageEvents()
348 {
349 return (page == kLoadGamePage ? kLoadGameSlot0 + currentItem : kSaveGameSlot0 + currentItem);
350 }
351
352
353 short CGUI::RunUserInterface(short whichPage)
354 {
355 short command = kNoCmdEvent;
356
357 if (lastKeyHit > gSystem->GetTicks()) return kCmdNoCommand;
358 lastKeyHit = gSystem->GetTicks() + gGUIConst->kKeyHitDelay;
359
360 gSoundSystem->Play(gSoundSystem->entrMenu, player->xm, player->ym);
361
362 switch (whichPage) {
363 case kMainPage:
364 OnOpenMainPage();
365 break;
366 case kNewGamePage:
367 OnOpenNewGamePage();
368 break;
369 case kLoadGamePage:
370 case kSaveGamePage:
371 OnOpenLoadPage(whichPage);
372 break;
373 case kHelpPage:
374 OnOpenHelpPage();
375 break;
376 case kCreditPage:
377 OnOpenCreditsPage();
378 break;
379 case kQuitPage:
380 OnOpenQuitPage();
381 break;
382 }
383
384 while (command == kNoCmdEvent) {
385
386 switch (ProcessKeyStrokes()) {
387 case kKeyEscape:
388 if (page != kMainPage) OnOpenMainPage(); else command = kCmdNoCommand;
389 break;
390
391 case kKeyReturn:
392 switch (page) {
393 case kMainPage:
394 command = MainPageEvents();
395 break;
396 case kNewGamePage:
397 command = NewGamePageEvents();
398 break;
399 case kLoadGamePage:
400 case kSaveGamePage:
401 command = LoadGamePageEvents();
402 break;
403 case kQuitPage:
404 command = QuitPageEvents();
405 break;
406 }
407 break;
408 }
409
410
411 SelectMenuItem();
412 currentMainScreen->FlipToScreen(0, 0);
413 }
414
415 return command;
416 }
417 void CGUI::OnOpenMainPage()
418 {
419 gLevel->PaintLevel();
420
421 currentMainScreen->PaintRect(gGUIConst->kUserMenuPosX, gGUIConst->kUserMenuPosY, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuWidth, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuHeight, kBlackColor, kShapemodusTransparent2);
422
423 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY, gGUIConst->kUserMainPageTitle, kShapemodusLava);
424
425 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 1 * gGUIConst->kUserMenuEntryDY, gGUIConst->kUserMenuEntry1, kShapemodusNormal);
426 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 2 * gGUIConst->kUserMenuEntryDY, gGUIConst->kUserMenuEntry2, kShapemodusNormal);
427 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 3 * gGUIConst->kUserMenuEntryDY, gGUIConst->kUserMenuEntry3, kShapemodusNormal);
428 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 4 * gGUIConst->kUserMenuEntryDY, gGUIConst->kUserMenuEntry4, kShapemodusNormal);
429 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 5 * gGUIConst->kUserMenuEntryDY, gGUIConst->kUserMenuEntry5, kShapemodusNormal);
430
431 currentItem = lastItem = 0;
432 currentNumOfItems = 4;
433 page = kMainPage;
434 currentItemStart = gGUIConst->kUserMenuEntryPosY + gGUIConst->kUserMenuEntryDY;
435 currentEntryDY = gGUIConst->kUserMenuEntryDY;
436
437 SelectMenuItem();
438 }
439
440 void CGUI::OnOpenNewGamePage()
441 {
442 gLevel->PaintLevel();
443
444 currentMainScreen->PaintRect(gGUIConst->kUserMenuPosX, gGUIConst->kUserMenuPosY, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuWidth, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuHeight, kBlackColor, kShapemodusTransparent2);
445
446 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY, gGUIConst->kNewGamePageTitle, kShapemodusLava);
447
448 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 1 * gGUIConst->kUserMenuEntryDY, gGUIConst->kNewGameEntry1, kShapemodusNormal);
449 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 2 * gGUIConst->kUserMenuEntryDY, gGUIConst->kNewGameEntry2, kShapemodusNormal);
450 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 3 * gGUIConst->kUserMenuEntryDY, gGUIConst->kNewGameEntry3, kShapemodusNormal);
451 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 4 * gGUIConst->kUserMenuEntryDY, gGUIConst->kNewGameEntry4, kShapemodusNormal);
452
453 currentItem = 1;
454 lastItem = 0;
455 currentNumOfItems = 3;
456 page = kNewGamePage;
457 currentItemStart = gGUIConst->kUserMenuEntryPosY + gGUIConst->kUserMenuEntryDY;
458 currentEntryDY = gGUIConst->kUserMenuEntryDY;
459
460 SelectMenuItem();
461 }
462
463
464 void CGUI::OnOpenLoadPage(short whichPage)
465 {
466 short n;
467
468 gLevel->PaintLevel();
469 currentMainScreen->PaintRect(gGUIConst->kUserMenuPosX, gGUIConst->kUserMenuPosY, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuWidth, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuHeight, kBlackColor, kShapemodusTransparent2);
470
471 for (n = 0; n < kNumOfSaveGameSlots; n ++) {
472 char *filename = gSystem->QualifyHomeDir(gGUIConst->kSavedGames[n]);
473 gLevel->GetSavedGameTitle(filename, sgTitles[n]); // by LL
474 delete [] filename;
475 }
476
477 if (whichPage == kSaveGamePage)
478 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 0 * gGUIConst->kUserMenuEntryDY, gGUIConst->kSavePageTitle, kShapemodusLava);
479 else
480 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 0 * gGUIConst->kUserMenuEntryDY, gGUIConst->kLoadPageTitle, kShapemodusLava);
481
482 for (n = 0; n < kNumOfSaveGameSlots; n ++) {
483 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + (n + 1) * gGUIConst->kUserMenuEntryDY, sgTitles[n], kShapemodusNormal);
484 }
485 currentItem = lastItem = 0;
486 currentNumOfItems = 5;
487 page = whichPage;
488 currentItemStart = gGUIConst->kUserMenuEntryPosY + gGUIConst->kUserMenuEntryDY;
489 currentEntryDY = gGUIConst->kUserMenuEntryDY;
490
491 SelectMenuItem();
492 }
493
494 void CGUI::OnOpenHelpPage()
495 {
496 gLevel->PaintLevel();
497 currentMainScreen->PaintRect(gGUIConst->kUserMenuPosX, gGUIConst->kUserMenuPosY, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuWidth, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuHeight, kBlackColor, kShapemodusTransparent2);
498
499 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 0 * gGUIConst->kUserMenuEntryDY, gGUIConst->kHelpPageTitle, kShapemodusLava);
500
501 currentMainScreen->PaintGraphic(1, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 2 * gGUIConst->kCreditsEntryDY, kShapemodusTransparent2);
502
503 currentItem = lastItem = -1;
504 currentNumOfItems = 0;
505 currentItemStart = gGUIConst->kUserMenuPosY;
506 currentEntryDY = gGUIConst->kHelpMenuEntryDY;
507
508 page = kHelpPage;
509 }
510
511 void CGUI::OnOpenCreditsPage()
512 {
513 gLevel->PaintLevel();
514
515 currentMainScreen->PaintRect(gGUIConst->kUserMenuPosX, gGUIConst->kUserMenuPosY, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuWidth, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuHeight, kBlackColor, kShapemodusTransparent2);
516
517 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 0 * gGUIConst->kCreditsEntryDY, gGUIConst->kCreditsPageTitle, kShapemodusLava);
518
519 currentMainScreen->PaintGraphic(0, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 2 * gGUIConst->kCreditsEntryDY, kShapemodusTransparent2);
520
521 currentItem = lastItem = 1;
522 currentNumOfItems = 0;
523 currentItemStart = gGUIConst->kUserMenuEntryPosY + 7 * gGUIConst->kCreditsEntryDY;
524 currentEntryDY = gGUIConst->kCreditsEntryDY;
525 page = kCreditPage;
526 }
527
528 void CGUI::OnOpenQuitPage()
529 {
530 gLevel->PaintLevel();
531
532 currentMainScreen->PaintRect(gGUIConst->kUserMenuPosX, gGUIConst->kUserMenuPosY, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuWidth, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuHeight, kBlackColor, kShapemodusTransparent2);
533
534 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX + kTitleTabulator, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 0 * gGUIConst->kCreditsEntryDY, gGUIConst->kCreditsPageTitle, kShapemodusLava);
535
536 currentMainScreen->PaintGraphic(0, gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 2 * gGUIConst->kCreditsEntryDY, kShapemodusTransparent2);
537
538 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 8 * gGUIConst->kCreditsEntryDY, gGUIConst->kCreditsEntry4, kShapemodusNormal);
539 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + gGUIConst->kUserMenuEntryPosY + 9 * gGUIConst->kCreditsEntryDY, gGUIConst->kCreditsEntry5, kShapemodusNormal);
540
541 currentItem = lastItem = 0;
542 currentNumOfItems = 1;
543 currentItemStart = gGUIConst->kUserMenuEntryPosY + 8 * gGUIConst->kCreditsEntryDY;
544 currentEntryDY = gGUIConst->kCreditsEntryDY;
545 page = kQuitPage;
546 }
547
548 void CGUI::SelectMenuItem()
549 {
550 char *curItem;
551
552 curItem = ItemToItem(lastItem);
553 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + currentItemStart + lastItem * currentEntryDY, curItem, kShapemodusNormal);
554
555 curItem = ItemToItem(currentItem);
556 currentMainScreen->DrawString(gGUIConst->kUserMenuPosX + gGUIConst->kUserMenuEntryPosX, gGUIConst->kUserMenuPosY + currentItemStart + currentItem * currentEntryDY, curItem, kShapemodusRandom);
557 }
558
559
560 char *CGUI::ItemToItem(short item)
561 {
562 switch (page) {
563 case kMainPage:
564 switch (item) {
565 case 0: return gGUIConst->kUserMenuEntry1; break;
566 case 1: return gGUIConst->kUserMenuEntry2; break;
567 case 2: return gGUIConst->kUserMenuEntry3; break;
568 case 3: return gGUIConst->kUserMenuEntry4; break;
569 case 4: return gGUIConst->kUserMenuEntry5; break;
570 default: return gGUIConst->kUserMenuEntry1; break;
571 }
572 break;
573
574 case kNewGamePage:
575 switch (item) {
576 case 0: return gGUIConst->kNewGameEntry1; break;
577 case 1: return gGUIConst->kNewGameEntry2; break;
578 case 2: return gGUIConst->kNewGameEntry3; break;
579 case 3: return gGUIConst->kNewGameEntry4; break;
580 default: return gGUIConst->kNewGameEntry1; break;
581 }
582 break;
583
584 case kLoadGamePage:
585 case kSaveGamePage:
586 return sgTitles[item];
587 break;
588
589 case kQuitPage:
590 switch (item) {
591 case 0: return gGUIConst->kCreditsEntry4; break;
592 case 1: return gGUIConst->kCreditsEntry5; break;
593 default: return gGUIConst->kCreditsEntry5; break;
594 }
595 break;
596
597 default:
598 return 0L;
599 break;
600 }
601 }
602
603 void CGUI::DisplayInfotext(short num)
604 {
605 currentMessage = messages->generalMessages[num];
606 msgDisplayTime = gSystem->GetTicks() + gGUIConst->kInfoTextTime;
607 }
608
609
610 void CGUI::OnPickUpSomething(short what)
611 {
612 switch (what) {
613 case kItemPhiol:
614 currentMessage = messages->msgPhiol;
615 break;
616 case kItemSorcery:
617 currentMessage = messages->msgBM;
618 break;
619 case kItemBow:
620 currentMessage = messages->msgBow;
621 break;
622 case kItemScie:
623 currentMessage = messages->msgScie;
624 break;
625 case kItemHands:
626 currentMessage = messages->msgHands;
627 break;
628 case kItemBomb:
629 currentMessage = messages->msgBombs;
630 break;
631 case kItemStaff:
632 currentMessage = messages->msgStaff;
633 break;
634 case kItemPhiolmun:
635 currentMessage = messages->msgPhiolMun;
636 break;
637 case kItemSorcerymun:
638 currentMessage = messages->msgBMMun;
639 break;
640 case kItemBowmun:
641 currentMessage = messages->msgBowMun;
642 break;
643 case kItemHandsmun:
644 currentMessage = messages->msgHandsMun;
645 break;
646 case kItemBombmun:
647 currentMessage = messages->msgBombsMun;
648 break;
649 case kItemStaffmun:
650 currentMessage = messages->msgStaffMun;
651 break;
652 case kItemOxygen:
653 currentMessage = messages->msgOxygen;
654 break;
655 case kItemHelppacket:
656 currentMessage = messages->msgHealth;
657 break;
658 default:
659 currentMessage = 0L;
660 break;
661 }
662 msgDisplayTime = gSystem->GetTicks() + gGUIConst->kInfoTextTime;
663 }
664
665
666 void CGUI::DisplayMessages()
667 {
668 if (msgDisplayTime > gSystem->GetTicks() && currentMessage)
669 currentMainScreen->DrawString(gGUIConst->kInfoTextLeft, gGUIConst->kInfoTextTop, currentMessage, kShapemodusTransparent1);
670 }
671
672
673 void CGUI::ResetTicks(long ticks)
674 {
675 lastKeyHit = ticks;
676
677 lastHealthPanelRefresh = 0;
678 healthCurveStart = 0;
679 lastOxygenPanelRefresh = 0;
680 oxygenCurveStart = 0;
681 msgDisplayTime = 0;
682 }
683
684 long GetLongConstant(FILE *f, char *constName);
685 double GetDoubleConstant(FILE *f, char *constName);
686 void GetStringConstant(FILE *f, char *constName, char *buffer);
687
688 void CGUI::LoadMessages()
689 {
690 FILE *f = fopen(gSystem->QualifyDataDir(kParFileName), "r"); // by LL
691 char msgString[6] = "msgxx";
692 short n;
693
694 messages = new tMessages;
695
696 GetStringConstant(f, "msgPickedUpHealth", messages->msgHealth);
697 GetStringConstant(f, "msgPickedUpOxygen", messages->msgOxygen);
698
699 GetStringConstant(f, "msgPickedUpPhiol", messages->msgPhiol);
700 GetStringConstant(f, "msgPickedUpBM", messages->msgBM);
701 GetStringConstant(f, "msgPickedUpBow", messages->msgBow);
702 GetStringConstant(f, "msgPickedUpScie", messages->msgScie);
703 GetStringConstant(f, "msgPickedUpHands", messages->msgHands);
704 GetStringConstant(f, "msgPickedUpBombs", messages->msgBombs);
705 GetStringConstant(f, "msgPickedUpStaff", messages->msgStaff);
706
707 GetStringConstant(f, "msgPickedUpPhiolMun", messages->msgPhiolMun);
708 GetStringConstant(f, "msgPickedUpBMMun", messages->msgBMMun);
709 GetStringConstant(f, "msgPickedUpBowMun", messages->msgBowMun);
710 GetStringConstant(f, "msgPickedUpHandMun", messages->msgHandsMun);
711 GetStringConstant(f, "msgPickedUpBombMun", messages->msgBombsMun);
712 GetStringConstant(f, "msgPickedUpStaffMun", messages->msgStaffMun);
713
714 for (n = 0; n < kMaxInfotexts -1; n ++) {
715 msgString[3] = (char)(n / 10) + '0';
716 msgString[4] = (char)(n % 10) + '0';
717 GetStringConstant(f, msgString, messages->generalMessages[n]);
718 }
719
720 fclose(f);
721 }
722
723
724 void LoadGUIParameters()
725 {
726 FILE *f = fopen(gSystem->QualifyDataDir(kParFileName), "r"); // by LL
727
728 gGUIConst = new tGUIConstants;
729
730 gGUIConst->kHealthPanelHeight = GetLongConstant(f, "kHealthPanelHeight");
731 gGUIConst->kHealthPanelPosX = GetLongConstant(f, "kHealthPanelPosX");
732 gGUIConst->kHealthPanelPosY = GetLongConstant(f, "kHealthPanelPosY");
733 gGUIConst->kHealthPanelRefreshRate = GetLongConstant(f, "kHealthPanelRefreshRate");
734 gGUIConst->kHealthPanelWidth = GetLongConstant(f, "kHealthPanelWidth");
735 gGUIConst->kOxygenPanelHeight = GetLongConstant(f, "kOxygenPanelHeight");
736 gGUIConst->kOxygenPanelPosX = GetLongConstant(f, "kOxygenPanelPosX");
737 gGUIConst->kOxygenPanelPosY = GetLongConstant(f, "kOxygenPanelPosY");
738 gGUIConst->kOxygenPanelRefreshRate = GetLongConstant(f, "kOxygenPanelRefreshRate");
739 gGUIConst->kOxygenPanelWidth = GetLongConstant(f, "kOxygenPanelWidth");
740 gGUIConst->kWeaponPanelHeight = GetLongConstant(f, "kWeaponPanelHeight");
741 gGUIConst->kWeaponPanelPosX = GetLongConstant(f, "kWeaponPanelPosX");
742 gGUIConst->kWeaponPanelPosY = GetLongConstant(f, "kWeaponPanelPosY");
743 gGUIConst->kWeaponPanelWidth = GetLongConstant(f, "kWeaponPanelWidth");
744 gGUIConst->kWeaponStatusWidth = GetLongConstant(f, "kWeaponStatusWidth");
745
746 gGUIConst->kUserMenuEntryDY = GetLongConstant(f, "kUserMenuEntryDY");
747 gGUIConst->kUserMenuEntryPosX = GetLongConstant(f, "kUserMenuEntryPosX");
748 gGUIConst->kUserMenuEntryPosY = GetLongConstant(f, "kUserMenuEntryPosY");
749 gGUIConst->kUserMenuHeight = GetLongConstant(f, "kUserMenuHeight");
750 gGUIConst->kUserMenuPosX = GetLongConstant(f, "kUserMenuPosX");
751 gGUIConst->kUserMenuPosY = GetLongConstant(f, "kUserMenuPosY");
752 gGUIConst->kUserMenuWidth = GetLongConstant(f, "kUserMenuWidth");
753 gGUIConst->kHelpMenuEntryDY = GetLongConstant(f, "kHelpMenuEntryDY");
754
755 gGUIConst->kInfoTextLeft = GetLongConstant(f, "kInfoTextLeft");
756 gGUIConst->kInfoTextTop = GetLongConstant(f, "kInfoTextTop");
757 gGUIConst->kInfoTextTime = GetLongConstant(f, "kInfoTextTime");
758
759 GetStringConstant(f, "kUserMainPageTitle", gGUIConst->kUserMainPageTitle);
760 GetStringConstant(f, "kUserMenuEntry1", gGUIConst->kUserMenuEntry1);
761 GetStringConstant(f, "kUserMenuEntry2", gGUIConst->kUserMenuEntry2);
762 GetStringConstant(f, "kUserMenuEntry3", gGUIConst->kUserMenuEntry3);
763 GetStringConstant(f, "kUserMenuEntry4", gGUIConst->kUserMenuEntry4);
764 GetStringConstant(f, "kUserMenuEntry5", gGUIConst->kUserMenuEntry5);
765
766 GetStringConstant(f, "kNewGamePageTitle", gGUIConst->kNewGamePageTitle);
767 GetStringConstant(f, "kNewGameEntry1", gGUIConst->kNewGameEntry1);
768 GetStringConstant(f, "kNewGameEntry2", gGUIConst->kNewGameEntry2);
769 GetStringConstant(f, "kNewGameEntry3", gGUIConst->kNewGameEntry3);
770 GetStringConstant(f, "kNewGameEntry4", gGUIConst->kNewGameEntry4);
771
772 GetStringConstant(f, "kNoSavedGame", gGUIConst->kNoSavedGame);
773 GetStringConstant(f, "kSavePageTitle", gGUIConst->kSavePageTitle);
774 GetStringConstant(f, "kLoadPageTitle", gGUIConst->kLoadPageTitle);
775 GetStringConstant(f, "kHelpPageTitle", gGUIConst->kHelpPageTitle);
776
777 GetStringConstant(f, "kSavedGame0", gGUIConst->kSavedGames[0]);
778 GetStringConstant(f, "kSavedGame1", gGUIConst->kSavedGames[1]);
779 GetStringConstant(f, "kSavedGame2", gGUIConst->kSavedGames[2]);
780 GetStringConstant(f, "kSavedGame3", gGUIConst->kSavedGames[3]);
781 GetStringConstant(f, "kSavedGame4", gGUIConst->kSavedGames[4]);
782 GetStringConstant(f, "kSavedGame5", gGUIConst->kSavedGames[5]);
783
784 gGUIConst->kKeyHitDelay = GetLongConstant(f, "kKeyHitDelay");
785
786 gGUIConst->kCreditsEntryDY = GetLongConstant(f, "kCreditsEntryDY");
787 GetStringConstant(f, "kCreditsPageTitle", gGUIConst->kCreditsPageTitle);
788 GetStringConstant(f, "kCreditsEntry1", gGUIConst->kCreditsEntry1);
789 GetStringConstant(f, "kCreditsEntry2", gGUIConst->kCreditsEntry2);
790 GetStringConstant(f, "kCreditsEntry3", gGUIConst->kCreditsEntry3);
791 GetStringConstant(f, "kCreditsEntry4", gGUIConst->kCreditsEntry4);
792 GetStringConstant(f, "kCreditsEntry5", gGUIConst->kCreditsEntry5);
793
794
795 fclose(f);
796 }
797
798
0 #ifndef __AMP_GUI__
1 #define __AMP_GUI__
2
3 #include "System.hpp"
4 #include "Player.hpp"
5 #include "Surface.hpp"
6
7 const short kMaxEntryLength = 20;
8 const short kNoCmdEvent = -1;
9 const short kNumOfSaveGameSlots = 6;
10 const short kMaxInfotexts = 45;
11
12 enum {
13 kMainPage,
14 kNewGamePage,
15 kLoadGamePage,
16 kSaveGamePage,
17 kCreditPage,
18 kHelpPage,
19 kQuitPage
20 };
21
22 const short kGUIsPositions[6][4] = {
23 {120, 0, 220, 100}, // health
24 {120, 100, 220, 200}, // oxygen
25 {0, 0, 120, 100}, // weapons
26 {120, 200, 280, 680}, // board
27 {0, 801, 210, 944}, // about box
28 {0, 943, 210, 1091} // key config
29 };
30
31 typedef struct {
32 short kHealthPanelWidth,
33 kHealthPanelHeight,
34 kHealthPanelPosX,
35 kHealthPanelPosY,
36 kHealthPanelRefreshRate,
37
38 kOxygenPanelWidth,
39 kOxygenPanelHeight,
40 kOxygenPanelPosX,
41 kOxygenPanelPosY,
42 kOxygenPanelRefreshRate,
43
44 kWeaponPanelWidth,
45 kWeaponPanelHeight,
46 kWeaponPanelPosX,
47 kWeaponPanelPosY,
48 kWeaponStatusWidth,
49
50 kUserMenuPosX,
51 kUserMenuPosY,
52 kUserMenuWidth,
53 kUserMenuHeight,
54 kUserMenuEntryPosX,
55 kUserMenuEntryPosY,
56 kUserMenuEntryDY;
57
58 short kInfoTextLeft;
59 short kInfoTextTop;
60 short kInfoTextTime;
61
62 short kHelpMenuEntryDY;
63
64 short kKeyHitDelay;
65
66 char kUserMainPageTitle[kMaxEntryLength];
67 char kUserMenuEntry1[kMaxEntryLength];
68 char kUserMenuEntry2[kMaxEntryLength];
69 char kUserMenuEntry3[kMaxEntryLength];
70 char kUserMenuEntry4[kMaxEntryLength];
71 char kUserMenuEntry5[kMaxEntryLength];
72
73 char kNewGamePageTitle[kMaxEntryLength];
74 char kNewGameEntry1[kMaxEntryLength];
75 char kNewGameEntry2[kMaxEntryLength];
76 char kNewGameEntry3[kMaxEntryLength];
77 char kNewGameEntry4[kMaxEntryLength];
78
79 char kNoSavedGame[kMaxEntryLength];
80 char kSavePageTitle[kMaxEntryLength];
81 char kLoadPageTitle[kMaxEntryLength];
82 char kHelpPageTitle[kMaxEntryLength];
83 char kSavedGames[kNumOfSaveGameSlots][kMaxEntryLength];
84
85 short kCreditsEntryDY;
86 char kCreditsPageTitle[kMaxEntryLength];
87 char kCreditsEntry1[kMaxEntryLength];
88 char kCreditsEntry2[kMaxEntryLength];
89 char kCreditsEntry3[kMaxEntryLength];
90 char kCreditsEntry4[kMaxEntryLength];
91 char kCreditsEntry5[kMaxEntryLength];
92 } tGUIConstants;
93
94
95 const short kMessageLength = 30;
96
97 typedef struct {
98 char msgHealth[kMessageLength];
99 char msgOxygen[kMessageLength];
100
101 char msgPhiol[kMessageLength];
102 char msgBM[kMessageLength];
103 char msgBow[kMessageLength];
104 char msgScie[kMessageLength];
105 char msgHands[kMessageLength];
106 char msgBombs[kMessageLength];
107 char msgStaff[kMessageLength];
108
109 char msgPhiolMun[kMessageLength];
110 char msgBMMun[kMessageLength];
111 char msgBowMun[kMessageLength];
112 char msgHandsMun[kMessageLength];
113 char msgBombsMun[kMessageLength];
114 char msgStaffMun[kMessageLength];
115
116 char generalMessages[kMaxInfotexts][kMessageLength];
117
118 } tMessages;
119
120
121 class CGUI {
122 protected:
123 Graphic_file *guis;
124 CGraphicSurface *backgroundPanel;
125 CGraphicSurface *healthPanel;
126 CGraphicSurface *oxygenPanel;
127 CGraphicSurface *weaponPanel;
128 CPlayer *player;
129 tMessages *messages;
130
131 long lastKeyHit;
132
133 long lastHealthPanelRefresh;
134 short healthCurveStart;
135 long lastOxygenPanelRefresh;
136 double oxygenCurveStart;
137
138 CGraphicSurface *currentMainScreen;
139 short currentItem, lastItem;
140 short currentNumOfItems;
141 short currentItemStart;
142 short currentEntryDY;
143 short page;
144
145 char sgTitles[kNumOfSaveGameSlots][30];
146 char *currentMessage;
147 long msgDisplayTime;
148
149 void DrawHealthPanel();
150 void DrawOxygenPanel();
151
152 void SelectMenuItem();
153 char *ItemToItem(short item);
154
155 short ProcessKeyStrokes();
156 short MainPageEvents();
157 short NewGamePageEvents();
158 short LoadGamePageEvents();
159 short QuitPageEvents();
160
161 void OnOpenMainPage();
162 void OnOpenNewGamePage();
163 void OnOpenLoadPage(short whichPage);
164 void OnOpenHelpPage();
165 void OnOpenCreditsPage();
166 void OnOpenQuitPage();
167
168 void LoadMessages();
169
170 public:
171 CGUI(CGraphicSurface *curMainScreen);
172 ~CGUI();
173
174 void SetFocus(CPlayer *focus);
175
176 void Update();
177 void UpdateWeapon();
178 short RunUserInterface(short page);
179 void ResetTicks(long ticks);
180 void OnPickUpSomething(short what);
181 void DisplayMessages();
182 void DisplayInfotext(short num);
183 };
184
185 #endif
0 #include "Item.hpp"
1 #include "Appl.hpp"
2 #include "Clut.hpp"
3 #include "SndSys.hpp"
4
5 extern CApplication *gApplication;
6 extern CShapeManager *gShapeManager;
7 extern CLevel *gLevel;
8 extern tConstValues *gConst;
9 extern CClutManager *gClutManager;
10 extern CSoundSystem *gSoundSystem;
11
12 CItem::CItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo) :
13 CThing(initx, inity, width, height, number)
14 {
15 typeID |= kItem;
16
17 info = itemInfo;
18 shape = gShapeManager->FindShape(itemInfo->iconID, 0);
19 currentShape = shape;
20 detonationStartTime = -1;
21 isCorona = info->iconID >= kCoronaIDs[0] && info->iconID <= kCoronaIDs[kNumOfCoronas -1];
22 coronaFader = 0.0;
23 deltaTime = 0;
24 dx -= 1;
25 xe -= 1;
26 }
27
28 CItem::~CItem()
29 {}
30
31 short CItem::Think()
32 {
33 CObject::Think();
34
35 if (detonationStartTime != -1) {
36 long frame = (long)((double)(lastTime - detonationStartTime) * gConst->kDetonationFrameTime);
37
38 if (frame > 4)
39 return kDestroyMe;
40 else
41 currentShape = gShapeManager->FindShape(gConst->kItemExplosionStartShape + frame, 0);
42 }
43 return kNoEvent;
44 }
45
46 void CItem::Move()
47 {
48 CThing::Move();
49 environmentForceX = environmentForceY = 0;
50 }
51
52 void CItem::Render(short planeX, short planeY, tRect *clipRect)
53 {
54 CElement *element = gLevel->GetElement(xm, ym);
55
56 if (!isCorona && currentShape) currentShape->RenderShape(xs - planeX, ys - planeY, clipRect,
57 modus, element ? element->brightness : 0, gApplication->plane);
58 else if (isCorona)
59 gClutManager->PrepareCorona(xm, ym, gApplication->plane);
60 }
61
62 void CItem::PostRender(short planeX, short planeY, tRect *clipRect)
63 {
64 if (isCorona) {
65 CElement *element = gLevel->GetElement(xm, ym);
66 gClutManager->DrawCorona(xm, ym, info->iconID - kCoronaIDs[0], element->data ? element->data : 1, gApplication->plane, coronaFader, deltaTime);
67 }
68 }
69
70 void CItem::OnDamage(short blessure)
71 {
72 if (blessure && info->flags & kItemExplodesMask && detonationStartTime == -1) {
73 tThingList *currentEntry = gApplication->collisionThingList;
74
75 detonationStartTime = lastTime;
76
77 while (currentEntry) {
78 if (currentEntry->thing != this) currentEntry->thing->TestForDamage(xs, ys, gConst->kItemExplosionRad, info->data);
79 currentEntry = currentEntry->next;
80 }
81 }
82 }
83
84 CStaticItem::CStaticItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo) :
85 CItem(initx, inity, width, height, number, itemInfo)
86 {
87 typeID |= kStaticItem;
88 background = 0;
89 weight = 32000;
90 weightless = 1;
91 LinkInLists();
92 }
93
94 CStaticItem::~CStaticItem()
95 {
96 }
97
98 void CStaticItem::LinkInLists()
99 {
100 gApplication->Enqueue(&gApplication->thingList, this);
101 gApplication->Enqueue(&gApplication->collisionThingList, this);
102 if (isCorona) {
103 gApplication->Enqueue(&gApplication->preRenderQueue, this);
104 gApplication->Enqueue(&gApplication->postRenderQueue, this);
105 }else gApplication->Enqueue(&gApplication->renderQueue, this);
106 }
107
108 void CStaticItem::UnlinkInLists()
109 {
110 gApplication->Dequeue(&gApplication->thingList, this);
111 gApplication->Dequeue(&gApplication->collisionThingList, this);
112 if (isCorona) {
113 gApplication->Dequeue(&gApplication->preRenderQueue, this);
114 gApplication->Dequeue(&gApplication->postRenderQueue, this);
115 }else gApplication->Dequeue(&gApplication->renderQueue, this);
116 }
117
118 short CStaticItem::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject)
119 {
120 short returnValue = CThing::Collision(sender, left, top, right, bottom, forcex, forcey, pfx, pfy, sourceWeight, collisionObject);
121 if (returnValue && info->flags & kItemHurtMask) {
122 ((CThing *)sender)->OnDamage(info->data);
123 }
124
125 return returnValue;
126 }
127
128
129 CBackgroundItem::CBackgroundItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo) :
130 CItem(initx, inity, width, height, number, itemInfo)
131 {
132 typeID |= kBackgroundItem;
133 weight = 0; // Background items are hanging in the air, they don't fall, so they have no weight
134 background = 1;
135 weightless = 1;
136
137 LinkInLists();
138 }
139
140 CBackgroundItem::~CBackgroundItem()
141 {
142 }
143
144 void CBackgroundItem::LinkInLists()
145 {
146 gApplication->Enqueue(&gApplication->thingList, this);
147 gApplication->Enqueue(&gApplication->preRenderQueue, this);
148 if (isCorona) {
149 gApplication->Enqueue(&gApplication->postRenderQueue, this);
150 }
151 }
152
153 void CBackgroundItem::UnlinkInLists()
154 {
155 gApplication->Dequeue(&gApplication->thingList, this);
156 gApplication->Dequeue(&gApplication->preRenderQueue, this);
157 if (isCorona) {
158 gApplication->Dequeue(&gApplication->postRenderQueue, this);
159 }
160 }
161
162 CMovableItem::CMovableItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo) :
163 CItem(initx, inity, width, height, number, itemInfo)
164 {
165 typeID |= kMovableItem;
166 weight = 1;
167 background = 0;
168 LinkInLists();
169 }
170
171 CMovableItem::~CMovableItem()
172 {
173 }
174
175 void CMovableItem::LinkInLists()
176 {
177 gApplication->Enqueue(&gApplication->thingList, this);
178 gApplication->Enqueue(&gApplication->collisionThingList, this);
179 if (isCorona) {
180 gApplication->Enqueue(&gApplication->preRenderQueue, this);
181 gApplication->Enqueue(&gApplication->postRenderQueue, this);
182 }else gApplication->Enqueue(&gApplication->renderQueue, this);
183 }
184
185 void CMovableItem::UnlinkInLists()
186 {
187 gApplication->Dequeue(&gApplication->thingList, this);
188 gApplication->Dequeue(&gApplication->collisionThingList, this);
189 if (isCorona) {
190 gApplication->Dequeue(&gApplication->preRenderQueue, this);
191 gApplication->Dequeue(&gApplication->postRenderQueue, this);
192 }else gApplication->Dequeue(&gApplication->renderQueue, this);
193 }
194
195
196 CPortableItem::CPortableItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo, short itemNo) :
197 CItem(initx, inity, width, height, number, itemInfo)
198 {
199 typeID |= kPortableItem;
200 type = itemNo;
201 background = 0;
202 weight = 1;
203 pickedUp = 0;
204 LinkInLists();
205 }
206
207 CPortableItem::~CPortableItem()
208 {
209 }
210
211 void CPortableItem::LinkInLists()
212 {
213 gApplication->Enqueue(&gApplication->thingList, this);
214 gApplication->Enqueue(&gApplication->collisionThingList, this);
215 if (isCorona) {
216 gApplication->Enqueue(&gApplication->preRenderQueue, this);
217 gApplication->Enqueue(&gApplication->postRenderQueue, this);
218 }else gApplication->Enqueue(&gApplication->renderQueue, this);
219 }
220
221 void CPortableItem::UnlinkInLists()
222 {
223 gApplication->Dequeue(&gApplication->thingList, this);
224 gApplication->Dequeue(&gApplication->collisionThingList, this);
225 if (isCorona) {
226 gApplication->Dequeue(&gApplication->preRenderQueue, this);
227 gApplication->Dequeue(&gApplication->postRenderQueue, this);
228 }else gApplication->Dequeue(&gApplication->renderQueue, this);
229 }
230
231
232 short CPortableItem::Think()
233 {
234 CObject::Think();
235
236 if (pickedUp) return kDestroyMe; else return kNoEvent;
237 }
238
239 short CPortableItem::PickMeUp(short &value)
240 {
241 value = info->data;
242 pickedUp = 1;
243
244 return type;
245 }
246
247 short CItem::Write(FILE *f)
248 {
249 long size = 0;
250
251 WRITEDATA(size);
252 WRITEDATA(typeID);
253 WRITEDATA(thingNumber);
254
255 size += CThing::Write(f);
256
257 WRITEDATA(isCorona);
258 WRITEDATA(detonationStartTime);
259
260 FINISHWRITE;
261
262 return size;
263 }
264
265
266 void CItem::Read(FILE *f)
267 {
268 long size = 0;
269
270 READDATA(size);
271 READDATA(typeID);
272 READDATA(thingNumber);
273
274 CThing::Read(f);
275
276 READDATA(isCorona);
277 READDATA(detonationStartTime);
278 }
279
280 short CPortableItem::Write(FILE *f)
281 {
282 long size = 0;
283
284 WRITEDATA(size);
285 WRITEDATA(typeID);
286 WRITEDATA(thingNumber);
287
288 size += CItem::Write(f);
289
290 WRITEDATA(pickedUp);
291 WRITEDATA(type);
292
293 FINISHWRITE;
294
295 return size;
296 }
297
298
299 void CPortableItem::Read(FILE *f)
300 {
301 long size = 0;
302
303 READDATA(size);
304 READDATA(typeID);
305 READDATA(thingNumber);
306
307 CItem::Read(f);
308
309 READDATA(pickedUp);
310 READDATA(type);
311 }
0 #ifndef __AMP_ITEM__
1 #define __AMP_ITEM__
2
3 #include "Thing.hpp"
4 #include "ObjInfo.hpp"
5 #include "Shape.hpp"
6
7 class CItem : public CThing {
8 protected:
9 CShape *shape;
10 CShape *currentShape;
11 tItemInfo *info;
12
13 long detonationStartTime;
14 short isCorona;
15 double coronaFader;
16
17 public:
18 CItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo);
19 ~CItem();
20
21 short Think();
22 void Render(short planeX, short planeY, tRect *clipRect);
23 void PostRender(short planeX, short planeY, tRect *clipRect);
24 void Move();
25
26 void OnDamage(short blessure);
27
28 short Write(FILE *f);
29 void Read(FILE *f);
30 };
31
32 class CStaticItem : public CItem {
33 protected:
34
35 public:
36 CStaticItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo);
37 ~CStaticItem();
38
39 void LinkInLists();
40 void UnlinkInLists();
41
42 short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
43 };
44
45 class CBackgroundItem : public CItem {
46 protected:
47
48 public:
49 CBackgroundItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo);
50 ~CBackgroundItem();
51
52 void LinkInLists();
53 void UnlinkInLists();
54 };
55
56 class CMovableItem : public CItem {
57 protected:
58
59 public:
60 CMovableItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo);
61 ~CMovableItem();
62
63 void LinkInLists();
64 void UnlinkInLists();
65 };
66
67 class CPortableItem : public CItem {
68 protected:
69 short pickedUp;
70 short type;
71
72 public:
73 CPortableItem(short initx, short inity, short width, short height, short number, tItemInfo *itemInfo, short type);
74 ~CPortableItem();
75
76 void LinkInLists();
77 void UnlinkInLists();
78
79 short Think();
80 short PickMeUp(short &value);
81
82 short Write(FILE *f);
83 void Read(FILE *f);
84 };
85
86 #endif
0 #include <stdio.h>
1 #include <string.h>
2 #include <time.h>
3
4 #include "Level.hpp"
5 #include "Appl.hpp"
6 #include "ConstVal.hpp"
7 #include "Gui.hpp"
8 #include "ShapeLd.hpp"
9
10 extern CApplication *gApplication;
11 extern CObjInfo *gObjInfo;
12 extern tConstValues *gConst;
13 extern CSystem *gSystem;
14 extern CShapeManager *gShapeManager;
15 extern tGUIConstants *gGUIConst;
16 extern CGUI *gGUI;
17 extern FILE *logFile;
18
19 //----------------------------------------------------
20 CLevel::CLevel(short levelNumber, char *fileName)
21 /* In: levelNumber: number of level to be loaded
22
23 First loads the level data from file, then generating each level element object, and if there are monsters
24 or items on the element, generate them
25 Then create platforms
26 */
27 {
28 if (fileName) {
29
30 ReadLevel(fileName);
31
32 }else{
33 short j, k;
34 tLevelElement *levelElement = new tLevelElement;
35 CThing *thing;
36
37 LoadBackground(levelNumber);
38
39 gObjInfo->CreatePlatforms();
40
41 if (!OpenDataFile(gSystem->QualifyDataDir(gConst->kFileLevel))) gSystem->Error("File kFileLevel not found or not able to open it", 0); // by LL
42
43 SetFilePos(levelNumber * kLevelWidth * kLevelHeight * sizeof(tLevelElement));
44
45 MSG("Creating level\n");
46 for (j = 0; j < kLevelHeight; j ++) {
47 for (k = 0; k < kLevelWidth; k ++) {
48 ReadData(levelElement, sizeof(tLevelElement));
49
50 TRANS_PUT_NUM(levelElement->kind);
51 TRANS_PUT_NUM(levelElement->iconID);
52 TRANS_PUT_NUM(levelElement->light);
53 TRANS_PUT_NUM(levelElement->refNum);
54 TRANS_PUT_NUM(levelElement->bitData);
55 TRANS_PUT_NUM(levelElement->monsterRef);
56 TRANS_PUT_NUM(levelElement->itemRef);
57
58 if (levelElement->iconID > 0) levelElement->iconID += gConst->kShapeSets[levelNumber] * 20;
59
60 if (levelElement->iconID)
61 level[j][k] = new CElement(k * kElementSize + kElementSize / 2, j * kElementSize + kElementSize / 2, kElementSize, kElementSize, levelElement);
62 else level[j][k] = new CBackgroundElement(k * kElementSize + kElementSize / 2, j * kElementSize + kElementSize / 2, kElementSize, kElementSize, levelElement);
63
64 level[j][k]->LinkPlatforms();
65
66 if (levelElement->monsterRef != -1) {
67 if (levelElement->monsterRef == kCameraNo)
68 thing = new CCamera(k * kElementSize, j * kElementSize, 2, 2, 0);
69 else
70 thing = gObjInfo->CreateMonster(levelElement->monsterRef, k, j);
71
72
73 if (thing->typeID & (kPlayer | kCamera)) {
74 focus = thing;
75 player = thing;
76 }
77 }
78
79 if (levelElement->itemRef != -1) {
80 thing = gObjInfo->CreateItem(levelElement->itemRef, k, j);
81 }
82
83 }
84 }
85
86 delete levelElement;
87
88 CloseDataFile();
89
90 gSystem->ResetTicks(0);
91 gGUI->ResetTicks(0);
92 }
93 }
94
95
96 CLevel::~CLevel()
97 {
98 short j, k;
99
100 for (j = 0; j < kLevelHeight; j ++) {
101 for (k = 0; k < kLevelWidth; k ++) {
102 delete level[j][k];
103 }
104 }
105 }
106
107 void CLevel::LoadBackground(short levelNumber)
108 {
109 if (gConst->kBackgrounds[levelNumber] != gApplication->lastBackground) {
110 gShapeManager->UnloadBackground();
111
112 if (gConst->kBackgrounds[levelNumber] == 1)
113 gShapeManager->LoadBackground(gConst->kFileBackground1);
114 else
115 gShapeManager->LoadBackground(gConst->kFileBackground2);
116 gApplication->lastBackground = gConst->kBackgrounds[levelNumber];
117 }
118 }
119
120 void CLevel::PaintLevel()
121 {
122 short j, k;
123 short planeX, planeY;
124 short startElementX, startElementY, numElementsX, numElementsY;
125 tRect clipRect;
126 tThingList *currentEntry;
127
128 focus->CalcPlaneOffsets(planeX, planeY);
129
130 clipRect.left = 0;
131 clipRect.top = 0;
132 clipRect.right = kGamePlaneWidth;
133 clipRect.bottom = kGamePlaneHeight;
134
135 startElementX = planeX / kElementSize;
136 startElementY = planeY / kElementSize;
137 numElementsX = kGamePlaneWidth / kElementSize;
138 numElementsY = kGamePlaneHeight / kElementSize;
139
140 for (j = startElementY; j < startElementY + numElementsY + 1 && j < kLevelHeight; j ++) {
141 for (k = startElementX; k < startElementX + numElementsX + 1 && k < kLevelWidth; k ++) {
142 level[j][k]->PaintElement(planeX, planeY, &clipRect);
143 }
144 }
145 currentEntry = gApplication->preRenderQueue;
146 while (currentEntry) {
147 currentEntry->thing->Render(planeX, planeY, &clipRect);
148 currentEntry = currentEntry->next;
149 }
150
151 currentEntry = gApplication->renderQueue;
152 while (currentEntry) {
153 currentEntry->thing->Render(planeX, planeY, &clipRect);
154 currentEntry = currentEntry->next;
155 }
156
157 currentEntry = gApplication->postRenderQueue;
158 while (currentEntry) {
159 currentEntry->thing->PostRender(planeX, planeY, &clipRect);
160 currentEntry = currentEntry->next;
161 }
162 }
163
164
165 CElement *CLevel::GetElement(double x, double y)
166 {
167 short elemx, elemy;
168
169 elemx = (short)(x / kElementSize);
170 elemy = (short)(y / kElementSize);
171
172 if (elemx >= 0 && elemy >= 0 && elemx < kLevelWidth && elemy < kLevelHeight)
173 return level[elemy][elemx];
174 else return 0L;
175 }
176
177 // -----------------------------------------------
178 void CLevel::SwitchLight(short lightID)
179 // Searches all elements with key equal to key, and then change their
180 // lights. Don't call this routine too often, it's slow
181 {
182 short j, k;
183
184 for (j = 0; j < kLevelHeight; j ++) {
185 for (k = 0; k < kLevelWidth; k ++) {
186 if (level[j][k]->key == lightID) level[j][k]->SwapLights();
187 }
188 }
189 }
190
191 // -----------------------------------------------
192 CElement *CLevel::FindRefnum(short refnum)
193 // Finds the first element with key == refnum and returns it
194 {
195 short j, k;
196
197 for (j = 0; j < kLevelHeight; j ++) {
198 for (k = 0; k < kLevelWidth; k ++) {
199 if (level[j][k]->key == refnum) return level[j][k];
200 }
201 }
202 return 0L;
203 }
204
205
206 void CLevel::WriteLevel(char *fileName)
207 {
208 char tmpName[12] = "tmp.sg0";
209 long versionNumber = kVersionNumber;
210 long key = kVersionKey;
211 time_t theTime;
212 long ticks;
213 long size;
214 tThingList *currentEntry;
215 char *tmpFileName;
216
217 tmpFileName = gSystem->QualifyHomeDir(tmpName);
218 remove(tmpFileName);
219 FILE *f = fopen(tmpFileName, "wb"); // by LL
220 if (!f) {
221 gSystem->Error("Cannot open the saving file", 0);
222 }
223
224 MSG("Writing save file header\n");
225 fwrite(&versionNumber, sizeof(versionNumber), 1, f);
226 fwrite(&key, sizeof(key), 1, f);
227 theTime = time(&theTime);
228 fwrite(&theTime, sizeof(theTime), 1, f);
229 ticks = gSystem->GetTicks();
230 fwrite(&ticks, sizeof(ticks), 1, f);
231 fwrite(&gApplication->difficulty, sizeof(gApplication->difficulty), 1, f);
232 size = 0;
233 fwrite(&size, sizeof(size), 1, f);
234 fwrite(&gApplication->levelNumber, sizeof(gApplication->levelNumber), 1, f);
235
236 MSG("Writing level elements\n");
237 for (short j = 0; j < kLevelHeight; j ++) {
238 for (short k = 0; k < kLevelWidth; k ++) {
239 level[j][k]->Write(f);
240 }
241 }
242
243 MSG("Writing objects\n");
244 currentEntry = gApplication->thingList;
245 while (currentEntry) {
246 currentEntry->thing->Write(f);
247 currentEntry = currentEntry->next;
248 }
249
250 size = ftell(f);
251 fseek(f, sizeof(versionNumber) + sizeof(key) + sizeof(theTime) + sizeof(ticks) + sizeof(gApplication->difficulty), SEEK_SET);
252 fwrite(&size, sizeof(size), 1, f);
253
254 MSG("Finishing up\n");
255 fflush(f);
256 fclose(f);
257
258 remove(fileName);
259 rename(tmpFileName, fileName);
260 delete [] tmpFileName;
261 }
262
263 void CLevel::GetSavedGameTitle(char *fileName, char *title)
264 {
265
266
267 long versionNumber, key;
268 time_t time;
269 FILE *f = fopen(fileName, "rb");
270 tm *tp;
271
272 if (f) fread(&versionNumber, sizeof(versionNumber), 1, f);
273 if (f) fread(&key, sizeof(key), 1, f);
274
275 if (!f || versionNumber != kVersionNumber || key != kVersionKey)
276 title = strcpy(title, gGUIConst->kNoSavedGame);
277 else {
278 fread(&time, sizeof(time), 1, f);
279 tp = localtime(&time);
280 strftime(title, 20, "%d.%m.%Y, %H.%M", tp);
281 }
282
283 if (f) fclose(f);
284 }
285
286 short CLevel::ReadLevel(char *fileName)
287 {
288 FILE *f = fopen(fileName, "rb");
289 long versionNumber, key;
290 time_t theTime;
291 long ticks;
292 long size, fileSize;
293 long typeID = -1;
294 CThing *thing;
295 short thingNumber;
296 short j, k;
297
298 if (!f) gSystem->Error("Cannot open the saving file", 0);
299
300 MSG("Reading level header\n");
301 fread(&versionNumber, sizeof(versionNumber), 1, f); if (versionNumber != kVersionNumber) return 0;
302 fread(&key, sizeof(key), 1, f); if (key != kVersionKey) return 0;
303 fread(&theTime, sizeof(theTime), 1, f);
304 fread(&ticks, sizeof(ticks), 1, f);
305 fread(&gApplication->difficulty, sizeof(gApplication->difficulty), 1, f);
306 fread(&fileSize, sizeof(fileSize), 1, f);
307 fread(&gApplication->levelNumber, sizeof(gApplication->levelNumber), 1, f);
308
309 LoadBackground(gApplication->levelNumber);
310
311 MSG("Reading level elements\n");
312 for (j = 0; j < kLevelHeight; j ++) {
313 for (k = 0; k < kLevelWidth; k ++) {
314 fread(&size, sizeof(size), 1, f);
315 fread(&typeID, sizeof(typeID), 1, f);
316 fseek(f, - (sizeof(size) + sizeof(typeID)), SEEK_CUR);
317
318 if (typeID & kBackgroundElement)
319 level[j][k] = new CBackgroundElement(k * kElementSize, j * kElementSize, kElementSize, kElementSize, 0L);
320 else
321 level[j][k] = new CElement(k * kElementSize, j * kElementSize, kElementSize, kElementSize, 0L);
322
323 level[j][k]->Read(f);
324 }
325 }
326
327
328 MSG("Reading objects\n");
329 while (!feof(f) && ftell(f) < fileSize) {
330
331
332 fread(&size, sizeof(size), 1, f);
333 fread(&typeID, sizeof(typeID), 1, f);
334 fread(&thingNumber, sizeof(thingNumber), 1, f);
335 fseek(f, - (sizeof(size) + sizeof(typeID) + sizeof(thingNumber)), SEEK_CUR);
336
337
338 if (typeID & kMonster) {
339 thing = gObjInfo->CreateMonster(thingNumber, 0, 0);
340
341 if (typeID & kPlayer) {
342 focus = thing;
343 player = thing;
344 }
345
346 thing->Read(f);
347 }
348
349 if (typeID & kItem) {
350 thing = gObjInfo->CreateItem(thingNumber, 0, 0);
351
352 thing->Read(f);
353 }
354
355 if (typeID & kBullet) {
356
357 if (typeID & kSorceryBullet)
358 thing = new CSorceryBullet(0, 0, 0, 0, 0, 0L, 0, 0, 0L, 0);
359 else if (typeID & kBombBullet)
360 thing = new CBombBullet(0, 0, 0, 0, 0, 0L, 0, 0, 0L, 0);
361 else if (typeID & kSineBullet)
362 thing = new CSineBullet(0, 0, 0, 0, 0, 0L, 0, 0, 0L, 0, 0, 0);
363 else if (typeID & kGuidedBullet)
364 thing = new CGuidedBullet(0, 0, 0, 0, 0, 0L, 0, 0, 0L, 0, 0L);
365 else
366 thing = new CBullet(0, 0, 0, 0, 0, 0L, 0, 0, 0L, 0);
367
368
369
370 thing->Read(f);
371 }
372
373 if (typeID & kPlatform) {
374 thing = new CPlatform(0, 0, 0, 0, 0, 0L);
375
376 thing->Read(f);
377
378 gApplication->platformTable[thingNumber] = (CPlatform *)thing;
379 }
380 }
381
382 MSG("Finishing up\n");
383 fflush(f);
384 fclose(f);
385
386 for (j = 0; j < kLevelHeight; j ++) {
387 for (k = 0; k < kLevelWidth; k ++) {
388 level[j][k]->LinkPlatforms();
389 }
390 }
391
392
393 gSystem->ResetTicks(ticks);
394 gGUI->ResetTicks(ticks);
395
396 return 1;
397 }
398
0 #ifndef __AMP_LEVEL__
1 #define __AMP_LEVEL__
2
3 #include "File.hpp"
4 #include "Element.hpp"
5 #include "AmpHead.hpp"
6 #include "ShapeLd.hpp"
7 #include "Thing.hpp"
8
9 class CLevel : public CFile {
10 protected:
11 void LoadBackground(short levNum);
12 public:
13 CElement *level[kLevelHeight][kLevelWidth];
14 CThing *player;
15 CThing *focus;
16
17
18 CLevel(short levelNumber, char *fileName);
19 ~CLevel();
20
21 void PaintLevel();
22 CElement *GetElement(double x, double y);
23 void SwitchLight(short lightID);
24 CElement *FindRefnum(short refnum);
25 void WriteLevel(char *fileName);
26 short ReadLevel(char *fileName);
27 void GetSavedGameTitle(char *fileName, char *title);
28 };
29
30
31 #endif
0 #include "System.hpp"
1 #include "Appl.hpp"
2 #include "Clut.hpp"
3 #include "Gui.hpp"
4 #include "SndSys.hpp"
5 #include "string.h"
6
7 // Services
8 CApplication *gApplication;
9 CSystem *gSystem;
10 CLevel *gLevel;
11 CObjInfo *gObjInfo;
12 CShapeManager *gShapeManager;
13 CClutManager *gClutManager;
14 tConstValues *gConst;
15 tConfigData *gConfigData;
16 CGUI *gGUI;
17 CSoundSystem *gSoundSystem;
18
19 static char **my_argv;
20 static int my_argc;
21
22 int checkParam(const char *s)
23 {
24 int i;
25
26 for (i=1; i<my_argc; i++) {
27 if (!strcasecmp(s, my_argv[i])) {
28 // printf("Detected option %s as %d\n", s, i);
29 return i;
30 }
31 }
32 return 0;
33 }
34
35 void showUsage()
36 {
37
38 printf("-ns, --nosound disable sound\n");
39 printf("-fs, --fullscreen try DGA fullscreen mode\n");
40 printf(" --version display version information and exit\n");
41 printf(" --help display this help and exit\n");
42 }
43
44 void showVersion()
45 {
46 printf("Amphetamine %s \n", kVersionString);
47 printf("Contact <loehrerl@bigfoot.com> for comments.\n");
48 }
49
50
51 int checkCommandLine()
52 {
53 if (checkParam("--help")) {
54 showUsage();
55 return -1;
56 }
57
58 if (checkParam("--version")) {
59 showVersion();
60 return -1;
61 }
62
63 gConfigData = new tConfigData;
64
65 gConfigData->haveSound= !(checkParam("--nosound") || checkParam("-ns")) ;
66 gConfigData->tryFullScreen= checkParam("--fullscreen") || checkParam("-fs");
67
68 return 0;
69 }
70
71 int main(int argc, char **argv)
72 {
73 my_argc = argc;
74 my_argv = argv;
75 if (checkCommandLine()) return 0;
76
77 gApplication = new CApplication();
78 gApplication->InitGraphics();
79 gApplication->LoadData();
80 gApplication->Run();
81 gApplication->UnloadData();
82 gApplication->Quit();
83 delete gApplication;
84
85 return 0;
86 }
0 #include "Monster.hpp"
1 #include "Appl.hpp"
2 #include "ConstVal.hpp"
3
4 extern CApplication *gApplication;
5 extern CShapeManager *gShapeManager;
6 extern CObjInfo *gObjInfo;
7 extern CLevel *gLevel;
8 extern tConstValues *gConst;
9
10 CMonster::CMonster(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) :
11 CThing(initx, inity, width, height, number)
12 {
13 typeID |= kMonster;
14 background = 0;
15 LinkInLists();
16
17 if (monsterInfo) {
18 info = monsterInfo;
19
20 OnAllocate();
21
22 lastWalkTime = 0;
23 lastShootTime = 0;
24 walkFrame = 0;
25 flying = 0;
26 teleportCounter = -1;
27 lastBlessureTime = 0;
28 dieFrameTime = 0;
29 dieFrame = -1;
30 speed = info->speed * gApplication->currentSpeedSF;
31 }
32
33 // additinal init
34 lastCollisionCode = kNoCollision;
35 status = kMonsterForward;
36 doDarken = 0;
37 }
38
39 void CMonster::OnAllocate()
40 {
41 for (short n = 0; n < 3; n ++) {
42 moveShapes[n] = gShapeManager->FindShape(info->moveShapes[n], 0);
43 deathShapes[n] = gShapeManager->FindShape(info->deathShapes[n], 0);
44 }
45 jumpShape = gShapeManager->FindShape(info->jumpShape, 0);
46 attackShape = gShapeManager->FindShape(info->attackShape, 0);
47
48 weapon = CreateWeapon(info->weapon);
49 currentShape = moveShapes[0];
50
51 health = info->energy * gApplication->currentHealthSF;
52 }
53
54
55 void CMonster::LinkInLists()
56 {
57 gApplication->Enqueue(&gApplication->thingList, this);
58 gApplication->Enqueue(&gApplication->collisionThingList, this);
59 gApplication->Enqueue(&gApplication->renderQueue, this);
60 }
61
62 void CMonster::UnlinkInLists()
63 {
64 gApplication->Dequeue(&gApplication->thingList, this);
65 gApplication->Dequeue(&gApplication->collisionThingList, this);
66 gApplication->Dequeue(&gApplication->renderQueue, this);
67 }
68
69
70 CMonster::~CMonster()
71 {
72 if (weapon) delete weapon;
73 }
74
75
76 CWeapon *CMonster::CreateWeapon(short weapon)
77 {
78 tWeaponInfo *tmp = gObjInfo->FindWeapon(weapon);
79 CWeapon *tmpWeapon;
80
81 noWeapon = 0;
82
83 switch (tmp->art) {
84 case kWeaponMultibullet:
85 tmpWeapon = new CMultiBulletWeapon(this, tmp, attackShape, gConst->kFirehandAngle);
86 break;
87 case kWeaponInHand:
88 tmpWeapon = new CWeapon(this, tmp, attackShape);
89 noWeapon = 1;
90 break;
91 case kWeaponSine:
92 tmpWeapon = new CSineWeapon(this, tmp, attackShape, gConst->kSineWeaponRad);
93 break;
94 case kWeaponGuided:
95 tmpWeapon = new CGuided(this, tmp, attackShape);
96 break;
97 case kWeaponSorcery:
98 tmpWeapon = new CSorcery(this, tmp, attackShape);
99 break;
100 case kWeaponNormal:
101 case kWeaponHasWeight:
102 default:
103 tmpWeapon = new CWeapon(this, tmp, attackShape);
104 break;
105 }
106 if (tmpWeapon) {
107 tmpWeapon->weaponStatus = kWeaponReady;
108 tmpWeapon->AddMunition(SHRT_MAX);
109 tmpWeapon->weaponNumber = weapon;
110 }
111 return tmpWeapon;
112 }
113
114 void CMonster::Move()
115 {
116
117 CThing::Move();
118
119 if (ys >= kLevelHeight * kElementSize) {
120 health = 0;
121 OnKill();
122 }
123
124 if (info->invisible) modus = kShapemodusShadow;
125
126 currentShape = moveShapes[walkFrame];
127
128 if (forceVectorX && lastTime > lastWalkTime ) {
129 walkFrame ++;
130 walkFrame %= 3;
131 lastWalkTime = lastTime + gConst->kWalkFrameTime;
132 }
133
134 if (forceVectorY < 0) currentShape = jumpShape;
135
136 if (dieFrame != -1) {
137 if (dieFrameTime < lastTime && dieFrame < 2) {
138 dieFrame ++;
139 dieFrameTime = lastTime + gConst->kDieFrameTime;
140
141 if (dieFrame == 2)
142 gApplication->Dequeue(&gApplication->collisionThingList, this);
143 }
144 currentShape = deathShapes[dieFrame];
145 }
146
147 if (weapon) doDarken = weapon->ShootAnimation(&currentShape);
148 }
149
150 short CMonster::Forces()
151 {
152 short collisionObject;
153
154
155 Gravitation();
156
157 CObject::Forces();
158
159 lastCollisionCode = ExertForce(resForceX, resForceY, collisionObject, 0L);
160 if (lastCollisionCode & (kCollisionOnLeft | kCollisionOnRight)) forceVectorX = 0;
161
162 return kNoEvent;
163 }
164
165 // --------------------------------------------------------------------
166 void CMonster::Render(short planeX, short planeY, tRect *clipRect)
167 // Renders the current Shape of the monster
168 {
169 CElement *element = gLevel->GetElement(xm, ym);
170 short screenPosx = xs - planeX, screenPosy = ys - planeY; // Position of monster on the screen
171 short brightness = (element && doDarken) ? element->brightness : 0;
172
173 // Teleporting...
174 if (teleportCounter != -1) {
175
176 if (teleportCounter > dx / 2) {
177 clipRect->left = MAX(screenPosx + dx - teleportCounter, clipRect->left);
178 clipRect->right = MIN(screenPosx + teleportCounter, clipRect->right);
179 }else{
180 clipRect->left = MAX(screenPosx + teleportCounter, clipRect->left);
181 clipRect->right = MIN(screenPosx + (xe - planeX) - teleportCounter, clipRect->right);
182 }
183
184 if (teleportDeltaTime < lastTime) {
185 teleportCounter ++;
186 teleportDeltaTime = lastTime + gConst->kTeleportTime / dx * 2;
187 }
188
189 if (teleportCounter == dx / 2) OnTeleport();
190 if (teleportCounter == dx) teleportCounter = -1;
191
192 modus = kShapemodusRandom;
193 }
194
195 // Testing for blessure invulnerability
196 if (lastBlessureTime > lastTime) modus = kShapemodusRandom;
197
198
199 if (lookDirection == kLookingLeft) modus |= kShapemodusBackwardFlag;
200
201 if (currentShape) currentShape->RenderShape(screenPosx, screenPosy, clipRect,
202 modus, brightness, gApplication->plane);
203 }
204
205 short CMonster::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject)
206 {
207 short returnValue = CThing::Collision(sender, left, top, right, bottom, forcex, forcey, pfx, pfy, sourceWeight, collisionObject);
208 if (returnValue && sender->typeID & kPlayer) {
209 if (dieFrame == -1) ((CThing *)sender)->OnDamage(info->touchBlessure);
210 if (info->canExplode && dieFrame == -1) OnKill();
211 }
212
213 return returnValue;
214 }
215
216 short CMonster::Think()
217 {
218 tThingList *bulletEntry;
219 short elemx, elemy;
220 double directionx, directiony;
221
222 CObject::Think();
223
224 if (dieFrame != -1) return kNoEvent;
225 if (gApplication->firstPlayRound) OnStart();
226
227 if (ABS(FindPlayerX()) > gConst->kActivateDistance) return kNoEvent;
228
229 // Checking for a treatment event
230 bulletEntry = gApplication->bulletList;
231 while (bulletEntry) {
232 if (((CBullet *)(bulletEntry->thing))->AmIATreatment(xs, ys, xe, ye, directionx, directiony)) {
233 OnTreatment(directionx, directiony);
234 bulletEntry = 0L;
235 }else bulletEntry = bulletEntry->next;
236 }
237
238 // Checking for an abyss event
239 if (forceVectorX > 0) {
240 elemx = (short)(xe + forceVectorX) / kElementSize;
241 elemy = (short)ym / kElementSize;
242 }else{
243 elemx = (short)(xs + forceVectorX) / kElementSize;
244 elemy = (short)ym / kElementSize;
245 }
246 if ((lastCollisionCode & kCollisionOnBottom) && elemx > 0 && elemy > 0 && elemx < kLevelWidth && elemy + 1 < kLevelHeight) {
247 if (gLevel->level[elemy][elemx]->background &&
248 gLevel->level[elemy + 1][elemx]->background) OnAbyss();
249 }
250
251 // Checking for a collision event
252 if (lastCollisionCode & ~kCollisionOnBottom) OnCollision();
253
254 // Checking for a landing event
255 if (flying && lastCollisionCode & kCollisionOnBottom) OnLanding();
256 flying = !(lastCollisionCode & kCollisionOnBottom);
257
258 // Sending an idle event
259 OnIdle();
260
261 return kNoEvent;
262 }
263
264 void CMonster::OnStart() {}
265 void CMonster::OnAbyss() {}
266 void CMonster::OnCollision() {}
267 void CMonster::OnLanding() {}
268 void CMonster::OnIdle() {}
269 void CMonster::OnTreatment(double directionx, double directiony) {}
270 void CMonster::OnShootSuccessful() {}
271 void CMonster::OnShootNotSuccessful() {}
272 void CMonster::OnTeleport() {}
273
274
275 // ---------------------------------------------
276 void CMonster::OnDamage(short blessure)
277 // Event occurs, when a monster is hit by something (bullet etc.)
278 {
279 if (dieFrame == -1 && lastBlessureTime < lastTime) {
280 health -= blessure;
281 if (health < 0)
282 OnKill();
283 else
284 lastBlessureTime = lastTime + gConst->kBlessureInvulnerabilityTime;
285 }
286 }
287
288
289 void CMonster::OnKill()
290 {
291 dieFrameTime = lastTime + gConst->kDieFrameTime;
292
293 dieFrame = 0;
294 }
295
296 void CMonster::OnTouch(CObject *touch)
297 {
298 if (dieFrame == -1) ((CThing *)touch)->OnDamage(info->touchBlessure);
299 }
300
301
302 double CMonster::FindPlayerX()
303 {
304 return gLevel->player->xm - xm;
305 }
306
307 double CMonster::FindPlayerY()
308 {
309 return gLevel->player->ym - ym;
310 }
311
312
313 short CMonster::Write(FILE *f)
314 {
315 long size = 0;
316
317 WRITEDATA(size);
318 WRITEDATA(typeID);
319 WRITEDATA(thingNumber);
320
321 size += CThing::Write(f);
322 if (weapon) size += weapon->Write(f);
323
324 WRITEDATA(speed);
325 WRITEDATA(lastWalkTime);
326 WRITEDATA(lastShootTime);
327 WRITEDATA(walkFrame);
328 WRITEDATA(status);
329 WRITEDATA(lastCollisionCode);
330 WRITEDATA(flying);
331 WRITEDATA(teleportDeltaTime);
332 WRITEDATA(teleportCounter);
333 WRITEDATA(lastBlessureTime);
334 WRITEDATA(dieFrameTime);
335 WRITEDATA(dieFrame);
336 WRITEDATA(doDarken);
337 WRITEDATA(health);
338
339 FINISHWRITE;
340
341 return size;
342 }
343
344 void CMonster::Read(FILE *f)
345 {
346 long size = 0;
347
348 READDATA(size);
349 READDATA(typeID);
350 READDATA(thingNumber);
351
352 CThing::Read(f);
353
354 OnAllocate();
355
356 if (weapon) weapon->Read(f);
357
358 READDATA(speed);
359 READDATA(lastWalkTime);
360 READDATA(lastShootTime);
361 READDATA(walkFrame);
362 READDATA(status);
363 READDATA(lastCollisionCode);
364 READDATA(flying);
365 READDATA(teleportDeltaTime);
366 READDATA(teleportCounter);
367 READDATA(lastBlessureTime);
368 READDATA(dieFrameTime);
369 READDATA(dieFrame);
370 READDATA(doDarken);
371 READDATA(health);
372
373 if (dieFrame != -1) gApplication->Dequeue(&gApplication->collisionThingList, this);
374 }
0 #ifndef __AMP_MONSTER__
1 #define __AMP_MONSTER__
2
3 #include "Thing.hpp"
4 #include "ObjInfo.hpp"
5 #include "Weapon.hpp"
6
7 enum { // stati
8 kMonsterForward,
9 kMonsterBackward,
10 kMonsterWaiting,
11 kMonsterFastForward, // for Warg
12 kMonsterFastBackward
13 };
14
15 // if no shoots are successful, so shoot at least every 4 seconds
16 const short kMonsterMaxShootDelay = 4000;
17 const short kWalkerWaitAfterShooting = 800;
18
19 class CMonster : public CThing {
20 protected:
21 CShape *moveShapes[3];
22 CShape *jumpShape;
23 CShape *attackShape;
24 CShape *deathShapes[3];
25
26 CWeapon *weapon;
27 short noWeapon;
28
29 tMonsterInfo *info;
30 long lastWalkTime, lastShootTime;
31 short walkFrame;
32 CShape *currentShape;
33 double speed;
34
35 short status;
36 short lastCollisionCode;
37 short flying;
38 long teleportDeltaTime; // actually only used by the player
39 short teleportCounter;
40 long lastBlessureTime;
41 long dieFrameTime;
42 short dieFrame;
43 short doDarken;
44
45 short health;
46
47 // Events
48 virtual void OnStart();
49 virtual void OnAbyss();
50 virtual void OnCollision();
51 virtual void OnLanding();
52 virtual void OnIdle();
53 virtual void OnTreatment(double directionx, double directiony);
54 virtual void OnTeleport(); // actually only used by the player
55
56 double FindPlayerX();
57 double FindPlayerY();
58 CWeapon *CreateWeapon(short weapon);
59
60 public:
61 CMonster(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
62 ~CMonster();
63
64 void OnAllocate();
65
66 void LinkInLists();
67 void UnlinkInLists();
68
69 // public events
70 virtual void OnShootSuccessful();
71 virtual void OnShootNotSuccessful();
72 virtual void OnDamage(short blessure);
73 virtual void OnKill();
74 virtual void OnTouch(CObject *touch);
75
76 virtual void Render(short planeX, short planeY, tRect *clipRect);
77 short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
78 short Think();
79 void Move();
80 short Forces();
81
82 virtual short Write(FILE *f);
83 virtual void Read(FILE *f);
84 };
85
86
87
88 #endif
0 #include "Monstrxx.hpp"
1 #include "Level.hpp"
2 #include "ConstVal.hpp"
3 #include "Appl.hpp"
4 #include "System.hpp"
5
6 extern CLevel *gLevel;
7 extern tConstValues *gConst;
8 extern CApplication *gApplication;
9 extern CSystem *gSystem;
10
11 /* ###########################################
12 CREEPER CLASS EVENTS
13 ############################################### */
14 CCreeper::CCreeper(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) : CMonster(initx, inity, width, height, number, monsterInfo)
15 {
16 }
17
18 CCreeper::~CCreeper()
19 {}
20
21 void CCreeper::OnStart()
22 {
23 OnLanding();
24 }
25
26 void CCreeper::OnLanding()
27 {
28
29 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
30 }
31
32 void CCreeper::OnCollision()
33 {
34 status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
35 }
36
37 void CCreeper::OnAbyss()
38 {
39 if (FindPlayerY() < 0) status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
40 }
41
42 void CCreeper::OnIdle()
43 {
44 lookDirection = (status == kMonsterBackward ? kLookingLeft : kLookingRight);
45 forceVectorX = speed * deltaTime * gConst->kVelocityUnit * (status == kMonsterForward ? 1.0 : -1.0);
46 }
47
48
49 /* ###########################################
50 WALKER CLASS EVENTS
51 ############################################### */
52
53 CWalker::CWalker(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) : CMonster(initx, inity, width, height, number, monsterInfo)
54 {
55 lastShoot = 0;
56 currentShootDelay = 0;
57 nextShootTime = 0;
58 }
59
60 CWalker::~CWalker()
61 {}
62
63 void CWalker::OnStart()
64 {
65 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
66 }
67
68 void CWalker::OnCollision()
69 {
70 status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
71 }
72
73 void CWalker::OnAbyss()
74 {
75 status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
76 }
77
78 void CWalker::OnIdle()
79 {
80 double px = FindPlayerX();
81
82 if (!noWeapon && lastTime > nextShootTime) {
83 lookDirection = (FindPlayerX() < 0 ? kLookingLeft : kLookingRight);
84
85 if (weapon->Shoot(px, FindPlayerY(), (px > 0 ? px + xs : px + xe))) {
86 nextShootTime = lastTime + currentShootDelay;
87 lastShoot = lastTime + kWalkerWaitAfterShooting;
88 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
89 };
90 }
91
92 lookDirection = (status == kMonsterBackward ? kLookingLeft : kLookingRight);
93
94 if (lastTime > lastShoot && lastTime > lastBlessureTime) forceVectorX = speed * deltaTime * gConst->kVelocityUnit * (status == kMonsterForward ? 1.0 : -1.0);
95 }
96
97
98 void CWalker::OnTreatment(double directionx, double directiony)
99 {
100 if (directiony > 0) {
101 if (directionx > 0) status = kMonsterForward; else status = kMonsterBackward;
102 }
103 }
104
105
106 void CWalker::OnShootSuccessful()
107 {
108 currentShootDelay = 0;
109 }
110
111 void CWalker::OnShootNotSuccessful()
112 {
113 if (currentShootDelay < kMonsterMaxShootDelay) currentShootDelay += kMonsterMaxShootDelay / 4;
114 }
115
116
117 /* ###########################################
118 JUMPER CLASS EVENTS
119 ############################################### */
120
121
122 CJumper::CJumper(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) : CMonster(initx, inity, width, height, number, monsterInfo)
123 {
124 inJump = 0;
125 nextShootTime = 0;
126 currentShootDelay = 0;
127 lastShoot = 0;
128 }
129
130 CJumper::~CJumper()
131 {}
132
133 void CJumper::OnStart()
134 {
135 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
136 }
137
138 void CJumper::OnCollision()
139 {
140 short elemx, elemy;
141 short condition;
142
143 // Is there only a step, so the jumper can jump onto the step (but only when the player
144 // is in this direction)
145 if (status == kMonsterForward) {
146 elemx = (short)((xs + (xe - xs) * 0.5) / kElementSize) +1;
147 condition = FindPlayerX() > 0 && elemx < kLevelWidth;
148 }else{
149 elemx = (short)((xs + (xe - xs) * 0.5) / kElementSize) -1;
150 condition = FindPlayerX() < 0 && elemx > 0;
151 }
152 elemy = (short)((ys + (ye - ys) * 0.5) / kElementSize) -1;
153
154 if (condition && elemy >= 0 && gLevel->level[elemy][elemx]->background)
155 Jump();
156 else if (!inJump)
157 status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
158 }
159
160 void CJumper::OnAbyss()
161 {
162 short condition;
163
164 // If there's an abyss, the jumper just jumps (only if the player is in the right direction)
165 if (status == kMonsterForward) {
166 condition = FindPlayerX() > 0;
167 }else{
168 condition = FindPlayerX() < 0;
169 }
170
171 if (condition)
172 Jump();
173 else
174 status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
175 }
176
177 void CJumper::OnIdle()
178 {
179 double px = FindPlayerX();
180 short oldStatus = status;
181
182 if (!noWeapon && lastTime > nextShootTime) {
183 lookDirection = (FindPlayerX() < 0 ? kLookingLeft : kLookingRight);
184 if (weapon->Shoot(px, FindPlayerY(), (px > 0 ? px + xs : px + xe))) {
185 nextShootTime = lastTime + currentShootDelay;
186 lastShoot = lastTime + kWalkerWaitAfterShooting;
187 }
188
189
190 }
191 lookDirection = (status == kMonsterBackward ? kLookingLeft : kLookingRight);
192
193 if (lastTime > lastShoot && lastTime > lastBlessureTime) forceVectorX = speed * deltaTime * gConst->kVelocityUnit * (status == kMonsterForward ? 1.0 : -1.0);
194 }
195
196
197 void CJumper::OnTreatment(double directionx, double directiony)
198 {
199 if (ABS(directiony / directionx) > 1.0) { // the bullet comes vertical
200 if (directiony > 0) {
201 if (directionx > 0) status = kMonsterForward; else status = kMonsterBackward;
202 }
203 }else{
204 Jump();
205 }
206 }
207
208 void CJumper::OnLanding()
209 {
210 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
211 inJump = 0;
212 }
213
214 void CJumper::OnShootSuccessful()
215 {
216 currentShootDelay = 0;
217 }
218
219 void CJumper::OnShootNotSuccessful()
220 {
221 if (currentShootDelay < kMonsterMaxShootDelay) currentShootDelay += kMonsterMaxShootDelay / 4;
222 }
223
224 void CJumper::Jump()
225 {
226 if (!inJump) {
227 forceVectorY = -gConst->kJumperJumpAcceleration * gConst->kVelocityUnit * deltaTime;
228 inJump = 1;
229 }
230 }
231
232
233 /* ###########################################
234 FLYER CLASS EVENTS
235 ############################################### */
236
237 CFlyer::CFlyer(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) : CMonster(initx, inity, width, height, number, monsterInfo)
238 {
239 weight = 10;
240 rescueMeX = 0;
241 rescueMeY = 0;
242 weightless = 1;
243
244 nextShootTime = 0;
245 currentShootDelay = 0;
246 lastShoot = 0;
247 }
248
249 CFlyer::~CFlyer()
250 {}
251
252 void CFlyer::OnIdle()
253 {
254 double px = FindPlayerX();
255
256 if (!noWeapon && lastTime > nextShootTime) {
257 lookDirection = (FindPlayerX() < 0 ? kLookingLeft : kLookingRight);
258 if (weapon->Shoot(px, FindPlayerY(), (px > 0 ? px + xs : px + xe))) {
259 nextShootTime = lastTime + currentShootDelay;
260 lastShoot = lastTime + kWalkerWaitAfterShooting;
261 }
262 }
263
264 if (lastTime > lastShoot) {
265 if (!rescueMeX && !rescueMeY) {
266 forceVectorX = speed * deltaTime * gConst->kVelocityUnit * SIGN(FindPlayerX());
267 forceVectorY = speed * deltaTime * gConst->kVelocityUnit * SIGN(FindPlayerY());
268 }else{
269 forceVectorX = rescueMeX * deltaTime;
270 forceVectorY = rescueMeY * deltaTime;
271 rescueMeX = 0;
272 rescueMeY = 0;
273 }
274 }
275 lookDirection = SIGN(forceVectorX);
276 }
277
278 void CFlyer::OnTreatment(double directionx, double directiony)
279 {
280 double len = sqrt(directionx * directionx + directiony * directiony);
281
282 rescueMeX = SIGN(directionx) * directiony * speed * gConst->kVelocityUnit / len * 2.0;
283 rescueMeY = SIGN(directiony) * -1.0 * directionx * speed * gConst->kVelocityUnit / len * 2.0;
284 }
285
286
287 void CFlyer::OnShootSuccessful()
288 {
289 currentShootDelay = 0;
290 }
291
292 void CFlyer::OnShootNotSuccessful()
293 {
294 if (currentShootDelay < kMonsterMaxShootDelay) currentShootDelay += kMonsterMaxShootDelay / 4;
295 }
296
297 void CFlyer::OnKill()
298 {
299 weightless = 0;
300 CMonster::OnKill();
301 }
302
303
304 /* ###########################################
305 WARG CLASS EVENTS
306 ############################################### */
307
308 CWarg::CWarg(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) : CMonster(initx, inity, width, height, number, monsterInfo)
309 {
310 inJump = 0;
311 if (monsterInfo) OnAllocate();
312 deathTime = 0;
313
314 nextShootTime = 0;
315 currentShootDelay = 0;
316 lastShoot = 0;
317 speedup = 1;
318 }
319
320 void CWarg::OnAllocate()
321 {
322 farWeapon = CreateWeapon(info->weapon + 1);
323 }
324
325 CWarg::~CWarg()
326 {
327 if (farWeapon) delete farWeapon;
328 }
329
330 void CWarg::OnStart()
331 {
332 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
333 }
334
335 void CWarg::OnCollision()
336 {
337 status = (lastCollisionCode & kCollisionOnRight ? kMonsterBackward : kMonsterForward);
338 speedup = 1;
339 }
340
341 void CWarg::OnAbyss()
342 {
343 status = (status == kMonsterForward ? kMonsterBackward : kMonsterForward);
344 speedup = 1.0;
345 }
346
347 void CWarg::OnIdle()
348 {
349 double px = FindPlayerX();
350 CWeapon *currentWeapon;
351
352 if (!noWeapon && lastTime > nextShootTime) {
353 lookDirection = (px < 0 ? kLookingLeft : kLookingRight);
354
355 currentWeapon = (ABS(px) > gConst->kWargNearWeaponRadix ? farWeapon : weapon);
356
357 if (currentWeapon->Shoot(px, FindPlayerY(), (px > 0 ? px + xs : px + xe))) {
358 nextShootTime = lastTime + currentShootDelay;
359 lastShoot = lastTime + kWalkerWaitAfterShooting;
360 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
361 };
362 }
363
364 lookDirection = (status == kMonsterBackward ? kLookingLeft : kLookingRight);
365
366 if (lastTime > lastShoot) forceVectorX = speed * deltaTime * lookDirection * gConst->kVelocityUnit * speedup;
367 }
368
369
370 void CWarg::OnTreatment(double directionx, double directiony)
371 {
372 if (ABS(directiony / directionx) > 1.0) { // the bullet comes vertical
373 if (directiony > 0) {
374 if (directionx > 0) status = kMonsterForward; else status = kMonsterBackward;
375 }
376 }else{
377 Jump();
378 status = (FindPlayerX() < 0 ? kMonsterBackward : kMonsterForward);
379 }
380 }
381
382 void CWarg::OnLanding()
383 {
384 inJump = 0;
385 }
386
387 void CWarg::Jump()
388 {
389 if (!inJump) {
390 forceVectorY = -gConst->kWargJumpAcceleration;
391 inJump = 1;
392 }
393 }
394
395 // ---------------------------------------------
396 void CWarg::OnDamage(short blessure)
397 // Event occurs, when a monster is hit by something (bullet etc.)
398 {
399 if (dieFrame == -1 && lastBlessureTime < lastTime) {
400 health -= blessure;
401 if (health < 0) {
402 OnKill();
403 deathTime = lastTime + gConst->kDelayAfterWargDeath;
404 } else {
405 lastBlessureTime = lastTime + gConst->kBlessureInvulnerabilityTime;
406 speedup = gConst->kWargFastSpeedup;
407 }
408 }
409 }
410
411 void CWarg::TestForDamage(double xb, double yb, short rad, short blessure)
412 {
413 CThing::TestForDamage(xb, yb, rad + dx / 2, blessure);
414 }
415
416 void CWarg::Render(short planeX, short planeY, tRect *clipRect)
417 {
418 CMonster::Render(planeX, planeY, clipRect);
419 if (deathTime && deathTime < gSystem->GetTicks()) gApplication->command = kCmdNextLevel;
420 }
421
422
423 short CWalker::Write(FILE *f)
424 {
425 long size = 0;
426
427 WRITEDATA(size);
428 WRITEDATA(typeID);
429 WRITEDATA(thingNumber);
430
431 size += CMonster::Write(f);
432
433 WRITEDATA(nextShootTime);
434 WRITEDATA(currentShootDelay);
435 WRITEDATA(lastShoot);
436
437 FINISHWRITE;
438
439 return size;
440 }
441
442 void CWalker::Read(FILE *f)
443 {
444 long size = 0;
445
446 READDATA(size);
447 READDATA(typeID);
448 READDATA(thingNumber);
449
450 CMonster::Read(f);
451
452 READDATA(nextShootTime);
453 READDATA(currentShootDelay);
454 READDATA(lastShoot);
455 }
456
457
458 short CJumper::Write(FILE *f)
459 {
460 long size = 0;
461
462 WRITEDATA(size);
463 WRITEDATA(typeID);
464 WRITEDATA(thingNumber);
465
466 size += CMonster::Write(f);
467
468 WRITEDATA(nextShootTime);
469 WRITEDATA(currentShootDelay);
470 WRITEDATA(lastShoot);
471 WRITEDATA(inJump);
472
473 FINISHWRITE;
474
475 return size;
476 }
477
478 void CJumper::Read(FILE *f)
479 {
480 long size = 0;
481
482 READDATA(size);
483 READDATA(typeID);
484 READDATA(thingNumber);
485
486 CMonster::Read(f);
487
488 READDATA(nextShootTime);
489 READDATA(currentShootDelay);
490 READDATA(lastShoot);
491 READDATA(inJump);
492 }
493
494 short CFlyer::Write(FILE *f)
495 {
496 long size = 0;
497
498 WRITEDATA(size);
499 WRITEDATA(typeID);
500 WRITEDATA(thingNumber);
501
502 size += CMonster::Write(f);
503
504 WRITEDATA(nextShootTime);
505 WRITEDATA(currentShootDelay);
506 WRITEDATA(lastShoot);
507 WRITEDATA(rescueMeX);
508 WRITEDATA(rescueMeY);
509
510 FINISHWRITE;
511
512 return size;
513 }
514
515 void CFlyer::Read(FILE *f)
516 {
517 long size = 0;
518
519 READDATA(size);
520 READDATA(typeID);
521 READDATA(thingNumber);
522
523 CMonster::Read(f);
524
525 READDATA(nextShootTime);
526 READDATA(currentShootDelay);
527 READDATA(lastShoot);
528 READDATA(rescueMeX);
529 READDATA(rescueMeY);
530 }
531
532
533 short CWarg::Write(FILE *f)
534 {
535 long size = 0;
536
537 WRITEDATA(size);
538 WRITEDATA(typeID);
539 WRITEDATA(thingNumber);
540
541 size += CMonster::Write(f);
542 if (farWeapon) size += farWeapon->Write(f);
543
544 WRITEDATA(nextShootTime);
545 WRITEDATA(currentShootDelay);
546 WRITEDATA(lastShoot);
547 WRITEDATA(inJump);
548 WRITEDATA(speedup);
549
550 FINISHWRITE;
551
552 return size;
553 }
554
555
556 void CWarg::Read(FILE *f)
557 {
558 long size = 0;
559
560 READDATA(size);
561 READDATA(typeID);
562 READDATA(thingNumber);
563
564 CMonster::Read(f);
565
566 OnAllocate();
567
568 if (farWeapon) farWeapon->Read(f);
569
570 READDATA(nextShootTime);
571 READDATA(currentShootDelay);
572 READDATA(lastShoot);
573 READDATA(inJump);
574 READDATA(speedup);
575 }
0 #ifndef __MONSTER_XTRAS__
1 #define __MONSTER_XTRAS__
2
3 #include "Monster.hpp"
4 #include "ObjInfo.hpp"
5
6 class CCreeper : public CMonster {
7 protected:
8 void OnStart();
9 void OnCollision();
10 void OnLanding();
11 void OnIdle();
12 void OnAbyss();
13
14 public:
15 CCreeper(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
16 ~CCreeper();
17 };
18
19 class CWalker : public CMonster {
20 protected:
21 long nextShootTime;
22 long currentShootDelay;
23 long lastShoot;
24
25 void OnStart();
26 void OnCollision();
27 void OnIdle();
28 void OnAbyss();
29 void OnTreatment(double dirx, double diry);
30
31 public:
32 CWalker(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
33 ~CWalker();
34
35 void OnShootSuccessful();
36 void OnShootNotSuccessful();
37
38 short Write(FILE *f);
39 void Read(FILE *f);
40 };
41
42 class CJumper : public CMonster {
43 protected:
44 long nextShootTime;
45 long currentShootDelay;
46 long lastShoot;
47 short inJump;
48
49 void OnStart();
50 void OnCollision();
51 void OnIdle();
52 void OnAbyss();
53 void OnTreatment(double dirx, double diry);
54 void OnLanding();
55
56 void Jump();
57
58 public:
59 CJumper(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
60 ~CJumper();
61
62 void OnShootSuccessful();
63 void OnShootNotSuccessful();
64
65 short Write(FILE *f);
66 void Read(FILE *f);
67 };
68
69
70 class CFlyer : public CMonster {
71 protected:
72 long nextShootTime;
73 long currentShootDelay;
74 long lastShoot;
75 double rescueMeX, rescueMeY;
76
77 void OnIdle();
78 void OnTreatment(double dirx, double diry);
79
80 public:
81 CFlyer(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
82 ~CFlyer();
83
84 void OnShootSuccessful();
85 void OnShootNotSuccessful();
86 void OnKill();
87
88 short Write(FILE *f);
89 void Read(FILE *f);
90 };
91
92 class CWarg : public CMonster {
93 protected:
94 CWeapon *farWeapon;
95 long nextShootTime;
96 long currentShootDelay;
97 long lastShoot;
98 short inJump;
99 double speedup;
100 long deathTime;
101
102 void OnStart();
103 void OnCollision();
104 void OnIdle();
105 void OnAbyss();
106 void OnTreatment(double dirx, double diry);
107 void OnLanding();
108
109 void Jump();
110
111 public:
112 CWarg(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
113 ~CWarg();
114
115 void OnAllocate();
116
117 void TestForDamage(double xb, double yb, short rad, short blessure);
118 void OnDamage(short blessure);
119 void Render(short planeX, short planeY, tRect *clipRect);
120
121 short Write(FILE *f);
122 void Read(FILE *f);
123 };
124
125 #endif
0 #include "ObjInfo.hpp"
1 #include "Monster.hpp"
2 #include "Monstrxx.hpp"
3 #include "Player.hpp"
4 #include "Item.hpp"
5 #include "ShapeDes.hpp"
6 #include "Appl.hpp"
7 #include "Pltform.hpp"
8 #include "ConstVal.hpp"
9 #include "System.hpp"
10 #include <stdio.h>
11
12 extern CApplication *gApplication;
13 extern tConstValues *gConst;
14 extern CSystem *gSystem;
15 extern FILE *logFile;
16
17 short *FindDescriptor(short id);
18
19 CObjInfo::CObjInfo(short levelNumber)
20 {
21 MSG("LoadMonsters\n");
22 LoadMonsters(levelNumber);
23 MSG("LoadItems\n");
24 LoadItems(levelNumber);
25 MSG("LoadWeapons\n");
26 LoadWeapons(levelNumber);
27 for (short n = 0; n < kNumPlatforms; n ++) platformInfo[n] = new tPlatformInfo;
28 }
29
30 CObjInfo::~CObjInfo()
31 {
32 short n;
33
34
35 for (n = 0; n < kNumMonster; n ++) delete monsterInfo[n];
36 for (n = 0; n < kNumItems; n ++) delete itemInfo[n];
37 for (n = 0; n < kNumWeapons; n ++) delete weaponInfo[n];
38 for (n = 0; n < kNumPlatforms; n ++) delete platformInfo[n];
39 }
40
41
42 void CObjInfo::LoadMonsters(short levelNumber)
43 {
44 if (!OpenDataFile(gSystem->QualifyDataDir(gConst->kFileMonster))) gSystem->Error("Cannot find file kFileMonster or unable to open it", 0); // by LL
45 SetFilePos(levelNumber * kNumMonster * sizeof(tMonsterInfo));
46
47 for (short n = 0; n < kNumMonster; n ++) {
48 monsterInfo[n] = new tMonsterInfo;
49 ReadData(monsterInfo[n], sizeof(tMonsterInfo));
50
51 TRANS_PUT_NUM(monsterInfo[n]->canExplode);
52 for (short m = 0; m < 3; m ++) {
53 TRANS_PUT_NUM(monsterInfo[n]->moveShapes[m]);
54 TRANS_PUT_NUM(monsterInfo[n]->additionalData[m]);
55 TRANS_PUT_NUM(monsterInfo[n]->deathShapes[m]);
56 }
57 TRANS_PUT_NUM(monsterInfo[n]->touchBlessure);
58 TRANS_PUT_NUM(monsterInfo[n]->additionalData[0]);
59 TRANS_PUT_NUM(monsterInfo[n]->additionalData[1]);
60 //TRANS_PUT_NUM(monsterInfo[n]->jumpShape);
61 TRANS_PUT_NUM(monsterInfo[n]->attackShape);
62 TRANS_PUT_NUM(monsterInfo[n]->unused);
63 TRANS_PUT_NUM(monsterInfo[n]->kind);
64 TRANS_PUT_NUM(monsterInfo[n]->speed);
65 TRANS_PUT_NUM(monsterInfo[n]->energy);
66 TRANS_PUT_NUM(monsterInfo[n]->weapon);
67 TRANS_PUT_NUM(monsterInfo[n]->aggression);
68 TRANS_PUT_NUM(monsterInfo[n]->invisible);
69 }
70
71 CloseDataFile();
72 }
73
74
75 void CObjInfo::LoadItems(short levelNumber)
76 {
77 if (!OpenDataFile(gSystem->QualifyDataDir(gConst->kFileObjects))) gSystem->Error("Cannot find file kFileObjects or uable to open it", 0); // by LL
78 SetFilePos(levelNumber * kNumItems * sizeof(tItemInfo));
79
80 for (short n = 0; n < kNumItems; n ++) {
81 itemInfo[n] = new tItemInfo;
82 ReadData(itemInfo[n], sizeof(tItemInfo));
83
84 TRANS_PUT_NUM(itemInfo[n]->iconID);
85 TRANS_PUT_NUM(itemInfo[n]->data);
86 TRANS_PUT_NUM(itemInfo[n]->flags);
87 }
88
89 CloseDataFile();
90 }
91
92 void CObjInfo::LoadWeapons(short levelNumber)
93 {
94 if (!OpenDataFile(gSystem->QualifyDataDir(gConst->kFileWeapon))) gSystem->Error("Cannot find file kFileWeapon or unable to open it", 0); // by LL
95
96 SetFilePos(levelNumber * kNumWeapons * sizeof(tWeaponInfo));
97
98 for (short n = 0; n < kNumWeapons; n ++) {
99 weaponInfo[n] = new tWeaponInfo;
100 ReadData(weaponInfo[n], sizeof(tWeaponInfo));
101
102 TRANS_PUT_NUM(weaponInfo[n]->art);
103 TRANS_PUT_NUM(weaponInfo[n]->projectileShapes[0]);
104 TRANS_PUT_NUM(weaponInfo[n]->projectileShapes[1]);
105 for (short m = 0; m < 5; m ++) {
106 TRANS_PUT_NUM(weaponInfo[n]->detonationShapes[m]);
107 }
108 TRANS_PUT_NUM(weaponInfo[n]->effect);
109 TRANS_PUT_NUM(weaponInfo[n]->speed);
110 TRANS_PUT_NUM(weaponInfo[n]->error);
111 TRANS_PUT_NUM(weaponInfo[n]->repetition);
112 TRANS_PUT_NUM(weaponInfo[n]->munition);
113 TRANS_PUT_NUM(weaponInfo[n]->rad);
114 TRANS_PUT_NUM(weaponInfo[n]->damage);
115 }
116
117 CloseDataFile();
118 }
119
120 void CObjInfo::LoadPlatforms(short levelNumber)
121 {
122 if (!OpenDataFile(gSystem->QualifyDataDir(gConst->kFilePlatform))) gSystem->Error("Cannot find file kFilePlatform or unable to open it", 0); // by LL
123 SetFilePos(levelNumber * kNumPlatforms * sizeof(tPlatformInfo));
124
125 for (short n = 0; n < kNumPlatforms; n ++) {
126 ReadData(platformInfo[n], sizeof(tPlatformInfo));
127
128 TRANS_PUT_NUM2(platformInfo[n]->ID);
129 TRANS_PUT_NUM2(platformInfo[n]->startx);
130 TRANS_PUT_NUM2(platformInfo[n]->starty);
131 TRANS_PUT_NUM2(platformInfo[n]->endx);
132 TRANS_PUT_NUM2(platformInfo[n]->endy);
133 TRANS_PUT_NUM2(platformInfo[n]->speed);
134 TRANS_PUT_NUM2(platformInfo[n]->delay);
135 TRANS_PUT_NUM2(platformInfo[n]->iconID);
136 TRANS_PUT_NUM2(platformInfo[n]->refNum);
137
138 //for (short m = 0; m < 8; m ++) TRANS_PUT_NUM2(platformInfo[n]->vars[m]);
139 }
140 }
141
142
143 short *FindDescriptor(short id)
144 {
145 short n;
146 for (n = 0; n < kNumShapes && id != kShapeDescriptor[n][0]; n++) {}
147 if (n < kNumShapes) return kShapeDescriptor[n];
148 else{
149 for (n = 0; n < kNumTextures && id != kTextureDescriptor[n][0]; n++) {}
150 if (n < kNumTextures) return kTextureDescriptor[n]; else return 0L;
151 }
152 }
153
154 //-----------------------------------------------------------------
155 CThing *CObjInfo::CreateMonster(short monsterNo, short j, short k)
156 /* In: monsterNo: Number of monster in monster info table
157 j, k: position in level elements
158 Out: new monster object
159
160 Creates a new monster object at position j, k (in level elements)
161 */
162 {
163 short *descriptor;
164
165 if (monsterNo != -1) {
166 descriptor = FindDescriptor(monsterInfo[monsterNo]->moveShapes[0]);
167
168 switch (monsterInfo[monsterNo]->kind) {
169 case kClassPlayer: return new CPlayer(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], monsterNo, monsterInfo[monsterNo]); break;
170 case kClassCreeper: return new CCreeper(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], monsterNo, monsterInfo[monsterNo]); break;
171 case kClassWalker: return new CWalker(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], monsterNo, monsterInfo[monsterNo]); break;
172 case kClassJumper: return new CJumper(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], monsterNo, monsterInfo[monsterNo]); break;
173 case kClassFlyer: return new CFlyer(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], monsterNo, monsterInfo[monsterNo]); break;
174 case kClassWarg: return new CWarg(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], monsterNo, monsterInfo[monsterNo]); break;
175 }
176 }
177 return 0L;
178 }
179
180 //------------------------------------------------------------------
181 CThing *CObjInfo::CreateItem(short itemNo, short j, short k)
182 /* In: itemNo: Number of item in item info record
183 j, k: position in level elements
184 Out: new item object
185 */
186 {
187 short *descriptor;
188
189 if (itemNo >= 0 && itemNo < kNumItems) {
190 descriptor = FindDescriptor(itemInfo[itemNo]->iconID);
191 switch (itemInfo[itemNo]->flags & 3) {
192 case kClassBackgroundItem: return new CBackgroundItem(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], itemNo, itemInfo[itemNo]); break;
193 case kClassUnpassableItem: return new CStaticItem(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], itemNo, itemInfo[itemNo]); break;
194 case kClassMovableItem: return new CMovableItem(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], itemNo, itemInfo[itemNo]); break;
195 case kClassPortableItem: return new CPortableItem(j * kElementSize + kElementSize / 2, k * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], itemNo, itemInfo[itemNo], itemNo); break;
196 }
197 }
198 return 0L;
199 }
200
201 void CObjInfo::CreatePlatforms()
202 {
203 short *descriptor;
204 CThing *temp;
205
206 for (short n = 0; n < kNumPlatforms; n ++) {
207 if (platformInfo[n]->exists) {
208 descriptor = FindDescriptor(platformInfo[n]->iconID);
209 temp = new CPlatform(platformInfo[n]->startx * kElementSize + kElementSize / 2, platformInfo[n]->starty * kElementSize + kElementSize / 2, descriptor[3], descriptor[4], n, platformInfo[n]);
210 gApplication->platformTable[n] = (CPlatform *)temp;
211 }else gApplication->platformTable[n] = 0L;
212 }
213 }
214
215 short CObjInfo::GetMonsterType(short ref)
216 {
217 return (ref == -1 ? -1 : monsterInfo[ref]->kind);
218 }
219
220 tItemInfo *CObjInfo::GetItemInfo(short ref)
221 {
222 return (ref == -1 ? 0L : itemInfo[ref]);
223 }
224
225 tWeaponInfo *CObjInfo::FindWeapon(short ref)
226 {
227 return weaponInfo[ref];
228 }
0 #ifndef __AMP_THINGINFO__
1 #define __AMP_THINGINFO__
2
3 #include "File.hpp"
4 #include "Thing.hpp"
5
6 const short kNumMonster = 12;
7 const short kNumItems = 42;
8 const short kNumWeapons = 16;
9 const short kNumPlatforms = 10;
10
11 struct tMonsterInfo {
12 Var2Bytes canExplode;
13 Var2Bytes moveShapes[3];
14 Var2Bytes touchBlessure;
15 Var2Bytes additionalData[2];
16 Var2Bytes jumpShape;
17 Var2Bytes attackShape;
18 Var1Byte unused;
19 Var2Bytes deathShapes[3];
20
21 Var2Bytes kind;
22 Var2Bytes speed;
23 Var2Bytes energy;
24 Var2Bytes weapon;
25 Var2Bytes aggression;
26 Var2Bytes invisible;
27 };
28
29 struct tItemInfo {
30 Var2Bytes iconID;
31 Var2Bytes data;
32 Var2Bytes flags;
33 };
34
35 struct tWeaponInfo {
36 Var2Bytes art;
37 Var2Bytes projectileShapes[2];
38 Var2Bytes detonationShapes[5];
39 Var2Bytes effect;
40 Var2Bytes speed;
41 Var2Bytes error;
42 Var2Bytes repetition;
43 Var2Bytes munition;
44 Var2Bytes rad;
45 Var2Bytes damage;
46 };
47
48 struct tPlatformInfo {
49 Var1Byte exists;
50 Var1Byte isElevator;
51 Var2Bytes ID;
52 Var2Bytes starty;
53 Var2Bytes startx;
54 Var2Bytes endy;
55 Var2Bytes endx;
56 Var2Bytes speed;
57 Var2Bytes delay;
58 Var2Bytes iconID;
59 Var2Bytes refNum;
60 Var1Byte playerControls;
61 Var1Byte stopsAtStart;
62 Var1Byte stopsAtEnd;
63 Var1Byte delaysBeforeStart;
64 Var1Byte hurts;
65 Var1Byte returnsOnHit;
66 Var1Byte activ;
67 Var1Byte unused;
68 };
69
70
71 class CObjInfo : public CFile {
72 protected:
73 void LoadMonsters(short levNum);
74 void LoadItems(short levNum);
75 void LoadWeapons(short levNum);
76
77 public:
78
79 tMonsterInfo* monsterInfo[kNumMonster];
80 tItemInfo* itemInfo[kNumItems];
81 tWeaponInfo* weaponInfo[kNumWeapons];
82
83 tPlatformInfo* platformInfo[kNumPlatforms];
84
85 CObjInfo(short levNum);
86 ~CObjInfo();
87
88 void LoadPlatforms(short levNum);
89
90 CThing *CreateMonster(short monsterNum, short j, short k);
91 CThing *CreateItem(short itemNum, short j, short k);
92
93 void CreatePlatforms();
94 short GetMonsterType(short ref);
95 tItemInfo *GetItemInfo(short ref);
96 tWeaponInfo *FindWeapon(short ref);
97 };
98
99 #endif
0 #include "Object.hpp"
1 #include "Appl.hpp"
2 #include "ConstVal.hpp"
3
4 #include <math.h>
5
6 enum {
7 kLeftTopCorner = 0,
8 kLeftBottomCorner = 1,
9 kRightTopCorner = 2,
10 kRightBottomCorner = 3
11 };
12
13 const double kCollisionThingDetectError = 3.0;
14
15 extern CApplication *gApplication;
16 extern CSystem *gSystem;
17 extern CLevel *gLevel;
18 extern tConstValues *gConst;
19
20 CObject::CObject(short initx, short inity, short width, short height)
21 {
22 typeID = 0;
23 typeID |= kObject;
24
25 xm = initx;
26 ym = inity;
27 xs = xm - width / 2;
28 ys = ym - height / 2;
29 xe = xs + width;
30 ye = ys + height;
31
32
33 forceVectorX = forceVectorY = 0;
34 gravitation = 0;
35 environmentForceX = environmentForceY = 0;
36 lastTime = 0;
37
38 // additinal initializations
39 weight = 0;
40 resForceX = resForceY = 0;
41 deltaTime = 0;
42 background = 0;
43 }
44
45 CObject::~CObject()
46 {}
47
48
49 short CObject::Think()
50 {
51 deltaTime = gApplication->deltaTime;
52 lastTime = gApplication->time;
53 pusher = 0L;
54 environmentForceX = environmentForceY = 0;
55
56 return kNoEvent;
57 }
58
59 short CObject::Forces()
60 {
61 resForceX = forceVectorX;
62 resForceY = forceVectorY + gravitation;
63
64 return kNoEvent;
65 }
66
67
68 void CalcSteps(double forcex, double forcey, double &sx, double &sy)
69 {
70 if (ABS(forcex) > ABS(forcey)) {
71 sx += SIGN(forcex);
72 sy += forcey / ABS(forcex);
73 }else{
74 sy += SIGN(forcey);
75 sx += forcex / ABS(forcey);
76 }
77 }
78
79 short CObject::ExertForce(double &forcex, double &forcey, short &collisionObject, CObject **obstacle)
80 {
81 double sx = 0, sy = 0;
82 short oldElem1x = -1, elem1x, oldElem1y = -1, elem1y;
83 short oldElem2x = -1, elem2x, oldElem2y = -1, elem2y;
84 short oldElem3x = -1, elem3x, oldElem3y = -1, elem3y;
85 short oldElem4x = -1, elem4x, oldElem4y = -1, elem4y;
86 short resultCode = 0, oldResultCode;
87 double oldForcex = forcex, oldForcey = forcey;
88 tThingList *currentEntry;
89 double postForcex, postForcey;
90 short tmpResultCode;
91
92 if (obstacle) *obstacle = 0L;
93 if (!forcex && !forcey) return kNoCollision;
94
95
96 do {
97 if (xs + sx <= 0) {
98 resultCode |= kCollisionOnLeft;
99 resultCode |= kCollisionWithLevelBorders;
100 }
101 if (xs + sx >= kLevelWidth * kElementSize -1) {
102 resultCode |= kCollisionOnRight;
103 resultCode |= kCollisionWithLevelBorders;
104 }
105 if (ys + sy <= 0) {
106 resultCode |= kCollisionOnTop;
107 resultCode |= kCollisionWithLevelBorders;
108 }
109
110 postForcex = (ABS(sx) > ABS(forcex) ? forcex : forcex - sx);
111 postForcey = (ABS(sy) > ABS(forcey) ? forcey : forcey - sy);
112
113 elem1x = (xs + sx) / kElementSize;
114 elem1y = (ys + sy) / kElementSize;
115 if ((elem1x != oldElem1x || elem1y != oldElem1y) && elem1x >= 0 && elem1y >= 0 && elem1x < kLevelWidth && elem1y < kLevelHeight) {
116 resultCode |= gLevel->level[elem1y][elem1x]->Collision(this, xs + sx, ys + sy, xe + sx, ye + sy, forcex, forcey, postForcex, postForcey, weight, collisionObject);
117 oldElem1x = elem1x;
118 oldElem1y = elem1y;
119 }
120
121 elem2x = (xe + sx) / kElementSize;
122 elem2y = (ys + sy) / kElementSize;
123 if ((elem2x != oldElem2x || elem2y != oldElem2y) && elem2x >= 0 && elem2y >= 0 && elem2x < kLevelWidth && elem2y < kLevelHeight) {
124 resultCode |= gLevel->level[elem2y][elem2x]->Collision(this, xs + sx, ys + sy, xe + sx, ye + sy, forcex, forcey, postForcex, postForcey, weight, collisionObject);
125 oldElem2x = elem2x;
126 oldElem2y = elem2y;
127 }
128
129 elem3x = (xs + sx) / kElementSize;
130 elem3y = (ye + sy) / kElementSize;
131 if ((elem3x != oldElem3x || elem3y != oldElem3y) && elem3x >= 0 && elem3y >= 0 && elem3x < kLevelWidth && elem3y < kLevelHeight) {
132 resultCode |= gLevel->level[elem3y][elem3x]->Collision(this, xs + sx, ys + sy, xe + sx, ye + sy, forcex, forcey, postForcex, postForcey, weight, collisionObject);
133 oldElem3x = elem3x;
134 oldElem3y = elem3y;
135 }
136
137 elem4x = (xe + sx) / kElementSize;
138 elem4y = (ye + sy) / kElementSize;
139 if ((elem4x != oldElem4x || elem4y != oldElem4y) && elem4x >= 0 && elem4y >= 0 && elem4x < kLevelWidth && elem4y < kLevelHeight) {
140 resultCode |= gLevel->level[elem4y][elem4x]->Collision(this, xs + sx, ys + sy, xe + sx, ye + sy, forcex, forcey, postForcex, postForcey, weight, collisionObject);
141 oldElem4x = elem4x;
142 oldElem4y = elem4y;
143 }
144
145 currentEntry = gApplication->collisionThingList;
146 while (currentEntry) {
147 oldResultCode = resultCode;
148 tmpResultCode = 0;
149 if (currentEntry->thing != this) tmpResultCode = currentEntry->thing->Collision(this, xs + sx, ys + sy, xe + sx, ye + sy, forcex, forcey, postForcex, postForcey, weight, collisionObject);
150 if (obstacle && tmpResultCode)
151 *obstacle = currentEntry->thing;
152 resultCode |= tmpResultCode;
153 currentEntry = currentEntry->next;
154 }
155
156 if ((resultCode & kCollisionOnTop) || (resultCode & kCollisionOnBottom)) {
157 if ((resultCode & kCollisionOnLeft) || (resultCode & kCollisionOnRight)) forcex = forcey = 0;
158 }
159
160 CalcSteps(forcex, forcey, sx, sy);
161
162 } while ((forcex || forcey) && (ABS(sx) < ABS(forcex) || !forcex) && (ABS(sy) < ABS(forcey) || !forcey));
163
164 if (ABS(forcex) > 1.0 && ((resultCode & kCollisionOnLeft) || (resultCode & kCollisionOnRight))) forcex = sx;
165 if (ABS(forcey) > 1.0 && ((resultCode & kCollisionOnTop) || (resultCode & kCollisionOnBottom))) forcey = sy;
166
167 if ((resultCode & kCollisionOnTop) && forcey < 0) forceVectorY = forcey = 0;
168 if (resultCode & kCollisionOnBottom) forceVectorY = forcey = 0;
169
170 return resultCode;
171 }
172
173 void CObject::OnTouch(CObject *touch) {}
174
175 // Determines if the line a1-a2 intersects with the line b1-b2 where equality does not count
176 short PointIntersection(double a1, double a2, double b1, double b2)
177 {
178 return !((a1 >= b1 && a2 >= b1 && a1 >= b2 && a2 >= b2) || (a1 <= b1 && a2 <= b1 && a1 <= b2 && a2 <= b2));
179 }
180
181 // Determines if the line a1-a2 intersects with the line b1-b2 where equality does count
182 short PointTouch(double a1, double a2, double b1, double b2)
183 {
184 return !((a1 > b1 && a2 > b1 && a1 > b2 && a2 > b2) || (a1 < b1 && a2 < b1 && a1 < b2 && a2 < b2));
185 }
186
187
188 short CObject::CollisionPossible(double ptx, double pty)
189 {
190 return (!background && ptx >= xs && ptx < xe && pty >= ys && pty < ye);
191 }
192
193 short CObject::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double postForcex, double postForcey, short sourceWeight, short &collisionObject)
194 {
195 if (background || (!forcex && !forcey)) return kNoCollision;
196
197
198 if (weight < sourceWeight) {
199 short carryx = 0, carryy = 0, collCode = kCollisionWithPushing;
200 double tmpForcex = forcex, tmpForcey = forcey;
201
202 pusher = sender;
203 sender->OnTouch(this);
204
205 if (((short)left >= (short)xe - kCollisionThingDetectError && (short)(left + forcex) <= (short)xe) ||
206 ((short)right <= (short)xs + kCollisionThingDetectError && (short)(right + forcex + kCollisionThingDetectError) >= (short)xs)) {
207 carryy = 1; forcey = 0;
208 }
209 if ((short)bottom <= (short)ys + kCollisionThingDetectError && (short)(bottom + forcey) >= (short)ys) {
210 carryx = 1; forcex = 0;
211 collCode |= kCollisionOnBottom;
212 }
213 collCode |= ExertForce(forcex, forcey, collisionObject, 0L);
214 environmentForceX = forcex;
215 environmentForceY = forcey;
216
217 if (carryx) forcex = tmpForcex;
218 if (carryy) forcey = tmpForcey;
219
220 return collCode;
221
222 } else {
223 if ((short)right == (short)xs && (PointIntersection(floor(top), floor(bottom), floor(ys), floor(ye) -1) ||
224 ((short)top == (short)ys && (short)bottom == (short)ye))) {
225 if (forcex > 0) {
226 forcex = 0;
227 //sender->OnTouch(this);
228 collisionObject = typeID;
229 return kCollisionOnRight;
230 }
231 }
232
233 if ((short)left == (short)xe -1 && (PointIntersection(floor(top), floor(bottom), floor(ys), floor(ye) -1) ||
234 ((short)top == (short)ys && (short)bottom == (short)ye))) {
235 if (forcex < 0) {
236 forcex = 0;
237 //sender->OnTouch(this);
238 collisionObject = typeID;
239 return kCollisionOnLeft;
240 }
241 }
242
243 if (((short)bottom >= (short)ys && (short)bottom <= (short)ys + 3) && PointIntersection(floor(left), floor(right), floor(xs), floor(xe) -1)) {
244 if (forcey > 0) {
245 forcey = 0;
246 //sender->OnTouch(this);
247 collisionObject = typeID;
248 return kCollisionOnBottom;
249 }
250 }
251
252 if ((short)top == (short)ye -1 && PointIntersection(floor(left), floor(right), floor(xs), floor(xe) -1)) {
253 if (forcey < 0) {
254 forcey = 0;
255 //sender->OnTouch(this);
256 collisionObject = typeID;
257 return kCollisionOnTop;
258 }
259 }
260
261 return kNoCollision;
262 }
263 }
264
265 void CObject::CollisionEvent(double friction, double externForce)
266 {
267 double theorForce;
268
269 if (forceVectorX) {
270 theorForce = forceVectorX - SIGN(forceVectorX) * friction * deltaTime;
271 if (SIGN(theorForce) != SIGN(forceVectorX))
272 forceVectorX = 0;
273 else forceVectorX = theorForce;
274 }
275 if (externForce) environmentForceX += externForce * deltaTime * gConst->kVelocityUnit;
276 }
277
278
279
280 short CObject::Write(FILE *f)
281 {
282 long size = 0;
283
284 WRITEDATA(size);
285 WRITEDATA(typeID);
286
287 WRITEDATA(xs);
288 WRITEDATA(ys);
289 WRITEDATA(xe);
290 WRITEDATA(ye);
291 WRITEDATA(xm);
292 WRITEDATA(ym);
293 WRITEDATA(weight);
294 WRITEDATA(forceVectorX);
295 WRITEDATA(forceVectorY);
296 WRITEDATA(environmentForceX);
297 WRITEDATA(environmentForceY);
298 WRITEDATA(gravitation);
299 WRITEDATA(resForceX);
300 WRITEDATA(resForceY);
301
302 WRITEDATA(background);
303
304 FINISHWRITE;
305
306 return size;
307 }
308
309 void CObject::Read(FILE *f)
310 {
311 long size;
312
313 READDATA(size);
314 READDATA(typeID);
315
316 READDATA(xs);
317 READDATA(ys);
318 READDATA(xe);
319 READDATA(ye);
320 READDATA(xm);
321 READDATA(ym);
322 READDATA(weight);
323 READDATA(forceVectorX);
324 READDATA(forceVectorY);
325 READDATA(environmentForceX);
326 READDATA(environmentForceY);
327 READDATA(gravitation);
328 READDATA(resForceX);
329 READDATA(resForceY);
330 READDATA(background);
331 }
0 #ifndef __AMP_OBJECT__
1 #define __AMP_OBJECT__
2
3 #include "Shape.hpp"
4
5 class CMonster;
6 class CGuidedBullet;
7 class CSoundSystem;
8
9 class CObject {
10 friend class CMonster;
11 friend class CGuidedBullet;
12 friend class CSoundSystem;
13
14 protected:
15 short weight;
16 double forceVectorX, forceVectorY;
17 double environmentForceX, environmentForceY;
18 double gravitation;
19 double resForceX, resForceY;
20 long lastTime, deltaTime;
21 CObject *pusher;
22
23 public:
24 unsigned long typeID;
25 short background;
26 double xs, ys, xe, ye, xm, ym;
27
28 CObject(short initx, short inity, short width, short height);
29 ~CObject();
30
31 short ExertForce(double &forcex, double &forcey, short &collisionObject, CObject **obstacle);
32 virtual short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
33 virtual void CollisionEvent(double friction, double externForce);
34 virtual short CollisionPossible(double ptx, double pty);
35 virtual short Think();
36 virtual short Forces();
37
38 virtual void OnTouch(CObject *touch);
39
40 virtual short Write(FILE *f);
41 virtual void Read(FILE *f);
42 };
43
44
45 #define WRITEDATA(data) fwrite(&data, sizeof(data), 1, f); size += sizeof(data)
46 #define READDATA(data) fread(&data, sizeof(data), 1, f);
47
48 #define FINISHWRITE fseek(f, -size, SEEK_CUR); fwrite(&size, sizeof(size), 1, f); fseek(f, size - sizeof(size), SEEK_CUR);
49
50 #endif
0 #include "Player.hpp"
1 #include "ShapeDes.hpp"
2 #include "Appl.hpp"
3 #include "ConstVal.hpp"
4 #include "Gui.hpp"
5 #include "Item.hpp"
6 #include "SndSys.hpp"
7
8 extern CApplication *gApplication;
9 extern CSystem *gSystem;
10 extern CShapeManager *gShapeManager;
11 extern CObjInfo *gObjInfo;
12 extern CLevel *gLevel;
13 extern tConstValues *gConst;
14 extern CGUI *gGUI;
15 extern tConfigData *gConfigData;
16 extern CSoundSystem *gSoundSystem;
17
18 CPlayer::CPlayer(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo) :
19 CMonster(initx, inity, width, height, number, monsterInfo)
20 {
21 short n;
22
23 typeID |= kPlayer;
24
25 xs += (dx - gConst->kPlayerWidth) / 2;
26 xe -= (dx - gConst->kPlayerWidth) / 2;
27 ys += 2;
28
29 weight = 2;
30 jumpTime = LONG_MAX;
31 jumped = 0;
32
33 for (short m = 0; m < 3; m ++) {
34 playerMoveShapes[0][m] = moveShapes[m];
35
36 }
37 attackShapes[0][0] = gShapeManager->FindShape(504, 0);
38 attackShapes[0][1] = attackShapes[0][2] = 0L;
39 jumpShapes[0] = jumpShape;
40
41 for (n = 1; n < 8; n ++) {
42 for (short m = 0; m < 3; m ++) {
43 playerMoveShapes[n][m] = gShapeManager->FindShape(500 + n * 10 + m, 0);
44 attackShapes[n][m] = gShapeManager->FindShape(504 + n * 10 + m, 0);
45 }
46 jumpShapes[n] = gShapeManager->FindShape(503 + n * 10, 0);
47 }
48
49 unused = weapon;
50 weapons[0] = new CHandWeapon(this, gObjInfo->FindWeapon(0), attackShapes[0][0], attackShapes[0][1], attackShapes[0][2]);
51 weapons[1] = new CWeapon(this, gObjInfo->FindWeapon(1), attackShapes[1][0]);
52 weapons[2] = new CSorcery(this, gObjInfo->FindWeapon(2), attackShapes[2][0]);
53 weapons[3] = new CWeapon(this, gObjInfo->FindWeapon(3), attackShapes[3][0]);
54 weapons[4] = new CHandWeapon(this, gObjInfo->FindWeapon(4), attackShapes[4][0], attackShapes[4][1], attackShapes[4][2]);
55 weapons[5] = new CMultiBulletWeapon(this, gObjInfo->FindWeapon(5), attackShapes[5][0], gConst->kFirehandAngle);
56 weapons[6] = new CBomb(this, gObjInfo->FindWeapon(6), attackShapes[6][0], attackShapes[3][1]);
57 weapons[7] = new CStaff(this, gObjInfo->FindWeapon(7), attackShapes[7][0], attackShapes[7][1]);
58 weapon = weapons[0];
59
60 for (n = 0; n <= 7; n ++) weapons[n]->weaponNumber = n;
61
62 teleportCounter = -1;
63 lastOxygenDecTime = 0;
64
65 lastWeaponChanging = 0; // by LL
66 lastActionTime = 0; // by LL
67 // teleportRefNum = 0; ? by LL
68 lastOxygenDecTime = 0; // by LL
69
70 lastPickupTime = 0;
71
72 currentWeapon = 0;
73 weapons[0]->weaponStatus = kWeaponReady;
74 oxygen = gConst->kInitialOxygen;
75 }
76
77
78 CPlayer::~CPlayer()
79 {
80 for (short n = 1; n < 8; n ++) delete weapons[n];
81 }
82
83 short CPlayer::Think()
84 {
85 CElement *element;
86 short action;
87 short liquid;
88 double currentSpeed;
89
90 CObject::Think();
91 if (gApplication->firstPlayRound) OnStart();
92
93 Gravitation();
94
95 element = gLevel->GetElement(xm, ym);
96 if (element) liquid = element->GetElementLiquid(); else liquid = kShapemodusNormal;
97
98 if (dieFrame == -1) {
99 currentSpeed = (gSystem->KeyPressed(gConfigData->runKey) && lastCollisionCode & kCollisionOnBottom ? info->speed * gConst->kRunScaleFactor : info->speed) * gConst->kVelocityUnit * deltaTime;
100
101 if (gSystem->KeyPressed(gConfigData->leftKey)) {
102 if (forceVectorX > -currentSpeed) forceVectorX -= gConst->kPlayerAcceleration * deltaTime;
103 lookDirection = kLookingLeft;
104 }
105 if (gSystem->KeyPressed(gConfigData->rightKey)) {
106 if (forceVectorX < currentSpeed) forceVectorX += gConst->kPlayerAcceleration * deltaTime;
107 lookDirection = kLookingRight;
108 }
109 if (gSystem->KeyPressed(gConfigData->jumpKey)) {
110 if (liquid == kShapemodusWater || liquid == kShapemodusLava) {
111 if (forceVectorY > -info->speed * gConst->kVelocityUnit * deltaTime) forceVectorY = -gConst->kPlayerLiquidAccel * deltaTime;
112 if (!gSoundSystem->playerDive->isPlaying()) gSoundSystem->Play(gSoundSystem->playerDive, xm, ym);
113 }else if (jumpTime > lastTime){
114 forceVectorY = -gConst->kJumpVelocity * gConst->kVelocityUnit * deltaTime;
115 if (!jumped) gSoundSystem->Play(gSoundSystem->playerJump, xm, ym);
116 jumped = 1;
117 }
118 }else jumpTime = 0;
119
120 if (gSystem->KeyPressed(gConfigData->shootKey)) {
121 weapons[currentWeapon]->Shoot(lookDirection == kLookingRight ? 1 : -1, 0, 0);
122 gGUI->UpdateWeapon();
123 }
124 if (gSystem->KeyPressed(gConfigData->prevWeaponKey) && lastTime > lastWeaponChanging) {
125 do {
126 currentWeapon ++;
127 if (currentWeapon > 7) currentWeapon = 0;
128 } while (weapons[currentWeapon]->weaponStatus != kWeaponReady);
129
130 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
131 gGUI->UpdateWeapon();
132 }
133
134 if (gSystem->KeyPressed(gConfigData->nextWeaponKey) && lastTime > lastWeaponChanging) {
135 do {
136 currentWeapon --;
137 if (currentWeapon < 0) currentWeapon = 7;
138 } while (weapons[currentWeapon]->weaponStatus != kWeaponReady);
139
140 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
141 gGUI->UpdateWeapon();
142 }
143
144 if (gSystem->KeyPressed(gConfigData->activateKey) && lastActionTime < lastTime) {
145 PerformAction();
146 lastActionTime = lastTime + gConst->kActionDelayTime;
147 }
148
149
150 if (gSystem->KeyPressed(gConfigData->weapon1Key) && weapons[0]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
151 currentWeapon = 0;
152 gGUI->UpdateWeapon();
153 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
154 }
155 if (gSystem->KeyPressed(gConfigData->weapon2Key) && weapons[1]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
156 currentWeapon = 1;
157 gGUI->UpdateWeapon();
158 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
159 }
160 if (gSystem->KeyPressed(gConfigData->weapon3Key) && weapons[2]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
161 currentWeapon = 2;
162 gGUI->UpdateWeapon();
163 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
164 }
165 if (gSystem->KeyPressed(gConfigData->weapon4Key) && weapons[3]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
166 currentWeapon = 3;
167 gGUI->UpdateWeapon();
168 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
169 }
170 if (gSystem->KeyPressed(gConfigData->weapon5Key) && weapons[4]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
171 currentWeapon = 4;
172 gGUI->UpdateWeapon();
173 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
174 }
175 if (gSystem->KeyPressed(gConfigData->weapon6Key) && weapons[5]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
176 currentWeapon = 5;
177 gGUI->UpdateWeapon();
178 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
179 }
180 if (gSystem->KeyPressed(gConfigData->weapon7Key) && weapons[6]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
181 currentWeapon = 6;
182 gGUI->UpdateWeapon();
183 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
184 }
185 if (gSystem->KeyPressed(gConfigData->weapon8Key) && weapons[7]->weaponStatus == kWeaponReady && lastTime > lastWeaponChanging) {
186 currentWeapon = 7;
187 gGUI->UpdateWeapon();
188 lastWeaponChanging = lastTime + gConst->kWeaponChangeTime;
189 }
190
191 if (liquid == kShapemodusWater || liquid == kShapemodusLava) {
192 oxygen -= gConst->kOxygenDecrease * deltaTime;
193 }
194 if (liquid == kShapemodusLava) OnDamage(gConst->kLavaDamage);
195 }
196
197 if (liquid == kShapemodusWater || liquid == kShapemodusLava) {
198 forceVectorX *= gConst->kLiquidFriction;
199 forceVectorY *= gConst->kLiquidFriction;
200 }
201
202 if (element) element->PassiveAction();
203
204 return kNoEvent;
205 }
206
207 // ------------------------------------------------
208 void CPlayer::PerformAction()
209 // Performs the action which is returned by CElement::Action
210 {
211 short action = 0;
212 CElement *element = gLevel->GetElement(xm, ym);
213
214 if (element) action = element->Action();
215
216 if (action & kTeleportMask) { // Player used a teleporter
217 teleportCounter = 0;
218 teleportRefNum = element->refNum;
219 teleportDeltaTime = lastTime;
220 currentJob = kJobTeleporting;
221 }
222 if (action & kExitMask) gApplication->command = kCmdNextLevel;
223 }
224
225 short CPlayer::Forces()
226 {
227 short collisionObject, collisionCode;
228
229 CObject::Forces();
230
231 lastCollisionCode = ExertForce(resForceX, resForceY, collisionObject, 0L);
232 if (lastCollisionCode & kCollisionOnBottom) {
233 jumpTime = lastTime + gConst->kJumpAccelerationTime;
234 jumped = 0;
235 }
236 if (lastCollisionCode & kCollisionOnTop) {
237 jumpTime = 0;
238 forceVectorY = 0;
239 }
240
241 if (lastCollisionCode & (kCollisionOnLeft | kCollisionOnRight)) forceVectorX = 0;
242
243 return kNoEvent;
244 }
245
246 void CPlayer::Move()
247 {
248 moveShapes[0] = playerMoveShapes[currentWeapon][0];
249 moveShapes[1] = playerMoveShapes[currentWeapon][1];
250 moveShapes[2] = playerMoveShapes[currentWeapon][2];
251 jumpShape = jumpShapes[currentWeapon];
252 weapon = weapons[currentWeapon];
253
254 CMonster::Move();
255 }
256
257 void CPlayer::OnStart()
258 {
259 gGUI->UpdateWeapon();
260 }
261
262 // ------------------------------------
263 void CPlayer::OnTeleport()
264 // Teleport event, sent by CMonster::Render
265 {
266 if (currentJob == kJobTeleporting) {
267 CElement *element = gLevel->FindRefnum(teleportRefNum);
268
269 if (element) {
270 element->Teleport(xs, ys);
271 xe = xs + dx; ye = ys + dy;
272 }
273 }
274 }
275
276 void CPlayer::GetItAll()
277 // cheat
278 {
279 int i;
280
281 for (i = 0; i < 7; ++i) {
282 //if (weapons[i]->weaponStatus != kWeaponReady) currentWeapon = i;
283 weapons[i]->weaponStatus = kWeaponReady;
284 weapons[i]->AddMunition(100);
285
286 oxygen += 100;
287 oxygen = MIN(oxygen, gConst->kInitialOxygen);
288
289 health += 100;
290 health = MIN(health, info->energy);
291 }
292 }
293
294 void CPlayer::OnTouch(CObject *touch)
295 {
296 short value;
297 short what;
298
299 if (touch->typeID & kPortableItem) {
300 what = ((CPortableItem *)touch)->PickMeUp(value);
301 gSoundSystem->Play(gSoundSystem->playerPickup, xm, ym);
302 switch (what) {
303 case kItemSword:
304 if (weapons[0]->weaponStatus != kWeaponReady) currentWeapon = 0;
305 weapons[0]->weaponStatus = kWeaponReady;
306 weapons[0]->AddMunition(0);
307 break;
308
309 case kItemPhiol:
310 if (weapons[1]->weaponStatus != kWeaponReady) currentWeapon = 1;
311 weapons[1]->weaponStatus = kWeaponReady;
312 weapons[1]->AddMunition(gObjInfo->GetItemInfo(kItemPhiolmun)->data);
313 break;
314
315 case kItemSorcery:
316 if (weapons[2]->weaponStatus != kWeaponReady) currentWeapon = 2;
317 weapons[2]->weaponStatus = kWeaponReady;
318 weapons[2]->AddMunition(gObjInfo->GetItemInfo(kItemSorcerymun)->data);
319 break;
320
321 case kItemBow:
322 if (weapons[3]->weaponStatus != kWeaponReady) currentWeapon = 3;
323 weapons[3]->weaponStatus = kWeaponReady;
324 weapons[3]->AddMunition(gObjInfo->GetItemInfo(kItemBowmun)->data);
325 break;
326
327 case kItemScie:
328 if (weapons[4]->weaponStatus != kWeaponReady) currentWeapon = 4;
329 weapons[4]->weaponStatus = kWeaponReady;
330 weapons[4]->AddMunition(0);
331 break;
332
333 case kItemHands:
334 if (weapons[5]->weaponStatus != kWeaponReady) currentWeapon = 5;
335 weapons[5]->weaponStatus = kWeaponReady;
336 weapons[5]->AddMunition(gObjInfo->GetItemInfo(kItemHandsmun)->data);
337 break;
338
339 case kItemBomb:
340 if (weapons[6]->weaponStatus != kWeaponReady) currentWeapon = 6;
341 weapons[6]->weaponStatus = kWeaponReady;
342 weapons[6]->AddMunition(gObjInfo->GetItemInfo(kItemBombmun)->data);
343 break;
344
345 case kItemStaff:
346 if (weapons[7]->weaponStatus != kWeaponReady) currentWeapon = 7;
347 weapons[7]->weaponStatus = kWeaponReady;
348 weapons[7]->AddMunition(gObjInfo->GetItemInfo(kItemStaffmun)->data);
349 break;
350
351 case kItemPhiolmun:
352 weapons[1]->AddMunition(value);
353 break;
354
355 case kItemSorcerymun:
356 weapons[2]->AddMunition(value);
357 break;
358
359 case kItemBowmun:
360 weapons[3]->AddMunition(value);
361 break;
362
363 case kItemSciemun:
364 weapons[4]->AddMunition(value);
365 break;
366
367 case kItemHandsmun:
368 weapons[5]->AddMunition(value);
369 break;
370
371 case kItemBombmun:
372 weapons[6]->AddMunition(value);
373 break;
374
375 case kItemStaffmun:
376 weapons[7]->AddMunition(value);
377 break;
378
379 case kItemOxygen:
380 oxygen += value;
381 oxygen = MIN(oxygen, gConst->kInitialOxygen);
382 break;
383
384 case kItemHelppacket:
385 health += value;
386 health = MIN(health, info->energy);
387 break;
388 }
389 lastPickupTime = lastTime + gConst->kPickupTime;
390 gGUI->UpdateWeapon();
391 gGUI->OnPickUpSomething(what);
392 }
393 }
394
395 void CPlayer::OnDamage(short blessure)
396 {
397 gSoundSystem->Play(gSoundSystem->firestoneDamage, xm, ym);
398 CMonster::OnDamage(blessure);
399 }
400
401 void CPlayer::SaveDataToNextLevel(tPlayerData *playerData)
402 {
403 for (short n = 0; n <= 7; n ++) weapons[n]->SaveDataToNextLevel(&(playerData->munition[n]), &(playerData->weaponStatus[n]));
404
405 playerData->currentWeapon = currentWeapon;
406 playerData->health = health;
407 playerData->oxygen = oxygen;
408 }
409
410 void CPlayer::RestoreDataFromNextLevel(tPlayerData *savedData)
411 {
412 currentWeapon = savedData->currentWeapon;
413 oxygen = savedData->oxygen;
414 health = savedData->health;
415 for (short n = 0; n <= 7; n ++) {
416 weapons[n]->RestoreDataFromPrevLevel(savedData->munition[n], savedData->weaponStatus[n]);
417 }
418 }
419
420 CCamera::CCamera(short initx, short inity, short width, short height, short thingNumber) : CThing(initx, inity, width, height, thingNumber)
421 {
422 typeID |= kCamera;
423
424 weightless = 1;
425
426 gApplication->Enqueue(&gApplication->thingList, this);
427 gApplication->Enqueue(&gApplication->renderQueue, this);
428 }
429
430 CCamera::~CCamera()
431 {
432 gApplication->Dequeue(&gApplication->thingList, this);
433 gApplication->Dequeue(&gApplication->renderQueue, this);
434 }
435
436 short CCamera::Forces()
437 {
438 if (xm < kLevelWidth * kElementSize - kGamePlaneWidth / 2)
439 forceVectorX = gConst->kCameraSpeed * deltaTime * gConst->kVelocityUnit;
440 else forceVectorX = 0;
441
442 return kNoEvent;
443 }
444
445 short CCamera::Think()
446 {
447 CElement *element;
448
449 CObject::Think();
450
451 element = gLevel->GetElement(xm, ym);
452 if (element && element->GetElementLiquid() == kShapemodusFog) {
453 currentMessage = gConst->kMonsterNames[element->data -1];
454 msgY = kGamePlaneHeight;
455 }
456
457 msgY -= gConst->kMonsterNameSpeed * deltaTime * gConst->kVelocityUnit;
458
459 return kNoEvent;
460 }
461
462 void CCamera::Move()
463 {
464 xm += forceVectorX;
465 }
466
467 void CCamera::Render(short planeX, short planeY, tRect *clipRect)
468 {
469 if (msgY > -kElementSize) gApplication->plane->DrawString(gConst->kMonsterNameX, (short)msgY, currentMessage, kShapemodusNormal);
470 }
471
472 short CPlayer::Write(FILE *f)
473 {
474 long size = 0;
475
476 WRITEDATA(size);
477 WRITEDATA(typeID);
478 WRITEDATA(thingNumber);
479
480 weapon = unused;
481 size += CMonster::Write(f);
482 weapon = unused;
483
484 for (short n = 0; n < 8; n ++) {
485 size += weapons[n]->Write(f);
486 }
487
488 WRITEDATA(jumpTime);
489 WRITEDATA(currentWeapon);
490 WRITEDATA(lastWeaponChanging);
491 WRITEDATA(lastPickupTime);
492 WRITEDATA(lastActionTime);
493 WRITEDATA(teleportRefNum);
494 WRITEDATA(currentJob);
495
496 WRITEDATA(oxygen);
497 WRITEDATA(lastOxygenDecTime);
498
499 FINISHWRITE;
500
501 return size;
502 }
503
504 void CPlayer::Read(FILE *f)
505 {
506 long size = 0;
507
508
509 READDATA(size);
510 READDATA(typeID);
511 READDATA(thingNumber);
512
513 CMonster::Read(f);
514
515 for (short n = 0; n < 8; n ++) {
516 weapons[n]->Read(f);
517 }
518
519 READDATA(jumpTime);
520 READDATA(currentWeapon);
521 READDATA(lastWeaponChanging);
522 READDATA(lastPickupTime);
523 READDATA(lastActionTime);
524 READDATA(teleportRefNum);
525 READDATA(currentJob);
526
527 READDATA(oxygen);
528 READDATA(lastOxygenDecTime);
529 }
0 #ifndef __AMP_PLAYER__
1 #define __AMP_PLAYER__
2
3 #include "Monster.hpp"
4 #include "SoundList.hpp"
5
6 enum {
7 kJobTeleporting,
8 kJobExiting
9 };
10
11 class CGUI;
12 struct tPlayerData;
13
14 class CPlayer : public CMonster {
15 friend class CGUI;
16
17 protected:
18 CShape *playerMoveShapes[8][3];
19 CShape *jumpShapes[8];
20 CShape *attackShapes[8][3];
21
22 CWeapon *weapons[8];
23 CWeapon *unused;
24
25 CSound *jumpSound;
26
27 long jumpTime;
28 short jumped;
29 short currentWeapon;
30 long lastWeaponChanging;
31 long lastPickupTime;
32 long lastActionTime;
33 short teleportRefNum;
34 short currentJob;
35
36 void PerformAction();
37 void OnTeleport();
38
39 double oxygen;
40 long lastOxygenDecTime;
41
42 void OnStart();
43
44 public:
45 CPlayer(short initx, short inity, short width, short height, short number, tMonsterInfo *monsterInfo);
46 ~CPlayer();
47
48 short Forces();
49 void Move();
50 short Think();
51
52 void OnTouch(CObject *touch);
53 void OnDamage(short blessure);
54
55 void SaveDataToNextLevel(tPlayerData *);
56 void RestoreDataFromNextLevel(tPlayerData *);
57
58 short Write(FILE *f);
59 void Read(FILE *f);
60
61 // cheat
62 void GetItAll();
63
64 };
65
66
67 class CCamera : public CThing {
68 private:
69 char *currentMessage;
70 double msgY;
71
72 public:
73 CCamera(short initx, short inity, short width, short height, short number);
74 ~CCamera();
75
76 short Forces();
77 void Move();
78 short Think();
79 void Render(short planeX, short planeY, tRect *clipRect);
80
81 };
82
83 #endif
0 #include "Pltform.hpp"
1 #include "Appl.hpp"
2 #include "Player.hpp"
3 #include "ConstVal.hpp"
4 #include "SndSys.hpp"
5
6 extern CApplication *gApplication;
7 extern CShapeManager *gShapeManager;
8 extern tConstValues *gConst;
9 extern CLevel *gLevel;
10 extern CSoundSystem *gSoundSystem;
11
12 const short kPlatformCollisionHeight = 30;
13
14 CPlatform::CPlatform(short initx, short inity, short width, short height, short number, tPlatformInfo *platformInfo) :
15 CThing(initx, inity, width, height, number)
16 {
17 typeID |= kPlatform;
18 LinkInLists();
19
20 if (platformInfo) {
21 info = platformInfo;
22 isLocal = 0;
23 weight = SHRT_MAX;
24 background = 0;
25
26 origHeight = dy;
27 ys = ym - kPlatformCollisionHeight / 2;
28 ye = ym + kPlatformCollisionHeight / 2;
29 dy = kPlatformCollisionHeight;
30 dx -= 1;
31 ye -= 1;
32
33 OnAllocate();
34
35 startx = info->startx * kElementSize;
36 starty = info->starty * kElementSize + (kElementSize - kPlatformCollisionHeight) / 2;
37 endx = info->endx * kElementSize;
38 endy = info->endy * kElementSize + (kElementSize - kPlatformCollisionHeight) / 2;
39
40 maxDistance = sqrt((endx - startx) * (endx - startx) + (endy - starty) * (endy - starty));
41
42 if (info->activ) action = kRunsStartToEnd; else action = kStopsAtStart;
43 }else info = 0L;
44 }
45
46 void CPlatform::OnAllocate()
47 {
48 shape = gShapeManager->FindShape(info->iconID, 0);
49 }
50
51
52 CPlatform::~CPlatform()
53 {
54 if (isLocal) delete info;
55 }
56
57 void CPlatform::LinkInLists()
58 {
59 gApplication->Enqueue(&gApplication->thingList, this);
60 gApplication->Enqueue(&gApplication->collisionThingList, this);
61 gApplication->Enqueue(&gApplication->renderQueue, this);
62 }
63
64 void CPlatform::UnlinkInLists()
65 {
66 gApplication->Dequeue(&gApplication->thingList, this);
67 gApplication->Dequeue(&gApplication->collisionThingList, this);
68 gApplication->Dequeue(&gApplication->renderQueue, this);
69 }
70
71 short CPlatform::Think()
72 {
73 double speedVector, distance;
74
75 CObject::Think();
76
77 switch (action) {
78
79 case kRunsStartToEnd:
80 distance = sqrt((xs - startx) * (xs - startx) + (ys - starty) * (ys - starty));
81
82 if (distance >= maxDistance) {
83 if (info->stopsAtEnd) action = kStopsAtEnd; else action = kDelaysAtEnd;
84 xs = endx; ys = endy;
85 xe = xs + kElementSize -1; ye = ys + kElementSize -1;
86 delayTime = lastTime;
87 gSoundSystem->Play(gSoundSystem->platformStop, xm, ym);
88 }else{
89 speedVector = info->speed * gConst->kVelocityUnit * deltaTime;
90 forceVectorX = (endx - startx) * speedVector / maxDistance;
91 forceVectorY = (endy - starty) * speedVector / maxDistance;
92 }
93 break;
94
95 case kRunsEndToStart:
96 distance = sqrt((xs - endx) * (xs - endx) + (ys - endy) * (ys - endy));
97
98 if (distance >= maxDistance) {
99 if (info->stopsAtStart) action = kStopsAtStart; else action = kDelaysAtStart;
100 xs = startx; ys = starty;
101 xe = xs + kElementSize -1; ye = ys + kElementSize -1;
102 delayTime = lastTime;
103 gSoundSystem->Play(gSoundSystem->platformStop, xm, ym);
104 }else{
105 speedVector = info->speed * gConst->kVelocityUnit * deltaTime;
106 forceVectorX = (startx - endx) * speedVector / maxDistance;
107 forceVectorY = (starty - endy) * speedVector / maxDistance;
108 }
109 break;
110
111 case kDelaysAtStart:
112 if (lastTime - delayTime > info->delay * kTimeFactor) {
113 action = kRunsStartToEnd;
114 gSoundSystem->Play(gSoundSystem->platformGo, xm, ym);
115 }
116 forceVectorX = forceVectorY = 0;
117 break;
118
119 case kDelaysAtEnd:
120 if (lastTime - delayTime > info->delay * kTimeFactor) {
121 action = kRunsEndToStart;
122 gSoundSystem->Play(gSoundSystem->platformGo, xm, ym);
123 }
124 forceVectorX = forceVectorY = 0;
125 break;
126
127 case kStopsAtStart:
128 case kStopsAtEnd:
129 forceVectorX = forceVectorY = 0;
130 break;
131 }
132
133 return kNoEvent;
134 }
135
136 short CPlatform::Forces()
137 {
138 short collisionObject, collisionCode;
139 CObject *collObj;
140
141 CObject::Forces();
142 double oldfx = resForceX, oldfy = resForceY;
143
144 collisionCode = ExertForce(resForceX, resForceY, collisionObject, &collObj);
145 if (!(collisionCode & kCollisionWithPushing)) {
146 if (collisionObject & (kElement | kItem | kPlatform)) { // Platforms can go through level elements
147 resForceX = oldfx; resForceY = oldfy;
148 }
149 }else if (collisionCode & ~kCollisionWithPushing) {
150 action = (action == kRunsStartToEnd ? kRunsEndToStart : kRunsStartToEnd);
151 if (info->returnsOnHit && collObj->typeID & kThing) ((CThing *)collObj)->OnDamage(info->returnsOnHit);
152
153 }
154 return kNoEvent;
155 }
156
157
158 void CPlatform::Render(short planeX, short planeY, tRect *clipRect)
159 {
160 CElement *element = gLevel->GetElement(xm, ym);
161
162 if (shape) shape->RenderShape(xs - planeX, ym - planeY - origHeight / 2, clipRect,
163 modus, element ? element->brightness : 0, gApplication->plane);
164 }
165
166 short CPlatform::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject)
167 {
168 if (right + 2 < xs || left - 2 > xe || bottom + 2 < ys || top - 2 > ye) return kNoCollision;
169
170 short returnValue;
171
172 if ((returnValue = CObject::Collision(sender, left, top, right, bottom, forcex, forcey, pfx, pfy, sourceWeight, collisionObject)) & kCollisionOnBottom) {
173 sender->CollisionEvent(gConst->kNormalFriction, 0);
174 if (info->hurts) ((CThing *)sender)->OnDamage(info->hurts);
175
176 if ((sender->typeID & kPlayer) && info->playerControls) {
177 if (action == kStopsAtStart) {
178 action = kRunsStartToEnd;
179 gSoundSystem->Play(gSoundSystem->platformGo, xm, ym);
180 }
181 if (action == kStopsAtEnd) {
182 action = kRunsEndToStart;
183 gSoundSystem->Play(gSoundSystem->platformGo, xm, ym);
184 }
185 }
186 }
187 return returnValue;
188 }
189
190 void CPlatform::OnTouch(CObject *touch)
191 {
192 if ((touch->typeID & kThing) && info->hurts) ((CThing *)touch)->OnDamage(info->hurts);
193 }
194
195 void CPlatform::Switch()
196 {
197 switch (action) {
198 case kRunsStartToEnd:
199 case kDelaysAtStart:
200 action = kStopsAtStart;
201 gSoundSystem->Play(gSoundSystem->platformStop, xm, ym);
202 break;
203 case kRunsEndToStart:
204 case kDelaysAtEnd:
205 action = kStopsAtEnd;
206 gSoundSystem->Play(gSoundSystem->platformStop, xm, ym);
207 break;
208 case kStopsAtStart:
209 action = kRunsStartToEnd;
210 gSoundSystem->Play(gSoundSystem->platformGo, xm, ym);
211 if (info->refNum > 0) gApplication->platformTable[info->refNum]->Switch();
212 break;
213 case kStopsAtEnd:
214 action = kRunsEndToStart;
215 gSoundSystem->Play(gSoundSystem->platformGo, xm, ym);
216 if (info->refNum > 0) gApplication->platformTable[info->refNum]->Switch();
217 break;
218 }
219 }
220
221
222 CShape *CPlatform::GetCurrentState(CShape *active, CShape *inactive)
223 {
224 if (action == kStopsAtStart || action == kStopsAtEnd) return inactive; else return active;
225 }
226
227
228
229 short CPlatform::Write(FILE *f)
230 {
231 long size = 0;
232
233 WRITEDATA(size);
234 WRITEDATA(typeID);
235 WRITEDATA(thingNumber);
236
237 size += CThing::Write(f);
238
239 WRITEDATA(origHeight);
240 WRITEDATA(action);
241 WRITEDATA(startx);
242 WRITEDATA(starty);
243 WRITEDATA(endx);
244 WRITEDATA(endy);
245 WRITEDATA(maxDistance);
246 WRITEDATA(delayTime);
247 fwrite(info, sizeof(tPlatformInfo), 1, f); size += sizeof(tPlatformInfo);
248
249 FINISHWRITE;
250
251 return size;
252 }
253
254 void CPlatform::Read(FILE *f)
255 {
256 long size = 0;
257
258 READDATA(size);
259 READDATA(typeID);
260 READDATA(thingNumber);
261
262 CThing::Read(f);
263
264 READDATA(origHeight);
265 READDATA(action);
266 READDATA(startx);
267 READDATA(starty);
268 READDATA(endx);
269 READDATA(endy);
270 READDATA(maxDistance);
271 READDATA(delayTime);
272
273 isLocal = 1;
274 info = new tPlatformInfo;
275 fread(info, sizeof(tPlatformInfo), 1, f);
276
277 OnAllocate();
278 }
0 #ifndef __AMP_PLATTFORMS__
1 #define __AMP_PLATTFORMS__
2
3 #include "Thing.hpp"
4 #include "ObjInfo.hpp"
5
6 enum {
7 kRunsStartToEnd = 0,
8 kRunsEndToStart,
9 kDelaysAtStart,
10 kDelaysAtEnd,
11 kStopsAtStart, // Platform stopped at start or while running start -> end
12 kStopsAtEnd // Platform stopped at end or while running end -> start
13 };
14
15 const short kTimeFactor = 100;
16
17 class CPlatform : public CThing {
18 protected:
19 tPlatformInfo *info;
20 short isLocal; // whether info is allocated by the platform itself (after loading) or by ObjInfo
21 CShape *shape;
22
23 short origHeight;
24
25 short action;
26 double startx, starty;
27 double endx, endy;
28 double maxDistance;
29 long delayTime;
30
31 public:
32 CPlatform(short initx, short inity, short width, short height, short number, tPlatformInfo *platformInfo);
33 ~CPlatform();
34
35 void OnAllocate();
36
37 void LinkInLists();
38 void UnlinkInLists();
39 short Think();
40 short Forces();
41 void Render(short planeX, short planeY, tRect *clipRect);
42 short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
43
44 void Switch();
45 CShape *GetCurrentState(CShape *active, CShape *inactive);
46 void OnTouch(CObject *touch);
47
48 short Write(FILE *f);
49 void Read(FILE *f);
50 };
51
52 #endif
0 #include "Shape.hpp"
1 #include "Appl.hpp"
2 #include "Clut.hpp"
3 #include <string.h>
4 #include <memory.h>
5
6 extern CApplication *gApplication;
7 extern CSystem *gSystem;
8 extern CClutManager *gClutManager;
9 extern tConstValues *gConst;
10 extern tConfigData *gConfigData;
11
12
13 CShape::CShape(unsigned char *bitmap, short descr[], long width)
14 {
15 this->id = descr[0];
16 this->dx = descr[3];
17 this->dy = descr[4];
18 }
19
20 CShape::~CShape()
21 {
22 delete [] shapeForward;
23 }
24
25 unsigned char *CShape::AllowPixelAccess(short &ddx, short &ddy)
26 {
27 ddx = dx; ddy = dy;
28 return shapeForward;
29 }
30
31 short CShape::RenderShape(short x, short y, tRect *clipRect, short modus, short percentage, CGraphicSurface *surface)
32 {
33 return dx;
34 }
35
36
37 #define kEndShapeToken 0L // the end of shape maker
38 #define kLineStartToken 1L // the line start marker
39 #define kDrawPixelsToken 2L // the draw run marker
40 #define kSkipPixelsToken 3L // the skip pixels marker
41 #define kClearColorIndex 0 // the index of the color defined as clear (in this case, white)
42 #define kFalse 0
43 #define kTrue 1
44
45 CMaskedShape::CMaskedShape(unsigned char *bitmap, short descr[], long width) : CShape(bitmap, descr, width)
46 {
47 shapeForward = new unsigned char [ 8 * dy * dx + 4 * dy + 4 + 8];
48 Encode(shapeForward, bitmap, descr, width);
49
50 shapeBackward = new unsigned char [ 8 * dy * dx + 4 * dy + 4 + 8];
51 Encode(shapeBackward, bitmap, descr, width);
52 }
53
54 /* Allow unaligned memory access if the architecture supports it (like IA-32)
55 */
56 #ifdef __OPT_MEM_ACCESS__
57
58 #define GET_LONG(adr) *(unsigned long *)adr
59 #define SET_LONG(adr, l) *(unsigned long *)adr = l
60
61 #else
62
63 #define GET_LONG(adr) ((long)((unsigned char *)(adr))[0] << 24) + ((long)((unsigned char *)(adr))[1] << 16) + ((long)((unsigned char *)(adr))[2] << 8) + ((long)((unsigned char *)(adr))[3])
64 #define SET_LONG(adr, l) ((unsigned char *)adr)[0] = (unsigned char)((l) >> 24); \
65 ((unsigned char *)adr)[1] = (unsigned char)((l) >> 16); \
66 ((unsigned char *)adr)[2] = (unsigned char)((l) >> 8); \
67 ((unsigned char *)adr)[3] = (unsigned char)(l)
68
69 #endif
70
71
72 void CMaskedShape::Encode(unsigned char *shape, unsigned char *bitmap, short descr[], long width)
73 {
74 unsigned short shapeHeight; // the height of the shape
75 unsigned short shapeWidth; // the width of the shape
76 unsigned char *destPtr; // the current position in the shape
77 unsigned char *srcPtr; // the current position in the souce graphic data
78 unsigned char *baseAddr; // the base address of the source pixmap
79 unsigned long rowBytes; // the row bytes of the source pixmap
80 unsigned char *rowStart; // the start of the current row in the pixmap
81 unsigned long yCounter; // a counter to scan the shape vertically
82 unsigned long xCounter; // a counter to scan the shape horizontally
83 unsigned char drawRunFlag; // are we in a draw pixels run?
84 unsigned char skipRunFlag; // are we in a skip pixels run?
85 unsigned char *lineStartPtr; // where is the line start token for this line
86 unsigned char *runTokenPtr; // where is the token for the current run
87 unsigned long runCounter; // how long is the current run?
88 long srcStep = (shape == shapeForward ? 1 : -1);
89
90 // determine the width and height of the shape (we use these values a lot)
91 shapeHeight = dy;
92 shapeWidth = dx;
93
94 // create a handle big enough for the worst case encoding
95 // ( 8 bytes/pixel + 4 bytes/row + 4 bytes/shape (end token) + 8 bytes/shape (rect) )
96
97
98 // lock the handle and get the pointer
99 destPtr = shape;
100
101 // store the shape rect
102 ((short *)destPtr)[0] = 0;
103 ((short *)destPtr)[1] = 0;
104 ((short *)destPtr)[2] = dx;
105 ((short *)destPtr)[3] = dy;
106 destPtr += 8;
107
108 // get the location of the source data
109 baseAddr = bitmap;
110 rowBytes = width;
111 rowStart = baseAddr + rowBytes * descr[2] + descr[1] + (shape == shapeForward ? 0 : dx);
112
113 // scan the shape row by row
114 for( yCounter = 0; yCounter < shapeHeight; yCounter++ )
115 {
116 // store the location of this line start
117 lineStartPtr = destPtr;
118 destPtr += sizeof( unsigned long );
119
120 // at the beginning of each row we are not in any run
121 drawRunFlag = kFalse;
122 skipRunFlag = kFalse;
123
124 // move to the start of the row
125 srcPtr = rowStart;
126
127 // scan each row of the shape
128 for( xCounter = 0; xCounter < shapeWidth; xCounter++ ) {
129 // is this pixel clear?
130 if ( *srcPtr == kClearColorIndex ) {
131 // are we in a draw run?
132 if ( drawRunFlag ) {
133 // end the draw run
134 drawRunFlag = kFalse;
135
136 // create the draw token
137 SET_LONG(runTokenPtr, ( kDrawPixelsToken << 24 ) + runCounter);
138
139 // pad to a mulitple of four
140 SET_LONG(destPtr ,0L);
141 destPtr += ( ( runCounter & 3L ) == 0 ) ? 0 : ( 4 - ( runCounter & 3L ) );
142 }
143
144 // are we in a skip run
145 if ( skipRunFlag ) {
146 // continue it
147 runCounter++;
148 } else {
149 // start one
150 skipRunFlag = kTrue;
151 runCounter = 1;
152 }
153 } else {
154 // are we in a skip run
155 if ( skipRunFlag ) {
156 // end the skip run
157 skipRunFlag = kFalse;
158
159 // create the skip token
160 //*( ( unsigned long * )destPtr ) = ( kSkipPixelsToken << 24 ) + runCounter;
161 SET_LONG(destPtr, ( kSkipPixelsToken << 24 ) + runCounter);
162 destPtr += sizeof( unsigned long );
163 }
164
165 // are we in a draw run
166 if ( drawRunFlag ) {
167 // continue it
168 runCounter++;
169
170 // copy the pixel
171 *destPtr = *srcPtr;
172
173 destPtr++;
174 } else {
175 // start one
176 drawRunFlag = kTrue;
177 runCounter = 1;
178
179 // save the location of the token (so we can fill it in later)
180 runTokenPtr = destPtr;
181 destPtr += sizeof( unsigned long );
182
183 // copy the pixel
184 *destPtr = *srcPtr;
185
186 destPtr++;
187 }
188 }
189
190 // move to the next byte
191 srcPtr += srcStep;
192 }
193
194 // are we in a draw run
195 if( drawRunFlag )
196 {
197 // end the draw run
198 drawRunFlag = kFalse;
199
200 // create the draw token
201 SET_LONG(runTokenPtr, ( kDrawPixelsToken << 24 ) + runCounter);
202
203 // pad to a mulitple of four
204 SET_LONG(destPtr, 0L);
205 destPtr += ( ( runCounter & 3L ) == 0 ) ? 0 : ( 4 - ( runCounter & 3L ) );
206 }
207
208 // create the line start token
209 SET_LONG(lineStartPtr, ( kLineStartToken << 24 ) + ( destPtr - ( lineStartPtr + 4 ) ));
210
211 // move the row start to the next row
212 rowStart += rowBytes;
213 }
214
215 // create the end of shape token
216 SET_LONG(destPtr, kEndShapeToken << 24);
217 destPtr += sizeof( unsigned long );
218
219 // Resize the handle to match the real size of the shape
220 //SetHandleSize( shapeHandle, destPtr - ( unsigned char * )( *shapeHandle ) );
221 }
222
223
224
225 CMaskedShape::~CMaskedShape()
226 {
227 delete [] shapeBackward;
228 }
229
230 short CMaskedShape::RenderShape(short x, short y, tRect *clipRect, short modus, short percentage, CGraphicSurface *surface)
231 {
232 if (clipRect->left > x || clipRect->top > y || clipRect->right < x + dx || clipRect->bottom < y + dy)
233 RenderShapeClipped(x, y, clipRect, modus, percentage, surface);
234 else RenderShapeUnclipped(x, y, modus, percentage, surface);
235
236 return dx;
237 }
238
239 void CMaskedShape::RenderShapeClipped(short x, short y, tRect *sClipRect, short modus, short percentage, CGraphicSurface *surface)
240 {
241 tRect clipRect; // the rect that defines the clipped shape
242 short pitch;
243 unsigned char *rowStart; // the pointer to the start of this row
244 unsigned char *srcPtr; // the current position in the sprite data
245 unsigned char *destPtr; // the current position in the destination pixmap
246 long miscCounter; // a counter for various purposes
247 long extraCounter; // a counter for right clippling purposes ( how much extra was there? )
248 unsigned long tokenOp; // the op code from the token
249 unsigned long tokenData; // the data from the token
250 unsigned char exitFlag; // should we exit from the loop?
251 long yCount; // how many lines down in the shape are we?
252 long xCount; // where are we in this line?
253 unsigned char *shape = (modus & kShapemodusBackwardFlag ? shapeBackward : shapeForward);
254
255 modus &= ~kShapemodusBackwardFlag; // clearing the direction flag
256
257
258 // create a clipped rect in the coordinates of the sprite
259 clipRect.left = x < sClipRect->left ? sClipRect->left - x : 0;
260 clipRect.right = x + dx > sClipRect->right ? sClipRect->right - x : dx;
261 clipRect.top = y < sClipRect->top ? sClipRect->top - y : 0;
262 clipRect.bottom = y + dy > sClipRect->bottom ? sClipRect->bottom - y : dy;
263
264 // set up the counters
265 yCount = 0;
266 xCount = 0;
267 // determine characteristics about the pixmap
268
269 rowStart = surface->GetSurfacePtr(&pitch);
270 rowStart += y * pitch + x;
271
272 // move to the right place in the shape ( just past the size rect )
273 srcPtr = shape + 8;
274
275 // loop until we are done
276 exitFlag = kFalse;
277 while( !exitFlag )
278 {
279 // get a token
280 tokenOp = GET_LONG(srcPtr ) >> 24;
281 tokenData = GET_LONG(srcPtr ) & 0x00ffffff;
282 srcPtr += sizeof( unsigned long );
283
284 // depending on the token
285 switch( tokenOp )
286 {
287 case kDrawPixelsToken:
288 miscCounter = tokenData;
289 extraCounter = 0;
290
291 // if we need to, clip to the left
292 if( xCount < clipRect.left )
293 {
294 // if this run does not appear at all, don't draw it
295 if ( miscCounter < clipRect.left - xCount )
296 {
297 destPtr += miscCounter;
298 srcPtr += miscCounter;
299 srcPtr += ( ( tokenData & 3L ) == 0 ) ? 0 : ( 4 - ( tokenData & 3L ) );
300 xCount += miscCounter;
301 break;
302 }
303 else
304 {
305 // if it does, skip to where we can draw
306 miscCounter -= clipRect.left - xCount;
307 destPtr += (clipRect.left - xCount);
308 srcPtr += (clipRect.left - xCount);
309 xCount += clipRect.left - xCount;
310 }
311 }
312
313 // if we need to, clip to the right
314 if ( xCount + miscCounter > clipRect.right )
315 {
316 // if this run does not appear at all, skip it
317 if ( xCount > clipRect.right )
318 {
319 destPtr += miscCounter;
320 srcPtr += miscCounter;
321 srcPtr += ( ( tokenData & 3L ) == 0 ) ? 0 : ( 4 - ( tokenData & 3L ) );
322 xCount += miscCounter;
323 break;
324 }
325 else
326 {
327 // if it does, setup to draw what we can
328 extraCounter = miscCounter;
329 miscCounter -= ( xCount + miscCounter ) - clipRect.right;
330 extraCounter -= miscCounter;
331 }
332 }
333
334 // adjust xCount for the run
335 xCount += miscCounter;
336
337 if (gConfigData->disableShapeModes) {
338 while (miscCounter)
339 {
340 *(unsigned char *)destPtr = *(unsigned char *)srcPtr;
341 destPtr += sizeof( unsigned char );
342 srcPtr += sizeof( unsigned char );
343 miscCounter -= sizeof( unsigned char );
344 }
345 }else{
346 while (miscCounter)
347 {
348 gClutManager->SetPixel((unsigned char *)srcPtr, (unsigned char *)destPtr, modus, percentage);
349 destPtr += sizeof( unsigned char );
350 srcPtr += sizeof( unsigned char );
351 miscCounter -= sizeof( unsigned char );
352 }
353 }
354
355
356 // adjust for right clipping
357 destPtr += extraCounter;
358 srcPtr += extraCounter;
359 xCount += extraCounter;
360
361 // adjust for the padding
362 srcPtr += ( ( tokenData & 3L ) == 0 ) ? 0 : ( 4 - ( tokenData & 3L ) );
363 break;
364
365 case kSkipPixelsToken:
366 destPtr += tokenData;
367 xCount += tokenData;
368 break;
369
370 case kLineStartToken:
371 // if this line is above the clip rect, skip to the next line
372 if( yCount < clipRect.top )
373 {
374 srcPtr += tokenData;
375 }
376
377 // set up the destination pointer
378 destPtr = rowStart;
379 rowStart += pitch;
380
381 // move the yCounter
382 yCount++;
383
384 // reset the xCounter
385 xCount = 0;
386
387 // if we have hit the bottom clip, exit the loop
388 if ( yCount > clipRect.bottom )
389 {
390 exitFlag = kTrue;
391 }
392 break;
393
394 case kEndShapeToken:
395 // signal a loop exit
396 exitFlag = kTrue;
397 break;
398
399 default:
400 // we should never get here
401 break;
402 }
403 }
404 surface->ReleaseSurface();
405 }
406
407
408
409 void CMaskedShape::RenderShapeUnclipped(short x, short y, short modus, short percentage, CGraphicSurface *surface)
410 {
411 short pitch;
412 unsigned char *rowStart; // the pointer to the start of this row
413 unsigned char *srcPtr; // the current position in the sprite data
414 unsigned char *destPtr; // the current position in the destination pixmap
415 long miscCounter; // a counter for various purposes
416 unsigned long tokenOp; // the op code from the token
417 unsigned long tokenData; // the data from the token
418 unsigned char exitFlag; // should we exit from the loop?
419 unsigned char *shape = (modus & kShapemodusBackwardFlag ? shapeBackward : shapeForward);
420
421 modus &= ~kShapemodusBackwardFlag; // clearing the direction flag
422
423 // determine characteristics about the pixmap
424 rowStart = surface->GetSurfacePtr(&pitch);
425 rowStart += y * pitch + x;
426
427 // move to the right place in the shape ( just past the size rect )
428 srcPtr = shape + 8;
429
430 // loop until we are done
431 exitFlag = kFalse;
432 while( !exitFlag )
433 {
434 // get a token
435 tokenOp = GET_LONG(srcPtr) >> 24;
436 tokenData = GET_LONG(srcPtr) & 0x00ffffff;
437 srcPtr += sizeof( unsigned long );
438
439 // depending on the token
440 switch( tokenOp )
441 {
442 case kDrawPixelsToken:
443 miscCounter = tokenData;
444
445
446 if (gConfigData->disableShapeModes) {
447 while (miscCounter)
448 {
449 *(unsigned char *)destPtr = *(unsigned char *)srcPtr;
450 destPtr += sizeof( unsigned char );
451 srcPtr += sizeof( unsigned char );
452 miscCounter -= sizeof( unsigned char );
453 }
454 }else{
455 while (miscCounter)
456 {
457 gClutManager->SetPixel((unsigned char *)srcPtr, (unsigned char *)destPtr, modus, percentage);
458 destPtr += sizeof( unsigned char );
459 srcPtr += sizeof( unsigned char );
460 miscCounter -= sizeof( unsigned char );
461 }
462 }
463
464
465 // adjust for the padding
466 srcPtr += ( ( tokenData & 3L ) == 0 ) ? 0 : ( 4 - ( tokenData & 3L ) );
467 break;
468
469 case kSkipPixelsToken:
470 destPtr += tokenData;
471 break;
472
473 case kLineStartToken:
474 // set up the destination pointer
475 destPtr = rowStart;
476 rowStart += pitch;
477 break;
478
479 case kEndShapeToken:
480 // signal a loop exit
481 exitFlag = kTrue;
482 break;
483
484 default:
485 // we should never get here
486 break;
487 }
488 }
489
490 surface->ReleaseSurface();
491 }
492
493
494
495
496 CTexture::CTexture(unsigned char *bitmap, short descr[], long width, short light) : CShape(bitmap, descr, width)
497 {
498 short j, k;
499 unsigned char *shapePtr;
500 short size = dx * dy;
501
502 shapeForward = new unsigned char[size];
503
504 bitmap = (unsigned char *)((unsigned long)bitmap + descr[2] * width + descr[1]);
505 shapePtr = shapeForward;
506
507 for (j = 0; j < dy; j ++) {
508 for (k = 0; k < dx; k ++) {
509 gClutManager->SetPixel(&(bitmap[k]), &(shapePtr[k]), kShapemodusNormal, light);
510 }
511 bitmap += width;
512 shapePtr += dx;
513 }
514 }
515
516
517 CTexture::~CTexture()
518 {
519 }
520
521
522 short CTexture::RenderShape(short x, short y, tRect *clipRect, short unused, short unused2, CGraphicSurface *surface)
523 {
524 unsigned char *startDestPtr, *startSourcePtr, *tmpSourcePtr, *tmpDestPtr;
525 short pitch, startX, startY, clipWidth, clipHeight, tmpWidth;
526
527 startDestPtr = surface->GetSurfacePtr(&pitch);
528 startDestPtr += MAX(y, clipRect->top) * pitch + MAX(x, clipRect->left);
529
530 startY = clipRect->top > y ? clipRect->top - y : 0;
531 startX = clipRect->left > x ? clipRect->left - x : 0;
532 startSourcePtr = shapeForward + startY * dx + startX;
533
534 clipWidth = (clipRect->right < x + dx ? clipRect->right - x : dx) - startX;
535 clipHeight = (clipRect->bottom < y + dy ? clipRect->bottom - y : dy) - startY;
536
537 if (clipWidth > 0 && clipHeight > 0) {
538 for (short j = 0; j < clipHeight; j ++) {
539 memcpy(startDestPtr, startSourcePtr, clipWidth);
540 startSourcePtr += dx;
541 startDestPtr += pitch;
542 }
543 }
544 surface->ReleaseSurface();
545
546 return dx;
547 }
548
549
550 CBackground::CBackground(unsigned char *bitmap, short descr[], long width) : CShape(bitmap, descr, width)
551 {
552 shapeForward = bitmap;
553
554 // For background shapes, descr[1] and descr[2] are the width and height of the background picture
555 shapeWidth = descr[1];
556 shapeHeight = descr[2];
557 }
558
559 CBackground::~CBackground()
560 {}
561
562 short CBackground::RenderShape(short x, short y, tRect *clipRect, short bkgndCoordX, short unused2, CGraphicSurface *surface)
563 {
564 unsigned char *startDestPtr, *startSourcePtr, *tmpSourcePtr, *tmpDestPtr;
565 short pitch, startX, startY, clipWidth, clipHeight, tmpWidth;
566 short bkgndPictCoordX = bkgndCoordX % shapeWidth;
567 short n;
568
569 startDestPtr = surface->GetSurfacePtr(&pitch);
570 startDestPtr += MAX(y, clipRect->top) * pitch + MAX(x, clipRect->left);
571
572 startY = MAX(clipRect->top, y);
573 startX = (bkgndPictCoordX + MAX(x, clipRect->left)) % shapeWidth;
574 startSourcePtr = shapeForward + MAX(y, clipRect->top) * shapeWidth;
575
576 clipWidth = (clipRect->right < x + dx ? clipRect->right : x + dx) - MAX(x, clipRect->left);
577 clipHeight = (clipRect->bottom < y + dy ? clipRect->bottom : y + dy) - startY;
578
579 for (short j = 0; j < clipHeight; j ++) {
580 tmpWidth = clipWidth;
581 tmpDestPtr = startDestPtr;
582
583 if (startX + tmpWidth >= shapeWidth) {
584 for (n = 0; n < tmpWidth; n ++) {
585 startDestPtr[n] = startSourcePtr[(startX + n) % shapeWidth];
586 }
587 }else{
588 tmpSourcePtr = startSourcePtr + startX;
589 memcpy(tmpDestPtr, tmpSourcePtr, tmpWidth);
590 }
591 startSourcePtr += shapeWidth;
592 startDestPtr += pitch;
593 }
594
595 surface->ReleaseSurface();
596
597 return dx;
598 }
0 #ifndef __AMP_SHAPES__
1 #define __AMP_SHAPES__
2
3 #include "AmpHead.hpp"
4 #include "Surface.hpp"
5
6 class CShape {
7 protected:
8 short id;
9 short dx, dy;
10 unsigned char *shapeForward;
11
12 public:
13 long ID;
14 long savedID;
15
16 CShape(unsigned char *, short [], long);
17 ~CShape();
18
19 virtual short RenderShape(short x, short y, tRect *clipRect, short modus, short percentage, CGraphicSurface *surface);
20 unsigned char *AllowPixelAccess(short &dx, short &dy);
21 };
22
23 class CMaskedShape : public CShape {
24 protected:
25 unsigned char *shapeBackward;
26
27 void Encode(unsigned char *, unsigned char *, short [], long);
28 void RenderShapeClipped(short x, short y, tRect *clipRect, short modus, short percentage, CGraphicSurface *surface);
29 void RenderShapeUnclipped(short x, short y, short modus, short percentage, CGraphicSurface *surface);
30
31 public:
32 CMaskedShape(unsigned char *, short [], long);
33 ~CMaskedShape();
34
35 short RenderShape(short x, short y, tRect *clipRect, short modus, short percentage, CGraphicSurface *surface);
36 };
37
38 class CTexture : public CShape {
39 protected:
40
41 public:
42 CTexture(unsigned char *, short [], long, short light);
43 ~CTexture();
44
45 short RenderShape(short x, short y, tRect *clipRect, short unused, short unused2, CGraphicSurface *surface);
46 };
47
48
49 class CBackground : public CShape {
50 protected:
51 short shapeWidth, shapeHeight;
52
53 public:
54 CBackground(unsigned char *, short [], long);
55 ~CBackground();
56
57 short RenderShape(short x, short y, tRect *clipRect, short unused, short unused2, CGraphicSurface *surface);
58 };
59
60 #endif
0 #ifndef __AMP_SHAPEDESCRIPTOR__
1 #define __AMP_SHAPEDESCRIPTOR__
2
3 #include "ShapeLd.hpp"
4
5 static short kShapeDescriptor[kNumShapes][5] = { // Items
6
7 // ID x y dx dy
8 //---------------------
9 {4100, 0, 576, 32, 32}, // Schwert
10 {4101, 32, 576, 32, 32}, // Phiole
11 {4102, 64, 576, 32, 32},
12 {4103, 96, 576, 32, 32},
13 {4104, 128, 576, 32, 32},
14 {4105, 160, 576, 32, 32},
15 {4106, 192, 576, 32, 32},
16 {4107, 224, 576, 32, 32},
17 {4110, 0, 608, 32, 32}, // Munition
18 {4111, 32, 608, 32, 32},
19 {4112, 64, 608, 32, 32},
20 {4113, 96, 608, 32, 32},
21 {4114, 128, 608, 32, 32},
22 {4115, 160, 608, 32, 32},
23 {4120, 192, 608, 32, 32}, // Helppacket
24 {4121, 224, 608, 32, 32}, // Sauerstoff
25 {4122, 256, 608, 32, 32}, // Feuerstein
26 {4000, 0, 512, 32, 32}, // Fenster 1
27 {4001, 32, 512, 32, 32}, // Fenster 2
28 {4002, 64, 512, 32, 32}, // Tor solid
29 {4003, 96, 512, 32, 32}, // Gitter
30 {4004, 128, 512, 32, 32}, // Dach l
31 {4005, 160, 512, 32, 32}, // Dach R
32 {4006, 192, 512, 32, 32}, // Busch 1
33 {4007, 224, 512, 32, 32}, // Busch 2
34 {4008, 256, 512, 32, 32}, // Tropfstein
35 {4009, 288, 512, 32, 32},
36 {4010, 320, 512, 32, 32},
37 {4011, 352, 512, 32, 32},
38 {4012, 384, 512, 32, 32},
39 {4013, 416, 512, 32, 32},
40 {4014, 448, 512, 32, 32},
41 {4015, 0, 544, 32, 32},
42 {4016, 32, 544, 32, 32},
43 {4017, 64, 544, 32, 32},
44 {4018, 96, 544, 32, 32},
45 {4020, 128, 544, 32, 32},
46 {4019, 416, 544, 64, 64},
47 // Player
48 {500, 0 * 32, 32, 32, 32}, // Sword
49 {501, 1 * 32, 32, 32, 32},
50 {502, 2 * 32, 32, 32, 32},
51 {503, 3 * 32, 32, 32, 32},
52 {504, 4 * 32, 32, 32, 32},
53 {505, 5 * 32, 32, 32, 32},
54 {506, 6 * 32, 32, 32, 32},
55 {507, 7 * 32, 32, 32, 32},
56 {520, 0 * 32, 64, 32, 32}, // Phiole
57 {521, 1 * 32, 64, 32, 32},
58 {522, 2 * 32, 64, 32, 32},
59 {523, 3 * 32, 64, 32, 32},
60 {524, 4 * 32, 64, 32, 32},
61 {510, 5 * 32, 64, 32, 32}, // Bacchetta
62 {511, 6 * 32, 64, 32, 32},
63 {512, 7 * 32, 64, 32, 32},
64 {513, 8 * 32, 64, 32, 32},
65 {514, 9 * 32, 64, 32, 32},
66 {530, 10 * 32, 64, 32, 32}, // Bow
67 {531, 11 * 32, 64, 32, 32},
68 {532, 12 * 32, 64, 32, 32},
69 {533, 13 * 32, 64, 32, 32},
70 {534, 14 * 32, 64, 32, 32},
71 {535, 15 * 32, 64, 32, 32},
72 {540, 0 * 32, 96, 32, 32}, // Scie
73 {541, 1 * 32, 96, 32, 32},
74 {542, 2 * 32, 96, 32, 32},
75 {543, 3 * 32, 96, 32, 32},
76 {544, 4 * 32, 96, 32, 32},
77 {545, 5 * 32, 96, 32, 32},
78 {546, 6 * 32, 96, 32, 32},
79 {550, 7 * 32, 96, 32, 32}, // Hands
80 {551, 8 * 32, 96, 32, 32},
81 {552, 9 * 32, 96, 32, 32},
82 {553, 10 * 32, 96, 32, 32},
83 {554, 11 * 32, 96, 32, 32},
84 {560, 0 * 32, 128, 32, 32}, // Bombs
85 {561, 1 * 32, 128, 32, 32},
86 {562, 2 * 32, 128, 32, 32},
87 {563, 3 * 32, 128, 32, 32},
88 {564, 4 * 32, 128, 32, 32},
89 {570, 5 * 32, 128, 32, 32}, // Staff
90 {571, 6 * 32, 128, 32, 32},
91 {572, 7 * 32, 128, 32, 32},
92 {573, 8 * 32, 128, 32, 32},
93 {574, 9 * 32, 128, 32, 32},
94 {575, 10 * 32, 128, 32, 32},
95 // Creeper
96 {1000, 0 * 32, 160, 32, 32},
97 {1001, 1 * 32, 160, 32, 32},
98 {1002, 2 * 32, 160, 32, 32},
99 {1003, 3 * 32, 160, 32, 32},
100 {1004, 4 * 32, 160, 32, 32},
101 {1005, 5 * 32, 160, 32, 32},
102 {1006, 6 * 32, 160, 32, 32},
103 {1007, 7 * 32, 160, 32, 32},
104 // Saqqraq
105 {1010, 8 * 32, 160, 32, 32},
106 {1011, 9 * 32, 160, 32, 32},
107 {1012, 10 * 32, 160, 32, 32},
108 {1013, 11 * 32, 160, 32, 32},
109 {1014, 12 * 32, 160, 32, 32},
110 {1015, 13 * 32, 160, 32, 32},
111 {1016, 14 * 32, 160, 32, 32},
112 {1017, 15 * 32, 160, 32, 32},
113 // Deadfish
114 {1020, 0 * 32, 192, 32, 32},
115 {1021, 1 * 32, 192, 32, 32},
116 {1022, 2 * 32, 192, 32, 32},
117 {1023, 3 * 32, 192, 32, 32},
118 {1024, 4 * 32, 192, 32, 32},
119 {1025, 5 * 32, 192, 32, 32},
120 {1026, 6 * 32, 192, 32, 32},
121 {1027, 7 * 32, 192, 32, 32},
122 // Ork
123 {1030, 8 * 32, 192, 32, 32},
124 {1031, 9 * 32, 192, 32, 32},
125 {1032, 10 * 32, 192, 32, 32},
126 {1033, 11 * 32, 192, 32, 32},
127 {1034, 12 * 32, 192, 32, 32},
128 {1035, 13 * 32, 192, 32, 32},
129 {1036, 14 * 32, 192, 32, 32},
130 {1037, 15 * 32, 192, 32, 32},
131 // Libelle
132 {1050, 0 * 32, 224, 32, 32},
133 {1051, 1 * 32, 224, 32, 32},
134 {1052, 2 * 32, 224, 32, 32},
135 {1053, 3 * 32, 224, 32, 32},
136 {1054, 4 * 32, 224, 32, 32},
137 {1055, 5 * 32, 224, 32, 32},
138 {1056, 6 * 32, 224, 32, 32},
139 {1057, 7 * 32, 224, 32, 32},
140 // BlackOrk
141 {1060, 8 * 32, 224, 32, 32},
142 {1061, 9 * 32, 224, 32, 32},
143 {1062, 10 * 32, 224, 32, 32},
144 {1063, 11 * 32, 224, 32, 32},
145 {1064, 12 * 32, 224, 32, 32},
146 {1065, 13 * 32, 224, 32, 32},
147 {1066, 14 * 32, 224, 32, 32},
148 {1067, 15 * 32, 224, 32, 32},
149 // Oger
150 {1070, 0 * 32, 256, 32, 32},
151 {1071, 1 * 32, 256, 32, 32},
152 {1072, 2 * 32, 256, 32, 32},
153 {1073, 3 * 32, 256, 32, 32},
154 {1074, 4 * 32, 256, 32, 32},
155 {1075, 5 * 32, 256, 32, 32},
156 {1076, 6 * 32, 256, 32, 32},
157 {1077, 7 * 32, 256, 32, 32},
158 // Nazgul
159 {1040, 8 * 32, 256, 32, 32},
160 {1041, 9 * 32, 256, 32, 32},
161 {1042, 10 * 32, 256, 32, 32},
162 {1043, 11 * 32, 256, 32, 32},
163 {1044, 12 * 32, 256, 32, 32},
164 {1045, 13 * 32, 256, 32, 32},
165 {1046, 14 * 32, 256, 32, 32},
166 {1047, 15 * 32, 256, 32, 32},
167 // Otyg
168 {1080, 0 * 32, 288, 32, 32},
169 {1081, 1 * 32, 288, 32, 32},
170 {1082, 2 * 32, 288, 32, 32},
171 {1083, 3 * 32, 288, 32, 32},
172 {1084, 4 * 32, 288, 32, 32},
173 {1085, 5 * 32, 288, 32, 32},
174 {1086, 6 * 32, 288, 32, 32},
175 {1087, 7 * 32, 288, 32, 32},
176 // Grieg
177 {1090, 8 * 32, 288, 32, 32},
178 {1091, 9 * 32, 288, 32, 32},
179 {1092, 10 * 32, 288, 32, 32},
180 {1093, 11 * 32, 288, 32, 32},
181 {1094, 12 * 32, 288, 32, 32},
182 {1095, 13 * 32, 288, 32, 32},
183 {1096, 14 * 32, 288, 32, 32},
184 {1097, 15 * 32, 288, 32, 32},
185 // Warg
186 {1100, 0 * 64, 320, 64, 64},
187 {1101, 1 * 64, 320, 64, 64},
188 {1102, 2 * 64, 320, 64, 64},
189 {1103, 3 * 64, 320, 64, 64},
190 {1104, 4 * 64, 320, 64, 64},
191 {1105, 5 * 64, 320, 64, 64},
192 {1106, 6 * 64, 320, 64, 64},
193 {1107, 7 * 64, 320, 64, 64},
194 // Weapons
195 {4803, 105, 649, 14, 14}, // Phiole
196 {5100, 7 * 32, 672, 32, 32},
197 {5101, 8 * 32, 672, 32, 32},
198 {4804, 138, 650, 12, 12}, // Zauberstab
199 {5110, 9 * 32, 672, 32, 32},
200 {5111, 10 * 32, 672, 32, 32},
201 {4802, 71, 650, 18, 10}, // Pfeilbogen
202 {5000, 0 * 32, 672, 32, 32},
203 {5001, 1 * 32, 672, 32, 32},
204 {5002, 2 * 32, 672, 32, 32},
205 {5003, 3 * 32, 672, 32, 32},
206 {5004, 4 * 32, 672, 32, 32},
207 {4805, 167, 650, 16, 14}, // Hand
208 {5120, 11 * 32, 672, 32, 32},
209 {5121, 12 * 32, 672, 32, 32},
210 {5122, 13 * 32, 672, 32, 32},
211 {5123, 14 * 32, 672, 32, 32},
212 {4806, 202, 652, 12, 12}, // Bombe
213 {5160, 0 * 64, 800, 64, 64},
214 {5161, 1 * 64, 800, 64, 64},
215 {5162, 2 * 64, 800, 64, 64},
216 {5163, 3 * 64, 800, 64, 64},
217 {5164, 4 * 64, 800, 64, 64},
218 {4807, 7 * 32, 640, 32, 32}, // Staff
219 {5126, 1 * 64, 704, 64, 64},
220 {5127, 2 * 64, 704, 64, 64},
221 {5128, 3 * 64, 704, 64, 64},
222 {5129, 4 * 64, 704, 64, 64},
223 {5130, 5 * 64, 704, 64, 64},
224 {4800, 9, 650, 14, 14}, // Unguided
225 {4801, 38, 646, 18, 18}, // aimed
226 {4810, 328, 649, 16, 16}, // guided
227 {5180, 4, 741, 27, 28},
228 {5181, 33, 736, 31, 31},
229 {5182, 159, 769, 30, 30},
230 //{4811, 6 * 32, 672, 32, 32},
231 {5138, 7 * 32, 768, 32, 32},
232 {5139, 8 * 32, 768, 32, 32},
233 {5140, 9 * 32, 768, 32, 32},
234 {5141, 10 * 32, 768, 32, 32},
235 {5142, 11 * 32, 768, 32, 32},
236 {4808, 263, 651, 18, 18}, // Trollbombs
237 {5124, 0 * 32, 704, 32, 32},
238 {5125, 1 * 32, 704, 32, 32},
239 {4809, 297, 650, 14, 12}, // Otyg
240 {5131, 0 * 32, 768, 32, 32},
241 {5132, 1 * 32, 768, 32, 32},
242 {5133, 2 * 32, 768, 32, 32},
243 {5134, 3 * 32, 768, 32, 32},
244 {5135, 4 * 32, 768, 32, 32},
245 {4113, 327, 649, 18, 18}, // Violett
246 {5120, 6 * 32, 736, 32, 32},
247 {5121, 7 * 32, 736, 32, 32},
248 {5122, 8 * 32, 736, 32, 32},
249 {5123, 9 * 32, 736, 32, 32},
250 {5124, 10 * 32, 736, 32, 32},
251 {4811, 356, 647, 25, 23}, // Warg 1
252 {5150, 12 * 32, 768, 32, 32},
253 {5151, 13 * 32, 768, 32, 32},
254 {4812, 384, 651, 34, 14}, // Warg 2
255 {2000, 0, 384, 32, 32}, // Türe
256 {2001, 33, 384, 30, 32}, // Lift
257 // Schalter etc.
258 {200, 0 * 32, 0, 32, 32},
259 {201, 1 * 32, 0, 32, 32},
260 {202, 2 * 32, 0, 32, 32},
261 {203, 3 * 32, 0, 32, 32},
262 {204, 4 * 32, 0, 32, 32},
263 {205, 5 * 32, 0, 32, 32},
264 {206, 6 * 32, 0, 32, 32},
265 {207, 7 * 32, 0, 32, 32},
266 {208, 8 * 32, 0, 32, 32},
267 {209, 9 * 32, 0, 32, 32},
268 {210, 362, 0, 32, 37},
269 {211, 394, 0, 32, 37},
270 {300, 10 * 32, 0, 32, 32},
271 // Letters
272 {65, 0, 864, 31, 24},
273 {66, 31, 864, 32, 24},
274 {67, 66, 864, 25, 24},
275 {68, 95, 864, 31, 24},
276 {69, 130, 864, 28, 24},
277 {70, 162, 864, 32, 24},
278 {71, 197, 864, 26, 24},
279 {72, 228, 864, 29, 24},
280 {73, 261, 864, 23, 24},
281
282 {74, 6, 888, 25, 25},
283 {75, 33, 888, 42, 25},
284 {76, 79, 888, 34, 25},
285 {77, 118, 888, 36, 25},
286 {78, 164, 888, 34, 25},
287 {79, 202, 888, 28, 25},
288 {80, 234, 888, 28, 25},
289 {81, 266, 888, 32, 25},
290 {82, 299, 888, 39, 25},
291
292 {83, 0, 914, 26, 25},
293 {84, 32, 914, 30, 25},
294 {85, 62, 914, 30, 25},
295 {86, 96, 914, 29, 25},
296 {87, 131, 914, 39, 25},
297 {88, 170, 914, 36, 25},
298 {89, 209, 914, 30, 25},
299 {90, 243, 914, 26, 25},
300
301 {33, 270, 914, 15, 25},
302 {63, 291, 914, 22, 25},
303
304 {49, 3, 939, 15, 21},
305 {50, 25, 939, 17, 21},
306 {51, 49, 939, 16, 21},
307 {52, 73, 939, 17, 21},
308 {53, 96, 939, 18, 21},
309 {54, 121, 939, 17, 21},
310 {55, 144, 939, 20, 21},
311 {56, 169, 939, 16, 21},
312 {57, 193, 939, 17, 21},
313 {48, 217, 939, 17, 21},
314 {46, 241, 939, 12, 21},
315 {44, 259, 939, 11, 21},
316 {45, 278, 939, 18, 21},
317
318 {10000, 317, 543, 94, 92},
319 {10001, 382, 806, 126, 126},
320 {10002, 322, 802, 40, 40}
321
322
323 };
324
325 static short kTextureDescriptor[kNumTextures][5] = {
326 // Texset 1
327 {3000, 0 * 32, 416, 32, 32},
328 {3001, 1 * 32, 416, 32, 32},
329 {3002, 2 * 32, 416, 32, 32},
330 {3003, 3 * 32, 416, 32, 32},
331 {3004, 4 * 32, 416, 32, 32},
332 {3005, 5 * 32, 416, 32, 32},
333 {3006, 6 * 32, 416, 32, 32},
334 {3007, 7 * 32, 416, 32, 32},
335 {3008, 8 * 32, 416, 32, 32},
336 {3009, 9 * 32, 416, 32, 32},
337 {3010, 10 * 32, 416, 32, 32},
338 {3011, 11 * 32, 416, 32, 32},
339 {3012, 12 * 32, 416, 32, 32},
340 {3013, 13 * 32, 416, 32, 32},
341 {3014, 14 * 32, 416, 32, 32},
342 // Texset 2
343 {3020, 0 * 32, 448, 32, 32},
344 {3021, 1 * 32, 448, 32, 32},
345 {3022, 2 * 32, 448, 32, 32},
346 {3023, 3 * 32, 448, 32, 32},
347 {3024, 4 * 32, 448, 32, 32},
348 {3025, 5 * 32, 448, 32, 32},
349 {3026, 6 * 32, 448, 32, 32},
350 {3027, 7 * 32, 448, 32, 32},
351 {3028, 8 * 32, 448, 32, 32},
352 {3029, 9 * 32, 448, 32, 32},
353 {3030, 10 * 32, 448, 32, 32},
354 {3031, 11 * 32, 448, 32, 32},
355 {3032, 12 * 32, 448, 32, 32},
356 {3033, 13 * 32, 448, 32, 32},
357 {3034, 14 * 32, 448, 32, 32},
358 // Texset 3
359 {3040, 0 * 32, 480, 32, 32},
360 {3041, 1 * 32, 480, 32, 32},
361 {3042, 2 * 32, 480, 32, 32},
362 {3043, 3 * 32, 480, 32, 32},
363 {3044, 4 * 32, 480, 32, 32},
364 {3045, 5 * 32, 480, 32, 32},
365 {3046, 6 * 32, 480, 32, 32},
366 {3047, 7 * 32, 480, 32, 32},
367 {3048, 8 * 32, 480, 32, 32},
368 {3049, 9 * 32, 480, 32, 32},
369 {3050, 10 * 32, 480, 32, 32},
370 {3051, 11 * 32, 480, 32, 32},
371 {3052, 12 * 32, 480, 32, 32},
372 {3053, 13 * 32, 480, 32, 32},
373 {3054, 14 * 32, 480, 32, 32}
374
375 };
376
377
378 #endif
0 #include "ShapeLd.hpp"
1 #include "Graphfil.hpp"
2 #include "Appl.hpp"
3 #include "Clut.hpp"
4 #include "ShapeDes.hpp"
5 #include "ConstVal.hpp"
6 #include <stdio.h>
7
8 extern CApplication *gApplication;
9 extern CSystem *gSystem;
10 extern CClutManager *gClutManager;
11 extern tConstValues *gConst;
12 extern CClutManager *gClutManager;
13 extern FILE *logFile;
14
15 CShapeManager::CShapeManager()
16 {
17 }
18
19 CShapeManager::~CShapeManager()
20 {
21 }
22
23 void CShapeManager::LoadShapes()
24 {
25 short n;
26 Graphic_file *plane;
27
28 MSG("Opening shape file\n");
29 plane = read_graphic_file(gSystem->QualifyDataDir(gConst->kFileShapes)); // by LL
30 if (!plane) gSystem->Error("Cannot find kFileShapes or cannot open it. Perhaps lack of memory?", 0);
31
32 MSG("Creating shapes and textures\n");
33 for (n = 0; n < kNumShapes; n ++) {
34 shapes[n] = new CMaskedShape(plane->bitmap, &kShapeDescriptor[n][0], plane->width);
35 }
36 for (n = 0; n < kNumTextures; n ++) {
37 for (short m = 0; m < 4; m ++) {
38 textures[n][m] = new CTexture(plane->bitmap, &kTextureDescriptor[n][0], plane->width, m);
39 }
40 }
41
42 gClutManager->CalculateCoronas(plane->bitmap, plane->width);
43
44 free_graphic_file(plane);
45 }
46
47 void CShapeManager::UnloadShapes()
48 {
49 short n;
50
51 for (n = 0; n < kNumShapes; n ++) {
52 delete shapes[n];
53 }
54 for (n = 0; n < kNumTextures; n ++) {
55 for (short m = 0; m < 4; m ++) {
56 delete textures[n][m];
57 }
58 }
59 }
60
61 void CShapeManager::LoadBackground(char *background)
62 {
63 MSG("Opening background image\n");
64 backgroundPicture = read_graphic_file(gSystem->QualifyDataDir(background));
65 if (!backgroundPicture) gSystem->Error("Cannot open background file. Lack of memory?", 0);
66 SwapBlackWhite(backgroundPicture);
67 }
68
69 void CShapeManager::UnloadBackground()
70 {
71 free_graphic_file(backgroundPicture);
72 }
73
74 CShape* CShapeManager::FindShape(short id, short light)
75 {
76 short n;
77 if (id == -1) return NULL; else {
78 if (id >= kTextureStart && id <= kTextureEnd) {
79 for (n = 0; n < kNumTextures && kTextureDescriptor[n][0] != id; n ++) {}
80 if (n != kNumTextures) return textures[n][light]; else return 0L;
81
82 }else{
83 for (n = 0; n < kNumShapes && kShapeDescriptor[n][0] != id; n ++) {}
84 if (n != kNumShapes) return shapes[n]; else return 0L;
85 }
86 }
87 }
88
89 unsigned char *CShapeManager::GetBackground(short &width, short &height)
90 {
91 width = backgroundPicture->width;
92 height = backgroundPicture->height;
93
94 return backgroundPicture->bitmap;
95 }
0 #ifndef __AMP_SHAPEMANAGER__
1 #define __AMP_SHAPEMANAGER__
2
3
4 #include "System.hpp"
5 #include "Shape.hpp"
6 #include "Graphfil.hpp"
7
8
9 enum {
10 kTotalShapes = 336,
11 kTextureStart = 3000,
12 kTextureEnd = 3054,
13 kNumTextures = 45,
14 kNumShapes = kTotalShapes - kNumTextures,
15 kAddPlayerStart = 510,
16 kAddPlayerEnd = 574
17 };
18
19
20 class CShapeManager {
21 protected:
22 CShape *shapes[kNumShapes];
23 CShape *textures[kNumTextures][4];
24 unsigned char *coronas;
25 Graphic_file *backgroundPicture;
26
27 public:
28 CShapeManager();
29 ~CShapeManager();
30
31 void LoadShapes();
32 void LoadBackground(char *name);
33 void UnloadShapes();
34 void UnloadBackground();
35
36 CShape *FindShape(short id, short light);
37 unsigned char *GetBackground(short &width, short &height);
38 };
39
40 #endif
0 #include "SndSys.hpp"
1 #include "Level.hpp"
2 #include "ConstVal.hpp"
3
4 extern CSoundSystem *gSoundSystem;
5 extern CLevel *gLevel;
6 extern tConstValues *gConst;
7 extern tConfigData *gConfigData;
8
9 const short kMaxUserSound = 10;
10
11 void Mix_Audio(void *udata, Uint8 *stream, int len)
12 {
13 gSoundSystem->ProcessList(udata, stream, len);
14 }
15
16 int InitializeSoundSystem()
17 {
18 SDL_AudioSpec wanted, obtained;
19
20 /* Set the audio format */
21 // Not all sounds are of the same sampling rate which is why
22 // some of them sound a little crappy. Some conversion should be performed...
23 wanted.freq = 11025;
24 wanted.format = (AUDIO_U8);
25 wanted.channels = 1;
26 wanted.samples = 512; /* Good low-latency value for callback */
27 wanted.callback = Mix_Audio;
28 wanted.userdata = NULL;
29
30 /* Open the audio device, forcing the desired format */
31 if ( SDL_OpenAudio(&wanted, &obtained) < 0 ) {
32 fprintf(stderr, "InitSoundSystem: Couldn't open audio: %s\n", SDL_GetError());
33 fprintf(stderr, "Sound was disabled. \n");
34 return(-1);
35 }
36 return(0);
37 }
38
39 CSoundSystem::CSoundSystem(int status)
40 {
41 state=status;
42
43 for (short n = 0; n < kNumWeapons; n ++) {
44 weaponLaunchSounds[n] = new CSound(kWeaponLaunchSounds[n]);
45 weaponHitSounds[n] = new CSound(kWeaponHitSounds[n]);
46 }
47
48 platformGo = new CSound(kPlatformGoSound);
49 platformStop = new CSound(kPlatformStopSound);
50 lightOn = new CSound(kLightOnSound);
51 lightOff = new CSound(kLightOffSound);
52
53 firestoneDamage = new CSound(kFirestoneDamage);
54
55 selMenu = new CSound(kSelMenuSound);
56 entrMenu = new CSound(kEntrMenuSound);
57 openMenu = new CSound(kOpenMenuSound);
58
59 playerJump = new CSound(kPlayerJumpSound);
60 playerDive = new CSound(kPlayerDiveSound);
61 playerPickup = new CSound(kPlayerPickupSound);
62
63 minDistance = gConst->kSoundMinDistance * gConst->kSoundMinDistance;
64 maxDistance = gConst->kSoundMaxDistance * gConst->kSoundMaxDistance;
65
66 playList = new CSoundList();
67
68 currentMaxSound = (SDL_MIX_MAXVOLUME) * gConfigData->soundVolume / kMaxUserSound;
69
70 if (state) {
71 SDL_PauseAudio(0); // turn the music on...
72 }
73
74 }
75
76 CSoundSystem::~CSoundSystem()
77 {
78 if (state) {
79 SDL_PauseAudio(1);
80 SDL_CloseAudio();
81 }
82 delete playList;
83 for (short n = 0; n < kNumWeapons; n ++) {
84 delete weaponLaunchSounds[n];
85 delete weaponHitSounds[n];
86 }
87
88 delete platformGo;
89 delete platformStop;
90 delete lightOn;
91 delete lightOff;
92
93 delete playerJump;
94 delete playerDive;
95 delete playerPickup;
96 }
97
98 void CSoundSystem::Play(CSound *which, double x, double y)
99 {
100 if (!state) return;
101 long distance = (long)((x - gLevel->focus->xm) * (x - gLevel->focus->xm) + (y - gLevel->focus->ym) * (y - gLevel->focus->ym));
102 double factor;
103
104 SoundState *newstate = new SoundState;
105
106 if (distance < minDistance) {
107 which->SetVol(currentMaxSound);
108 } else if (distance < maxDistance) {
109 factor = double(distance - minDistance) / double(maxDistance - minDistance);
110 which->SetVol(currentMaxSound - currentMaxSound * factor);
111 } else return;
112
113 which->Play(newstate);
114 playList->Insert(newstate);
115
116 }
117
118 void CSoundSystem::ProcessList(void *udata, Uint8 *stream, int len)
119 {
120 SoundState *theSound;
121 int mixlen;
122
123 playList->Reset();
124 // traverse the list of sounds being played
125 while (theSound = playList->GetNext()) {
126 mixlen = MIN(len, (int) theSound->bytesleft);
127 SDL_MixAudio(stream, theSound->soundpos, mixlen, theSound->volume);
128 theSound->soundpos += mixlen;
129 theSound->bytesleft -= mixlen;
130 if (!theSound->bytesleft) { // sound finished playing
131 playList->RemoveCurrent();
132 }
133 }
134 }
0 #ifndef _AMPH_SOUND_SYS_
1
2 #define _AMPH_SOUND_SYS_
3
4 #include "ObjInfo.hpp"
5 #include "SoundList.hpp"
6
7 const char kWeaponLaunchSounds[kNumWeapons][21] = {
8 "sounds/swordl.wav",
9 "sounds/phioll.wav",
10 "sounds/sorceryl.wav",
11 "sounds/bowl.wav",
12 "sounds/sciel.wav",
13 "sounds/handsl.wav",
14 "sounds/bombl.wav",
15 "sounds/staffl.wav",
16 "sounds/borkl.wav",
17 "sounds/aimedl.wav",
18 "sounds/guidedl.wav",
19 "sounds/trolll.wav",
20 "sounds/otygl.wav",
21 "sounds/nazgull.wav",
22 "sounds/warg1l.wav",
23 "sounds/warg2l.wav"
24 };
25
26 const char kWeaponHitSounds[kNumWeapons][21] = {
27 "sounds/swordh.wav",
28 "sounds/phiolh.wav",
29 "sounds/sorceryh.wav",
30 "sounds/bowh.wav",
31 "sounds/scieh.wav",
32 "sounds/handsh.wav",
33 "sounds/bombh.wav",
34 "sounds/staffh.wav",
35 "sounds/borkh.wav",
36 "sounds/aimedh.wav",
37 "sounds/guidedh.wav",
38 "sounds/trollh.wav",
39 "sounds/otygh.wav",
40 "sounds/nazgulh.wav",
41 "sounds/warg1h.wav",
42 "sounds/warg2h.wav"
43 };
44
45
46
47 const char kPlatformGoSound[21] = "sounds/platgo.wav";
48 const char kPlatformStopSound[21] = "sounds/platstop.wav";
49 const char kLightOnSound[21] = "sounds/lighton.wav";
50 const char kLightOffSound[21] = "sounds/lightoff.wav";
51
52 const char kSelMenuSound[21] = "sounds/selmenu.wav";
53 const char kEntrMenuSound[21] = "sounds/entrmenu.wav";
54 const char kOpenMenuSound[21] = "sounds/openmenu.wav";
55
56 const char kFirestoneDamage[21] = "sounds/stonedam.wav";
57
58 const char kPlayerJumpSound[21] = "sounds/jump.wav";
59 const char kPlayerDiveSound[21] = "sounds/dive.wav";
60 const char kPlayerPickupSound[21] = "sounds/pickup.wav";
61
62 class CSoundSystem {
63
64 private:
65 long maxDistance, minDistance;
66 long currentMaxSound;
67 // List of sounds being played
68 CSoundList *playList;
69
70 public:
71 // Weapon sounds
72 int state;
73 CSound *weaponLaunchSounds[kNumWeapons];
74 CSound *weaponHitSounds[kNumWeapons];
75
76 // Platform and light sounds
77 CSound *platformGo;
78 CSound *platformStop;
79 CSound *lightOn;
80 CSound *lightOff;
81
82 // Item sounds
83 CSound *firestoneDamage;
84
85 // GUI sounds
86 CSound *selMenu;
87 CSound *entrMenu;
88 CSound *openMenu;
89 CSound *playerJump;
90 CSound *playerDive;
91 CSound *playerPickup;
92
93 CSoundSystem(int state);
94 ~CSoundSystem();
95
96 void ProcessList(void*, Uint8*, int );
97 void Play(CSound *which, double x, double y);
98
99 };
100
101 #endif
0 // SoundList.cpp: Implementierung der Klasse CSoundList.
1 //
2 //////////////////////////////////////////////////////////////////////
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <math.h>
6 #include <stdio.h>
7 #include "SoundList.hpp"
8 #include "System.hpp"
9
10 extern CSystem *gSystem;
11
12 //////////////////////////////////////////////////////////////////////
13 // Konstruktion/Destruktion
14 //////////////////////////////////////////////////////////////////////
15
16 extern FILE *logFile;
17
18 CSound::CSound(const char* wav)
19 {
20 if (wav) {
21 // MSG("Loading ");
22 // MSG(wav);
23 if (!SDL_LoadWAV(gSystem->QualifyDataDir(wav),&specs, &data, &soundlen)) {
24 // MSG(" failed");
25 } else {
26 // MSG(" succeeded\n");
27 }
28 state = 1;
29 }
30 Reset();
31 }
32
33 void CSound::Reset()
34 {
35 playing = 0;
36 }
37
38 CSound::~CSound()
39 {
40 delete [] data;
41 }
42
43 void CSound::Play(SoundState *newstate)
44 {
45 newstate->sound=this;
46 newstate->bytesleft=soundlen;
47 newstate->volume=volume;
48 newstate->soundpos=data;
49 newstate->next=NULL;
50 }
51
52 bool CSound::isPlaying()
53 {
54 if (state) {
55 return (bool)playing;
56 }else return 0;
57 }
58
59 void CSound::SetVol(long vol)
60 {
61 volume=vol;
62 }
63
64
65 // --------------------------------------------------------
66
67 void CSoundList::Reset() {
68 current = first;
69 prev = first;
70 }
71
72 CSoundList::CSoundList()
73 {
74 first = new SoundState;
75 first->sound=NULL;
76 first->next=NULL;
77 Reset();
78 }
79
80 CSoundList::~CSoundList()
81 {
82 delete first;
83 }
84
85 SoundState *CSoundList::GetNext()
86 {
87 if (current) {
88 prev = current;
89 current = current->next;
90 }
91 return current;
92 }
93
94 void CSoundList::Insert(SoundState *s)
95 {
96 s->sound->playing ++;
97 s->next=first->next;
98 first->next=s;
99 }
100
101 void CSoundList::RemoveCurrent()
102 {
103 SoundState *tmp;
104
105 tmp =current;
106
107 if (current->sound) {
108 current->sound->playing --;
109 }
110 prev->next = current->next;
111 current = current->next;
112
113 delete tmp;
114 }
0 // SoundList.hpp: Schnittstelle für die Klasse CSoundList.
1 //
2 //////////////////////////////////////////////////////////////////////
3
4 #if !defined(_AMPH_SOUND_LIST_)
5 #define _AMPH_SOUND_LIST_
6
7 extern "C" {
8 #include <SDL/SDL.h>
9 #include <SDL/SDL_audio.h>
10 #include <SDL/SDL_types.h>
11 }
12
13 class CSound;
14
15 struct SoundState {
16 Uint8 *soundpos;
17 Uint32 bytesleft;
18 int volume;
19 CSound *sound;
20 SoundState *next;
21 };
22
23 class CSound
24 {
25 private:
26 short state; // 0 if sound doesn't exist, 1 if ok
27 public:
28 Uint8 *data;
29 Uint32 soundlen, playing;
30 int volume;
31
32 SDL_AudioSpec specs;
33 CSound(const char* wav);
34 ~CSound();
35 void Play(SoundState *newstate);
36 void Reset();
37 bool isPlaying();
38 void SetVol(long vol);
39 };
40
41
42 class CSoundList
43 {
44 public:
45 CSoundList();
46 ~CSoundList();
47
48 void Reset();
49 void Insert(SoundState *s);
50 SoundState *GetNext();
51 void RemoveCurrent();
52
53 private:
54 SoundState *first, *prev, *current;
55 };
56
57 #endif
0 #include "Surface.hpp"
1 #include "Shape.hpp"
2 #include "ShapeLd.hpp"
3 #include "Clut.hpp"
4 #include "ConstVal.hpp"
5 #include <memory.h>
6
7 const short kNoCharSpace = 20;
8 const char kNoCharChar = '_';
9
10 extern CSystem *gSystem;
11 extern CShapeManager *gShapeManager;
12 extern CClutManager *gClutManager;
13 extern tConstValues *gConst;
14
15 CGraphicSurface::CGraphicSurface(short dx, short dy)
16 {
17 buffer = gSystem->AllocateBuffer(dx, dy);
18 gSystem->SetBufferPalette(buffer);
19
20 width = dx;
21 height = dy;
22
23 numGraphics = 0;
24 }
25
26 CGraphicSurface::~CGraphicSurface()
27 {
28 for (short n = 0; n < numGraphics; n ++) {
29 if (graphicTypes[n] == kGraphicEmbedded) free_graphic_file(graphics[n]);
30 }
31 gSystem->DisposeBuffer(buffer);
32 }
33
34 unsigned char *CGraphicSurface::GetSurfacePtr(short *pitch)
35 {
36 unsigned char *tmp = gSystem->GetBufferPtr(buffer, pitch);
37
38 return tmp;
39 }
40
41 void CGraphicSurface::ReleaseSurface()
42 {
43 gSystem->ReleaseBufferPtr(buffer);
44 }
45
46 void CGraphicSurface::InsertGraphic(char *filename, Graphic_file *graphic, tRect *position)
47 {
48 if (filename) {
49 graphics[numGraphics] = read_graphic_file(filename);
50
51 SwapBlackWhite(graphics[numGraphics]);
52
53 graphicsPositions[numGraphics].left = 0;
54 graphicsPositions[numGraphics].top = 0;
55 graphicsPositions[numGraphics].right = graphics[numGraphics]->width;
56 graphicsPositions[numGraphics].bottom = graphics[numGraphics]->height;
57 graphicTypes[numGraphics] = kGraphicEmbedded;
58
59 numGraphics ++;
60 }
61 if (graphic && position) {
62 graphics[numGraphics] = graphic;
63
64 graphicsPositions[numGraphics].left = position->left;
65 graphicsPositions[numGraphics].top = position->top;
66 graphicsPositions[numGraphics].right = position->right;
67 graphicsPositions[numGraphics].bottom = position->bottom;
68 graphicTypes[numGraphics] = kGraphicReferenced;
69
70 numGraphics ++;
71 }
72 }
73
74 void CGraphicSurface::PaintGraphic(short num, short left, short top, short modus)
75 {
76 short j, k;
77 short bottom, right;
78 unsigned char *baseAddr, *linePtr, *sourcePtr, *sourceLinePtr;
79 short pitch;
80
81 baseAddr = gSystem->GetBufferPtr(buffer, &pitch);
82
83 // Luke hat hier das -1 entfernt
84 bottom = MIN(top + graphicsPositions[num].bottom - graphicsPositions[num].top, height);
85 right = MIN(left + graphicsPositions[num].right - graphicsPositions[num].left, pitch);
86
87 baseAddr += top * pitch + left;
88 sourcePtr = graphics[num]->bitmap + graphicsPositions[num].top * graphics[num]->width + graphicsPositions[num].left;
89
90 for (j = top; j < bottom; j ++) {
91 k = right - left;
92
93 sourceLinePtr = sourcePtr;
94 linePtr = baseAddr;
95
96 if (modus == kShapemodusNormal) {
97 memcpy(linePtr, sourcePtr, k);
98 } else {
99 while (k) {
100 gClutManager->SetPixel((unsigned char *)sourceLinePtr, (unsigned char *)linePtr, modus, 0);
101 linePtr++;
102 sourceLinePtr++;
103 k--;
104 }
105 }
106 baseAddr += pitch;
107 sourcePtr += graphics[num]->width;
108 }
109
110 gSystem->ReleaseBufferPtr(buffer);
111 }
112
113
114
115 #define INT_TO_FIXED(i) ((i) << 16)
116 #define FIXED_TO_INT(f) ((f) >> 16)
117 #define FIXED_TO_FLOAT(f) (((double) (f)) * 1.52587890625e-5)
118 #define FLOAT_TO_FIXED(f) ((long) ((f) * 65536.0))
119
120
121 void CGraphicSurface::DrawAntialiasedLine(short x1, short y1, short x2, short y2, unsigned char color, short modus)
122 {
123 unsigned char *baseAddr;
124 short pitch;
125
126 baseAddr = gSystem->GetBufferPtr(buffer, &pitch);
127
128 x1 = MAX(0, x1);
129 x1 = MIN(pitch, x1);
130 x2 = MAX(0, x2);
131 x2 = MIN(pitch, x2);
132 y1 = MAX(0, y1);
133 y1 = MIN(height -1, y1);
134 y2 = MAX(0, y2);
135 y2 = MIN(height -1, y2);
136
137 short dx = x2 - x1, dy = y2 - y1, dmax;
138 long ex, ey, curx = 0, cury = 0;
139 long lastx, lasty;
140 short counter;
141
142 if (abs(dx) > abs(dy)) {
143 ex = FLOAT_TO_FIXED(SIGN(dx) * 1.0);
144 ey = FLOAT_TO_FIXED((double)dy / (double)abs(dx));
145 counter = SIGN(dx) * dx;
146 }else{
147 ex = FLOAT_TO_FIXED((double)dx / (double)abs(dy));
148 ey = FLOAT_TO_FIXED(SIGN(dy) * 1.0);
149 counter = SIGN(dy) * dy;
150 }
151 curx = INT_TO_FIXED(x1);
152 cury = INT_TO_FIXED(y1);
153
154 lastx = INT_TO_FIXED(x1);
155 lasty = INT_TO_FIXED(y1);
156
157
158
159 baseAddr += (FIXED_TO_INT(lasty) * pitch + FIXED_TO_INT(lastx));
160
161 while (counter) {
162 gClutManager->SetPixel((unsigned char *)&color, baseAddr, modus, 0);
163
164 curx += ex;
165 cury += ey;
166 counter --;
167
168 if (lasty >> 16 != cury >> 16) {
169 baseAddr += (SIGN(cury - lasty)) * pitch;
170 lasty = cury;
171 }
172 if (lastx >> 16 != curx >> 16) {
173 baseAddr += SIGN(curx - lastx);
174 lastx = curx;
175 }
176 }
177 gSystem->ReleaseBufferPtr(buffer);
178 }
179
180
181 void CGraphicSurface::PaintRect(short left, short top, short right, short bottom, unsigned char color, short modus)
182 {
183 short j, k;
184 unsigned char *baseAddr;
185 short pitch;
186
187 baseAddr = gSystem->GetBufferPtr(buffer, &pitch);
188
189 left = MAX(0, left);
190 top = MAX(0, top);
191 left = MIN(pitch, left);
192 top = MIN(height, top);
193
194 right = MAX(0, right);
195 bottom = MAX(0, bottom);
196 right = MIN(pitch, right);
197 bottom = MIN(height, bottom);
198
199
200 baseAddr += top * pitch;
201
202 for (j = top; j < bottom; j ++) {
203 for (k = left; k < right; k ++) {
204 gClutManager->SetPixel((unsigned char *)&color, baseAddr + k, modus, 0);
205 }
206 baseAddr += pitch;
207 }
208
209 gSystem->ReleaseBufferPtr(buffer);
210 }
211
212 void CGraphicSurface::DrawString(short left, short top, char *text, short modus)
213 {
214 short n = 0, x, startWord, startShapePos;
215 short shapePos = left;
216 short dx, unused;
217 CShape *shape;
218 unsigned char *unused2;
219
220 tRect clipRect;
221
222 clipRect.left = clipRect.top = 0;
223 clipRect.right = width; clipRect.bottom = height;
224
225 while (text && text[n] != '\0') {
226 startWord = n;
227 startShapePos = shapePos;
228 x = n;
229 while (text[x] != kNoCharChar && text[x] != '\0') {
230 shape = gShapeManager->FindShape((short)text[x], 0);
231 if (shape) unused2 = shape->AllowPixelAccess(dx, unused); else dx = 0;
232 shapePos += dx;
233 x ++;
234 }
235 if (shapePos >= width) {
236 top += gConst->kTextYDistance;
237 shapePos = left;
238 }else shapePos = startShapePos;
239
240 x = startWord;
241 while (text[x] != kNoCharChar && text[x] != '\0') {
242 shape = gShapeManager->FindShape((short)text[x], 0);
243 if (shape) shapePos += shape->RenderShape(shapePos, top, &clipRect, modus, 0, this);
244 x ++;
245 }
246
247 if (text[x] == kNoCharChar) {
248 shapePos += kNoCharSpace;
249 x ++;
250 }
251 n = x;
252 }
253 }
254
255 void CGraphicSurface::FlipToScreen(short left, short top)
256 {
257 gSystem->FlipSurfaces(buffer, width, height, left, top);
258 }
0 #ifndef __AMP_GRAPHSURFACE__
1 #define __AMP_GRAPHSURFACE__
2
3 #include "System.hpp"
4 #include "Graphfil.hpp"
5
6 const short kMaxGraphics = 32;
7 const short kNumChars = 40;
8
9 enum {
10 kGraphicEmbedded,
11 kGraphicReferenced
12 }; // graphicType
13
14 class CShape;
15
16 class CGraphicSurface {
17 protected:
18 tGraphicBuffer *buffer;
19
20 Graphic_file *graphics[kMaxGraphics];
21 short graphicTypes[kMaxGraphics];
22 short numGraphics;
23 tRect graphicsPositions[kMaxGraphics];
24
25 public:
26 short width, height;
27
28 CGraphicSurface(short dx, short dy);
29 ~CGraphicSurface();
30
31 void InsertGraphic(char *filename, Graphic_file *graphic, tRect *position);
32 void PaintGraphic(short num, short left, short top, short modus);
33 void DrawAntialiasedLine(short x1, short y1, short x2, short y2, unsigned char color, short modus);
34 void PaintRect(short left, short top, short right, short bottom, unsigned char color, short modus);
35 void DrawString(short left, short top, char *text, short modus);
36
37 void FlipToScreen(short left, short top);
38 unsigned char *GetSurfacePtr(short *pitch);
39 void ReleaseSurface();
40 };
41
42 #endif
0 /*************************************
1 System.cpp
2
3 (c) 1999 Jonas Spillmann
4
5 Contains system-depending routines such as creating windows and video buffers
6 **************************************/
7
8 #include "System.hpp"
9 #include "Graphfil.hpp"
10 #include <sys/time.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include "Appl.hpp"
17 #include "Level.hpp"
18 #include "Player.hpp"
19
20 #ifdef _USE_LIB_XPM
21 extern "C" {
22 #include <X11/xpm.h>
23 }
24 #endif
25
26 extern FILE *logFile;
27 extern CSystem *gSystem;
28 extern CApplication *gApplication;
29 extern CLevel *gLevel;
30 extern tConfigData *gConfigData;
31
32 int InitializeSoundSystem();
33
34 /* Loads the icon to a surface */
35
36 inline static unsigned char Hex2Dec(char digit)
37 {
38 if (digit > 64)
39 return (digit - 55);
40 else
41 return (digit - 48);
42 }
43
44 static void ExtractColors(char *gstring, Uint8 *red, Uint8 *green, Uint8 *blue) {
45
46 *red = Hex2Dec(gstring[1])*16+Hex2Dec(gstring[2]);
47 *green = Hex2Dec(gstring[3])*16+Hex2Dec(gstring[4]);
48 *blue = Hex2Dec(gstring[5])*16+Hex2Dec(gstring[6]);
49 }
50
51 #ifdef _USE_LIB_XPM
52
53 SDL_Surface *CSystem::XPM2Surface(char *filename)
54 {
55 int x, ret;
56 unsigned int i, y;
57 unsigned char *buffer;
58 unsigned int *data;
59 short pitch;
60 SDL_Surface *icon;
61 XpmImage xpmimage;
62 SDL_Color *palette;
63
64 ret = XpmReadFileToXpmImage(filename, &xpmimage, NULL);
65
66 if (ret != XpmSuccess || xpmimage.cpp > 1) { // only 8bit pixmaps will work
67 return NULL;
68 }
69
70 icon = AllocateBuffer(xpmimage.width,xpmimage.height);
71 palette = new SDL_Color[xpmimage.ncolors];
72
73 // Get color palette
74 for (i=0; i < xpmimage.ncolors; ++i) {
75 ExtractColors(xpmimage.colorTable[i].c_color, &(palette[i].r),&(palette[i].g),&(palette[i].b));
76 }
77
78 buffer = GetBufferPtr(icon, &pitch);
79 data = xpmimage.data;
80
81 // Copy data
82 for (y = 0; y < xpmimage.width; y++ ) {
83 for (x = 0; x < xpmimage.height; x++) {
84 *buffer = (unsigned char)*data;
85 buffer++; data++;
86 }
87 }
88
89 ReleaseBufferPtr(icon);
90 SDL_SetColors(icon, palette, 0, xpmimage.ncolors);
91
92 return icon;
93 }
94
95 #endif
96
97 /* This function may run in a separate event thread */
98 static int FilterEvents(const SDL_Event *event) {
99
100 /* This quit event signals the closing of the window */
101 if ( (event->type == SDL_QUIT) ) {
102 exit(0);
103 return(0);
104 }
105 if ( event->type == SDL_KEYDOWN ) {
106 if (event->key.keysym.mod == KMOD_RALT || event->key.keysym.mod == KMOD_LALT){
107 switch (event->key.keysym.sym) {
108 case (SDLK_s):
109 gSystem->ScreenShot();
110 break;
111 case (SDLK_n):
112 gApplication->command = kCmdNextLevel;
113 break;
114 case (SDLK_p):
115 gApplication->command = kCmdPrevLevel;
116 break;
117 case (SDLK_w):
118 ((CPlayer *)gLevel->player)->GetItAll();
119 break;
120 default:
121 break;
122 }
123 return(0);
124 }
125 }
126 return(1);
127 }
128
129 char *CSystem::QualifyHomeDir(const char *fname)
130 {
131 char *tmp = new char[strlen(homeDir)+strlen(fname)+2];
132 sprintf(tmp, "%s/%s", homeDir, fname);
133
134 return tmp;
135 }
136
137 char *CSystem::QualifyDataDir(const char *fname)
138 {
139 char *tmp = new char[strlen(dataDir)+strlen(fname)+2];
140 sprintf(tmp, "%s/%s", dataDir, fname);
141
142 return tmp;
143 }
144
145 void CSystem::GetHomeDir()
146 {
147 char *tmp;
148 int rcode;
149
150 if (tmp = getenv("HOME")) {
151 homeDir = new char[strlen(tmp)+strlen(kHomeName)+2];
152 sprintf(homeDir, "%s/%s", tmp, kHomeName);
153 } else {
154 homeDir = strdup(".");
155 }
156 rcode = mkdir(homeDir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
157 }
158
159 //---------------------------------------------------------
160 CSystem::CSystem(char *theName)
161 /* In: theName: Name of the application
162
163 Register the application class and allocates space for the palette
164
165 WP: -
166 */
167 {
168 GetHomeDir();
169 dataDir = new char[strlen(INSTALL_DIR)+1];
170 strcpy(dataDir, INSTALL_DIR);
171
172 char *logFileName = QualifyHomeDir(kLogFileName);
173
174 logFile = fopen(logFileName, "w"); // by LL
175
176 strcpy(name, theName);
177
178 /* Initialize SDL */
179 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0 ) {
180 MSG("SDL_Init_Failed.");
181 MSG(SDL_GetError());
182
183 exit(1);
184 }
185 atexit(SDL_Quit);
186
187 // Ignore most events
188 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
189 SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);
190 SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
191 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
192 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
193 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
194 /* Filter quit and mouse motion events */
195 SDL_SetEventFilter(FilterEvents);
196
197 #ifdef _USE_LIB_XPM
198
199 SDL_Surface *icon;
200 icon = XPM2Surface(QualifyDataDir("amph.xpm"));
201 if (icon) {
202 SDL_WM_SetIcon(icon, 0);
203 DisposeBuffer(icon);
204 }
205
206 #endif
207
208 textout = false;
209
210 palColors = new RGBcolor[256];
211 palette = new SDL_Color[256];
212 startTicks = 0;
213
214 }
215
216
217 //------------------------------------
218 CSystem::~CSystem()
219 /*
220 Releases SDL
221 */
222 {
223
224 }
225
226 //-----------------------------------------------------------------------------
227 void CSystem::NewWindow(short left, short top, short width, short height)
228 /* In: left, top, width, height: position and size of windows being created
229 Usually left and top are set to 0 and width, height are equal to the screen size
230
231 Creates a new window
232 Initializes DirectX
233 Calls sound initialization
234
235 WP: * Application class registered
236 */
237 {
238 MSG("InitializeSoundSystem\n");
239 workingSound = gConfigData->haveSound && !(InitializeSoundSystem());
240 }
241
242
243 //----------------------------------------------------------
244 void CSystem::DisposeWindow()
245 /*
246 Destroys window
247 */
248 {
249 SDL_Quit();
250 }
251
252
253 //-----------------------------------------------------------------------
254 void CSystem::AllocateScreen(short rx, short ry, short depth)
255 /* In: rx, ry: Width and height of the videobuffer being allocated
256 depth: Pixeldepth of video buffer. Must be set to 8
257
258 Out: -
259
260 Locks the screen
261 Sets the screen resolution to rx x ry
262 Creates the primary video surface (which is actually the visible screen)
263
264 WP: * DirectDraw - object allocated (done in NewWindow)
265 * Window created
266 */
267 {
268 Uint32 sdl_vid_options;
269
270 MSG("Allocating screens\n");
271 sdl_vid_options = SDL_INIT_TIMER | SDL_HWSURFACE|SDL_HWPALETTE;
272 if (gConfigData->tryFullScreen) {
273 sdl_vid_options = sdl_vid_options | SDL_FULLSCREEN;
274 }
275
276 screenPort=SDL_SetVideoMode(640, 480, 8, sdl_vid_options);
277 if (!screenPort) {
278 fprintf(stderr, "Opening a window failed: %s \n", SDL_GetError());
279 exit(1);
280 }
281 PaintString(name,0,0,0);
282 SDL_ShowCursor(0);
283 }
284
285
286 // -------------------------------------------------
287 tGraphicBuffer *CSystem::AllocateBuffer(short rx, short ry)
288 /* In: rx, ry: Size of buffer being allocated
289 Out: Reference to new graphic buffer
290
291 Allocates a new graphics buffer. The buffer is allocated in main memory
292 because read access is faster on main memory than on video memory (perhaps not
293 true for AGP video cards)
294
295 WP: * Directdraw object created
296 */
297 {
298 tGraphicBuffer *port;
299
300 MSG("Allocate a buffer\n");
301 port = SDL_CreateRGBSurface(SDL_SWSURFACE,rx,ry,kScreenDepth,0,0,0,0);
302 if (port == NULL) Error("Error while creating an SDL Surface", 0);
303
304 return port;
305 }
306
307 //-------------------------------------------------------
308 void CSystem::DisposeScreen()
309 /* Disposes the screen buffer
310 */
311 {
312 if (screenPort) SDL_FreeSurface(screenPort);
313 }
314
315 //------------------------------------------------------
316 void CSystem::DisposeBuffer(tGraphicBuffer *buffer)
317 /* In: buffer: buffer being disposed
318
319 Disposes the indicated graphic buffer
320
321 WP: * buffer exists and is not locked
322 */
323 {
324 if (buffer) SDL_FreeSurface(buffer);
325 }
326
327
328 // --------------------------------------------------------
329 void CSystem::LoadPalette(char *name)
330 /* In: name: Name of palette file. The palette file must be a *.gif image file
331 with a saved palette. The image itself is ignored
332
333 Reads the palette file and stores the color information in the allocated palette array
334 Transforms the palette to a DirectDraw - palette and loads it
335 Make this palette active for the screen buffer
336
337 WP: * directDraw - object allocated
338 * palette allocated (in CSystem::CSystem)
339 * The file name must exist
340 */
341 {
342 Graphic_file *gf = read_graphic_file(QualifyDataDir(name));
343 if (!gf) Error("Cannot find or open the palette file (*.pal)", 0);
344
345 for (short n = 0; n < 256; n ++) {
346 palColors[n].red = gf->palette[n].red;
347 palColors[n].green = gf->palette[n].green;
348 palColors[n].blue = gf->palette[n].blue;
349 }
350
351 free_graphic_file(gf);
352
353 // Alle Farben der Reihe nach aus dem File lesen
354 for (short i=0; i<256; i++) {
355 palette[i].r = palColors[i].red;
356 palette[i].g = palColors[i].green;
357 palette[i].b = palColors[i].blue;
358 }
359
360 // Perform funny color switch
361 palette[0].r = 0;
362 palette[0].g = 0;
363 palette[0].b = 0;
364 palette[255].r = 255;
365 palette[255].g = 255;
366 palette[255].b = 255;
367
368 SDL_SetColors(screenPort, palette, 0, 256);
369 }
370
371 // --------------------------------------------------------
372 void CSystem::SetBufferPalette(tGraphicBuffer *buffer)
373 /* In: buffer: The buffer the palette should be made active
374
375 Makes the palette active for the indicated buffer. For each buffer this routine
376 must be called
377
378 WP: * buffer exists
379 * The palette is loaded (done in LoadPalette)
380 */
381 {
382 SDL_SetColors(buffer, palette, 0, 256);
383 }
384
385 // -------------------------------------------------------------------------
386 unsigned char *CSystem::GetBufferPtr(tGraphicBuffer *buffer, short *width)
387 // In: buffer: The buffer being locked for pixel access
388 //
389 // Out: width: Actual width of pixel plane of this buffer
390 //
391 // Prepares the graphic buffer indicated for drawing and returns the actual width
392 // and the adress of the plane
393 // if buffer = 0L, then the standard screen buffer will be locked
394 //
395 // WP: * buffer exists
396 // * width points to a valid container
397 {
398 if ( SDL_MUSTLOCK(buffer) ) {
399 if ( SDL_LockSurface(buffer) < 0 )
400 return NULL;
401 }
402
403 *width = buffer->pitch;
404
405 return (unsigned char *)buffer->pixels;
406 }
407
408 // -----------------------------------------------------------
409 void CSystem::ReleaseBufferPtr(tGraphicBuffer *buffer)
410 // Unlocks the graphic buffer indicated. If buffer = 0L, then the standard
411 // screen buffer will be unlocked
412 {
413 if ( SDL_MUSTLOCK(buffer) ) {
414 SDL_UnlockSurface(buffer);
415 }
416 }
417
418 // ----------------------------------------------------------------
419 void CSystem::FlipSurfaces(tGraphicBuffer *buffer, short width, short height, short posx, short posy)
420 /* In: buffer: The buffer being flipped to screen
421 width, height: Width and height of the plane being flipped. Usually equal to
422 the size of the buffer
423 posx, posy: Position of the lefttop corner of the flipped plane on the screen
424 */
425 // Blittes the content of buffer to the screen, assuming the buffer to have width X height,
426 // and blitting it on the screen to position posx / posy
427 // If buffer = 0L, then the standard screen buffer will be blitted using standard coordinates
428
429 // WP: * The screenPort is allocated (in AllocateScreen)
430 // * buffer exists
431 {
432 int hRet;
433 SDL_Rect rcRect, destRect;
434
435 if (buffer) {
436 rcRect.x = 0;
437 rcRect.y = 0;
438 rcRect.w = width;
439 rcRect.h = height;
440
441 destRect.x = posx;
442 destRect.y = posy;
443 destRect.w = width;
444 destRect.h = height;
445
446 hRet = SDL_BlitSurface( buffer, &rcRect, screenPort,&destRect);
447 SDL_UpdateRects(screenPort, 1, &destRect);
448 }
449 }
450
451 void CSystem::ProcessEvents()
452 {
453 SDL_Event event;
454 while (SDL_PollEvent(&event)) {
455
456 } // Luke
457 }
458
459
460 //----------------------------------------------
461 boolVar CSystem::KeyPressed(short key)
462 // In: key: Virtual key code of the tested key
463 // Out: True if the key is being pressed
464 //
465 // WP: -
466 {
467 Uint8 *keyboard_state;
468
469 ProcessEvents();
470 keyboard_state = SDL_GetKeyState(0);
471 return (boolVar)(keyboard_state[key] == SDL_PRESSED);
472 }
473
474 //--------------------------------------------------------
475 void CSystem::Error(char *message, short errorNo)
476 /* In: message: Error text
477 errorNo: Error number
478
479 Writes the message followed by the error number in the log file
480
481 WP: * logFile exists
482 */
483 {
484 MSG(message); fprintf(logFile, " %d\n", errorNo); fflush(logFile);
485 }
486
487
488 long CSystem::GetTickCount()
489 {
490 // Unused
491 struct timeval now;
492 long ticks;
493
494 gettimeofday(&now, NULL);
495 ticks=now.tv_sec*1000+now.tv_usec/1000;
496 return ticks;
497 }
498
499 //---------------------------------------------
500 long CSystem::GetTicks()
501 /* Out: Ticks
502
503 WP: startTicks is valid (done in ResetTicks)
504 */
505 {
506 return (SDL_GetTicks() + startTicks);
507 }
508
509 //---------------------------------------------------
510 void CSystem::ResetTicks(long startTickOffset)
511 /* In: startTickOffset: Reset value for ticks
512
513 */
514 {
515 startTicks = -SDL_GetTicks() + startTickOffset;
516 }
517
518 //-----------------------------------------------------------------------------------
519 void CSystem::PaintString(char *text, short x, short y, unsigned long foreColor)
520 /* In: text: Text being drawn
521 x, y: Position on screen
522 foreColor: color of text
523
524 Draws the text on the screen. Usually you do not call this routine
525
526 WP: * screenPort is allocated
527 */
528 {
529 SDL_WM_SetCaption(text,NULL);
530 }
531
532 void CSystem::ScreenShot()
533 {
534 if (screenPort) {
535 char *fileName = QualifyHomeDir("screenshot.bmp");
536 SDL_SaveBMP(screenPort, fileName);
537 delete [] fileName;
538 }
539 }
540
541 FILE *CSystem::FindFile(const char *fname)
542 {
543 FILE *tmp;
544
545 if (tmp=fopen(gSystem->QualifyHomeDir(fname), "r"))
546 return tmp; // check home directory
547 else
548 delete [] tmp;
549
550 if (tmp=fopen(gSystem->QualifyDataDir(fname), "r"))
551 return tmp; // check data directory
552 else
553 delete [] tmp;
554
555 return NULL; // failed
556 }
0 #ifndef __AMP_SYSTEM__
1 #define __AMP_SYSTEM__
2
3
4 #include <stdlib.h>
5 #include <stdarg.h>
6 #include <math.h>
7 #include <stdio.h>
8 #include "AmpHead.hpp"
9
10 extern "C" {
11 #include <SDL/SDL.h>
12 }
13
14 #ifndef INSTALL_DIR
15 #define INSTALL_DIR "/usr/local/games/amph"
16 #endif
17
18 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
19 #undef __BIG_ENDIAN__
20 #else
21 #define __BIG_ENDIAN__ 1
22 #endif
23
24 typedef bool boolVar;
25
26 const char kHomeName[] = ".amph";
27
28 enum {
29 kKeyLeft = SDLK_LEFT,
30 kKeyRight = SDLK_RIGHT,
31 kKeyUp = SDLK_UP,
32 kKeyDown = SDLK_DOWN,
33 kKeyD = SDLK_d,
34 kKeyC = SDLK_c,
35 kKeyY = SDLK_y,
36 kKeyX = SDLK_x,
37 kKeyScrLock = SDLK_SCROLLOCK,
38 kKeyPrscreen = SDLK_NUMLOCK,
39 kKeyEscape = SDLK_ESCAPE,
40 kKeyTab = SDLK_TAB,
41 kKeyPlus = SDLK_KP_PLUS,
42 kKeyMinus = SDLK_KP_MINUS,
43 kKeyControl = SDLK_LCTRL,
44 kKeyReturn = SDLK_RETURN,
45 kKeySpace = SDLK_SPACE
46 };
47
48 const unsigned char kASCIISpace = 32;
49 const unsigned char kASCIIEqual = 61;
50
51 const long kTicksPerSecond = 1000;
52 // Windows can't change the color indexes for black and white
53 const unsigned char kWhiteColor = 255;
54 const unsigned char kBlackColor = 0;
55
56 typedef SDL_Surface tGraphicBuffer;
57
58 //************************* class CSystem ********************
59
60 class CSystem {
61 protected:
62 //"""""""""""""""" Misc stuff
63 char name[16];
64 long startTicks;
65 bool textout;
66
67 //"""""""""""""""" Graphics stuff
68 tGraphicBuffer *screenPort;
69 SDL_Color *palette;
70 #ifdef _USE_LIB_XPM
71 SDL_Surface *XPM2Surface(char *pixmap);
72 #endif
73
74 public:
75 RGBcolor *palColors;
76 char *homeDir;
77 char *dataDir;
78 int workingSound;
79
80 //"""""""""""""""" System Stuff
81 CSystem(char *);
82 ~CSystem();
83
84 void NewWindow(short, short, short, short);
85 void DisposeWindow();
86
87 //"""""""""""""""" SDL Stuff
88 void AllocateScreen(short rx, short ry, short depth);
89 tGraphicBuffer *AllocateBuffer(short rx, short ry);
90 void DisposeBuffer(tGraphicBuffer *);
91 void DisposeScreen();
92 void LoadPalette(char *name);
93 void SetBufferPalette(tGraphicBuffer *);
94 unsigned char *GetBufferPtr(tGraphicBuffer *, short *width);
95 void ReleaseBufferPtr(tGraphicBuffer *);
96 void FlipSurfaces(tGraphicBuffer *, short width, short height, short posx, short posy);
97
98 //"""""""""""""""" User stuff
99 void Error(char *message, short errorNo);
100 boolVar KeyPressed(short key);
101 long GetTicks();
102 long GetTickCount();
103 void ResetTicks(long startTickOffset);
104 void PaintString(char *, short x, short y, unsigned long color);
105 void ProcessEvents();
106 void GetHomeDir();
107 char *QualifyDataDir(const char *fname);
108 char *QualifyHomeDir(const char *fname);
109 void ScreenShot();
110 FILE *FindFile(const char *fname);
111 };
112
113 #endif
0 #include "Thing.hpp"
1 #include "Appl.hpp"
2 #include "ConstVal.hpp"
3
4 extern CApplication *gApplication;
5 extern tConstValues *gConst;
6 extern CLevel *gLevel;
7
8
9 CThing::CThing(short initx, short inity, short width, short height, short number) : CObject(initx, inity, width, height)
10 {
11 typeID |= kThing;
12
13 dx = xe - xs;
14 dy = ye - ys;
15
16 weight = 10;
17 next = prev = nextCollisionThing = prevCollisionThing = 0L;
18 lookDirection = kLookingRight;
19 weightless = 0;
20 thingNumber = number;
21
22 // additinal initializations
23 modus = 0;
24 }
25
26 CThing::~CThing()
27 {}
28
29 void CThing::Gravitation()
30 {
31 if (weight && !weightless && forceVectorY < gConst->kMaxFallingSpeed * deltaTime * gConst->kVelocityUnit) forceVectorY += gConst->kGravitation * deltaTime;
32 }
33
34
35 void CThing::LinkInLists()
36 {
37 gApplication->Enqueue(&gApplication->thingList, this);
38 }
39
40 void CThing::UnlinkInLists()
41 {
42 gApplication->Dequeue(&gApplication->thingList, this);
43 }
44
45
46 void CThing::Render(short planeX, short planeY, tRect *clipRect)
47 {}
48
49 void CThing::PostRender(short planeX, short planeY, tRect *clipRect)
50 {}
51
52 short CThing::Forces()
53 {
54 short collisionObject;
55
56 Gravitation();
57
58 CObject::Forces();
59 ExertForce(resForceX, resForceY, collisionObject, 0L);
60
61 return kNoEvent;
62 }
63
64 void CThing::Move()
65 {
66 CElement *element;
67
68 //CObject::Forces();
69
70 if (ys < kLevelHeight * kElementSize) {
71 xs += resForceX + environmentForceX;
72 xe += resForceX + environmentForceX;
73 ys += resForceY + environmentForceY;
74 ye += resForceY + environmentForceY;
75 xm = xs + (xe - xs) * 0.5;
76 ym = ys + (ye - ys) * 0.5;
77 }
78 element = gLevel->GetElement(xm, ym);
79 modus = (element ? element->GetElementLiquid() : kShapemodusNormal);
80 }
81
82 void CThing::CalcPlaneOffsets(short &planex, short &planey)
83 {
84 short midx = xm;
85 short midy = ym;
86
87 if (midx <= kGamePlaneWidth / 2) planex = 0;
88 else if (midx >= kLevelWidth * kElementSize - kGamePlaneWidth / 2) planex = kLevelWidth * kElementSize - kGamePlaneWidth;
89 else planex = midx - kGamePlaneWidth / 2;
90
91 if (midy <= kGamePlaneHeight / 2) planey = 0;
92 else if (midy >= kLevelHeight * kElementSize - kGamePlaneHeight / 2) planey = kLevelHeight * kElementSize - kGamePlaneHeight;
93 else planey = midy - kGamePlaneHeight / 2;
94 }
95
96 short CThing::Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject)
97 {
98 if (right + forcex < xs || left + forcex > xe ||
99 bottom + forcey < ys || top + forcey > ye) return kNoCollision;
100
101 short returnValue = CObject::Collision(sender, left, top, right, bottom, forcex, forcey, pfx, pfy, sourceWeight, collisionObject);
102
103 if (returnValue & (kCollisionOnBottom | kCollisionWithPushing)) {
104 sender->CollisionEvent(gConst->kNormalFriction, 0);
105 }
106 return returnValue;
107 }
108
109 // ------------------------------------------------------------------------------
110 void CThing::TestForDamage(double xb, double yb, short rad, short blessure)
111 // Sending a damage event to the thing if the distance to the bullet is less than rad
112 {
113 if ((xm - xb) * (xm - xb) + (ym - yb) * (ym - yb) <= rad * rad) OnDamage(blessure);
114 }
115
116
117 void CThing::OnDamage(short blessure)
118 {
119 }
120
121
122 short CThing::Write(FILE *f)
123 {
124 long size = 0;
125
126 WRITEDATA(size);
127 WRITEDATA(typeID);
128 WRITEDATA(thingNumber);
129
130 size += CObject::Write(f);
131
132 WRITEDATA(lookDirection);
133 WRITEDATA(weightless);
134 WRITEDATA(dx);
135 WRITEDATA(dy);
136 WRITEDATA(modus);
137
138 FINISHWRITE;
139
140 return size;
141 }
142
143 void CThing::Read(FILE *f)
144 {
145 long size = 0;
146
147 READDATA(size);
148 READDATA(typeID);
149 READDATA(thingNumber);
150
151 CObject::Read(f);
152
153 READDATA(lookDirection);
154 READDATA(weightless);
155 READDATA(dx);
156 READDATA(dy);
157 READDATA(modus);
158 }
0 #ifndef __AMP_THING__
1 #define __AMP_THING__
2
3 #include "Object.hpp"
4
5 class CWeapon;
6 class CHandWeapon;
7 class CSorcery;
8 class CBomb;
9 class CMultiBulletWeapon;
10 class CStaff;
11 class CSineWeapon;
12 class CGuided;
13
14 enum { // Looking values
15 kLookingRight = 1,
16 kLookingLeft = -1
17 };
18
19 class CThing : public CObject {
20 friend class CWeapon;
21 friend class CHandWeapon;
22 friend class CSorcery;
23 friend class CBomb;
24 friend class CMultiBulletWeapon;
25 friend class CStaff;
26 friend class CSineWeapon;
27 friend class CGuided;
28
29 protected:
30 short lookDirection; // in which direction the thing looks
31 short weightless;
32 short dx, dy;
33 short modus;
34 short thingNumber;
35
36 public:
37 CThing *next, *prev, *nextCollisionThing, *prevCollisionThing;
38 CThing *nextPreRenderThing, *prevPreRenderThing;
39 CThing *nextPostRenderThing, *prevPostRenderThing;
40
41
42 CThing(short initx, short inity, short width, short height, short number);
43 ~CThing();
44
45 void Gravitation();
46 virtual void LinkInLists();
47 virtual void UnlinkInLists();
48
49 virtual void Render(short planeX, short planeY, tRect *clipRect);
50 virtual void PostRender(short planeX, short planeY, tRect *clipRect);
51 virtual void Move();
52 virtual short Forces();
53 void CalcPlaneOffsets(short &planex, short &planey);
54 short Collision(CObject *sender, double left, double top, double right, double bottom, double &forcex, double &forcey, double pfx, double pfy, short sourceWeight, short &collisionObject);
55 virtual void TestForDamage(double xb, double yb, short rad, short blessure);
56
57 virtual void OnDamage(short blessure);
58
59 virtual short Write(FILE *f);
60 virtual void Read(FILE *f);
61
62
63
64 };
65
66 #endif
0 #include "Weapon.hpp"
1 #include "System.hpp"
2 #include "Bullet.hpp"
3 #include "Appl.hpp"
4 #include "Thing.hpp"
5 #include "ConstVal.hpp"
6 #include "SndSys.hpp"
7
8 extern CSystem *gSystem;
9 extern CApplication *gApplication;
10 extern tConstValues *gConst;
11 extern CLevel *gLevel;
12 extern CSoundSystem *gSoundSystem;
13
14 short *FindDescriptor(short id);
15
16
17 CWeapon::CWeapon(CThing *own, tWeaponInfo *weaponInfo, CShape *attack)
18 {
19 owner = own;
20 info = weaponInfo;
21 attackShape = attack;
22 lastShoot = 0;
23 lastShootFrame = 0; // by LL
24 weaponStatus = kWeaponDoesntExist;
25 munition = 0;
26 repetition = (owner->typeID & kPlayer) ? info->repetition : info->repetition * gApplication->currentWeaponSF;
27 }
28
29 CWeapon::~CWeapon()
30 {}
31
32 void CWeapon::AddMunition(short mun)
33 {
34 munition += mun;
35 munition = MIN(munition, info->munition);
36 if (weaponStatus == kWeaponOutOfMunition) weaponStatus = kWeaponReady;
37 }
38
39 short CWeapon::Shoot(double directionx, double directiony, double targetpos)
40 {
41 CBullet *temp;
42 short *descr;
43
44 if (weaponStatus == kWeaponReady && lastShoot <= gSystem->GetTicks()) {
45 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
46 lastShoot = gSystem->GetTicks() + repetition;
47 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
48 descr = FindDescriptor(info->projectileShapes[0]);
49 temp = new CBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, directionx, directiony, owner, targetpos);
50
51 munition --;
52 if (!munition) weaponStatus = kWeaponOutOfMunition;
53
54 return 1;
55 }else return 0;
56 }
57
58 short CWeapon::ShootAnimation(CShape **currentShape)
59 {
60 if (owner->lastTime < lastShootFrame) {
61 *currentShape = attackShape;
62 return 0;
63 }else return 1;
64 }
65
66
67 void CWeapon::SaveDataToNextLevel(short *mun, short *stat)
68 {
69 *mun = munition;
70 *stat = weaponStatus;
71 }
72
73 void CWeapon::RestoreDataFromPrevLevel(short mun, short stat)
74 {
75 munition = mun;
76 weaponStatus = stat;
77 }
78
79 CHandWeapon::CHandWeapon(CThing *own, tWeaponInfo *weaponInfo, CShape *attack1, CShape *attack2, CShape *attack3) : CWeapon(own, weaponInfo, attack1)
80 {
81 numAnimFrames = 1;
82 attackShape2 = attack2; if (attackShape2) numAnimFrames = 2;
83 attackShape3 = attack3; if (attackShape3) numAnimFrames = 3;
84
85 animationFrame = 4;
86 shootFrameTime = gConst->kShootFrameTime * (4 - numAnimFrames);
87 }
88
89 CHandWeapon::~CHandWeapon() {}
90
91 short CHandWeapon::Shoot(double directionx, double unused, double unused2)
92 {
93 if (weaponStatus == kWeaponReady && lastShoot <= gSystem->GetTicks()) {
94 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
95 lastShoot = gSystem->GetTicks() + repetition;
96 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
97 animationFrame = 0;
98
99 return 1;
100 }else return 0;
101 }
102
103 short CHandWeapon::ShootAnimation(CShape **currentShape)
104 {
105 if (animationFrame < numAnimFrames) {
106 switch (animationFrame) {
107 case 0: *currentShape = attackShape; break;
108 case 1: *currentShape = attackShape2; break;
109 case 2: *currentShape = attackShape3; break;
110 }
111 if (owner->lastTime > lastShootFrame) {
112 animationFrame ++;
113 lastShootFrame = owner->lastTime + shootFrameTime;
114 }
115 return 0;
116 }else if (animationFrame == numAnimFrames) {
117
118 tThingList *currentEntry = gApplication->collisionThingList;
119
120 while (currentEntry) {
121 if (currentEntry->thing != owner) currentEntry->thing->TestForDamage(owner->lookDirection == kLookingRight ? owner->xe : owner->xs, owner->ye - gConst->kWeaponCarryHeight, info->rad, info->damage);
122 currentEntry = currentEntry->next;
123 }
124 animationFrame = SHRT_MAX;
125 }
126 return 1;
127 }
128
129 CSorcery::CSorcery(CThing *own, tWeaponInfo *weaponInfo, CShape *attack) : CWeapon(own, weaponInfo, attack)
130 {}
131
132 CSorcery::~CSorcery() {}
133
134 short CSorcery::Shoot(double directionx, double directiony, double unused)
135 {
136 CBullet *temp;
137 short *descr;
138
139 if (weaponStatus == kWeaponReady && lastShoot <= gSystem->GetTicks()) {
140 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
141 lastShoot = gSystem->GetTicks() + repetition;
142 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
143 descr = FindDescriptor(info->projectileShapes[0]);
144 temp = new CSorceryBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, directionx, ABS(directionx), owner, 0);
145
146 munition --;
147 if (!munition) weaponStatus = kWeaponOutOfMunition;
148
149 return 1;
150 }else return 0;
151 }
152
153 CBomb::CBomb(CThing *own, tWeaponInfo *weaponInfo, CShape *attack, CShape *det) : CWeapon(own, weaponInfo, attack)
154 {
155 status = kReady;
156 detonator = det;
157 }
158
159 CBomb::~CBomb() {}
160
161 short CBomb::Shoot(double directionx, double directiony, double unused)
162 {
163 CBombBullet *temp;
164 short *descr;
165
166 if (weaponStatus == kWeaponReady && lastShoot <= gSystem->GetTicks()) {
167 lastShoot = gSystem->GetTicks() + repetition;
168 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
169
170 if (status == kReady) {
171 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
172 status = kDetonation;
173 descr = FindDescriptor(info->projectileShapes[0]);
174 temp = new CBombBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, directionx, directiony, owner, 0);
175 bomb = temp;
176
177 munition --;
178 }else{
179 gSoundSystem->Play(gSoundSystem->weaponHitSounds[weaponNumber], bomb->xm, bomb->ym);
180 if (bomb) ((CBombBullet *)bomb)->detonate = 1;
181 bomb = 0L;
182 status = kReady;
183 if (!munition) weaponStatus = kWeaponOutOfMunition;
184 }
185 return 1;
186 }else return 0;
187 }
188
189 short CBomb::ShootAnimation(CShape **currentShape)
190 {
191 if (status == kDetonation) *currentShape = detonator;
192 if (owner->lastTime < lastShootFrame && status == kDetonation) *currentShape = attackShape;
193 return 1;
194 }
195
196
197 CMultiBulletWeapon::CMultiBulletWeapon(CThing *own, tWeaponInfo *weaponInfo, CShape *attack, double angle) : CWeapon(own, weaponInfo, attack)
198 {
199 numOfBullets = weaponInfo->error;
200 alpha = angle;
201 initAlpha = (double)(numOfBullets - 1) / 2.0 * alpha;
202 }
203
204 CMultiBulletWeapon::~CMultiBulletWeapon() {}
205
206
207 short CMultiBulletWeapon::Shoot(double directionx, double directiony, double targetpos)
208 {
209 CBullet *temp;
210 short *descr;
211 double dx, dy, tmp;
212
213 if (weaponStatus == kWeaponReady && lastShoot <= gSystem->GetTicks()) {
214 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
215 lastShoot = gSystem->GetTicks() + repetition;
216 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
217 descr = FindDescriptor(info->projectileShapes[0]);
218
219 dx = directionx * cos(initAlpha) - directiony * sin(initAlpha);
220 dy = directionx * sin(initAlpha) + directiony * cos(initAlpha);
221 for (short n = 0; n < numOfBullets && weaponStatus == kWeaponReady; n ++) {
222 temp = new CBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, dx, dy, owner, targetpos);
223
224 munition --;
225 if (!munition) weaponStatus = kWeaponOutOfMunition;
226
227 tmp = dx * cos(alpha) + dy * sin(alpha);
228 dy = -dx * sin(alpha) + dy * cos(alpha);
229 dx = tmp;
230 }
231
232 return 1;
233 }else return 0;
234 }
235
236
237 CStaff::CStaff(CThing *own, tWeaponInfo *weaponInfo, CShape *attack, CShape *load) : CWeapon(own, weaponInfo, attack)
238 {
239 loaded = load;
240 inLoad = 0;
241 lastLoad = 0;
242 }
243
244 CStaff::~CStaff()
245 {}
246
247
248 short CStaff::Shoot(double directionx, double directiony, double targetpos)
249 {
250 long time = gSystem->GetTicks();
251
252 dx = directionx;
253 dy = directiony;
254
255 if (time - lastLoad < 100) {
256 lastLoad = time;
257 if (time - staffLoadTime >= gConst->kStaffLoadTime) inLoad = 1;
258 }else if (lastShoot <= time && weaponStatus == kWeaponReady) {
259 lastLoad = time;
260 staffLoadTime = time;
261 }
262
263 return 0;
264 }
265
266
267 short CStaff::ShootAnimation(CShape **currentShape)
268 {
269 long time = gSystem->GetTicks();
270
271 if (time - lastLoad < 100) { // Weapon is in load
272 if (time - staffLoadTime < gConst->kStaffLoadTime)
273 *currentShape = attackShape;
274 else *currentShape = loaded;
275 return 0;
276 }else if (inLoad) { // Weapon is released
277 CBullet *temp;
278 short *descr;
279
280 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
281 lastShoot = gSystem->GetTicks() + repetition;
282 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
283 descr = FindDescriptor(info->projectileShapes[0]);
284 temp = new CSineBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, dx, 0, owner, 0, gConst->kSineWeaponRad, info->error);
285
286 munition --;
287 if (!munition) weaponStatus = kWeaponOutOfMunition;
288
289 inLoad = 0;
290 }
291
292 if (time < lastShootFrame) {
293 *currentShape = loaded;
294 return 0;
295 }
296 return 1;
297 }
298
299
300 CSineWeapon::CSineWeapon(CThing *own, tWeaponInfo *weaponInfo, CShape *attack, short rad) : CWeapon(own, weaponInfo, attack)
301 {
302 radius = rad;
303 }
304
305 CSineWeapon::~CSineWeapon()
306 {}
307
308 short CSineWeapon::Shoot(double directionx, double directiony, double targetpos)
309 {
310 CBullet *temp;
311 short *descr;
312
313 if (lastShoot <= gSystem->GetTicks()) {
314 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
315 lastShoot = gSystem->GetTicks() + repetition;
316 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
317 descr = FindDescriptor(info->projectileShapes[0]);
318 temp = new CSineBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, directionx, directiony, owner, targetpos, radius, info->error);
319 return 1;
320 }else return 0;
321 }
322
323 CGuided::CGuided(CThing *own, tWeaponInfo *weaponInfo, CShape *attack) : CWeapon(own, weaponInfo, attack)
324 {
325 }
326
327 CGuided::~CGuided()
328 {}
329
330 short CGuided::Shoot(double directionx, double directiony, double targetpos)
331 {
332 CBullet *temp;
333 short *descr;
334
335 if (lastShoot <= gSystem->GetTicks()) {
336 gSoundSystem->Play(gSoundSystem->weaponLaunchSounds[weaponNumber], owner->xm, owner->ym);
337 lastShoot = gSystem->GetTicks() + repetition;
338 lastShootFrame = gSystem->GetTicks() + gConst->kShootFrameTime;
339 descr = FindDescriptor(info->projectileShapes[0]);
340 temp = new CGuidedBullet((owner->lookDirection == kLookingRight ? owner->xe - descr[3] / 2 - kWeaponBodyOffset : owner->xs + kWeaponBodyOffset + descr[3] / 2), owner->ye - gConst->kWeaponCarryHeight, descr[3], descr[4], weaponNumber, info, directionx, directiony, owner, targetpos, gLevel->player);
341
342 return 1;
343 }else return 0;
344 }
345
346
347
348 short CWeapon::Write(FILE *f)
349 {
350 long size = 0;
351
352 WRITEDATA(size);
353
354 WRITEDATA(munition);
355 WRITEDATA(lastShoot);
356 WRITEDATA(lastShootFrame);
357 WRITEDATA(weaponStatus);
358 WRITEDATA(repetition);
359
360 FINISHWRITE;
361
362 return size;
363 }
364
365 void CWeapon::Read(FILE *f)
366 {
367 long size = 0;
368
369 READDATA(size);
370
371 READDATA(munition);
372 READDATA(lastShoot);
373 READDATA(lastShootFrame);
374 READDATA(weaponStatus);
375 READDATA(repetition);
376 }
377
378 short CHandWeapon::Write(FILE *f)
379 {
380 long size = 0;
381
382 WRITEDATA(size);
383
384 size += CWeapon::Write(f);
385
386 WRITEDATA(animationFrame);
387 WRITEDATA(numAnimFrames);
388 WRITEDATA(shootFrameTime);
389
390 FINISHWRITE;
391
392 return size;
393 }
394
395 void CHandWeapon::Read(FILE *f)
396 {
397 long size = 0;
398
399 READDATA(size);
400
401 CWeapon::Read(f);
402
403 READDATA(animationFrame);
404 READDATA(numAnimFrames);
405 READDATA(shootFrameTime);
406
407 }
408
409 short CBomb::Write(FILE *f)
410 {
411 long size = 0;
412
413 WRITEDATA(size);
414
415 size += CWeapon::Write(f);
416
417 WRITEDATA(status);
418
419 FINISHWRITE;
420
421 return size;
422 }
423
424 void CBomb::Read(FILE *f)
425 {
426 long size = 0;
427
428 READDATA(size);
429
430 CWeapon::Read(f);
431
432 READDATA(status);
433 }
434
435
436 short CStaff::Write(FILE *f)
437 {
438 long size = 0;
439
440 WRITEDATA(size);
441
442 size += CWeapon::Write(f);
443
444 WRITEDATA(staffLoadTime);
445 WRITEDATA(lastLoad);
446 WRITEDATA(inLoad);
447 WRITEDATA(dx);
448 WRITEDATA(dy);
449
450 FINISHWRITE;
451
452 return size;
453 }
454
455 void CStaff::Read(FILE *f)
456 {
457 long size = 0;
458
459 READDATA(size);
460
461 CWeapon::Read(f);
462
463 READDATA(staffLoadTime);
464 READDATA(lastLoad);
465 READDATA(inLoad);
466 READDATA(dx);
467 READDATA(dy);
468
469 }
0 #ifndef __AMP_WEAPON__
1 #define __AMP_WEAPON__
2
3 #include "ObjInfo.hpp"
4 #include "Thing.hpp"
5 #include "SoundList.hpp"
6
7 const short kWeaponBodyOffset = 3; // At which direction of the body the shooted bullet is placed
8
9 class CGUI;
10
11 class CWeapon {
12 friend class CGUI;
13
14 protected:
15 CThing *owner;
16 tWeaponInfo *info;
17 CShape *attackShape;
18 short munition;
19
20 long lastShoot, lastShootFrame;
21 short repetition;
22
23 CSound *launchSound, *hitSound;
24
25
26 public:
27 long ID;
28 long savedID;
29 short weaponStatus;
30 short weaponNumber;
31
32 CWeapon(CThing *own, tWeaponInfo *weaponInfo, CShape *attack);
33 ~CWeapon();
34
35 void SetID(long);
36
37 void AddMunition(short munition);
38 virtual short Shoot(double directionx, double directiony, double targetpos);
39 virtual short ShootAnimation(CShape **);
40
41 void SaveDataToNextLevel(short *, short *);
42 void RestoreDataFromPrevLevel(short, short);
43
44 virtual short Write(FILE *f);
45 virtual void Read(FILE *f);
46 };
47
48
49 class CHandWeapon : public CWeapon {
50 protected:
51 CShape *attackShape2, *attackShape3;
52 short animationFrame;
53 short numAnimFrames;
54 long shootFrameTime;
55
56 public:
57 CHandWeapon(CThing *own, tWeaponInfo *weaponInfo, CShape *attack1, CShape *attack2, CShape *attack3);
58 ~CHandWeapon();
59
60 short Shoot(double directionx, double directiony, double targetpos);
61 short ShootAnimation(CShape **);
62
63 short Write(FILE *f);
64 void Read(FILE *f);
65 };
66
67
68 class CSorcery : public CWeapon {
69 protected:
70
71 public:
72 CSorcery(CThing *own, tWeaponInfo *weaponInfo, CShape *attack);
73 ~CSorcery();
74
75 short Shoot(double directionx, double directiony, double unused);
76 };
77
78 enum { // stati
79 kReady,
80 kDetonation
81 };
82
83 class CBomb : public CWeapon {
84 protected:
85 short status;
86 CThing *bomb;
87 CShape *detonator;
88
89 public:
90 CBomb(CThing *own, tWeaponInfo *info, CShape *attack, CShape *det);
91 ~CBomb();
92
93 short Shoot(double directionx, double directiony, double unused);
94 short ShootAnimation(CShape **);
95
96 short Write(FILE *f);
97 void Read(FILE *f);
98 };
99
100 class CMultiBulletWeapon : public CWeapon {
101 protected:
102 short numOfBullets;
103 double alpha, initAlpha;
104
105 public:
106 CMultiBulletWeapon(CThing *own, tWeaponInfo *info, CShape *attack, double angle);
107 ~CMultiBulletWeapon();
108
109 short Shoot(double directionx, double directiony, double targetpos);
110 };
111
112
113 class CStaff : public CWeapon {
114 protected:
115 long staffLoadTime;
116 long lastLoad;
117 short inLoad;
118 CShape *loaded;
119 double dx, dy;
120
121 public:
122 CStaff(CThing *own, tWeaponInfo *info, CShape *attack, CShape *load);
123 ~CStaff();
124
125 short Shoot(double directionx, double directiony, double unused);
126 short ShootAnimation(CShape **);
127
128 short Write(FILE *f);
129 void Read(FILE *f);
130 };
131
132
133 class CSineWeapon : public CWeapon {
134 protected:
135 short radius;
136
137 public:
138 CSineWeapon(CThing *own, tWeaponInfo *info, CShape *attack, short rad);
139 ~CSineWeapon();
140
141 short Shoot(double directionx, double directiony, double targetpos);
142 };
143
144
145 class CGuided : public CWeapon
146 {
147 public:
148 CGuided(CThing *own, tWeaponInfo *info, CShape *attack);
149 ~CGuided();
150
151 short Shoot(double directionx, double directiony, double targetpos);
152 };
153
154 #endif