Remove unnecessary projects and libs
This commit is contained in:
77
.gitmodules
vendored
77
.gitmodules
vendored
@@ -1,38 +1,3 @@
|
||||
[submodule "project/jni/application/NewRAW"]
|
||||
path = project/jni/application/NewRAW
|
||||
url = https://github.com/usineur/android-newraw.git
|
||||
[submodule "project/jni/boost/src"]
|
||||
path = project/jni/boost/src
|
||||
url = https://github.com/moritz-wundke/Boost-for-Android.git
|
||||
branch = master
|
||||
update = merge
|
||||
[submodule "project/jni/application/commandergenius/commandergenius"]
|
||||
path = project/jni/application/commandergenius/commandergenius
|
||||
url = https://github.com/gerstrong/Commander-Genius.git
|
||||
[submodule "project/jni/application/openarena/engine"]
|
||||
path = project/jni/application/openarena/engine
|
||||
url = https://github.com/pelya/openarena-engine.git
|
||||
[submodule "project/jni/application/openarena/vm"]
|
||||
path = project/jni/application/openarena/vm
|
||||
url = https://github.com/pelya/openarena-vm
|
||||
[submodule "project/jni/application/teeworlds/src"]
|
||||
path = project/jni/application/teeworlds/src
|
||||
url = https://github.com/pelya/teeworlds.git
|
||||
[submodule "project/jni/application/xserver/xserver"]
|
||||
path = project/jni/application/xserver/xserver
|
||||
url = https://github.com/pelya/xserver.git
|
||||
branch = xsdl-1.20
|
||||
update = merge
|
||||
[submodule "android-shmem"]
|
||||
path = project/jni/shmem
|
||||
url = https://github.com/pelya/android-shmem.git
|
||||
branch = master
|
||||
update = merge
|
||||
[submodule "project/jni/application/hid-pc-keyboard/src"]
|
||||
path = project/jni/application/hid-pc-keyboard/src
|
||||
url = https://github.com/pelya/android-keyboard-gadget.git
|
||||
branch = master
|
||||
update = merge
|
||||
[submodule "project/jni/iconv/src"]
|
||||
path = project/jni/iconv/src
|
||||
url = https://github.com/pelya/libiconv-libicu-android.git
|
||||
@@ -42,48 +7,6 @@
|
||||
path = project/jni/application/openttd/src
|
||||
url = https://github.com/n-ice-community/openttd-android.git
|
||||
branch = 12
|
||||
[submodule "project/jni/application/uae4all2"]
|
||||
path = project/jni/application/uae4all2
|
||||
url = https://github.com/lubomyr/uae4all2.git
|
||||
[submodule "project/jni/application/basiliskii/basiliskii"]
|
||||
path = project/jni/application/basiliskii/basiliskii
|
||||
url = https://github.com/pelya/BasiliskII-android.git
|
||||
[submodule "project/jni/vncserver/src"]
|
||||
path = project/jni/vncserver/src
|
||||
url = https://github.com/LibVNC/libvncserver.git
|
||||
[submodule "project/jni/application/vice/vice"]
|
||||
path = project/jni/application/vice/vice
|
||||
url = https://github.com/lubomyr/vice-2.4.git
|
||||
[submodule "project/jni/application/xserver/pulseaudio"]
|
||||
path = project/jni/application/xserver/pulseaudio
|
||||
url = https://github.com/pelya/pulseaudio-android.git
|
||||
branch = master
|
||||
[submodule "project/jni/application/supertux/supertux"]
|
||||
path = project/jni/application/supertux/supertux
|
||||
url = https://github.com/pelya/supertux.git
|
||||
[submodule "project/jni/application/fheroes2/fheroes2"]
|
||||
path = project/jni/application/fheroes2/fheroes2
|
||||
url = https://github.com/gerstrong/fheroes2plus.git
|
||||
[submodule "project/jni/application/ninslash/src"]
|
||||
path = project/jni/application/ninslash/src
|
||||
url = https://github.com/pelya/Ninslash.git
|
||||
branch = master
|
||||
update = merge
|
||||
[submodule "project/jni/application/openttd-jgrpp/src"]
|
||||
path = project/jni/application/openttd-jgrpp/src
|
||||
url = https://github.com/pelya/OpenTTD-JGR-patchpack.git
|
||||
branch = android-desktop
|
||||
[submodule "project/jni/application/liero/src"]
|
||||
path = project/jni/application/liero/src
|
||||
url = https://github.com/pelya/liero-android.git
|
||||
[submodule "project/jni/application/openlierox/src"]
|
||||
path = project/jni/application/openlierox/src
|
||||
url = https://github.com/albertz/openlierox.git
|
||||
branch = half-assed-android-port
|
||||
[submodule "project/jni/application/xserver-debian/debian-image"]
|
||||
path = project/jni/application/xserver-debian/debian-image
|
||||
url = https://github.com/pelya/debian-noroot
|
||||
branch = master
|
||||
[submodule "project/jni/sdl2"]
|
||||
path = project/jni/sdl2
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
|
||||
Submodule project/jni/application/NewRAW deleted from 65b7361c8e
@@ -1,34 +0,0 @@
|
||||
# The application settings for Android libSDL port
|
||||
AppSettingVersion=16
|
||||
LibSdlVersion=1.2
|
||||
AppName="REminiscence"
|
||||
AppFullName=fr.freecyxdown.sdl
|
||||
ScreenOrientation=h
|
||||
InhibitSuspend=n
|
||||
AppDataDownloadUrl="Data files size is 1 Mb|http://anddev.at.ua/data/reminiscence-data.zip?attredirects=0&d=1"
|
||||
SdlVideoResize=y
|
||||
SdlVideoResizeKeepAspect=n
|
||||
NeedDepthBuffer=n
|
||||
AppUsesMouse=n
|
||||
AppNeedsTwoButtonMouse=n
|
||||
AppNeedsArrowKeys=y
|
||||
AppNeedsTextInput=y
|
||||
AppUsesJoystick=n
|
||||
AppHandlesJoystickSensitivity=n
|
||||
AppUsesMultitouch=n
|
||||
NonBlockingSwapBuffers=n
|
||||
RedefinedKeys="RSHIFT RETURN BACKSPACE RETURN SPACE"
|
||||
AppTouchscreenKeyboardKeysAmount=3
|
||||
AppTouchscreenKeyboardKeysAmountAutoFire=0
|
||||
RedefinedKeysScreenKb="RSHIFT RETURN BACKSPACE RETURN SPACE"
|
||||
MultiABI=n
|
||||
AppVersionCode=01901
|
||||
AppVersionName="0.1.9"
|
||||
CompiledLibraries="jpeg png"
|
||||
CustomBuildScript=n
|
||||
AppCflags='-Dmain=SDL_main -DBYPASS_PROTECTION'
|
||||
AppLdflags=''
|
||||
AppSubdirsBuild=''
|
||||
AppUseCrystaXToolchain=n
|
||||
AppCmdline=''
|
||||
ReadmeText='^You may press "Home" now - the data will be downloaded in background'
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
LOCAL_PATH=`dirname $0`
|
||||
LOCAL_PATH=`cd $LOCAL_PATH && pwd`
|
||||
|
||||
# Hacks for broken configure scripts
|
||||
#rm -rf $LOCAL_PATH/../../obj/local/armeabi/libSDL_*.so
|
||||
#rm -rf $LOCAL_PATH/../../obj/local/armeabi/libsdl_main.so
|
||||
|
||||
# Uncomment if your configure expects SDL libraries in form "libSDL_name.so"
|
||||
#if [ -e $LOCAL_PATH/../../obj/local/armeabi/libsdl_mixer.so ] ; then
|
||||
# ln -sf libsdl_mixer.so $LOCAL_PATH/../../obj/local/armeabi/libSDL_Mixer.so
|
||||
#fi
|
||||
|
||||
#for F in $LOCAL_PATH/../../obj/local/armeabi/libsdl_*.so; do
|
||||
# LIBNAME=`echo $F | sed "s@$LOCAL_PATH/../../obj/local/armeabi/libsdl_\(.*\)[.]so@\1@"`
|
||||
# ln -sf libsdl_$LIBNAME.so $LOCAL_PATH/../../obj/local/armeabi/libSDL_$LIBNAME.so
|
||||
#done
|
||||
|
||||
../setEnvironment.sh make -C REminiscence-0.1.9 -j2 && cp -f REminiscence-0.1.9/rs libapplication.so
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,29 +0,0 @@
|
||||
|
||||
SDL_CFLAGS = `sdl-config --cflags` -Dmain=SDL_main -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/home/lubomyr/src/endless_space/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include -I/home/lubomyr/project/jni/sdl-1.2/include
|
||||
SDL_LIBS = `sdl-config --libs` -nostdlib -Wl,-soname,libapplication.so -Wl,-shared,-Bsymbolic -Wl,--whole-archive -Wl,--no-whole-archive /home/lubomyr/src/endless_space/android-ndk-r4-crystax/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /home/lubomyr/src/endless_space/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/lib/libc.a -L/home/lubomyr/project/obj/local/armeabi -lsdl-1.2 -lm -llog -lgcc -L/home/lubomyr/src/endless_space/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/lib
|
||||
|
||||
DEFINES = -DBYPASS_PROTECTION
|
||||
#DEFINES = -DBYPASS_PROTECTION -DNDEBUG
|
||||
|
||||
CXX = arm-eabi-g++
|
||||
CXXFLAGS:= -g -Wall -Wuninitialized -Wno-unknown-pragmas -Wshadow -Wimplicit
|
||||
CXXFLAGS+= -Wundef -Wreorder -Wwrite-strings -Wnon-virtual-dtor -Wno-multichar
|
||||
CXXFLAGS+= $(SDL_CFLAGS) $(DEFINES)
|
||||
|
||||
SRCS = collision.cpp cutscene.cpp file.cpp game.cpp graphics.cpp main.cpp menu.cpp \
|
||||
mixer.cpp mod_player.cpp piege.cpp resource.cpp scaler.cpp sfx_player.cpp \
|
||||
staticres.cpp systemstub_sdl.cpp unpack.cpp util.cpp video.cpp
|
||||
|
||||
OBJS = $(SRCS:.cpp=.o)
|
||||
DEPS = $(SRCS:.cpp=.d)
|
||||
|
||||
rs: $(OBJS)
|
||||
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(SDL_LIBS) -lz
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) -MMD -c $< -o $*.o
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d
|
||||
|
||||
-include $(DEPS)
|
||||
@@ -1,138 +0,0 @@
|
||||
|
||||
REminiscence README
|
||||
Release version: 0.1.9 (Mar 16 2007)
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
About:
|
||||
------
|
||||
|
||||
REminiscence is a re-implementation of the engine used in the game Flashback
|
||||
made by Delphine Software and released in 1992. More informations about the
|
||||
game can be found at [1], [2] and [3].
|
||||
|
||||
|
||||
Supported Versions:
|
||||
-------------------
|
||||
|
||||
Only the PC DOS versions are supported. The engine has been reported to work
|
||||
with english, french, german and spanish versions of the game.
|
||||
|
||||
|
||||
Compiling:
|
||||
----------
|
||||
|
||||
Tweak the Makefile if needed and type make (only gcc3 has been tested so far).
|
||||
The SDL and zlib libraries are required.
|
||||
|
||||
|
||||
Data Files:
|
||||
-----------
|
||||
|
||||
You will need the original files, here is the required list :
|
||||
|
||||
FB_TXT.FNT
|
||||
GLOBAL.ICN
|
||||
GLOBAL.FIB
|
||||
GLOBAL.SPC
|
||||
*.OFF
|
||||
*.SPR
|
||||
*.MAP
|
||||
*.PAL
|
||||
*.ANI
|
||||
*.CT
|
||||
*.MBK
|
||||
*.OBJ
|
||||
*.PGE
|
||||
*.RP
|
||||
*.TBN
|
||||
*.CMD
|
||||
*.POL
|
||||
*CINE.*
|
||||
|
||||
If you have a version distributed by SSI, you'll have to rename some files :
|
||||
|
||||
logosssi.cmd -> logos.cmd
|
||||
logosssi.pol -> logos.pol
|
||||
menu1ssi.map -> menu1.map
|
||||
menu1ssi.pal -> menu1.pal
|
||||
|
||||
In order to hear music, you'll need the original music files (.mod) of the
|
||||
amiga version. Copy them to the DATA directory and rename them like this :
|
||||
|
||||
mod.flashback-ascenseur
|
||||
mod.flashback-ceinturea
|
||||
mod.flashback-chute
|
||||
mod.flashback-desintegr
|
||||
mod.flashback-donneobjt
|
||||
mod.flashback-fin
|
||||
mod.flashback-fin2
|
||||
mod.flashback-game_over
|
||||
mod.flashback-holocube
|
||||
mod.flashback-introb
|
||||
mod.flashback-jungle
|
||||
mod.flashback-logo
|
||||
mod.flashback-memoire
|
||||
mod.flashback-missionca
|
||||
mod.flashback-options1
|
||||
mod.flashback-options2
|
||||
mod.flashback-reunion
|
||||
mod.flashback-taxi
|
||||
mod.flashback-teleport2
|
||||
mod.flashback-teleporta
|
||||
mod.flashback-voyage
|
||||
|
||||
|
||||
Running:
|
||||
--------
|
||||
|
||||
By default, the engine will try to load the game data files from the 'DATA'
|
||||
directory (as the original game did). The savestates are saved in the current
|
||||
directory. These paths can be changed using command line switches :
|
||||
|
||||
Usage: rs [OPTIONS]...
|
||||
--datapath=PATH Path to data files (default 'DATA')
|
||||
--savepath=PATH Path to save files (default '.')
|
||||
|
||||
In-game hotkeys :
|
||||
|
||||
Arrow Keys move Conrad
|
||||
Enter use the current inventory object
|
||||
Shift talk / use / run / shoot
|
||||
Escape display the options
|
||||
Backspace display the inventory
|
||||
Alt Enter toggle windowed/fullscreen mode
|
||||
Alt + and - change video scaler
|
||||
Ctrl S save game state
|
||||
Ctrl L load game state
|
||||
Ctrl + and - change game state slot
|
||||
Ctrl R toggle input keys record
|
||||
Ctrl P toggle input keys replay
|
||||
|
||||
Debug hotkeys :
|
||||
|
||||
Ctrl F toggle fast mode
|
||||
Ctrl I set Conrad life counter to 32767
|
||||
Ctrl B toggle display of updated dirty blocks
|
||||
Ctrl M mirror mode (just a hack, really)
|
||||
|
||||
|
||||
Credits:
|
||||
--------
|
||||
|
||||
Delphine Software, obviously, for making another great game.
|
||||
Yaz0r, Pixel and gawd for sharing information they gathered on the game.
|
||||
|
||||
|
||||
Contact:
|
||||
--------
|
||||
|
||||
Gregory Montoir, cyx@users.sourceforge.net
|
||||
|
||||
|
||||
URLs:
|
||||
-----
|
||||
|
||||
[1] http://www.mobygames.com/game/flashback-the-quest-for-identity
|
||||
[2] http://en.wikipedia.org/wiki/Flashback:_The_Quest_for_Identity
|
||||
[3] http://ramal.free.fr/fb_en.htm
|
||||
@@ -1,523 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
void Game::col_prepareRoomState() {
|
||||
memset(_col_activeCollisionSlots, 0xFF, sizeof(_col_activeCollisionSlots));
|
||||
_col_currentLeftRoom = _res._ctData[CT_LEFT_ROOM + _currentRoom];
|
||||
_col_currentRightRoom = _res._ctData[CT_RIGHT_ROOM + _currentRoom];
|
||||
for (int i = 0; i != _col_curPos; ++i) {
|
||||
CollisionSlot *_di = _col_slotsTable[i];
|
||||
uint8 room = _di->ct_pos / 64;
|
||||
if (room == _currentRoom) {
|
||||
_col_activeCollisionSlots[0x30 + (_di->ct_pos & 0x3F)] = i;
|
||||
} else if (room == _col_currentLeftRoom) {
|
||||
_col_activeCollisionSlots[0x00 + (_di->ct_pos & 0x3F)] = i;
|
||||
} else if (room == _col_currentRightRoom) {
|
||||
_col_activeCollisionSlots[0x60 + (_di->ct_pos & 0x3F)] = i;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_COLLISION
|
||||
printf("---\n");
|
||||
for (int y = 0; y < 7; ++y) {
|
||||
for (int x = 0; x < 16; ++x) {
|
||||
printf("%d", _res._ctData[0x100 + _currentRoom * 0x70 + y * 16 + x]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Game::col_clearState() {
|
||||
_col_curPos = 0;
|
||||
_col_curSlot = _col_slots;
|
||||
}
|
||||
|
||||
void Game::col_preparePiegeState(LivePGE *pge) {
|
||||
debug(DBG_COL, "Game::col_preparePiegeState() pge_num=%d", pge - &_pgeLive[0]);
|
||||
CollisionSlot *ct_slot1, *ct_slot2;
|
||||
if (pge->init_PGE->unk1C == 0) {
|
||||
pge->collision_slot = 0xFF;
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
ct_slot1 = 0;
|
||||
for (int c = 0; c < pge->init_PGE->unk1C; ++c) {
|
||||
ct_slot2 = _col_curSlot;
|
||||
if (ct_slot2 + 1 > &_col_slots[255])
|
||||
return;
|
||||
_col_curSlot = ct_slot2 + 1;
|
||||
int16 pos = col_getGridPos(pge, i);
|
||||
if (pos < 0) {
|
||||
if (ct_slot1 == 0) {
|
||||
pge->collision_slot = 0xFF;
|
||||
} else {
|
||||
ct_slot1->index = 0xFFFF;
|
||||
}
|
||||
return;
|
||||
}
|
||||
ct_slot2->ct_pos = pos;
|
||||
ct_slot2->live_pge = pge;
|
||||
ct_slot2->index = 0xFFFF;
|
||||
int16 _ax = col_findSlot(pos);
|
||||
if (_ax >= 0) {
|
||||
ct_slot2->prev_slot = _col_slotsTable[_ax];
|
||||
_col_slotsTable[_ax] = ct_slot2;
|
||||
if (ct_slot1 == 0) {
|
||||
pge->collision_slot = _ax;
|
||||
} else {
|
||||
ct_slot1->index = _ax;
|
||||
}
|
||||
LivePGE *temp_pge = ct_slot2->live_pge;
|
||||
if (temp_pge->flags & 0x80) {
|
||||
_pge_liveTable2[temp_pge->index] = temp_pge;
|
||||
temp_pge->flags |= 4;
|
||||
}
|
||||
if (ct_slot2->prev_slot) {
|
||||
temp_pge = ct_slot2->prev_slot->live_pge;
|
||||
if (temp_pge->flags & 0x80) {
|
||||
_pge_liveTable2[temp_pge->index] = temp_pge;
|
||||
temp_pge->flags |= 4;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ct_slot2->prev_slot = 0;
|
||||
_col_slotsTable[_col_curPos] = ct_slot2;
|
||||
if (ct_slot1 == 0) {
|
||||
pge->collision_slot = _col_curPos;
|
||||
} else {
|
||||
ct_slot1->index = _col_curPos;
|
||||
}
|
||||
_col_curPos++;
|
||||
}
|
||||
ct_slot1 = ct_slot2;
|
||||
i += 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 Game::col_getGridPos(LivePGE *pge, int16 dx) {
|
||||
int16 x = pge->pos_x + dx;
|
||||
int16 y = pge->pos_y;
|
||||
|
||||
int8 c = pge->room_location;
|
||||
if (c < 0) return 0xFFFF;
|
||||
|
||||
if (x < 0) {
|
||||
c = _res._ctData[CT_LEFT_ROOM + c];
|
||||
if (c < 0) return 0xFFFF;
|
||||
x += 256;
|
||||
} else if (x >= 256) {
|
||||
c = _res._ctData[CT_RIGHT_ROOM + c];
|
||||
if (c < 0) return 0xFFFF;
|
||||
x -= 256;
|
||||
} else if (y < 0) {
|
||||
c = _res._ctData[CT_UP_ROOM + c];
|
||||
if (c < 0) return 0xFFFF;
|
||||
y += 216;
|
||||
} else if (y >= 216) {
|
||||
c = _res._ctData[CT_DOWN_ROOM + c];
|
||||
if (c < 0) return 0xFFFF;
|
||||
y -= 216;
|
||||
}
|
||||
|
||||
x = (x + 8) >> 4;
|
||||
y = (y - 8) / 72;
|
||||
if (x < 0 || x > 15 || y < 0 || y > 2) {
|
||||
return 0xFFFF;
|
||||
} else {
|
||||
return y * 16 + x + c * 64;
|
||||
}
|
||||
}
|
||||
|
||||
int16 Game::col_findSlot(int16 pos) {
|
||||
for (uint16 i = 0; i < _col_curPos; ++i) {
|
||||
if (_col_slotsTable[i]->ct_pos == pos)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16 Game::col_getGridData(LivePGE *pge, int16 dy, int16 dx) {
|
||||
if (_pge_currentPiegeFacingDir) {
|
||||
dx = -dx;
|
||||
}
|
||||
const int16 pge_grid_y = _col_currentPiegeGridPosY + dy;
|
||||
const int16 pge_grid_x = _col_currentPiegeGridPosX + dx;
|
||||
const int8 *room_ct_data;
|
||||
int8 next_room;
|
||||
if (pge_grid_x < 0) {
|
||||
room_ct_data = &_res._ctData[CT_LEFT_ROOM];
|
||||
next_room = room_ct_data[pge->room_location];
|
||||
if (next_room < 0) return 1;
|
||||
room_ct_data += pge_grid_x + 16 + pge_grid_y * 16 + next_room * 0x70;
|
||||
return (int16)room_ct_data[0x40];
|
||||
} else if (pge_grid_x >= 16) {
|
||||
room_ct_data = &_res._ctData[CT_RIGHT_ROOM];
|
||||
next_room = room_ct_data[pge->room_location];
|
||||
if (next_room < 0) return 1;
|
||||
room_ct_data += pge_grid_x - 16 + pge_grid_y * 16 + next_room * 0x70;
|
||||
return (int16)room_ct_data[0x80];
|
||||
} else if (pge_grid_y < 1) {
|
||||
room_ct_data = &_res._ctData[CT_UP_ROOM];
|
||||
next_room = room_ct_data[pge->room_location];
|
||||
if (next_room < 0) return 1;
|
||||
room_ct_data += pge_grid_x + (pge_grid_y + 6) * 16 + next_room * 0x70;
|
||||
return (int16)room_ct_data[0x100];
|
||||
} else if (pge_grid_y >= 7) {
|
||||
room_ct_data = &_res._ctData[CT_DOWN_ROOM];
|
||||
next_room = room_ct_data[pge->room_location];
|
||||
if (next_room < 0) return 1;
|
||||
room_ct_data += pge_grid_x + (pge_grid_y - 6) * 16 + next_room * 0x70;
|
||||
return (int16)room_ct_data[0xC0];
|
||||
} else {
|
||||
room_ct_data = &_res._ctData[0x100];
|
||||
room_ct_data += pge_grid_x + pge_grid_y * 16 + pge->room_location * 0x70;
|
||||
return (int16)room_ct_data[0];
|
||||
}
|
||||
}
|
||||
|
||||
LivePGE *Game::col_findPiege(LivePGE *pge, uint16 arg2) {
|
||||
if (pge->collision_slot != 0xFF) {
|
||||
CollisionSlot *slot = _col_slotsTable[pge->collision_slot];
|
||||
while (slot) {
|
||||
if (slot->live_pge == pge) {
|
||||
slot = slot->prev_slot;
|
||||
} else {
|
||||
if (arg2 == 0xFFFF || arg2 == slot->live_pge->init_PGE->object_type) {
|
||||
return slot->live_pge;
|
||||
} else {
|
||||
slot = slot->prev_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 Game::col_findCurrentCollidingObject(LivePGE *pge, uint8 n1, uint8 n2, uint8 n3, LivePGE **pge_out) {
|
||||
if (pge_out) {
|
||||
*pge_out = pge;
|
||||
}
|
||||
if (pge->collision_slot != 0xFF) {
|
||||
CollisionSlot *cs = _col_slotsTable[pge->collision_slot];
|
||||
while (cs) {
|
||||
LivePGE *col_pge = cs->live_pge;
|
||||
if (pge_out) {
|
||||
*pge_out = col_pge;
|
||||
}
|
||||
if (col_pge->init_PGE->object_type == n1 ||
|
||||
col_pge->init_PGE->object_type == n2 ||
|
||||
col_pge->init_PGE->object_type == n3) {
|
||||
return col_pge->init_PGE->colliding_icon_num;
|
||||
} else {
|
||||
cs = cs->prev_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16 Game::col_detectHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC) {
|
||||
debug(DBG_COL, "col_detectHit()");
|
||||
int16 pos_dx, pos_dy, var8, varA;
|
||||
int16 collision_score = 0;
|
||||
int8 pge_room = pge->room_location;
|
||||
if (pge_room < 0 || pge_room >= 0x40) {
|
||||
return 0;
|
||||
}
|
||||
int16 thr = pge->init_PGE->counter_values[0];
|
||||
if (thr > 0) {
|
||||
pos_dx = -1;
|
||||
pos_dy = -1;
|
||||
} else {
|
||||
pos_dx = 1;
|
||||
pos_dy = 1;
|
||||
thr = -thr;
|
||||
}
|
||||
if (_pge_currentPiegeFacingDir) {
|
||||
pos_dx = -pos_dx;
|
||||
}
|
||||
int16 grid_pos_x = (pge->pos_x + 8) >> 4;
|
||||
int16 grid_pos_y = (pge->pos_y / 72);
|
||||
if (grid_pos_y >= 0 && grid_pos_y <= 2) {
|
||||
grid_pos_y *= 16;
|
||||
collision_score = 0;
|
||||
var8 = 0;
|
||||
varA = 0;
|
||||
if (argA != 0) {
|
||||
var8 = pos_dy;
|
||||
grid_pos_x += pos_dx;
|
||||
varA = 1;
|
||||
}
|
||||
while (varA <= thr) {
|
||||
if (grid_pos_x < 0) {
|
||||
pge_room = _res._ctData[CT_LEFT_ROOM + pge_room];
|
||||
if (pge_room < 0) break;
|
||||
grid_pos_x += 16;
|
||||
}
|
||||
if (grid_pos_x >= 16) {
|
||||
pge_room = _res._ctData[CT_RIGHT_ROOM + pge_room];
|
||||
if (pge_room < 0) break;
|
||||
grid_pos_x -= 16;
|
||||
}
|
||||
int16 slot = col_findSlot(grid_pos_y + grid_pos_x + pge_room * 64);
|
||||
if (slot >= 0) {
|
||||
CollisionSlot *cs = _col_slotsTable[slot];
|
||||
while (cs) {
|
||||
collision_score += (this->*callback1)(cs->live_pge, pge, arg2, arg4);
|
||||
cs = cs->prev_slot;
|
||||
}
|
||||
}
|
||||
if ((this->*callback2)(pge, var8, varA, arg2) != 0) {
|
||||
break;
|
||||
}
|
||||
grid_pos_x += pos_dx;
|
||||
++varA;
|
||||
var8 += pos_dy;
|
||||
}
|
||||
}
|
||||
if (argC == -1) {
|
||||
return collision_score;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallback1(LivePGE *pge, int16 dy, int16 unk1, int16 unk2) {
|
||||
if (col_getGridData(pge, 1, dy) != 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallback6(LivePGE *pge, int16 dy, int16 unk1, int16 unk2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2) {
|
||||
if (pge1 != pge2 && (pge1->flags & 4)) {
|
||||
if (pge1->init_PGE->object_type == unk2) {
|
||||
if ((pge1->flags & 1) == (pge2->flags & 1)) {
|
||||
if (col_detectHitCallbackHelper(pge1, unk1) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2) {
|
||||
if (pge1 != pge2 && (pge1->flags & 4)) {
|
||||
if (pge1->init_PGE->object_type == unk2) {
|
||||
if ((pge1->flags & 1) != (pge2->flags & 1)) {
|
||||
if (col_detectHitCallbackHelper(pge1, unk1) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallback4(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2) {
|
||||
if (pge1 != pge2 && (pge1->flags & 4)) {
|
||||
if (pge1->init_PGE->object_type == unk2) {
|
||||
if ((pge1->flags & 1) != (pge2->flags & 1)) {
|
||||
if (col_detectHitCallbackHelper(pge1, unk1) == 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, unk1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2) {
|
||||
if (pge1 != pge2 && (pge1->flags & 4)) {
|
||||
if (pge1->init_PGE->object_type == unk2) {
|
||||
if ((pge1->flags & 1) == (pge2->flags & 1)) {
|
||||
if (col_detectHitCallbackHelper(pge1, unk1) == 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, unk1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallbackHelper(LivePGE *pge, int16 groupId) {
|
||||
InitPGE *init_pge = pge->init_PGE;
|
||||
assert(init_pge->obj_node_number < _res._numObjectNodes);
|
||||
ObjectNode *on = _res._objectNodesMap[init_pge->obj_node_number];
|
||||
Object *obj = &on->objects[pge->first_obj_number];
|
||||
int i = pge->first_obj_number;
|
||||
while (pge->obj_type == obj->type && on->last_obj_number > i) {
|
||||
if (obj->opcode2 == 0x6B) { // pge_op_isInGroupSlice
|
||||
if (obj->opcode_arg2 == 0) {
|
||||
if (groupId == 1 || groupId == 2) return 0xFFFF;
|
||||
}
|
||||
if (obj->opcode_arg2 == 1) {
|
||||
if (groupId == 3 || groupId == 4) return 0xFFFF;
|
||||
}
|
||||
} else if (obj->opcode2 == 0x22) { // pge_op_isInGroup
|
||||
if (obj->opcode_arg2 == groupId) return 0xFFFF;
|
||||
}
|
||||
|
||||
if (obj->opcode1 == 0x6B) { // pge_op_isInGroupSlice
|
||||
if (obj->opcode_arg1 == 0) {
|
||||
if (groupId == 1 || groupId == 2) return 0xFFFF;
|
||||
}
|
||||
if (obj->opcode_arg1 == 1) {
|
||||
if (groupId == 3 || groupId == 4) return 0xFFFF;
|
||||
}
|
||||
} else if (obj->opcode1 == 0x22) { // pge_op_isInGroup
|
||||
if (obj->opcode_arg1 == groupId) return 0xFFFF;
|
||||
}
|
||||
++obj;
|
||||
++i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectGunHitCallback1(LivePGE *pge, int16 arg2, int16 arg4, int16 arg6) {
|
||||
int16 _ax = col_getGridData(pge, 1, arg2);
|
||||
if (_ax != 0) {
|
||||
if (!(_ax & 2) || (arg6 != 1)) {
|
||||
return _ax;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectGunHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16) {
|
||||
if (pge1 != pge2 && (pge1->flags & 4)) {
|
||||
if (pge1->init_PGE->object_type == 1 || pge1->init_PGE->object_type == 10) {
|
||||
uint8 id;
|
||||
if ((pge1->flags & 1) != (pge2->flags & 1)) {
|
||||
id = 4;
|
||||
if (arg4 == 0) {
|
||||
id = 3;
|
||||
}
|
||||
} else {
|
||||
id = 2;
|
||||
if (arg4 == 0) {
|
||||
id = 1;
|
||||
}
|
||||
}
|
||||
if (col_detectHitCallbackHelper(pge1, id) != 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, id);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectGunHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16) {
|
||||
if (pge1 != pge2 && (pge1->flags & 4)) {
|
||||
if (pge1->init_PGE->object_type == 1 || pge1->init_PGE->object_type == 12 || pge1->init_PGE->object_type == 10) {
|
||||
uint8 id;
|
||||
if ((pge1->flags & 1) != (pge2->flags & 1)) {
|
||||
id = 4;
|
||||
if (arg4 == 0) {
|
||||
id = 3;
|
||||
}
|
||||
} else {
|
||||
id = 2;
|
||||
if (arg4 == 0) {
|
||||
id = 1;
|
||||
}
|
||||
}
|
||||
if (col_detectHitCallbackHelper(pge1, id) != 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectGunHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC) {
|
||||
int8 pge_room = pge->room_location;
|
||||
if (pge_room < 0 || pge_room >= 0x40) return 0;
|
||||
int16 thr, pos_dx, pos_dy;
|
||||
if (argC == -1) {
|
||||
thr = pge->init_PGE->counter_values[0];
|
||||
} else {
|
||||
thr = pge->init_PGE->counter_values[3];
|
||||
}
|
||||
if (thr > 0) {
|
||||
pos_dx = -1;
|
||||
pos_dy = -1;
|
||||
} else {
|
||||
pos_dx = 1;
|
||||
pos_dy = 1;
|
||||
thr = -thr;
|
||||
}
|
||||
if (_pge_currentPiegeFacingDir) {
|
||||
pos_dx = -pos_dx;
|
||||
}
|
||||
int16 grid_pos_x = (pge->pos_x + 8) >> 4;
|
||||
int16 grid_pos_y = (pge->pos_y - 8) / 72;
|
||||
if (grid_pos_y >= 0 && grid_pos_y <= 2) {
|
||||
grid_pos_y *= 16;
|
||||
int16 var8 = 0;
|
||||
int16 varA = 0;
|
||||
if (argA != 0) {
|
||||
var8 = pos_dy;
|
||||
grid_pos_x += pos_dx;
|
||||
varA = 1;
|
||||
}
|
||||
while (varA <= thr) {
|
||||
if (grid_pos_x < 0) {
|
||||
pge_room = _res._ctData[CT_LEFT_ROOM + pge_room];
|
||||
if (pge_room < 0) return 0;
|
||||
grid_pos_x += 0x10;
|
||||
}
|
||||
if (grid_pos_x >= 0x10) {
|
||||
pge_room = _res._ctData[CT_RIGHT_ROOM + pge_room];
|
||||
if (pge_room < 0) return 0;
|
||||
grid_pos_x -= 0x10;
|
||||
}
|
||||
int16 slot = col_findSlot(pge_room * 64 + grid_pos_x + grid_pos_y);
|
||||
if (slot >= 0) {
|
||||
CollisionSlot *cs = _col_slotsTable[slot];
|
||||
while (cs) {
|
||||
int r = (this->*callback1)(cs->live_pge, pge, arg2, arg4);
|
||||
if (r != 0) return r;
|
||||
cs = cs->prev_slot;
|
||||
}
|
||||
}
|
||||
if ((this->*callback2)(pge, var8, varA, arg2) != 0) {
|
||||
break;
|
||||
}
|
||||
grid_pos_x += pos_dx;
|
||||
++varA;
|
||||
var8 += pos_dy;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CUTSCENE_H__
|
||||
#define __CUTSCENE_H__
|
||||
|
||||
#include "intern.h"
|
||||
#include "graphics.h"
|
||||
|
||||
struct ModPlayer;
|
||||
struct Resource;
|
||||
struct SystemStub;
|
||||
struct Video;
|
||||
|
||||
struct Cutscene {
|
||||
typedef void (Cutscene::*OpcodeStub)();
|
||||
|
||||
enum {
|
||||
NUM_OPCODES = 15,
|
||||
TIMER_SLICE = 15
|
||||
};
|
||||
|
||||
static const OpcodeStub _opcodeTable[];
|
||||
static const char *_namesTable[];
|
||||
static const uint16 _offsetsTable[];
|
||||
static const uint16 _cosTable[];
|
||||
static const uint16 _sinTable[];
|
||||
static const uint8 _creditsData[];
|
||||
static const uint16 _creditsCutSeq[];
|
||||
static const uint8 _musicTable[];
|
||||
static const uint8 _protectionShapeData[];
|
||||
|
||||
Graphics _gfx;
|
||||
ModPlayer *_ply;
|
||||
Resource *_res;
|
||||
SystemStub *_stub;
|
||||
Video *_vid;
|
||||
Version _ver;
|
||||
|
||||
uint16 _id;
|
||||
uint16 _deathCutsceneId;
|
||||
bool _interrupted;
|
||||
bool _stop;
|
||||
uint8 *_polPtr;
|
||||
uint8 *_cmdPtr;
|
||||
uint8 *_cmdPtrBak;
|
||||
uint32 _tstamp;
|
||||
uint8 _frameDelay;
|
||||
bool _newPal;
|
||||
uint8 _palBuf[0x20 * 2];
|
||||
uint16 _startOffset;
|
||||
bool _creditsSequence;
|
||||
uint32 _rotData[4];
|
||||
uint8 _primitiveColor;
|
||||
uint8 _clearScreen;
|
||||
Point _vertices[0x80];
|
||||
bool _hasAlphaColor;
|
||||
uint8 _varText;
|
||||
uint8 _varKey;
|
||||
int16 _shape_ix;
|
||||
int16 _shape_iy;
|
||||
int16 _shape_ox;
|
||||
int16 _shape_oy;
|
||||
int16 _shape_cur_x;
|
||||
int16 _shape_cur_y;
|
||||
int16 _shape_prev_x;
|
||||
int16 _shape_prev_y;
|
||||
uint16 _shape_count;
|
||||
uint32 _shape_cur_x16;
|
||||
uint32 _shape_cur_y16;
|
||||
uint32 _shape_prev_x16;
|
||||
uint32 _shape_prev_y16;
|
||||
uint8 _textSep[0x14];
|
||||
uint8 _textBuf[500];
|
||||
const uint8 *_textCurPtr;
|
||||
uint8 *_textCurBuf;
|
||||
uint8 _textUnk2;
|
||||
uint8 _creditsTextPosX;
|
||||
uint8 _creditsTextPosY;
|
||||
int16 _creditsTextCounter;
|
||||
uint8 *_page0, *_page1, *_pageC;
|
||||
|
||||
Cutscene(ModPlayer *player, Resource *res, SystemStub *stub, Video *vid, Version ver);
|
||||
|
||||
void sync();
|
||||
void copyPalette(const uint8 *pal, uint16 num);
|
||||
void updatePalette();
|
||||
void setPalette();
|
||||
void initRotationData(uint16 a, uint16 b, uint16 c);
|
||||
uint16 findTextSeparators(const uint8 *p);
|
||||
void drawText(int16 x, int16 y, const uint8 *p, uint16 color, uint8 *page, uint8 n);
|
||||
void swapLayers();
|
||||
void drawCreditsText();
|
||||
void drawProtectionShape(uint8 shapeNum, int16 zoom);
|
||||
void drawShape(const uint8 *data, int16 x, int16 y);
|
||||
void drawShapeScale(const uint8 *data, int16 zoom, int16 b, int16 c, int16 d, int16 e, int16 f, int16 g);
|
||||
void drawShapeScaleRotate(const uint8 *data, int16 zoom, int16 b, int16 c, int16 d, int16 e, int16 f, int16 g);
|
||||
|
||||
void op_markCurPos();
|
||||
void op_refreshScreen();
|
||||
void op_waitForSync();
|
||||
void op_drawShape();
|
||||
void op_setPalette();
|
||||
void op_drawStringAtBottom();
|
||||
void op_nop();
|
||||
void op_skip3();
|
||||
void op_refreshAll();
|
||||
void op_drawShapeScale();
|
||||
void op_drawShapeScaleRotate();
|
||||
void op_drawCreditsText();
|
||||
void op_drawStringAtPos();
|
||||
void op_handleKeys();
|
||||
|
||||
uint8 fetchNextCmdByte();
|
||||
uint16 fetchNextCmdWord();
|
||||
void mainLoop(uint16 offset);
|
||||
void load(uint16 cutName);
|
||||
void prepare();
|
||||
void startCredits();
|
||||
void play();
|
||||
};
|
||||
|
||||
#endif // __CUTSCENE_H__
|
||||
@@ -1,222 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "zlib.h"
|
||||
#include "file.h"
|
||||
|
||||
|
||||
struct File_impl {
|
||||
bool _ioErr;
|
||||
File_impl() : _ioErr(false) {}
|
||||
virtual bool open(const char *path, const char *mode) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual uint32 size() = 0;
|
||||
virtual void seek(int32 off) = 0;
|
||||
virtual void read(void *ptr, uint32 len) = 0;
|
||||
virtual void write(void *ptr, uint32 len) = 0;
|
||||
};
|
||||
|
||||
struct stdFile : File_impl {
|
||||
FILE *_fp;
|
||||
stdFile() : _fp(0) {}
|
||||
bool open(const char *path, const char *mode) {
|
||||
_ioErr = false;
|
||||
_fp = fopen(path, mode);
|
||||
return (_fp != 0);
|
||||
}
|
||||
void close() {
|
||||
if (_fp) {
|
||||
fclose(_fp);
|
||||
_fp = 0;
|
||||
}
|
||||
}
|
||||
uint32 size() {
|
||||
uint32 sz = 0;
|
||||
if (_fp) {
|
||||
int pos = ftell(_fp);
|
||||
fseek(_fp, 0, SEEK_END);
|
||||
sz = ftell(_fp);
|
||||
fseek(_fp, pos, SEEK_SET);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
void seek(int32 off) {
|
||||
if (_fp) {
|
||||
fseek(_fp, off, SEEK_SET);
|
||||
}
|
||||
}
|
||||
void read(void *ptr, uint32 len) {
|
||||
if (_fp) {
|
||||
uint32 r = fread(ptr, 1, len, _fp);
|
||||
if (r != len) {
|
||||
_ioErr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
void write(void *ptr, uint32 len) {
|
||||
if (_fp) {
|
||||
uint32 r = fwrite(ptr, 1, len, _fp);
|
||||
if (r != len) {
|
||||
_ioErr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct zlibFile : File_impl {
|
||||
gzFile _fp;
|
||||
zlibFile() : _fp(0) {}
|
||||
bool open(const char *path, const char *mode) {
|
||||
_ioErr = false;
|
||||
_fp = gzopen(path, mode);
|
||||
return (_fp != 0);
|
||||
}
|
||||
void close() {
|
||||
if (_fp) {
|
||||
gzclose(_fp);
|
||||
_fp = 0;
|
||||
}
|
||||
}
|
||||
uint32 size() {
|
||||
uint32 sz = 0;
|
||||
if (_fp) {
|
||||
int pos = gztell(_fp);
|
||||
gzseek(_fp, 0, SEEK_END);
|
||||
sz = gztell(_fp);
|
||||
gzseek(_fp, pos, SEEK_SET);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
void seek(int32 off) {
|
||||
if (_fp) {
|
||||
gzseek(_fp, off, SEEK_SET);
|
||||
}
|
||||
}
|
||||
void read(void *ptr, uint32 len) {
|
||||
if (_fp) {
|
||||
uint32 r = gzread(_fp, ptr, len);
|
||||
if (r != len) {
|
||||
_ioErr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
void write(void *ptr, uint32 len) {
|
||||
if (_fp) {
|
||||
uint32 r = gzwrite(_fp, ptr, len);
|
||||
if (r != len) {
|
||||
_ioErr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
File::File(bool gzipped) {
|
||||
if (gzipped) {
|
||||
_impl = new zlibFile;
|
||||
} else {
|
||||
_impl = new stdFile;
|
||||
}
|
||||
}
|
||||
|
||||
File::~File() {
|
||||
_impl->close();
|
||||
delete _impl;
|
||||
}
|
||||
|
||||
bool File::open(const char *filename, const char *directory, const char *mode) {
|
||||
_impl->close();
|
||||
char buf[512];
|
||||
sprintf(buf, "%s/%s", directory, filename);
|
||||
char *p = buf + strlen(directory) + 1;
|
||||
string_lower(p);
|
||||
bool opened = _impl->open(buf, mode);
|
||||
if (!opened) { // let's try uppercase
|
||||
string_upper(p);
|
||||
opened = _impl->open(buf, mode);
|
||||
}
|
||||
return opened;
|
||||
}
|
||||
|
||||
void File::close() {
|
||||
_impl->close();
|
||||
}
|
||||
|
||||
bool File::ioErr() const {
|
||||
return _impl->_ioErr;
|
||||
}
|
||||
|
||||
uint32 File::size() {
|
||||
return _impl->size();
|
||||
}
|
||||
|
||||
void File::seek(int32 off) {
|
||||
_impl->seek(off);
|
||||
}
|
||||
|
||||
void File::read(void *ptr, uint32 len) {
|
||||
_impl->read(ptr, len);
|
||||
}
|
||||
|
||||
uint8 File::readByte() {
|
||||
uint8 b;
|
||||
read(&b, 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
uint16 File::readUint16LE() {
|
||||
uint8 lo = readByte();
|
||||
uint8 hi = readByte();
|
||||
return (hi << 8) | lo;
|
||||
}
|
||||
|
||||
uint32 File::readUint32LE() {
|
||||
uint16 lo = readUint16LE();
|
||||
uint16 hi = readUint16LE();
|
||||
return (hi << 16) | lo;
|
||||
}
|
||||
|
||||
uint16 File::readUint16BE() {
|
||||
uint8 hi = readByte();
|
||||
uint8 lo = readByte();
|
||||
return (hi << 8) | lo;
|
||||
}
|
||||
|
||||
uint32 File::readUint32BE() {
|
||||
uint16 hi = readUint16BE();
|
||||
uint16 lo = readUint16BE();
|
||||
return (hi << 16) | lo;
|
||||
}
|
||||
|
||||
void File::write(void *ptr, uint32 len) {
|
||||
_impl->write(ptr, len);
|
||||
}
|
||||
|
||||
void File::writeByte(uint8 b) {
|
||||
write(&b, 1);
|
||||
}
|
||||
|
||||
void File::writeUint16BE(uint16 n) {
|
||||
writeByte(n >> 8);
|
||||
writeByte(n & 0xFF);
|
||||
}
|
||||
|
||||
void File::writeUint32BE(uint32 n) {
|
||||
writeUint16BE(n >> 16);
|
||||
writeUint16BE(n & 0xFFFF);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __FILE_H__
|
||||
#define __FILE_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct File_impl;
|
||||
|
||||
struct File {
|
||||
File(bool gzipped = false);
|
||||
~File();
|
||||
|
||||
File_impl *_impl;
|
||||
|
||||
bool open(const char *filename, const char *directory, const char *mode);
|
||||
void close();
|
||||
bool ioErr() const;
|
||||
uint32 size();
|
||||
void seek(int32 off);
|
||||
void read(void *ptr, uint32 len);
|
||||
uint8 readByte();
|
||||
uint16 readUint16LE();
|
||||
uint32 readUint32LE();
|
||||
uint16 readUint16BE();
|
||||
uint32 readUint32BE();
|
||||
void write(void *ptr, uint32 size);
|
||||
void writeByte(uint8 b);
|
||||
void writeUint16BE(uint16 n);
|
||||
void writeUint32BE(uint32 n);
|
||||
};
|
||||
|
||||
#endif // __FILE_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,391 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GAME_H__
|
||||
#define __GAME_H__
|
||||
|
||||
#include "intern.h"
|
||||
#include "cutscene.h"
|
||||
#include "menu.h"
|
||||
#include "mixer.h"
|
||||
#include "mod_player.h"
|
||||
#include "resource.h"
|
||||
#include "sfx_player.h"
|
||||
#include "video.h"
|
||||
|
||||
struct File;
|
||||
struct SystemStub;
|
||||
|
||||
struct Game {
|
||||
typedef int (Game::*pge_OpcodeProc)(ObjectOpcodeArgs *args);
|
||||
typedef int (Game::*pge_ZOrderCallback)(LivePGE *, LivePGE *, uint8, uint8);
|
||||
typedef int (Game::*col_Callback1)(LivePGE *, LivePGE *, int16, int16);
|
||||
typedef int (Game::*col_Callback2)(LivePGE *, int16, int16, int16);
|
||||
|
||||
enum {
|
||||
CT_UP_ROOM = 0x00,
|
||||
CT_DOWN_ROOM = 0x40,
|
||||
CT_RIGHT_ROOM = 0x80,
|
||||
CT_LEFT_ROOM = 0xC0
|
||||
};
|
||||
|
||||
static const Level _gameLevels[];
|
||||
static const uint16 _scoreTable[];
|
||||
static const uint8 _monsterListLevel1[];
|
||||
static const uint8 _monsterListLevel2[];
|
||||
static const uint8 _monsterListLevel3[];
|
||||
static const uint8 _monsterListLevel4_1[];
|
||||
static const uint8 _monsterListLevel4_2[];
|
||||
static const uint8 _monsterListLevel5_1[];
|
||||
static const uint8 _monsterListLevel5_2[];
|
||||
static const uint8 *_monsterListLevels[];
|
||||
static const uint8 _monsterPals[4][32];
|
||||
static const char *_monsterNames[];
|
||||
static const pge_OpcodeProc _pge_opcodeTable[];
|
||||
static const uint8 _pge_modKeysTable[];
|
||||
static const uint8 _protectionCodeData[];
|
||||
static const uint8 _protectionPal[];
|
||||
|
||||
Cutscene _cut;
|
||||
Menu _menu;
|
||||
Mixer _mix;
|
||||
ModPlayer _modPly;
|
||||
Resource _res;
|
||||
SfxPlayer _sfxPly;
|
||||
Video _vid;
|
||||
SystemStub *_stub;
|
||||
const char *_savePath;
|
||||
|
||||
const uint8 *_stringsTable;
|
||||
const char **_textsTable;
|
||||
uint8 _currentLevel;
|
||||
uint8 _skillLevel;
|
||||
uint32 _score;
|
||||
uint8 _currentRoom;
|
||||
uint8 _currentIcon;
|
||||
bool _loadMap;
|
||||
uint8 _printLevelCodeCounter;
|
||||
uint32 _randSeed;
|
||||
uint16 _currentInventoryIconNum;
|
||||
uint16 _curMonsterFrame;
|
||||
uint16 _curMonsterNum;
|
||||
uint8 _blinkingConradCounter;
|
||||
uint16 _textToDisplay;
|
||||
bool _eraseBackground;
|
||||
AnimBufferState _animBuffer0State[41];
|
||||
AnimBufferState _animBuffer1State[6]; // Conrad
|
||||
AnimBufferState _animBuffer2State[42];
|
||||
AnimBufferState _animBuffer3State[12];
|
||||
AnimBuffers _animBuffers;
|
||||
uint8 _bankData[0x7000];
|
||||
uint8 *_firstBankData;
|
||||
uint8 *_lastBankData;
|
||||
BankSlot _bankSlots[49];
|
||||
BankSlot *_curBankSlot;
|
||||
const uint8 *_bankDataPtrs;
|
||||
uint16 _deathCutsceneCounter;
|
||||
bool _saveStateCompleted;
|
||||
|
||||
Game(SystemStub *, const char *dataPath, const char *savePath, Version ver);
|
||||
|
||||
void run();
|
||||
void resetGameState();
|
||||
void mainLoop();
|
||||
void updateTiming();
|
||||
void playCutscene(int id = -1);
|
||||
void loadLevelMap();
|
||||
void loadLevelData();
|
||||
void start();
|
||||
void drawIcon(uint8 iconNum, int16 x, int16 y, uint8 colMask);
|
||||
void drawCurrentInventoryItem();
|
||||
void printLevelCode();
|
||||
void showFinalScore();
|
||||
bool handleConfigPanel();
|
||||
bool handleContinueAbort();
|
||||
bool handleProtectionScreen();
|
||||
void printSaveStateCompleted();
|
||||
void drawLevelTexts();
|
||||
void drawStoryTexts();
|
||||
void prepareAnims();
|
||||
void prepareAnimsHelper(LivePGE *pge, int16 dx, int16 dy);
|
||||
void drawAnims();
|
||||
void drawAnimBuffer(uint8 stateNum, AnimBufferState *state);
|
||||
void drawObject(const uint8 *dataPtr, int16 x, int16 y, uint8 flags);
|
||||
void drawObjectFrame(const uint8 *dataPtr, int16 x, int16 y, uint8 flags);
|
||||
void decodeCharacterFrame(const uint8 *dataPtr, uint8 *dstPtr);
|
||||
void drawCharacter(const uint8 *dataPtr, int16 x, int16 y, uint8 a, uint8 b, uint8 flags);
|
||||
uint8 *loadBankData(uint16 MbkEntryNum);
|
||||
int loadMonsterSprites(LivePGE *pge);
|
||||
void playSound(uint8 sfxId, uint8 softVol);
|
||||
uint16 getRandomNumber();
|
||||
void changeLevel();
|
||||
uint16 getLineLength(const uint8 *str) const;
|
||||
void handleInventory();
|
||||
uint8 *findBankData(uint16 entryNum);
|
||||
|
||||
|
||||
// pieges
|
||||
bool _pge_playAnimSound;
|
||||
GroupPGE _pge_groups[256];
|
||||
GroupPGE *_pge_groupsTable[256];
|
||||
GroupPGE *_pge_nextFreeGroup;
|
||||
LivePGE *_pge_liveTable2[256]; // active pieges list (index = pge number)
|
||||
LivePGE *_pge_liveTable1[256]; // pieges list by room (index = room)
|
||||
LivePGE _pgeLive[256];
|
||||
uint8 _pge_currentPiegeRoom;
|
||||
bool _pge_currentPiegeFacingDir; // (false == left)
|
||||
bool _pge_processOBJ;
|
||||
uint8 _pge_inpKeysMask;
|
||||
uint16 _pge_opTempVar1;
|
||||
uint16 _pge_opTempVar2;
|
||||
uint16 _pge_compareVar1;
|
||||
uint16 _pge_compareVar2;
|
||||
|
||||
void pge_resetGroups();
|
||||
void pge_removeFromGroup(uint8 idx);
|
||||
int pge_isInGroup(LivePGE *pge_dst, uint16 group_id, uint16 counter);
|
||||
void pge_loadForCurrentLevel(uint16 idx);
|
||||
void pge_process(LivePGE *pge);
|
||||
void pge_setupNextAnimFrame(LivePGE *pge, GroupPGE *le);
|
||||
void pge_playAnimSound(LivePGE *pge, uint16 arg2);
|
||||
void pge_setupAnim(LivePGE *pge);
|
||||
int pge_execute(LivePGE *live_pge, InitPGE *init_pge, const Object *obj);
|
||||
void pge_prepare();
|
||||
void pge_setupDefaultAnim(LivePGE *pge);
|
||||
uint16 pge_processOBJ(LivePGE *pge);
|
||||
void pge_setupOtherPieges(LivePGE *pge, InitPGE *init_pge);
|
||||
void pge_addToCurrentRoomList(LivePGE *pge, uint8 room);
|
||||
void pge_getInput();
|
||||
int pge_op_isInpUp(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpBackward(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpDown(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpForward(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpUpMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpBackwardMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpDownMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpForwardMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpIdle(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpNoMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision0u(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision00(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision0d(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision1u(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision10(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision1d(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision2u(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision20(ObjectOpcodeArgs *args);
|
||||
int pge_op_getCollision2d(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide0u(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide00(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide0d(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide1u(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide10(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide1d(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide2u(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide20(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide2d(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides0o0d(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides2o2d(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides0o0u(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides2o2u(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides2u2o(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup0(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup1(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup2(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup3(ObjectOpcodeArgs *args);
|
||||
int pge_op_isPiegeDead(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides1u2o(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides1u1o(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides1o1u(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x2B(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x2C(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x2D(ObjectOpcodeArgs *args);
|
||||
int pge_op_nop(ObjectOpcodeArgs *args);
|
||||
int pge_op_pickupObject(ObjectOpcodeArgs *args);
|
||||
int pge_op_addItemToInventory(ObjectOpcodeArgs *args);
|
||||
int pge_op_copyPiege(ObjectOpcodeArgs *args);
|
||||
int pge_op_canUseCurrentInventoryItem(ObjectOpcodeArgs *args);
|
||||
int pge_op_removeItemFromInventory(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x34(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInpMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_setCollisionState1(ObjectOpcodeArgs *args);
|
||||
int pge_op_setCollisionState0(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup1(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup2(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup3(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup4(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x3C(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x3D(ObjectOpcodeArgs *args);
|
||||
int pge_op_setPiegeCounter(ObjectOpcodeArgs *args);
|
||||
int pge_op_decPiegeCounter(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x40(ObjectOpcodeArgs *args);
|
||||
int pge_op_wakeUpPiege(ObjectOpcodeArgs *args);
|
||||
int pge_op_removePiege(ObjectOpcodeArgs *args);
|
||||
int pge_op_removePiegeIfNotNear(ObjectOpcodeArgs *args);
|
||||
int pge_op_loadPiegeCounter(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x45(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x46(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x47(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x48(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x49(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x4A(ObjectOpcodeArgs *args);
|
||||
int pge_op_killPiege(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInCurrentRoom(ObjectOpcodeArgs *args);
|
||||
int pge_op_isNotInCurrentRoom(ObjectOpcodeArgs *args);
|
||||
int pge_op_scrollPosY(ObjectOpcodeArgs *args);
|
||||
int pge_op_playDefaultDeathCutscene(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x50(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x52(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x53(ObjectOpcodeArgs *args);
|
||||
int pge_op_isPiegeNear(ObjectOpcodeArgs *args);
|
||||
int pge_op_setLife(ObjectOpcodeArgs *args);
|
||||
int pge_op_incLife(ObjectOpcodeArgs *args);
|
||||
int pge_op_setPiegeDefaultAnim(ObjectOpcodeArgs *args);
|
||||
int pge_op_setLifeCounter(ObjectOpcodeArgs *args);
|
||||
int pge_op_decLifeCounter(ObjectOpcodeArgs *args);
|
||||
int pge_op_playCutscene(ObjectOpcodeArgs *args);
|
||||
int pge_op_isTempVar2Set(ObjectOpcodeArgs *args);
|
||||
int pge_op_playDeathCutscene(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x5D(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x5E(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x5F(ObjectOpcodeArgs *args);
|
||||
int pge_op_findAndCopyPiege(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInRandomRange(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x62(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x63(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x64(ObjectOpcodeArgs *args);
|
||||
int pge_op_addToCredits(ObjectOpcodeArgs *args);
|
||||
int pge_op_subFromCredits(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x67(ObjectOpcodeArgs *args);
|
||||
int pge_op_setCollisionState2(ObjectOpcodeArgs *args);
|
||||
int pge_op_saveState(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6A(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroupSlice(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6C(ObjectOpcodeArgs *args);
|
||||
int pge_op_isCollidingObject(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6E(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6F(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x70(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x71(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x72(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x73(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides4u(ObjectOpcodeArgs *args);
|
||||
int pge_op_doesNotCollide4u(ObjectOpcodeArgs *args);
|
||||
int pge_op_isBelowConrad(ObjectOpcodeArgs *args);
|
||||
int pge_op_isAboveConrad(ObjectOpcodeArgs *args);
|
||||
int pge_op_isNotFacingConrad(ObjectOpcodeArgs *args);
|
||||
int pge_op_isFacingConrad(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides2u1u(ObjectOpcodeArgs *args);
|
||||
int pge_op_displayText(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x7C(ObjectOpcodeArgs *args);
|
||||
int pge_op_playSound(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x7E(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x7F(ObjectOpcodeArgs *args);
|
||||
int pge_op_setPiegePosX(ObjectOpcodeArgs *args);
|
||||
int pge_op_setPiegePosModX(ObjectOpcodeArgs *args);
|
||||
int pge_op_changeRoom(ObjectOpcodeArgs *args);
|
||||
int pge_op_hasInventoryItem(ObjectOpcodeArgs *args);
|
||||
int pge_op_changeLevel(ObjectOpcodeArgs *args);
|
||||
int pge_op_shakeScreen(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x86(ObjectOpcodeArgs *args);
|
||||
int pge_op_playSoundGroup(ObjectOpcodeArgs *args);
|
||||
int pge_op_adjustPos(ObjectOpcodeArgs *args);
|
||||
int pge_op_setTempVar1(ObjectOpcodeArgs *args);
|
||||
int pge_op_isTempVar1Set(ObjectOpcodeArgs *args);
|
||||
int pge_setCurrentInventoryObject(LivePGE *pge);
|
||||
void pge_updateInventory(LivePGE *pge1, LivePGE *pge2);
|
||||
void pge_reorderInventory(LivePGE *pge);
|
||||
LivePGE *pge_getInventoryItemBefore(LivePGE *pge, LivePGE *last_pge);
|
||||
void pge_addToInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
|
||||
int pge_updateCollisionState(LivePGE *pge, int16 pge_dy, uint8 var8);
|
||||
int pge_ZOrder(LivePGE *pge, int16 num, pge_ZOrderCallback compare, uint16 unk);
|
||||
void pge_updateGroup(uint8 idx, uint8 unk1, int16 unk2);
|
||||
void pge_removeFromInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
|
||||
int pge_ZOrderByAnimY(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderByAnimYIfType(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderIfIndex(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderByIndex(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderByObj(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderIfDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderIfSameDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderIfTypeAndSameDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderIfTypeAndDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
int pge_ZOrderByNumber(LivePGE *pge1, LivePGE *pge2, uint8 comp, uint8 comp2);
|
||||
|
||||
|
||||
// collision
|
||||
CollisionSlot _col_slots[256];
|
||||
uint8 _col_curPos;
|
||||
CollisionSlot *_col_slotsTable[256];
|
||||
CollisionSlot *_col_curSlot;
|
||||
CollisionSlot2 _col_slots2[256];
|
||||
CollisionSlot2 *_col_slots2Cur;
|
||||
CollisionSlot2 *_col_slots2Next;
|
||||
uint8 _col_activeCollisionSlots[0x30 * 3]; // left, current, right
|
||||
uint8 _col_currentLeftRoom;
|
||||
uint8 _col_currentRightRoom;
|
||||
int16 _col_currentPiegeGridPosX;
|
||||
int16 _col_currentPiegeGridPosY;
|
||||
|
||||
void col_prepareRoomState();
|
||||
void col_clearState();
|
||||
LivePGE *col_findPiege(LivePGE *pge, uint16 arg2);
|
||||
int16 col_findSlot(int16 pos);
|
||||
void col_preparePiegeState(LivePGE *dst_pge);
|
||||
uint16 col_getGridPos(LivePGE *pge, int16 dx);
|
||||
int16 col_getGridData(LivePGE *pge, int16 dy, int16 dx);
|
||||
uint8 col_findCurrentCollidingObject(LivePGE *pge, uint8 n1, uint8 n2, uint8 n3, LivePGE **pge_out);
|
||||
int16 col_detectHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC);
|
||||
int col_detectHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
|
||||
int col_detectHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
|
||||
int col_detectHitCallback4(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
|
||||
int col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16 unk1, int16 unk2);
|
||||
int col_detectHitCallback1(LivePGE *pge, int16 dy, int16 unk1, int16 unk2);
|
||||
int col_detectHitCallback6(LivePGE *pge, int16 dy, int16 unk1, int16 unk2);
|
||||
int col_detectHitCallbackHelper(LivePGE *pge, int16 unk1);
|
||||
int col_detectGunHitCallback1(LivePGE *pge, int16 arg2, int16 arg4, int16 arg6);
|
||||
int col_detectGunHitCallback2(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16);
|
||||
int col_detectGunHitCallback3(LivePGE *pge1, LivePGE *pge2, int16 arg4, int16);
|
||||
int col_detectGunHit(LivePGE *pge, int16 arg2, int16 arg4, col_Callback1 callback1, col_Callback2 callback2, int16 argA, int16 argC);
|
||||
|
||||
|
||||
// input
|
||||
uint8 _inp_lastKeysHit;
|
||||
uint8 _inp_lastKeysHitLeftRight;
|
||||
bool _inp_replay;
|
||||
bool _inp_record;
|
||||
File *_inp_demo;
|
||||
|
||||
void inp_handleSpecialKeys();
|
||||
void inp_update();
|
||||
|
||||
|
||||
// save/load state
|
||||
uint8 _stateSlot;
|
||||
bool _validSaveState;
|
||||
|
||||
void makeGameDemoName(char *buf);
|
||||
void makeGameStateName(uint8 slot, char *buf);
|
||||
bool saveGameState(uint8 slot);
|
||||
bool loadGameState(uint8 slot);
|
||||
void saveState(File *f);
|
||||
void loadState(File *f);
|
||||
};
|
||||
|
||||
#endif // __GAME_H__
|
||||
@@ -1,718 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "graphics.h"
|
||||
|
||||
|
||||
void Graphics::setClippingRect(int16 rx, int16 ry, int16 rw, int16 rh) {
|
||||
debug(DBG_VIDEO, "Graphics::setClippingRect(%d, %d, %d, %d)", rx, ry, rw, rh);
|
||||
_crx = rx;
|
||||
_cry = ry;
|
||||
_crw = rw;
|
||||
_crh = rh;
|
||||
}
|
||||
|
||||
void Graphics::drawPoint(uint8 color, const Point *pt) {
|
||||
debug(DBG_VIDEO, "Graphics::drawPoint() col=0x%X x=%d, y=%d", color, pt->x, pt->y);
|
||||
if (pt->x >= 0 && pt->x < _crw && pt->y >= 0 && pt->y < _crh) {
|
||||
*(_layer + (pt->y + _cry) * 256 + pt->x + _crx) = color;
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::drawLine(uint8 color, const Point *pt1, const Point *pt2) {
|
||||
debug(DBG_VIDEO, "Graphics::drawLine()");
|
||||
int16 dxincr1 = 1;
|
||||
int16 dyincr1 = 1;
|
||||
int16 dx = pt2->x - pt1->x;
|
||||
if (dx < 0) {
|
||||
dxincr1 = -1;
|
||||
dx = -dx;
|
||||
}
|
||||
int16 dy = pt2->y - pt1->y;
|
||||
if (dy < 0) {
|
||||
dyincr1 = -1;
|
||||
dy = -dy;
|
||||
}
|
||||
int16 dxincr2, dyincr2, delta1, delta2;
|
||||
if (dx < dy) {
|
||||
dxincr2 = 0;
|
||||
dyincr2 = 1;
|
||||
delta1 = dx;
|
||||
delta2 = dy;
|
||||
if (dyincr1 < 0) {
|
||||
dyincr2 = -1;
|
||||
}
|
||||
} else {
|
||||
dxincr2 = 1;
|
||||
dyincr2 = 0;
|
||||
delta1 = dy;
|
||||
delta2 = dx;
|
||||
if (dxincr1 < 0) {
|
||||
dxincr2 = -1;
|
||||
}
|
||||
}
|
||||
Point pt;
|
||||
pt.x = pt1->x;
|
||||
pt.y = pt1->y;
|
||||
int16 octincr1 = delta1 * 2 - delta2 * 2;
|
||||
int16 octincr2 = delta1 * 2;
|
||||
int16 oct = delta1 * 2 - delta2;
|
||||
if (delta2 >= 0) {
|
||||
drawPoint(color, &pt);
|
||||
while (--delta2 >= 0) {
|
||||
if (oct >= 0) {
|
||||
pt.x += dxincr1;
|
||||
pt.y += dyincr1;
|
||||
oct += octincr1;
|
||||
} else {
|
||||
pt.x += dxincr2;
|
||||
pt.y += dyincr2;
|
||||
oct += octincr2;
|
||||
}
|
||||
drawPoint(color, &pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::addEllipseRadius(int16 y, int16 x1, int16 x2) {
|
||||
debug(DBG_VIDEO, "Graphics::addEllipseRadius()");
|
||||
if (y >= 0 && y <= _crh) {
|
||||
y = (y - _areaPoints[0]) * 2;
|
||||
if (x1 < 0) {
|
||||
x1 = 0;
|
||||
}
|
||||
if (x2 >= _crw) {
|
||||
x2 = _crw - 1;
|
||||
}
|
||||
_areaPoints[y + 1] = x1;
|
||||
_areaPoints[y + 2] = x2;
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::drawEllipse(uint8 color, bool hasAlpha, const Point *pt, int16 rx, int16 ry) {
|
||||
debug(DBG_VIDEO, "Graphics::drawEllipse()");
|
||||
bool flag = false;
|
||||
int16 y = pt->y - ry;
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
if (y < _crh) {
|
||||
if (pt->y + ry >= 0) {
|
||||
_areaPoints[0] = y;
|
||||
int32 dy = 0;
|
||||
int32 rxsq = rx * rx;
|
||||
int32 rxsq2 = rx * rx * 2;
|
||||
int32 rxsq4 = rx * rx * 4;
|
||||
int32 rysq = ry * ry;
|
||||
int32 rysq2 = ry * ry * 2;
|
||||
int32 rysq4 = ry * ry * 4;
|
||||
|
||||
int32 dx = 0;
|
||||
int32 b = rx * ((rysq2 & 0xFFFF) + (rysq2 >> 16));
|
||||
int32 a = 2 * b;
|
||||
|
||||
int32 ny1, ny2, nx1, nx2;
|
||||
ny1 = ny2 = rysq4 / 2 - a + rxsq;
|
||||
nx1 = nx2 = rxsq2 - b + rysq;
|
||||
|
||||
while (ny2 < 0) {
|
||||
int16 x2 = pt->x + rx;
|
||||
int16 x1 = pt->x - rx;
|
||||
int16 by = pt->y + dy;
|
||||
int16 ty = pt->y - dy;
|
||||
if (x1 != x2) {
|
||||
addEllipseRadius(by, x1, x2);
|
||||
if (ty < by) {
|
||||
addEllipseRadius(ty, x1, x2);
|
||||
}
|
||||
}
|
||||
dy += 1;
|
||||
dx += rxsq4;
|
||||
nx1 = dx;
|
||||
if (nx2 < 0) {
|
||||
nx2 += nx1 + rxsq2;
|
||||
ny2 += nx1;
|
||||
} else {
|
||||
--rx;
|
||||
a -= rysq4;
|
||||
ny1 = a;
|
||||
nx2 += nx1 + rxsq2 - ny1;
|
||||
ny2 += nx1 + rysq2 - ny1;
|
||||
}
|
||||
}
|
||||
|
||||
while (rx >= 0) {
|
||||
bool flag2 = false;
|
||||
int16 x2 = pt->x + rx;
|
||||
int16 x1 = pt->x - rx;
|
||||
int16 by = pt->y + dy;
|
||||
int16 ty = pt->y - dy;
|
||||
if (!flag && x1 != x2) {
|
||||
flag2 = true;
|
||||
addEllipseRadius(by, x1, x2);
|
||||
if (ty < by) {
|
||||
addEllipseRadius(ty, x1, x2);
|
||||
}
|
||||
}
|
||||
if (flag2) {
|
||||
flag = true;
|
||||
}
|
||||
--rx;
|
||||
a -= rysq4;
|
||||
nx1 = a;
|
||||
if (ny2 < 0) {
|
||||
++dy;
|
||||
flag = false;
|
||||
dx += rxsq4;
|
||||
ny2 += dx - nx1 + rysq2;
|
||||
ny1 = dx - nx1 + rysq2;
|
||||
} else {
|
||||
ny2 += rysq2 - nx1;
|
||||
ny1 = rysq2 - nx1;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
++dy;
|
||||
}
|
||||
|
||||
while (dy <= ry) {
|
||||
int16 ty = pt->y - dy;
|
||||
int16 by = pt->y + dy;
|
||||
if (ty < by) {
|
||||
addEllipseRadius(ty, pt->x, pt->x);
|
||||
}
|
||||
addEllipseRadius(by, pt->x, pt->x);
|
||||
++dy;
|
||||
}
|
||||
y = pt->y + ry + 1;
|
||||
if (y > _crh) {
|
||||
y = _crh;
|
||||
}
|
||||
y = (y - _areaPoints[0]) * 2;
|
||||
_areaPoints[y + 1] = -1;
|
||||
fillArea(color, hasAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::fillArea(uint8 color, bool hasAlpha) {
|
||||
debug(DBG_VIDEO, "Graphics::fillArea()");
|
||||
int16 *pts = _areaPoints;
|
||||
uint8 *dst = _layer + (_cry + *pts++) * 256 + _crx;
|
||||
int16 x1 = *pts++;
|
||||
if (x1 >= 0) {
|
||||
if (hasAlpha && color > 0xC7) {
|
||||
do {
|
||||
int16 x2 = *pts++;
|
||||
if (x2 < _crw && x2 >= x1) {
|
||||
int len = x2 - x1 + 1;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
*(dst + x1 + i) |= color & 8; // XXX 0x88
|
||||
}
|
||||
}
|
||||
dst += 256;
|
||||
x1 = *pts++;
|
||||
} while (x1 >= 0);
|
||||
} else {
|
||||
do {
|
||||
int16 x2 = *pts++;
|
||||
if (x2 < _crw && x2 >= x1) {
|
||||
int len = x2 - x1 + 1;
|
||||
memset(dst + x1, color, len);
|
||||
}
|
||||
dst += 256;
|
||||
x1 = *pts++;
|
||||
} while (x1 >= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::drawSegment(uint8 color, bool hasAlpha, int16 ys, const Point *pts, uint8 numPts) {
|
||||
debug(DBG_VIDEO, "Graphics::drawSegment()");
|
||||
int16 xmin, xmax, ymin, ymax;
|
||||
xmin = xmax = pts[0].x;
|
||||
ymin = ymax = pts[0].y;
|
||||
for (int i = 1; i < numPts; ++i) {
|
||||
int16 x = pts[i].x;
|
||||
int16 y = pts[i].y;
|
||||
if ((xmin << 16) + ymin > (x << 16) + y) {
|
||||
xmin = x;
|
||||
ymin = y;
|
||||
}
|
||||
if ((xmax << 16) + ymax < (x << 16) + y) {
|
||||
xmax = x;
|
||||
ymax = y;
|
||||
}
|
||||
}
|
||||
if (xmin < 0) {
|
||||
xmin = 0;
|
||||
}
|
||||
if (xmax >= _crw) {
|
||||
xmax = _crw - 1;
|
||||
}
|
||||
_areaPoints[0] = ys;
|
||||
_areaPoints[1] = xmin;
|
||||
_areaPoints[2] = xmax;
|
||||
_areaPoints[3] = -1;
|
||||
fillArea(color, hasAlpha);
|
||||
}
|
||||
|
||||
void Graphics::drawPolygonOutline(uint8 color, const Point *pts, uint8 numPts) {
|
||||
debug(DBG_VIDEO, "Graphics::drawPolygonOutline()");
|
||||
assert(numPts >= 2);
|
||||
int i;
|
||||
for (i = 0; i < numPts - 1; ++i) {
|
||||
drawLine(color, &pts[i], &pts[i + 1]);
|
||||
}
|
||||
drawLine(color, &pts[i], &pts[0]);
|
||||
}
|
||||
|
||||
static int32 calcPolyStep1(int16 dx, int16 dy) {
|
||||
debug(DBG_VIDEO, "Graphics::calcPolyStep1()");
|
||||
assert(dy != 0);
|
||||
int32 a = dx * 256;
|
||||
if ((a >> 16) < dy) {
|
||||
a = ((int16)(a / dy)) * 256;
|
||||
} else {
|
||||
a = ((a / 256) / dy) & 0xFFFF0000;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
static int32 calcPolyStep2(int16 dx, int16 dy) {
|
||||
debug(DBG_VIDEO, "Graphics::calcPolyStep2()");
|
||||
assert(dy != 0);
|
||||
int32 a = dx * 256;
|
||||
if ((a >> 16) < dy) {
|
||||
a = ((int16)(a / dy)) * 256;
|
||||
} else {
|
||||
a = ((a / 256) / dy) << 16;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
static void drawPolygonHelper1(int32 &x, int16 &y, int32 &step, int16 *&pts, int16 *&start) {
|
||||
bool first = true;
|
||||
x = pts[0];
|
||||
y = pts[1];
|
||||
int16 dy, dx;
|
||||
do {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
x = *pts;
|
||||
}
|
||||
--pts;
|
||||
dy = *pts - y;
|
||||
--pts;
|
||||
dx = *pts - x;
|
||||
} while (dy <= 0 && start < pts);
|
||||
x <<= 16;
|
||||
if (dy > 0) {
|
||||
step = calcPolyStep1(dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
static void drawPolygonHelper2(int32 &x, int16 &y, int32 &step, int16 *&pts, int16 *&start) {
|
||||
bool first = true;
|
||||
x = *start++;
|
||||
y = *start++;
|
||||
int16 dy, dx;
|
||||
do {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
x = *start;
|
||||
start += 2;
|
||||
}
|
||||
dy = start[1] - y;
|
||||
dx = start[0] - x;
|
||||
} while (dy <= 0 && start < pts);
|
||||
x <<= 16;
|
||||
if (dy > 0) {
|
||||
step = calcPolyStep2(dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::drawPolygon(uint8 color, bool hasAlpha, const Point *pts, uint8 numPts) {
|
||||
debug(DBG_VIDEO, "Graphics::drawPolygon()");
|
||||
assert(numPts * 4 < 0x100);
|
||||
|
||||
int16 *apts1 = &_areaPoints[0x100];
|
||||
int16 *apts2 = &_areaPoints[0x100 + numPts * 2];
|
||||
|
||||
int16 xmin, xmax, ymin, ymax;
|
||||
xmin = xmax = pts[0].x;
|
||||
ymin = ymax = pts[0].y;
|
||||
|
||||
int16 *spts = apts1;
|
||||
*apts1++ = *apts2++ = pts[0].x;
|
||||
*apts1++ = *apts2++ = pts[0].y;
|
||||
|
||||
for (int p = 1; p < numPts; ++p) {
|
||||
int16 x = pts[p].x;
|
||||
int16 y = pts[p].y;
|
||||
if (ymin > y) {
|
||||
ymin = y;
|
||||
spts = apts1;
|
||||
}
|
||||
if (ymax < y) {
|
||||
ymax = y;
|
||||
}
|
||||
*apts1++ = *apts2++ = x;
|
||||
*apts1++ = *apts2++ = y;
|
||||
|
||||
if (xmin > x) {
|
||||
xmin = x;
|
||||
}
|
||||
if (xmax < x) {
|
||||
xmax = x;
|
||||
}
|
||||
}
|
||||
int16 *rpts = _areaPoints;
|
||||
if (xmax < 0 || xmin >= _crw || ymax < 0 || ymin >= _crh) {
|
||||
return;
|
||||
}
|
||||
if (numPts == 2) {
|
||||
drawLine(color, &pts[0], &pts[1]);
|
||||
return;
|
||||
}
|
||||
if (ymax == ymin) {
|
||||
drawSegment(color, hasAlpha, ymax, pts, numPts);
|
||||
return;
|
||||
}
|
||||
int16 x, dx, y, dy;
|
||||
int32 a, b, d, f;
|
||||
int32 xstep1 = 0;
|
||||
int32 xstep2 = 0;
|
||||
|
||||
apts1 = &spts[numPts * 2];
|
||||
xmax = _crw - 1;
|
||||
ymax = _crh - 1;
|
||||
int32 l1 = 65536;
|
||||
int32 l2 = -65536;
|
||||
if (ymin < 0) {
|
||||
int16 x0, y0;
|
||||
do {
|
||||
--apts1;
|
||||
y0 = *apts1;
|
||||
--apts1;
|
||||
x0 = *apts1;
|
||||
} while (y0 < 0);
|
||||
x = apts1[2];
|
||||
y = apts1[3];
|
||||
dy = y0 - y;
|
||||
dx = x0 - x;
|
||||
xstep1 = (dy << 16) | dx;
|
||||
assert(dy != 0);
|
||||
a = y * dx / dy;
|
||||
b = (x - a) << 16;
|
||||
d = xstep1 = calcPolyStep1(dx, dy);
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
}
|
||||
if (d < l1) {
|
||||
d = l2;
|
||||
}
|
||||
d /= 2;
|
||||
b -= d;
|
||||
|
||||
do {
|
||||
x0 = *spts++;
|
||||
y0 = *spts++;
|
||||
} while (*(spts + 1) < 0);
|
||||
dy = spts[1] - y0;
|
||||
dx = spts[0] - x0;
|
||||
xstep2 = (dy << 16) | dx;
|
||||
assert(dy != 0);
|
||||
a = y0 * dx / dy;
|
||||
f = (x0 - a) << 16;
|
||||
d = xstep2 = calcPolyStep2(dx, dy);
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
}
|
||||
if (d < l1) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
f += d;
|
||||
ymin = 0;
|
||||
*rpts++ = 0;
|
||||
goto gfx_startLine;
|
||||
}
|
||||
|
||||
*rpts++ = ymin;
|
||||
|
||||
gfx_startNewLine:
|
||||
drawPolygonHelper2(f, ymin, xstep2, apts1, spts);
|
||||
if (spts >= apts1) {
|
||||
b = apts1[0] << 16;
|
||||
dy = apts1[1];
|
||||
if (dy <= ymax) goto gfx_endLine;
|
||||
goto gfx_fillArea;
|
||||
}
|
||||
drawPolygonHelper1(b, ymin, xstep1, apts1, spts);
|
||||
d = xstep1;
|
||||
if (d < 0) {
|
||||
if (d >= l2) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
b += d;
|
||||
}
|
||||
d = xstep2;
|
||||
if (d >= 0) {
|
||||
if (d <= l1) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
f += d;
|
||||
}
|
||||
d = b;
|
||||
if (d < 0) {
|
||||
d = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = d >> 16;
|
||||
*rpts++ = x;
|
||||
++ymin;
|
||||
d = xstep1;
|
||||
if (d >= 0) {
|
||||
if (d <= l1) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
}
|
||||
b += d;
|
||||
d = xstep2;
|
||||
if (d < 0) {
|
||||
if (d >= l2) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
}
|
||||
f += d;
|
||||
|
||||
gfx_startLine:
|
||||
while (1) {
|
||||
dy = apts1[1];
|
||||
if (spts >= apts1) {
|
||||
break;
|
||||
} else if (dy > spts[1]) {
|
||||
dy = spts[1];
|
||||
if (dy > ymax) {
|
||||
goto gfx_drawPolygonEnd;
|
||||
}
|
||||
dy -= ymin;
|
||||
if (dy > 0) {
|
||||
--dy;
|
||||
do {
|
||||
a = b;
|
||||
if (a < 0) {
|
||||
a = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = a >> 16;
|
||||
*rpts++ = x;
|
||||
b += xstep1;
|
||||
f += xstep2;
|
||||
--dy;
|
||||
} while (dy >= 0);
|
||||
}
|
||||
drawPolygonHelper2(f, ymin, xstep2, apts1, spts);
|
||||
d = xstep2;
|
||||
if (d >= 0) {
|
||||
if (d <= l1) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
f += d;
|
||||
} else {
|
||||
d = b;
|
||||
if (d < 0) {
|
||||
d = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = d >> 16;
|
||||
*rpts++ = x;
|
||||
++ymin;
|
||||
d = xstep2;
|
||||
if (d >= l2) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
f += d;
|
||||
b += xstep1;
|
||||
}
|
||||
} else if (dy == spts[1]) {
|
||||
if (dy > ymax) goto gfx_drawPolygonEnd;
|
||||
dy -= ymin;
|
||||
if (dy > 0) {
|
||||
--dy;
|
||||
do {
|
||||
a = b;
|
||||
if (a < 0) {
|
||||
a = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = a >> 16;
|
||||
*rpts++ = x;
|
||||
b += xstep1;
|
||||
f += xstep2;
|
||||
--dy;
|
||||
} while (dy >= 0);
|
||||
}
|
||||
goto gfx_startNewLine;
|
||||
} else if (dy > ymax) {
|
||||
goto gfx_drawPolygonEnd;
|
||||
} else {
|
||||
dy -= ymin;
|
||||
if (dy > 0) {
|
||||
--dy;
|
||||
do {
|
||||
a = b;
|
||||
if (a < 0) {
|
||||
a = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = a >> 16;
|
||||
*rpts++ = x;
|
||||
b += xstep1;
|
||||
f += xstep2;
|
||||
--dy;
|
||||
} while (dy >= 0);
|
||||
}
|
||||
drawPolygonHelper1(b, ymin, xstep1, apts1, spts);
|
||||
d = xstep1;
|
||||
if (d < 0) {
|
||||
if (d >= l2) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
b += d;
|
||||
} else {
|
||||
d = b;
|
||||
if (d < 0) {
|
||||
d = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = d >> 16;
|
||||
*rpts++ = x;
|
||||
++ymin;
|
||||
d = xstep1;
|
||||
if (d <= l1) {
|
||||
d = l1;
|
||||
}
|
||||
d /= 2;
|
||||
b += d;
|
||||
f += xstep2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dy > ymax) goto gfx_drawPolygonEnd;
|
||||
dy -= ymin;
|
||||
if (dy < 0) goto gfx_fillArea;
|
||||
if (dy > 0) {
|
||||
--dy;
|
||||
do {
|
||||
a = b;
|
||||
if (a < 0) {
|
||||
a = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = a >> 16;
|
||||
*rpts++ = x;
|
||||
b += xstep1;
|
||||
f += xstep2;
|
||||
--dy;
|
||||
} while (dy >= 0);
|
||||
}
|
||||
|
||||
b = f = (apts1[0] << 16) | apts1[1];
|
||||
|
||||
gfx_endLine:
|
||||
d = xstep1;
|
||||
if (d >= 0) {
|
||||
if (d >= l1) {
|
||||
d /= 2;
|
||||
b -= d;
|
||||
}
|
||||
}
|
||||
d = xstep2;
|
||||
if (d < 0) {
|
||||
d /= 2;
|
||||
f -= d;
|
||||
}
|
||||
a = b;
|
||||
if (a < 0) {
|
||||
a = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = a >> 16;
|
||||
*rpts++ = x;
|
||||
goto gfx_fillArea;
|
||||
|
||||
gfx_drawPolygonEnd:
|
||||
dy = ymax - ymin;
|
||||
if (dy >= 0) {
|
||||
do {
|
||||
a = b;
|
||||
if (a < 0) {
|
||||
a = 0;
|
||||
}
|
||||
x = f >> 16;
|
||||
if (x > xmax) {
|
||||
x = xmax;
|
||||
}
|
||||
*rpts++ = a >> 16;
|
||||
*rpts++ = x;
|
||||
b += xstep1;
|
||||
f += xstep2;
|
||||
--dy;
|
||||
} while (dy >= 0);
|
||||
}
|
||||
|
||||
gfx_fillArea:
|
||||
*rpts++ = -1;
|
||||
fillArea(color, hasAlpha);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GRAPHICS_H__
|
||||
#define __GRAPHICS_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct Graphics {
|
||||
uint8 *_layer;
|
||||
int16 _areaPoints[0x200];
|
||||
int16 _crx, _cry, _crw, _crh;
|
||||
|
||||
void setClippingRect(int16 vx, int16 vy, int16 vw, int16 vh);
|
||||
void drawPoint(uint8 color, const Point *pt);
|
||||
void drawLine(uint8 color, const Point *pt1, const Point *pt2);
|
||||
void addEllipseRadius(int16 y, int16 x1, int16 x2);
|
||||
void drawEllipse(uint8 color, bool hasAlpha, const Point *pt, int16 rx, int16 ry);
|
||||
void fillArea(uint8 color, bool hasAlpha);
|
||||
void drawSegment(uint8 color, bool hasAlpha, int16 ys, const Point *pts, uint8 numPts);
|
||||
void drawPolygonOutline(uint8 color, const Point *pts, uint8 numPts);
|
||||
void drawPolygon(uint8 color, bool hasAlpha, const Point *pts, uint8 numPts);
|
||||
};
|
||||
|
||||
#endif // __GRAPHICS_H__
|
||||
@@ -1,193 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __INTERN_H__
|
||||
#define __INTERN_H__
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include "sys.h"
|
||||
#include "util.h"
|
||||
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline void SWAP(T &a, T &b) {
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
enum Version {
|
||||
VER_FR,
|
||||
VER_EN,
|
||||
VER_DE,
|
||||
VER_SP
|
||||
};
|
||||
|
||||
struct Color {
|
||||
uint8 r;
|
||||
uint8 g;
|
||||
uint8 b;
|
||||
};
|
||||
|
||||
struct Point {
|
||||
int16 x;
|
||||
int16 y;
|
||||
};
|
||||
|
||||
struct Level {
|
||||
const char *name;
|
||||
const char *name2;
|
||||
uint16 cutscene_id;
|
||||
};
|
||||
|
||||
struct InitPGE {
|
||||
uint16 type;
|
||||
int16 pos_x;
|
||||
int16 pos_y;
|
||||
uint16 obj_node_number;
|
||||
uint16 life;
|
||||
int16 counter_values[4];
|
||||
uint8 object_type;
|
||||
uint8 init_room;
|
||||
uint8 room_location;
|
||||
uint8 init_flags;
|
||||
uint8 colliding_icon_num;
|
||||
uint8 icon_num;
|
||||
uint8 object_id;
|
||||
uint8 skill;
|
||||
uint8 mirror_x;
|
||||
uint8 flags;
|
||||
uint8 unk1C; // collidable, collision_data_len
|
||||
uint8 text_num;
|
||||
};
|
||||
|
||||
struct LivePGE {
|
||||
uint16 obj_type;
|
||||
int16 pos_x;
|
||||
int16 pos_y;
|
||||
uint8 anim_seq;
|
||||
uint8 room_location;
|
||||
int16 life;
|
||||
int16 counter_value;
|
||||
uint8 collision_slot;
|
||||
uint8 next_inventory_PGE;
|
||||
uint8 current_inventory_PGE;
|
||||
uint8 unkF; // unk_inventory_PGE
|
||||
uint16 anim_number;
|
||||
uint8 flags;
|
||||
uint8 index;
|
||||
uint16 first_obj_number;
|
||||
LivePGE *next_PGE_in_room;
|
||||
InitPGE *init_PGE;
|
||||
};
|
||||
|
||||
struct GroupPGE {
|
||||
GroupPGE *next_entry;
|
||||
uint16 index;
|
||||
uint16 group_id;
|
||||
};
|
||||
|
||||
struct Object {
|
||||
uint16 type;
|
||||
int8 dx;
|
||||
int8 dy;
|
||||
uint16 init_obj_type;
|
||||
uint8 opcode2;
|
||||
uint8 opcode1;
|
||||
uint8 flags;
|
||||
uint8 opcode3;
|
||||
uint16 init_obj_number;
|
||||
int16 opcode_arg1;
|
||||
int16 opcode_arg2;
|
||||
int16 opcode_arg3;
|
||||
};
|
||||
|
||||
struct ObjectNode {
|
||||
uint16 last_obj_number;
|
||||
Object *objects;
|
||||
uint16 num_objects;
|
||||
};
|
||||
|
||||
struct ObjectOpcodeArgs {
|
||||
LivePGE *pge; // arg0
|
||||
int16 a; // arg2
|
||||
int16 b; // arg4
|
||||
};
|
||||
|
||||
struct AnimBufferState {
|
||||
int16 x;
|
||||
int16 y;
|
||||
const uint8 *dataPtr;
|
||||
LivePGE *pge;
|
||||
};
|
||||
|
||||
struct AnimBuffers {
|
||||
AnimBufferState *_states[4];
|
||||
uint8 _curPos[4];
|
||||
|
||||
void addState(uint8 stateNum, int16 x, int16 y, const uint8 *dataPtr, LivePGE *pge);
|
||||
};
|
||||
|
||||
struct CollisionSlot {
|
||||
int16 ct_pos;
|
||||
CollisionSlot *prev_slot;
|
||||
LivePGE *live_pge;
|
||||
uint16 index;
|
||||
};
|
||||
|
||||
struct MbkEntry {
|
||||
uint16 offset;
|
||||
uint16 len;
|
||||
};
|
||||
|
||||
struct BankSlot {
|
||||
uint16 entryNum;
|
||||
uint8 *ptr;
|
||||
};
|
||||
|
||||
struct CollisionSlot2 {
|
||||
CollisionSlot2 *next_slot;
|
||||
int8 *unk2;
|
||||
uint8 data_size;
|
||||
uint8 data_buf[0x10]; // XXX check size
|
||||
};
|
||||
|
||||
struct InventoryItem {
|
||||
uint8 icon_num;
|
||||
InitPGE *init_pge;
|
||||
LivePGE *live_pge;
|
||||
};
|
||||
|
||||
struct SoundFx {
|
||||
uint32 offset;
|
||||
uint16 len;
|
||||
uint8 *data;
|
||||
};
|
||||
|
||||
#endif // __INTERN_H__
|
||||
@@ -1,50 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2006 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "locale.h"
|
||||
|
||||
|
||||
Locale::Locale(Version ver)
|
||||
: _ver(ver) {
|
||||
switch (_ver) {
|
||||
case VER_FR:
|
||||
_stringsTable = _stringsTableFR;
|
||||
_textsTable = _textsTableFR;
|
||||
break;
|
||||
case VER_EN:
|
||||
_stringsTable = _stringsTableEN;
|
||||
_textsTable = _textsTableEN;
|
||||
break;
|
||||
case VER_DE:
|
||||
_stringsTable = _stringsTableDE;
|
||||
_textsTable = _textsTableDE;
|
||||
break;
|
||||
case VER_SP:
|
||||
_stringsTable = _stringsTableSP;
|
||||
_textsTable = _textsTableSP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Locale::get(int id) const {
|
||||
const char *text = 0;
|
||||
if (id >= 0 && id < LI_NUM) {
|
||||
text = _textsTable[id];
|
||||
}
|
||||
return text;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2006 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __LOCALE_H__
|
||||
#define __LOCALE_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct Locale {
|
||||
enum Id {
|
||||
LI_01_CONTINUE_OR_ABORT = 0,
|
||||
LI_02_TIME,
|
||||
LI_03_CONTINUE,
|
||||
LI_04_ABORT,
|
||||
LI_05_COMPLETED,
|
||||
LI_06_LEVEL,
|
||||
LI_07_START,
|
||||
LI_08_SKILL,
|
||||
LI_09_PASSWORD,
|
||||
LI_10_INFO,
|
||||
LI_11_QUIT,
|
||||
LI_12_SKILL_LEVEL,
|
||||
LI_13_EASY,
|
||||
LI_14_NORMAL,
|
||||
LI_15_EXPERT,
|
||||
LI_16_ENTER_PASSWORD1,
|
||||
LI_17_ENTER_PASSWORD2,
|
||||
LI_18_RESUME_GAME,
|
||||
LI_19_ABORT_GAME,
|
||||
LI_20_LOAD_GAME,
|
||||
LI_21_SAVE_GAME,
|
||||
LI_22_SAVE_SLOT,
|
||||
|
||||
LI_NUM
|
||||
};
|
||||
|
||||
static const char *_textsTableFR[];
|
||||
static const char *_textsTableEN[];
|
||||
static const char *_textsTableDE[];
|
||||
static const char *_textsTableSP[];
|
||||
static const uint8 _stringsTableFR[];
|
||||
static const uint8 _stringsTableEN[];
|
||||
static const uint8 _stringsTableDE[];
|
||||
static const uint8 _stringsTableSP[];
|
||||
|
||||
Version _ver;
|
||||
const char **_textsTable;
|
||||
const uint8 *_stringsTable;
|
||||
|
||||
Locale(Version ver);
|
||||
const char *get(int id) const;
|
||||
};
|
||||
|
||||
#endif // __LOCALE_H__
|
||||
@@ -1,85 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
#include "game.h"
|
||||
#include "systemstub.h"
|
||||
|
||||
static const char *USAGE =
|
||||
"REminiscence - Flashback Interpreter\n"
|
||||
"Usage: rs [OPTIONS]...\n"
|
||||
" --datapath=PATH Path to data files (default 'DATA')\n"
|
||||
" --savepath=PATH Path to save files (default '.')";
|
||||
|
||||
static bool parseOption(const char *arg, const char *longCmd, const char **opt) {
|
||||
bool handled = false;
|
||||
if (arg[0] == '-' && arg[1] == '-') {
|
||||
if (strncmp(arg + 2, longCmd, strlen(longCmd)) == 0) {
|
||||
*opt = arg + 2 + strlen(longCmd);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
static Version detectVersion(const char *dataPath) {
|
||||
static struct {
|
||||
const char *filename;
|
||||
Version ver;
|
||||
} checkTable[] = {
|
||||
{ "ENGCINE.BIN", VER_EN },
|
||||
{ "FR_CINE.BIN", VER_FR },
|
||||
{ "GERCINE.BIN", VER_DE },
|
||||
{ "SPACINE.BIN", VER_SP }
|
||||
};
|
||||
for (uint8 i = 0; i < ARRAYSIZE(checkTable); ++i) {
|
||||
File f;
|
||||
if (f.open(checkTable[i].filename, dataPath, "rb")) {
|
||||
return checkTable[i].ver;
|
||||
}
|
||||
}
|
||||
error("Unable to find data files, check that all required files are present");
|
||||
return VER_EN;
|
||||
}
|
||||
|
||||
#undef main
|
||||
|
||||
#include <SDL.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *dataPath = "DATA";
|
||||
const char *savePath = ".";
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
bool opt = false;
|
||||
if (strlen(argv[i]) >= 2) {
|
||||
opt |= parseOption(argv[i], "datapath=", &dataPath);
|
||||
opt |= parseOption(argv[i], "savepath=", &savePath);
|
||||
}
|
||||
if (!opt) {
|
||||
printf(USAGE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Version ver = detectVersion(dataPath);
|
||||
g_debugMask = DBG_INFO; // DBG_CUT | DBG_VIDEO | DBG_RES | DBG_MENU | DBG_PGE | DBG_GAME | DBG_UNPACK | DBG_COL | DBG_MOD | DBG_SFX;
|
||||
SystemStub *stub = SystemStub_SDL_create();
|
||||
Game *g = new Game(stub, dataPath, savePath, ver);
|
||||
g->run();
|
||||
delete g;
|
||||
delete stub;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
#include "mod_player.h"
|
||||
#include "resource.h"
|
||||
#include "systemstub.h"
|
||||
#include "video.h"
|
||||
#include "menu.h"
|
||||
|
||||
|
||||
Menu::Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid)
|
||||
: _ply(ply), _res(res), _stub(stub), _vid(vid) {
|
||||
}
|
||||
|
||||
void Menu::drawString(const char *str, int16 y, int16 x, uint8 color) {
|
||||
debug(DBG_MENU, "Menu::drawString()");
|
||||
uint8 v1b = _vid->_charFrontColor;
|
||||
uint8 v2b = _vid->_charTransparentColor;
|
||||
uint8 v3b = _vid->_charShadowColor;
|
||||
switch (color) {
|
||||
case 0:
|
||||
_vid->_charFrontColor = _charVar1;
|
||||
_vid->_charTransparentColor = _charVar2;
|
||||
_vid->_charShadowColor = _charVar2;
|
||||
break;
|
||||
case 1:
|
||||
_vid->_charFrontColor = _charVar2;
|
||||
_vid->_charTransparentColor = _charVar1;
|
||||
_vid->_charShadowColor = _charVar1;
|
||||
break;
|
||||
case 2:
|
||||
_vid->_charFrontColor = _charVar3;
|
||||
_vid->_charTransparentColor = 0xFF;
|
||||
_vid->_charShadowColor = _charVar1;
|
||||
break;
|
||||
case 3:
|
||||
_vid->_charFrontColor = _charVar4;
|
||||
_vid->_charTransparentColor = 0xFF;
|
||||
_vid->_charShadowColor = _charVar1;
|
||||
break;
|
||||
case 4:
|
||||
_vid->_charFrontColor = _charVar2;
|
||||
_vid->_charTransparentColor = 0xFF;
|
||||
_vid->_charShadowColor = _charVar1;
|
||||
break;
|
||||
case 5:
|
||||
_vid->_charFrontColor = _charVar2;
|
||||
_vid->_charTransparentColor = 0xFF;
|
||||
_vid->_charShadowColor = _charVar5;
|
||||
break;
|
||||
}
|
||||
|
||||
drawString2(str, y, x);
|
||||
|
||||
_vid->_charFrontColor = v1b;
|
||||
_vid->_charTransparentColor = v2b;
|
||||
_vid->_charShadowColor = v3b;
|
||||
}
|
||||
|
||||
void Menu::drawString2(const char *str, int16 y, int16 x) {
|
||||
debug(DBG_MENU, "Menu::drawString2()");
|
||||
int len = 0;
|
||||
while (*str) {
|
||||
_vid->drawChar((uint8)*str, y, x + len);
|
||||
++str;
|
||||
++len;
|
||||
}
|
||||
_vid->markBlockAsDirty(x * 8, y * 8, len * 8, 8);
|
||||
}
|
||||
|
||||
void Menu::loadPicture(const char *prefix) {
|
||||
debug(DBG_MENU, "Menu::loadPicture('%s')", prefix);
|
||||
_res->load_MAP_menu(prefix, _res->_memBuf);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int y = 0; y < 224; ++y) {
|
||||
for (int x = 0; x < 64; ++x) {
|
||||
_vid->_frontLayer[i + x * 4 + 256 * y] = _res->_memBuf[0x3800 * i + x + 64 * y];
|
||||
}
|
||||
}
|
||||
}
|
||||
_res->load_PAL_menu(prefix, _res->_memBuf);
|
||||
_stub->setPalette(_res->_memBuf, 256);
|
||||
}
|
||||
|
||||
void Menu::handleInfoScreen() {
|
||||
debug(DBG_MENU, "Menu::handleInfoScreen()");
|
||||
_vid->fadeOut();
|
||||
switch (_res->_ver) {
|
||||
case VER_FR:
|
||||
loadPicture("instru_f");
|
||||
break;
|
||||
case VER_EN:
|
||||
case VER_DE:
|
||||
case VER_SP:
|
||||
loadPicture("instru_e");
|
||||
break;
|
||||
}
|
||||
_vid->fullRefresh();
|
||||
_vid->updateScreen();
|
||||
do {
|
||||
_stub->sleep(EVENTS_DELAY);
|
||||
_stub->processEvents();
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
break;
|
||||
}
|
||||
} while (!_stub->_pi.quit);
|
||||
}
|
||||
|
||||
void Menu::handleSkillScreen(uint8 &new_skill) {
|
||||
debug(DBG_MENU, "Menu::handleSkillScreen()");
|
||||
static const uint8 option_colors[3][3] = { { 2, 3, 3 }, { 3, 2, 3}, { 3, 3, 2 } };
|
||||
_vid->fadeOut();
|
||||
loadPicture("menu3");
|
||||
_vid->fullRefresh();
|
||||
drawString(_res->getMenuString(LocaleData::LI_12_SKILL_LEVEL), 12, 4, 3);
|
||||
int skill_level = new_skill;
|
||||
do {
|
||||
drawString(_res->getMenuString(LocaleData::LI_13_EASY), 15, 14, option_colors[skill_level][0]);
|
||||
drawString(_res->getMenuString(LocaleData::LI_14_NORMAL), 17, 14, option_colors[skill_level][1]);
|
||||
drawString(_res->getMenuString(LocaleData::LI_15_EXPERT), 19, 14, option_colors[skill_level][2]);
|
||||
|
||||
_vid->updateScreen();
|
||||
_stub->sleep(EVENTS_DELAY);
|
||||
_stub->processEvents();
|
||||
|
||||
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
|
||||
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
|
||||
if (skill_level != 0) {
|
||||
--skill_level;
|
||||
} else {
|
||||
skill_level = 2;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
|
||||
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
|
||||
if (skill_level != 2) {
|
||||
++skill_level;
|
||||
} else {
|
||||
skill_level = 0;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
new_skill = skill_level;
|
||||
return;
|
||||
}
|
||||
} while (!_stub->_pi.quit);
|
||||
new_skill = 1;
|
||||
}
|
||||
|
||||
bool Menu::handlePasswordScreen(uint8 &new_skill, uint8 &new_level) {
|
||||
debug(DBG_MENU, "Menu::handlePasswordScreen()");
|
||||
_vid->fadeOut();
|
||||
_vid->_charShadowColor = _charVar1;
|
||||
_vid->_charTransparentColor = 0xFF;
|
||||
_vid->_charFrontColor = _charVar4;
|
||||
_vid->fullRefresh();
|
||||
char password[7];
|
||||
int len = 0;
|
||||
do {
|
||||
loadPicture("menu2");
|
||||
drawString2(_res->getMenuString(LocaleData::LI_16_ENTER_PASSWORD1), 15, 3);
|
||||
drawString2(_res->getMenuString(LocaleData::LI_17_ENTER_PASSWORD2), 17, 3);
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
_vid->drawChar((uint8)password[i], 21, i + 15);
|
||||
}
|
||||
_vid->drawChar(0x20, 21, len + 15);
|
||||
|
||||
_vid->markBlockAsDirty(15 * 8, 21 * 8, (len + 1) * 8, 8);
|
||||
_vid->updateScreen();
|
||||
_stub->sleep(EVENTS_DELAY);
|
||||
_stub->processEvents();
|
||||
char c = _stub->_pi.lastChar;
|
||||
if (c != 0) {
|
||||
_stub->_pi.lastChar = 0;
|
||||
if (len < 6) {
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c &= ~0x20;
|
||||
}
|
||||
if ((c >= 'A' && c <= 'Z') || (c == 0x20)) {
|
||||
password[len] = c;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.backspace) {
|
||||
_stub->_pi.backspace = false;
|
||||
if (len > 0) {
|
||||
--len;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
password[len] = '\0';
|
||||
for (int level = 0; level < 8; ++level) {
|
||||
for (int skill = 0; skill < 3; ++skill) {
|
||||
if (strcmp(_passwords[level][skill], password) == 0) {
|
||||
new_level = level;
|
||||
new_skill = skill;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} while (!_stub->_pi.quit);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Menu::handleTitleScreen(uint8 &new_skill, uint8 &new_level) {
|
||||
debug(DBG_MENU, "Menu::handleTitleScreen()");
|
||||
bool quit_loop = false;
|
||||
int menu_entry = 0;
|
||||
bool reinit_screen = true;
|
||||
bool continue_game = true;
|
||||
_charVar1 = 0;
|
||||
_charVar2 = 0;
|
||||
_charVar3 = 0;
|
||||
_charVar4 = 0;
|
||||
_charVar5 = 0;
|
||||
_ply->play(1);
|
||||
while (!quit_loop) {
|
||||
if (reinit_screen) {
|
||||
_vid->fadeOut();
|
||||
loadPicture("menu1");
|
||||
_vid->fullRefresh();
|
||||
_charVar3 = 1;
|
||||
_charVar4 = 2;
|
||||
menu_entry = 0;
|
||||
reinit_screen = false;
|
||||
}
|
||||
int selected_menu_entry = -1;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
int color = (i == menu_entry) ? 2 : 3;
|
||||
drawString(_res->getMenuString(LocaleData::LI_07_START + i), 16 + i * 2, 20, color);
|
||||
}
|
||||
|
||||
_vid->updateScreen();
|
||||
_stub->sleep(EVENTS_DELAY);
|
||||
_stub->processEvents();
|
||||
|
||||
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
|
||||
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
|
||||
if (menu_entry != 0) {
|
||||
--menu_entry;
|
||||
} else {
|
||||
menu_entry = 4;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
|
||||
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
|
||||
if (menu_entry != 4) {
|
||||
++menu_entry;
|
||||
} else {
|
||||
menu_entry = 0;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
selected_menu_entry = menu_entry;
|
||||
}
|
||||
|
||||
if (selected_menu_entry != -1) {
|
||||
switch (selected_menu_entry) {
|
||||
case MENU_OPTION_ITEM_START:
|
||||
new_level = 0;
|
||||
quit_loop = true;
|
||||
break;
|
||||
case MENU_OPTION_ITEM_SKILL:
|
||||
handleSkillScreen(new_skill);
|
||||
reinit_screen = true;
|
||||
break;
|
||||
case MENU_OPTION_ITEM_PASSWORD:
|
||||
if (handlePasswordScreen(new_skill, new_level)) {
|
||||
quit_loop = true;
|
||||
} else {
|
||||
reinit_screen = true;
|
||||
}
|
||||
break;
|
||||
case MENU_OPTION_ITEM_INFO:
|
||||
handleInfoScreen();
|
||||
reinit_screen = true;
|
||||
break;
|
||||
case MENU_OPTION_ITEM_QUIT:
|
||||
continue_game = false;
|
||||
quit_loop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.quit) {
|
||||
continue_game = false;
|
||||
quit_loop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_ply->stop();
|
||||
return continue_game;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MENU_H__
|
||||
#define __MENU_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct ModPlayer;
|
||||
struct Resource;
|
||||
struct SystemStub;
|
||||
struct Video;
|
||||
|
||||
struct Menu {
|
||||
enum {
|
||||
MENU_OPTION_ITEM_START = 0,
|
||||
MENU_OPTION_ITEM_SKILL,
|
||||
MENU_OPTION_ITEM_PASSWORD,
|
||||
MENU_OPTION_ITEM_INFO,
|
||||
MENU_OPTION_ITEM_QUIT
|
||||
};
|
||||
|
||||
enum {
|
||||
EVENTS_DELAY = 80
|
||||
};
|
||||
|
||||
static const char *_passwords[8][3];
|
||||
|
||||
ModPlayer *_ply;
|
||||
Resource *_res;
|
||||
SystemStub *_stub;
|
||||
Video *_vid;
|
||||
|
||||
const char **_textOptions;
|
||||
uint8 _charVar1;
|
||||
uint8 _charVar2;
|
||||
uint8 _charVar3;
|
||||
uint8 _charVar4;
|
||||
uint8 _charVar5;
|
||||
|
||||
Menu(ModPlayer *ply, Resource *res, SystemStub *stub, Video *vid);
|
||||
|
||||
void drawString(const char *str, int16 y, int16 x, uint8 color);
|
||||
void drawString2(const char *str, int16 y, int16 x);
|
||||
void loadPicture(const char *prefix);
|
||||
void handleInfoScreen();
|
||||
void handleSkillScreen(uint8 &new_skill);
|
||||
bool handlePasswordScreen(uint8 &new_skill, uint8 &new_level);
|
||||
bool handleTitleScreen(uint8 &new_skill, uint8 &new_level);
|
||||
};
|
||||
|
||||
#endif // __MENU_H__
|
||||
@@ -1,124 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "mixer.h"
|
||||
#include "systemstub.h"
|
||||
|
||||
|
||||
Mixer::Mixer(SystemStub *stub)
|
||||
: _stub(stub) {
|
||||
}
|
||||
|
||||
void Mixer::init() {
|
||||
memset(_channels, 0, sizeof(_channels));
|
||||
_premixHook = 0;
|
||||
_mutex = _stub->createMutex();
|
||||
_stub->startAudio(Mixer::mixCallback, this);
|
||||
}
|
||||
|
||||
void Mixer::free() {
|
||||
stopAll();
|
||||
_stub->stopAudio();
|
||||
_stub->destroyMutex(_mutex);
|
||||
}
|
||||
|
||||
void Mixer::setPremixHook(PremixHook premixHook, void *userData) {
|
||||
debug(DBG_SND, "Mixer::setPremixHook()");
|
||||
MutexStack(_stub, _mutex);
|
||||
_premixHook = premixHook;
|
||||
_premixHookData = userData;
|
||||
}
|
||||
|
||||
void Mixer::play(const MixerChunk *mc, uint16 freq, uint8 volume) {
|
||||
debug(DBG_SND, "Mixer::play(%d, %d)", freq, volume);
|
||||
MutexStack(_stub, _mutex);
|
||||
MixerChannel *ch = 0;
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
MixerChannel *cur = &_channels[i];
|
||||
if (cur->active) {
|
||||
if (cur->chunk.data == mc->data) {
|
||||
cur->chunkPos = 0;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ch = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ch) {
|
||||
ch->active = true;
|
||||
ch->volume = volume;
|
||||
ch->chunk = *mc;
|
||||
ch->chunkPos = 0;
|
||||
ch->chunkInc = (freq << FRAC_BITS) / _stub->getOutputSampleRate();
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Mixer::getSampleRate() const {
|
||||
return _stub->getOutputSampleRate();
|
||||
}
|
||||
|
||||
void Mixer::stopAll() {
|
||||
debug(DBG_SND, "Mixer::stopAll()");
|
||||
MutexStack(_stub, _mutex);
|
||||
for (uint8 i = 0; i < NUM_CHANNELS; ++i) {
|
||||
_channels[i].active = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addclamp(int16& a, int b) {
|
||||
int add = a + b;
|
||||
if (add < -32767) {
|
||||
add = -32767;
|
||||
} else if (add > 32767) {
|
||||
add = 32767;
|
||||
}
|
||||
a = add;
|
||||
}
|
||||
|
||||
void Mixer::mix(int8 *buf1, int len) {
|
||||
int16 *buf = (int16 *)buf1;
|
||||
MutexStack(_stub, _mutex);
|
||||
memset(buf, 0, len);
|
||||
len /= 2;
|
||||
if (_premixHook) {
|
||||
if (!_premixHook(_premixHookData, buf, len)) {
|
||||
_premixHook = 0;
|
||||
_premixHookData = 0;
|
||||
}
|
||||
}
|
||||
for (uint8 i = 0; i < NUM_CHANNELS; ++i) {
|
||||
MixerChannel *ch = &_channels[i];
|
||||
if (ch->active) {
|
||||
for (int pos = 0; pos < len; ++pos) {
|
||||
if ((ch->chunkPos >> FRAC_BITS) >= (ch->chunk.len - 1)) {
|
||||
ch->active = false;
|
||||
break;
|
||||
}
|
||||
int out = resampleLinear(&ch->chunk, ch->chunkPos, ch->chunkInc, FRAC_BITS);
|
||||
addclamp(buf[pos], out * Mixer::MIX_AMPLIFICATIION * ch->volume / Mixer::MAX_VOLUME );
|
||||
ch->chunkPos += ch->chunkInc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mixer::mixCallback(void *param, uint8 *buf, int len) {
|
||||
((Mixer *)param)->mix((int8 *)buf, len);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MIXER_H__
|
||||
#define __MIXER_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct MixerChunk {
|
||||
uint8 *data;
|
||||
uint32 len;
|
||||
|
||||
int8 getPCM(int offset) const {
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
} else if (offset >= (int)len) {
|
||||
offset = len - 1;
|
||||
}
|
||||
return (int8)data[offset];
|
||||
}
|
||||
};
|
||||
|
||||
struct MixerChannel {
|
||||
uint8 active;
|
||||
uint8 volume;
|
||||
MixerChunk chunk;
|
||||
uint32 chunkPos;
|
||||
uint32 chunkInc;
|
||||
};
|
||||
|
||||
struct SystemStub;
|
||||
|
||||
struct Mixer {
|
||||
typedef bool (*PremixHook)(void *userData, int16 *buf, int len);
|
||||
|
||||
enum {
|
||||
NUM_CHANNELS = 4,
|
||||
FRAC_BITS = 12,
|
||||
MAX_VOLUME = 64,
|
||||
MIX_AMPLIFICATIION = 64 // TODO: edit here to tweak sound
|
||||
};
|
||||
|
||||
void *_mutex;
|
||||
SystemStub *_stub;
|
||||
MixerChannel _channels[NUM_CHANNELS];
|
||||
PremixHook _premixHook;
|
||||
void *_premixHookData;
|
||||
|
||||
Mixer(SystemStub *stub);
|
||||
void init();
|
||||
void free();
|
||||
void setPremixHook(PremixHook premixHook, void *userData);
|
||||
void play(const MixerChunk *mc, uint16 freq, uint8 volume);
|
||||
void stopAll();
|
||||
uint32 getSampleRate() const;
|
||||
void mix(int8 *buf, int len);
|
||||
|
||||
//static void addclamp(int16 &a, int b);
|
||||
static void mixCallback(void *param, uint8 *buf, int len);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
int resampleLinear(T *sample, int pos, int step, int fracBits) {
|
||||
const int inputPos = pos >> fracBits;
|
||||
const int inputFrac = (1 << fracBits) - 1;
|
||||
int out = sample->getPCM(inputPos);
|
||||
out += (sample->getPCM(inputPos + 1) - out) * inputFrac >> fracBits;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int resample3Pt(T *sample, int pos, int step, int fracBits) {
|
||||
const int inputPos = pos >> fracBits;
|
||||
const int inputFrac = (1 << fracBits) - 1;
|
||||
int out = sample->getPCM(inputPos) >> 1;
|
||||
out += sample->getPCM(inputPos + ((inputFrac - (step >> 1)) >> fracBits)) >> 2;
|
||||
out += sample->getPCM(inputPos + ((inputFrac + (step >> 1)) >> fracBits)) >> 2;
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif // __MIXER_H__
|
||||
@@ -1,533 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
#include "mixer.h"
|
||||
#include "mod_player.h"
|
||||
|
||||
|
||||
ModPlayer::ModPlayer(Mixer *mixer, const char *dataPath)
|
||||
: _playing(false), _mix(mixer), _dataPath(dataPath) {
|
||||
memset(&_modInfo, 0, sizeof(_modInfo));
|
||||
}
|
||||
|
||||
uint16 ModPlayer::findPeriod(uint16 period, uint8 fineTune) const {
|
||||
for (int p = 0; p < 36; ++p) {
|
||||
if (_periodTable[p] == period) {
|
||||
return fineTune * 36 + p;
|
||||
}
|
||||
}
|
||||
error("Invalid period=%d", period);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ModPlayer::load(File *f) {
|
||||
f->read(_modInfo.songName, 20);
|
||||
_modInfo.songName[20] = 0;
|
||||
debug(DBG_MOD, "songName = '%s'", _modInfo.songName);
|
||||
|
||||
for (int s = 0; s < NUM_SAMPLES; ++s) {
|
||||
SampleInfo *si = &_modInfo.samples[s];
|
||||
f->read(si->name, 22);
|
||||
si->name[22] = 0;
|
||||
si->len = f->readUint16BE() * 2;
|
||||
si->fineTune = f->readByte();
|
||||
si->volume = f->readByte();
|
||||
si->repeatPos = f->readUint16BE() * 2;
|
||||
si->repeatLen = f->readUint16BE() * 2;
|
||||
si->data = 0;
|
||||
assert(si->len == 0 || si->repeatPos + si->repeatLen <= si->len);
|
||||
debug(DBG_MOD, "sample=%d name='%s' len=%d vol=%d", s, si->name, si->len, si->volume);
|
||||
}
|
||||
_modInfo.numPatterns = f->readByte();
|
||||
assert(_modInfo.numPatterns < NUM_PATTERNS);
|
||||
f->readByte(); // 0x7F
|
||||
f->read(_modInfo.patternOrderTable, NUM_PATTERNS);
|
||||
f->readUint32BE(); // 'M.K.', Protracker, 4 channels
|
||||
|
||||
uint16 n = 0;
|
||||
for (int i = 0; i < NUM_PATTERNS; ++i) {
|
||||
if (_modInfo.patternOrderTable[i] != 0) {
|
||||
n = MAX(n, _modInfo.patternOrderTable[i]);
|
||||
}
|
||||
}
|
||||
debug(DBG_MOD, "numPatterns=%d",n + 1);
|
||||
n = (n + 1) * 64 * 4 * 4; // 64 lines of 4 notes per channel
|
||||
_modInfo.patternsTable = (uint8 *)malloc(n);
|
||||
assert(_modInfo.patternsTable);
|
||||
f->read(_modInfo.patternsTable, n);
|
||||
|
||||
for (int s = 0; s < NUM_SAMPLES; ++s) {
|
||||
SampleInfo *si = &_modInfo.samples[s];
|
||||
if (si->len != 0) {
|
||||
si->data = (int8 *)malloc(si->len);
|
||||
if (si->data) {
|
||||
f->read(si->data, si->len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModPlayer::unload() {
|
||||
if (_modInfo.songName[0]) {
|
||||
free(_modInfo.patternsTable);
|
||||
for (int s = 0; s < NUM_SAMPLES; ++s) {
|
||||
free(_modInfo.samples[s].data);
|
||||
}
|
||||
memset(&_modInfo, 0, sizeof(_modInfo));
|
||||
}
|
||||
}
|
||||
|
||||
void ModPlayer::play(uint8 num) {
|
||||
if (!_playing && num < _modulesFilesCount) {
|
||||
File f;
|
||||
bool found = false;
|
||||
for (uint8 i = 0; i < ARRAYSIZE(_modulesFiles[num]); ++i) {
|
||||
if (f.open(_modulesFiles[num][i], _dataPath, "rb")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
warning("Can't find music file %d", num);
|
||||
} else {
|
||||
load(&f);
|
||||
_currentPatternOrder = 0;
|
||||
_currentPatternPos = 0;
|
||||
_currentTick = 0;
|
||||
_patternDelay = 0;
|
||||
_songSpeed = 6;
|
||||
_songTempo = 125;
|
||||
_patternLoopPos = 0;
|
||||
_patternLoopCount = -1;
|
||||
_samplesLeft = 0;
|
||||
_songNum = num;
|
||||
_introSongHack = false;
|
||||
memset(_tracks, 0, sizeof(_tracks));
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
_playing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModPlayer::stop() {
|
||||
if (_playing) {
|
||||
_mix->setPremixHook(0, 0);
|
||||
_playing = false;
|
||||
}
|
||||
unload();
|
||||
}
|
||||
|
||||
void ModPlayer::handleNote(int trackNum, uint32 noteData) {
|
||||
Track *tk = &_tracks[trackNum];
|
||||
uint16 sampleNum = ((noteData >> 24) & 0xF0) | ((noteData >> 12) & 0xF);
|
||||
uint16 samplePeriod = (noteData >> 16) & 0xFFF;
|
||||
uint16 effectData = noteData & 0xFFF;
|
||||
debug(DBG_MOD, "ModPlayer::handleNote(%d) p=%d/%d sampleNumber=0x%X samplePeriod=0x%X effectData=0x%X tk->period=%d", trackNum, _currentPatternPos, _currentPatternOrder, sampleNum, samplePeriod, effectData, tk->period);
|
||||
if (sampleNum != 0) {
|
||||
tk->sample = &_modInfo.samples[sampleNum - 1];
|
||||
tk->volume = tk->sample->volume;
|
||||
tk->pos = 0;
|
||||
}
|
||||
if (samplePeriod != 0) {
|
||||
tk->periodIndex = findPeriod(samplePeriod, tk->sample->fineTune);
|
||||
if ((effectData >> 8) != 0x3 && (effectData >> 8) != 0x5) {
|
||||
tk->period = _periodTable[tk->periodIndex];
|
||||
tk->freq = PAULA_FREQ / tk->period;
|
||||
} else {
|
||||
tk->portamento = _periodTable[tk->periodIndex];
|
||||
}
|
||||
tk->vibratoAmp = 0;
|
||||
tk->vibratoSpeed = 0;
|
||||
tk->vibratoPos = 0;
|
||||
}
|
||||
tk->effectData = effectData;
|
||||
}
|
||||
|
||||
void ModPlayer::applyVolumeSlide(int trackNum, int amount) {
|
||||
debug(DBG_MOD, "ModPlayer::applyVolumeSlide(%d, %d)", trackNum, amount);
|
||||
Track *tk = &_tracks[trackNum];
|
||||
int vol = tk->volume + amount;
|
||||
if (vol < 0) {
|
||||
vol = 0;
|
||||
} else if (vol > 64) {
|
||||
vol = 64;
|
||||
}
|
||||
tk->volume = vol;
|
||||
}
|
||||
|
||||
void ModPlayer::applyVibrato(int trackNum) {
|
||||
debug(DBG_MOD, "ModPlayer::applyVibrato(%d)", trackNum);
|
||||
Track *tk = &_tracks[trackNum];
|
||||
int vib = tk->vibratoAmp * _sineWaveTable[tk->vibratoPos] / 128;
|
||||
if (tk->period + vib != 0) {
|
||||
tk->freq = PAULA_FREQ / (tk->period + vib);
|
||||
}
|
||||
tk->vibratoPos += tk->vibratoSpeed;
|
||||
if (tk->vibratoPos >= 64) {
|
||||
tk->vibratoPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ModPlayer::applyPortamento(int trackNum) {
|
||||
debug(DBG_MOD, "ModPlayer::applyPortamento(%d)", trackNum);
|
||||
Track *tk = &_tracks[trackNum];
|
||||
if (tk->period < tk->portamento) {
|
||||
tk->period = MIN(tk->period + tk->portamentoSpeed, tk->portamento);
|
||||
} else if (tk->period > tk->portamento) {
|
||||
tk->period = MAX(tk->period - tk->portamentoSpeed, tk->portamento);
|
||||
}
|
||||
if (tk->period != 0) {
|
||||
tk->freq = PAULA_FREQ / tk->period;
|
||||
}
|
||||
}
|
||||
|
||||
void ModPlayer::handleEffect(int trackNum, bool tick) {
|
||||
Track *tk = &_tracks[trackNum];
|
||||
uint8 effectNum = tk->effectData >> 8;
|
||||
uint8 effectXY = tk->effectData & 0xFF;
|
||||
uint8 effectX = effectXY >> 4;
|
||||
uint8 effectY = effectXY & 0xF;
|
||||
debug(DBG_MOD, "ModPlayer::handleEffect(%d) effectNum=0x%X effectXY=0x%X", trackNum, effectNum, effectXY);
|
||||
switch (effectNum) {
|
||||
case 0x0: // arpeggio
|
||||
if (tick && effectXY != 0) {
|
||||
uint16 period = tk->period;
|
||||
switch (_currentTick & 3) {
|
||||
case 1:
|
||||
period = _periodTable[tk->periodIndex + effectX];
|
||||
break;
|
||||
case 2:
|
||||
period = _periodTable[tk->periodIndex + effectY];
|
||||
break;
|
||||
}
|
||||
tk->freq = PAULA_FREQ / period;
|
||||
}
|
||||
break;
|
||||
case 0x1: // portamento up
|
||||
if (tick) {
|
||||
tk->period -= effectXY;
|
||||
if (tk->period < 113) { // note B-3
|
||||
tk->period = 113;
|
||||
}
|
||||
tk->freq = PAULA_FREQ / tk->period;
|
||||
}
|
||||
break;
|
||||
case 0x2: // portamento down
|
||||
if (tick) {
|
||||
tk->period += effectXY;
|
||||
if (tk->period > 856) { // note C-1
|
||||
tk->period = 856;
|
||||
}
|
||||
tk->freq = PAULA_FREQ / tk->period;
|
||||
}
|
||||
break;
|
||||
case 0x3: // tone portamento
|
||||
if (!tick) {
|
||||
if (effectXY != 0) {
|
||||
tk->portamentoSpeed = effectXY;
|
||||
}
|
||||
} else {
|
||||
applyPortamento(trackNum);
|
||||
}
|
||||
break;
|
||||
case 0x4: // vibrato
|
||||
if (!tick) {
|
||||
if (effectX != 0) {
|
||||
tk->vibratoSpeed = effectX;
|
||||
}
|
||||
if (effectY != 0) {
|
||||
tk->vibratoAmp = effectY;
|
||||
}
|
||||
} else {
|
||||
applyVibrato(trackNum);
|
||||
}
|
||||
break;
|
||||
case 0x5: // tone portamento + volume slide
|
||||
if (tick) {
|
||||
applyPortamento(trackNum);
|
||||
applyVolumeSlide(trackNum, effectX - effectY);
|
||||
}
|
||||
break;
|
||||
case 0x6: // vibrato + volume slide
|
||||
if (tick) {
|
||||
applyVibrato(trackNum);
|
||||
applyVolumeSlide(trackNum, effectX - effectY);
|
||||
}
|
||||
break;
|
||||
case 0x9: // set sample offset
|
||||
if (!tick) {
|
||||
tk->pos = effectXY << (8 + FRAC_BITS);
|
||||
}
|
||||
break;
|
||||
case 0xA: // volume slide
|
||||
if (tick) {
|
||||
applyVolumeSlide(trackNum, effectX - effectY);
|
||||
}
|
||||
break;
|
||||
case 0xB: // position jump
|
||||
if (!tick) {
|
||||
_currentPatternOrder = effectXY;
|
||||
_currentPatternPos = 0;
|
||||
assert(_currentPatternOrder < _modInfo.numPatterns);
|
||||
}
|
||||
break;
|
||||
case 0xC: // set volume
|
||||
if (!tick) {
|
||||
assert(effectXY <= 64);
|
||||
tk->volume = effectXY;
|
||||
}
|
||||
break;
|
||||
case 0xD: // pattern break
|
||||
if (!tick) {
|
||||
_currentPatternPos = effectX * 10 + effectY;
|
||||
assert(_currentPatternPos < 64);
|
||||
++_currentPatternOrder;
|
||||
debug(DBG_MOD, "_currentPatternPos = %d _currentPatternOrder = %d", _currentPatternPos, _currentPatternOrder);
|
||||
}
|
||||
break;
|
||||
case 0xE: // extended effects
|
||||
switch (effectX) {
|
||||
case 0x0: // set filter, ignored
|
||||
break;
|
||||
case 0x1: // fineslide up
|
||||
if (!tick) {
|
||||
tk->period -= effectY;
|
||||
if (tk->period < 113) { // B-3 note
|
||||
tk->period = 113;
|
||||
}
|
||||
tk->freq = PAULA_FREQ / tk->period;
|
||||
}
|
||||
break;
|
||||
case 0x2: // fineslide down
|
||||
if (!tick) {
|
||||
tk->period += effectY;
|
||||
if (tk->period > 856) { // C-1 note
|
||||
tk->period = 856;
|
||||
}
|
||||
tk->freq = PAULA_FREQ / tk->period;
|
||||
}
|
||||
break;
|
||||
case 0x6: // loop pattern
|
||||
if (!tick) {
|
||||
if (effectY == 0) {
|
||||
_patternLoopPos = _currentPatternPos | (_currentPatternOrder << 8);
|
||||
debug(DBG_MOD, "_patternLoopPos=%d/%d", _currentPatternPos, _currentPatternOrder);
|
||||
} else {
|
||||
if (_patternLoopCount == -1) {
|
||||
_patternLoopCount = effectY;
|
||||
_currentPatternPos = _patternLoopPos & 0xFF;
|
||||
_currentPatternOrder = _patternLoopPos >> 8;
|
||||
} else {
|
||||
--_patternLoopCount;
|
||||
if (_patternLoopCount != 0) {
|
||||
_currentPatternPos = _patternLoopPos & 0xFF;
|
||||
_currentPatternOrder = _patternLoopPos >> 8;
|
||||
} else {
|
||||
_patternLoopCount = -1;
|
||||
}
|
||||
}
|
||||
debug(DBG_MOD, "_patternLoopCount=%d", _patternLoopCount);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x9: // retrigger sample
|
||||
if (tick) {
|
||||
tk->retriggerCounter = effectY;
|
||||
} else {
|
||||
if (tk->retriggerCounter == 0) {
|
||||
tk->pos = 0;
|
||||
tk->retriggerCounter = effectY;
|
||||
debug(DBG_MOD, "retrigger sample=%d _songSpeed=%d", effectY, _songSpeed);
|
||||
}
|
||||
--tk->retriggerCounter;
|
||||
}
|
||||
break;
|
||||
case 0xA: // fine volume slide up
|
||||
if (!tick) {
|
||||
applyVolumeSlide(trackNum, effectY);
|
||||
}
|
||||
break;
|
||||
case 0xB: // fine volume slide down
|
||||
if (!tick) {
|
||||
applyVolumeSlide(trackNum, -effectY);
|
||||
}
|
||||
break;
|
||||
case 0xC: // cut sample
|
||||
if (!tick) {
|
||||
tk->cutCounter = effectY;
|
||||
} else {
|
||||
--tk->cutCounter;
|
||||
if (tk->cutCounter == 0) {
|
||||
tk->volume = 0;
|
||||
}
|
||||
}
|
||||
case 0xD: // delay sample
|
||||
if (!tick) {
|
||||
tk->delayCounter = effectY;
|
||||
} else {
|
||||
if (tk->delayCounter != 0) {
|
||||
--tk->delayCounter;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xE: // delay pattern
|
||||
if (!tick) {
|
||||
debug(DBG_MOD, "ModPlayer::handleEffect() _currentTick=%d delay pattern=%d", _currentTick, effectY);
|
||||
_patternDelay = effectY;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
warning("Unhandled extended effect 0x%X params=0x%X", effectX, effectY);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xF: // set speed
|
||||
if (!tick) {
|
||||
if (effectXY < 0x20) {
|
||||
_songSpeed = effectXY;
|
||||
} else {
|
||||
_songTempo = effectXY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
warning("Unhandled effect 0x%X params=0x%X", effectNum, effectXY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ModPlayer::handleTick() {
|
||||
if (!_playing) {
|
||||
return;
|
||||
}
|
||||
// if (_patternDelay != 0) {
|
||||
// --_patternDelay;
|
||||
// return;
|
||||
// }
|
||||
if (_currentTick == 0) {
|
||||
debug(DBG_MOD, "_currentPatternOrder=%d _currentPatternPos=%d", _currentPatternOrder, _currentPatternPos);
|
||||
uint8 currentPattern = _modInfo.patternOrderTable[_currentPatternOrder];
|
||||
const uint8 *p = _modInfo.patternsTable + (currentPattern * 64 + _currentPatternPos) * 16;
|
||||
for (int i = 0; i < NUM_TRACKS; ++i) {
|
||||
uint32 noteData = READ_BE_UINT32(p);
|
||||
handleNote(i, noteData);
|
||||
p += 4;
|
||||
}
|
||||
++_currentPatternPos;
|
||||
if (_currentPatternPos == 64) {
|
||||
++_currentPatternOrder;
|
||||
_currentPatternPos = 0;
|
||||
debug(DBG_MOD, "ModPlayer::handleTick() _currentPatternOrder = %d/%d", _currentPatternOrder, _modInfo.numPatterns);
|
||||
// On the amiga version, the introduction cutscene is shorter than the PC version ;
|
||||
// so the music module doesn't synchronize at all with the PC datafiles, here we
|
||||
// add a hack to let the music play longer
|
||||
if (_songNum == 0 && _currentPatternOrder == 3 && !_introSongHack) {
|
||||
_currentPatternOrder = 1;
|
||||
_introSongHack = true;
|
||||
// warning("Introduction module synchronization hack");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < NUM_TRACKS; ++i) {
|
||||
handleEffect(i, (_currentTick != 0));
|
||||
}
|
||||
++_currentTick;
|
||||
if (_currentTick == _songSpeed) {
|
||||
_currentTick = 0;
|
||||
}
|
||||
if (_currentPatternOrder == _modInfo.numPatterns) {
|
||||
debug(DBG_MOD, "ModPlayer::handleEffect() _currentPatternOrder == _modInfo.numPatterns");
|
||||
_playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addclamp(int16& a, int b) {
|
||||
int add = a + b;
|
||||
if (add < -32767) {
|
||||
add = -32767;
|
||||
} else if (add > 32767) {
|
||||
add = 32767;
|
||||
}
|
||||
a = add;
|
||||
}
|
||||
|
||||
void ModPlayer::mixSamples(int16 *buf, int samplesLen) {
|
||||
for (int i = 0; i < NUM_TRACKS; ++i) {
|
||||
Track *tk = &_tracks[i];
|
||||
if (tk->sample != 0 && tk->delayCounter == 0) {
|
||||
int16 *mixbuf = buf;
|
||||
SampleInfo *si = tk->sample;
|
||||
int len = si->len << FRAC_BITS;
|
||||
int loopLen = si->repeatLen << FRAC_BITS;
|
||||
int loopPos = si->repeatPos << FRAC_BITS;
|
||||
int deltaPos = (tk->freq << FRAC_BITS) / _mix->getSampleRate();
|
||||
int curLen = samplesLen;
|
||||
int pos = tk->pos;
|
||||
while (curLen != 0) {
|
||||
int count;
|
||||
if (loopLen > (2 << FRAC_BITS)) {
|
||||
if (pos >= loopPos + loopLen) {
|
||||
pos -= loopLen;
|
||||
}
|
||||
count = MIN(curLen, (loopPos + loopLen - pos - 1) / deltaPos + 1);
|
||||
curLen -= count;
|
||||
} else {
|
||||
if (pos >= len) {
|
||||
count = 0;
|
||||
} else {
|
||||
count = MIN(curLen, (len - pos - 1) / deltaPos + 1);
|
||||
}
|
||||
curLen = 0;
|
||||
}
|
||||
while (count--) {
|
||||
int out = resample3Pt(si, pos, deltaPos, FRAC_BITS);
|
||||
addclamp(*mixbuf++, out * Mixer::MIX_AMPLIFICATIION * tk->volume / 64);
|
||||
pos += deltaPos;
|
||||
}
|
||||
}
|
||||
tk->pos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ModPlayer::mix(int16 *buf, int len) {
|
||||
if (_playing) {
|
||||
memset(buf, 0, len*2);
|
||||
const int samplesPerTick = _mix->getSampleRate() / (50 * _songTempo / 125);
|
||||
while (len != 0) {
|
||||
if (_samplesLeft == 0) {
|
||||
handleTick();
|
||||
_samplesLeft = samplesPerTick;
|
||||
}
|
||||
int count = _samplesLeft;
|
||||
if (count > len) {
|
||||
count = len;
|
||||
}
|
||||
_samplesLeft -= count;
|
||||
len -= count;
|
||||
mixSamples(buf, count);
|
||||
buf += count;
|
||||
}
|
||||
}
|
||||
return _playing;
|
||||
}
|
||||
|
||||
bool ModPlayer::mixCallback(void *param, int16 *buf, int len) {
|
||||
return ((ModPlayer *)param)->mix(buf, len);
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MOD_PLAYER_H__
|
||||
#define __MOD_PLAYER_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct File;
|
||||
struct Mixer;
|
||||
|
||||
struct ModPlayer {
|
||||
enum {
|
||||
NUM_SAMPLES = 31,
|
||||
NUM_TRACKS = 4,
|
||||
NUM_PATTERNS = 128,
|
||||
FRAC_BITS = 12,
|
||||
PAULA_FREQ = 3546897
|
||||
};
|
||||
|
||||
struct SampleInfo {
|
||||
char name[23];
|
||||
uint16 len;
|
||||
uint8 fineTune;
|
||||
uint8 volume;
|
||||
uint16 repeatPos;
|
||||
uint16 repeatLen;
|
||||
int8 *data;
|
||||
|
||||
int8 getPCM(int offset) const {
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
} else if (offset >= (int)len) {
|
||||
offset = len - 1;
|
||||
}
|
||||
return data[offset];
|
||||
}
|
||||
};
|
||||
|
||||
struct ModuleInfo {
|
||||
char songName[21];
|
||||
SampleInfo samples[NUM_SAMPLES];
|
||||
uint8 numPatterns;
|
||||
uint8 patternOrderTable[NUM_PATTERNS];
|
||||
uint8 *patternsTable;
|
||||
};
|
||||
|
||||
struct Track {
|
||||
SampleInfo *sample;
|
||||
uint8 volume;
|
||||
int pos;
|
||||
int freq;
|
||||
uint16 period;
|
||||
uint16 periodIndex;
|
||||
uint16 effectData;
|
||||
int vibratoSpeed;
|
||||
int vibratoAmp;
|
||||
int vibratoPos;
|
||||
int portamento;
|
||||
int portamentoSpeed;
|
||||
int retriggerCounter;
|
||||
int delayCounter;
|
||||
int cutCounter;
|
||||
};
|
||||
|
||||
static const int8 _sineWaveTable[];
|
||||
static const uint16 _periodTable[];
|
||||
static const char *_modulesFiles[][2];
|
||||
static const int _modulesFilesCount;
|
||||
|
||||
ModuleInfo _modInfo;
|
||||
uint8 _currentPatternOrder;
|
||||
uint8 _currentPatternPos;
|
||||
uint8 _currentTick;
|
||||
uint8 _songSpeed;
|
||||
uint8 _songTempo;
|
||||
int _patternDelay;
|
||||
int _patternLoopPos;
|
||||
int _patternLoopCount;
|
||||
int _samplesLeft;
|
||||
uint8 _songNum;
|
||||
bool _introSongHack;
|
||||
bool _playing;
|
||||
Track _tracks[NUM_TRACKS];
|
||||
Mixer *_mix;
|
||||
const char *_dataPath;
|
||||
|
||||
ModPlayer(Mixer *mixer, const char *dataPath);
|
||||
|
||||
uint16 findPeriod(uint16 period, uint8 fineTune) const;
|
||||
void load(File *f);
|
||||
void unload();
|
||||
void play(uint8 num);
|
||||
void stop();
|
||||
void handleNote(int trackNum, uint32 noteData);
|
||||
void handleTick();
|
||||
void applyVolumeSlide(int trackNum, int amount);
|
||||
void applyVibrato(int trackNum);
|
||||
void applyPortamento(int trackNum);
|
||||
void handleEffect(int trackNum, bool tick);
|
||||
void mixSamples(int16 *buf, int len);
|
||||
bool mix(int16 *buf, int len);
|
||||
|
||||
static bool mixCallback(void *param, int16 *buf, int len);
|
||||
};
|
||||
|
||||
#endif // __MOD_PLAYER_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,742 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
#include "unpack.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
Resource::Resource(const char *dataPath, Version ver) {
|
||||
memset(this, 0, sizeof(Resource));
|
||||
_dataPath = dataPath;
|
||||
_ver = ver;
|
||||
_memBuf = (uint8 *)malloc(0xE000);
|
||||
}
|
||||
|
||||
Resource::~Resource() {
|
||||
clearLevelRes();
|
||||
free(_fnt);
|
||||
free(_icn);
|
||||
free(_tab);
|
||||
free(_spr1);
|
||||
free(_memBuf);
|
||||
free(_cmd);
|
||||
free(_pol);
|
||||
free(_cine_off);
|
||||
free(_cine_txt);
|
||||
for (int i = 0; i < _numSfx; ++i) {
|
||||
free(_sfxList[i].data);
|
||||
}
|
||||
free(_sfxList);
|
||||
free(_voiceBuf);
|
||||
}
|
||||
|
||||
void Resource::clearLevelRes() {
|
||||
free(_tbn); _tbn = 0;
|
||||
free(_mbk); _mbk = 0;
|
||||
free(_mbkData); _mbkData = 0;
|
||||
free(_pal); _pal = 0;
|
||||
free(_map); _map = 0;
|
||||
free(_spc); _spc = 0;
|
||||
free(_ani); _ani = 0;
|
||||
free_OBJ();
|
||||
}
|
||||
|
||||
void Resource::load_FIB(const char *fileName) {
|
||||
debug(DBG_RES, "Resource::load_FIB('%s')", fileName);
|
||||
static const uint8 fibonacciTable[] = {
|
||||
0xDE, 0xEB, 0xF3, 0xF8, 0xFB, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0D, 0x15
|
||||
};
|
||||
sprintf(_entryName, "%s.FIB", fileName);
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
_numSfx = f.readUint16LE();
|
||||
_sfxList = (SoundFx *)malloc(_numSfx * sizeof(SoundFx));
|
||||
if (!_sfxList) {
|
||||
error("Unable to allocate SoundFx table");
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < _numSfx; ++i) {
|
||||
SoundFx *sfx = &_sfxList[i];
|
||||
sfx->offset = f.readUint32LE();
|
||||
sfx->len = f.readUint16LE();
|
||||
sfx->data = 0;
|
||||
}
|
||||
for (i = 0; i < _numSfx; ++i) {
|
||||
SoundFx *sfx = &_sfxList[i];
|
||||
if (sfx->len == 0) {
|
||||
continue;
|
||||
}
|
||||
f.seek(sfx->offset);
|
||||
uint8 *data = (uint8 *)malloc(sfx->len * 2);
|
||||
if (!data) {
|
||||
error("Unable to allocate SoundFx data buffer");
|
||||
}
|
||||
sfx->data = data;
|
||||
uint8 c = f.readByte();
|
||||
*data++ = c;
|
||||
*data++ = c;
|
||||
uint16 sz = sfx->len - 1;
|
||||
while (sz--) {
|
||||
uint8 d = f.readByte();
|
||||
c += fibonacciTable[d >> 4];
|
||||
*data++ = c;
|
||||
c += fibonacciTable[d & 15];
|
||||
*data++ = c;
|
||||
}
|
||||
sfx->len *= 2;
|
||||
}
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_MAP_menu(const char *fileName, uint8 *dstPtr) {
|
||||
debug(DBG_RES, "Resource::load_MAP_menu('%s')", fileName);
|
||||
sprintf(_entryName, "%s.MAP", fileName);
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
if (f.size() != 0x3800 * 4) {
|
||||
error("Wrong file size for '%s', %d", _entryName, f.size());
|
||||
}
|
||||
f.read(dstPtr, 0x3800 * 4);
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_PAL_menu(const char *fileName, uint8 *dstPtr) {
|
||||
debug(DBG_RES, "Resource::load_PAL_menu('%s')", fileName);
|
||||
sprintf(_entryName, "%s.PAL", fileName);
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
if (f.size() != 768) {
|
||||
error("Wrong file size for '%s', %d", _entryName, f.size());
|
||||
}
|
||||
f.read(dstPtr, 768);
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_SPR_OFF(const char *fileName, uint8 *sprData) {
|
||||
debug(DBG_RES, "Resource::load_SPR_OFF('%s')", fileName);
|
||||
sprintf(_entryName, "%s.OFF", fileName);
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
int len = f.size();
|
||||
uint8 *offData = (uint8 *)malloc(len);
|
||||
if (!offData) {
|
||||
error("Unable to allocate sprite offsets");
|
||||
}
|
||||
f.read(offData, len);
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
const uint8 *p = offData;
|
||||
uint16 pos;
|
||||
while ((pos = READ_LE_UINT16(p)) != 0xFFFF) {
|
||||
uint32 off = READ_LE_UINT32(p + 2);
|
||||
if (off == 0xFFFFFFFF) {
|
||||
_spr_off[pos] = 0;
|
||||
} else {
|
||||
_spr_off[pos] = sprData + off;
|
||||
}
|
||||
p += 6;
|
||||
}
|
||||
free(offData);
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_CINE() {
|
||||
const char *baseName = 0;
|
||||
switch (_ver) {
|
||||
case VER_FR:
|
||||
baseName = "FR_CINE";
|
||||
break;
|
||||
case VER_EN:
|
||||
baseName = "ENGCINE";
|
||||
break;
|
||||
case VER_DE:
|
||||
baseName = "GERCINE";
|
||||
break;
|
||||
case VER_SP:
|
||||
baseName = "SPACINE";
|
||||
break;
|
||||
}
|
||||
debug(DBG_RES, "Resource::load_CINE('%s')", baseName);
|
||||
if (_cine_off == 0) {
|
||||
sprintf(_entryName, "%s.BIN", baseName);
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
int len = f.size();
|
||||
_cine_off = (uint8 *)malloc(len);
|
||||
if (!_cine_off) {
|
||||
error("Unable to allocate cinematics offsets");
|
||||
}
|
||||
f.read(_cine_off, len);
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
if (_cine_txt == 0) {
|
||||
sprintf(_entryName, "%s.TXT", baseName);
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
int len = f.size();
|
||||
_cine_txt = (uint8 *)malloc(len);
|
||||
if (!_cine_txt) {
|
||||
error("Unable to allocate cinematics text data");
|
||||
}
|
||||
f.read(_cine_txt, len);
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_TEXT() {
|
||||
File f;
|
||||
// Load game strings
|
||||
_stringsTable = 0;
|
||||
if (f.open("STRINGS.TXT", _dataPath, "rb")) {
|
||||
const int sz = f.size();
|
||||
_extStringsTable = (uint8 *)malloc(sz);
|
||||
if (_extStringsTable) {
|
||||
f.read(_extStringsTable, sz);
|
||||
_stringsTable = _extStringsTable;
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
if (!_stringsTable) {
|
||||
switch (_ver) {
|
||||
case VER_FR:
|
||||
_stringsTable = LocaleData::_stringsTableFR;
|
||||
break;
|
||||
case VER_EN:
|
||||
_stringsTable = LocaleData::_stringsTableEN;
|
||||
break;
|
||||
case VER_DE:
|
||||
_stringsTable = LocaleData::_stringsTableDE;
|
||||
break;
|
||||
case VER_SP:
|
||||
_stringsTable = LocaleData::_stringsTableSP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Load menu strings
|
||||
_textsTable = 0;
|
||||
if (f.open("MENUS.TXT", _dataPath, "rb")) {
|
||||
const int offs = LocaleData::LI_NUM * sizeof(char *);
|
||||
const int sz = f.size() + 1;
|
||||
_extTextsTable = (char **)malloc(offs + sz);
|
||||
if (_extTextsTable) {
|
||||
char *textData = (char *)_extTextsTable + offs;
|
||||
f.read(textData, sz);
|
||||
textData[sz] = 0;
|
||||
int textsCount = 0;
|
||||
for (char *eol; (eol = strpbrk(textData, "\r\n")) != 0; ) {
|
||||
*eol++ = 0;
|
||||
if (*eol == '\r' || *eol == '\n') {
|
||||
*eol++ = 0;
|
||||
}
|
||||
if (textsCount < LocaleData::LI_NUM && textData[0] != 0) {
|
||||
_extTextsTable[textsCount] = textData;
|
||||
++textsCount;
|
||||
}
|
||||
textData = eol;
|
||||
}
|
||||
if (textsCount < LocaleData::LI_NUM && textData[0] != 0) {
|
||||
_extTextsTable[textsCount] = textData;
|
||||
++textsCount;
|
||||
}
|
||||
if (textsCount < LocaleData::LI_NUM) {
|
||||
free(_extTextsTable);
|
||||
_extTextsTable = 0;
|
||||
} else {
|
||||
_textsTable = (const char **)_extTextsTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!_textsTable) {
|
||||
switch (_ver) {
|
||||
case VER_FR:
|
||||
_textsTable = LocaleData::_textsTableFR;
|
||||
break;
|
||||
case VER_EN:
|
||||
_textsTable = LocaleData::_textsTableEN;
|
||||
break;
|
||||
case VER_DE:
|
||||
_textsTable = LocaleData::_textsTableDE;
|
||||
break;
|
||||
case VER_SP:
|
||||
_textsTable = LocaleData::_textsTableSP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::free_TEXT() {
|
||||
if (_extTextsTable) {
|
||||
free(_extTextsTable);
|
||||
_extTextsTable = 0;
|
||||
}
|
||||
_stringsTable = 0;
|
||||
if (_extStringsTable) {
|
||||
free(_extStringsTable);
|
||||
_extStringsTable = 0;
|
||||
}
|
||||
_textsTable = 0;
|
||||
}
|
||||
|
||||
void Resource::load(const char *objName, int objType) {
|
||||
debug(DBG_RES, "Resource::load('%s', %d)", objName, objType);
|
||||
LoadStub loadStub = 0;
|
||||
switch (objType) {
|
||||
case OT_MBK:
|
||||
debug(DBG_RES, "chargement bank (mbk)");
|
||||
sprintf(_entryName, "%s.MBK", objName);
|
||||
loadStub = &Resource::load_MBK;
|
||||
break;
|
||||
case OT_PGE:
|
||||
debug(DBG_RES, "chargement piege (pge)");
|
||||
sprintf(_entryName, "%s.PGE", objName);
|
||||
loadStub = &Resource::load_PGE;
|
||||
break;
|
||||
case OT_PAL:
|
||||
debug(DBG_RES, "chargement palettes (pal)");
|
||||
sprintf(_entryName, "%s.PAL", objName);
|
||||
loadStub = &Resource::load_PAL;
|
||||
break;
|
||||
case OT_CT:
|
||||
debug(DBG_RES, "chargement collision (ct)");
|
||||
sprintf(_entryName, "%s.CT", objName);
|
||||
loadStub = &Resource::load_CT;
|
||||
break;
|
||||
case OT_MAP:
|
||||
debug(DBG_RES, "ouverture map (map)");
|
||||
sprintf(_entryName, "%s.MAP", objName);
|
||||
loadStub = &Resource::load_MAP;
|
||||
break;
|
||||
case OT_SPC:
|
||||
debug(DBG_RES, "chargement sprites caracteres (spc)");
|
||||
strcpy(_entryName, "GLOBAL.SPC");
|
||||
loadStub = &Resource::load_SPC;
|
||||
break;
|
||||
case OT_RP:
|
||||
debug(DBG_RES, "chargement positions des banks pour sprite_car (rp)");
|
||||
sprintf(_entryName, "%s.RP", objName);
|
||||
loadStub = &Resource::load_RP;
|
||||
break;
|
||||
case OT_SPR:
|
||||
debug(DBG_RES, "chargement des sprites (spr)");
|
||||
sprintf(_entryName, "%s.SPR", objName);
|
||||
loadStub = &Resource::load_SPR;
|
||||
break;
|
||||
case OT_SPRM:
|
||||
debug(DBG_RES, "chargement des sprites monstre (spr)");
|
||||
sprintf(_entryName, "%s.SPR", objName);
|
||||
loadStub = &Resource::load_SPRM;
|
||||
break;
|
||||
case OT_ICN:
|
||||
debug(DBG_RES, "chargement des icones (icn)");
|
||||
sprintf(_entryName, "%s.ICN", objName);
|
||||
loadStub = &Resource::load_ICN;
|
||||
break;
|
||||
case OT_FNT:
|
||||
debug(DBG_RES, "chargement de la font (fnt)");
|
||||
sprintf(_entryName, "%s.FNT", objName);
|
||||
loadStub = &Resource::load_FNT;
|
||||
break;
|
||||
case OT_OBJ:
|
||||
debug(DBG_RES, "chargement objets (obj)");
|
||||
sprintf(_entryName, "%s.OBJ", objName);
|
||||
loadStub = &Resource::load_OBJ;
|
||||
break;
|
||||
case OT_ANI:
|
||||
debug(DBG_RES, "chargement animations (ani)");
|
||||
sprintf(_entryName, "%s.ANI", objName);
|
||||
loadStub = &Resource::load_ANI;
|
||||
break;
|
||||
case OT_TBN:
|
||||
debug(DBG_RES, "chargement des textes (tbn)");
|
||||
sprintf(_entryName, "%s.TBN", objName);
|
||||
loadStub = &Resource::load_TBN;
|
||||
break;
|
||||
case OT_CMD:
|
||||
debug(DBG_RES, "chargement des commandes (cmd)");
|
||||
sprintf(_entryName, "%s.CMD", objName);
|
||||
loadStub = &Resource::load_CMD;
|
||||
break;
|
||||
case OT_POL:
|
||||
debug(DBG_RES, "chargement des polygones (pol)");
|
||||
sprintf(_entryName, "%s.POL", objName);
|
||||
loadStub = &Resource::load_POL;
|
||||
break;
|
||||
default:
|
||||
error("Unimplemented Resource::load() type %d", objType);
|
||||
break;
|
||||
}
|
||||
if (loadStub) {
|
||||
File f;
|
||||
if (f.open(_entryName, _dataPath, "rb")) {
|
||||
(this->*loadStub)(&f);
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
}
|
||||
} else {
|
||||
error("Can't open '%s'", _entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_CT(File *pf) {
|
||||
debug(DBG_RES, "Resource::load_CT()");
|
||||
int len = pf->size();
|
||||
uint8 *tmp = (uint8 *)malloc(len);
|
||||
if (!tmp) {
|
||||
error("Unable to allocate CT buffer");
|
||||
} else {
|
||||
pf->read(tmp, len);
|
||||
if (!delphine_unpack((uint8 *)_ctData, tmp, len)) {
|
||||
error("Bad CRC for collision data");
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_FNT(File *f) {
|
||||
debug(DBG_RES, "Resource::load_FNT()");
|
||||
int len = f->size();
|
||||
_fnt = (uint8 *)malloc(len);
|
||||
if (!_fnt) {
|
||||
error("Unable to allocate FNT buffer");
|
||||
} else {
|
||||
f->read(_fnt, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_MBK(File *f) {
|
||||
debug(DBG_RES, "Resource::load_MBK()");
|
||||
uint8 num = f->readByte();
|
||||
int dataSize = f->size() - num * 6;
|
||||
_mbk = (MbkEntry *)malloc(sizeof(MbkEntry) * num);
|
||||
if (!_mbk) {
|
||||
error("Unable to allocate MBK buffer");
|
||||
}
|
||||
f->seek(0);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
f->readUint16BE(); /* unused */
|
||||
_mbk[i].offset = f->readUint16BE() - num * 6;
|
||||
_mbk[i].len = f->readUint16BE();
|
||||
debug(DBG_RES, "dataSize=0x%X entry %d off=0x%X len=0x%X", dataSize, i, _mbk[i].offset + num * 6, _mbk[i].len);
|
||||
assert(_mbk[i].offset <= dataSize);
|
||||
}
|
||||
_mbkData = (uint8 *)malloc(dataSize);
|
||||
if (!_mbkData) {
|
||||
error("Unable to allocate MBK data buffer");
|
||||
}
|
||||
f->read(_mbkData, dataSize);
|
||||
}
|
||||
|
||||
void Resource::load_ICN(File *f) {
|
||||
debug(DBG_RES, "Resource::load_ICN()");
|
||||
int len = f->size();
|
||||
_icn = (uint8 *)malloc(len);
|
||||
if (!_icn) {
|
||||
error("Unable to allocate ICN buffer");
|
||||
} else {
|
||||
f->read(_icn, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_SPR(File *f) {
|
||||
debug(DBG_RES, "Resource::load_SPR()");
|
||||
int len = f->size() - 12;
|
||||
_spr1 = (uint8 *)malloc(len);
|
||||
if (!_spr1) {
|
||||
error("Unable to allocate SPR buffer");
|
||||
} else {
|
||||
f->seek(12);
|
||||
f->read(_spr1, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_SPRM(File *f) {
|
||||
debug(DBG_RES, "Resource::load_SPRM()");
|
||||
int len = f->size() - 12;
|
||||
f->seek(12);
|
||||
f->read(_sprm, len);
|
||||
}
|
||||
|
||||
void Resource::load_RP(File *f) {
|
||||
debug(DBG_RES, "Resource::load_RP()");
|
||||
f->read(_rp, 0x4A);
|
||||
}
|
||||
|
||||
void Resource::load_SPC(File *f) {
|
||||
debug(DBG_RES, "Resource::load_SPC()");
|
||||
int len = f->size();
|
||||
_spc = (uint8 *)malloc(len);
|
||||
if (!_spc) {
|
||||
error("Unable to allocate SPC buffer");
|
||||
} else {
|
||||
f->read(_spc, len);
|
||||
_numSpc = READ_BE_UINT16(_spc) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_PAL(File *f) {
|
||||
debug(DBG_RES, "Resource::load_PAL()");
|
||||
int len = f->size();
|
||||
_pal = (uint8 *)malloc(len);
|
||||
if (!_pal) {
|
||||
error("Unable to allocate PAL buffer");
|
||||
} else {
|
||||
f->read(_pal, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_MAP(File *f) {
|
||||
debug(DBG_RES, "Resource::load_MAP()");
|
||||
int len = f->size();
|
||||
_map = (uint8 *)malloc(len);
|
||||
if (!_map) {
|
||||
error("Unable to allocate MAP buffer");
|
||||
} else {
|
||||
f->read(_map, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_OBJ(File *f) {
|
||||
debug(DBG_RES, "Resource::load_OBJ()");
|
||||
|
||||
uint16 i;
|
||||
|
||||
_numObjectNodes = f->readUint16LE();
|
||||
assert(_numObjectNodes < 255);
|
||||
|
||||
uint32 offsets[256];
|
||||
for (i = 0; i < _numObjectNodes; ++i) {
|
||||
offsets[i] = f->readUint32LE();
|
||||
}
|
||||
offsets[i] = f->size() - 2;
|
||||
|
||||
int numObjectsCount = 0;
|
||||
uint16 objectsCount[256];
|
||||
for (i = 0; i < _numObjectNodes; ++i) {
|
||||
int diff = offsets[i + 1] - offsets[i];
|
||||
if (diff != 0) {
|
||||
objectsCount[numObjectsCount] = (diff - 2) / 0x12;
|
||||
debug(DBG_RES, "i=%d objectsCount[numObjectsCount]=%d", i, objectsCount[numObjectsCount]);
|
||||
++numObjectsCount;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 prevOffset = 0;
|
||||
ObjectNode *prevNode = 0;
|
||||
int iObj = 0;
|
||||
for (i = 0; i < _numObjectNodes; ++i) {
|
||||
if (prevOffset != offsets[i]) {
|
||||
ObjectNode *on = (ObjectNode *)malloc(sizeof(ObjectNode));
|
||||
if (!on) {
|
||||
error("Unable to allocate ObjectNode num=%d", i);
|
||||
}
|
||||
f->seek(offsets[i] + 2);
|
||||
on->last_obj_number = f->readUint16LE();
|
||||
on->num_objects = objectsCount[iObj];
|
||||
debug(DBG_RES, "last=%d num=%d", on->last_obj_number, on->num_objects);
|
||||
on->objects = (Object *)malloc(sizeof(Object) * on->num_objects);
|
||||
for (uint16 j = 0; j < on->num_objects; ++j) {
|
||||
Object *obj = &on->objects[j];
|
||||
obj->type = f->readUint16LE();
|
||||
obj->dx = f->readByte();
|
||||
obj->dy = f->readByte();
|
||||
obj->init_obj_type = f->readUint16LE();
|
||||
obj->opcode2 = f->readByte();
|
||||
obj->opcode1 = f->readByte();
|
||||
obj->flags = f->readByte();
|
||||
obj->opcode3 = f->readByte();
|
||||
obj->init_obj_number = f->readUint16LE();
|
||||
obj->opcode_arg1 = f->readUint16LE();
|
||||
obj->opcode_arg2 = f->readUint16LE();
|
||||
obj->opcode_arg3 = f->readUint16LE();
|
||||
debug(DBG_RES, "obj_node=%d obj=%d op1=0x%X op2=0x%X op3=0x%X", i, j, obj->opcode2, obj->opcode1, obj->opcode3);
|
||||
}
|
||||
++iObj;
|
||||
prevOffset = offsets[i];
|
||||
prevNode = on;
|
||||
}
|
||||
_objectNodesMap[i] = prevNode;
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::free_OBJ() {
|
||||
debug(DBG_RES, "Resource::free_OBJ()");
|
||||
ObjectNode *prevNode = 0;
|
||||
for (int i = 0; i < _numObjectNodes; ++i) {
|
||||
if (_objectNodesMap[i] != prevNode) {
|
||||
ObjectNode *curNode = _objectNodesMap[i];
|
||||
free(curNode->objects);
|
||||
_objectNodesMap[i] = 0;
|
||||
prevNode = curNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_PGE(File *f) {
|
||||
debug(DBG_RES, "Resource::load_PGE()");
|
||||
int len = f->size() - 2;
|
||||
_pgeNum = f->readUint16LE();
|
||||
memset(_pgeInit, 0, sizeof(_pgeInit));
|
||||
debug(DBG_RES, "len=%d _pgeNum=%d", len, _pgeNum);
|
||||
for (uint16 i = 0; i < _pgeNum; ++i) {
|
||||
InitPGE *pge = &_pgeInit[i];
|
||||
pge->type = f->readUint16LE();
|
||||
pge->pos_x = f->readUint16LE();
|
||||
pge->pos_y = f->readUint16LE();
|
||||
pge->obj_node_number = f->readUint16LE();
|
||||
pge->life = f->readUint16LE();
|
||||
for (int lc = 0; lc < 4; ++lc) {
|
||||
pge->counter_values[lc] = f->readUint16LE();
|
||||
}
|
||||
pge->object_type = f->readByte();
|
||||
pge->init_room = f->readByte();
|
||||
pge->room_location = f->readByte();
|
||||
pge->init_flags = f->readByte();
|
||||
pge->colliding_icon_num = f->readByte();
|
||||
pge->icon_num = f->readByte();
|
||||
pge->object_id = f->readByte();
|
||||
pge->skill = f->readByte();
|
||||
pge->mirror_x = f->readByte();
|
||||
pge->flags = f->readByte();
|
||||
pge->unk1C = f->readByte();
|
||||
f->readByte();
|
||||
pge->text_num = f->readByte();
|
||||
f->readByte();
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_ANI(File *f) {
|
||||
debug(DBG_RES, "Resource::load_ANI()");
|
||||
int size = f->size() - 2;
|
||||
_ani = (uint8 *)malloc(size);
|
||||
if (!_ani) {
|
||||
error("Unable to allocate ANI buffer");
|
||||
} else {
|
||||
f->seek(2);
|
||||
f->read(_ani, size);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_TBN(File *f) {
|
||||
debug(DBG_RES, "Resource::load_TBN()");
|
||||
int len = f->size();
|
||||
_tbn = (uint8 *)malloc(len);
|
||||
if (!_tbn) {
|
||||
error("Unable to allocate TBN buffer");
|
||||
} else {
|
||||
f->read(_tbn, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_CMD(File *pf) {
|
||||
debug(DBG_RES, "Resource::load_CMD()");
|
||||
free(_cmd);
|
||||
int len = pf->size();
|
||||
_cmd = (uint8 *)malloc(len);
|
||||
if (!_cmd) {
|
||||
error("Unable to allocate CMD buffer");
|
||||
} else {
|
||||
pf->read(_cmd, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_POL(File *pf) {
|
||||
debug(DBG_RES, "Resource::load_POL()");
|
||||
free(_pol);
|
||||
int len = pf->size();
|
||||
_pol = (uint8 *)malloc(len);
|
||||
if (!_pol) {
|
||||
error("Unable to allocate POL buffer");
|
||||
} else {
|
||||
pf->read(_pol, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_VCE(int num, int segment, uint8 **buf, uint32 *bufSize) {
|
||||
*buf = 0;
|
||||
int offset = _voicesOffsetsTable[num];
|
||||
if (offset != 0xFFFF) {
|
||||
const uint16 *p = _voicesOffsetsTable + offset / 2;
|
||||
offset = (*p++) * 2048;
|
||||
int count = *p++;
|
||||
if (segment < count) {
|
||||
File f;
|
||||
if (f.open("VOICE.VCE", _dataPath, "rb")) {
|
||||
int voiceSize = p[segment] * 2048 / 5;
|
||||
free(_voiceBuf);
|
||||
_voiceBuf = (uint8 *)malloc(voiceSize);
|
||||
if (_voiceBuf) {
|
||||
uint8 *dst = _voiceBuf;
|
||||
offset += 0x2000;
|
||||
for (int s = 0; s < count; ++s) {
|
||||
int len = p[s] * 2048;
|
||||
for (int i = 0; i < len / (0x2000 + 2048); ++i) {
|
||||
if (s == segment) {
|
||||
f.seek(offset);
|
||||
int n = 2048;
|
||||
while (n--) {
|
||||
int v = f.readByte();
|
||||
if (v & 0x80) {
|
||||
v = -(v & 0x7F);
|
||||
}
|
||||
*dst++ = (uint8)(v & 0xFF);
|
||||
}
|
||||
}
|
||||
offset += 0x2000 + 2048;
|
||||
}
|
||||
if (s == segment) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*buf = _voiceBuf;
|
||||
*bufSize = voiceSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __RESOURCE_H__
|
||||
#define __RESOURCE_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct File;
|
||||
|
||||
struct LocaleData {
|
||||
enum Id {
|
||||
LI_01_CONTINUE_OR_ABORT = 0,
|
||||
LI_02_TIME,
|
||||
LI_03_CONTINUE,
|
||||
LI_04_ABORT,
|
||||
LI_05_COMPLETED,
|
||||
LI_06_LEVEL,
|
||||
LI_07_START,
|
||||
LI_08_SKILL,
|
||||
LI_09_PASSWORD,
|
||||
LI_10_INFO,
|
||||
LI_11_QUIT,
|
||||
LI_12_SKILL_LEVEL,
|
||||
LI_13_EASY,
|
||||
LI_14_NORMAL,
|
||||
LI_15_EXPERT,
|
||||
LI_16_ENTER_PASSWORD1,
|
||||
LI_17_ENTER_PASSWORD2,
|
||||
LI_18_RESUME_GAME,
|
||||
LI_19_ABORT_GAME,
|
||||
LI_20_LOAD_GAME,
|
||||
LI_21_SAVE_GAME,
|
||||
LI_22_SAVE_SLOT,
|
||||
|
||||
LI_NUM
|
||||
};
|
||||
|
||||
static const char *_textsTableFR[];
|
||||
static const char *_textsTableEN[];
|
||||
static const char *_textsTableDE[];
|
||||
static const char *_textsTableSP[];
|
||||
static const uint8 _stringsTableFR[];
|
||||
static const uint8 _stringsTableEN[];
|
||||
static const uint8 _stringsTableDE[];
|
||||
static const uint8 _stringsTableSP[];
|
||||
};
|
||||
|
||||
struct Resource {
|
||||
typedef void (Resource::*LoadStub)(File *);
|
||||
|
||||
enum ObjectType {
|
||||
OT_MBK = 0x00,
|
||||
OT_PGE = 0x01,
|
||||
OT_PAL = 0x02,
|
||||
OT_CT = 0x03,
|
||||
OT_MAP = 0x04,
|
||||
OT_SGD = 0x05,
|
||||
OT_SPC = 0x06,
|
||||
OT_RP = 0x07,
|
||||
OT_DEMO = 0x08,
|
||||
OT_ANI = 0x09,
|
||||
OT_OBJ = 0x0A,
|
||||
OT_TBN = 0x0B,
|
||||
OT_SPR = 0x0C,
|
||||
OT_TAB = 0x0D,
|
||||
OT_ICN = 0x0E,
|
||||
OT_FNT = 0x0F,
|
||||
OT_TXTBIN = 0x10,
|
||||
OT_CMD = 0x11,
|
||||
OT_POL = 0x12,
|
||||
OT_SPRM = 0x13,
|
||||
OT_OFF = 0x14,
|
||||
|
||||
OT_NUM = 0x15
|
||||
};
|
||||
|
||||
static const uint16 _voicesOffsetsTable[];
|
||||
|
||||
const char *_dataPath;
|
||||
Version _ver;
|
||||
char _entryName[30];
|
||||
uint8 *_fnt;
|
||||
MbkEntry *_mbk;
|
||||
uint8 *_mbkData;
|
||||
uint8 *_icn;
|
||||
uint8 *_tab;
|
||||
uint8 *_spc; // BE
|
||||
uint16 _numSpc;
|
||||
uint8 _rp[0x4A];
|
||||
uint8 *_pal; // BE
|
||||
uint8 *_ani;
|
||||
uint8 *_tbn;
|
||||
int8 _ctData[0x1D00];
|
||||
uint8 *_spr1;
|
||||
uint8 *_spr_off[1287]; // 0-0x22F + 0x28E-0x2E9 ... conrad, 0x22F-0x28D : junkie
|
||||
uint8 _sprm[0x8411]; // MERCENAI.SPR size
|
||||
uint16 _pgeNum;
|
||||
InitPGE _pgeInit[256];
|
||||
uint8 *_map;
|
||||
uint16 _numObjectNodes;
|
||||
ObjectNode *_objectNodesMap[255];
|
||||
uint8 *_memBuf;
|
||||
SoundFx *_sfxList;
|
||||
uint8 _numSfx;
|
||||
uint8 *_cmd;
|
||||
uint8 *_pol;
|
||||
uint8 *_cine_off;
|
||||
uint8 *_cine_txt;
|
||||
uint8 *_voiceBuf;
|
||||
char **_extTextsTable;
|
||||
const char **_textsTable;
|
||||
uint8 *_extStringsTable;
|
||||
const uint8 *_stringsTable;
|
||||
|
||||
Resource(const char *dataPath, Version ver);
|
||||
~Resource();
|
||||
|
||||
void clearLevelRes();
|
||||
void load_FIB(const char *fileName);
|
||||
void load_MAP_menu(const char *fileName, uint8 *dstPtr);
|
||||
void load_PAL_menu(const char *fileName, uint8 *dstPtr);
|
||||
void load_SPR_OFF(const char *fileName, uint8 *sprData);
|
||||
void load_CINE();
|
||||
void load_TEXT();
|
||||
void free_TEXT();
|
||||
void load(const char *objName, int objType);
|
||||
void load_CT(File *pf);
|
||||
void load_FNT(File *pf);
|
||||
void load_MBK(File *pf);
|
||||
void load_ICN(File *pf);
|
||||
void load_SPR(File *pf);
|
||||
void load_SPRM(File *pf);
|
||||
void load_RP(File *pf);
|
||||
void load_SPC(File *pf);
|
||||
void load_PAL(File *pf);
|
||||
void load_MAP(File *pf);
|
||||
void load_OBJ(File *pf);
|
||||
void free_OBJ();
|
||||
void load_PGE(File *pf);
|
||||
void load_ANI(File *pf);
|
||||
void load_TBN(File *pf);
|
||||
void load_CMD(File *pf);
|
||||
void load_POL(File *pf);
|
||||
void load_VCE(int num, int segment, uint8 **buf, uint32 *bufSize);
|
||||
const uint8 *getGameString(int num) {
|
||||
return _stringsTable + READ_LE_UINT16(_stringsTable + num * 2);
|
||||
}
|
||||
const char *getMenuString(int num) {
|
||||
return (num >= 0 && num < LocaleData::LI_NUM) ? _textsTable[num] : "";
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __RESOURCE_H__
|
||||
@@ -1,142 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "scaler.h"
|
||||
|
||||
|
||||
const Scaler _scalers[] = {
|
||||
{ "point1x", &point1x, 1 },
|
||||
{ "point2x", &point2x, 2 },
|
||||
{ "scale2x", &scale2x, 2 },
|
||||
{ "point3x", &point3x, 3 },
|
||||
{ "scale3x", &scale3x, 3 }
|
||||
};
|
||||
|
||||
void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
|
||||
dstPitch >>= 1;
|
||||
while (h--) {
|
||||
memcpy(dst, src, w * 2);
|
||||
dst += dstPitch;
|
||||
src += srcPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
|
||||
dstPitch >>= 1;
|
||||
while (h--) {
|
||||
uint16 *p = dst;
|
||||
for (int i = 0; i < w; ++i, p += 2) {
|
||||
uint16 c = *(src + i);
|
||||
*(p) = c;
|
||||
*(p + 1) = c;
|
||||
*(p + dstPitch) = c;
|
||||
*(p + dstPitch + 1) = c;
|
||||
}
|
||||
dst += dstPitch * 2;
|
||||
src += srcPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
|
||||
dstPitch >>= 1;
|
||||
while (h--) {
|
||||
uint16 *p = dst;
|
||||
for (int i = 0; i < w; ++i, p += 3) {
|
||||
uint16 c = *(src + i);
|
||||
*(p) = c;
|
||||
*(p + 1) = c;
|
||||
*(p + 2) = c;
|
||||
*(p + dstPitch) = c;
|
||||
*(p + dstPitch + 1) = c;
|
||||
*(p + dstPitch + 2) = c;
|
||||
*(p + 2 * dstPitch) = c;
|
||||
*(p + 2 * dstPitch + 1) = c;
|
||||
*(p + 2 * dstPitch + 2) = c;
|
||||
}
|
||||
dst += dstPitch * 3;
|
||||
src += srcPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void scale2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
|
||||
dstPitch >>= 1;
|
||||
while (h--) {
|
||||
uint16 *p = dst;
|
||||
for (int i = 0; i < w; ++i, p += 2) {
|
||||
uint16 B = *(src + i - srcPitch);
|
||||
uint16 D = *(src + i - 1);
|
||||
uint16 E = *(src + i);
|
||||
uint16 F = *(src + i + 1);
|
||||
uint16 H = *(src + i + srcPitch);
|
||||
if (B != H && D != F) {
|
||||
*(p) = D == B ? D : E;
|
||||
*(p + 1) = B == F ? F : E;
|
||||
*(p + dstPitch) = D == H ? D : E;
|
||||
*(p + dstPitch + 1) = H == F ? F : E;
|
||||
} else {
|
||||
*(p) = E;
|
||||
*(p + 1) = E;
|
||||
*(p + dstPitch) = E;
|
||||
*(p + dstPitch + 1) = E;
|
||||
}
|
||||
}
|
||||
dst += dstPitch * 2;
|
||||
src += srcPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void scale3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
|
||||
dstPitch >>= 1;
|
||||
while (h--) {
|
||||
uint16 *p = dst;
|
||||
for (int i = 0; i < w; ++i, p += 3) {
|
||||
uint16 A = *(src + i - srcPitch - 1);
|
||||
uint16 B = *(src + i - srcPitch);
|
||||
uint16 C = *(src + i - srcPitch + 1);
|
||||
uint16 D = *(src + i - 1);
|
||||
uint16 E = *(src + i);
|
||||
uint16 F = *(src + i + 1);
|
||||
uint16 G = *(src + i + srcPitch - 1);
|
||||
uint16 H = *(src + i + srcPitch);
|
||||
uint16 I = *(src + i + srcPitch + 1);
|
||||
if (B != H && D != F) {
|
||||
*(p) = D == B ? D : E;
|
||||
*(p + 1) = (D == B && E != C) || (B == F && E != A) ? B : E;
|
||||
*(p + 2) = B == F ? F : E;
|
||||
*(p + dstPitch) = (D == B && E != G) || (D == B && E != A) ? D : E;
|
||||
*(p + dstPitch + 1) = E;
|
||||
*(p + dstPitch + 2) = (B == F && E != I) || (H == F && E != C) ? F : E;
|
||||
*(p + 2 * dstPitch) = D == H ? D : E;
|
||||
*(p + 2 * dstPitch + 1) = (D == H && E != I) || (H == F && E != G) ? H : E;
|
||||
*(p + 2 * dstPitch + 2) = H == F ? F : E;
|
||||
} else {
|
||||
*(p) = E;
|
||||
*(p + 1) = E;
|
||||
*(p + 2) = E;
|
||||
*(p + dstPitch) = E;
|
||||
*(p + dstPitch + 1) = E;
|
||||
*(p + dstPitch + 2) = E;
|
||||
*(p + 2 * dstPitch) = E;
|
||||
*(p + 2 * dstPitch + 1) = E;
|
||||
*(p + 2 * dstPitch + 2) = E;
|
||||
}
|
||||
}
|
||||
dst += dstPitch * 3;
|
||||
src += srcPitch;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SCALER_H__
|
||||
#define __SCALER_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
typedef void (*ScaleProc)(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
|
||||
|
||||
enum {
|
||||
NUM_SCALERS = 5
|
||||
};
|
||||
|
||||
struct Scaler {
|
||||
const char *name;
|
||||
ScaleProc proc;
|
||||
uint8 factor;
|
||||
};
|
||||
|
||||
extern const Scaler _scalers[];
|
||||
|
||||
void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
|
||||
void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
|
||||
void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
|
||||
void scale2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
|
||||
void scale3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
|
||||
|
||||
#endif // __SCALER_H__
|
||||
@@ -1,185 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "mixer.h"
|
||||
#include "sfx_player.h"
|
||||
|
||||
|
||||
SfxPlayer::SfxPlayer(Mixer *mixer)
|
||||
: _mod(0), _playing(false), _mix(mixer) {
|
||||
}
|
||||
|
||||
void SfxPlayer::play(uint8 num) {
|
||||
debug(DBG_SFX, "SfxPlayer::play(%d)", num);
|
||||
if (!_playing) {
|
||||
if (num >= 68 && num <= 75) {
|
||||
static const Module *modTable[] = {
|
||||
&_module68, &_module68, &_module70, &_module70,
|
||||
&_module72, &_module73, &_module74, &_module75
|
||||
};
|
||||
_mod = modTable[num - 68];
|
||||
_curOrder = 0;
|
||||
_numOrders = READ_BE_UINT16(_mod->moduleData);
|
||||
_orderDelay = 0;
|
||||
_modData = _mod->moduleData + 0x22;
|
||||
memset(_samples, 0, sizeof(_samples));
|
||||
_samplesLeft = 0;
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
_playing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SfxPlayer::stop() {
|
||||
if (_playing) {
|
||||
_mix->setPremixHook(0, 0);
|
||||
_playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SfxPlayer::playSample(int channel, const uint8 *sampleData, uint16 period) {
|
||||
assert(channel < NUM_CHANNELS);
|
||||
SampleInfo *si = &_samples[channel];
|
||||
si->len = READ_BE_UINT16(sampleData); sampleData += 2;
|
||||
si->vol = READ_BE_UINT16(sampleData); sampleData += 2;
|
||||
si->loopPos = READ_BE_UINT16(sampleData); sampleData += 2;
|
||||
si->loopLen = READ_BE_UINT16(sampleData); sampleData += 2;
|
||||
si->freq = PAULA_FREQ / period;
|
||||
si->pos = 0;
|
||||
si->data = sampleData;
|
||||
}
|
||||
|
||||
void SfxPlayer::handleTick() {
|
||||
if (!_playing) {
|
||||
return;
|
||||
}
|
||||
if (_orderDelay != 0) {
|
||||
--_orderDelay;
|
||||
// check for end of song
|
||||
if (_orderDelay == 0 && _modData == 0) {
|
||||
_playing = false;
|
||||
}
|
||||
} else {
|
||||
_orderDelay = READ_BE_UINT16(_mod->moduleData + 2);
|
||||
debug(DBG_SFX, "curOrder=%d/%d _orderDelay=%d\n", _curOrder, _numOrders, _orderDelay);
|
||||
int16 period = 0;
|
||||
for (int ch = 0; ch < 3; ++ch) {
|
||||
const uint8 *sampleData = 0;
|
||||
uint8 b = *_modData++;
|
||||
if (b != 0) {
|
||||
--b;
|
||||
assert(b < 5);
|
||||
period = READ_BE_UINT16(_mod->moduleData + 4 + b * 2);
|
||||
sampleData = _mod->sampleData[b];
|
||||
}
|
||||
b = *_modData++;
|
||||
if (b != 0) {
|
||||
int16 per = period + (b - 1);
|
||||
if (per >= 0 && per < 40) {
|
||||
per = _periodTable[per];
|
||||
} else if (per == -3) {
|
||||
per = 0xA0;
|
||||
} else {
|
||||
per = 0x71;
|
||||
}
|
||||
playSample(ch, sampleData, per);
|
||||
}
|
||||
}
|
||||
++_curOrder;
|
||||
if (_curOrder >= _numOrders) {
|
||||
debug(DBG_SFX, "End of song");
|
||||
_orderDelay += 20;
|
||||
_modData = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void addclamp(int16& a, int b) {
|
||||
int add = a + b;
|
||||
if (add < -32767) {
|
||||
add = -32767;
|
||||
} else if (add > 32767) {
|
||||
add = 32767;
|
||||
}
|
||||
a = add;
|
||||
}
|
||||
|
||||
void SfxPlayer::mixSamples(int16 *buf, int samplesLen) {
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
SampleInfo *si = &_samples[i];
|
||||
if (si->data) {
|
||||
int16 *mixbuf = buf;
|
||||
int len = si->len << FRAC_BITS;
|
||||
int loopLen = si->loopLen << FRAC_BITS;
|
||||
int loopPos = si->loopPos << FRAC_BITS;
|
||||
int deltaPos = (si->freq << FRAC_BITS) / _mix->getSampleRate();
|
||||
int curLen = samplesLen;
|
||||
int pos = si->pos;
|
||||
while (curLen != 0) {
|
||||
int count;
|
||||
if (loopLen > (2 << FRAC_BITS)) {
|
||||
assert(si->loopPos + si->loopLen <= si->len);
|
||||
if (pos >= loopPos + loopLen) {
|
||||
pos -= loopLen;
|
||||
}
|
||||
count = MIN(curLen, (loopPos + loopLen - pos - 1) / deltaPos + 1);
|
||||
curLen -= count;
|
||||
} else {
|
||||
if (pos >= len) {
|
||||
count = 0;
|
||||
} else {
|
||||
count = MIN(curLen, (len - pos - 1) / deltaPos + 1);
|
||||
}
|
||||
curLen = 0;
|
||||
}
|
||||
while (count--) {
|
||||
int out = resample3Pt(si, pos, deltaPos, FRAC_BITS);
|
||||
addclamp(*mixbuf++, out * Mixer::MIX_AMPLIFICATIION * si->vol / 64);
|
||||
pos += deltaPos;
|
||||
}
|
||||
}
|
||||
si->pos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SfxPlayer::mix(int16 *buf, int len) {
|
||||
if (_playing) {
|
||||
memset(buf, 0, len*2);
|
||||
const int samplesPerTick = _mix->getSampleRate() / 50;
|
||||
while (len != 0) {
|
||||
if (_samplesLeft == 0) {
|
||||
handleTick();
|
||||
_samplesLeft = samplesPerTick;
|
||||
}
|
||||
int count = _samplesLeft;
|
||||
if (count > len) {
|
||||
count = len;
|
||||
}
|
||||
_samplesLeft -= count;
|
||||
len -= count;
|
||||
mixSamples(buf, count);
|
||||
buf += count;
|
||||
}
|
||||
}
|
||||
return _playing;
|
||||
}
|
||||
|
||||
bool SfxPlayer::mixCallback(void *param, int16 *buf, int len) {
|
||||
return ((SfxPlayer *)param)->mix(buf, len);
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SFX_PLAYER_H__
|
||||
#define __SFX_PLAYER_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct Mixer;
|
||||
|
||||
struct SfxPlayer {
|
||||
enum {
|
||||
NUM_SAMPLES = 5,
|
||||
NUM_CHANNELS = 3,
|
||||
FRAC_BITS = 12,
|
||||
PAULA_FREQ = 3546897
|
||||
};
|
||||
|
||||
struct Module {
|
||||
const uint8 *sampleData[NUM_SAMPLES];
|
||||
const uint8 *moduleData;
|
||||
};
|
||||
|
||||
struct SampleInfo {
|
||||
uint16 len;
|
||||
uint16 vol;
|
||||
uint16 loopPos;
|
||||
uint16 loopLen;
|
||||
int freq;
|
||||
int pos;
|
||||
const uint8 *data;
|
||||
|
||||
int8 getPCM(int offset) const {
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
} else if (offset >= (int)len) {
|
||||
offset = len - 1;
|
||||
}
|
||||
return (int8)data[offset];
|
||||
}
|
||||
};
|
||||
|
||||
static const uint8 _musicData68[];
|
||||
static const uint8 _musicData70[];
|
||||
static const uint8 _musicData72[];
|
||||
static const uint8 _musicData73[];
|
||||
static const uint8 _musicData74[];
|
||||
static const uint8 _musicData75[];
|
||||
static const uint8 _musicDataSample1[];
|
||||
static const uint8 _musicDataSample2[]; // tick
|
||||
static const uint8 _musicDataSample3[]; // bell
|
||||
static const uint8 _musicDataSample4[];
|
||||
static const uint8 _musicDataSample5[];
|
||||
static const uint8 _musicDataSample6[];
|
||||
static const uint8 _musicDataSample7[];
|
||||
static const uint8 _musicDataSample8[];
|
||||
static const Module _module68;
|
||||
static const Module _module70;
|
||||
static const Module _module72;
|
||||
static const Module _module73;
|
||||
static const Module _module74;
|
||||
static const Module _module75;
|
||||
static const uint16 _periodTable[];
|
||||
|
||||
const Module *_mod;
|
||||
bool _playing;
|
||||
int _samplesLeft;
|
||||
uint16 _curOrder;
|
||||
uint16 _numOrders;
|
||||
uint16 _orderDelay;
|
||||
const uint8 *_modData;
|
||||
SampleInfo _samples[NUM_CHANNELS];
|
||||
Mixer *_mix;
|
||||
|
||||
SfxPlayer(Mixer *mixer);
|
||||
|
||||
void play(uint8 num);
|
||||
void stop();
|
||||
void playSample(int channel, const uint8 *sampleData, uint16 period);
|
||||
void handleTick();
|
||||
bool mix(int16 *buf, int len);
|
||||
void mixSamples(int16 *buf, int samplesLen);
|
||||
|
||||
static bool mixCallback(void *param, int16 *buf, int len);
|
||||
};
|
||||
|
||||
#endif // __SFX_PLAYER_H__
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,49 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SYS_H__
|
||||
#define __SYS_H__
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
typedef unsigned long uint32;
|
||||
typedef signed long int32;
|
||||
|
||||
inline uint16 READ_BE_UINT16(const void *ptr) {
|
||||
const uint8 *b = (const uint8 *)ptr;
|
||||
return (b[0] << 8) | b[1];
|
||||
}
|
||||
|
||||
inline uint32 READ_BE_UINT32(const void *ptr) {
|
||||
const uint8 *b = (const uint8 *)ptr;
|
||||
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
}
|
||||
|
||||
inline uint16 READ_LE_UINT16(const void *ptr) {
|
||||
const uint8 *b = (const uint8 *)ptr;
|
||||
return (b[1] << 8) | b[0];
|
||||
}
|
||||
|
||||
inline uint32 READ_LE_UINT32(const void *ptr) {
|
||||
const uint8 *b = (const uint8 *)ptr;
|
||||
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
|
||||
}
|
||||
|
||||
#endif // __SYS_H__
|
||||
@@ -1,106 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SYSTEMSTUB_H__
|
||||
#define __SYSTEMSTUB_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct PlayerInput {
|
||||
enum {
|
||||
DIR_UP = 1 << 0,
|
||||
DIR_DOWN = 1 << 1,
|
||||
DIR_LEFT = 1 << 2,
|
||||
DIR_RIGHT = 1 << 3
|
||||
};
|
||||
enum {
|
||||
DF_FASTMODE = 1 << 0,
|
||||
DF_DBLOCKS = 1 << 1,
|
||||
DF_SETLIFE = 1 << 2
|
||||
};
|
||||
|
||||
uint8 dirMask;
|
||||
bool enter;
|
||||
bool space;
|
||||
bool shift;
|
||||
bool backspace;
|
||||
bool escape;
|
||||
|
||||
char lastChar;
|
||||
|
||||
bool save;
|
||||
bool load;
|
||||
int stateSlot;
|
||||
|
||||
bool inpRecord;
|
||||
bool inpReplay;
|
||||
|
||||
bool mirrorMode;
|
||||
|
||||
uint8 dbgMask;
|
||||
bool quit;
|
||||
};
|
||||
|
||||
struct SystemStub {
|
||||
typedef void (*AudioCallback)(void *param, uint8 *stream, int len);
|
||||
|
||||
PlayerInput _pi;
|
||||
|
||||
virtual ~SystemStub() {}
|
||||
|
||||
virtual void init(const char *title, uint16 w, uint16 h) = 0;
|
||||
virtual void destroy() = 0;
|
||||
|
||||
virtual void setPalette(const uint8 *pal, uint16 n) = 0;
|
||||
virtual void setPaletteEntry(uint8 i, const Color *c) = 0;
|
||||
virtual void getPaletteEntry(uint8 i, Color *c) = 0;
|
||||
virtual void setOverscanColor(uint8 i) = 0;
|
||||
virtual void copyRect(int16 x, int16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch) = 0;
|
||||
virtual void updateScreen(uint8 shakeOffset) = 0;
|
||||
|
||||
virtual void processEvents() = 0;
|
||||
virtual void sleep(uint32 duration) = 0;
|
||||
virtual uint32 getTimeStamp() = 0;
|
||||
|
||||
virtual void startAudio(AudioCallback callback, void *param) = 0;
|
||||
virtual void stopAudio() = 0;
|
||||
virtual uint32 getOutputSampleRate() = 0;
|
||||
|
||||
virtual void *createMutex() = 0;
|
||||
virtual void destroyMutex(void *mutex) = 0;
|
||||
virtual void lockMutex(void *mutex) = 0;
|
||||
virtual void unlockMutex(void *mutex) = 0;
|
||||
};
|
||||
|
||||
struct MutexStack {
|
||||
SystemStub *_stub;
|
||||
void *_mutex;
|
||||
|
||||
MutexStack(SystemStub *stub, void *mutex)
|
||||
: _stub(stub), _mutex(mutex) {
|
||||
_stub->lockMutex(_mutex);
|
||||
}
|
||||
~MutexStack() {
|
||||
_stub->unlockMutex(_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
extern SystemStub *SystemStub_SDL_create();
|
||||
extern SystemStub *SystemStub_Win32_create();
|
||||
|
||||
#endif // __SYSTEMSTUB_H__
|
||||
@@ -1,582 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
#include "scaler.h"
|
||||
#include "systemstub.h"
|
||||
|
||||
|
||||
struct SystemStub_SDL : SystemStub {
|
||||
enum {
|
||||
MAX_BLIT_RECTS = 200,
|
||||
SOUND_SAMPLE_RATE = 11025,
|
||||
JOYSTICK_COMMIT_VALUE = 3200
|
||||
};
|
||||
|
||||
uint8 *_offscreen;
|
||||
SDL_Surface *_screen;
|
||||
SDL_Surface *_sclscreen;
|
||||
bool _fullscreen;
|
||||
uint8 _scaler;
|
||||
uint8 _overscanColor;
|
||||
uint16 _pal[256];
|
||||
uint16 _screenW, _screenH;
|
||||
SDL_Joystick *_joystick;
|
||||
SDL_Rect _blitRects[MAX_BLIT_RECTS];
|
||||
uint16 _numBlitRects;
|
||||
|
||||
virtual ~SystemStub_SDL() {}
|
||||
virtual void init(const char *title, uint16 w, uint16 h);
|
||||
virtual void destroy();
|
||||
virtual void setPalette(const uint8 *pal, uint16 n);
|
||||
virtual void setPaletteEntry(uint8 i, const Color *c);
|
||||
virtual void getPaletteEntry(uint8 i, Color *c);
|
||||
virtual void setOverscanColor(uint8 i);
|
||||
virtual void copyRect(int16 x, int16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch);
|
||||
virtual void updateScreen(uint8 shakeOffset);
|
||||
virtual void processEvents();
|
||||
virtual void sleep(uint32 duration);
|
||||
virtual uint32 getTimeStamp();
|
||||
virtual void startAudio(AudioCallback callback, void *param);
|
||||
virtual void stopAudio();
|
||||
virtual uint32 getOutputSampleRate();
|
||||
virtual void *createMutex();
|
||||
virtual void destroyMutex(void *mutex);
|
||||
virtual void lockMutex(void *mutex);
|
||||
virtual void unlockMutex(void *mutex);
|
||||
|
||||
void prepareGfxMode();
|
||||
void cleanupGfxMode();
|
||||
void switchGfxMode(bool fullscreen, uint8 scaler);
|
||||
void flipGfx();
|
||||
void forceGfxRedraw();
|
||||
void drawRect(SDL_Rect *rect, uint8 color, uint16 *dst, uint16 dstPitch);
|
||||
};
|
||||
|
||||
SystemStub *SystemStub_SDL_create() {
|
||||
return new SystemStub_SDL();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::init(const char *title, uint16 w, uint16 h) {
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
SDL_WM_SetCaption(title, NULL);
|
||||
memset(&_pi, 0, sizeof(_pi));
|
||||
_screenW = w;
|
||||
_screenH = h;
|
||||
// allocate some extra bytes for the scaling routines
|
||||
int size_offscreen = (w + 2) * (h + 2) * 2;
|
||||
_offscreen = (uint8 *)malloc(size_offscreen);
|
||||
if (!_offscreen) {
|
||||
error("SystemStub_SDL::init() Unable to allocate offscreen buffer");
|
||||
}
|
||||
memset(_offscreen, 0, size_offscreen);
|
||||
_fullscreen = false;
|
||||
_scaler = 0;
|
||||
memset(_pal, 0, sizeof(_pal));
|
||||
prepareGfxMode();
|
||||
_joystick = NULL;
|
||||
if (SDL_NumJoysticks() > 0) {
|
||||
_joystick = SDL_JoystickOpen(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::destroy() {
|
||||
cleanupGfxMode();
|
||||
if (SDL_JoystickOpened(0)) {
|
||||
SDL_JoystickClose(_joystick);
|
||||
}
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::setPalette(const uint8 *pal, uint16 n) {
|
||||
assert(n <= 256);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
uint8 r = pal[i * 3 + 0];
|
||||
uint8 g = pal[i * 3 + 1];
|
||||
uint8 b = pal[i * 3 + 2];
|
||||
_pal[i] = SDL_MapRGB(_screen->format, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::setPaletteEntry(uint8 i, const Color *c) {
|
||||
uint8 r = (c->r << 2) | (c->r & 3);
|
||||
uint8 g = (c->g << 2) | (c->g & 3);
|
||||
uint8 b = (c->b << 2) | (c->b & 3);
|
||||
_pal[i] = SDL_MapRGB(_screen->format, r, g, b);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::getPaletteEntry(uint8 i, Color *c) {
|
||||
SDL_GetRGB(_pal[i], _screen->format, &c->r, &c->g, &c->b);
|
||||
c->r >>= 2;
|
||||
c->g >>= 2;
|
||||
c->b >>= 2;
|
||||
}
|
||||
|
||||
void SystemStub_SDL::setOverscanColor(uint8 i) {
|
||||
_overscanColor = i;
|
||||
}
|
||||
|
||||
void SystemStub_SDL::copyRect(int16 x, int16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch) {
|
||||
if (_numBlitRects >= MAX_BLIT_RECTS) {
|
||||
warning("SystemStub_SDL::copyRect() Too many blit rects, you may experience graphical glitches");
|
||||
} else {
|
||||
// extend the dirty region by 1 pixel for scalers accessing 'outer' pixels
|
||||
--x;
|
||||
--y;
|
||||
w += 2;
|
||||
h += 2;
|
||||
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
if (x + w > _screenW) {
|
||||
w = _screenW - x;
|
||||
}
|
||||
if (y + h > _screenH) {
|
||||
h = _screenH - y;
|
||||
}
|
||||
|
||||
SDL_Rect *br = &_blitRects[_numBlitRects];
|
||||
|
||||
br->x = _pi.mirrorMode ? _screenW - (x + w) : x;
|
||||
br->y = y;
|
||||
br->w = w;
|
||||
br->h = h;
|
||||
++_numBlitRects;
|
||||
|
||||
uint16 *p = (uint16 *)_offscreen + (br->y + 1) * _screenW + (br->x + 1);
|
||||
buf += y * pitch + x;
|
||||
|
||||
if (_pi.mirrorMode) {
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
p[i] = _pal[buf[w - 1 - i]];
|
||||
}
|
||||
p += _screenW;
|
||||
buf += pitch;
|
||||
}
|
||||
} else {
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
p[i] = _pal[buf[i]];
|
||||
}
|
||||
p += _screenW;
|
||||
buf += pitch;
|
||||
}
|
||||
}
|
||||
if (_pi.dbgMask & PlayerInput::DF_DBLOCKS) {
|
||||
drawRect(br, 0xE7, (uint16 *)_offscreen + _screenW + 1, _screenW * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::updateScreen(uint8 shakeOffset) {
|
||||
//SDL_Flip(_screen);
|
||||
|
||||
const int mul = _scalers[_scaler].factor;
|
||||
if (shakeOffset == 0) {
|
||||
for (int i = 0; i < _numBlitRects; ++i) {
|
||||
SDL_Rect *br = &_blitRects[i];
|
||||
int16 dx = br->x * mul;
|
||||
int16 dy = br->y * mul;
|
||||
SDL_LockSurface(_sclscreen);
|
||||
uint16 *dst = (uint16 *)_sclscreen->pixels + dy * _sclscreen->pitch / 2 + dx;
|
||||
const uint16 *src = (uint16 *)_offscreen + (br->y + 1) * _screenW + (br->x + 1);
|
||||
(*_scalers[_scaler].proc)(dst, _sclscreen->pitch, src, _screenW, br->w, br->h);
|
||||
SDL_UnlockSurface(_sclscreen);
|
||||
br->x *= mul;
|
||||
br->y *= mul;
|
||||
br->w *= mul;
|
||||
br->h *= mul;
|
||||
SDL_BlitSurface(_sclscreen, br, _screen, br);
|
||||
}
|
||||
SDL_UpdateRects(_screen, _numBlitRects, _blitRects);
|
||||
} else {
|
||||
SDL_LockSurface(_sclscreen);
|
||||
uint16 w = _screenW;
|
||||
uint16 h = _screenH - shakeOffset;
|
||||
uint16 *dst = (uint16 *)_sclscreen->pixels;
|
||||
const uint16 *src = (uint16 *)_offscreen + _screenW + 1;
|
||||
(*_scalers[_scaler].proc)(dst, _sclscreen->pitch, src, _screenW, w, h);
|
||||
SDL_UnlockSurface(_sclscreen);
|
||||
|
||||
SDL_Rect bsr, bdr;
|
||||
bdr.x = 0;
|
||||
bdr.y = 0;
|
||||
bdr.w = _screenW * mul;
|
||||
bdr.h = shakeOffset * mul;
|
||||
SDL_FillRect(_screen, &bdr, _pal[_overscanColor]);
|
||||
|
||||
bsr.x = 0;
|
||||
bsr.y = 0;
|
||||
bsr.w = _screenW * mul;
|
||||
bsr.h = (_screenH - shakeOffset) * mul;
|
||||
bdr.x = 0;
|
||||
bdr.y = shakeOffset * mul;
|
||||
bdr.w = bsr.w;
|
||||
bdr.h = bsr.h;
|
||||
SDL_BlitSurface(_sclscreen, &bsr, _screen, &bdr);
|
||||
|
||||
bdr.x = 0;
|
||||
bdr.y = 0;
|
||||
bdr.w = _screenW * mul;
|
||||
bdr.h = _screenH * mul;
|
||||
SDL_UpdateRects(_screen, 1, &bdr);
|
||||
}
|
||||
_numBlitRects = 0;
|
||||
|
||||
}
|
||||
|
||||
void SystemStub_SDL::processEvents() {
|
||||
SDL_Event ev;
|
||||
while (SDL_PollEvent(&ev)) {
|
||||
switch (ev.type) {
|
||||
case SDL_QUIT:
|
||||
_pi.quit = true;
|
||||
break;
|
||||
case SDL_JOYHATMOTION:
|
||||
_pi.dirMask = 0;
|
||||
if (ev.jhat.value & SDL_HAT_UP) {
|
||||
_pi.dirMask |= PlayerInput::DIR_UP;
|
||||
}
|
||||
if (ev.jhat.value & SDL_HAT_DOWN) {
|
||||
_pi.dirMask |= PlayerInput::DIR_DOWN;
|
||||
}
|
||||
if (ev.jhat.value & SDL_HAT_LEFT) {
|
||||
_pi.dirMask |= PlayerInput::DIR_LEFT;
|
||||
}
|
||||
if (ev.jhat.value & SDL_HAT_RIGHT) {
|
||||
_pi.dirMask |= PlayerInput::DIR_RIGHT;
|
||||
}
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
switch (ev.jaxis.axis) {
|
||||
case 0:
|
||||
if (ev.jaxis.value > JOYSTICK_COMMIT_VALUE) {
|
||||
_pi.dirMask |= PlayerInput::DIR_RIGHT;
|
||||
if (_pi.dirMask & PlayerInput::DIR_LEFT) {
|
||||
_pi.dirMask &= ~PlayerInput::DIR_LEFT;
|
||||
}
|
||||
} else if (ev.jaxis.value < -JOYSTICK_COMMIT_VALUE) {
|
||||
_pi.dirMask |= PlayerInput::DIR_LEFT;
|
||||
if (_pi.dirMask & PlayerInput::DIR_RIGHT) {
|
||||
_pi.dirMask &= ~PlayerInput::DIR_RIGHT;
|
||||
}
|
||||
} else {
|
||||
_pi.dirMask &= ~(PlayerInput::DIR_RIGHT | PlayerInput::DIR_LEFT);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (ev.jaxis.value > JOYSTICK_COMMIT_VALUE) {
|
||||
_pi.dirMask |= PlayerInput::DIR_DOWN;
|
||||
if (_pi.dirMask & PlayerInput::DIR_UP) {
|
||||
_pi.dirMask &= ~PlayerInput::DIR_UP;
|
||||
}
|
||||
} else if (ev.jaxis.value < -JOYSTICK_COMMIT_VALUE) {
|
||||
_pi.dirMask |= PlayerInput::DIR_UP;
|
||||
if (_pi.dirMask & PlayerInput::DIR_DOWN) {
|
||||
_pi.dirMask &= ~PlayerInput::DIR_DOWN;
|
||||
}
|
||||
} else {
|
||||
_pi.dirMask = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
switch (ev.jbutton.button) {
|
||||
case 0:
|
||||
_pi.space = true;
|
||||
break;
|
||||
case 1:
|
||||
_pi.shift = true;
|
||||
break;
|
||||
case 2:
|
||||
_pi.enter = true;
|
||||
break;
|
||||
case 3:
|
||||
_pi.backspace = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
switch (ev.jbutton.button) {
|
||||
case 0:
|
||||
_pi.space = false;
|
||||
break;
|
||||
case 1:
|
||||
_pi.shift = false;
|
||||
break;
|
||||
case 2:
|
||||
_pi.enter = false;
|
||||
break;
|
||||
case 3:
|
||||
_pi.backspace = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
switch (ev.key.keysym.sym) {
|
||||
case SDLK_LEFT:
|
||||
_pi.dirMask &= ~PlayerInput::DIR_LEFT;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
_pi.dirMask &= ~PlayerInput::DIR_RIGHT;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
_pi.dirMask &= ~PlayerInput::DIR_UP;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
_pi.dirMask &= ~PlayerInput::DIR_DOWN;
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
_pi.space = false;
|
||||
break;
|
||||
case SDLK_RSHIFT:
|
||||
case SDLK_LSHIFT:
|
||||
_pi.shift = false;
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
_pi.enter = false;
|
||||
break;
|
||||
case SDLK_ESCAPE:
|
||||
_pi.escape = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (ev.key.keysym.mod & KMOD_ALT) {
|
||||
if (ev.key.keysym.sym == SDLK_RETURN) {
|
||||
switchGfxMode(!_fullscreen, _scaler);
|
||||
} else if (ev.key.keysym.sym == SDLK_KP_PLUS) {
|
||||
uint8 s = _scaler + 1;
|
||||
if (s < NUM_SCALERS) {
|
||||
switchGfxMode(_fullscreen, s);
|
||||
}
|
||||
} else if (ev.key.keysym.sym == SDLK_KP_MINUS) {
|
||||
int8 s = _scaler - 1;
|
||||
if (_scaler > 0) {
|
||||
switchGfxMode(_fullscreen, s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (ev.key.keysym.mod & KMOD_CTRL) {
|
||||
if (ev.key.keysym.sym == SDLK_f) {
|
||||
_pi.dbgMask ^= PlayerInput::DF_FASTMODE;
|
||||
} else if (ev.key.keysym.sym == SDLK_b) {
|
||||
_pi.dbgMask ^= PlayerInput::DF_DBLOCKS;
|
||||
} else if (ev.key.keysym.sym == SDLK_i) {
|
||||
_pi.dbgMask ^= PlayerInput::DF_SETLIFE;
|
||||
} else if (ev.key.keysym.sym == SDLK_m) {
|
||||
_pi.mirrorMode = !_pi.mirrorMode;
|
||||
flipGfx();
|
||||
} else if (ev.key.keysym.sym == SDLK_s) {
|
||||
_pi.save = true;
|
||||
} else if (ev.key.keysym.sym == SDLK_l) {
|
||||
_pi.load = true;
|
||||
} else if (ev.key.keysym.sym == SDLK_KP_PLUS) {
|
||||
_pi.stateSlot = 1;
|
||||
} else if (ev.key.keysym.sym == SDLK_KP_MINUS) {
|
||||
_pi.stateSlot = -1;
|
||||
} else if (ev.key.keysym.sym == SDLK_r) {
|
||||
_pi.inpRecord = true;
|
||||
} else if (ev.key.keysym.sym == SDLK_p) {
|
||||
_pi.inpReplay = true;
|
||||
}
|
||||
}
|
||||
_pi.lastChar = ev.key.keysym.sym;
|
||||
switch (ev.key.keysym.sym) {
|
||||
case SDLK_LEFT:
|
||||
_pi.dirMask |= PlayerInput::DIR_LEFT;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
_pi.dirMask |= PlayerInput::DIR_RIGHT;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
_pi.dirMask |= PlayerInput::DIR_UP;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
_pi.dirMask |= PlayerInput::DIR_DOWN;
|
||||
break;
|
||||
case SDLK_BACKSPACE:
|
||||
case SDLK_TAB:
|
||||
_pi.backspace = true;
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
_pi.space = true;
|
||||
break;
|
||||
case SDLK_RSHIFT:
|
||||
case SDLK_LSHIFT:
|
||||
_pi.shift = true;
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
_pi.enter = true;
|
||||
break;
|
||||
case SDLK_ESCAPE:
|
||||
_pi.escape = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::sleep(uint32 duration) {
|
||||
SDL_Delay(duration);
|
||||
}
|
||||
|
||||
uint32 SystemStub_SDL::getTimeStamp() {
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::startAudio(AudioCallback callback, void *param) {
|
||||
SDL_AudioSpec desired;
|
||||
memset(&desired, 0, sizeof(desired));
|
||||
desired.freq = SOUND_SAMPLE_RATE;
|
||||
desired.format = AUDIO_S16;
|
||||
desired.channels = 1;
|
||||
desired.samples = 2048;
|
||||
desired.callback = callback;
|
||||
desired.userdata = param;
|
||||
if (SDL_OpenAudio(&desired, NULL) == 0) {
|
||||
SDL_PauseAudio(0);
|
||||
} else {
|
||||
error("SystemStub_SDL::startAudio() Unable to open sound device");
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::stopAudio() {
|
||||
SDL_CloseAudio();
|
||||
}
|
||||
|
||||
uint32 SystemStub_SDL::getOutputSampleRate() {
|
||||
return SOUND_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
void *SystemStub_SDL::createMutex() {
|
||||
return SDL_CreateMutex();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::destroyMutex(void *mutex) {
|
||||
SDL_DestroyMutex((SDL_mutex *)mutex);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::lockMutex(void *mutex) {
|
||||
SDL_mutexP((SDL_mutex *)mutex);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::unlockMutex(void *mutex) {
|
||||
SDL_mutexV((SDL_mutex *)mutex);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::prepareGfxMode() {
|
||||
|
||||
int w = _screenW * _scalers[_scaler].factor;
|
||||
int h = _screenH * _scalers[_scaler].factor;
|
||||
|
||||
//_screen = SDL_SetVideoMode(w, h, 16, _fullscreen ? (SDL_FULLSCREEN | SDL_HWSURFACE) : SDL_HWSURFACE);
|
||||
debug(DBG_INFO, "Requesting video %dx%d", w, h);
|
||||
_screen = SDL_SetVideoMode(w, h, 16, SDL_SWSURFACE);
|
||||
if (!_screen) {
|
||||
error("SystemStub_SDL::prepareGfxMode() Unable to allocate _screen buffer");
|
||||
}
|
||||
const SDL_PixelFormat *pf = _screen->format;
|
||||
// Android TODO: get rid of filthy scaler and draw directly to Android surface
|
||||
_sclscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16, pf->Rmask, pf->Gmask, pf->Bmask, pf->Amask);
|
||||
//_sclscreen = _screen; // Android hack
|
||||
if (!_sclscreen) {
|
||||
error("SystemStub_SDL::prepareGfxMode() Unable to allocate _sclscreen buffer");
|
||||
}
|
||||
forceGfxRedraw();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::cleanupGfxMode() {
|
||||
if (_offscreen) {
|
||||
free(_offscreen);
|
||||
_offscreen = 0;
|
||||
}
|
||||
|
||||
if (_sclscreen) {
|
||||
SDL_FreeSurface(_sclscreen);
|
||||
_sclscreen = 0;
|
||||
}
|
||||
|
||||
if (_screen) {
|
||||
// freed by SDL_Quit()
|
||||
_screen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::switchGfxMode(bool fullscreen, uint8 scaler) {
|
||||
|
||||
SDL_Surface *prev_sclscreen = _sclscreen;
|
||||
SDL_FreeSurface(_screen);
|
||||
_fullscreen = fullscreen;
|
||||
_scaler = scaler;
|
||||
prepareGfxMode();
|
||||
SDL_BlitSurface(prev_sclscreen, NULL, _sclscreen, NULL);
|
||||
SDL_FreeSurface(prev_sclscreen);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::flipGfx() {
|
||||
uint16 scanline[256];
|
||||
assert(_screenW <= 256);
|
||||
uint16 *p = (uint16 *)_offscreen + _screenW + 1;
|
||||
for (int y = 0; y < _screenH; ++y) {
|
||||
p += _screenW;
|
||||
for (int x = 0; x < _screenW; ++x) {
|
||||
scanline[x] = *--p;
|
||||
}
|
||||
memcpy(p, scanline, _screenW * sizeof(uint16));
|
||||
p += _screenW;
|
||||
}
|
||||
forceGfxRedraw();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::forceGfxRedraw() {
|
||||
_numBlitRects = 1;
|
||||
_blitRects[0].x = 0;
|
||||
_blitRects[0].y = 0;
|
||||
_blitRects[0].w = _screenW;
|
||||
_blitRects[0].h = _screenH;
|
||||
}
|
||||
|
||||
void SystemStub_SDL::drawRect(SDL_Rect *rect, uint8 color, uint16 *dst, uint16 dstPitch) {
|
||||
dstPitch >>= 1;
|
||||
int x1 = rect->x;
|
||||
int y1 = rect->y;
|
||||
int x2 = rect->x + rect->w - 1;
|
||||
int y2 = rect->y + rect->h - 1;
|
||||
assert(x1 >= 0 && x2 < _screenW && y1 >= 0 && y2 < _screenH);
|
||||
for (int i = x1; i <= x2; ++i) {
|
||||
*(dst + y1 * dstPitch + i) = *(dst + y2 * dstPitch + i) = _pal[color];
|
||||
}
|
||||
for (int j = y1; j <= y2; ++j) {
|
||||
*(dst + j * dstPitch + x1) = *(dst + j * dstPitch + x2) = _pal[color];
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "unpack.h"
|
||||
|
||||
|
||||
static int rcr(UnpackCtx *uc, int CF) {
|
||||
int rCF = (uc->chk & 1);
|
||||
uc->chk >>= 1;
|
||||
if (CF) {
|
||||
uc->chk |= 0x80000000;
|
||||
}
|
||||
return rCF;
|
||||
}
|
||||
|
||||
static int next_chunk(UnpackCtx *uc) {
|
||||
int CF = rcr(uc, 0);
|
||||
if (uc->chk == 0) {
|
||||
uc->chk = READ_BE_UINT32(uc->src); uc->src -= 4;
|
||||
uc->crc ^= uc->chk;
|
||||
CF = rcr(uc, 1);
|
||||
}
|
||||
return CF;
|
||||
}
|
||||
|
||||
static uint16 get_code(UnpackCtx *uc, uint8 num_chunks) {
|
||||
uint16 c = 0;
|
||||
while (num_chunks--) {
|
||||
c <<= 1;
|
||||
if (next_chunk(uc)) {
|
||||
c |= 1;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static void dec_unk1(UnpackCtx *uc, uint8 num_chunks, uint8 add_count) {
|
||||
uint16 count = get_code(uc, num_chunks) + add_count + 1;
|
||||
uc->datasize -= count;
|
||||
while (count--) {
|
||||
*uc->dst = (uint8)get_code(uc, 8);
|
||||
--uc->dst;
|
||||
}
|
||||
}
|
||||
|
||||
static void dec_unk2(UnpackCtx *uc, uint8 num_chunks) {
|
||||
uint16 i = get_code(uc, num_chunks);
|
||||
uint16 count = uc->size + 1;
|
||||
uc->datasize -= count;
|
||||
while (count--) {
|
||||
*uc->dst = *(uc->dst + i);
|
||||
--uc->dst;
|
||||
}
|
||||
}
|
||||
|
||||
bool delphine_unpack(uint8 *dst, const uint8 *src, int len) {
|
||||
UnpackCtx uc;
|
||||
uc.src = src + len - 4;
|
||||
uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4;
|
||||
uc.dst = dst + uc.datasize - 1;
|
||||
uc.size = 0;
|
||||
uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4;
|
||||
uc.chk = READ_BE_UINT32(uc.src); uc.src -= 4;
|
||||
debug(DBG_UNPACK, "delphine_unpack() crc=0x%X datasize=0x%X", uc.crc, uc.datasize);
|
||||
uc.crc ^= uc.chk;
|
||||
do {
|
||||
if (!next_chunk(&uc)) {
|
||||
uc.size = 1;
|
||||
if (!next_chunk(&uc)) {
|
||||
dec_unk1(&uc, 3, 0);
|
||||
} else {
|
||||
dec_unk2(&uc, 8);
|
||||
}
|
||||
} else {
|
||||
uint16 c = get_code(&uc, 2);
|
||||
if (c == 3) {
|
||||
dec_unk1(&uc, 8, 8);
|
||||
} else if (c < 2) {
|
||||
uc.size = c + 2;
|
||||
dec_unk2(&uc, c + 9);
|
||||
} else {
|
||||
uc.size = get_code(&uc, 8);
|
||||
dec_unk2(&uc, 12);
|
||||
}
|
||||
}
|
||||
} while (uc.datasize > 0);
|
||||
return uc.crc == 0;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __UNPACK_H__
|
||||
#define __UNPACK_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
|
||||
struct UnpackCtx {
|
||||
int size, datasize;
|
||||
uint32 crc;
|
||||
uint32 chk;
|
||||
uint8 *dst;
|
||||
const uint8 *src;
|
||||
};
|
||||
|
||||
extern bool delphine_unpack(uint8 *dst, const uint8 *src, int len);
|
||||
|
||||
|
||||
#endif // __UNPACK_H__
|
||||
@@ -1,74 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <cstdarg>
|
||||
#include "util.h"
|
||||
#include <android/log.h>
|
||||
|
||||
|
||||
uint16 g_debugMask;
|
||||
|
||||
void debug(uint16 cm, const char *msg, ...) {
|
||||
char buf[1024];
|
||||
if (cm & g_debugMask) {
|
||||
va_list va;
|
||||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
printf("%s\n", buf);
|
||||
fflush(stdout);
|
||||
__android_log_print(ANDROID_LOG_INFO, "REminiscence", "%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
void error(const char *msg, ...) {
|
||||
char buf[1024];
|
||||
va_list va;
|
||||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
fprintf(stderr, "ERROR: %s!\n", buf);
|
||||
__android_log_print(ANDROID_LOG_INFO, "REminiscence", "ERROR: %s", buf);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void warning(const char *msg, ...) {
|
||||
char buf[1024];
|
||||
va_list va;
|
||||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
fprintf(stderr, "WARNING: %s!\n", buf);
|
||||
__android_log_print(ANDROID_LOG_INFO, "REminiscence", "WARNING: %s", buf);
|
||||
}
|
||||
|
||||
void string_lower(char *p) {
|
||||
for (; *p; ++p) {
|
||||
if (*p >= 'A' && *p <= 'Z') {
|
||||
*p += 'a' - 'A';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void string_upper(char *p) {
|
||||
for (; *p; ++p) {
|
||||
if (*p >= 'a' && *p <= 'z') {
|
||||
*p += 'A' - 'a';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_H__
|
||||
#define __UTIL_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
enum {
|
||||
DBG_INFO = 1 << 0,
|
||||
DBG_RES = 1 << 1,
|
||||
DBG_MENU = 1 << 2,
|
||||
DBG_UNPACK = 1 << 3,
|
||||
DBG_PGE = 1 << 4,
|
||||
DBG_VIDEO = 1 << 5,
|
||||
DBG_GAME = 1 << 6,
|
||||
DBG_COL = 1 << 7,
|
||||
DBG_SND = 1 << 8,
|
||||
DBG_CUT = 1 << 9,
|
||||
DBG_MOD = 1 << 10,
|
||||
DBG_SFX = 1 << 11
|
||||
};
|
||||
|
||||
extern uint16 g_debugMask;
|
||||
|
||||
extern void debug(uint16 cm, const char *msg, ...);
|
||||
extern void error(const char *msg, ...);
|
||||
extern void warning(const char *msg, ...);
|
||||
|
||||
extern void string_lower(char *p);
|
||||
extern void string_upper(char *p);
|
||||
|
||||
#endif // __UTIL_H__
|
||||
@@ -1,411 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
#include "systemstub.h"
|
||||
#include "video.h"
|
||||
|
||||
|
||||
Video::Video(Resource *res, SystemStub *stub)
|
||||
: _res(res), _stub(stub) {
|
||||
_frontLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
|
||||
memset(_frontLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
|
||||
_backLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
|
||||
memset(_backLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
|
||||
_tempLayer = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
|
||||
memset(_tempLayer, 0, GAMESCREEN_W * GAMESCREEN_H);
|
||||
_tempLayer2 = (uint8 *)malloc(GAMESCREEN_W * GAMESCREEN_H);
|
||||
memset(_tempLayer2, 0, GAMESCREEN_W * GAMESCREEN_H);
|
||||
_screenBlocks = (uint8 *)malloc((GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
|
||||
memset(_screenBlocks, 0, (GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
|
||||
_fullRefresh = true;
|
||||
_shakeOffset = 0;
|
||||
_charFrontColor = 0;
|
||||
_charTransparentColor = 0;
|
||||
_charShadowColor = 0;
|
||||
}
|
||||
|
||||
Video::~Video() {
|
||||
free(_frontLayer);
|
||||
free(_backLayer);
|
||||
free(_tempLayer);
|
||||
free(_tempLayer2);
|
||||
free(_screenBlocks);
|
||||
}
|
||||
|
||||
void Video::markBlockAsDirty(int16 x, int16 y, uint16 w, uint16 h) {
|
||||
debug(DBG_VIDEO, "Video::markBlockAsDirty(%d, %d, %d, %d)", x, y, w, h);
|
||||
assert(x >= 0 && x + w <= GAMESCREEN_W && y >= 0 && y + h <= GAMESCREEN_H);
|
||||
int bx1 = x / SCREENBLOCK_W;
|
||||
int by1 = y / SCREENBLOCK_H;
|
||||
int bx2 = (x + w - 1) / SCREENBLOCK_W;
|
||||
int by2 = (y + h - 1) / SCREENBLOCK_H;
|
||||
assert(bx2 < GAMESCREEN_W / SCREENBLOCK_W && by2 < GAMESCREEN_H / SCREENBLOCK_H);
|
||||
for (; by1 <= by2; ++by1) {
|
||||
for (int i = bx1; i <= bx2; ++i) {
|
||||
_screenBlocks[by1 * (GAMESCREEN_W / SCREENBLOCK_W) + i] = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Video::updateScreen() {
|
||||
debug(DBG_VIDEO, "Video::updateScreen()");
|
||||
// _fullRefresh = true;
|
||||
if (_fullRefresh) {
|
||||
_stub->copyRect(0, 0, Video::GAMESCREEN_W, Video::GAMESCREEN_H, _frontLayer, 256);
|
||||
_stub->updateScreen(_shakeOffset);
|
||||
_fullRefresh = false;
|
||||
} else {
|
||||
int i, j;
|
||||
int count = 0;
|
||||
uint8 *p = _screenBlocks;
|
||||
for (j = 0; j < GAMESCREEN_H / SCREENBLOCK_H; ++j) {
|
||||
uint16 nh = 0;
|
||||
for (i = 0; i < GAMESCREEN_W / SCREENBLOCK_W; ++i) {
|
||||
if (p[i] != 0) {
|
||||
--p[i];
|
||||
++nh;
|
||||
} else if (nh != 0) {
|
||||
int16 x = (i - nh) * SCREENBLOCK_W;
|
||||
_stub->copyRect(x, j * SCREENBLOCK_H, nh * SCREENBLOCK_W, SCREENBLOCK_H, _frontLayer, 256);
|
||||
nh = 0;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
if (nh != 0) {
|
||||
int16 x = (i - nh) * SCREENBLOCK_W;
|
||||
_stub->copyRect(x, j * SCREENBLOCK_H, nh * SCREENBLOCK_W, SCREENBLOCK_H, _frontLayer, 256);
|
||||
++count;
|
||||
}
|
||||
p += GAMESCREEN_W / SCREENBLOCK_W;
|
||||
}
|
||||
if (count != 0) {
|
||||
_stub->updateScreen(_shakeOffset);
|
||||
}
|
||||
}
|
||||
if (_shakeOffset != 0) {
|
||||
_shakeOffset = 0;
|
||||
_fullRefresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::fullRefresh() {
|
||||
debug(DBG_VIDEO, "Video::fullRefresh()");
|
||||
_fullRefresh = true;
|
||||
memset(_screenBlocks, 0, (GAMESCREEN_W / SCREENBLOCK_W) * (GAMESCREEN_H / SCREENBLOCK_H));
|
||||
}
|
||||
|
||||
void Video::fadeOut() {
|
||||
debug(DBG_VIDEO, "Video::fadeOut()");
|
||||
for (int step = 16; step >= 0; --step) {
|
||||
for (int c = 0; c < 256; ++c) {
|
||||
Color col;
|
||||
_stub->getPaletteEntry(c, &col);
|
||||
col.r = col.r * step >> 4;
|
||||
col.g = col.g * step >> 4;
|
||||
col.b = col.b * step >> 4;
|
||||
_stub->setPaletteEntry(c, &col);
|
||||
}
|
||||
fullRefresh();
|
||||
updateScreen();
|
||||
_stub->sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::setPaletteSlotBE(int palSlot, int palNum) {
|
||||
debug(DBG_VIDEO, "Video::setPaletteSlotBE()");
|
||||
const uint8 *p = _res->_pal + palNum * 0x20;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
uint16 color = READ_BE_UINT16(p); p += 2;
|
||||
uint8 t = (color == 0) ? 0 : 3;
|
||||
Color c;
|
||||
c.r = ((color & 0x00F) << 2) | t;
|
||||
c.g = ((color & 0x0F0) >> 2) | t;
|
||||
c.b = ((color & 0xF00) >> 6) | t;
|
||||
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::setPaletteSlotLE(int palSlot, const uint8 *palData) {
|
||||
debug(DBG_VIDEO, "Video::setPaletteSlotLE()");
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
uint16 color = READ_LE_UINT16(palData); palData += 2;
|
||||
Color c;
|
||||
c.b = (color & 0x00F) << 2;
|
||||
c.g = (color & 0x0F0) >> 2;
|
||||
c.r = (color & 0xF00) >> 6;
|
||||
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::setTextPalette() {
|
||||
debug(DBG_VIDEO, "Video::setTextPalette()");
|
||||
const uint8 *p = _textPal;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
uint16 color = READ_LE_UINT16(p); p += 2;
|
||||
Color c;
|
||||
c.b = (color & 0x00F) << 2;
|
||||
c.g = (color & 0x0F0) >> 2;
|
||||
c.r = (color & 0xF00) >> 6;
|
||||
_stub->setPaletteEntry(0xE0 + i, &c);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::setPalette0xF() {
|
||||
debug(DBG_VIDEO, "Video::setPalette0xF()");
|
||||
const uint8 *p = _palSlot0xF;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
Color c;
|
||||
c.r = *p++ >> 2;
|
||||
c.g = *p++ >> 2;
|
||||
c.b = *p++ >> 2;
|
||||
_stub->setPaletteEntry(0xF0 + i, &c);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::copyLevelMap(uint16 room) {
|
||||
debug(DBG_VIDEO, "Video::copyLevelMap(%d)", room);
|
||||
assert(room < 0x40);
|
||||
int32 off = READ_LE_UINT32(_res->_map + room * 6);
|
||||
if (off == 0) {
|
||||
error("Invalid room %d", room);
|
||||
}
|
||||
bool packed = true;
|
||||
if (off < 0) {
|
||||
off = -off;
|
||||
packed = false;
|
||||
}
|
||||
const uint8 *p = _res->_map + off;
|
||||
_mapPalSlot1 = *p++;
|
||||
_mapPalSlot2 = *p++;
|
||||
_mapPalSlot3 = *p++;
|
||||
_mapPalSlot4 = *p++;
|
||||
if (packed) {
|
||||
uint8 *vid = _frontLayer;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
uint16 sz = READ_LE_UINT16(p); p += 2;
|
||||
decodeLevelMap(sz, p, _res->_memBuf); p += sz;
|
||||
memcpy(vid, _res->_memBuf, 256 * 56);
|
||||
vid += 256 * 56;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int y = 0; y < 224; ++y) {
|
||||
for (int x = 0; x < 64; ++x) {
|
||||
_frontLayer[i + x * 4 + 256 * y] = p[256 * 56 * i + x + 64 * y];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(_backLayer, _frontLayer, Video::GAMESCREEN_W * Video::GAMESCREEN_H);
|
||||
}
|
||||
|
||||
void Video::decodeLevelMap(uint16 sz, const uint8 *src, uint8 *dst) {
|
||||
debug(DBG_VIDEO, "Video::decodeLevelMap() sz = 0x%X", sz);
|
||||
const uint8 *end = src + sz;
|
||||
while (src < end) {
|
||||
int16 code = (int8)*src++;
|
||||
if (code < 0) {
|
||||
int len = 1 - code;
|
||||
memset(dst, *src++, len);
|
||||
dst += len;
|
||||
} else {
|
||||
++code;
|
||||
memcpy(dst, src, code);
|
||||
src += code;
|
||||
dst += code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Video::setLevelPalettes() {
|
||||
debug(DBG_VIDEO, "Video::setLevelPalettes()");
|
||||
if (_unkPalSlot2 == 0) {
|
||||
_unkPalSlot2 = _mapPalSlot3;
|
||||
}
|
||||
if (_unkPalSlot1 == 0) {
|
||||
_unkPalSlot1 = _mapPalSlot3;
|
||||
}
|
||||
setPaletteSlotBE(0x0, _mapPalSlot1);
|
||||
setPaletteSlotBE(0x1, _mapPalSlot2);
|
||||
setPaletteSlotBE(0x2, _mapPalSlot3);
|
||||
setPaletteSlotBE(0x3, _mapPalSlot4);
|
||||
if (_unkPalSlot1 == _mapPalSlot3) {
|
||||
setPaletteSlotLE(4, _conradPal1);
|
||||
} else {
|
||||
setPaletteSlotLE(4, _conradPal2);
|
||||
}
|
||||
// slot 5 is monster palette
|
||||
setPaletteSlotBE(0x8, _mapPalSlot1);
|
||||
setPaletteSlotBE(0x9, _mapPalSlot2);
|
||||
setPaletteSlotBE(0xA, _unkPalSlot2);
|
||||
setPaletteSlotBE(0xB, _mapPalSlot4);
|
||||
// slots 0xC and 0xD are cutscene palettes
|
||||
setTextPalette();
|
||||
}
|
||||
|
||||
void Video::drawSpriteSub1(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
|
||||
debug(DBG_VIDEO, "Video::drawSpriteSub1(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
if (src[i] != 0) {
|
||||
dst[i] = src[i] | colMask;
|
||||
}
|
||||
}
|
||||
src += pitch;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::drawSpriteSub2(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
|
||||
debug(DBG_VIDEO, "Video::drawSpriteSub2(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
if (src[-i] != 0) {
|
||||
dst[i] = src[-i] | colMask;
|
||||
}
|
||||
}
|
||||
src += pitch;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::drawSpriteSub3(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
|
||||
debug(DBG_VIDEO, "Video::drawSpriteSub3(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
if (src[i] != 0 && !(dst[i] & 0x80)) {
|
||||
dst[i] = src[i] | colMask;
|
||||
}
|
||||
}
|
||||
src += pitch;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::drawSpriteSub4(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
|
||||
debug(DBG_VIDEO, "Video::drawSpriteSub4(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
if (src[-i] != 0 && !(dst[i] & 0x80)) {
|
||||
dst[i] = src[-i] | colMask;
|
||||
}
|
||||
}
|
||||
src += pitch;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::drawSpriteSub5(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
|
||||
debug(DBG_VIDEO, "Video::drawSpriteSub5(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
if (src[i * pitch] != 0 && !(dst[i] & 0x80)) {
|
||||
dst[i] = src[i * pitch] | colMask;
|
||||
}
|
||||
}
|
||||
++src;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::drawSpriteSub6(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask) {
|
||||
debug(DBG_VIDEO, "Video::drawSpriteSub6(0x%X, 0x%X, 0x%X, 0x%X)", pitch, w, h, colMask);
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
if (src[-i * pitch] != 0 && !(dst[i] & 0x80)) {
|
||||
dst[i] = src[-i * pitch] | colMask;
|
||||
}
|
||||
}
|
||||
++src;
|
||||
dst += 256;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::drawChar(uint8 c, int16 y, int16 x) {
|
||||
debug(DBG_VIDEO, "Video::drawChar(0x%X, %d, %d)", c, y, x);
|
||||
y *= 8;
|
||||
x *= 8;
|
||||
const uint8 *src = _res->_fnt + (c - 32) * 32;
|
||||
uint8 *dst = _frontLayer + x + 256 * y;
|
||||
for (int h = 0; h < 8; ++h) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
uint8 c1 = (*src & 0xF0) >> 4;
|
||||
uint8 c2 = (*src & 0x0F) >> 0;
|
||||
++src;
|
||||
|
||||
if (c1 != 0) {
|
||||
if (c1 != 2) {
|
||||
*dst = _charFrontColor;
|
||||
} else {
|
||||
*dst = _charShadowColor;
|
||||
}
|
||||
} else if (_charTransparentColor != 0xFF) {
|
||||
*dst = _charTransparentColor;
|
||||
}
|
||||
++dst;
|
||||
|
||||
if (c2 != 0) {
|
||||
if (c2 != 2) {
|
||||
*dst = _charFrontColor;
|
||||
} else {
|
||||
*dst = _charShadowColor;
|
||||
}
|
||||
} else if (_charTransparentColor != 0xFF) {
|
||||
*dst = _charTransparentColor;
|
||||
}
|
||||
++dst;
|
||||
}
|
||||
dst += 256 - 8;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Video::drawString(const char *str, int16 x, int16 y, uint8 col) {
|
||||
debug(DBG_VIDEO, "Video::drawString('%s', %d, %d, 0x%X)", str, x, y, col);
|
||||
int len = 0;
|
||||
int offset = y * 256 + x;
|
||||
uint8 *dst = _frontLayer + offset;
|
||||
while (1) {
|
||||
uint8 c = *str++;
|
||||
if (c == 0 || c == 0xB || c == 0xA) {
|
||||
break;
|
||||
}
|
||||
uint8 *dst_char = dst;
|
||||
const uint8 *src = _res->_fnt + (c - 32) * 32;
|
||||
for (int h = 0; h < 8; ++h) {
|
||||
for (int w = 0; w < 4; ++w) {
|
||||
uint8 c1 = (*src & 0xF0) >> 4;
|
||||
uint8 c2 = (*src & 0x0F) >> 0;
|
||||
++src;
|
||||
if (c1 != 0) {
|
||||
*dst_char = (c1 == 0xF) ? col : (0xE0 + c1);
|
||||
}
|
||||
++dst_char;
|
||||
if (c2 != 0) {
|
||||
*dst_char = (c2 == 0xF) ? col : (0xE0 + c2);
|
||||
}
|
||||
++dst_char;
|
||||
}
|
||||
dst_char += 256 - 8;
|
||||
}
|
||||
dst += 8; // character width
|
||||
++len;
|
||||
}
|
||||
markBlockAsDirty(x, y, len * 8, 8);
|
||||
return str - 1;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2007 Gregory Montoir
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __VIDEO_H__
|
||||
#define __VIDEO_H__
|
||||
|
||||
#include "intern.h"
|
||||
|
||||
struct Resource;
|
||||
struct SystemStub;
|
||||
|
||||
struct Video {
|
||||
enum {
|
||||
GAMESCREEN_W = 256,
|
||||
GAMESCREEN_H = 224,
|
||||
SCREENBLOCK_W = 8,
|
||||
SCREENBLOCK_H = 8,
|
||||
CHAR_W = 8,
|
||||
CHAR_H = 8
|
||||
};
|
||||
|
||||
static const uint8 _conradPal1[];
|
||||
static const uint8 _conradPal2[];
|
||||
static const uint8 _textPal[];
|
||||
static const uint8 _palSlot0xF[];
|
||||
|
||||
Resource *_res;
|
||||
SystemStub *_stub;
|
||||
|
||||
uint8 *_frontLayer;
|
||||
uint8 *_backLayer;
|
||||
uint8 *_tempLayer;
|
||||
uint8 *_tempLayer2;
|
||||
uint8 _unkPalSlot1, _unkPalSlot2;
|
||||
uint8 _mapPalSlot1, _mapPalSlot2, _mapPalSlot3, _mapPalSlot4;
|
||||
uint8 _charFrontColor;
|
||||
uint8 _charTransparentColor;
|
||||
uint8 _charShadowColor;
|
||||
uint8 *_screenBlocks;
|
||||
bool _fullRefresh;
|
||||
uint8 _shakeOffset;
|
||||
|
||||
Video(Resource *res, SystemStub *stub);
|
||||
~Video();
|
||||
|
||||
void markBlockAsDirty(int16 x, int16 y, uint16 w, uint16 h);
|
||||
void updateScreen();
|
||||
void fullRefresh();
|
||||
void fadeOut();
|
||||
void setPaletteSlotBE(int palSlot, int palNum);
|
||||
void setPaletteSlotLE(int palSlot, const uint8 *palData);
|
||||
void setTextPalette();
|
||||
void setPalette0xF();
|
||||
void copyLevelMap(uint16 room);
|
||||
void decodeLevelMap(uint16 sz, const uint8 *src, uint8 *dst);
|
||||
void setLevelPalettes();
|
||||
void drawSpriteSub1(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
|
||||
void drawSpriteSub2(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
|
||||
void drawSpriteSub3(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
|
||||
void drawSpriteSub4(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
|
||||
void drawSpriteSub5(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
|
||||
void drawSpriteSub6(const uint8 *src, uint8 *dst, int pitch, int h, int w, uint8 colMask);
|
||||
void drawChar(uint8 c, int16 y, int16 x);
|
||||
const char *drawString(const char *str, int16 x, int16 y, uint8 col);
|
||||
};
|
||||
|
||||
#endif // __VIDEO_H__
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,259 +0,0 @@
|
||||
# The application settings for Android libSDL port
|
||||
|
||||
# Specify application name (e.x. My Application)
|
||||
AppName="Alien Blaster"
|
||||
|
||||
# Specify reversed site name of application (e.x. com.mysite.myapp)
|
||||
AppFullName=de.schwardtnet.alienblaster
|
||||
|
||||
# Application version code (integer)
|
||||
AppVersionCode=110014
|
||||
|
||||
# Application user-visible version name (string)
|
||||
AppVersionName="1.1.0.14"
|
||||
|
||||
# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...'
|
||||
# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu
|
||||
# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped
|
||||
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
|
||||
# these files are put inside .apk package by build system
|
||||
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
|
||||
AppDataDownloadUrl="!Game data|alienblaster110_data1.zip^!Game data|alienblaster110_data2.zip^!Game data|alienblaster110_data3.zip"
|
||||
|
||||
# Reset SDL config when updating application to the new version (y) / (n)
|
||||
ResetSdlConfigForThisVersion=n
|
||||
|
||||
# Delete application data files when upgrading (specify file/dir paths separated by spaces)
|
||||
DeleteFilesOnUpgrade="%"
|
||||
|
||||
# Here you may type readme text, which will be shown during startup. Format is:
|
||||
# Text in English, use \\\\n to separate lines (that's four backslashes)^de:Text in Deutsch^ru:Text in Russian^button:Button that will open some URL:http://url-to-open/
|
||||
ReadmeText='^You can press "Home" now - the data will be downloaded in background^In game press "Menu" for secondary fire, "Volume Up/Down" to cycle weapons'
|
||||
|
||||
# libSDL version to use (1.2/1.3/2.0)
|
||||
LibSdlVersion=1.3
|
||||
|
||||
# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape
|
||||
ScreenOrientation=h
|
||||
|
||||
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
|
||||
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)
|
||||
VideoDepthBpp=16
|
||||
|
||||
# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedDepthBuffer=n
|
||||
|
||||
# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n)
|
||||
NeedStencilBuffer=n
|
||||
|
||||
# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device
|
||||
# you need this option only if you're developing 3-d app (y) or (n)
|
||||
NeedGles2=n
|
||||
|
||||
# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL,
|
||||
# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n)
|
||||
SwVideoMode=n
|
||||
|
||||
# Application video output will be resized to fit into native device screen (y)/(n)
|
||||
SdlVideoResize=y
|
||||
|
||||
# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n)
|
||||
SdlVideoResizeKeepAspect=n
|
||||
|
||||
# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer
|
||||
InhibitSuspend=n
|
||||
|
||||
# Create Android service, so the app is less likely to be killed while in background
|
||||
CreateService=
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread -
|
||||
# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n)
|
||||
CompatibilityHacksForceScreenUpdate=
|
||||
|
||||
# Application does not call SDL_Flip() or SDL_UpdateRects() after mouse click (ScummVM and all Amiga emulators do that) -
|
||||
# force screen update by moving mouse cursor a little after each click (y) or (n)
|
||||
CompatibilityHacksForceScreenUpdateMouseClick=y
|
||||
|
||||
# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n)
|
||||
CompatibilityHacksStaticInit=n
|
||||
|
||||
# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)
|
||||
CompatibilityHacksTextInputEmulatesHwKeyboard=n
|
||||
|
||||
# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)
|
||||
CompatibilityHacksPreventAudioChopping=
|
||||
|
||||
# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n)
|
||||
CompatibilityHacksAppIgnoresAudioBufferSize=
|
||||
|
||||
# Hack for VCMI: preload additional shared libraries before aplication start
|
||||
CompatibilityHacksAdditionalPreloadedSharedLibraries=""
|
||||
|
||||
# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -
|
||||
# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n)
|
||||
CompatibilityHacksSlowCompatibleEventQueue=
|
||||
|
||||
# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL
|
||||
CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=
|
||||
|
||||
# Application uses SDL_UpdateRects() properly, and does not draw in any region outside those rects.
|
||||
# This improves drawing speed, but I know only one application that does that, and it's written by me (y)/(n)
|
||||
CompatibilityHacksProperUsageOfSDL_UpdateRects=
|
||||
|
||||
# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user
|
||||
AppUsesMouse=n
|
||||
|
||||
# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n)
|
||||
AppNeedsTwoButtonMouse=n
|
||||
|
||||
# Right mouse button can do long-press/drag&drop action, necessary for some games (y) or (n)
|
||||
# If you disable it, swiping with two fingers will send mouse wheel events
|
||||
RightMouseButtonLongPress=
|
||||
|
||||
# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n)
|
||||
ShowMouseCursor=n
|
||||
|
||||
# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n)
|
||||
GenerateSubframeTouchEvents=
|
||||
|
||||
# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n)
|
||||
ForceRelativeMouseMode=n
|
||||
|
||||
# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n)
|
||||
AppNeedsArrowKeys=y
|
||||
|
||||
# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n)
|
||||
# Joystick always follows finger, so moving mouse requires touching the screen with other finger
|
||||
FloatingScreenJoystick=y
|
||||
|
||||
# Application needs text input (y) or (n), enables button for text input on screen
|
||||
AppNeedsTextInput=y
|
||||
|
||||
# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1
|
||||
# This will disable AppNeedsArrowKeys option
|
||||
AppUsesJoystick=n
|
||||
|
||||
# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n)
|
||||
AppUsesSecondJoystick=n
|
||||
|
||||
# Application uses third on-screen joystick, as SDL joystick 0 axes 20-21 (y)/(n)
|
||||
AppUsesThirdJoystick=
|
||||
|
||||
# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7
|
||||
AppUsesAccelerometer=
|
||||
|
||||
# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4
|
||||
AppUsesGyroscope=
|
||||
|
||||
# Use gyroscope to move mouse cursor (y) or (n), it eats battery, and can be disabled in settings, do not use with AppUsesGyroscope setting
|
||||
MoveMouseWithGyroscope=
|
||||
|
||||
# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0
|
||||
AppUsesMultitouch=n
|
||||
|
||||
# Application records audio (it will use any available source, such a s microphone)
|
||||
# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void);
|
||||
# This option will add additional permission to Android manifest (y)/(n)
|
||||
AppRecordsAudio=
|
||||
|
||||
# Application needs to access SD card. If your data files are bigger than 5 Mb, enable it. (y) / (n)
|
||||
AccessSdCard=
|
||||
|
||||
# Application needs Internet access. If you disable it, you'll have to bundle all your data files inside .apk (y) / (n)
|
||||
AccessInternet=
|
||||
|
||||
# Immersive mode - Android will hide on-screen Home/Back keys. Looks bad if you invoke Android keyboard. (y) / (n)
|
||||
ImmersiveMode=
|
||||
|
||||
# Application implements Android-specific routines to put to background, and will not draw anything to screen
|
||||
# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them
|
||||
# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n)
|
||||
# This option is reported to be buggy, sometimes failing to restore video state
|
||||
NonBlockingSwapBuffers=n
|
||||
|
||||
# Redefine common hardware keys to SDL keysyms
|
||||
# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent
|
||||
# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices
|
||||
# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th)
|
||||
# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA
|
||||
RedefinedKeys="RETURN LCTRL NO_REMAP NO_REMAP LCTRL"
|
||||
|
||||
# Number of virtual keyboard keys (currently 6 is maximum)
|
||||
AppTouchscreenKeyboardKeysAmount=4
|
||||
|
||||
# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right)
|
||||
RedefinedKeysScreenKb="RETURN LCTRL PAGEUP PAGEDOWN LCTRL"
|
||||
|
||||
# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu
|
||||
RedefinedKeysScreenKbNames=""
|
||||
|
||||
# On-screen keys theme
|
||||
# 0 = Ultimate Droid by Sean Stieber (green, with gamepad joystick)
|
||||
# 1 = Simple Theme by Beholder (white, with gamepad joystick)
|
||||
# 2 = Sun by Sirea (yellow, with round joystick)
|
||||
# 3 = Keen by Gerstrong (multicolor, with round joystick)
|
||||
TouchscreenKeysTheme=2
|
||||
|
||||
# Redefine gamepad keys to SDL keysyms, button order is:
|
||||
# A B X Y L1 R1 L2 R2 LThumb RThumb
|
||||
RedefinedKeysGamepad=""
|
||||
|
||||
# How long to show startup menu button, in msec, 0 to disable startup menu
|
||||
StartupMenuButtonTimeout=3000
|
||||
|
||||
# Menu items to hide from startup menu, available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
HiddenMenuOptions='OptionalDownloadConfig'
|
||||
|
||||
# Menu items to show at startup - this is Java code snippet, leave empty for default
|
||||
# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration()
|
||||
# Available menu items:
|
||||
# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout
|
||||
FirstStartMenuOptions=''
|
||||
|
||||
# Specify architectures to compile, 'all' or 'y' to compile for all architectures.
|
||||
# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips
|
||||
MultiABI='n'
|
||||
|
||||
# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower
|
||||
AppMinimumRAM=
|
||||
|
||||
# Optional shared libraries to compile - removing some of them will save space
|
||||
# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed
|
||||
# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2
|
||||
CompiledLibraries="sdl_mixer sdl_image"
|
||||
|
||||
# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n)
|
||||
CustomBuildScript=n
|
||||
|
||||
# Aditional CFLAGS for application
|
||||
AppCflags='-O3'
|
||||
|
||||
# Additional LDFLAGS for application
|
||||
AppLdflags=''
|
||||
|
||||
# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable
|
||||
AppOverlapsSystemHeaders=
|
||||
|
||||
# Build only following subdirs (empty will build all dirs, ignored with custom script)
|
||||
AppSubdirsBuild=''
|
||||
|
||||
# Exclude these files from build
|
||||
AppBuildExclude=''
|
||||
|
||||
# Application command line parameters, including app name as 0-th param
|
||||
AppCmdline=''
|
||||
|
||||
# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens
|
||||
# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge
|
||||
MinimumScreenSize=
|
||||
|
||||
# Your AdMob Publisher ID, (n) if you don't want advertisements
|
||||
AdmobPublisherId=
|
||||
|
||||
# Your AdMob test device ID, to receive a test ad
|
||||
AdmobTestDeviceId=
|
||||
|
||||
# Your AdMob banner size (BANNER/FULL_BANNER/LEADERBOARD/MEDIUM_RECTANGLE/SMART_BANNER/WIDE_SKYSCRAPER/FULL_WIDTH:Height/Width:AUTO_HEIGHT/Width:Height)
|
||||
AdmobBannerSize=
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,66 +0,0 @@
|
||||
# game name
|
||||
GAME_NAME=alienBlaster
|
||||
|
||||
# the compiler to use
|
||||
COMPILER=g++
|
||||
|
||||
# include path
|
||||
INCLUDE_PATH=-I.
|
||||
|
||||
#OPTIMIZATION=-g -pg -fprofile-arcs
|
||||
#OPTIMIZATION=-O3
|
||||
OPTIMIZATION=-g
|
||||
#OPTIMIZATION=
|
||||
|
||||
# SDL library
|
||||
SDL_LIBS=$(shell sdl-config --libs)
|
||||
SDL_FLAGS=$(shell sdl-config --cflags)
|
||||
|
||||
# game flags
|
||||
GAME_FLAGS=-D_GNU_SOURCE -Wall -Winline -finline-functions $(SDL_FLAGS) $(OPTIMIZATION)
|
||||
GAME_LIBS=-lSDL_mixer $(SDL_LIBS) $(OPTIMIZATION)
|
||||
|
||||
# all objectfiles
|
||||
OBJECT_FILES=main.o surfaceDB.o soundDB.o options.o geometry.o video.o game.o \
|
||||
racer.o racers.o shots.o shot.o boundingBox.o items.o item.o font.o \
|
||||
explosion.o explosions.o mixer.o enemys.o enemy.o wrecks.o wreck.o \
|
||||
settings.o intro.o setDifficulty.o global.o formation.o infoscreen.o \
|
||||
menuArcadeMode.o sonic.o banners.o banner.o smokePuff.o smokePuffs.o \
|
||||
shieldGlow.o background.o input.o
|
||||
|
||||
.PHONY: all game clean realclean rebuild tgz
|
||||
|
||||
all: depend $(GAME_NAME)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.da
|
||||
|
||||
realclean:
|
||||
rm -f *.o *.da *~ Makefile.dep
|
||||
|
||||
rebuild: realclean game
|
||||
|
||||
.SUFFIXES: .cpp
|
||||
|
||||
# How to compile a c++ programm
|
||||
$(GAME_NAME): $(OBJECT_FILES)
|
||||
@echo ""
|
||||
@echo ""
|
||||
@echo "Linking $@"
|
||||
@$(COMPILER) $(GAME_LIBS) -o $(GAME_NAME) $(OBJECT_FILES)
|
||||
mv $(GAME_NAME) ../
|
||||
|
||||
%.o: %.cpp
|
||||
@echo ""
|
||||
@echo ""
|
||||
@echo "Compiling $<"
|
||||
@$(COMPILER) $(GAME_FLAGS) $(INCLUDE_PATH) -c $< -o $@
|
||||
|
||||
depend: dep
|
||||
|
||||
dep:
|
||||
-touch Makefile.dep
|
||||
-makedepend $(INCLUDE_PATH) -Y -f Makefile.dep *.cpp 2> /dev/null
|
||||
-rm -f Makefile.dep.bak
|
||||
|
||||
-include Makefile.dep
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
Compatibility wrapper to compile the same code on both SDL 1.2 and 1.3 without many #ifdefs
|
||||
*/
|
||||
|
||||
#ifndef __SDL_FORWARD_COMPAT_H__
|
||||
#define __SDL_FORWARD_COMPAT_H__
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_video.h>
|
||||
#include <SDL_version.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error "This header is for C++ only, you're unlucky, sorry"
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
|
||||
struct SdlCompat_AcceleratedSurface
|
||||
{
|
||||
SDL_Texture * t;
|
||||
int w, h;
|
||||
SDL_PixelFormat * format;
|
||||
};
|
||||
|
||||
enum { SDL_SRCALPHA = 8, SDL_SRCCOLORKEY = 16 }; // Some dummy non-zero values
|
||||
|
||||
typedef SDL_Keycode SDLKey;
|
||||
|
||||
extern SDL_Renderer * SDL_global_renderer;
|
||||
|
||||
static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(SDL_Surface * surface)
|
||||
{
|
||||
SdlCompat_AcceleratedSurface * ret = new SdlCompat_AcceleratedSurface();
|
||||
// Allocate accelerated surface even if that means loss of color quality
|
||||
Uint32 format;
|
||||
Uint32 colorkey;
|
||||
Uint8 alpha;
|
||||
|
||||
ret->w = surface->w;
|
||||
ret->h = surface->h;
|
||||
ret->format = new SDL_PixelFormat();
|
||||
memcpy(ret->format, surface->format, sizeof(SDL_PixelFormat));
|
||||
|
||||
format = SDL_PIXELFORMAT_RGB565;
|
||||
if( SDL_GetColorKey(surface, &colorkey) == 0 )
|
||||
{
|
||||
format = SDL_PIXELFORMAT_RGBA4444;
|
||||
}
|
||||
|
||||
ret->t = SDL_CreateTextureFromSurface(SDL_global_renderer, surface);
|
||||
|
||||
if( ! ret->t )
|
||||
{
|
||||
SDL_SetError("SdlCompat_CreateAcceleratedSurface: Cannot allocate HW texture, W %d H %d format %x surface->flags %x", ret->w, ret->h, format, surface->flags );
|
||||
return ret;
|
||||
}
|
||||
|
||||
SDL_SetTextureBlendMode( ret->t, SDL_BLENDMODE_BLEND );
|
||||
//SDL_SetTextureAlphaMod( ret->t, SDL_ALPHA_OPAQUE );
|
||||
SDL_SetTextureAlphaMod( ret->t, 128 );
|
||||
if( SDL_GetSurfaceAlphaMod(surface, &alpha) == 0 )
|
||||
SDL_SetTextureAlphaMod( ret->t, alpha );
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
static inline int SDL_BlitSurface( SdlCompat_AcceleratedSurface * src, SDL_Rect * srcR, SdlCompat_AcceleratedSurface * unused, SDL_Rect * destR )
|
||||
{
|
||||
return SDL_RenderCopy(SDL_global_renderer, src->t, srcR, destR);
|
||||
};
|
||||
|
||||
static inline void SDL_FreeSurface(SdlCompat_AcceleratedSurface * surface)
|
||||
{
|
||||
SDL_DestroyTexture(surface->t);
|
||||
delete surface->format;
|
||||
delete surface;
|
||||
};
|
||||
|
||||
static inline void SDL_FillRect( SdlCompat_AcceleratedSurface * unused, const SDL_Rect* rect, Uint32 color )
|
||||
{
|
||||
Uint8 r = color & 0xff, g = (color >> 8) & 0xff, b = (color >> 16) & 0xff;
|
||||
SDL_SetRenderDrawColor(SDL_global_renderer, r, g, b, SDL_ALPHA_OPAQUE /* a */);
|
||||
SDL_RenderFillRect(SDL_global_renderer, rect);
|
||||
};
|
||||
|
||||
static inline int SDL_Flip(SdlCompat_AcceleratedSurface * unused)
|
||||
{
|
||||
SDL_RenderPresent(SDL_global_renderer);
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline int SDL_SetAlpha(SdlCompat_AcceleratedSurface * surface, Uint32 flag, Uint8 alpha)
|
||||
{
|
||||
if( ! flag )
|
||||
alpha = SDL_ALPHA_OPAQUE;
|
||||
return SDL_SetTextureAlphaMod(surface->t, alpha);
|
||||
};
|
||||
|
||||
static inline void SdlCompat_ReloadSurfaceToVideoMemory(SdlCompat_AcceleratedSurface * surface, SDL_Surface * src)
|
||||
{
|
||||
// Allocate accelerated surface even if that means loss of color quality
|
||||
Uint32 format;
|
||||
int access, w, h;
|
||||
SDL_QueryTexture(surface->t, &format, &access, &w, &h);
|
||||
|
||||
int bpp;
|
||||
Uint32 r,g,b,a;
|
||||
SDL_PixelFormatEnumToMasks(format, &bpp, &r, &g, &b, &a);
|
||||
SDL_Surface * formatsurf = SDL_CreateRGBSurface(0, 1, 1, bpp, r, g, b, a);
|
||||
SDL_Surface * converted = SDL_ConvertSurface( src, formatsurf->format, 0 );
|
||||
|
||||
SDL_LockSurface(converted);
|
||||
|
||||
SDL_UpdateTexture( surface->t, NULL, converted->pixels, converted->pitch );
|
||||
SDL_UnlockSurface(converted);
|
||||
|
||||
SDL_FreeSurface(converted);
|
||||
SDL_FreeSurface(formatsurf);
|
||||
|
||||
if( src->flags & SDL_SRCALPHA )
|
||||
{
|
||||
SDL_SetTextureBlendMode( surface->t, SDL_BLENDMODE_BLEND );
|
||||
Uint8 alpha = 128;
|
||||
if( SDL_GetSurfaceAlphaMod( src, &alpha ) < 0 )
|
||||
alpha = 128;
|
||||
SDL_SetTextureAlphaMod( surface->t, alpha );
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef SDL_Surface SdlCompat_AcceleratedSurface;
|
||||
|
||||
static inline SdlCompat_AcceleratedSurface * SdlCompat_CreateAcceleratedSurface(SDL_Surface * surface)
|
||||
{
|
||||
return SDL_ConvertSurface(surface, surface->format, surface->flags | SDL_HWSURFACE);
|
||||
};
|
||||
|
||||
static inline void SdlCompat_ReloadSurfaceToVideoMemory(SDL_Surface * surface, SDL_Surface * src)
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef _AS_STRING_H_
|
||||
#define _AS_STRING_H_
|
||||
|
||||
#include <sstream>
|
||||
|
||||
template<typename T> std::string asString(const T& obj) {
|
||||
|
||||
std::ostringstream t;
|
||||
t << obj;
|
||||
std::string res(t.str());
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,138 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "background.h"
|
||||
#include "global.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "SDL.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Background::Background() {
|
||||
minTileWidth = 9999999;
|
||||
minTileHeight = 9999999;
|
||||
tilesPerLine = 0;
|
||||
tilesPerColumn = 0;
|
||||
step = 0;
|
||||
}
|
||||
|
||||
|
||||
void Background::clearTileList() {
|
||||
tileNames.clear();
|
||||
tilesPerLine = 0;
|
||||
tilesPerColumn = 0;
|
||||
}
|
||||
|
||||
|
||||
void Background::addTile( string tilename ) {
|
||||
tileNames.push_back( tilename );
|
||||
}
|
||||
|
||||
|
||||
void Background::generateBackground( int length ) {
|
||||
tileSurfaces.clear();
|
||||
minTileWidth = 9999999;
|
||||
minTileHeight = 9999999;
|
||||
|
||||
// load all tiles
|
||||
vector< SdlCompat_AcceleratedSurface* > tmpTiles;
|
||||
for(int i=tileNames.size()-1; i>=0; i--) {
|
||||
|
||||
SdlCompat_AcceleratedSurface *tile = surfaceDB.loadSurface( tileNames[i] );
|
||||
|
||||
if (tile != NULL) {
|
||||
tmpTiles.push_back( tile );
|
||||
if (tile->w < minTileWidth) {
|
||||
minTileWidth = tile->w;
|
||||
}
|
||||
if (tile->h < minTileHeight) {
|
||||
minTileHeight = tile->h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate tiles per line and tiles per row
|
||||
tilesPerLine = SCREEN_WIDTH / minTileWidth;
|
||||
if (SCREEN_WIDTH % minTileWidth) {
|
||||
tilesPerLine++;
|
||||
}
|
||||
tilesPerColumn = SCREEN_HEIGHT / minTileHeight;
|
||||
if (SCREEN_HEIGHT % minTileHeight) {
|
||||
tilesPerColumn++;
|
||||
}
|
||||
|
||||
int rows = length / minTileHeight;
|
||||
if (length % minTileHeight) {
|
||||
rows++;
|
||||
}
|
||||
|
||||
// cout << "Background: minTileWidth=" << minTileWidth << " minTileHeight=" << minTileHeight << " rows=" << rows << endl;
|
||||
|
||||
// generate random background
|
||||
for(int i=rows*tilesPerLine; i; i--) {
|
||||
tileSurfaces.push_back( tmpTiles[ rand() % tmpTiles.size() ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Background::draw( SdlCompat_AcceleratedSurface* screen ) {
|
||||
step = (step+1) % (tilesPerColumn*minTileHeight);
|
||||
draw( screen, step );
|
||||
}
|
||||
|
||||
|
||||
void Background::draw( SdlCompat_AcceleratedSurface* screen, int step ) {
|
||||
if (step < 0) {
|
||||
step *= -1;
|
||||
}
|
||||
int startLine = (step / minTileHeight);
|
||||
int offset = (step % minTileHeight);
|
||||
|
||||
SDL_Rect srcRect;
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
|
||||
SDL_Rect dstRect;
|
||||
|
||||
for(int y = 0; y < tilesPerColumn+1; y++) {
|
||||
for(int x = 0; x < tilesPerLine; x++) {
|
||||
|
||||
int diffX = SCREEN_WIDTH - x * minTileWidth;
|
||||
if ( diffX >= minTileWidth ) {
|
||||
srcRect.w = minTileWidth;
|
||||
} else {
|
||||
srcRect.w = diffX;
|
||||
}
|
||||
dstRect.w = srcRect.w;
|
||||
|
||||
if (y==0) {
|
||||
int diffY = -(offset - minTileHeight);
|
||||
srcRect.h = diffY;
|
||||
} else {
|
||||
srcRect.h = minTileHeight;
|
||||
}
|
||||
dstRect.h = srcRect.h;
|
||||
|
||||
dstRect.x = x * minTileWidth;
|
||||
dstRect.y = SCREEN_HEIGHT + offset - (y+1) * minTileHeight;
|
||||
SDL_BlitSurface( tileSurfaces[ ((y+startLine)*tilesPerLine+x) % tileSurfaces.size()] , &srcRect, screen, &dstRect );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef _BACKGROUND_H_
|
||||
#define _BACKGROUND_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "SdlForwardCompat.h"
|
||||
|
||||
class Background {
|
||||
public:
|
||||
Background();
|
||||
|
||||
void clearTileList();
|
||||
void addTile( std::string tilename );
|
||||
void generateBackground( int length );
|
||||
void draw( SdlCompat_AcceleratedSurface* screen );
|
||||
void draw( SdlCompat_AcceleratedSurface* screen, int step );
|
||||
|
||||
private:
|
||||
|
||||
int minTileWidth;
|
||||
int minTileHeight;
|
||||
int tilesPerLine;
|
||||
int tilesPerColumn;
|
||||
int step;
|
||||
|
||||
std::vector< std::string > tileNames;
|
||||
std::vector< SdlCompat_AcceleratedSurface* > tileSurfaces;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,122 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "banner.h"
|
||||
#include "surfaceDB.h"
|
||||
#include <iostream>
|
||||
|
||||
Banner::Banner( BannerTexts text, BannerModes mode, BannerBoni bonus ) {
|
||||
sprite = surfaceDB.loadSurface( FN_BANNER_TEXTS[ text ], true );
|
||||
this->mode = mode;
|
||||
if ( this->mode == BANNER_MODE_RANDOM ) {
|
||||
this->mode = (BannerModes)(rand() % NR_BANNER_MODES);
|
||||
}
|
||||
this->bonus = bonus;
|
||||
if ( this->bonus != BANNER_BONUS_NONE ) {
|
||||
spriteBonus = surfaceDB.loadSurface( FN_BANNER_BONUS[ bonus ], true );
|
||||
}
|
||||
|
||||
pos = Vector2D( -1000, -1000 );
|
||||
|
||||
if ( mode == BANNER_MODE_ITEM_COLLECTED_SINGLE_PLAYER ) {
|
||||
pos = Vector2D( 10, SCREEN_HEIGHT - 20 - sprite->h );
|
||||
} else if ( mode == BANNER_MODE_ITEM_COLLECTED_PLAYER_ONE ) {
|
||||
pos = Vector2D( 10, SCREEN_HEIGHT - 20 - sprite->h );
|
||||
} else if ( mode == BANNER_MODE_ITEM_COLLECTED_PLAYER_TWO ) {
|
||||
pos = Vector2D( SCREEN_WIDTH - sprite->w - 10,
|
||||
SCREEN_HEIGHT - 20 - sprite->h );
|
||||
}
|
||||
timeLived = 0;
|
||||
}
|
||||
|
||||
|
||||
Banner::~Banner() {}
|
||||
|
||||
bool Banner::isExpired() {
|
||||
return timeLived > BANNER_MODE_LIFETIME[ mode ];
|
||||
}
|
||||
|
||||
|
||||
void Banner::update( int dT ) {
|
||||
timeLived += dT;
|
||||
|
||||
switch ( mode ) {
|
||||
case BANNER_MODE_FLY_FROM_LEFT:
|
||||
{
|
||||
if ( timeLived < 1000 ) {
|
||||
pos = Vector2D( -(sprite->w) + ((SCREEN_WIDTH + sprite->w)/ 2) * (timeLived / 1000.0),
|
||||
200 - sprite->h / 2 );
|
||||
} else if ( 1000 < timeLived && timeLived < 3000 ) {
|
||||
pos = Vector2D( ( SCREEN_WIDTH - sprite->w ) / 2,
|
||||
200 - sprite->h / 2 );
|
||||
} else {
|
||||
pos = Vector2D( ((SCREEN_WIDTH - sprite->w)/2) +
|
||||
((SCREEN_WIDTH + sprite->w)/2)*((timeLived-3000)/2000.0),
|
||||
200 - sprite->h / 2 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BANNER_MODE_FROM_TOP:
|
||||
{
|
||||
if ( timeLived < 1000 ) {
|
||||
pos = Vector2D( (SCREEN_WIDTH - sprite->w)/2,
|
||||
-(sprite->h) + (200 + sprite->h/2) * (timeLived / 1000.0) );
|
||||
} else if ( 1000 < timeLived && timeLived < 3000 ) {
|
||||
pos = Vector2D( (SCREEN_WIDTH - sprite->w)/2,
|
||||
200 - (sprite->h / 2 ) );
|
||||
} else {
|
||||
pos = Vector2D( (SCREEN_WIDTH - sprite->w)/2,
|
||||
200 - (sprite->h / 2) +
|
||||
(200 + (sprite->h / 2))*((timeLived-3000)/2000.0) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BANNER_MODE_ITEM_COLLECTED_SINGLE_PLAYER:
|
||||
case BANNER_MODE_ITEM_COLLECTED_PLAYER_ONE:
|
||||
case BANNER_MODE_ITEM_COLLECTED_PLAYER_TWO:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Banner::movingAway() {
|
||||
return ( 3000 <= timeLived );
|
||||
}
|
||||
|
||||
void Banner::draw(SdlCompat_AcceleratedSurface *screen) {
|
||||
SDL_Rect r;
|
||||
r.x = lroundf(pos.getX());
|
||||
r.y = lroundf(pos.getY());
|
||||
r.w = sprite->w;
|
||||
r.h = sprite->h;
|
||||
SDL_BlitSurface( sprite, 0, screen, &r );
|
||||
if ( bonus != BANNER_BONUS_NONE &&
|
||||
1000 < timeLived && timeLived < 3000 ) {
|
||||
r.x = SCREEN_WIDTH / 2 - spriteBonus->w / 2;
|
||||
r.y = 250;
|
||||
r.w = spriteBonus->w;
|
||||
r.h = spriteBonus->h;
|
||||
SDL_BlitSurface( spriteBonus, 0, screen, &r );
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef BANNER_H
|
||||
#define BANNER_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include <string>
|
||||
#include "geometry.h"
|
||||
#include "global.h"
|
||||
|
||||
class Banner {
|
||||
SdlCompat_AcceleratedSurface *sprite;
|
||||
SdlCompat_AcceleratedSurface *spriteBonus;
|
||||
|
||||
int sound;
|
||||
|
||||
Vector2D pos;
|
||||
int timeLived;
|
||||
|
||||
BannerModes mode;
|
||||
BannerBoni bonus;
|
||||
|
||||
public:
|
||||
Banner( BannerTexts text, BannerModes mode, BannerBoni bonus );
|
||||
~Banner();
|
||||
|
||||
void update( int dT );
|
||||
void draw( SdlCompat_AcceleratedSurface *screen );
|
||||
bool isExpired();
|
||||
bool movingAway();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,90 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "banners.h"
|
||||
#include "banner.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Banners::Banners() {}
|
||||
|
||||
Banners::~Banners() {
|
||||
vector<Banner *>::iterator i;
|
||||
for (i = banners.begin(); i != banners.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
void Banners::addBanner( BannerTexts bannerText, BannerModes mode,
|
||||
BannerBoni bonus ) {
|
||||
Banner *newBanner = new Banner( bannerText, mode, bonus );
|
||||
banners.push_back( newBanner );
|
||||
}
|
||||
|
||||
void Banners::expireBanners() {
|
||||
unsigned int i = 0;
|
||||
while ( i < banners.size() ) {
|
||||
if ( banners[i]->isExpired() ) {
|
||||
delete banners[i];
|
||||
banners.erase(banners.begin() + i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Banners::deleteAllBanners() {
|
||||
unsigned int i = 0;
|
||||
while ( i < banners.size() ) {
|
||||
delete banners[i];
|
||||
i++;
|
||||
}
|
||||
banners.clear();
|
||||
}
|
||||
|
||||
void Banners::update( int dT ) {
|
||||
switch ( banners.size() ) {
|
||||
case 0: break;
|
||||
case 1: banners[0]->update( dT ); break;
|
||||
default:
|
||||
{
|
||||
banners[0]->update( dT );
|
||||
if ( banners[0]->movingAway() ) {
|
||||
banners[1]->update( dT );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Banners::draw(SdlCompat_AcceleratedSurface *screen) {
|
||||
switch ( banners.size() ) {
|
||||
case 0: break;
|
||||
case 1: banners[0]->draw( screen ); break;
|
||||
default:
|
||||
{
|
||||
banners[0]->draw( screen );
|
||||
if ( banners[0]->movingAway() ) {
|
||||
banners[1]->draw( screen );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef BANNERS_H
|
||||
#define BANNERS_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "global.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class Banner;
|
||||
|
||||
class Banners {
|
||||
std::vector<Banner *> banners;
|
||||
|
||||
public:
|
||||
Banners();
|
||||
~Banners();
|
||||
|
||||
void addBanner( BannerTexts bannerText, BannerModes mode=BANNER_MODE_RANDOM,
|
||||
BannerBoni bonus=ARCADE_BONUS_FOR_FORMATION_DESTRUCTION );
|
||||
void expireBanners();
|
||||
void deleteAllBanners();
|
||||
void update( int dT );
|
||||
void draw(SdlCompat_AcceleratedSurface *screen);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,123 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "boundingBox.h"
|
||||
/*
|
||||
void setX(Uint16 newX) {box.x = newX;}
|
||||
void setY(Uint16 newY) {box.y = newY;}
|
||||
void setWidth(Uint16 newWidth) {box.w = newWidth;}
|
||||
void setHeight(Uint16 newHeight) {box.h = newHeight;}
|
||||
*/
|
||||
|
||||
BoundingBox::BoundingBox(int x, int y, int width, int height) {
|
||||
box.x = x;
|
||||
box.y = y;
|
||||
box.w = width;
|
||||
box.h = height;
|
||||
}
|
||||
|
||||
int BoundingBox::getUpperBound() {
|
||||
return box.y;
|
||||
}
|
||||
|
||||
int BoundingBox::getLowerBound() {
|
||||
return box.y + box.h;
|
||||
}
|
||||
|
||||
int BoundingBox::getLeftBound() {
|
||||
return box.x;
|
||||
}
|
||||
|
||||
int BoundingBox::getRightBound() {
|
||||
return box.x + box.w;
|
||||
}
|
||||
|
||||
bool BoundingBox::overlaps(BoundingBox *other) {
|
||||
return ( !(getUpperBound() > other->getLowerBound()) &&
|
||||
!(getLowerBound() < other-> getUpperBound()) &&
|
||||
!(getLeftBound() > other->getRightBound()) &&
|
||||
!(getRightBound() < other->getLeftBound()) );
|
||||
}
|
||||
|
||||
bool BoundingBox::overlaps(const Vector2D &startOfLine, const Vector2D &endOfLine) {
|
||||
|
||||
// FIXME: optimize me!
|
||||
RectangleGeo rect( Vector2D( box.x, box.y ),
|
||||
Vector2D( box.x + box.w, box.y + box.h ) );
|
||||
// FIXME: optimize me!
|
||||
|
||||
bool overlaps = false;
|
||||
|
||||
overlaps = rect.isInside( endOfLine );
|
||||
if ( overlaps ) return true;
|
||||
overlaps = rect.isInside( startOfLine );
|
||||
if ( overlaps ) return true;
|
||||
|
||||
// check some points between the two end points
|
||||
Vector2D delta((endOfLine.getX() - startOfLine.getX()) / 4.0,
|
||||
(endOfLine.getY() - startOfLine.getY()) / 4.0);
|
||||
Vector2D actPoint = startOfLine + delta;
|
||||
int i = 1;
|
||||
while (!overlaps && i <= 3 ) {
|
||||
overlaps = rect.isInside(actPoint);
|
||||
actPoint += delta;
|
||||
i++;
|
||||
}
|
||||
return overlaps;
|
||||
}
|
||||
|
||||
bool BoundingBox::overlaps(const Circle &circle) {
|
||||
RectangleGeo rect( Vector2D( box.x, box.y ),
|
||||
Vector2D( box.x + box.w, box.y + box.h ) );
|
||||
return (rect.isInside(circle.getCenter()) ||
|
||||
circle.isInside(rect.getPosLeftTop()) ||
|
||||
circle.isInside(rect.getPosRightBottom()) ||
|
||||
circle.isInside(Vector2D( box.x, box.y + box.h )) ||
|
||||
circle.isInside(Vector2D( box.x + box.w, box.y )));
|
||||
}
|
||||
|
||||
void BoundingBox::modifyX(int value) {
|
||||
box.x += value;
|
||||
}
|
||||
|
||||
void BoundingBox::modifyY(int value) {
|
||||
box.y += value;
|
||||
}
|
||||
|
||||
void BoundingBox::moveUpperBound(int upperBound) {
|
||||
box.y = upperBound;
|
||||
}
|
||||
|
||||
void BoundingBox::moveLowerBound(int lowerBound) {
|
||||
box.y = lowerBound - box.h;
|
||||
}
|
||||
|
||||
void BoundingBox::moveLeftBound(int leftBound) {
|
||||
box.x = leftBound;
|
||||
}
|
||||
|
||||
void BoundingBox::moveRightBound(int rightBound) {
|
||||
box.x = rightBound - box.w;
|
||||
}
|
||||
|
||||
/*
|
||||
SDL_Rect *BoundingBox::getRect() {
|
||||
return &box;
|
||||
}
|
||||
*/
|
||||
@@ -1,54 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef BOUNDING_BOX_H
|
||||
#define BOUNDING_BOX_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "geometry.h"
|
||||
|
||||
struct MyRect {
|
||||
int x, y, w, h;
|
||||
};
|
||||
|
||||
class BoundingBox {
|
||||
|
||||
private:
|
||||
//SDL_Rect box;
|
||||
MyRect box;
|
||||
|
||||
public:
|
||||
BoundingBox(int x, int y, int width, int height);
|
||||
int getUpperBound();
|
||||
int getLowerBound();
|
||||
int getLeftBound();
|
||||
int getRightBound();
|
||||
bool overlaps(BoundingBox *other);
|
||||
bool overlaps(const Vector2D &startOfLine, const Vector2D &endOfLine);
|
||||
bool overlaps(const Circle &circle);
|
||||
void modifyX(int value);
|
||||
void modifyY(int value);
|
||||
void moveUpperBound(int upperBound);
|
||||
void moveLowerBound(int lowerBound);
|
||||
void moveLeftBound(int leftBound);
|
||||
void moveRightBound(int rightBound);
|
||||
// SDL_Rect *getRect();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,537 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "enemy.h"
|
||||
#include "SDL.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "boundingBox.h"
|
||||
#include "mixer.h"
|
||||
#include "shots.h"
|
||||
#include "shot.h"
|
||||
#include "racers.h"
|
||||
#include "racer.h"
|
||||
#include "items.h"
|
||||
#include "item.h"
|
||||
#include "wrecks.h"
|
||||
#include "wreck.h"
|
||||
#include "global.h"
|
||||
#include "explosions.h"
|
||||
#include "explosion.h"
|
||||
#include "options.h"
|
||||
|
||||
Enemy::Enemy( Vector2D pos, Vector2D vel, EnemyTypes whichEnemyType,
|
||||
bool isInFormation, bool fireByFormation ) {
|
||||
|
||||
this->isInFormation = isInFormation;
|
||||
this->fireByFormation = fireByFormation;
|
||||
enemyType = whichEnemyType;
|
||||
hitpoints = ENEMY_HITPOINTS[ enemyType ];
|
||||
|
||||
this->pos = pos;
|
||||
this->vel = vel;
|
||||
relTargetPos = Vector2D(0,0);
|
||||
|
||||
switch ( enemyType ) {
|
||||
case FIGHTER:
|
||||
{
|
||||
string fn = LVL_ENEMY_FIGHTER;
|
||||
levelConf->getStr( LVL_ENEMY_FIGHTER, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
|
||||
fn = LVL_ENEMY_FIGHTER_SHADOW;
|
||||
levelConf->getStr( LVL_ENEMY_FIGHTER_SHADOW, fn );
|
||||
spriteShadow = surfaceDB.loadSurface( fn, true );
|
||||
break;
|
||||
}
|
||||
case BOMBER:
|
||||
{
|
||||
string fn = LVL_ENEMY_BOMBER;
|
||||
levelConf->getStr( LVL_ENEMY_BOMBER, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
|
||||
fn = LVL_ENEMY_BOMBER_SHADOW;
|
||||
levelConf->getStr( LVL_ENEMY_BOMBER_SHADOW, fn );
|
||||
spriteShadow = surfaceDB.loadSurface( fn, true );
|
||||
break;
|
||||
}
|
||||
case TANK:
|
||||
{
|
||||
string fn = LVL_ENEMY_TANK;
|
||||
levelConf->getStr( LVL_ENEMY_TANK, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
break;
|
||||
}
|
||||
|
||||
case BOSS_1_MAIN_GUN:
|
||||
{
|
||||
string fn = LVL_ENEMY_BOSS_1_MAIN_GUN;
|
||||
levelConf->getStr( LVL_ENEMY_BOSS_1_MAIN_GUN, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_ROCKET_LAUNCHER:
|
||||
{
|
||||
string fn = LVL_ENEMY_BOSS_1_ROCKET_LAUNCHER;
|
||||
levelConf->getStr( LVL_ENEMY_BOSS_1_ROCKET_LAUNCHER, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_SHOT_BATTERY_LEFT:
|
||||
{
|
||||
string fn = LVL_ENEMY_BOSS_1_SHOT_BATTERY_LEFT;
|
||||
levelConf->getStr( LVL_ENEMY_BOSS_1_SHOT_BATTERY_LEFT, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_SHOT_BATTERY_RIGHT:
|
||||
{
|
||||
string fn = LVL_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT;
|
||||
levelConf->getStr( LVL_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
break;
|
||||
}
|
||||
case BOSS_2:
|
||||
{
|
||||
spriteEnemy = surfaceDB.loadSurface( FN_ENEMY_BOSS_2 );
|
||||
spriteShadow = surfaceDB.loadSurface( FN_ENEMY_BOSS_2_SHADOW, true );
|
||||
boss2PointReached = false;
|
||||
boss2TargetPos = Vector2D(SCREEN_WIDTH / 2, 100);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
string fn = LVL_ENEMY_FIGHTER;
|
||||
levelConf->getStr( LVL_ENEMY_FIGHTER, fn );
|
||||
spriteEnemy = surfaceDB.loadSurface( fn );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boundingBox = new BoundingBox( lroundf(pos.getX() - spriteEnemy->w * 0.45),
|
||||
lroundf(pos.getY() - spriteEnemy->h * 0.45),
|
||||
lroundf(spriteEnemy->w * 0.9),
|
||||
lroundf(spriteEnemy->h * 0.9) );
|
||||
nextShotPrimary = rand() % (ENEMY_RAND_WAIT_PRIMARY[ enemyType ]+1);
|
||||
nextShotSecondary = rand() % (ENEMY_RAND_WAIT_SECONDARY[ enemyType ]+1);
|
||||
|
||||
sndShotPrimary = Mixer::mixer().loadSample( FN_SOUND_SHOT_PRIMARY );
|
||||
sndShotSecondary = Mixer::mixer().loadSample( FN_SOUND_SHOT_SECONDARY );
|
||||
}
|
||||
|
||||
Enemy::~Enemy() {
|
||||
delete boundingBox;
|
||||
}
|
||||
|
||||
|
||||
bool Enemy::isExpired() {
|
||||
return ( hitpoints <= 0 ||
|
||||
pos.getY() < -500 ||
|
||||
pos.getY() > SCREEN_HEIGHT + 500 ||
|
||||
pos.getX() < -500 ||
|
||||
pos.getX() > SCREEN_WIDTH + 500 );
|
||||
}
|
||||
|
||||
|
||||
void Enemy::expire() {
|
||||
hitpoints = -1;
|
||||
}
|
||||
|
||||
Circle Enemy::getBoundingCircle() {
|
||||
return Circle( pos, min(spriteEnemy->w / 2, spriteEnemy->h / 2) );
|
||||
}
|
||||
|
||||
BoundingBox *Enemy::getBoundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
bool Enemy::collidesWith( const Vector2D &shotPosOld, const Vector2D &shotPosNew ) {
|
||||
return boundingBox->overlaps(shotPosOld, shotPosNew);
|
||||
}
|
||||
|
||||
bool Enemy::collidesWith( BoundingBox *box ) {
|
||||
return boundingBox->overlaps( box );
|
||||
}
|
||||
|
||||
bool Enemy::collidesWith( const Circle &circle ) {
|
||||
return boundingBox->overlaps( circle );
|
||||
}
|
||||
|
||||
bool Enemy::collidesWithAsCircle( const Circle &circle ) {
|
||||
return ( circle.getRadius() + spriteEnemy->w / 2 > circle.getCenter().distanceTo( pos ) );
|
||||
}
|
||||
|
||||
bool Enemy::collidesWithAsCircle( BoundingBox *box ) {
|
||||
return ( box->overlaps( Circle( pos, min( spriteEnemy->h / 2, spriteEnemy->w / 2 ) ) ) );
|
||||
}
|
||||
|
||||
|
||||
void Enemy::update( int dT ) {
|
||||
move( dT );
|
||||
if ( !fireByFormation ) {
|
||||
shootPrimary( dT );
|
||||
shootSecondary( dT );
|
||||
}
|
||||
}
|
||||
|
||||
void Enemy::move( int dT ) {
|
||||
switch ( enemyType ) {
|
||||
case FIGHTER:
|
||||
case BOMBER:
|
||||
{
|
||||
if ( scrollingOn ) pos += vel * dT / 1000.0;
|
||||
else pos += (vel - SCROLL_SPEED) * dT / 1000.0;
|
||||
if ( isInFormation && relTargetPos != Vector2D(0,0) ) {
|
||||
Vector2D addMovement =
|
||||
Vector2D( 40, relTargetPos.getDirection(), POLAR ) * dT / 1000.0;
|
||||
if ( addMovement.getLength() > relTargetPos.getLength() ) {
|
||||
addMovement.setLength( relTargetPos.getLength() );
|
||||
}
|
||||
pos += addMovement;
|
||||
relTargetPos -= addMovement;
|
||||
}
|
||||
updateBoundingBox();
|
||||
break;
|
||||
}
|
||||
case TANK: {
|
||||
if ( scrollingOn ) pos += vel * dT / 1000.0;
|
||||
updateBoundingBox();
|
||||
break;
|
||||
}
|
||||
case BOSS_1_MAIN_GUN:
|
||||
case BOSS_1_ROCKET_LAUNCHER:
|
||||
case BOSS_1_SHOT_BATTERY_LEFT:
|
||||
case BOSS_1_SHOT_BATTERY_RIGHT: {
|
||||
if ( scrollingOn ) {
|
||||
pos += Vector2D( 0, SCROLL_SPEED * dT / 1000.0 );
|
||||
updateBoundingBox();
|
||||
if ( pos.getY() >= BOSS_1_END_Y ) {
|
||||
scrollingOn = false;
|
||||
pos.setY( BOSS_1_END_Y );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOSS_2: {
|
||||
if ( boss2PointReached ) {
|
||||
boss2TargetPos = Vector2D( (rand() % (SCREEN_WIDTH - spriteEnemy->w)) + spriteEnemy->w / 2, rand() % 100 + spriteEnemy->h );
|
||||
boss2PointReached = false;
|
||||
} else {
|
||||
pos += (boss2TargetPos - pos) / 50;
|
||||
}
|
||||
if ( pos.distanceTo(boss2TargetPos) < 15.0 ) boss2PointReached = true;
|
||||
updateBoundingBox();
|
||||
break;
|
||||
}
|
||||
default: cout << "enemys.cc::move(): unknown enemyType" << endl; break;
|
||||
}
|
||||
}
|
||||
|
||||
void Enemy::updateBoundingBox() {
|
||||
boundingBox->moveUpperBound( lroundf(pos.getY() - spriteEnemy->h * 0.45) );
|
||||
boundingBox->moveLeftBound( lroundf(pos.getX() - spriteEnemy->w * 0.45) );
|
||||
}
|
||||
|
||||
|
||||
void Enemy::firePrimary() {
|
||||
switch (enemyType) {
|
||||
case FIGHTER:
|
||||
{
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos + Vector2D( 0, spriteEnemy->h / 2 ),
|
||||
90 );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOMBER:
|
||||
{
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos + Vector2D( -7, spriteEnemy->h / 2 ),
|
||||
100 );
|
||||
shots->addShot( shot );
|
||||
shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos + Vector2D( +7, spriteEnemy->h / 2 ),
|
||||
80 );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
case TANK:
|
||||
{
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos,
|
||||
(rand() % 360) - 180 );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_MAIN_GUN:
|
||||
{
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos,
|
||||
(rand() % 20) + 80 );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_SHOT_BATTERY_LEFT:
|
||||
{
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos,
|
||||
(rand() % 120) + 30 );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_SHOT_BATTERY_RIGHT:
|
||||
{
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_NORMAL, 666,
|
||||
pos,
|
||||
(rand() % 120) + 30 );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOSS_1_ROCKET_LAUNCHER:
|
||||
{
|
||||
unsigned int racerIdx = rand() % racers->getNrRacers();
|
||||
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos, angle );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotSecondary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOSS_2:
|
||||
{
|
||||
unsigned int racerIdx = rand() % racers->getNrRacers();
|
||||
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
|
||||
Shot *shot = new Shot( ENEMY_SHOT_NORMAL, 666, pos, angle );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotPrimary, 0 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Enemy::shootPrimary( int dT ) {
|
||||
nextShotPrimary -= dT;
|
||||
if ( nextShotPrimary < 0 ) {
|
||||
firePrimary();
|
||||
nextShotPrimary =
|
||||
(rand() % (ENEMY_RAND_WAIT_PRIMARY[ enemyType ]+1)) + ENEMY_COOLDOWN_PRIMARY[ enemyType ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Enemy::fireSecondary() {
|
||||
switch (enemyType) {
|
||||
case TANK:
|
||||
{
|
||||
unsigned int racerIdx = rand() % racers->getNrRacers();
|
||||
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
|
||||
|
||||
Shot *shot =
|
||||
new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos, angle );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotSecondary, 0 );
|
||||
break;
|
||||
}
|
||||
case BOSS_2:
|
||||
{
|
||||
unsigned int racerIdx = rand() % racers->getNrRacers();
|
||||
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
|
||||
Shot *shot = new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos - Vector2D(-80,0), angle );
|
||||
shots->addShot( shot );
|
||||
shot = new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos - Vector2D(+80,0), angle );
|
||||
shots->addShot( shot );
|
||||
Mixer::mixer().playSample( sndShotSecondary, 0 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Enemy::shootSecondary( int dT ) {
|
||||
nextShotSecondary -= dT;
|
||||
if ( nextShotSecondary < 0 ) {
|
||||
fireSecondary();
|
||||
nextShotSecondary =
|
||||
(rand() % (ENEMY_RAND_WAIT_SECONDARY[ enemyType ]+1)) +
|
||||
ENEMY_COOLDOWN_SECONDARY[ enemyType ];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Enemy::doDamage( ShotTypes shotType, int fromWhichPlayer ) {
|
||||
bool allreadyDead = isExpired();
|
||||
|
||||
switch (shotType) {
|
||||
case SHOT_NORMAL: hitpoints -= DAMAGE_SHOT_NORMAL; break;
|
||||
case SHOT_NORMAL_HEAVY: hitpoints -= DAMAGE_SHOT_NORMAL_HEAVY; break;
|
||||
case SHOT_DOUBLE: hitpoints -= DAMAGE_SHOT_DOUBLE; break;
|
||||
case SHOT_DOUBLE_HEAVY: hitpoints -= DAMAGE_SHOT_DOUBLE_HEAVY; break;
|
||||
case SHOT_TRIPLE: hitpoints -= DAMAGE_SHOT_TRIPLE; break;
|
||||
|
||||
case SHOT_HF_NORMAL: hitpoints -= DAMAGE_SHOT_HF_NORMAL; break;
|
||||
case SHOT_HF_DOUBLE: hitpoints -= DAMAGE_SHOT_HF_DOUBLE; break;
|
||||
case SHOT_HF_TRIPLE: hitpoints -= DAMAGE_SHOT_HF_TRIPLE; break;
|
||||
case SHOT_HF_QUATTRO: hitpoints -= DAMAGE_SHOT_HF_QUATTRO; break;
|
||||
case SHOT_HF_QUINTO: hitpoints -= DAMAGE_SHOT_HF_QUINTO; break;
|
||||
|
||||
case SHOT_DUMBFIRE: hitpoints -= DAMAGE_SHOT_DUMBFIRE; break;
|
||||
case SHOT_DUMBFIRE_DOUBLE: hitpoints -= DAMAGE_SHOT_DUMBFIRE_DOUBLE; break;
|
||||
case SHOT_KICK_ASS_ROCKET: hitpoints -= DAMAGE_SHOT_KICK_ASS_ROCKET; break;
|
||||
case SHOT_HELLFIRE: hitpoints -= DAMAGE_SHOT_HELLFIRE; break;
|
||||
case SHOT_MACHINE_GUN: hitpoints -= DAMAGE_SHOT_MACHINE_GUN; break;
|
||||
case SHOT_ENERGY_BEAM: hitpoints -= DAMAGE_SHOT_ENERGY_BEAM; break;
|
||||
|
||||
case SHOT_HF_DUMBFIRE: hitpoints -= DAMAGE_SHOT_HF_DUMBFIRE; break;
|
||||
case SHOT_HF_DUMBFIRE_DOUBLE: hitpoints -= DAMAGE_SHOT_HF_DUMBFIRE_DOUBLE; break;
|
||||
case SHOT_HF_KICK_ASS_ROCKET: hitpoints -= DAMAGE_SHOT_HF_KICK_ASS_ROCKET; break;
|
||||
case SHOT_HF_LASER: hitpoints -= DAMAGE_SHOT_HF_LASER; break;
|
||||
|
||||
case SPECIAL_SHOT_HEATSEEKER: hitpoints -= DAMAGE_SPECIAL_SHOT_HEATSEEKER; break;
|
||||
case SPECIAL_SHOT_NUKE: hitpoints -= DAMAGE_SPECIAL_SHOT_NUKE; break;
|
||||
default:
|
||||
{
|
||||
cout << "Enemy::doDamage: unexpected shotType: " << shotType << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( enemyType < NR_ENEMY_TYPES_NORMAL ) {
|
||||
// the enemy just died -> explode, generate item,
|
||||
if ( (!allreadyDead) && isExpired() ) {
|
||||
// the player gets points, who did the final shot
|
||||
if ( 0 <= fromWhichPlayer && fromWhichPlayer < (int)racers->getNrRacers() ) {
|
||||
racers->getRacer( fromWhichPlayer )->receivePoints( ENEMY_POINTS_FOR_DEST[ enemyType ]);
|
||||
}
|
||||
// explode
|
||||
Explosion *newExplosion =
|
||||
new Explosion( FN_EXPLOSION_ENEMY, pos, vel, EXPLOSION_NORMAL_AIR );
|
||||
explosions->addExplosion( newExplosion );
|
||||
// generate wreck
|
||||
Wreck *newWreck = new Wreck( pos, WRECK_FOR_ENEMYTYPE[ enemyType ]);
|
||||
wrecks->addWreck( newWreck );
|
||||
// generate item
|
||||
if ( rand() % ENEMY_DIES_ITEM_APPEAR_CHANCE[ enemyType ] == 0 ) {
|
||||
items->generateItemNow( pos, vel / 10.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
// it's a boss!!!
|
||||
else {
|
||||
if ( (!allreadyDead) && isExpired() ) {
|
||||
// explode
|
||||
Explosion *newExplosion;
|
||||
for(int i = 0; i < 10; i++){
|
||||
newExplosion = new Explosion(
|
||||
FN_EXPLOSION_ENEMY,
|
||||
pos + Vector2D(rand() % spriteEnemy->w - spriteEnemy->w / 2, rand() % spriteEnemy->h - spriteEnemy->h / 2),
|
||||
vel + Vector2D(rand() % 100 - 50, rand() % 100 - 50) / 5.0,
|
||||
EXPLOSION_NORMAL_GROUND );
|
||||
explosions->addExplosion( newExplosion );
|
||||
}
|
||||
|
||||
// generate wreck
|
||||
Wreck *newWreck = new Wreck( pos, WRECK_FOR_ENEMYTYPE[ enemyType ]);
|
||||
wrecks->addWreck( newWreck );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Enemy::drawGroundEnemy( SdlCompat_AcceleratedSurface *screen ) {
|
||||
if ( ENEMY_FLYING[ enemyType ] ) return;
|
||||
|
||||
SDL_Rect destR;
|
||||
|
||||
destR.x = lroundf(pos.getX()) - spriteEnemy->w / 2;
|
||||
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2;
|
||||
destR.w = spriteEnemy->w;
|
||||
destR.h = spriteEnemy->h;
|
||||
|
||||
SDL_BlitSurface( spriteEnemy, 0, screen, &destR );
|
||||
}
|
||||
|
||||
void Enemy::drawAirEnemy( SdlCompat_AcceleratedSurface *screen ) {
|
||||
if ( !ENEMY_FLYING[ enemyType ] ) return;
|
||||
|
||||
SDL_Rect destR;
|
||||
|
||||
destR.x = lroundf(pos.getX()) - spriteEnemy->w / 2;
|
||||
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2;
|
||||
destR.w = spriteEnemy->w;
|
||||
destR.h = spriteEnemy->h;
|
||||
|
||||
SDL_BlitSurface( spriteEnemy, 0, screen, &destR );
|
||||
}
|
||||
|
||||
void Enemy::drawShadow( SdlCompat_AcceleratedSurface *screen ) {
|
||||
if ( !ENEMY_FLYING[ enemyType ] ) return;
|
||||
|
||||
SDL_Rect destR;
|
||||
|
||||
destR.x = lroundf(pos.getX()) - spriteShadow->w / 2 - ENEMY_FLYING_HEIGHT[ enemyType ];
|
||||
destR.y = lroundf(pos.getY()) - spriteShadow->h / 2 + ENEMY_FLYING_HEIGHT[ enemyType ];
|
||||
destR.w = spriteShadow->w;
|
||||
destR.h = spriteShadow->h;
|
||||
|
||||
SDL_BlitSurface( spriteShadow, 0, screen, &destR );
|
||||
}
|
||||
|
||||
|
||||
void Enemy::drawStats( SdlCompat_AcceleratedSurface *screen ) {
|
||||
// draw status of the bosses
|
||||
float pixPerHP = spriteEnemy->w / (float)(ENEMY_HITPOINTS[ enemyType ]);
|
||||
SDL_Rect destR;
|
||||
// draw damage
|
||||
destR.x = lroundf(pos.getX()) - spriteEnemy->w / 2;
|
||||
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2 - 4;
|
||||
float damageToDraw = min( (float)ENEMY_HITPOINTS[ enemyType ] / 2, hitpoints );
|
||||
destR.w = lroundf(pixPerHP * damageToDraw);
|
||||
destR.h = 3;
|
||||
SDL_FillRect( screen, &destR, SDL_MapRGB(screen->format, 255, 0, 0) );
|
||||
// draw shields
|
||||
destR.x = lroundf(pos.getX());
|
||||
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2 - 4;
|
||||
float shieldToDraw = min( (float)ENEMY_HITPOINTS[ enemyType ] / 2,
|
||||
hitpoints - ENEMY_HITPOINTS[ enemyType ] / 2 );
|
||||
if ( shieldToDraw < 1 ) destR.w = 0;
|
||||
else destR.w = lroundf(pixPerHP * shieldToDraw);
|
||||
destR.h = 3;
|
||||
SDL_FillRect(screen, &destR, SDL_MapRGB(screen->format, 0, 255, 0) );
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef ENEMY_HH
|
||||
#define ENEMY_HH
|
||||
|
||||
#include "SDL.h"
|
||||
#include "geometry.h"
|
||||
#include <string>
|
||||
#include "shot.h"
|
||||
#include "global.h"
|
||||
|
||||
class Shot;
|
||||
class Shots;
|
||||
class BoundingBox;
|
||||
|
||||
class Enemy {
|
||||
private:
|
||||
SdlCompat_AcceleratedSurface *spriteEnemy;
|
||||
SdlCompat_AcceleratedSurface *spriteShadow;
|
||||
// for collision with racers or shots.
|
||||
// A rectangle with racersize * 0.9 is used.
|
||||
BoundingBox *boundingBox;
|
||||
|
||||
// Movement-System
|
||||
Vector2D pos; // absolute position
|
||||
Vector2D vel; // the velocity vector
|
||||
|
||||
Vector2D relTargetPos;
|
||||
|
||||
// needed for cooldown
|
||||
int nextShotPrimary;
|
||||
int nextShotSecondary;
|
||||
|
||||
int sndShotPrimary;
|
||||
int sndShotSecondary;
|
||||
|
||||
float hitpoints;
|
||||
|
||||
EnemyTypes enemyType;
|
||||
|
||||
bool isInFormation;
|
||||
bool fireByFormation;
|
||||
bool boss2PointReached;
|
||||
Vector2D boss2TargetPos;
|
||||
|
||||
public:
|
||||
Enemy( Vector2D pos, Vector2D vel, EnemyTypes whichEnemyType, bool isInFormation=false,
|
||||
bool fireByFormation=false );
|
||||
~Enemy();
|
||||
|
||||
bool isExpired();
|
||||
void expire();
|
||||
bool isDead() { return ( hitpoints <= 0 ); }
|
||||
|
||||
EnemyTypes getType() { return enemyType; }
|
||||
|
||||
void update( int dT );
|
||||
|
||||
void firePrimary();
|
||||
void fireSecondary();
|
||||
|
||||
// The enemy will make an additional movement of newRelTargetPos.
|
||||
// This is used, when the enemy is part of a formation and should move
|
||||
// to another position in the formation.
|
||||
void setNewRelTargetPos( Vector2D newRelTargetPos ) { relTargetPos = newRelTargetPos; }
|
||||
|
||||
void setPos(Vector2D newPos);
|
||||
Vector2D getPos() { return pos; }
|
||||
Vector2D getVel() { return vel; }
|
||||
Vector2D setVel(Vector2D newVel); // returns old vel
|
||||
|
||||
|
||||
private:
|
||||
// fire the Guns!
|
||||
void shootPrimary( int dT );
|
||||
void shootSecondary( int dT );
|
||||
// moves the enemy according to his velocity
|
||||
void move( int dT );
|
||||
// move the boundingBox accordingly to the movement
|
||||
void updateBoundingBox();
|
||||
|
||||
public:
|
||||
void drawGroundEnemy( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawAirEnemy( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawShadow( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawStats( SdlCompat_AcceleratedSurface *screen );
|
||||
|
||||
// collision system
|
||||
// return if the line between the two points collides with the boundingBox
|
||||
bool collidesWith( const Vector2D &shotPosOld, const Vector2D &shotPosNew );
|
||||
// return if the racers boundingBox overlaps with box
|
||||
bool collidesWith( BoundingBox *box );
|
||||
// return if the racers boundingBox overlaps with circle
|
||||
bool collidesWith( const Circle &circle );
|
||||
// returns if a inner circle around the racer overlaps with circle
|
||||
bool collidesWithAsCircle( const Circle &circle );
|
||||
// returns if a inner circle around the racer overlaps with circle
|
||||
bool collidesWithAsCircle( BoundingBox *box );
|
||||
// returns the boundingBox of the racer
|
||||
BoundingBox *getBoundingBox();
|
||||
Circle getBoundingCircle();
|
||||
|
||||
// the enemy got hit -> do the damage according to the shotType
|
||||
void doDamage( ShotTypes shotType, int fromWhichPlayer );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,374 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include "global.h"
|
||||
#include "enemys.h"
|
||||
#include "enemy.h"
|
||||
#include "racers.h"
|
||||
#include "racer.h"
|
||||
#include "wrecks.h"
|
||||
#include "wreck.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "formation.h"
|
||||
#include "banners.h"
|
||||
#include "options.h"
|
||||
|
||||
Enemys::Enemys() {
|
||||
timeToNextEnemy = GENERATE_ENEMY_DELAY + (rand() % (GENERATE_ENEMY_RAND_DELAY+1));
|
||||
timeToNextFormation =
|
||||
GENERATE_FORMATION_DELAY + (rand() % (GENERATE_FORMATION_RAND_DELAY + 1));
|
||||
bossActive = 0;
|
||||
enemysKilled = 0;
|
||||
enemysGenerated = 0;
|
||||
}
|
||||
|
||||
Enemys::~Enemys() {
|
||||
vector<Enemy *>::iterator i;
|
||||
for (i = enemys.begin(); i != enemys.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
vector<Formation *>::iterator f;
|
||||
for (f = formations.begin(); f != formations.end(); ++f) {
|
||||
delete *f;
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::addEnemy( Enemy *newEnemy ) {
|
||||
if ( newEnemy ) {
|
||||
enemys.push_back( newEnemy );
|
||||
enemysGenerated++;
|
||||
}
|
||||
}
|
||||
|
||||
bool Enemys::minibossDead(){
|
||||
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
|
||||
if ( enemys[ i ]->getType() == BOSS_2 ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Enemys::bossDead() {
|
||||
bool dead = true;
|
||||
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
|
||||
if ( enemys[ i ]->getType() >= NR_ENEMY_TYPES_NORMAL ) {
|
||||
dead = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dead) bossActive = 0;
|
||||
return dead;
|
||||
}
|
||||
|
||||
|
||||
void Enemys::bossTime( int bossNr ) {
|
||||
bossActive = bossNr;
|
||||
Enemy *boss;
|
||||
Wreck *wreck;
|
||||
switch (bossNr) {
|
||||
// Final boss
|
||||
case 1:
|
||||
{
|
||||
wreck = new Wreck( Vector2D( SCREEN_WIDTH / 2 , -120 ), WRECK_BOSS_1_BACKGROUND );
|
||||
wrecks->addWreck( wreck );
|
||||
|
||||
boss = new Enemy( Vector2D( 321, -102 ), Vector2D( 0, SCROLL_SPEED ), BOSS_1_MAIN_GUN );
|
||||
addEnemy( boss );
|
||||
boss = new Enemy( Vector2D( 248, -73 ), Vector2D( 0, SCROLL_SPEED ),
|
||||
BOSS_1_SHOT_BATTERY_LEFT );
|
||||
addEnemy( boss );
|
||||
boss = new Enemy( Vector2D( 393, -73 ), Vector2D( 0, SCROLL_SPEED ),
|
||||
BOSS_1_SHOT_BATTERY_RIGHT );
|
||||
addEnemy( boss );
|
||||
boss = new Enemy( Vector2D( 50, -85 ), Vector2D( 0, SCROLL_SPEED ),
|
||||
BOSS_1_ROCKET_LAUNCHER );
|
||||
addEnemy( boss );
|
||||
boss = new Enemy( Vector2D( 590, -85 ), Vector2D( 0, SCROLL_SPEED ),
|
||||
BOSS_1_ROCKET_LAUNCHER );
|
||||
addEnemy( boss );
|
||||
break;
|
||||
}
|
||||
// Miniboss
|
||||
case 2:
|
||||
{
|
||||
boss = new Enemy( Vector2D( SCREEN_WIDTH / 2 , -100 ),
|
||||
Vector2D( 0, SCROLL_SPEED ), BOSS_2 );
|
||||
addEnemy( boss );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << "Enemys::bossTime: unexpected bossNr: " << bossNr << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Enemys::generateEnemys( int dT ) {
|
||||
if ( bossActive != 0 ) return;
|
||||
|
||||
|
||||
timeToNextFormation -= dT;
|
||||
if ( timeToNextFormation < 0 ) {
|
||||
FormationTypes whichFormation = (FormationTypes)(rand() % NR_FORMATION_TYPES);
|
||||
int flags = 0;
|
||||
if ( rand() % 2 == 0 ) flags = flags | FORMATION_CHANGE_ON_KILL;
|
||||
if ( rand() % 2 == 0 ) {
|
||||
flags = flags | FORMATION_CHANGE_SPONTANEOUS;
|
||||
if ( rand() % 2 == 0 ) flags = flags | FORMATION_CHANGE_OFTEN;
|
||||
else flags = flags | FORMATION_CHANGE_SELDOM;
|
||||
}
|
||||
FormationShotPatterns shotPattern =
|
||||
(FormationShotPatterns)getRandValue( FORMATION_SP_CHANCES, NR_FORMATION_SP );
|
||||
|
||||
Formation *newV =
|
||||
new Formation( whichFormation,
|
||||
Vector2D( 80 + (rand() % (SCREEN_WIDTH - 160)), -100 ),
|
||||
Vector2D( 0, 40 ),
|
||||
FORMATION_MAX_NR_ENEMYS[ whichFormation ] - (rand() % 3),
|
||||
(FormationEnemySets)(rand() % NR_FORMATION_ENEMY_SETS),
|
||||
flags, shotPattern );
|
||||
formations.push_back( newV );
|
||||
|
||||
timeToNextFormation =
|
||||
GENERATE_FORMATION_DELAY + (rand() % (GENERATE_FORMATION_RAND_DELAY + 1));
|
||||
}
|
||||
|
||||
|
||||
timeToNextEnemy -= dT;
|
||||
if ( timeToNextEnemy < 0 ) {
|
||||
int enemyType = getRandValue( ENEMY_APPEAR_CHANCES, NR_ENEMY_TYPES_NORMAL );
|
||||
Enemy *newOne = 0;
|
||||
switch ((EnemyTypes)enemyType) {
|
||||
case FIGHTER:
|
||||
{
|
||||
bool collides;
|
||||
float xpos;
|
||||
for ( int i = 0; i < 10; i++ ) {
|
||||
collides = false;
|
||||
xpos = 20 + rand() % (SCREEN_WIDTH - 40);
|
||||
// check if collides with a formation
|
||||
for ( unsigned int f = 0; f < formations.size(); f++ ) {
|
||||
Vector2D formationCenter = formations[ f ]->getCenter();
|
||||
collides =
|
||||
formationCenter.getY() < 150 &&
|
||||
fabs(xpos - formationCenter.getX()) < 150;
|
||||
if (collides) break;
|
||||
}
|
||||
}
|
||||
if ( !collides ) {
|
||||
newOne = new Enemy( Vector2D( xpos, -20 ), // position
|
||||
Vector2D( (rand() % 5) - 2, rand() % 7 + 3 ) * 10, // velocity
|
||||
FIGHTER );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BOMBER:
|
||||
{
|
||||
bool collides;
|
||||
float xpos;
|
||||
for ( int i = 0; i < 10; i++ ) {
|
||||
collides = false;
|
||||
xpos = 20 + rand() % (SCREEN_WIDTH - 40);
|
||||
// check if collides with a formation
|
||||
for ( unsigned int f = 0; f < formations.size(); f++ ) {
|
||||
Vector2D formationCenter = formations[ f ]->getCenter();
|
||||
collides =
|
||||
formationCenter.getY() < 150 &&
|
||||
fabs(xpos - formationCenter.getX()) < 150;
|
||||
if (collides) break;
|
||||
}
|
||||
}
|
||||
if ( !collides ) {
|
||||
newOne = new Enemy( Vector2D( xpos, -20 ), // position
|
||||
Vector2D( (rand() % 5) - 2, rand() % 3 + 3 ) * 10, // velocity
|
||||
BOMBER );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TANK:
|
||||
{
|
||||
// SdlCompat_AcceleratedSurface *spriteTank = surfaceDB.loadSurface( FN_ENEMY_TANK );
|
||||
// SdlCompat_AcceleratedSurface *spriteTankWreck = surfaceDB.loadSurface( FN_WRECK_TANK );
|
||||
string fn1, fn2;
|
||||
levelConf->getStr( LVL_ENEMY_TANK, fn1 );
|
||||
levelConf->getStr( LVL_WRECK_TANK, fn2 );
|
||||
SdlCompat_AcceleratedSurface *spriteTank = surfaceDB.loadSurface( fn1 );
|
||||
SdlCompat_AcceleratedSurface *spriteTankWreck = surfaceDB.loadSurface( fn2 );
|
||||
int halfWidthTank = spriteTank->w / 2;
|
||||
int halfHeightTank = spriteTank->h / 2;
|
||||
int halfWidthTankWreck = spriteTankWreck->w / 2;
|
||||
int halfHeightTankWreck = spriteTankWreck->h / 2;
|
||||
|
||||
int xPos;
|
||||
|
||||
for ( int i = 0; i < 10; i++ ) {
|
||||
bool collides = false;
|
||||
xPos = halfWidthTank + rand() % (SCREEN_WIDTH - spriteTank->w);
|
||||
// check if collides with another tank
|
||||
for ( unsigned int t = 0; t < enemys.size(); t++ ) {
|
||||
if ( enemys[ t ]->getType() == TANK ) {
|
||||
Vector2D enemyTankPos = enemys[ t ]->getPos();
|
||||
collides =
|
||||
!(enemyTankPos.getX() - halfWidthTank > xPos + halfWidthTank) &&
|
||||
!(enemyTankPos.getX() + halfWidthTank < xPos - halfWidthTank) &&
|
||||
!(enemyTankPos.getY() - halfHeightTank > 0);
|
||||
if (collides) break;
|
||||
}
|
||||
}
|
||||
if (!collides) {
|
||||
// check if collides with an old wreck
|
||||
for ( unsigned int w = 0; w < wrecks->getNrWrecks(); w++ ) {
|
||||
if ( wrecks->getWreck( w )->getType() == WRECK_TANK ) {
|
||||
Vector2D wreckPos = wrecks->getWreck(w)->getPos();
|
||||
collides =
|
||||
!(wreckPos.getX() - halfWidthTankWreck > xPos + halfWidthTank) &&
|
||||
!(wreckPos.getX() + halfWidthTankWreck < xPos - halfWidthTank) &&
|
||||
!(wreckPos.getY() - halfHeightTankWreck > 0);
|
||||
if (collides) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no collision -> generate this enemy
|
||||
if ( !collides ) {
|
||||
// the tank and the background have to be at the same pixel-fraction
|
||||
// to avoid a waggle-effect
|
||||
float correlateToBackground = actBackgroundPos - truncf(actBackgroundPos);
|
||||
newOne = new Enemy( Vector2D( xPos, -halfHeightTank - correlateToBackground ),
|
||||
Vector2D (0, SCROLL_SPEED), // tanks are not moving
|
||||
TANK );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << "generateEnemys(): unexpected enemyType: " << enemyType << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addEnemy( newOne );
|
||||
// +1 for security
|
||||
timeToNextEnemy = GENERATE_ENEMY_DELAY + (rand() % (GENERATE_ENEMY_RAND_DELAY+1));
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::updateEnemys( int dT ) {
|
||||
vector<Formation *>::iterator f;
|
||||
for (f = formations.begin(); f != formations.end(); ++f) {
|
||||
(*f)->update( dT );
|
||||
}
|
||||
vector<Enemy *>::iterator i;
|
||||
for (i = enemys.begin(); i != enemys.end(); ++i) {
|
||||
(*i)->update( dT );
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::doNukeDamage() {
|
||||
vector<Enemy *>::iterator i;
|
||||
for (i = enemys.begin(); i != enemys.end(); ++i) {
|
||||
(*i)->doDamage( SPECIAL_SHOT_NUKE, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Enemys::deleteExpiredEnemys() {
|
||||
unsigned int i = 0;
|
||||
while ( i < enemys.size() ) {
|
||||
if ( enemys[i]->isExpired() ) {
|
||||
if ( enemys[i]->isDead() ) {
|
||||
enemysKilled++;
|
||||
if ( arcadeGame ) {
|
||||
if ( enemysKilled % 50 == 0 ) {
|
||||
banners->addBanner( BANNER_ENEMYS_KILLED,
|
||||
BANNER_MODE_RANDOM,
|
||||
ARCADE_BONUS_FOR_ENEMYS_KILLED );
|
||||
racers->receivePointsArcade( ARCADE_POINTS_FOR_ENEMYS_KILLED );
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( unsigned int f = 0; f < formations.size(); f++ ) {
|
||||
formations[f]->enemyKilled( enemys[i] );
|
||||
}
|
||||
delete enemys[i];
|
||||
enemys.erase(enemys.begin() + i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
unsigned int f = 0;
|
||||
while ( f < formations.size() ) {
|
||||
if ( formations[f]->isExpired() ) {
|
||||
// assert, that the formation is not deleted, because all
|
||||
// enemys in the formation flew out of the screen
|
||||
if ( arcadeGame && formations[f]->getCenter().getY() < SCREEN_HEIGHT + 400 ) {
|
||||
banners->addBanner( (BannerTexts)(rand() % NR_BANNER_TEXTS),
|
||||
BANNER_MODE_RANDOM,
|
||||
ARCADE_BONUS_FOR_FORMATION_DESTRUCTION );
|
||||
racers->receivePointsArcade( ARCADE_POINTS_FOR_FORMATION_DESTRUCTION );
|
||||
}
|
||||
delete formations[f];
|
||||
formations.erase(formations.begin() + f);
|
||||
} else {
|
||||
f++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::drawGroundEnemys(SdlCompat_AcceleratedSurface *screen) {
|
||||
vector<Enemy *>::iterator i;
|
||||
for (i = enemys.begin(); i != enemys.end(); ++i) {
|
||||
(*i)->drawGroundEnemy(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::drawAirEnemys(SdlCompat_AcceleratedSurface *screen) {
|
||||
vector<Enemy *>::iterator i;
|
||||
for (i = enemys.begin(); i != enemys.end(); ++i) {
|
||||
(*i)->drawAirEnemy(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::drawShadows(SdlCompat_AcceleratedSurface *screen) {
|
||||
vector<Enemy *>::iterator i;
|
||||
for (i = enemys.begin(); i != enemys.end(); ++i) {
|
||||
(*i)->drawShadow(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::drawBossStats( SdlCompat_AcceleratedSurface *screen ) {
|
||||
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
|
||||
if ( enemys[ i ]->getType() >= NR_ENEMY_TYPES_NORMAL ) {
|
||||
enemys[ i ]->drawStats( screen );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Enemys::drawAllStats( SdlCompat_AcceleratedSurface *screen ) {
|
||||
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
|
||||
enemys[ i ]->drawStats( screen );
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef ENEMYS_H
|
||||
#define ENEMYS_H
|
||||
|
||||
#include <vector>
|
||||
#include "SDL.h"
|
||||
|
||||
|
||||
class Enemy;
|
||||
class Formation;
|
||||
|
||||
class Enemys {
|
||||
std::vector<Enemy *> enemys;
|
||||
|
||||
std::vector<Formation *> formations;
|
||||
|
||||
int timeToNextEnemy;
|
||||
int timeToNextFormation;
|
||||
|
||||
// if != 0, only the enemys for this boss are generated
|
||||
int bossActive;
|
||||
|
||||
int enemysGenerated;
|
||||
int enemysKilled;
|
||||
|
||||
public:
|
||||
|
||||
Enemys();
|
||||
~Enemys();
|
||||
|
||||
void addEnemy( Enemy *newEnemy );
|
||||
|
||||
bool minibossDead();
|
||||
bool bossDead();
|
||||
void bossTime( int bossNr );
|
||||
void generateEnemys( int dT );
|
||||
void deleteExpiredEnemys();
|
||||
|
||||
inline Enemy *getEnemy(unsigned int i) { return enemys[i]; }
|
||||
inline unsigned int getNrEnemys() { return enemys.size(); }
|
||||
inline int getNrEnemysKilled() { return enemysKilled; }
|
||||
inline int getNrEnemysGenerated() { return enemysGenerated; }
|
||||
|
||||
|
||||
// move and shoot
|
||||
void updateEnemys( int dT );
|
||||
|
||||
// a nuke exploded -> damage all enemys
|
||||
void doNukeDamage();
|
||||
|
||||
// draws the enemys.
|
||||
void drawGroundEnemys( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawAirEnemys( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawShadows( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawBossStats( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawAllStats( SdlCompat_AcceleratedSurface *screen );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,109 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "explosion.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "mixer.h"
|
||||
#include "global.h"
|
||||
|
||||
Explosion::Explosion(string fn, const Vector2D &position,
|
||||
const Vector2D &velocity, const ExplosionTypes &explosionType) {
|
||||
sprite = surfaceDB.loadSurface(fn, true);
|
||||
|
||||
nrAnimStages = sprite->w / sprite->h;
|
||||
expired = false;
|
||||
|
||||
sndExplosion = Mixer::mixer().loadSample( FN_SOUND_EXPLOSION_NORMAL );
|
||||
Mixer::mixer().playSample( sndExplosion, 0 );
|
||||
|
||||
this->explosionType = explosionType;
|
||||
pos = position;
|
||||
vel = velocity;
|
||||
|
||||
switch (explosionType) {
|
||||
case EXPLOSION_NORMAL_AIR:
|
||||
case EXPLOSION_NORMAL_GROUND:
|
||||
{
|
||||
timePerStage = LIFETIME_EXPL_NORMAL / nrAnimStages;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
timePerStage = 0;
|
||||
actAnimStage = nrAnimStages;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
actAnimStage = 0;
|
||||
timeLived = 0;
|
||||
timeNextAnimStage = timePerStage;
|
||||
}
|
||||
|
||||
Explosion::~Explosion() {}
|
||||
|
||||
void Explosion::update( int dT ) {
|
||||
if ( scrollingOn ) pos += vel * dT / 1000.0;
|
||||
timeLived += dT;
|
||||
if ( timeLived > timeNextAnimStage ) {
|
||||
timeNextAnimStage += timePerStage;
|
||||
actAnimStage++;
|
||||
if (actAnimStage == nrAnimStages) expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Explosion::drawAirExplosion(SdlCompat_AcceleratedSurface *screen) {
|
||||
if (expired) return;
|
||||
if ( ! ( explosionType == EXPLOSION_NORMAL_AIR ) ) return;
|
||||
|
||||
SDL_Rect dest;
|
||||
dest.x = lroundf(pos.getX()) - sprite->w / (2*nrAnimStages);
|
||||
dest.y = lroundf(pos.getY()) - sprite->h / 2;
|
||||
dest.w = sprite->w / nrAnimStages;
|
||||
dest.h = sprite->h;
|
||||
|
||||
SDL_Rect src;
|
||||
src.x = actAnimStage * sprite->w / nrAnimStages;
|
||||
src.y = 0;
|
||||
src.w = sprite->w / nrAnimStages;
|
||||
src.h = sprite->h;
|
||||
|
||||
SDL_BlitSurface( sprite, &src, screen, &dest );
|
||||
}
|
||||
|
||||
void Explosion::drawGroundExplosion(SdlCompat_AcceleratedSurface *screen) {
|
||||
if (expired) return;
|
||||
if ( ! ( explosionType == EXPLOSION_NORMAL_GROUND ) ) return;
|
||||
|
||||
SDL_Rect dest;
|
||||
dest.x = lroundf(pos.getX()) - sprite->w / (2*nrAnimStages);
|
||||
dest.y = lroundf(pos.getY()) - sprite->h / 2;
|
||||
dest.w = sprite->w / nrAnimStages;
|
||||
dest.h = sprite->h;
|
||||
|
||||
SDL_Rect src;
|
||||
src.x = actAnimStage * sprite->w / nrAnimStages;
|
||||
src.y = 0;
|
||||
src.w = sprite->w / nrAnimStages;
|
||||
src.h = sprite->h;
|
||||
|
||||
SDL_BlitSurface( sprite, &src, screen, &dest );
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef EXPLOSION_H
|
||||
#define EXPLOSION_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "geometry.h"
|
||||
#include <string>
|
||||
#include "global.h"
|
||||
|
||||
class Explosion {
|
||||
|
||||
// a sprite, that contains horizontally all animationframes of the explosion.
|
||||
// it is assumed, that every frame is quadratic.
|
||||
SdlCompat_AcceleratedSurface *sprite;
|
||||
|
||||
// how many frames does this explosion have?
|
||||
int nrAnimStages;
|
||||
// which frame is now?
|
||||
int actAnimStage;
|
||||
// how long should one frame last (ms)
|
||||
int timePerStage;
|
||||
// how long is the current explosion already active
|
||||
int timeLived;
|
||||
// at what timeLived starts the next frame?
|
||||
int timeNextAnimStage;
|
||||
|
||||
// the explosion can be deleted
|
||||
bool expired;
|
||||
|
||||
int sndExplosion;
|
||||
|
||||
Vector2D pos;
|
||||
Vector2D vel; // the explosion moves - yeah
|
||||
ExplosionTypes explosionType;
|
||||
|
||||
public:
|
||||
Explosion(string fn, const Vector2D &position,
|
||||
const Vector2D &velocity, const ExplosionTypes &explosionType);
|
||||
~Explosion();
|
||||
// updates the position and the counters
|
||||
void update( int dT );
|
||||
void drawAirExplosion(SdlCompat_AcceleratedSurface *screen);
|
||||
void drawGroundExplosion(SdlCompat_AcceleratedSurface *screen);
|
||||
bool isExpired() { return expired; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "explosions.h"
|
||||
#include "explosion.h"
|
||||
|
||||
Explosions::Explosions() {
|
||||
}
|
||||
|
||||
Explosions::~Explosions() {
|
||||
vector<Explosion *>::iterator i;
|
||||
for (i = explosions.begin(); i != explosions.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
void Explosions::addExplosion(Explosion *explosion) {
|
||||
if (explosion) {
|
||||
explosions.push_back(explosion);
|
||||
}
|
||||
}
|
||||
|
||||
void Explosions::drawAirExplosions(SdlCompat_AcceleratedSurface *screen) {
|
||||
vector<Explosion *>::iterator i;
|
||||
for (i = explosions.begin(); i != explosions.end(); ++i) {
|
||||
(*i)->drawAirExplosion(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Explosions::drawGroundExplosions(SdlCompat_AcceleratedSurface *screen) {
|
||||
vector<Explosion *>::iterator i;
|
||||
for (i = explosions.begin(); i != explosions.end(); ++i) {
|
||||
(*i)->drawGroundExplosion(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Explosions::updateExplosions( int dT ) {
|
||||
vector<Explosion *>::iterator i;
|
||||
for (i = explosions.begin(); i != explosions.end(); ++i) {
|
||||
(*i)->update( dT );
|
||||
}
|
||||
}
|
||||
|
||||
void Explosions::expireExplosions() {
|
||||
unsigned int i = 0;
|
||||
while ( i < explosions.size() ) {
|
||||
if ( explosions[i]->isExpired() ) {
|
||||
delete explosions[i];
|
||||
explosions.erase(explosions.begin() + i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef EXPLOSIONS_H
|
||||
#define EXPLOSIONS_H
|
||||
|
||||
#include <vector>
|
||||
#include "SDL.h"
|
||||
#include "SdlForwardCompat.h"
|
||||
|
||||
class Explosion;
|
||||
|
||||
/* manages the explosion-objects */
|
||||
class Explosions {
|
||||
vector<Explosion *> explosions;
|
||||
|
||||
public:
|
||||
Explosions();
|
||||
~Explosions();
|
||||
|
||||
inline unsigned int getNrExplosions() { return explosions.size(); }
|
||||
|
||||
void addExplosion( Explosion *explosion );
|
||||
// moves the explosions and updates the counters
|
||||
void updateExplosions( int dT );
|
||||
// deletes the explosions, that have timed out
|
||||
void expireExplosions();
|
||||
// draws all explosions
|
||||
void drawAirExplosions( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawGroundExplosions( SdlCompat_AcceleratedSurface *screen );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,158 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "font.h"
|
||||
#include "global.h"
|
||||
#include "surfaceDB.h"
|
||||
#include <iostream>
|
||||
|
||||
Font::Font(string fn) {
|
||||
sprites[0] = surfaceDB.loadSurface( fn + "-1.bmp" );
|
||||
sprites[1] = surfaceDB.loadSurface( fn + "-2.bmp" );
|
||||
sprites[2] = surfaceDB.loadSurface( fn + "-3.bmp" );
|
||||
charset = " ABCDEFGHIJKLMNOPQRSTUVWXYZÜÄÖabcdefghijklmnopqrstuvwxyzüäöß0123456789!\"§$%&/()=?*+'#,.-;:_@°\\";
|
||||
// 94 Zeichen
|
||||
charWidth = sprites[0]->w / MAX_CHARS_PER_TEXTURE;
|
||||
charHeight = sprites[0]->h;
|
||||
}
|
||||
|
||||
Font::~Font() {
|
||||
;
|
||||
}
|
||||
|
||||
void Font::setCharWidth(int width) {
|
||||
charWidth = width;
|
||||
}
|
||||
|
||||
int Font::getCharWidth() {
|
||||
return charWidth;
|
||||
}
|
||||
|
||||
int Font::getCharHeight() {
|
||||
return sprites[0]->h;
|
||||
}
|
||||
|
||||
void Font::drawInt(SdlCompat_AcceleratedSurface *screen, int posx, int posy, int val, int alignDigitCnt, int flags) {
|
||||
int indent = 0;
|
||||
int digitCnt = 1;
|
||||
int i=1;
|
||||
while ( val >= i*10 ) {
|
||||
digitCnt++;
|
||||
i *= 10;
|
||||
}
|
||||
|
||||
// cout << endl << "drawInt.val=" << val << endl;
|
||||
// cout << "drawInt.digitCnt=" << digitCnt << endl;
|
||||
// cout << "drawInt.alignDigitCnt-old=" << alignDigitCnt << endl;
|
||||
|
||||
if (alignDigitCnt < digitCnt) {
|
||||
alignDigitCnt = digitCnt;
|
||||
}
|
||||
// cout << "drawInt.alignDigitCnt-new=" << alignDigitCnt << endl;
|
||||
|
||||
if (flags & FONT_ALIGN_CENTERED) {
|
||||
indent = -(alignDigitCnt * charWidth) / 2;
|
||||
}
|
||||
if (flags & FONT_ALIGN_RIGHT) {
|
||||
indent = -(alignDigitCnt * charWidth);
|
||||
}
|
||||
|
||||
SDL_Rect destR;
|
||||
SDL_Rect srcR;
|
||||
while (alignDigitCnt > 0) {
|
||||
if ((digitCnt > 0) ||
|
||||
((flags & FONT_ALIGN_FILL_ZERO) != 0)) {
|
||||
|
||||
destR.x = indent + posx + (alignDigitCnt-1) * charWidth;
|
||||
destR.y = posy;
|
||||
destR.w = charWidth;
|
||||
destR.h = charHeight;
|
||||
|
||||
unsigned int charsetpos = charset.find( (char)((val % 10) + '0') );
|
||||
if (charsetpos == string::npos )
|
||||
charsetpos = 0; // Space
|
||||
srcR.x = (charsetpos % MAX_CHARS_PER_TEXTURE) * charWidth;
|
||||
|
||||
// srcR.x = (1 + 2*26 + (val % 10)) * charWidth;
|
||||
srcR.y = 0;
|
||||
srcR.w = charWidth;
|
||||
srcR.h = charHeight;
|
||||
|
||||
SDL_BlitSurface( sprites[charsetpos / MAX_CHARS_PER_TEXTURE], &srcR, screen, &destR );
|
||||
}
|
||||
val /= 10;
|
||||
digitCnt--;
|
||||
alignDigitCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Font::drawStr(SdlCompat_AcceleratedSurface *screen, int posx, int posy, const string &text, int flags) {
|
||||
|
||||
int indent = 0;
|
||||
if ( flags & (FONT_ALIGN_CENTERED | FONT_ALIGN_RIGHT) ) {
|
||||
for(unsigned int i=0; i < text.size(); ++i) {
|
||||
if (!(flags & FONT_MONOSPACE) && text[i] == ' ') {
|
||||
indent += ((charWidth * 2) / 3);
|
||||
} else {
|
||||
indent += charWidth;
|
||||
}
|
||||
}
|
||||
if (flags & FONT_ALIGN_CENTERED) {
|
||||
indent = -indent / 2;
|
||||
} else {
|
||||
indent = -indent;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect destR;
|
||||
SDL_Rect srcR;
|
||||
|
||||
int x = 0;
|
||||
unsigned int charsetpos;
|
||||
for(unsigned int i=0; i < text.size(); ++i) {
|
||||
x = 0;
|
||||
charsetpos = charset.find(text[i]);
|
||||
if (charsetpos == string::npos )
|
||||
charsetpos = 0; // Space
|
||||
x = (charsetpos % MAX_CHARS_PER_TEXTURE) * charWidth;
|
||||
|
||||
destR.x = posx + indent;
|
||||
destR.y = posy;
|
||||
destR.w = charWidth;
|
||||
destR.h = sprites[0]->h;
|
||||
|
||||
srcR.x = x;
|
||||
srcR.y = 0;
|
||||
srcR.w = charWidth;
|
||||
srcR.h = sprites[0]->h;
|
||||
|
||||
SDL_BlitSurface( sprites[charsetpos / MAX_CHARS_PER_TEXTURE], &srcR, screen, &destR );
|
||||
|
||||
if (!(flags & FONT_MONOSPACE) && text[i] == ' ') {
|
||||
posx += ((charWidth * 2) / 3);
|
||||
} else {
|
||||
posx += charWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef FONT_H
|
||||
#define FONT_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include <string>
|
||||
#include "SdlForwardCompat.h"
|
||||
|
||||
// *** Code ***
|
||||
//
|
||||
// font->drawStr( screen, 150, 260, "Zeile 1" );
|
||||
// font->drawStr( screen, 150, 290, "Zeile 2", FONT_ALIGN_CENTERED );
|
||||
// font->drawStr( screen, 150, 320, "Zeile 3", FONT_ALIGN_RIGHT );
|
||||
// font->drawInt( screen, 150, 350, 123, 0 );
|
||||
// font->drawInt( screen, 150, 380, 123, 0, FONT_ALIGN_FILL_ZERO );
|
||||
// font->drawInt( screen, 150, 410, 123, 6 );
|
||||
// font->drawInt( screen, 150, 440, 123, 6, FONT_ALIGN_FILL_ZERO );
|
||||
// font->drawInt( screen, 150, 400, 123, 6, FONT_ALIGN_CENTERED );
|
||||
// font->drawInt( screen, 150, 425, 123, 6, FONT_ALIGN_CENTERED | FONT_ALIGN_FILL_ZERO );
|
||||
// font->drawInt( screen, 150, 350, 123, 6, FONT_ALIGN_RIGHT );
|
||||
// font->drawInt( screen, 150, 375, 123, 6, FONT_ALIGN_RIGHT | FONT_ALIGN_FILL_ZERO );
|
||||
//
|
||||
// *** Result ***
|
||||
//
|
||||
// Zeile 1
|
||||
// Zeile 2
|
||||
// Zeile 3
|
||||
// 123
|
||||
// 123
|
||||
// 123
|
||||
// 000123
|
||||
// 123
|
||||
// 000123
|
||||
// 123
|
||||
// 000123
|
||||
|
||||
const int FONT_ALIGN_FILL_ZERO = (1<<0); // fill with leading zeros
|
||||
const int FONT_ALIGN_CENTERED = (1<<1); // text centered around posx/posy
|
||||
const int FONT_ALIGN_RIGHT = (1<<2); // text aligned right (on the left side of posx)
|
||||
const int FONT_MONOSPACE = (1<<3);
|
||||
|
||||
class Font {
|
||||
private:
|
||||
enum { MAX_CHARS_PER_TEXTURE = 32 }; // OpenGL ES does not allow textures wider than 1024 bytes, so we have to split it
|
||||
SdlCompat_AcceleratedSurface *sprites[3]; // Our font has only 94 letters
|
||||
int charWidth;
|
||||
int charHeight;
|
||||
std::string charset;
|
||||
|
||||
public:
|
||||
Font(std::string fn);
|
||||
~Font();
|
||||
|
||||
void setCharWidth(int width);
|
||||
int getCharWidth();
|
||||
int getCharHeight();
|
||||
void drawInt(SdlCompat_AcceleratedSurface *screen, int posx, int posy, int val, int alignDigitCnt, int flags = 0);
|
||||
void drawStr(SdlCompat_AcceleratedSurface *screen, int posx, int posy, const std::string &text, int flags = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,645 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "formation.h"
|
||||
#include "enemy.h"
|
||||
#include "enemys.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Formation::Formation( FormationTypes whichFormation, Vector2D centerAtStart,
|
||||
Vector2D startVel, int nrEnemys,
|
||||
FormationEnemySets enemyTypes,
|
||||
int flagsFormationChangePolicy,
|
||||
FormationShotPatterns shotPattern ) {
|
||||
|
||||
formationType = whichFormation;
|
||||
formationCenter = centerAtStart;
|
||||
formationSpeed = startVel;
|
||||
|
||||
changeOnKill = flagsFormationChangePolicy & FORMATION_CHANGE_ON_KILL;
|
||||
changeSpontaneous = flagsFormationChangePolicy & FORMATION_CHANGE_SPONTANEOUS;
|
||||
changeOften = flagsFormationChangePolicy & FORMATION_CHANGE_OFTEN;
|
||||
changeSeldom = flagsFormationChangePolicy & FORMATION_CHANGE_SELDOM;
|
||||
if ( changeSpontaneous && !changeSeldom && !changeOften ) changeSeldom = true;
|
||||
if ( changeOften ) {
|
||||
nextFormationChange =
|
||||
FORMATION_CHANGE_OFTEN_DELAY +
|
||||
rand() % (FORMATION_CHANGE_OFTEN_RAND_DELAY+1);
|
||||
} else if ( changeSeldom ) {
|
||||
nextFormationChange =
|
||||
FORMATION_CHANGE_SELDOM_DELAY +
|
||||
rand() % (FORMATION_CHANGE_SELDOM_RAND_DELAY+1);
|
||||
}
|
||||
|
||||
if ( nrEnemys > FORMATION_MAX_NR_ENEMYS[ formationType ] )
|
||||
nrInvolved = FORMATION_MAX_NR_ENEMYS[ formationType ];
|
||||
else if ( nrEnemys < 0 ) nrInvolved = 0;
|
||||
else nrInvolved = nrEnemys;
|
||||
|
||||
this->shotPattern = shotPattern;
|
||||
actShootingEnemy = 0;
|
||||
|
||||
if ( shotPattern == FORMATION_SP_NONE ) formationFires = false;
|
||||
else formationFires = true;
|
||||
|
||||
vector<Vector2D> targetPos;
|
||||
fillTargetPos( targetPos );
|
||||
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
Enemy *newOne;
|
||||
switch ( enemyTypes ) {
|
||||
case FORMATION_ENEMY_SET_DEFAULT:
|
||||
case FORMATION_ENEMY_SET_FIGHTER:
|
||||
{
|
||||
newOne = new Enemy( formationCenter + targetPos[ i ], formationSpeed, FIGHTER,
|
||||
true, formationFires );
|
||||
break;
|
||||
}
|
||||
case FORMATION_ENEMY_SET_BOMBER:
|
||||
{
|
||||
newOne = new Enemy( formationCenter + targetPos[ i ], formationSpeed, BOMBER,
|
||||
true, formationFires );
|
||||
break;
|
||||
}
|
||||
case FORMATION_ENEMY_SET_FIGHTER_BOMBER:
|
||||
{
|
||||
newOne =
|
||||
new Enemy( formationCenter + targetPos[ i ], formationSpeed,
|
||||
(EnemyTypes)(FIGHTER + (i % 2)),
|
||||
true, formationFires );
|
||||
break;
|
||||
}
|
||||
}
|
||||
enemys->addEnemy( newOne );
|
||||
involvedEnemys.push_back( newOne );
|
||||
}
|
||||
|
||||
enemyWasKilled = false;
|
||||
// wait at least 100 ms before the first shot
|
||||
nextFirePrimary = 100;
|
||||
nextFireSecondary = 100;
|
||||
|
||||
// cout << "Type: " << formationType << " SP: " << shotPattern << endl;
|
||||
}
|
||||
|
||||
Formation::~Formation() {}
|
||||
|
||||
|
||||
void Formation::enemyKilled( Enemy *killedEnemy ) {
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
if ( involvedEnemys[i] == killedEnemy ) {
|
||||
enemyWasKilled = true;
|
||||
involvedEnemys.erase( involvedEnemys.begin() + i );
|
||||
nrInvolved--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Formation::update( int dT ) {
|
||||
if ( changeSpontaneous ) handleSpontaneousFormationChange( dT );
|
||||
|
||||
if ( enemyWasKilled ) {
|
||||
// change the formation?
|
||||
if ( changeOnKill && (rand() % 100 < 70) ) chooseNewFormationType();
|
||||
moveEnemyInFormation();
|
||||
enemyWasKilled = false;
|
||||
}
|
||||
formationCenter += formationSpeed * dT / 1000.0;
|
||||
shoot( dT );
|
||||
}
|
||||
|
||||
|
||||
void Formation::handleSpontaneousFormationChange( int dT ) {
|
||||
nextFormationChange -= dT;
|
||||
if ( changeSpontaneous && nextFormationChange < 0 ) {
|
||||
|
||||
chooseNewFormationType();
|
||||
moveEnemyInFormation();
|
||||
|
||||
if ( changeOften ) {
|
||||
nextFormationChange =
|
||||
FORMATION_CHANGE_OFTEN_DELAY +
|
||||
rand() % (FORMATION_CHANGE_OFTEN_RAND_DELAY+1);
|
||||
} else if ( changeSeldom ) {
|
||||
nextFormationChange =
|
||||
FORMATION_CHANGE_SELDOM_DELAY +
|
||||
rand() % (FORMATION_CHANGE_SELDOM_RAND_DELAY+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::moveEnemyInFormation() {
|
||||
// calc the target positions in the new formation (relative to the center of the formation)
|
||||
vector<Vector2D> targetPos;
|
||||
fillTargetPos( targetPos );
|
||||
|
||||
// choose the best mapping from enemy to targetPosition
|
||||
// (shortest way for enemy to its position is best)
|
||||
vector<Vector2D> relPosForEnemies;
|
||||
getBestMapping( targetPos, relPosForEnemies );
|
||||
|
||||
// give the enemy its order
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
involvedEnemys[i]->setNewRelTargetPos( relPosForEnemies[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::chooseNewFormationType() {
|
||||
bool found = false;
|
||||
int i = 0;
|
||||
while ( i < 10 && !found ) {
|
||||
FormationTypes newFormationType = (FormationTypes)(rand() % (NR_FORMATION_TYPES-1));
|
||||
if ( formationType == newFormationType ) {
|
||||
newFormationType = (FormationTypes)(NR_FORMATION_TYPES - 1);
|
||||
}
|
||||
if ( nrInvolved <= FORMATION_MAX_NR_ENEMYS[ newFormationType ] ) {
|
||||
formationType = newFormationType;
|
||||
found = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::fillTargetPos( vector<Vector2D> &targetPos ) {
|
||||
switch ( formationType ) {
|
||||
case FORMATION_V:
|
||||
{
|
||||
fillTargetPosFormationV( targetPos );
|
||||
break;
|
||||
}
|
||||
case FORMATION_REVERSE_V:
|
||||
{
|
||||
fillTargetPosFormationReverseV( targetPos );
|
||||
break;
|
||||
}
|
||||
case FORMATION_BLOCK:
|
||||
{
|
||||
fillTargetPosFormationBlock( targetPos );
|
||||
break;
|
||||
}
|
||||
case FORMATION_LINE:
|
||||
{
|
||||
fillTargetPosFormationLine( targetPos );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::fillTargetPosFormationV( vector<Vector2D> &targetPos ) {
|
||||
switch ( nrInvolved ) {
|
||||
case 1:
|
||||
{
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-30,0) );
|
||||
targetPos.push_back( Vector2D(30,0) );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-50,25) );
|
||||
targetPos.push_back( Vector2D(0,-25) );
|
||||
targetPos.push_back( Vector2D(50,25) );
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-80,25) );
|
||||
targetPos.push_back( Vector2D(-30,-25) );
|
||||
targetPos.push_back( Vector2D(30,-25) );
|
||||
targetPos.push_back( Vector2D(80,25) );
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-100,50) );
|
||||
targetPos.push_back( Vector2D(-50,0) );
|
||||
targetPos.push_back( Vector2D(0,-50) );
|
||||
targetPos.push_back( Vector2D(50,0) );
|
||||
targetPos.push_back( Vector2D(100,50) );
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-130,50) );
|
||||
targetPos.push_back( Vector2D(-80,0) );
|
||||
targetPos.push_back( Vector2D(-30,-50) );
|
||||
targetPos.push_back( Vector2D(30,-50) );
|
||||
targetPos.push_back( Vector2D(80,0) );
|
||||
targetPos.push_back( Vector2D(130,50) );
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-150,75) );
|
||||
targetPos.push_back( Vector2D(-100,25) );
|
||||
targetPos.push_back( Vector2D(-50,-25) );
|
||||
targetPos.push_back( Vector2D(0,-75) );
|
||||
targetPos.push_back( Vector2D(50,-25) );
|
||||
targetPos.push_back( Vector2D(100,25) );
|
||||
targetPos.push_back( Vector2D(150,75) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << "fillTargetPosFormationV: too many enemys involved: " << nrInvolved << endl;
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::fillTargetPosFormationReverseV( vector<Vector2D> &targetPos ) {
|
||||
switch ( nrInvolved ) {
|
||||
case 1:
|
||||
{
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-30,0) );
|
||||
targetPos.push_back( Vector2D(30,0) );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-50,-25) );
|
||||
targetPos.push_back( Vector2D(0,25) );
|
||||
targetPos.push_back( Vector2D(50,-25) );
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-80,-25) );
|
||||
targetPos.push_back( Vector2D(-30,25) );
|
||||
targetPos.push_back( Vector2D(30,25) );
|
||||
targetPos.push_back( Vector2D(80,-25) );
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-100,-50) );
|
||||
targetPos.push_back( Vector2D(-50,0) );
|
||||
targetPos.push_back( Vector2D(0,50) );
|
||||
targetPos.push_back( Vector2D(50,0) );
|
||||
targetPos.push_back( Vector2D(100,-50) );
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-130,-50) );
|
||||
targetPos.push_back( Vector2D(-80,0) );
|
||||
targetPos.push_back( Vector2D(-30,50) );
|
||||
targetPos.push_back( Vector2D(30,50) );
|
||||
targetPos.push_back( Vector2D(80,0) );
|
||||
targetPos.push_back( Vector2D(130,-50) );
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-150,-75) );
|
||||
targetPos.push_back( Vector2D(-100,-25) );
|
||||
targetPos.push_back( Vector2D(-50,25) );
|
||||
targetPos.push_back( Vector2D(0,75) );
|
||||
targetPos.push_back( Vector2D(50,25) );
|
||||
targetPos.push_back( Vector2D(100,-25) );
|
||||
targetPos.push_back( Vector2D(150,-75) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << "fillTargetPosFormationReverseV: too many enemys involved: "
|
||||
<< nrInvolved << endl;
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::fillTargetPosFormationBlock( vector<Vector2D> &targetPos ) {
|
||||
switch ( nrInvolved ) {
|
||||
case 1:
|
||||
{
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-30,0) );
|
||||
targetPos.push_back( Vector2D(30,0) );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-30,25) );
|
||||
targetPos.push_back( Vector2D(0,-25) );
|
||||
targetPos.push_back( Vector2D(30,25) );
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-30,-25) );
|
||||
targetPos.push_back( Vector2D(-30,25) );
|
||||
targetPos.push_back( Vector2D(30,-25) );
|
||||
targetPos.push_back( Vector2D(30,25) );
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-40,-30) );
|
||||
targetPos.push_back( Vector2D(-40,30) );
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
targetPos.push_back( Vector2D(40,-30) );
|
||||
targetPos.push_back( Vector2D(40,30) );
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-60,-30) );
|
||||
targetPos.push_back( Vector2D(-60,30) );
|
||||
targetPos.push_back( Vector2D(0,-30) );
|
||||
targetPos.push_back( Vector2D(0,30) );
|
||||
targetPos.push_back( Vector2D(60,-30) );
|
||||
targetPos.push_back( Vector2D(60,30) );
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-60,-50) );
|
||||
targetPos.push_back( Vector2D(-60,0) );
|
||||
targetPos.push_back( Vector2D(0,-50) );
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
targetPos.push_back( Vector2D(0,50) );
|
||||
targetPos.push_back( Vector2D(60,-50) );
|
||||
targetPos.push_back( Vector2D(60,0) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << "fillTargetPosFormationBlock: too many enemys involved: " << nrInvolved << endl;
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Formation::fillTargetPosFormationLine( vector<Vector2D> &targetPos ) {
|
||||
switch ( nrInvolved ) {
|
||||
case 1:
|
||||
{
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-30,0) );
|
||||
targetPos.push_back( Vector2D(30,0) );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-60,0) );
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
targetPos.push_back( Vector2D(60,0) );
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-90,0) );
|
||||
targetPos.push_back( Vector2D(-30,0) );
|
||||
targetPos.push_back( Vector2D(30,0) );
|
||||
targetPos.push_back( Vector2D(90,0) );
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-120,0) );
|
||||
targetPos.push_back( Vector2D(-60,0) );
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
targetPos.push_back( Vector2D(60,0) );
|
||||
targetPos.push_back( Vector2D(120,0) );
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
targetPos.push_back( Vector2D(-150,0) );
|
||||
targetPos.push_back( Vector2D(-90,0) );
|
||||
targetPos.push_back( Vector2D(-30,0) );
|
||||
targetPos.push_back( Vector2D(30,0) );
|
||||
targetPos.push_back( Vector2D(90,0) );
|
||||
targetPos.push_back( Vector2D(150,0) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << "fillTargetPosFormationLine: too many enemys involved: " << nrInvolved << endl;
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
targetPos.push_back( Vector2D(0,0) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
void Formation::getBestMapping( vector<Vector2D> &targetPos,
|
||||
vector<Vector2D> &relPosForFighters ) {
|
||||
|
||||
int actPerm[nrInvolved];
|
||||
vector<Vector2D> *bestMapping = new vector<Vector2D>();
|
||||
vector<Vector2D> *testMapping = new vector<Vector2D>();
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
bestMapping->push_back( Vector2D( 0,0 ) );
|
||||
testMapping->push_back( Vector2D( 0,0 ) );
|
||||
actPerm[ i ] = i;
|
||||
}
|
||||
float mapCost = 1000000;
|
||||
|
||||
int nrPerm = factorial( nrInvolved );
|
||||
|
||||
for ( int perm = 0; perm < nrPerm; perm++ ) {
|
||||
calcNextPerm( actPerm );
|
||||
float testMappingCost = calcTestMapping( actPerm, targetPos, testMapping );
|
||||
if ( mapCost > testMappingCost ) {
|
||||
vector<Vector2D> *tmpMapping = bestMapping;
|
||||
bestMapping = testMapping;
|
||||
testMapping = tmpMapping;
|
||||
mapCost = testMappingCost;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int e = 0; e < nrInvolved; e++ ) {
|
||||
relPosForFighters.push_back( (*bestMapping)[e] );
|
||||
}
|
||||
delete bestMapping;
|
||||
delete testMapping;
|
||||
}
|
||||
|
||||
|
||||
void Formation::calcNextPerm( int *perm ) {
|
||||
int n = nrInvolved;
|
||||
int i = n-1;
|
||||
int j = n;
|
||||
int tmp;
|
||||
|
||||
while ( i != 0 && perm[ i-1 ] >= perm[ i ] ) {
|
||||
i--;
|
||||
}
|
||||
if ( i == 0 ) {
|
||||
for ( int k = 0; k < n/2; k++ ) {
|
||||
tmp = perm[ k ];
|
||||
perm[ k ] = perm[ n - k - 1 ];
|
||||
perm[ n - k - 1 ] = tmp;
|
||||
}
|
||||
return;
|
||||
}
|
||||
while ( perm[ j-1 ] <= perm[ i-1 ] ) {
|
||||
--j;
|
||||
}
|
||||
tmp = perm[ i-1 ];
|
||||
perm[ i-1 ] = perm[ j-1 ];
|
||||
perm[ j-1 ] = tmp;
|
||||
|
||||
i++;
|
||||
j = n;
|
||||
|
||||
while ( i < j ) {
|
||||
tmp = perm[ i-1 ];
|
||||
perm[ i-1 ] = perm[ j-1 ];
|
||||
perm[ j-1 ] = tmp;
|
||||
i++;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float Formation::calcTestMapping( int *perm, vector<Vector2D> &targetPos,
|
||||
vector<Vector2D> *mapping ) {
|
||||
|
||||
float cost = 0;
|
||||
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
// enemy i shall fly to the position targetPos[perm[i]]
|
||||
// save the vector from its actual pos to its new targetpos in mapping
|
||||
(*mapping)[ i ] =
|
||||
targetPos[ perm[i] ] + formationCenter -
|
||||
involvedEnemys[ i ]->getPos();
|
||||
|
||||
if ( cost < (*mapping)[ i ].getLength() ) {
|
||||
cost = (*mapping)[ i ].getLength();
|
||||
}
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
int Formation::factorial( int n ) {
|
||||
int result = 1;
|
||||
for ( int i = 2; i <= n; i++ ) {
|
||||
result *= i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Formation::shoot( int dT ) {
|
||||
if ( shotPattern == FORMATION_SP_NONE ) return;
|
||||
nextFirePrimary -= dT;
|
||||
// nextFireSecondary -= dT;
|
||||
|
||||
float enemyRatio = FORMATION_MAX_NR_ENEMYS[ formationType ] / (float)nrInvolved;
|
||||
|
||||
while ( nextFirePrimary < 0 ) {
|
||||
switch ( shotPattern ) {
|
||||
case FORMATION_SP_VOLLEY_FAST:
|
||||
case FORMATION_SP_VOLLEY_MEDIUM:
|
||||
case FORMATION_SP_VOLLEY_SLOW:
|
||||
{
|
||||
for ( int i = 0; i < nrInvolved; i++ ) {
|
||||
involvedEnemys[ i ]->firePrimary();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FORMATION_SP_RAND_FAST:
|
||||
case FORMATION_SP_RAND_MEDIUM:
|
||||
case FORMATION_SP_RAND_SLOW:
|
||||
{
|
||||
involvedEnemys[ rand() % nrInvolved ]->firePrimary();
|
||||
break;
|
||||
}
|
||||
case FORMATION_SP_LEFT_RIGHT_FAST:
|
||||
case FORMATION_SP_LEFT_RIGHT_MEDIUM:
|
||||
{
|
||||
actShootingEnemy = (actShootingEnemy + 1) % nrInvolved;
|
||||
involvedEnemys[ actShootingEnemy ]->firePrimary();
|
||||
break;
|
||||
}
|
||||
case FORMATION_SP_RIGHT_LEFT_FAST:
|
||||
case FORMATION_SP_RIGHT_LEFT_MEDIUM:
|
||||
{
|
||||
actShootingEnemy--;
|
||||
if ( actShootingEnemy < 0 ) actShootingEnemy = nrInvolved-1;
|
||||
involvedEnemys[ actShootingEnemy ]->firePrimary();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nextFirePrimary +=
|
||||
lroundf( (FORMATION_SP_PRIMARY_DELAY[ shotPattern ] +
|
||||
rand() % (FORMATION_SP_PRIMARY_RAND_DELAY[ shotPattern ] + 1)) * enemyRatio );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef FORMATION_H
|
||||
#define FORMATION_H
|
||||
|
||||
#include <vector>
|
||||
#include "global.h"
|
||||
#include "geometry.h"
|
||||
|
||||
class Enemy;
|
||||
|
||||
class Formation {
|
||||
private:
|
||||
std::vector<Enemy *> involvedEnemys;
|
||||
int nrInvolved;
|
||||
|
||||
FormationTypes formationType;
|
||||
|
||||
Vector2D formationCenter;
|
||||
Vector2D formationSpeed;
|
||||
|
||||
bool enemyWasKilled;
|
||||
|
||||
bool formationFires;
|
||||
int nextFirePrimary;
|
||||
int nextFireSecondary;
|
||||
|
||||
bool changeOnKill, changeSpontaneous, changeOften, changeSeldom;
|
||||
int nextFormationChange;
|
||||
FormationShotPatterns shotPattern;
|
||||
int actShootingEnemy;
|
||||
|
||||
void chooseNewFormationType();
|
||||
|
||||
void handleSpontaneousFormationChange( int dT );
|
||||
void moveEnemyInFormation();
|
||||
void fillTargetPos( vector<Vector2D> &targetPos );
|
||||
void fillTargetPosFormationV( vector<Vector2D> &targetPos );
|
||||
void fillTargetPosFormationReverseV( vector<Vector2D> &targetPos );
|
||||
void fillTargetPosFormationBlock( vector<Vector2D> &targetPos );
|
||||
void fillTargetPosFormationLine( vector<Vector2D> &targetPos );
|
||||
void getBestMapping( vector<Vector2D> &targetPos,
|
||||
vector<Vector2D> &relPosForFighters );
|
||||
|
||||
void calcNextPerm( int *perm );
|
||||
float calcTestMapping( int *perm, vector<Vector2D> &targetPos,
|
||||
vector<Vector2D> *mapping );
|
||||
int factorial( int n );
|
||||
|
||||
void shoot( int dT );
|
||||
|
||||
public:
|
||||
Formation( FormationTypes whichFormation, Vector2D centerAtStart,
|
||||
Vector2D startVel, int nrEnemys=66,
|
||||
FormationEnemySets enemyTypes=FORMATION_ENEMY_SET_DEFAULT,
|
||||
int flagsFormationChangePolicy=0,
|
||||
FormationShotPatterns shotPattern=FORMATION_SP_NONE );
|
||||
~Formation();
|
||||
|
||||
Vector2D getCenter() { return formationCenter; }
|
||||
|
||||
void enemyKilled( Enemy *killedEnemy );
|
||||
void update( int dT );
|
||||
bool isExpired() { return (nrInvolved == 0); }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,963 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sstream>
|
||||
#include <android/log.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "mixer.h"
|
||||
#include "game.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "racers.h"
|
||||
#include "racer.h"
|
||||
#include "video.h"
|
||||
#include "shots.h"
|
||||
#include "shot.h"
|
||||
#include "items.h"
|
||||
#include "explosions.h"
|
||||
#include "explosion.h"
|
||||
#include "enemys.h"
|
||||
#include "font.h"
|
||||
#include "mixer.h"
|
||||
#include "input.h"
|
||||
#include "wrecks.h"
|
||||
#include "wreck.h"
|
||||
#include "global.h"
|
||||
#include "settings.h"
|
||||
#include "intro.h"
|
||||
#include "setDifficulty.h"
|
||||
#include "menuArcadeMode.h"
|
||||
#include "asstring.h"
|
||||
#include "sonic.h"
|
||||
#include "banners.h"
|
||||
#include "banner.h"
|
||||
#include "smokePuffs.h"
|
||||
#include "background.h"
|
||||
#include "options.h"
|
||||
|
||||
Racers *racers = NULL;
|
||||
Enemys *enemys = NULL;
|
||||
Shots *shots = NULL;
|
||||
Explosions *explosions = NULL;
|
||||
Items *items = NULL;
|
||||
Wrecks *wrecks = NULL;
|
||||
Banners *banners = NULL;
|
||||
SmokePuffs *smokePuffs = NULL;
|
||||
Options *levelConf = NULL;
|
||||
|
||||
bool scrollingOn;
|
||||
bool nukeIsInPlace;
|
||||
bool playMusicOn;
|
||||
bool onePlayerGame;
|
||||
bool arcadeGame;
|
||||
int difficultyLevel;
|
||||
float actBackgroundPos;
|
||||
|
||||
Game::Game() {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 1");
|
||||
videoserver = new Video();
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 2");
|
||||
screen = 0;
|
||||
screen = videoserver->init();
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 3");
|
||||
settings = new Settings();
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 4");
|
||||
intro = new Intro( screen );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 5");
|
||||
setDifficulty = new SetDifficulty( screen );
|
||||
menuArcadeMode = new MenuArcadeMode( screen );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 6");
|
||||
|
||||
pauseSprite = surfaceDB.loadSurface( FN_PAUSED );
|
||||
youLoseSprite = surfaceDB.loadSurface( FN_YOU_LOSE );
|
||||
youWinSprite = surfaceDB.loadSurface( FN_YOU_WIN );
|
||||
// for arcadeMode
|
||||
gameOverSprite = surfaceDB.loadSurface( FN_GAME_OVER );
|
||||
|
||||
nukeEffectSurface = surfaceDB.loadSurface( FN_NUKE_EFFECT );
|
||||
|
||||
bossAlarm = Mixer::mixer().loadSample( FN_SOUND_BOSS_ALARM, 60 );
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 7");
|
||||
|
||||
fontTime = new Font( FN_FONT_NUMBERS_TIME );
|
||||
fontSizeTime = fontTime->getCharWidth();
|
||||
|
||||
racers = 0;
|
||||
explosions = 0;
|
||||
enemys = 0;
|
||||
shots = 0;
|
||||
items = 0;
|
||||
wrecks = 0;
|
||||
banners = 0;
|
||||
smokePuffs = 0;
|
||||
// needed for calculating fps
|
||||
frameCnt = 0;
|
||||
tickCnt = 0;
|
||||
|
||||
gameState = GS_INTRO;
|
||||
paused = true;
|
||||
sdlTicks = SDL_GetTicks();
|
||||
gameActRuntime = 0;
|
||||
timeNukeEnd = 0;
|
||||
timePauseOn = 0;
|
||||
timeMinibossOn = 0;
|
||||
|
||||
scrollingOn = true;
|
||||
showAllShipStats = false;
|
||||
playMusicOn = true;
|
||||
onePlayerGame = false;
|
||||
arcadeGame = false;
|
||||
difficultyLevel = 1;
|
||||
|
||||
sonic1 = new Sonic();
|
||||
sonic2 = new Sonic();
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 8");
|
||||
|
||||
background = new Background();
|
||||
loadLevel( FN_LEVEL_ONE_PLAYER );
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 9");
|
||||
|
||||
SdlCompat_AcceleratedSurface *loadingSprite = surfaceDB.loadSurface( FN_LOADING );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 10");
|
||||
SDL_Rect dest;
|
||||
dest.x = (SCREEN_WIDTH - loadingSprite->w ) / 2;
|
||||
dest.y = (SCREEN_HEIGHT - loadingSprite->h ) / 2;
|
||||
dest.w = loadingSprite->w;
|
||||
dest.h = loadingSprite->h;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 11");
|
||||
SDL_BlitSurface( loadingSprite, 0, screen, &dest );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 12");
|
||||
SDL_Flip( screen );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 13");
|
||||
initAllSurfaces();
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 14");
|
||||
}
|
||||
|
||||
Game::~Game(){
|
||||
if (videoserver) delete videoserver;
|
||||
if (settings) delete settings;
|
||||
if (intro) delete intro;
|
||||
if (setDifficulty) delete setDifficulty;
|
||||
if (racers) delete racers;
|
||||
if (shots) delete shots;
|
||||
if (explosions) delete explosions;
|
||||
if (enemys) delete enemys;
|
||||
if (items) delete items;
|
||||
if (wrecks) delete wrecks;
|
||||
if (fontTime) delete fontTime;
|
||||
if (sonic1) delete sonic1;
|
||||
if (sonic2) delete sonic2;
|
||||
if (banners) delete banners;
|
||||
if (smokePuffs) delete smokePuffs;
|
||||
}
|
||||
|
||||
void Game::initNewGame() {
|
||||
parseGlobalConfigValues( difficultyLevel );
|
||||
|
||||
if (racers) delete racers;
|
||||
if (shots) delete shots;
|
||||
if (explosions) delete explosions;
|
||||
if (enemys) delete enemys;
|
||||
if (items) delete items;
|
||||
if (wrecks) delete wrecks;
|
||||
if (sonic1) delete sonic1;
|
||||
if (sonic2) delete sonic2;
|
||||
if (banners) delete banners;
|
||||
if (smokePuffs) delete smokePuffs;
|
||||
|
||||
banners = new Banners();
|
||||
smokePuffs = new SmokePuffs();
|
||||
|
||||
racers = new Racers();
|
||||
Racer *racer;
|
||||
|
||||
if ( !arcadeGame ) {
|
||||
if ( onePlayerGame ) {
|
||||
loadLevel( FN_LEVEL_ONE_PLAYER );
|
||||
if ( setDifficulty->getPlayerOneLightFighter() ) {
|
||||
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
|
||||
Vector2D(320,350), LIGHT_FIGHTER );
|
||||
} else {
|
||||
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
|
||||
Vector2D(320,350), HEAVY_FIGHTER );
|
||||
}
|
||||
racers->addRacer(racer);
|
||||
}
|
||||
// two players
|
||||
else {
|
||||
loadLevel( FN_LEVEL_TWO_PLAYER );
|
||||
if ( setDifficulty->getPlayerOneLightFighter() ) {
|
||||
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
|
||||
Vector2D(250,350), LIGHT_FIGHTER );
|
||||
} else {
|
||||
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
|
||||
Vector2D(250,350), HEAVY_FIGHTER );
|
||||
}
|
||||
racers->addRacer(racer);
|
||||
|
||||
if ( setDifficulty->getPlayerTwoLightFighter() ) {
|
||||
racer = new Racer( FN_LIGHT_FIGHTER_2, 1,
|
||||
Vector2D(390,350), LIGHT_FIGHTER );
|
||||
} else {
|
||||
racer = new Racer( FN_HEAVY_FIGHTER_2, 1,
|
||||
Vector2D(390,350), HEAVY_FIGHTER );
|
||||
}
|
||||
racers->addRacer(racer);
|
||||
}
|
||||
}
|
||||
// arcade game
|
||||
else {
|
||||
loadLevel( FN_LEVEL_ARCADEMODE );
|
||||
if ( menuArcadeMode->getPlayerOneLightFighter() ) {
|
||||
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
|
||||
Vector2D(320,350), LIGHT_FIGHTER );
|
||||
} else {
|
||||
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
|
||||
Vector2D(320,350), HEAVY_FIGHTER );
|
||||
}
|
||||
racers->addRacer(racer);
|
||||
}
|
||||
|
||||
racers->getKeyActionMaps();
|
||||
|
||||
explosions = new Explosions();
|
||||
enemys = new Enemys();
|
||||
shots = new Shots();
|
||||
items = new Items();
|
||||
wrecks = new Wrecks();
|
||||
|
||||
gameActRuntime = 0;
|
||||
paused = true;
|
||||
bossTime = false;
|
||||
bossNukeEffect = false;
|
||||
bossExplosion = Mixer::mixer().loadSample( FN_SOUND_EXPLOSION_BOSS );
|
||||
|
||||
minibossAlreadyKilled = false;
|
||||
minibossTime = false;
|
||||
timeMinibossOn = SDL_GetTicks();
|
||||
timeLastUpdate = SDL_GetTicks();
|
||||
timeNukeEnd = SDL_GetTicks();
|
||||
timePauseOn = SDL_GetTicks();
|
||||
actBackgroundPos = 0;
|
||||
|
||||
scrollingOn = true;
|
||||
nukeIsInPlace = false;
|
||||
|
||||
sonic1 = new Sonic();
|
||||
sonic2 = new Sonic();
|
||||
sonic1->setActive( false );
|
||||
sonic2->setActive( false );
|
||||
}
|
||||
|
||||
void Game::run(){
|
||||
while( gameState != GS_QUIT ) {
|
||||
switch (gameState) {
|
||||
case GS_SCREENSHOTS:
|
||||
{
|
||||
intro->showScreenshots();
|
||||
gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
case GS_INTRO:
|
||||
{
|
||||
intro->run( gameState );
|
||||
break;
|
||||
}
|
||||
case GS_SET_DIFFICULTY:
|
||||
{
|
||||
setDifficulty->run( gameState, onePlayerGame);
|
||||
break;
|
||||
}
|
||||
case GS_ARCADE_MODE_SETUP:
|
||||
{
|
||||
menuArcadeMode->run( gameState );
|
||||
break;
|
||||
}
|
||||
case GS_ARCADE_MODE_FINISHED:
|
||||
{
|
||||
menuArcadeMode->run( gameState, racers->getPointsArcadeMode() );
|
||||
break;
|
||||
}
|
||||
case GS_OPTIONS:
|
||||
{
|
||||
options();
|
||||
break;
|
||||
}
|
||||
case GS_ROUNDFINISHED:
|
||||
{
|
||||
roundFinished();
|
||||
break;
|
||||
}
|
||||
case GS_BOSS_KILLED:
|
||||
{
|
||||
bossKilled();
|
||||
break;
|
||||
}
|
||||
case GS_PLAYON:
|
||||
{
|
||||
initNewGame();
|
||||
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_PLAYON, -1, 1000 );
|
||||
playOn();
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************/
|
||||
/**** PlayOn *********************/
|
||||
/*********************************/
|
||||
|
||||
void Game::playOn() {
|
||||
int A = SDL_GetTicks();
|
||||
frameCnt = 0;
|
||||
tickCnt = 0;
|
||||
{
|
||||
std::ostringstream logout;
|
||||
logout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt
|
||||
<< " SDL_GetTicks()=" << A;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", logout.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
while ( gameState == GS_PLAYON ) {
|
||||
handleEventsPlayOn();
|
||||
if (!paused) {
|
||||
updateGameState();
|
||||
}
|
||||
drawPlayOn();
|
||||
// miniboss
|
||||
if ( minibossTime && enemys->minibossDead() ) minibossAlreadyKilled = true;
|
||||
if (!minibossAlreadyKilled && !arcadeGame && !paused && !minibossTime &&
|
||||
(unsigned int)GAME_LENGTH / 2 <= gameActRuntime) {
|
||||
generateMiniboss();
|
||||
}
|
||||
if ( minibossTime && enemys->bossDead() ) minibossKilled();
|
||||
// endboss
|
||||
if (!arcadeGame && !paused && !bossTime && !minibossTime &&
|
||||
(unsigned int)GAME_LENGTH < gameActRuntime) {
|
||||
enemys->bossTime(1); // generates the boss
|
||||
bossTime = true;
|
||||
Mixer::mixer().playSample( bossAlarm , 0, true );
|
||||
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_BOSS1, -1, 0 );
|
||||
}
|
||||
if ( bossTime && enemys->bossDead() ) gameState = GS_BOSS_KILLED;
|
||||
if ( racers->bothPlayersLost() ) gameState = GS_ROUNDFINISHED;
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream logout;
|
||||
|
||||
int B = SDL_GetTicks();
|
||||
logout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt
|
||||
<< " SDL_GetTicks()=" << B << endl;
|
||||
logout << "Milliseconds: " << B-A << endl;
|
||||
logout << "Frames/sec : " << (float)frameCnt / ((float)(B-A) / 1000.0) << endl;
|
||||
logout << "ms/Frame : " << (float)tickCnt / (float)frameCnt << endl;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", logout.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Game::pause() {
|
||||
if (paused) {
|
||||
Uint32 timePaused = SDL_GetTicks() - timePauseOn;
|
||||
timeLastUpdate += timePaused;
|
||||
} else {
|
||||
timePauseOn = SDL_GetTicks();
|
||||
}
|
||||
paused = !paused;
|
||||
}
|
||||
|
||||
|
||||
void Game::handleEventsPlayOn() {
|
||||
SDL_Event event;
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_MOUSEBUTTONDOWN: {
|
||||
if (paused) pause();
|
||||
racers->handleEvent(input.translate(event), input.isPressed(event));
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP: {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_F10: {
|
||||
pause();
|
||||
break;
|
||||
}
|
||||
case SDLK_F5: {
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
case SDLK_F6: {
|
||||
showAllShipStats = !showAllShipStats;
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE: {
|
||||
gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
case SDLK_F1: {
|
||||
if (!paused) pause();
|
||||
settings->settingsDialog(screen);
|
||||
racers->getKeyActionMaps();
|
||||
pause();
|
||||
break;
|
||||
}
|
||||
case SDLK_F7: {
|
||||
if ( playMusicOn ) {
|
||||
playMusicOn = false;
|
||||
Mixer::mixer().stopMusic();
|
||||
} else {
|
||||
playMusicOn = true;
|
||||
if ( bossTime ) Mixer::mixer().playMusic( MUSIC_BOSS1, -1, 1000 );
|
||||
else Mixer::mixer().playMusic( MUSIC_PLAYON, -1, 1000 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
case SDL_JOYAXISMOTION:
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
racers->handleEvent(input.translate(event), input.isPressed(event));
|
||||
break;
|
||||
case SDL_QUIT: {
|
||||
gameState = GS_QUIT;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// what to do in one tick
|
||||
void Game::updateGameState() {
|
||||
int dT = SDL_GetTicks() - timeLastUpdate;
|
||||
timeLastUpdate += dT;
|
||||
if ( !minibossTime ) gameActRuntime += dT;
|
||||
|
||||
if ( nukeIsInPlace ) handleNuke();
|
||||
|
||||
enemys->generateEnemys( dT );
|
||||
explosions->updateExplosions( dT );
|
||||
|
||||
smokePuffs->update( dT );
|
||||
shots->moveAndCollide( dT );
|
||||
wrecks->updateWrecks( dT );
|
||||
enemys->updateEnemys( dT );
|
||||
if ( !arcadeGame ) items->generate( dT );
|
||||
items->update( dT );
|
||||
|
||||
racers->moveAndCollide( dT );
|
||||
racers->pickUpItems();
|
||||
racers->shoot();
|
||||
if ( !arcadeGame ) racers->rechargeShield( dT );
|
||||
|
||||
enemys->deleteExpiredEnemys();
|
||||
shots->expireShots();
|
||||
items->expireItems();
|
||||
explosions->expireExplosions();
|
||||
wrecks->expireWrecks();
|
||||
racers->expireRacers();
|
||||
smokePuffs->expireSmokePuffs();
|
||||
sonicDeflectorEffect();
|
||||
|
||||
banners->update( dT );
|
||||
banners->expireBanners();
|
||||
|
||||
if ( scrollingOn ) actBackgroundPos -= SCROLL_SPEED * dT / 1000.0;
|
||||
|
||||
if ( arcadeGame ) {
|
||||
racers->receivePointsArcade( ARCADE_POINTS_PER_TEN_SECONDS * dT / 10000.0 );
|
||||
}
|
||||
}
|
||||
|
||||
void Game::handleNuke() {
|
||||
sonic1->setActive( false );
|
||||
sonic2->setActive( false );
|
||||
|
||||
enemys->doNukeDamage();
|
||||
shots->deleteAllShots();
|
||||
timeNukeEnd = SDL_GetTicks() + NUKE_EFFECT_DURATION;
|
||||
nukeIsInPlace = false;
|
||||
}
|
||||
|
||||
void Game::sonicDeflectorEffect() {
|
||||
for ( unsigned int i = 0; i < racers->getNrRacers(); i++) {
|
||||
if ( racers->getRacer(i)->getShipType() == LIGHT_FIGHTER ) {
|
||||
Shot* nearestRocket = shots->getNearestRocket( racers->getRacer(i)->getPos() );
|
||||
// a rocket exists and it is in range of the sonic
|
||||
if ( nearestRocket != NULL &&
|
||||
(nearestRocket->getPos() - racers->getRacer(i)->getPos()).getLength() <
|
||||
RACER_SONIC_ACTIVATION_DIST ) {
|
||||
// activate the correct sonic
|
||||
if (i == 0) {
|
||||
sonic1->setPos( racers->getRacer(i)->getPos(), nearestRocket->getPos() );
|
||||
nearestRocket->deflectedBySonicFromPlayer1 = true;
|
||||
} else {
|
||||
sonic2->setPos( racers->getRacer(i)->getPos(), nearestRocket->getPos() );
|
||||
nearestRocket->deflectedBySonicFromPlayer2 = true;
|
||||
}
|
||||
// no rocket is in sonic-range
|
||||
} else {
|
||||
// deactivate the sonic
|
||||
if (i == 0) {
|
||||
sonic1->setActive( false );
|
||||
} else {
|
||||
sonic2->setActive( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::drawPlayOn() {
|
||||
drawBackground();
|
||||
wrecks->draw(screen);
|
||||
enemys->drawGroundEnemys(screen);
|
||||
shots->drawShadows(screen);
|
||||
racers->drawShadows(screen);
|
||||
enemys->drawShadows(screen);
|
||||
explosions->drawGroundExplosions(screen);
|
||||
|
||||
smokePuffs->draw(screen);
|
||||
|
||||
sonic1->draw(screen);
|
||||
sonic2->draw(screen);
|
||||
|
||||
shots->drawGroundShots(screen);
|
||||
shots->drawGroundAirShots(screen);
|
||||
items->draw(screen);
|
||||
enemys->drawAirEnemys(screen);
|
||||
racers->drawRacers(screen);
|
||||
shots->drawAirShots(screen);
|
||||
explosions->drawAirExplosions(screen);
|
||||
|
||||
|
||||
if ( showAllShipStats ) enemys->drawAllStats(screen);
|
||||
else {
|
||||
if ( bossTime ) {
|
||||
enemys->drawBossStats(screen);
|
||||
fontTime->drawStr( screen, (screen->w / 2), 5, "BOSS", FONT_ALIGN_CENTERED );
|
||||
}
|
||||
}
|
||||
|
||||
if ( SDL_GetTicks() < timeNukeEnd ) {
|
||||
drawNukeEffect();
|
||||
}
|
||||
|
||||
racers->drawStats(screen);
|
||||
|
||||
banners->draw(screen);
|
||||
if ( !arcadeGame && !bossTime && !minibossTime ) drawTime();
|
||||
else {
|
||||
if ( bossTime || minibossTime ) {
|
||||
fontTime->drawStr( screen, (screen->w / 2), 5, "BOSS", FONT_ALIGN_CENTERED );
|
||||
}
|
||||
else {
|
||||
drawPointsArcadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
if (paused) drawPaused();
|
||||
|
||||
SDL_Flip( screen );
|
||||
|
||||
frameCnt++;
|
||||
}
|
||||
|
||||
void Game::drawBackground() {
|
||||
background->draw(screen, (int) (actBackgroundPos + 0.5) );
|
||||
}
|
||||
|
||||
|
||||
void Game::drawTime() {
|
||||
Uint32 timeToDraw;
|
||||
timeToDraw = (GAME_LENGTH - gameActRuntime) / 1000;
|
||||
if ( timeToDraw > 0 ) {
|
||||
int digitCnt = 1;
|
||||
Uint32 i=1;
|
||||
while ( timeToDraw >= i*10 ) {
|
||||
digitCnt++;
|
||||
i *= 10;
|
||||
}
|
||||
fontTime->drawInt(screen, (screen->w / 2) - (fontSizeTime * digitCnt) / 2, 5,
|
||||
timeToDraw, digitCnt, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Game::drawPointsArcadeMode() {
|
||||
int pointsToDraw = racers->getPointsArcadeMode();
|
||||
if ( pointsToDraw < 0 ) return;
|
||||
|
||||
int digitCnt = 1;
|
||||
int i=1;
|
||||
while ( pointsToDraw >= i*10 ) {
|
||||
digitCnt++;
|
||||
i *= 10;
|
||||
}
|
||||
fontTime->drawInt( screen, (screen->w / 2) - (fontSizeTime * digitCnt) / 2, 10,
|
||||
pointsToDraw, digitCnt, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Game::drawPaused() {
|
||||
SDL_Rect r;
|
||||
r.x = screen->w/2 - pauseSprite->w/2;
|
||||
r.y = screen->h/2 - pauseSprite->h/2;
|
||||
r.w = pauseSprite->w;
|
||||
r.h = pauseSprite->h;
|
||||
SDL_BlitSurface( pauseSprite, 0, screen, &r );
|
||||
}
|
||||
|
||||
|
||||
void Game::drawNukeEffect() {
|
||||
// effect-process: transparent -> nearly opaque -> transparent
|
||||
int timeFromMaximum = (NUKE_EFFECT_DURATION / 2) - (timeNukeEnd - SDL_GetTicks());
|
||||
timeFromMaximum = abs(timeFromMaximum);
|
||||
|
||||
SDL_SetAlpha( nukeEffectSurface, SDL_SRCALPHA,
|
||||
lroundf(((NUKE_EFFECT_DURATION / 2) - timeFromMaximum) * 128.0 /
|
||||
(NUKE_EFFECT_DURATION / 2)) );
|
||||
|
||||
SDL_BlitSurface( nukeEffectSurface, 0, screen, 0 );
|
||||
|
||||
/*
|
||||
int randRange = (int)
|
||||
(( ((NUKE_EFFECT_DURATION / 2.0) - timeFromMaximum) * NUKE_QUAKE_EFFECT /
|
||||
(NUKE_EFFECT_DURATION / 2.0 ) ) + 0.5);
|
||||
|
||||
int randX, randY;
|
||||
if ( randRange == 0 ) randRange = 1;
|
||||
randX = (rand() % randRange) - randRange / 2;
|
||||
randY = (rand() % randRange) - randRange / 2;
|
||||
|
||||
SDL_Rect src, dest;
|
||||
if ( randX < 0 ) {
|
||||
src.x = -randX;
|
||||
src.w = screen->w + randX;
|
||||
dest.x = 0;
|
||||
dest.w = screen->w + randX;
|
||||
} else {
|
||||
src.x = 0;
|
||||
src.w = screen->w - randX;
|
||||
dest.x = randX;
|
||||
dest.w = screen->w - randX;
|
||||
}
|
||||
if ( randY < 0 ) {
|
||||
src.y = -randY;
|
||||
src.h = screen->h + randY;
|
||||
dest.y = 0;
|
||||
dest.h = screen->h + randY;
|
||||
} else {
|
||||
src.y = 0;
|
||||
src.h = screen->h - randY;
|
||||
dest.y = randY;
|
||||
dest.h = screen->h - randY;
|
||||
}
|
||||
|
||||
SDL_BlitSurface( screen, &src, screen, &dest );
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// not in use - not needed anymore
|
||||
void Game::timeManagement() {
|
||||
Uint32 sdlTicksNew = SDL_GetTicks();
|
||||
tickCnt += sdlTicksNew - sdlTicks;
|
||||
// 25 Frames per Second is wanted
|
||||
// we needed less than 40 ms -> wait till the 40 ms are over
|
||||
while ( sdlTicks + 40 > sdlTicksNew ) {
|
||||
sdlTicksNew = SDL_GetTicks();
|
||||
}
|
||||
sdlTicks = sdlTicksNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************/
|
||||
/** Options ************************/
|
||||
/***********************************/
|
||||
|
||||
void Game::options() {}
|
||||
|
||||
|
||||
/************************************/
|
||||
/** Round Finished ******************/
|
||||
/************************************/
|
||||
|
||||
void Game::roundFinished() {
|
||||
drawRoundFinished();
|
||||
SDL_Flip( screen );
|
||||
while (gameState == GS_ROUNDFINISHED ) {
|
||||
handleEventsRoundFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void Game::handleEventsRoundFinished() {
|
||||
SDL_Event event;
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_SPACE:
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
if ( arcadeGame ) gameState = GS_ARCADE_MODE_FINISHED;
|
||||
else gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
case SDLK_F5:
|
||||
{
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_QUIT:
|
||||
{
|
||||
if ( arcadeGame ) gameState = GS_ARCADE_MODE_FINISHED;
|
||||
else gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::drawRoundFinished() {
|
||||
SDL_Rect r;
|
||||
|
||||
if ( arcadeGame ) {
|
||||
r.x = screen->w/2 - gameOverSprite->w / 2;
|
||||
r.y = screen->h/2 - gameOverSprite->h / 2;
|
||||
r.w = gameOverSprite->w;
|
||||
r.h = gameOverSprite->h;
|
||||
SDL_BlitSurface( gameOverSprite, 0, screen, &r );
|
||||
|
||||
fontTime->drawStr( screen, screen->w/2, screen->h/2 + gameOverSprite->h/2 + 50,
|
||||
"SCORE: " + asString( racers->getPointsArcadeMode() ),
|
||||
FONT_ALIGN_CENTERED );
|
||||
fontTime->drawStr( screen, screen->w/2, screen->h/2 + gameOverSprite->h/2 + 100,
|
||||
"Kill Rate: " + asString(enemys->getNrEnemysKilled())
|
||||
+ "/" + asString(enemys->getNrEnemysGenerated()),
|
||||
FONT_ALIGN_CENTERED );
|
||||
}
|
||||
|
||||
// normal game
|
||||
else {
|
||||
if ( racers->bothPlayersLost() ) {
|
||||
r.x = screen->w/2 - youLoseSprite->w / 2;
|
||||
r.y = screen->h/2 - youLoseSprite->h / 2;
|
||||
r.w = youLoseSprite->w;
|
||||
r.h = youLoseSprite->h;
|
||||
SDL_BlitSurface( youLoseSprite, 0, screen, &r );
|
||||
} else {
|
||||
r.x = screen->w/2 - youWinSprite->w / 2;
|
||||
r.y = screen->h/2 - youWinSprite->h / 2;
|
||||
r.w = youWinSprite->w;
|
||||
r.h = youWinSprite->h;
|
||||
SDL_BlitSurface( youWinSprite, 0, screen, &r );
|
||||
fontTime->drawStr(screen, screen->w/2, screen->h/2 + youWinSprite->h/2 + 50,
|
||||
"Kill Rate: " + asString(enemys->getNrEnemysKilled())
|
||||
+ ":" + asString(enemys->getNrEnemysGenerated()),
|
||||
FONT_ALIGN_CENTERED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************/
|
||||
/** Miniboss ***********************/
|
||||
/************************************/
|
||||
|
||||
void Game::generateMiniboss() {
|
||||
scrollingOn = false;
|
||||
minibossTime = true;
|
||||
enemys->bossTime(2); // generates the miniboss
|
||||
Mixer::mixer().playSample( bossAlarm , 0, true );
|
||||
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_BOSS1, -1, 0 );
|
||||
}
|
||||
|
||||
void Game::minibossKilled() {
|
||||
scrollingOn = true;
|
||||
minibossTime = false;
|
||||
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_PLAYON, -1, 0 );
|
||||
}
|
||||
|
||||
|
||||
/************************************/
|
||||
/** Boss Killed *********************/
|
||||
/************************************/
|
||||
|
||||
void Game::bossKilled() {
|
||||
int BOSS_EXPLOSION_DURATION = 3000;
|
||||
int startOfBossExplosion = SDL_GetTicks();
|
||||
int actualTime;
|
||||
bool bossExplosionSound = false;
|
||||
timeNukeEnd = SDL_GetTicks() + BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION;
|
||||
|
||||
while ( gameState == GS_BOSS_KILLED ) {
|
||||
actualTime = SDL_GetTicks();
|
||||
updateBossKilled();
|
||||
if ( (actualTime - startOfBossExplosion) < BOSS_EXPLOSION_DURATION ) {
|
||||
// explosions
|
||||
Explosion *newExplosion =
|
||||
new Explosion( FN_EXPLOSION_ENEMY,
|
||||
Vector2D( rand() % SCREEN_WIDTH, rand() % 150 ),
|
||||
Vector2D( 0, 0 ),
|
||||
EXPLOSION_NORMAL_GROUND );
|
||||
explosions->addExplosion( newExplosion );
|
||||
}
|
||||
else if ( (actualTime - startOfBossExplosion) < (BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION) ) {
|
||||
// nuke effect
|
||||
if ( !bossExplosionSound ) {
|
||||
Mixer::mixer().playSample( bossExplosion, 0, true );
|
||||
bossExplosionSound = false;
|
||||
enemys->doNukeDamage();
|
||||
enemys->deleteExpiredEnemys();
|
||||
shots->deleteAllShots();
|
||||
items->deleteAllItems();
|
||||
wrecks->deleteAllWrecks();
|
||||
Wreck *newWreck = new Wreck( Vector2D( SCREEN_WIDTH / 2, 70 ), WRECK_BOSS_1_DESTROYED);
|
||||
wrecks->addWreck( newWreck );
|
||||
bossNukeEffect = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bossNukeEffect = false;
|
||||
}
|
||||
if ( (actualTime - startOfBossExplosion) > (BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION + 4000) ) {
|
||||
gameState = GS_ROUNDFINISHED;
|
||||
}
|
||||
drawBossKilled();
|
||||
handleEventsBossKilled();
|
||||
}
|
||||
}
|
||||
|
||||
void Game::handleEventsBossKilled() {
|
||||
SDL_Event event;
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYUP: {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
case SDLK_SPACE:
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
case SDLK_F5:
|
||||
{
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_QUIT:
|
||||
{
|
||||
gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Game::drawBossKilled() {
|
||||
drawBackground();
|
||||
wrecks->draw(screen);
|
||||
enemys->drawGroundEnemys(screen);
|
||||
shots->drawShadows(screen);
|
||||
racers->drawShadows(screen);
|
||||
enemys->drawShadows(screen);
|
||||
explosions->drawGroundExplosions(screen);
|
||||
shots->drawGroundShots(screen);
|
||||
shots->drawGroundAirShots(screen);
|
||||
items->draw(screen);
|
||||
enemys->drawAirEnemys(screen);
|
||||
racers->drawRacers(screen);
|
||||
shots->drawAirShots(screen);
|
||||
explosions->drawAirExplosions(screen);
|
||||
if ( bossNukeEffect ) drawNukeEffect();
|
||||
racers->drawStats(screen);
|
||||
SDL_Flip( screen );
|
||||
}
|
||||
|
||||
void Game::updateBossKilled() {
|
||||
int dT = SDL_GetTicks() - timeLastUpdate;
|
||||
timeLastUpdate += dT;
|
||||
explosions->updateExplosions( dT );
|
||||
explosions->expireExplosions();
|
||||
}
|
||||
|
||||
|
||||
void Game::loadLevel( string fn ) {
|
||||
if (levelConf) {
|
||||
delete levelConf;
|
||||
}
|
||||
levelConf = new Options( fn );
|
||||
|
||||
// load background tiles
|
||||
background->clearTileList();
|
||||
int cnt = 0;
|
||||
if (!levelConf->getInt( LVL_BACKG_TILE_CNT, cnt )) {
|
||||
cout << "ERROR: " << fn << " contains no '" << LVL_BACKG_TILE_CNT << "' keyword!" << endl;
|
||||
exit(0);
|
||||
}
|
||||
for(int i=0; i < cnt; i++) {
|
||||
string tilename;
|
||||
if (levelConf->getStr( LVL_BACKG_TILE + asString( i ), tilename ) ) {
|
||||
background->addTile( tilename );
|
||||
}
|
||||
}
|
||||
int len = SCREEN_WIDTH;
|
||||
levelConf->getInt( LVL_BACKG_LENGTH, len );
|
||||
background->generateBackground( len );
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef GAME_HH
|
||||
#define GAME_HH
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SdlForwardCompat.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
class Video;
|
||||
class SurfaceDB;
|
||||
class Racers;
|
||||
class Shots;
|
||||
class Explosions;
|
||||
class Enemys;
|
||||
class Items;
|
||||
class Font;
|
||||
class Intro;
|
||||
class SetDifficulty;
|
||||
class MenuArcadeMode;
|
||||
class Sonic;
|
||||
class Background;
|
||||
class Options;
|
||||
|
||||
enum GameStates { GS_QUIT, GS_SCREENSHOTS, GS_INTRO, GS_SET_DIFFICULTY,
|
||||
GS_OPTIONS, GS_ARCADE_MODE_SETUP, GS_ARCADE_MODE_FINISHED,
|
||||
GS_PLAYON, GS_ROUNDFINISHED, GS_BOSS_KILLED };
|
||||
|
||||
/* The big class, that has to control the gamelogic and keep track of all the
|
||||
game objects and their dependencies. */
|
||||
class Game {
|
||||
// Video system
|
||||
SdlCompat_AcceleratedSurface *screen;
|
||||
|
||||
SdlCompat_AcceleratedSurface *pauseSprite;
|
||||
SdlCompat_AcceleratedSurface *youLoseSprite;
|
||||
SdlCompat_AcceleratedSurface *youWinSprite;
|
||||
SdlCompat_AcceleratedSurface *gameOverSprite;
|
||||
SdlCompat_AcceleratedSurface *nukeEffectSurface;
|
||||
SdlCompat_AcceleratedSurface *hud;
|
||||
|
||||
// Time system
|
||||
Font *fontTime;
|
||||
int fontSizeTime;
|
||||
|
||||
Uint32 frameCnt;
|
||||
Uint32 tickCnt;
|
||||
Uint32 sdlTicks;
|
||||
Uint32 gameActRuntime;
|
||||
Uint32 timePauseOn;
|
||||
Uint32 timeMinibossOn;
|
||||
Uint32 timeLastUpdate;
|
||||
Uint32 timeNukeEnd;
|
||||
|
||||
bool paused;
|
||||
|
||||
bool showAllShipStats;
|
||||
|
||||
Background *background;
|
||||
|
||||
// is the game in playon or in intro or somewhere else?
|
||||
GameStates gameState;
|
||||
Intro *intro;
|
||||
SetDifficulty *setDifficulty;
|
||||
MenuArcadeMode *menuArcadeMode;
|
||||
|
||||
// boss specific
|
||||
bool bossTime;
|
||||
bool minibossTime;
|
||||
bool minibossAlreadyKilled;
|
||||
bool bossNukeEffect;
|
||||
int bossExplosion;
|
||||
int bossAlarm;
|
||||
|
||||
Sonic *sonic1;
|
||||
Sonic *sonic2;
|
||||
|
||||
public:
|
||||
// for access from main()
|
||||
Game();
|
||||
~Game();
|
||||
// the outer game loop
|
||||
void run();
|
||||
|
||||
private:
|
||||
// starts a new game
|
||||
void initNewGame();
|
||||
|
||||
/* Methods for GS_PLAYON */
|
||||
// the inner loop when the race is going on
|
||||
void playOn();
|
||||
void handleEventsPlayOn();
|
||||
// toggles the pause state (takes into account the corresponding time problems)
|
||||
void pause();
|
||||
void updateGameState();
|
||||
void handleNuke();
|
||||
void sonicDeflectorEffect();
|
||||
void drawPlayOn();
|
||||
void drawBackground();
|
||||
void drawTime();
|
||||
void drawPointsArcadeMode();
|
||||
void drawPaused();
|
||||
void drawNukeEffect();
|
||||
void timeManagement(); // not needed and used any more
|
||||
|
||||
|
||||
/* Methods for GS_OPTIONS (not implemented by now) */
|
||||
void options();
|
||||
void loadLevel( std::string fn );
|
||||
|
||||
/* Methods for GS_ROUNDFINISHED (the time is up -> display the winner) */
|
||||
void roundFinished();
|
||||
void drawRoundFinished();
|
||||
void handleEventsRoundFinished();
|
||||
|
||||
void generateMiniboss();
|
||||
void minibossKilled();
|
||||
|
||||
void bossKilled();
|
||||
void updateBossKilled();
|
||||
void drawBossKilled();
|
||||
void handleEventsBossKilled();
|
||||
};
|
||||
|
||||
#endif //#ifndef GAME_HH
|
||||
|
||||
@@ -1,793 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2000,2001, Jelle Kok, University of Amsterdam
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University of Amsterdam nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**************************************************************************************
|
||||
* goemetry.cc
|
||||
*
|
||||
* implements:
|
||||
* class Vector2D
|
||||
* namespace Geometry
|
||||
* class Line
|
||||
* class Circle
|
||||
* class Rectangle
|
||||
*
|
||||
* requires:
|
||||
*
|
||||
* Maintainer: wenns
|
||||
*
|
||||
* Changelog:
|
||||
*
|
||||
*************************************************************************************/
|
||||
|
||||
//Furthermore it contains some goniometric functions to work with sine, cosine
|
||||
//and tangent functions using degrees and some utility functions to return
|
||||
//the maximum and the minimum of two values.
|
||||
|
||||
#include "geometry.h"
|
||||
#include <algorithm> // max and min
|
||||
#include <stdio.h> // needed for sprintf
|
||||
|
||||
AngDeg Rad2Deg ( AngRad x ) { return ( x * 180 / M_PI ); }
|
||||
AngRad Deg2Rad ( AngDeg x ) { return ( x * M_PI / 180 ); }
|
||||
float cosDeg ( AngDeg x ) { return ( cos( Deg2Rad( x ) ) ); }
|
||||
float sinDeg ( AngDeg x ) { return ( sin( Deg2Rad( x ) ) ); }
|
||||
float tanDeg ( AngDeg x ) { return ( tan( Deg2Rad( x ) ) ); }
|
||||
AngDeg atanDeg ( float x ) { return ( Rad2Deg( atan( x ) ) ); }
|
||||
|
||||
float atan2Deg( float x, float y ){
|
||||
if( fabs( x ) < EPSILON && fabs( y ) < EPSILON )
|
||||
return ( 0.0 );
|
||||
|
||||
return ( Rad2Deg( atan2( x, y ) ) );
|
||||
}
|
||||
|
||||
|
||||
AngDeg acosDeg( float x ){
|
||||
if( x >= 1 )
|
||||
return ( 0.0 );
|
||||
else if( x <= -1 )
|
||||
return ( 180.0 );
|
||||
|
||||
return ( Rad2Deg( acos( x ) ) );
|
||||
}
|
||||
|
||||
|
||||
AngDeg asinDeg( float x ){
|
||||
if( x >= 1 )
|
||||
return ( 90.0 );
|
||||
else if ( x <= -1 )
|
||||
return ( -90.0 );
|
||||
|
||||
return ( Rad2Deg( asin( x ) ) );
|
||||
}
|
||||
|
||||
|
||||
float normalizeTo180Deg(float angle){
|
||||
while( angle > 180.0 ) angle -= 360.0;
|
||||
while( angle < -180.0 ) angle += 360.0;
|
||||
|
||||
return ( angle );
|
||||
}
|
||||
|
||||
|
||||
bool isAngInInterval( AngDeg ang, AngDeg angMin, AngDeg angMax ){
|
||||
// convert all angles to interval 0..360
|
||||
if( ( ang + 360 ) < 360 ) ang += 360;
|
||||
if( ( angMin + 360 ) < 360 ) angMin += 360;
|
||||
if( ( angMax + 360 ) < 360 ) angMax += 360;
|
||||
|
||||
if( angMin < angMax ) // 0 ---false-- angMin ---true-----angMax---false--360
|
||||
return angMin < ang && ang < angMax ;
|
||||
else // 0 ---true--- angMax ---false----angMin---true---360
|
||||
return !( angMax < ang && ang < angMin );
|
||||
}
|
||||
|
||||
|
||||
AngDeg getBisectorTwoAngles( AngDeg angMin, AngDeg angMax ){
|
||||
// separate sine and cosine part to circumvent boundary problem
|
||||
//return Vector2D::normalizeAngle(
|
||||
return normalizeTo180Deg( //wenns changed
|
||||
atan2Deg( (sinDeg( angMin) + sinDeg( angMax ) )/2.0,
|
||||
(cosDeg( angMin) + cosDeg( angMax ) )/2.0 ) );
|
||||
}
|
||||
|
||||
AngDeg getAngleDifference( AngDeg ang1, AngDeg ang2 ){
|
||||
return (normalizeTo180Deg( ang1 - ang2 ));
|
||||
}
|
||||
|
||||
AngDeg getAbsAngleDifference( AngDeg ang1, AngDeg ang2 ){
|
||||
return fabs(normalizeTo180Deg( ang1 - ang2 ));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************** CLASS VECTOR2D **************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
Vector2D::Vector2D( float x, float y, CoordSystemT cs ){
|
||||
setVector2D( x, y, cs );
|
||||
}
|
||||
|
||||
|
||||
ostream& operator <<( ostream &os, Vector2D v ){
|
||||
return ( os << "( " << v.x << ", " << v.y << " )" );
|
||||
}
|
||||
|
||||
|
||||
void Vector2D::show( CoordSystemT cs ){
|
||||
if( cs == CARTESIAN )
|
||||
cout << *this << endl;
|
||||
else
|
||||
cout << "( r: " << getLength( ) << ", phi: " << getDirection( ) << " )";
|
||||
}
|
||||
|
||||
/*
|
||||
bool Vector2D::isInvalid() const {
|
||||
return (isUndefined(x) || (isUndefined(y))
|
||||
// || (fabs(x) >= 100000.0) || (fabs(y) >= 100000.0)
|
||||
|| isinf(x) || isinf(y) || isnan(x) || isnan(y));
|
||||
}
|
||||
*/
|
||||
|
||||
void Vector2D::setVector2D( float dX, float dY, CoordSystemT cs){
|
||||
if( cs == CARTESIAN ) { x = dX; y = dY; }
|
||||
else *this = getVector2DFromPolar( dX, dY );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector2D Vector2D::setLength( float d ){
|
||||
if( getLength( ) > EPSILON )
|
||||
( *this ) *= ( d / getLength( ) );
|
||||
|
||||
return ( *this );
|
||||
}
|
||||
|
||||
Vector2D Vector2D::rotate( AngDeg angle ){
|
||||
// determine the polar representation of the current Vector2D
|
||||
float dMag = this->getLength( );
|
||||
float dNewDir = this->getDirection( ) + angle; // add rotation angle to phi
|
||||
setVector2D( dMag, dNewDir, POLAR ); // convert back to Cartesian
|
||||
return ( *this );
|
||||
}
|
||||
|
||||
Vector2D Vector2D::globalToRelative( Vector2D origin, AngDeg ang ){
|
||||
// convert global coordinates into relative coordinates by aligning relative
|
||||
// frame and world frame. First perform translation to make origins of both
|
||||
// frames coincide. Then perform rotation to make axes of both frames coincide
|
||||
// (use negative angle since you rotate relative frame to world frame).
|
||||
*this -= origin;
|
||||
return ( rotate( -ang ) );
|
||||
}
|
||||
|
||||
Vector2D Vector2D::relativeToGlobal( Vector2D origin, AngDeg ang ){
|
||||
// convert relative coordinates into global coordinates by aligning world
|
||||
// frame and relative frame. First perform rotation to make axes of both
|
||||
// frames coincide (use positive angle since you rotate world frame to
|
||||
// relative frame). Then perform translation to make origins of both frames
|
||||
// coincide.
|
||||
rotate( ang );
|
||||
*this += origin;
|
||||
return ( *this );
|
||||
}
|
||||
|
||||
Vector2D Vector2D::getVector2DOnLineFraction( Vector2D &p,
|
||||
float dFrac ){
|
||||
// determine point on line that lies at fraction dFrac of whole line
|
||||
// example: this --- 0.25 --------- p
|
||||
// formula: this + dFrac * ( p - this ) = this - dFrac * this + dFrac * p =
|
||||
// ( 1 - dFrac ) * this + dFrac * p
|
||||
return ( ( *this ) * ( 1.0 - dFrac ) + ( p * dFrac ) );
|
||||
}
|
||||
|
||||
|
||||
Vector2D Vector2D::getVector2DFromPolar( float dMag, AngDeg ang ){
|
||||
// cos(phi) = x/r <=> x = r*cos(phi); sin(phi) = y/r <=> y = r*sin(phi)
|
||||
return ( Vector2D( dMag * cosDeg( ang ), dMag * sinDeg( ang ) ) );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************** NAMESPACE GEOMETRY ***************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
float Geometry::getLengthGeomSeries( float dFirst, float dRatio, float dSum ){
|
||||
if( dRatio < 0 )
|
||||
cerr << "(Geometry:getLengthGeomSeries): negative ratio" << endl;
|
||||
|
||||
// s = a + ar + ar^2 + .. + ar^n-1 and thus sr = ar + ar^2 + .. + ar^n
|
||||
// subtract: sr - s = - a + ar^n) => s(1-r)/a + 1 = r^n = temp
|
||||
// log r^n / n = n log r / log r = n = length
|
||||
float temp = (dSum * ( dRatio - 1 ) / dFirst) + 1;
|
||||
if( temp <= 0 )
|
||||
return -1.0;
|
||||
return log( temp ) / log( dRatio ) ;
|
||||
}
|
||||
|
||||
|
||||
float Geometry::getSumGeomSeries( float dFirst, float dRatio, float dLength){
|
||||
// s = a + ar + ar^2 + .. + ar^n-1 and thus sr = ar + ar^2 + .. + ar^n
|
||||
// subtract: s - sr = a - ar^n) => s = a(1-r^n)/(1-r)
|
||||
return dFirst * ( 1 - pow( dRatio, dLength ) ) / ( 1 - dRatio ) ;
|
||||
}
|
||||
|
||||
|
||||
float Geometry::getSumInfGeomSeries( float dFirst, float dRatio ){
|
||||
if( dRatio > 1 )
|
||||
cerr << "(Geometry:CalcLengthGeomSeries): series does not converge" << endl;
|
||||
|
||||
// s = a(1-r^n)/(1-r) with n->inf and 0<r<1 => r^n = 0
|
||||
return dFirst / ( 1 - dRatio );
|
||||
}
|
||||
|
||||
|
||||
float Geometry::getFirstGeomSeries( float dSum, float dRatio, float dLength){
|
||||
// s = a + ar + ar^2 + .. + ar^n-1 and thus sr = ar + ar^2 + .. + ar^n
|
||||
// subtract: s - sr = a - ar^n) => s = a(1-r^n)/(1-r) => a = s*(1-r)/(1-r^n)
|
||||
return dSum * ( 1 - dRatio )/( 1 - pow( dRatio, dLength ) ) ;
|
||||
}
|
||||
|
||||
float Geometry::getFirstInfGeomSeries( float dSum, float dRatio ){
|
||||
if( dRatio > 1 )
|
||||
cerr << "(Geometry:getFirstInfGeomSeries):series does not converge" << endl;
|
||||
|
||||
// s = a(1-r^n)/(1-r) with r->inf and 0<r<1 => r^n = 0 => a = s ( 1 - r)
|
||||
return dSum * ( 1 - dRatio );
|
||||
}
|
||||
|
||||
int Geometry::abcFormula(float a, float b, float c, float *s1, float *s2){
|
||||
float dDiscr = b*b - 4*a*c; // discriminant is b^2 - 4*a*c
|
||||
if (fabs(dDiscr) < EPSILON ) // if discriminant = 0
|
||||
{
|
||||
*s1 = -b / (2 * a); // only one solution
|
||||
return 1;
|
||||
}
|
||||
else if (dDiscr < 0) // if discriminant < 0
|
||||
return 0; // no solutions
|
||||
else // if discriminant > 0
|
||||
{
|
||||
dDiscr = sqrt(dDiscr); // two solutions
|
||||
*s1 = (-b + dDiscr ) / (2 * a);
|
||||
*s2 = (-b - dDiscr ) / (2 * a);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** CLASS CIRCLE ******************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
Circle::Circle( Vector2D pos, float dR ){
|
||||
setCircle( pos, dR );
|
||||
}
|
||||
|
||||
Circle::Circle( ){
|
||||
setCircle( Vector2D(-1000.0,-1000.0), 0);
|
||||
}
|
||||
|
||||
void Circle::show( ostream& os) const {
|
||||
os << "c:" << posCenter << ", r:" << radius;
|
||||
}
|
||||
|
||||
bool Circle::setCircle( const Vector2D &pos, float dR ){
|
||||
setCenter( pos );
|
||||
return setRadius( dR );
|
||||
}
|
||||
bool Circle::setRadius( float dR ){
|
||||
if( dR > 0 ){
|
||||
radius = dR;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
radius = 0.0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Circle::getIntersectionPoints( const Circle &c, Vector2D *p1,
|
||||
Vector2D *p2) const {
|
||||
float x0, y0, r0;
|
||||
float x1, y1, r1;
|
||||
|
||||
x0 = getCenter( ).getX();
|
||||
y0 = getCenter( ).getY();
|
||||
r0 = getRadius( );
|
||||
x1 = c.getCenter( ).getX();
|
||||
y1 = c.getCenter( ).getY();
|
||||
r1 = c.getRadius( );
|
||||
|
||||
float d, dx, dy, h, a, x, y, p2_x, p2_y;
|
||||
|
||||
// first calculate distance between two centers circles P0 and P1.
|
||||
dx = x1 - x0;
|
||||
dy = y1 - y0;
|
||||
d = sqrt(dx*dx + dy*dy);
|
||||
|
||||
// normalize differences
|
||||
dx /= d; dy /= d;
|
||||
|
||||
// a is distance between p0 and point that is the intersection point P2
|
||||
// that intersects P0-P1 and the line that crosses the two intersection
|
||||
// points P3 and P4.
|
||||
// Define two triangles: P0,P2,P3 and P1,P2,P3.
|
||||
// with distances a, h, r0 and b, h, r1 with d = a + b
|
||||
// We know a^2 + h^2 = r0^2 and b^2 + h^2 = r1^2 which then gives
|
||||
// a^2 + r1^2 - b^2 = r0^2 with d = a + b ==> a^2 + r1^2 - (d-a)^2 = r0^2
|
||||
// ==> r0^2 + d^2 - r1^2 / 2*d
|
||||
a = (r0*r0 + d*d - r1*r1) / (2.0 * d);
|
||||
|
||||
// h is then a^2 + h^2 = r0^2 ==> h = sqrt( r0^2 - a^2 )
|
||||
float arg = r0*r0 - a*a;
|
||||
h = (arg > 0.0) ? sqrt(arg) : 0.0;
|
||||
|
||||
// First calculate P2
|
||||
p2_x = x0 + a * dx;
|
||||
p2_y = y0 + a * dy;
|
||||
|
||||
// and finally the two intersection points
|
||||
x = p2_x - h * dy;
|
||||
y = p2_y + h * dx;
|
||||
p1->setVector2D( x, y );
|
||||
x = p2_x + h * dy;
|
||||
y = p2_y - h * dx;
|
||||
p2->setVector2D( x, y );
|
||||
|
||||
return (arg < 0.0) ? 0 : ((arg == 0.0 ) ? 1 : 2);
|
||||
}
|
||||
|
||||
|
||||
float Circle::getIntersectionArea( const Circle &c ) const {
|
||||
Vector2D pos1, pos2, pos3;
|
||||
float d, h, dArea;
|
||||
AngDeg ang;
|
||||
|
||||
d = getCenter().distanceTo( c.getCenter() ); // dist between two centers
|
||||
if( d > c.getRadius() + getRadius() ) // larger than sum radii
|
||||
return 0.0; // circles do not intersect
|
||||
if( d <= fabs(c.getRadius() - getRadius() ) ) // one totally in the other
|
||||
{
|
||||
float dR = min( c.getRadius(), getRadius() );// return area smallest circle
|
||||
return M_PI*dR*dR;
|
||||
}
|
||||
|
||||
int iNrSol = getIntersectionPoints( c, &pos1, &pos2 );
|
||||
if( iNrSol != 2 )
|
||||
return 0.0;
|
||||
|
||||
// the intersection area of two circles can be divided into two segments:
|
||||
// left and right of the line between the two intersection points p1 and p2.
|
||||
// The outside area of each segment can be calculated by taking the part
|
||||
// of the circle pie excluding the triangle from the center to the
|
||||
// two intersection points.
|
||||
// The pie equals pi*r^2 * rad(2*ang) / 2*pi = 0.5*rad(2*ang)*r^2 with ang
|
||||
// the angle between the center c of the circle and one of the two
|
||||
// intersection points. Thus the angle between c and p1 and c and p3 where
|
||||
// p3 is the point that lies halfway between p1 and p2.
|
||||
// This can be calculated using ang = asin( d / r ) with d the distance
|
||||
// between p1 and p3 and r the radius of the circle.
|
||||
// The area of the triangle is 2*0.5*h*d.
|
||||
|
||||
pos3 = pos1.getVector2DOnLineFraction( pos2, 0.5 );
|
||||
d = pos1.distanceTo( pos3 );
|
||||
h = pos3.distanceTo( getCenter() );
|
||||
ang = asin( d / getRadius() );
|
||||
|
||||
dArea = ang*getRadius()*getRadius();
|
||||
dArea = dArea - d*h;
|
||||
|
||||
// and now for the other segment the same story
|
||||
h = pos3.distanceTo( c.getCenter() );
|
||||
ang = asin( d / c.getRadius() );
|
||||
dArea = dArea + ang*c.getRadius()*c.getRadius();
|
||||
dArea = dArea - d*h;
|
||||
|
||||
return dArea;
|
||||
}
|
||||
|
||||
|
||||
bool Circle::calcTangentIntersectionPoints(const Vector2D startPoint, Vector2D &point1, Vector2D &point2){
|
||||
if(isInside(startPoint)){
|
||||
// Startpoint is inside circle -> there are no tangent interception points
|
||||
return(false);
|
||||
}
|
||||
|
||||
//float d = posCenter.getLength()-startPoint.getLength();
|
||||
float d = (posCenter-startPoint).getLength();
|
||||
float r = radius;
|
||||
|
||||
float alphaRad = asin(r/d);
|
||||
|
||||
float p = sqrt(d*d-r*r);
|
||||
|
||||
point1.setX(cos(alphaRad)*p);
|
||||
point1.setY(sin(alphaRad)*p);
|
||||
point2.setX(cos(-alphaRad)*p);
|
||||
point2.setY(sin(-alphaRad)*p);
|
||||
|
||||
point1=point1.rotate((posCenter-startPoint).getDirection());
|
||||
point2=point2.rotate((posCenter-startPoint).getDirection());
|
||||
|
||||
point1+=startPoint;
|
||||
point2+=startPoint;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************** CLASS LINE *******************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
Line::Line( float dA, float dB, float dC ){
|
||||
a = dA;
|
||||
b = dB;
|
||||
c = dC;
|
||||
}
|
||||
|
||||
Line::Line() {
|
||||
a = 666.66;
|
||||
b = 666.66;
|
||||
c = 666.66;
|
||||
}
|
||||
|
||||
ostream& operator <<(ostream & os, Line l){
|
||||
float a = l.getACoefficient();
|
||||
float b = l.getBCoefficient();
|
||||
float c = l.getCCoefficient();
|
||||
|
||||
// ay + bx + c = 0 -> y = -b/a x - c/a
|
||||
if( a == 0 )
|
||||
os << "x = " << -c/b;
|
||||
else{
|
||||
os << "y = ";
|
||||
if( b != 0 )
|
||||
os << -b/a << "x ";
|
||||
if( c > 0 )
|
||||
os << "- " << fabs(c/a);
|
||||
else if( c < 0 )
|
||||
os << "+ " << fabs(c/a);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
void Line::show( ostream& os){
|
||||
os << *this;
|
||||
}
|
||||
|
||||
Vector2D Line::getIntersection( Line line ){
|
||||
Vector2D pos(666.66,666.66);
|
||||
float x, y;
|
||||
|
||||
if( (b == line.getBCoefficient())&&(b!=-a) ) { // lines are parallel, no intersection
|
||||
return pos;
|
||||
}
|
||||
if( a == 0 ){ // bx + c = 0 and a2*y + b2*x + c2 = 0 ==> x = -c/b
|
||||
x = -c/b; // calculate x using the current line
|
||||
y = line.getYGivenX(x); // and calculate the y using the second line
|
||||
}
|
||||
|
||||
// ay + bx + c = 0 and b2*x + c2 = 0 ==> x = -c2/b2
|
||||
// calculate x using 2nd line and calculate y using current line
|
||||
else if( line.getACoefficient() == 0 ){
|
||||
x = -line.getCCoefficient()/line.getBCoefficient();
|
||||
y = getYGivenX(x);
|
||||
}
|
||||
|
||||
// ay + bx + c = 0 and a2y + b2*x + c2 = 0
|
||||
// y = (-b2/a2)x - c2/a2
|
||||
// bx = -a*y - c => bx = -a*(-b2/a2)x -a*(-c2/a2) - c ==>
|
||||
// ==> a2*bx = a*b2*x + a*c2 - a2*c ==> x = (a*c2 - a2*c)/(a2*b - a*b2)
|
||||
// calculate x using the above formula and the y using the current line
|
||||
else{
|
||||
x = (a*line.getCCoefficient() - line.getACoefficient()*c)/
|
||||
(line.getACoefficient()*b - a*line.getBCoefficient());
|
||||
y = getYGivenX(x);
|
||||
}
|
||||
|
||||
return Vector2D( x, y );
|
||||
}
|
||||
|
||||
|
||||
int Line::getCircleIntersectionPoints( Circle circle,
|
||||
Vector2D *posSolution1, Vector2D *posSolution2 ){
|
||||
int iSol;
|
||||
float dSol1, dSol2;
|
||||
float h = circle.getCenter().getX();
|
||||
float k = circle.getCenter().getY();
|
||||
|
||||
// line: x = -c/b (if a = 0)
|
||||
// circle: (x-h)^2 + (y-k)^2 = r^2, with h = center.x and k = center.y
|
||||
// fill in:(-c/b-h)^2 + y^2 -2ky + k^2 - r^2 = 0
|
||||
// y^2 -2ky + (-c/b-h)^2 + k^2 - r^2 = 0
|
||||
// and determine solutions for y using abc-formula
|
||||
if( fabs(a) < EPSILON ){
|
||||
iSol = Geometry::abcFormula( 1, -2*k, ((-c/b) - h)*((-c/b) - h)
|
||||
+ k*k - circle.getRadius()*circle.getRadius(), &dSol1, &dSol2);
|
||||
posSolution1->setVector2D( (-c/b), dSol1 );
|
||||
posSolution2->setVector2D( (-c/b), dSol2 );
|
||||
return iSol;
|
||||
}
|
||||
|
||||
// ay + bx + c = 0 => y = -b/a x - c/a, with da = -b/a and db = -c/a
|
||||
// circle: (x-h)^2 + (y-k)^2 = r^2, with h = center.x and k = center.y
|
||||
// fill in:x^2 -2hx + h^2 + (da*x-db)^2 -2k(da*x-db) + k^2 - r^2 = 0
|
||||
// x^2 -2hx + h^2 + da^2*x^2 + 2da*db*x + db^2 -2k*da*x -2k*db
|
||||
// + k^2 - r^2 = 0
|
||||
// (1+da^2)*x^2 + 2(da*db-h-k*da)*x + h2 + db^2 -2k*db + k^2 - r^2 = 0
|
||||
// and determine solutions for x using abc-formula
|
||||
// fill in x in original line equation to get y coordinate
|
||||
float da = -b/a;
|
||||
float db = -c/a;
|
||||
|
||||
float dA = 1 + da*da;
|
||||
float dB = 2*( da*db - h - k*da );
|
||||
float dC = h*h + db*db - 2*k*db + k*k - circle.getRadius()*circle.getRadius();
|
||||
|
||||
iSol = Geometry::abcFormula( dA, dB, dC, &dSol1, &dSol2 );
|
||||
|
||||
posSolution1->setVector2D( dSol1, da*dSol1 + db );
|
||||
posSolution2->setVector2D( dSol2, da*dSol2 + db );
|
||||
return iSol;
|
||||
}
|
||||
|
||||
|
||||
Line Line::getTangentLine( Vector2D pos ){ // Senkrechte errichten, nix mit Tangente
|
||||
// ay + bx + c = 0 -> y = (-b/a)x + (-c/a)
|
||||
// tangent: y = (a/b)*x + C1 -> by - ax + C2 = 0 => C2 = ax - by
|
||||
// with pos.y = y, pos.x = x
|
||||
return Line( b, -a, a*pos.getX() - b*pos.getY() );
|
||||
}
|
||||
|
||||
|
||||
Vector2D Line::getPointOnLineClosestTo( Vector2D pos ){
|
||||
Line l2 = getTangentLine( pos ); // get tangent line
|
||||
return getIntersection( l2 ); // and intersection between the two lines
|
||||
}
|
||||
|
||||
|
||||
float Line::distanceToPoint( Vector2D pos ){
|
||||
return pos.distanceTo( getPointOnLineClosestTo( pos ) );
|
||||
}
|
||||
|
||||
|
||||
bool Line::isInBetween( Vector2D pos, Vector2D point1, Vector2D point2){
|
||||
pos = getPointOnLineClosestTo( pos ); // get closest point
|
||||
float dDist = point1.distanceTo( point2 ); // get distance between 2 pos
|
||||
// if the distance from both points to the projection is smaller than this
|
||||
// dist, the pos lies in between.
|
||||
return pos.distanceTo( point1 ) <= dDist &&
|
||||
pos.distanceTo( point2 ) <= dDist;
|
||||
}
|
||||
|
||||
|
||||
float Line::getYGivenX( float x ){
|
||||
if( a == 0 ){
|
||||
cerr << "(Line::getYGivenX) Cannot calculate Y coordinate: " ;
|
||||
show( cerr );
|
||||
cerr << endl;
|
||||
return 0;
|
||||
}
|
||||
// ay + bx + c = 0 ==> ay = -(b*x + c)/a
|
||||
return -(b*x+c)/a;
|
||||
}
|
||||
|
||||
|
||||
float Line::getXGivenY( float y ){
|
||||
if( b == 0 ){
|
||||
cerr << "(Line::getXGivenY) Cannot calculate X coordinate\n" ;
|
||||
return 0;
|
||||
}
|
||||
// ay + bx + c = 0 ==> bx = -(a*y + c)/a
|
||||
return -(a*y+c)/b;
|
||||
}
|
||||
|
||||
|
||||
Line Line::makeLineFromTwoPoints( Vector2D pos1, Vector2D pos2 ){
|
||||
// 1*y + bx + c = 0 => y = -bx - c
|
||||
// with -b the direction coefficient (or slope)
|
||||
// and c = - y - bx
|
||||
float dA=1.0, dB, dC;
|
||||
float dTemp = pos2.getX() - pos1.getX(); // determine the slope
|
||||
if( fabs(dTemp) < EPSILON ){
|
||||
// ay + bx + c = 0 with vertical slope=> a = 0, b = 1
|
||||
dA = 0.0;
|
||||
dB = 1.0;
|
||||
}
|
||||
else{
|
||||
// y = (-b)x -c with -b the slope of the line
|
||||
dA = 1.0;
|
||||
dB = -(pos2.getY() - pos1.getY())/dTemp;
|
||||
}
|
||||
// ay + bx + c = 0 ==> c = -a*y - b*x
|
||||
dC = - dA*pos2.getY() - dB * pos2.getX();
|
||||
return Line( dA, dB, dC );
|
||||
}
|
||||
|
||||
|
||||
Line Line::makeLineFromPositionAndAngle( Vector2D vec, AngDeg angle ){
|
||||
// calculate point somewhat further in direction 'angle' and make
|
||||
// line from these two points.
|
||||
return makeLineFromTwoPoints( vec, vec+Vector2D(1,angle,POLAR));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** CLASS RECTANGLE ***************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
RectangleGeo::RectangleGeo( Vector2D pos, Vector2D pos2 ){
|
||||
setRectanglePoints( pos, pos2 );
|
||||
}
|
||||
|
||||
|
||||
void RectangleGeo::setRectanglePoints( Vector2D pos1, Vector2D pos2 ){
|
||||
posLeftTop.setX ( min( pos1.getX(), pos2.getX() ) );
|
||||
posLeftTop.setY ( min( pos1.getY(), pos2.getY() ) );
|
||||
posRightBottom.setX( max( pos1.getX(), pos2.getX() ) );
|
||||
posRightBottom.setY( max( pos1.getY(), pos2.getY() ) );
|
||||
}
|
||||
|
||||
|
||||
void RectangleGeo::show( ostream& os ) const {
|
||||
os << "rect(" << posLeftTop << " " << posRightBottom << ")";
|
||||
}
|
||||
|
||||
|
||||
bool RectangleGeo::isInside( Vector2D pos ) const {
|
||||
return ( (getPosLeftTop().getX() <= pos.getX()) &&
|
||||
(pos.getX() <= getPosRightBottom().getX()) &&
|
||||
(getPosLeftTop().getY() <= pos.getY()) &&
|
||||
(pos.getY() <= getPosRightBottom().getY()) );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** CLASS CONE ********************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
Cone::Cone( Vector2D peak,
|
||||
float fstAngle, float sndAngle,
|
||||
float maxDistance, float minDistance ) {
|
||||
setPeak( peak );
|
||||
setAngles( fstAngle, sndAngle );
|
||||
setMaxDistance( maxDistance );
|
||||
setMinDistance( minDistance );
|
||||
}
|
||||
|
||||
void Cone::show( ostream& os ) const {
|
||||
os << "(p:" << peak << " fst:" << fstAngle << " snd:" << sndAngle
|
||||
<< " maxDist:" << maxDistance << " minDist:" << minDistance << ")";
|
||||
}
|
||||
|
||||
bool Cone::isInside( Vector2D pos ) const {
|
||||
float dist = pos.distanceTo( peak );
|
||||
float angle = (pos - peak).getDirection();
|
||||
return ( ( minDistance <= dist && dist <= maxDistance &&
|
||||
isAngInInterval( angle, fstAngle, sndAngle ) ) ||
|
||||
( dist == 0 && minDistance == 0) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** TESTING PURPOSES *************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/*
|
||||
#include<iostream.h>
|
||||
|
||||
int main( void ){
|
||||
float dFirst = 1.0;
|
||||
float dRatio = 2.5;
|
||||
float dSum = 63.4375;
|
||||
float dLength = 4.0;
|
||||
|
||||
printf( "sum: %f\n", Geometry::getSumGeomSeries( dFirst, dRatio, dLength));
|
||||
printf( "length: %f\n", Geometry::getLengthGeomSeries( dFirst, dRatio, dSum));
|
||||
}
|
||||
|
||||
int main( void ){
|
||||
Line l1(1,-1,3 );
|
||||
Line l2(1,-0.2,10 );
|
||||
Line l3 = Line::makeLineFromTwoPoints( Vector2D(1,-1), Vector2D(2,-2) );
|
||||
l3.show();
|
||||
cout << endl;
|
||||
l1.show();
|
||||
l2.show();
|
||||
l1.getIntersection( l2 ).show();
|
||||
}
|
||||
|
||||
int main( void ){
|
||||
Line l( 1, -1, 0 );
|
||||
Vector2D s1, s2;
|
||||
int i = l.getCircleIntersectionPoints( Circle( Vector2D(1,1), 1 ), &s1, &s2 );
|
||||
printf( "number of solutions: %d\n", i );
|
||||
if( i == 2 ){
|
||||
cout << s1 << " " << s2 ;
|
||||
}
|
||||
else if( i == 1 ){
|
||||
cout << s1;
|
||||
}
|
||||
cout << "line: " << l << endl;
|
||||
}
|
||||
|
||||
int main( void ){
|
||||
Circle c11( Vector2D( 10, 0 ), 10);
|
||||
Circle c12( Vector2D( 40, 3 ), 40 );
|
||||
Circle c21( Vector2D( 0,0 ), 5);
|
||||
Circle c22( Vector2D( 3,0 ), 40 );
|
||||
|
||||
Vector2D p1, p2;
|
||||
|
||||
cout << c11.getIntersectionArea( c21 ) << endl;
|
||||
cout << c12.getIntersectionArea( c21 ) << endl;
|
||||
cout << c22.getIntersectionArea( c11 ) << endl;
|
||||
cout << c12.getIntersectionArea( c22 ) << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( void ){
|
||||
cout << getBisectorTwoAngles( -155.3, 179.0 ) << endl;
|
||||
cout << getBisectorTwoAngles( -179.3, 179.0 ) << endl;
|
||||
}
|
||||
|
||||
int main( ) {
|
||||
Vector2D pos = Vector2D::getVector2DFromPolar(10, 45);
|
||||
cout << pos << endl;
|
||||
cout << pos.getDirection() << endl;
|
||||
cout << pos.getLength() << endl;
|
||||
|
||||
//Vector2D pos = Vector2D(10, 0);
|
||||
//cout << pos << endl;
|
||||
//cout << pos.getDirection() << endl;
|
||||
//pos.rotate(90);
|
||||
//cout << pos << endl;
|
||||
//cout << pos.getDirection() << endl;
|
||||
}
|
||||
|
||||
int main( ) {
|
||||
Cone c( Vector2D(-10,-10), -170, -150, 50 );
|
||||
c.show();
|
||||
cout << endl
|
||||
<< "isInside( Vector2D(0,0)): " << c.isInside( Vector2D(0,0) ) << endl
|
||||
<< "isInside( Vector2D(0,-5)): " << c.isInside( Vector2D(0,-5) ) << endl
|
||||
<< "isInside( Vector2D(-12,-11)): " << c.isInside( Vector2D(-12,-11) ) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,864 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2000,2001, Jelle Kok, University of Amsterdam
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the University of Amsterdam nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**************************************************************************************
|
||||
* geometry.hh
|
||||
*
|
||||
* implements:
|
||||
* class Vector2D
|
||||
* namespace Geometry
|
||||
* class Line
|
||||
* class Circle
|
||||
* class Rectangle
|
||||
* class Cone
|
||||
*
|
||||
* requires:
|
||||
*
|
||||
* Maintainer: wenns, pagra
|
||||
*
|
||||
* Changelog:
|
||||
*
|
||||
* Note:
|
||||
*************************************************************************************/
|
||||
|
||||
#ifndef GEOMETRY_HH
|
||||
#define GEOMETRY_HH
|
||||
|
||||
#include <math.h> // needed for M_PI constant
|
||||
#include <vector> // To fix include dependencies
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
const float EPSILON = 0.001;
|
||||
|
||||
typedef float AngRad; /**< Type definition for angles in degrees. */
|
||||
typedef float AngDeg; /**< Type definition for angles in radians. */
|
||||
|
||||
/**
|
||||
* Converts an angle in radians to the corresponding angle in degrees.
|
||||
* @param x an angle in radians
|
||||
* @return the corresponding angle in degrees
|
||||
*/
|
||||
AngDeg Rad2Deg ( AngRad x );
|
||||
|
||||
/**
|
||||
* Converts an angle in degrees to the corresponding angle in radians.
|
||||
* @param x an angle in degrees
|
||||
* @return the corresponding angle in radians
|
||||
*/
|
||||
AngRad Deg2Rad ( AngDeg x );
|
||||
|
||||
/**
|
||||
* Returns the cosine of a given angle in degrees using the
|
||||
* built-in cosine function that works with angles in radians.
|
||||
* @param x an angle in degrees
|
||||
* @return the cosine of the given angle
|
||||
*/
|
||||
float cosDeg ( AngDeg x );
|
||||
|
||||
/**
|
||||
* Returns the sine of a given angle in degrees using the
|
||||
* built-in sine function that works with angles in radians.
|
||||
* @param x an angle in degrees
|
||||
* @return the sine of the given angle
|
||||
*/
|
||||
float sinDeg ( AngDeg x );
|
||||
|
||||
/**
|
||||
* Returns the tangent of a given angle in degrees using the
|
||||
* built-in tangent function that works with angles in radians.
|
||||
* @param x an angle in degrees
|
||||
* @return the tangent of the given angle
|
||||
*/
|
||||
float tanDeg ( AngDeg x );
|
||||
|
||||
/**
|
||||
* Rreturns the principal value of the arc tangent of x in degrees
|
||||
* using the built-in arc tangent function which returns this value in radians.
|
||||
* @param x a float value
|
||||
* @return the arc tangent of the given value in degrees
|
||||
*/
|
||||
AngDeg atanDeg ( float x );
|
||||
|
||||
/**
|
||||
* Returns the principal value of the arc tangent of y/x in
|
||||
* degrees using the signs of both arguments to determine the quadrant of the
|
||||
* return value. For this the built-in 'atan2' function is used which returns
|
||||
* this value in radians.
|
||||
* @param x a float value
|
||||
* @param y a float value
|
||||
* @return the arc tangent of y/x in degrees taking the signs of x and y into
|
||||
* account
|
||||
*/
|
||||
float atan2Deg ( float x, float y );
|
||||
|
||||
/**
|
||||
* Returns the principal value of the arc cosine of x in degrees
|
||||
* using the built-in arc cosine function which returns this value in radians.
|
||||
* @param x a float value
|
||||
* @return the arc cosine of the given value in degrees
|
||||
*/
|
||||
AngDeg acosDeg ( float x );
|
||||
|
||||
/**
|
||||
* Returns the principal value of the arc sine of x in degrees
|
||||
* using the built-in arc sine function which returns this value in radians.
|
||||
* @param x a float value
|
||||
* @return the arc sine of the given value in degrees
|
||||
*/
|
||||
AngDeg asinDeg ( float x );
|
||||
|
||||
/**
|
||||
* Returns a boolean value which indicates whether the value
|
||||
* 'ang' (from interval [-180..180] lies in the interval [angMin..angMax].
|
||||
* Examples: isAngInInterval( -100, 4, -150) returns false
|
||||
* isAngInInterval( 45, 4, -150) returns true
|
||||
* @param ang angle that should be checked
|
||||
* @param angMin minimum angle in interval
|
||||
* @param angMax maximum angle in interval
|
||||
* @return boolean indicating whether ang lies in [angMin..angMax]
|
||||
*/
|
||||
bool isAngInInterval ( AngDeg ang, AngDeg angMin, AngDeg angMax );
|
||||
|
||||
/**
|
||||
* Returns the bisector (average) of two angles. It deals
|
||||
* with the boundary problem, thus when 'angMin' equals 170 and 'angMax'
|
||||
* equals -100, -145 is returned.
|
||||
* @param angMin minimum angle [-180,180]
|
||||
* @param angMax maximum angle [-180,180]
|
||||
* @return average of angMin and angMax.
|
||||
*/
|
||||
AngDeg getBisectorTwoAngles( AngDeg angMin, AngDeg angMax );
|
||||
|
||||
/**
|
||||
* Returns the difference of two angles in degrees [-180,180]
|
||||
* @param ang1 first angle [-180,180]
|
||||
* @param ang2 second angle [-180,180]
|
||||
*/
|
||||
AngDeg getAngleDifference( AngDeg ang1, AngDeg ang2 );
|
||||
|
||||
|
||||
/**
|
||||
* Returns the absolute difference of two angles in degrees [0,180]
|
||||
* @param ang1 first angle [-180,180]
|
||||
* @param ang2 second angle [-180,180]
|
||||
*/
|
||||
AngDeg getAbsAngleDifference( AngDeg ang1, AngDeg ang2 );
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes an arbitrary angle in 180 Deg System
|
||||
* @param angle: the angle to normalize
|
||||
* @return float (-180..180]
|
||||
*/
|
||||
float normalizeTo180Deg(float angle);
|
||||
|
||||
|
||||
/**
|
||||
* CoordSystem is an enumeration of the different specified coordinate systems.
|
||||
* The two possibilities are CARTESIAN or POLAR. These values are for instance
|
||||
* used in the initializing a Vector2D. The CoordSystem indicates whether
|
||||
* the supplied arguments represent the position in cartesian or in polar
|
||||
* coordinates.
|
||||
*/
|
||||
enum CoordSystemT {
|
||||
CARTESIAN,
|
||||
POLAR
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/******************** CLASS VECTOR2D **************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* This class contains an x- and y-coordinate of a position (x,y) as member
|
||||
* data and methods which operate on this position. The standard arithmetic
|
||||
* operators are overloaded and can thus be applied to positions (x,y). It is
|
||||
* also possible to represent a position in polar coordinates (r,phi), since
|
||||
* the class contains a method to convert these into cartesian coordinates (x,y).
|
||||
*/
|
||||
class Vector2D {
|
||||
private:
|
||||
float x; /**< x-coordinate of this position */
|
||||
float y; /**< y-coordinate of this position */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for the Vector2D class. When the supplied Coordinate System
|
||||
* type equals CARTESIAN, the arguments x and y denote the x- and y-coordinates
|
||||
* of the new position. When it equals POLAR however, the arguments x and y
|
||||
* denote the polar coordinates of the new position; in this case x is thus
|
||||
* equal to the distance r from the origin and y is equal to the angle phi that
|
||||
* the polar vector makes with the x-axis.
|
||||
* @param x the x-coordinate of the new position when cs == CARTESIAN; the
|
||||
* distance of the new position from the origin when cs = POLAR
|
||||
* @param y the y-coordinate of the new position when cs = CARTESIAN; the
|
||||
* angle that the polar vector makes with the x-axis when cs = POLAR
|
||||
* @param cs a CoordSystemT indicating whether x and y denote cartesian
|
||||
* coordinates or polar coordinates
|
||||
* @return the Vector2D corresponding to the given arguments
|
||||
*/
|
||||
Vector2D ( float x = 0,
|
||||
float y = 0,
|
||||
CoordSystemT cs = CARTESIAN);
|
||||
|
||||
//////////////////// overloaded arithmetic operators /////////////////////////////
|
||||
/*
|
||||
* Note: all operators parametrized with float values apply these values to both
|
||||
* coordinates of the vector
|
||||
*/
|
||||
|
||||
/**
|
||||
* Overloaded version of unary minus operator for Vector2Ds. The current Vector2D
|
||||
* itself is left unchanged.
|
||||
* @return a negated version of the current Vector2D
|
||||
*/
|
||||
Vector2D operator - ( ) { return ( Vector2D( -x, -y ) ); }
|
||||
|
||||
Vector2D operator + ( const float &d ) const { return ( Vector2D( x + d, y + d ) ); }
|
||||
Vector2D operator + ( const Vector2D &p ) const { return ( Vector2D( x + p.x, y + p.y ) ); }
|
||||
Vector2D operator - ( const float &d ) const { return ( Vector2D( x - d, y - d ) ); }
|
||||
Vector2D operator - ( const Vector2D &p ) const { return ( Vector2D( x - p.x, y - p.y ) ); }
|
||||
Vector2D operator * ( const float &d ) const { return ( Vector2D( x * d, y * d ) ); }
|
||||
Vector2D operator * ( const Vector2D &p ) const { return ( Vector2D( x * p.x, y * p.y ) ); }
|
||||
Vector2D operator / ( const float &d ) const { return ( Vector2D( x / d, y / d ) ); }
|
||||
Vector2D operator / ( const Vector2D &p ) const { return ( Vector2D( x / p.x, y / p.y ) ); }
|
||||
void operator = ( const float &d ) { x = d; y = d; }
|
||||
void operator += ( const Vector2D &p ) { x += p.x; y += p.y; }
|
||||
void operator += ( const float &d ) { x += d; y += d; }
|
||||
void operator -= ( const Vector2D &p ) { x -= p.x; y -= p.y; }
|
||||
void operator -= ( const float &d ) { x -= d; y -= d; }
|
||||
void operator *= ( const Vector2D &p ) { x *= p.x; y *= p.y; }
|
||||
void operator *= ( const float &d ) { x *= d; y *= d; }
|
||||
void operator /= ( const Vector2D &p ) { x /= p.x; y /= p.y; }
|
||||
void operator /= ( const float &d ) { x /= d; y /= d; }
|
||||
bool operator != ( const Vector2D &p ) const { return ( ( x != p.x ) || ( y != p.y ) ); }
|
||||
bool operator != ( const float &d ) const { return ( ( x != d ) || ( y != d ) ); }
|
||||
bool operator == ( const Vector2D &p ) const { return ( ( x == p.x ) && ( y == p.y ) ); }
|
||||
bool operator == ( const float &d ) const { return ( ( x == d ) && ( y == d ) ); }
|
||||
|
||||
//////////////////////// methods for producing output ////////////////////////////
|
||||
friend ostream& operator << ( ostream &os,
|
||||
Vector2D p );
|
||||
/**
|
||||
* Writes the current Vector2D to standard output. It can also print a polar
|
||||
* representation of the current Vector2D.
|
||||
* @param cs a CoordSystemtT indicating whether a POLAR or CARTESIAN
|
||||
* representation of the current Vector2D should be printed
|
||||
*/
|
||||
void show ( CoordSystemT cs = CARTESIAN );
|
||||
|
||||
// accessors
|
||||
void setX ( float newX ) { x = newX; }
|
||||
float getX ( ) const { return x; }
|
||||
void setY ( float newY ) { y = newY; }
|
||||
float getY ( ) const { return y; }
|
||||
|
||||
/**
|
||||
* decides if the Vector2D is invalid
|
||||
* @return true, if the Vector2D is invalid, false otherwise
|
||||
*/
|
||||
bool isInvalid() const;
|
||||
|
||||
/**
|
||||
* (re)sets the coordinates of the current Vector2D. The given
|
||||
* coordinates can either be polar or Cartesian coordinates.
|
||||
* @param newX a float value indicating either a new Cartesian x-coordinate when
|
||||
* cs=CARTESIAN or a new polar r-coordinate (distance) when cs=POLAR
|
||||
* @param newY a float value indicating either a new Cartesian y-coordinate when
|
||||
* cs=CARTESIAN or a new polar phi-coordinate (angle) when cs=POLAR
|
||||
* @param cs a CoordSystemT indicating whether x and y denote cartesian
|
||||
* coordinates or polar coordinates
|
||||
*/
|
||||
void setVector2D ( float newX = 0,
|
||||
float newY = 0,
|
||||
CoordSystemT cs = CARTESIAN);
|
||||
|
||||
//wenns: temp workaround
|
||||
//void setVector2D_Orig( float dX, float dY, CoordSystemT cs);
|
||||
|
||||
/**
|
||||
* Determines the distance between the current Vector2D and a
|
||||
* given Vector2D.
|
||||
* @param p a Vector2D
|
||||
* @return the distance between the current Vector2D and the given
|
||||
* Vector2D
|
||||
*/
|
||||
inline float distanceTo ( const Vector2D &p ) const
|
||||
{ return ( ( *this - p ).getLength( ) ); }
|
||||
|
||||
/**
|
||||
* Adjusts the coordinates of the current Vector2D in such a way
|
||||
* that the length of the corresponding vector equals the float value which
|
||||
* is supplied as an argument.
|
||||
* @param f a float value representing a new length
|
||||
* @return the result of scaling the vector corresponding with the current
|
||||
* Vector2D to the given length thus yielding a different Vector2D
|
||||
*/
|
||||
Vector2D setLength ( float f );
|
||||
|
||||
/**
|
||||
* This method determines the length of Vector2D using the formula of Pythagoras.
|
||||
* @return the length of the Vector2D
|
||||
*/
|
||||
inline float getLength ( ) const { return ( sqrt( x * x + y * y ) ); }
|
||||
|
||||
/**
|
||||
* This method determines the direction of the current Vector2D (the phi-coordinate
|
||||
* in polar representation)
|
||||
* @return the direction in degrees of the current Vector2D
|
||||
*/
|
||||
inline AngDeg getDirection ( ) const { return ( atan2Deg( y, x ) ); }
|
||||
|
||||
/////////////////////// comparison methods for positions ///////////////////////////
|
||||
|
||||
/**
|
||||
* Determines whether the current Vector2D is in front of a
|
||||
* given Vector2D, i.e. whether the x-coordinate of the current Vector2D
|
||||
* is larger than the x-coordinate of the given Vector2D.
|
||||
* @param p a Vector2D to which the current Vector2D must be compared
|
||||
* @return true when the current Vector2D is in front of the given
|
||||
* Vector2D; false otherwise
|
||||
*/
|
||||
bool isInFrontOf ( const Vector2D &p )
|
||||
{ return ( ( x > p.getX( ) ) ? true : false ); }
|
||||
/**< similar as above */
|
||||
bool isInFrontOf ( const float &d ) { return ( ( x > d ) ? true : false ); }
|
||||
|
||||
/**
|
||||
* Determines whether the current Vector2D is behind a given
|
||||
* Vector2D, i.e. whether the x-coordinate of the current Vector2D is
|
||||
* smaller than the x-coordinate of the given Vector2D.
|
||||
* @param p a Vector2D to which the current Vector2D must be compared
|
||||
* @return true when the current Vector2D is behind the given Vector2D;
|
||||
* false otherwise
|
||||
*/
|
||||
bool isBehindOf ( const Vector2D &p )
|
||||
{ return ( ( x < p.getX( ) ) ? true : false ); }
|
||||
/**< similar as above */
|
||||
bool isBehindOf ( const float &d ) { return ( ( x < d ) ? true : false ); }
|
||||
|
||||
/**
|
||||
* Determines whether the current Vector2D is to the left of a
|
||||
* given Vector2D, i.e. whether the y-coordinate of the current Vector2D
|
||||
* is smaller than the y-coordinate of the given Vector2D.
|
||||
* @param p a Vector2D to which the current Vector2D must be compared
|
||||
* @return true when the current Vector2D is to the left of the given
|
||||
* Vector2D; false otherwise
|
||||
*/
|
||||
bool isLeftOf ( const Vector2D &p )
|
||||
{ return ( ( y < p.getY( ) ) ? true : false ); }
|
||||
/**< similar as above */
|
||||
bool isLeftOf ( const float &d ) { return ( ( y < d ) ? true : false ); }
|
||||
|
||||
/**
|
||||
* This method determines whether the current Vector2D is to the right of a
|
||||
* given Vector2D, i.e. whether the y-coordinate of the current Vector2D
|
||||
* is larger than the y-coordinate of the given Vector2D.
|
||||
* @param p a Vector2D to which the current Vector2D must be compared
|
||||
* @return true when the current Vector2D is to the right of the given
|
||||
* Vector2D; false otherwise
|
||||
*/
|
||||
bool isRightOf ( const Vector2D &p )
|
||||
{ return ( ( y > p.getY( ) ) ? true : false ); }
|
||||
/**< similar as above */
|
||||
bool isRightOf ( const float &d ) { return ( ( y > d ) ? true : false ); }
|
||||
|
||||
/**
|
||||
* Determines whether the current Vector2D is in between two
|
||||
* given Vector2Ds when looking in the x-direction, i.e. whether the current
|
||||
* Vector2D is in front of the first argument and behind the second.
|
||||
* @param p1 a Vector2D to which the current Vector2D must be compared
|
||||
* @param p2 a Vector2D to which the current Vector2D must be compared
|
||||
* @return true when the current Vector2D is in between the two given
|
||||
* Vector2Ds when looking in the x-direction; false otherwise
|
||||
*/
|
||||
inline bool isBetweenX ( const Vector2D &p1,
|
||||
const Vector2D &p2 )
|
||||
{ return ( ( isInFrontOf( p1 ) && isBehindOf( p2 ) ) ? true : false ); }
|
||||
/**< similar as above */
|
||||
inline bool isBetweenX ( const float &d1,
|
||||
const float &d2 )
|
||||
{ return ( ( isInFrontOf( d1 ) && isBehindOf( d2 ) ) ? true : false ); }
|
||||
|
||||
/**
|
||||
* Determines whether the current Vector2D is in between two
|
||||
* given Vector2Ds when looking in the y-direction, i.e. whether the current
|
||||
* Vector2D is to the right of the first argument and to the left of the
|
||||
* second.
|
||||
* @param p1 a Vector2D to which the current Vector2D must be compared
|
||||
* @param p2 a Vector2D to which the current Vector2D must be compared
|
||||
* @return true when the current Vector2D is in between the two given
|
||||
* Vector2Ds when looking in the y-direction; false otherwise
|
||||
*/
|
||||
bool isBetweenY ( const Vector2D &p1,
|
||||
const Vector2D &p2 )
|
||||
{ return ( ( isRightOf( p1 ) && isLeftOf( p2 ) ) ? true : false ); }
|
||||
/**< similar as above */
|
||||
bool isBetweenY ( const float &d1,
|
||||
const float &d2 )
|
||||
{ return ( ( isRightOf( d1 ) && isLeftOf( d2 ) ) ? true : false ); }
|
||||
|
||||
/////////////////// conversion methods for positions ////////////////////////////
|
||||
|
||||
/**
|
||||
* Normalizes a Vector2D by setting the length of the
|
||||
* corresponding vector to 1.
|
||||
* @return the result of normalizing the current Vector2D
|
||||
*/
|
||||
inline Vector2D normalize ( ) { return ( setLength( 1.0 ) ); }
|
||||
|
||||
/**
|
||||
* Rotates the current Vector2D over a given angle .
|
||||
* @param angle an angle in degrees over which the current Vector2D must be rotated
|
||||
* @return the result of rotating the current Vector2D over the given angle
|
||||
*/
|
||||
Vector2D rotate ( AngDeg angle );
|
||||
|
||||
/**
|
||||
* Converts the coordinates of the current Vector2D (which are represented in an
|
||||
* global coordinate system with the origin at (0,0)) into relative coordinates
|
||||
* in a different coordinate system (e.g. relative to a player). The new coordinate
|
||||
* system is defined by the arguments to the method.
|
||||
* @param origin the origin of the relative coordinate frame
|
||||
* @param ang the angle between the world frame and the relative frame
|
||||
* (reasoning from the world frame)
|
||||
* @return the result of converting the current global Vector2D into a
|
||||
* relative Vector2D
|
||||
*/
|
||||
Vector2D globalToRelative ( Vector2D orig,
|
||||
AngDeg ang );
|
||||
/**< similar to above */
|
||||
Vector2D relativeToGlobal ( Vector2D orig,
|
||||
AngDeg ang );
|
||||
/**
|
||||
* Returns a Vector2D that lies somewhere on the vector between
|
||||
* the current Vector2D and a given Vector2D. The desired position is
|
||||
* specified by a given fraction of this vector (e.g. 0.5 means exactly in
|
||||
* the middle of the vector).
|
||||
* @param p a Vector2D which defines the vector to the current Vector2D
|
||||
* @param dFrac float representing the fraction of the connecting vector at
|
||||
* which the desired Vector2D lies.
|
||||
* @return the Vector2D which lies at fraction dFrac on the vector
|
||||
* connecting p and the current Vector2D
|
||||
*/
|
||||
Vector2D getVector2DOnLineFraction( Vector2D &p,
|
||||
float dFrac );
|
||||
|
||||
/**
|
||||
* Converts a polar representation of a Vector2D into a Cartesian.
|
||||
* @param dMag a float representing the polar r-coordinate, i.e. the distance
|
||||
* from the point to the origin
|
||||
* @param ang the angle that the polar vector makes with the x-axis, i.e. the
|
||||
* polar phi-coordinate
|
||||
* @return the result of converting the given polar representation into a
|
||||
* Cartesian representation thus yielding a Cartesian Vector2D
|
||||
*/
|
||||
//static Vector2D getVector2DFromPolar( float dMag,
|
||||
// AngDeg ang );
|
||||
|
||||
//wenns: temp workaround
|
||||
static Vector2D getVector2DFromPolar/*_Orig*/( float dMag, AngDeg ang );
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/********************* NAMESPACE GEOMETRY *********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
namespace Geometry {
|
||||
///////////////////////////// geometric series //////////////////////////////////
|
||||
|
||||
/*
|
||||
* A geometric series is one in which there is a constant ratio between each
|
||||
* element and the one preceding it.
|
||||
* Normally: s = a + ar + ar^2 + ... + ar^n
|
||||
* Now: Sum = First + First*Ratio + First*Ratio^2 + .. + Fist*Ratio^n
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determines the length of a geometric series given its first element, the sum
|
||||
* of the elements in the series and the constant ratio between the elements.
|
||||
* @param first first term of the series
|
||||
* @param ratio ratio with which the the first term is multiplied
|
||||
* @param sum the total sum of all the serie
|
||||
* @return the length(n in above example) of the series
|
||||
*/
|
||||
float getLengthGeomSeries (float first, float ratio, float sum );
|
||||
|
||||
/**
|
||||
* Determines the sum of a geometric series given its first element, the ratio and
|
||||
* the number of steps in the series
|
||||
* @param first first term of the series
|
||||
* @param ratio ratio with which the the first term is multiplied
|
||||
* @param length the number of steps to be taken into account
|
||||
* @return the sum of the series
|
||||
*/
|
||||
float getSumGeomSeries ( float first, float ratio, float length );
|
||||
/**
|
||||
* Determines the sum of an infinite geometric series given its first element and
|
||||
* the constant ratio between the elements. Note that such an infinite series will
|
||||
* only converge when 0<r<1.
|
||||
* @param first first term of the series
|
||||
* @param ratio ratio with which the the first term is multiplied
|
||||
* @return the sum of the series
|
||||
*/
|
||||
float getSumInfGeomSeries ( float first, float ratio );
|
||||
|
||||
/**
|
||||
* Determines the first element of a geometric series given its element, the ratio
|
||||
* and the number of steps in the series
|
||||
* @param sum sum of the series
|
||||
* @param ratio ratio with which the the first term is multiplied
|
||||
* @param length the number of steps to be taken into account
|
||||
* @return the first element (a) of a serie
|
||||
*/
|
||||
float getFirstGeomSeries ( float sum, float ratio, float length );
|
||||
|
||||
/**
|
||||
* Determines the first element of an infinite geometric series given its first
|
||||
* element and the constant ratio between the elements. Note that such an infinite
|
||||
* series will only converge when 0<r<1.
|
||||
* @param sum sum of the series
|
||||
* @param ratio ratio with which the the first term is multiplied
|
||||
* @return the first term of the series
|
||||
*/
|
||||
float getFirstInfGeomSeries ( float sum, float ratio );
|
||||
|
||||
/////////////////////////////// Pythagoras' Theorem ////////////////////////////////
|
||||
/**
|
||||
* Performs the abc formula (Pythagoras' Theorem) on the given parameters and puts
|
||||
* the result in *s1 en *s2. It returns the number of found coordinates.
|
||||
* @param a a parameter in abc formula
|
||||
* @param b b parameter in abc formula
|
||||
* @param c c parameter in abc formula
|
||||
* @param *s1 first result of abc formula
|
||||
* @param *s2 second result of abc formula
|
||||
* @return number of found x-coordinates
|
||||
*/
|
||||
int abcFormula ( float a, float b, float c, float *s1, float *s2 );
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** CLASS CIRCLE ******************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* This class represents a circle. A circle is defined by one Vector2D
|
||||
* (which denotes the center) and its radius.
|
||||
*/
|
||||
class Circle{
|
||||
Vector2D posCenter; /**< Center of the circle */
|
||||
float radius; /**< Radius of the circle */
|
||||
|
||||
public:
|
||||
Circle( );
|
||||
Circle( Vector2D pos, float r );
|
||||
|
||||
void show ( ostream& os = cout ) const;
|
||||
|
||||
// accessors
|
||||
/**
|
||||
* Sets the values of the circle.
|
||||
* @param pos new center of the circle
|
||||
* @param r new radius of the circle ( > 0 )
|
||||
* @return bool indicating whether radius was set
|
||||
*/
|
||||
bool setCircle ( const Vector2D &pos, float r );
|
||||
|
||||
/**
|
||||
* Sets the radius of the circle.
|
||||
* @param r new radius of the circle ( > 0 )
|
||||
* @return bool indicating whether radius was set
|
||||
*/
|
||||
bool setRadius ( const float r );
|
||||
void setCenter ( const Vector2D &pos ) { posCenter = pos; }
|
||||
|
||||
float getRadius () const { return radius; }
|
||||
Vector2D getCenter () const { return posCenter; }
|
||||
float getCircumference () const { return 2.0*M_PI*getRadius(); }
|
||||
float getArea () const { return M_PI*getRadius()*getRadius(); }
|
||||
|
||||
/**
|
||||
* Returns a boolean that indicates whether 'pos' is located inside the circle.
|
||||
* @param pos position of which should be checked whether it is located in the
|
||||
* circle
|
||||
* @return bool indicating whether pos lies inside the circle
|
||||
*/
|
||||
bool isInside ( const Vector2D &pos ) const
|
||||
{ return posCenter.distanceTo( pos ) < getRadius(); }
|
||||
|
||||
/**
|
||||
* Returns the two possible intersection points between two circles. This method
|
||||
* returns the number of solutions that were found.
|
||||
* @param c circle with which intersection should be found
|
||||
* @param p1 will be filled with first solution
|
||||
* @param p2 will be filled with second solution
|
||||
* @return number of solutions.
|
||||
*/
|
||||
int getIntersectionPoints ( const Circle &c, Vector2D *p1, Vector2D *p2) const;
|
||||
|
||||
/**
|
||||
* Returns the size of the intersection area of two circles.
|
||||
* @param c circle with which intersection should be determined
|
||||
* @return size of the intersection area.
|
||||
*/
|
||||
float getIntersectionArea ( const Circle &c ) const ;
|
||||
|
||||
|
||||
bool calcTangentIntersectionPoints(const Vector2D, Vector2D &point1, Vector2D &point2);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************** CLASS LINE *******************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* This class contains the representation of a line. A line is defined
|
||||
* by the formula ay + bx + c = 0. The coefficients a, b and c are stored
|
||||
* and used in the calculations.
|
||||
*/
|
||||
class Line {
|
||||
// a line is defined by the formula: ay + bx + c = 0
|
||||
float a; /**< This is the a coefficient in the line ay + bx + c = 0 */
|
||||
float b; /**< This is the b coefficient in the line ay + bx + c = 0 */
|
||||
float c; /**< This is the c coefficient in the line ay + bx + c = 0 */
|
||||
|
||||
public:
|
||||
Line( float a, float b, float c );
|
||||
Line();
|
||||
|
||||
//accessors
|
||||
float getACoefficient ( ) const { return a; }
|
||||
float getBCoefficient ( ) const { return b; }
|
||||
float getCCoefficient ( ) const { return c; }
|
||||
|
||||
|
||||
// print methods
|
||||
void show( ostream& os = cout );
|
||||
friend ostream& operator << (ostream & os, Line l);
|
||||
|
||||
/**
|
||||
* Returns the intersection point between the current Line and the specified line.
|
||||
* @param line line with which the intersection should be calculated.
|
||||
* @return Vector2D position that is the intersection point.
|
||||
*/
|
||||
Vector2D getIntersection ( Line line );
|
||||
|
||||
/**
|
||||
* This method calculates the intersection points between the current line
|
||||
* and the circle specified with as center 'posCenter' and radius 'radius'.
|
||||
* The number of solutions are returned and the corresponding points are put
|
||||
* in the third and fourth argument of the method
|
||||
* @param c circle with which intersection points should be found
|
||||
* @param posSolution1 first intersection (if any)
|
||||
* @param posSolution2 second intersection (if any)
|
||||
*/
|
||||
int getCircleIntersectionPoints( Circle circle,
|
||||
Vector2D *posSolution1,
|
||||
Vector2D *posSolution2 );
|
||||
|
||||
/**
|
||||
* Returns the tangent line to a Vector2D. This is the line between the specified
|
||||
* position and the closest point on the line to this position.
|
||||
* @param pos Vector2D point with which tangent line is calculated.
|
||||
* @return Line line tangent to this position
|
||||
*/
|
||||
Line getTangentLine ( Vector2D pos );
|
||||
|
||||
/**
|
||||
* Returns the closest point on a line to a given position.
|
||||
* @param pos point to which closest point should be determined
|
||||
* @return Vector2D closest point on line to 'pos'.
|
||||
*/
|
||||
Vector2D getPointOnLineClosestTo ( Vector2D pos );
|
||||
|
||||
/**
|
||||
* Returns the distance between a specified position and the closest point on
|
||||
* the given line.
|
||||
* @param pos position to which distance should be calculated
|
||||
* @return float indicating the distance to the line.
|
||||
*/
|
||||
float distanceToPoint ( Vector2D pos );
|
||||
|
||||
/**
|
||||
* Determines whether the projection of a point on the current line lies between
|
||||
* two other points ('point1' and 'point2') that lie on the same line.
|
||||
* @param pos point of which projection is checked.
|
||||
* @param point1 first point on line
|
||||
* @param point2 second point on line
|
||||
* @return true when projection of 'pos' lies between 'point1' and 'point2'.
|
||||
*/
|
||||
bool isInBetween ( Vector2D pos,
|
||||
Vector2D point1,
|
||||
Vector2D point2 );
|
||||
|
||||
/**
|
||||
* Calculates the y coordinate given the x coordinate
|
||||
* @param x coordinate
|
||||
* @return y coordinate on this line
|
||||
*/
|
||||
float getYGivenX ( float x );
|
||||
|
||||
/**
|
||||
* Calculates the x coordinate given the y coordinate
|
||||
* @param y coordinate
|
||||
* @return x coordinate on this line
|
||||
*/
|
||||
float getXGivenY ( float y );
|
||||
|
||||
/////// static methods to make a line using an easier representation ////////
|
||||
/**
|
||||
* Creates a line given two points.
|
||||
* @param pos1 first point
|
||||
* @param pos2 second point
|
||||
* @return line that passes through the two specified points.
|
||||
*/
|
||||
static Line makeLineFromTwoPoints ( Vector2D pos1,
|
||||
Vector2D pos2 );
|
||||
|
||||
/**
|
||||
* Creates a line given a position and an angle.
|
||||
* @param vec position through which the line passes
|
||||
* @param angle direction of the line.
|
||||
* @return line that goes through position 'vec' with angle 'angle'.
|
||||
*/
|
||||
static Line makeLineFromPositionAndAngle ( Vector2D vec,
|
||||
AngDeg angle );
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** CLASS RECTANGLE ***************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* This class represents a rectangle. A rectangle is defined by two Vector2Ds
|
||||
* the one at the upper left corner and the one at the right bottom.
|
||||
*/
|
||||
class RectangleGeo {
|
||||
Vector2D posLeftTop; /**< top left position of the rectangle */
|
||||
Vector2D posRightBottom; /**< bottom right position of the rectangle */
|
||||
|
||||
public:
|
||||
/**
|
||||
* This is the constructor of a Rectangle. Two points will be given. The
|
||||
* order does not matter as long as two opposite points are given (left
|
||||
* top and right bottom or right top and left bottom).
|
||||
* @param pos first point that defines corner of rectangle
|
||||
* @param pos2 second point that defines other corner of rectangle
|
||||
* @return rectangle with 'pos' and 'pos2' as opposite corners.
|
||||
*/
|
||||
RectangleGeo ( Vector2D pos, Vector2D pos2 );
|
||||
|
||||
void show ( ostream& os = cout ) const;
|
||||
|
||||
/**
|
||||
* Determines whether the given position lies inside the current rectangle.
|
||||
* @param pos position which is checked whether it lies in rectangle
|
||||
* @return true when 'pos' lies in the rectangle, false otherwise
|
||||
*/
|
||||
bool isInside ( Vector2D pos ) const;
|
||||
|
||||
/**
|
||||
* Sets the upper left and right bottom point of the current rectangle.
|
||||
* @param pos first point that defines corner of rectangle
|
||||
* @param pos2 second point that defines other corner of rectangle
|
||||
*/
|
||||
void setRectanglePoints( Vector2D pos1,
|
||||
Vector2D pos2 );
|
||||
|
||||
void setPosLeftTop ( Vector2D pos ) { posLeftTop = pos; }
|
||||
void setPosRightBottom ( Vector2D pos ) { posRightBottom = pos; }
|
||||
Vector2D getPosLeftTop () const { return posLeftTop; }
|
||||
Vector2D getPosRightBottom () const { return posRightBottom; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/********************** CLASS CONE **** ***************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* This class represents a cone. A cone is defined by one point,
|
||||
* two angles (-180 to 180), a maximum and a minimum distance.
|
||||
* The point gives the peak of the cone. A point that lies in the cone
|
||||
* is at least minimum distance and at most maximum distance away from
|
||||
* the peak. Additionally the point must lie in the segment between
|
||||
* the first angle (the left edge) and the second angle (the other edge).
|
||||
* The area is defined by rotating the first edge (given by the first angle)
|
||||
* clockwise (mit dem Uhrzeigersinn) till the second angle is reached.
|
||||
*/
|
||||
class Cone {
|
||||
Vector2D peak; /**< peak of the cone */
|
||||
float fstAngle; /**< the left edge. Start of clockwise rotation. */
|
||||
float sndAngle; /**< the right edge. End of clockwise rotation. */
|
||||
float maxDistance; /**< the max. distance a point on the cone can be away from the peak. */
|
||||
float minDistance; /**< the min. distance a point on the cone must be away from the peak. */
|
||||
|
||||
public:
|
||||
/**
|
||||
* This is the constructor of a Cone. The cone lies between fstAngle and sndAngle,
|
||||
* where sndAngle is interpreted as being clockwise rotated in relation
|
||||
* to fstAngle.
|
||||
* @param peak first point that defines top of the cone
|
||||
* @param fstAngle absolute angle of the first edge
|
||||
* @param sndAngle absolute angle of the second edge.
|
||||
* @param maxDistance max. distance a point on the cone can be away from the peak
|
||||
* @param minDistance min. distance a point on the cone must be away from the peak
|
||||
*/
|
||||
Cone( Vector2D peak,
|
||||
float fstAngle, float sndAngle,
|
||||
float maxDistance, float minDistance = 0 );
|
||||
|
||||
void show( ostream& os = cout ) const;
|
||||
|
||||
/**
|
||||
* Determines whether the given position lies inside the current cone.
|
||||
* @param pos position which is checked whether it lies in cone
|
||||
* @return true when 'pos' lies in the cone, false otherwise
|
||||
*/
|
||||
bool isInside( Vector2D pos ) const;
|
||||
|
||||
inline void setPeak( Vector2D newPeak ) { peak = newPeak; }
|
||||
inline void setAngles( float newFstAngle, float newSndAngle ) {
|
||||
fstAngle = newFstAngle, sndAngle = newSndAngle;
|
||||
}
|
||||
inline void setFstAngle( float newFstAngle ) { fstAngle = newFstAngle; }
|
||||
inline void setSndAngle( float newSndAngle ) { sndAngle = newSndAngle; }
|
||||
inline void setMaxDistance( float newMaxDistance) { maxDistance = newMaxDistance; }
|
||||
inline void setMinDistance( float newMinDistance) { minDistance = newMinDistance; }
|
||||
|
||||
};
|
||||
|
||||
#endif //Geometry.hh
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "global.h"
|
||||
#include "options.h"
|
||||
#include "asstring.h"
|
||||
#include <iostream>
|
||||
#include "SDL.h"
|
||||
#include "surfaceDB.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int GAME_LENGTH = 300000; // ms
|
||||
int ITEM_LIFETIME = 20000; // ms
|
||||
int ITEM_APPEAR_DELAY = 10000; // ms
|
||||
int ITEM_APPEAR_RAND_DELAY = 20000; // ms
|
||||
int ITEM_HEALTH_REPAIR_AMOUNT = 100;
|
||||
|
||||
int ITEM_HEATSEEKER_AMMO = 70;
|
||||
int ITEM_NUKE_AMMO = 2;
|
||||
int ITEM_DEFLECTOR_AMMO = 1;
|
||||
int ITEM_DEFLECTOR_ACTIVATION_DIST = 200;
|
||||
int ITEM_DEFLECTOR_POWER = 100;
|
||||
int ITEM_DEFLECTOR_DURATION = 15000;
|
||||
|
||||
int ITEM_APPEAR_CHANCES[] = { 50, 20, 30, 30, 30, 50, 20, 20, 30, 20, 20 };
|
||||
|
||||
int GENERATE_ENEMY_DELAY = 100;
|
||||
int GENERATE_ENEMY_RAND_DELAY = 2000;
|
||||
|
||||
int LIGHT_FIGHTER_MAX_SHIELD = 200;
|
||||
int HEAVY_FIGHTER_MAX_SHIELD = 500;
|
||||
int LIGHT_FIGHTER_MAX_DAMAGE = 200;
|
||||
int HEAVY_FIGHTER_MAX_DAMAGE = 500;
|
||||
|
||||
int LIGHT_FIGHTER_SHIELD_RECHARGE = 80;
|
||||
int HEAVY_FIGHTER_SHIELD_RECHARGE = 110;
|
||||
|
||||
int RACER_DEFLECTOR_ACTIVATION_DIST = 150;
|
||||
int RACER_DEFLECTOR_POWER = 50;
|
||||
int RACER_SONIC_ACTIVATION_DIST = 200;
|
||||
int RACER_SONIC_POWER = 50;
|
||||
|
||||
int ENEMY_HITPOINTS[] = { 80, 120, 150, 2000, 1500, 1000, 1000, 3000 };
|
||||
int ENEMY_COLLISION_DAMAGE[] = {20, 40, 0, 0, 0, 0, 0, 2000};
|
||||
int ENEMY_DIES_ITEM_APPEAR_CHANCE[] = {15, 12, 8, 0, 0, 0, 0, 1};
|
||||
int ENEMY_APPEAR_CHANCES[] = {40, 40, 10, 0, 0, 0, 0, 0};
|
||||
int ENEMY_COOLDOWN_PRIMARY[] = {400, 400, 400, 50, 500, 100, 100, 300};
|
||||
int ENEMY_COOLDOWN_SECONDARY[] = {0, 0, 2000, 0, 0, 0, 0, 600};
|
||||
int ENEMY_RAND_WAIT_PRIMARY[] = {1500, 1000, 300, 80, 1000, 200, 200, 2000};
|
||||
int ENEMY_RAND_WAIT_SECONDARY[] = {0, 0, 10000, 0, 0, 0, 0, 400};
|
||||
|
||||
int GENERATE_FORMATION_DELAY = 5000;
|
||||
int GENERATE_FORMATION_RAND_DELAY = 20000;
|
||||
|
||||
int FORMATION_MAX_NR_ENEMYS[] = {7,7,7,6};
|
||||
int FORMATION_SP_CHANCES[] = { 10, 10, 5, 5, 20, 10, 5, 20, 10, 20, 10 };
|
||||
int FORMATION_SP_PRIMARY_DELAY[] = {0, 80, 120, 160,
|
||||
500, 800, 1100,
|
||||
150, 250, 150, 250};
|
||||
int FORMATION_SP_PRIMARY_RAND_DELAY[] = { 0, 80, 120, 160,
|
||||
1000, 1500, 2000,
|
||||
0, 0, 0, 0 };
|
||||
|
||||
|
||||
|
||||
|
||||
void parseGlobalConfigValues( int difficultyLevel ) {
|
||||
|
||||
Options *op = 0;
|
||||
op = new Options( FN_DIFFICULTY_CONFIG +
|
||||
asString(difficultyLevel) +
|
||||
FN_DIFFICULTY_CONFIG_SUFFIX );
|
||||
|
||||
op->getInt( "GAME_LENGTH", GAME_LENGTH );
|
||||
|
||||
op->getInt( "ITEM_LIFETIME", ITEM_LIFETIME );
|
||||
op->getInt( "ITEM_APPEAR_DELAY", ITEM_APPEAR_DELAY );
|
||||
op->getInt( "ITEM_APPEAR_RAND_DELAY", ITEM_APPEAR_RAND_DELAY );
|
||||
|
||||
op->getInt( "ITEM_HEALTH_REPAIR_AMOUNT", ITEM_HEALTH_REPAIR_AMOUNT );
|
||||
|
||||
op->getInt( "ITEM_HEATSEEKER_AMMO", ITEM_HEATSEEKER_AMMO );
|
||||
op->getInt( "ITEM_NUKE_AMMO", ITEM_NUKE_AMMO );
|
||||
op->getInt( "ITEM_DEFLECTOR_AMMO", ITEM_DEFLECTOR_AMMO );
|
||||
op->getInt( "ITEM_DEFLECTOR_DURATION", ITEM_DEFLECTOR_DURATION );
|
||||
op->getInt( "ITEM_DEFLECTOR_ACTIVATION_DIST", ITEM_DEFLECTOR_ACTIVATION_DIST );
|
||||
op->getInt( "ITEM_DEFLECTOR_POWER", ITEM_DEFLECTOR_POWER );
|
||||
|
||||
op->getInt( "GENERATE_ENEMY_DELAY", GENERATE_ENEMY_DELAY );
|
||||
op->getInt( "GENERATE_ENEMY_RAND_DELAY", GENERATE_ENEMY_RAND_DELAY );
|
||||
|
||||
op->getInt( "LIGHT_FIGHTER_MAX_SHIELD", LIGHT_FIGHTER_MAX_SHIELD );
|
||||
op->getInt( "HEAVY_FIGHTER_MAX_SHIELD", HEAVY_FIGHTER_MAX_SHIELD );
|
||||
op->getInt( "LIGHT_FIGHTER_MAX_DAMAGE", LIGHT_FIGHTER_MAX_DAMAGE );
|
||||
op->getInt( "HEAVY_FIGHTER_MAX_DAMAGE", HEAVY_FIGHTER_MAX_DAMAGE );
|
||||
op->getInt( "LIGHT_FIGHTER_SHIELD_RECHARGE", LIGHT_FIGHTER_SHIELD_RECHARGE );
|
||||
op->getInt( "HEAVY_FIGHTER_SHIELD_RECHARGE", HEAVY_FIGHTER_SHIELD_RECHARGE );
|
||||
|
||||
op->getInt( "HEAVY_FIGHTER_DEFLECTOR_ACTIVATION_DIST",
|
||||
RACER_DEFLECTOR_ACTIVATION_DIST );
|
||||
op->getInt( "HEAVY_FIGHTER_DEFLECTOR_POWER",
|
||||
RACER_DEFLECTOR_POWER );
|
||||
|
||||
op->getInt( "FIGHTER_HITPOINTS", ENEMY_HITPOINTS[ FIGHTER ] );
|
||||
op->getInt( "BOMBER_HITPOINTS", ENEMY_HITPOINTS[ BOMBER ] );
|
||||
op->getInt( "TURRET_HITPOINTS", ENEMY_HITPOINTS[ TANK ] );
|
||||
op->getInt( "BOSS1_MAIN_GUN_HITPOINTS", ENEMY_HITPOINTS[ BOSS_1_MAIN_GUN ] );
|
||||
op->getInt( "BOSS1_ROCKET_LAUNCHER_HITPOINTS", ENEMY_HITPOINTS[ BOSS_1_ROCKET_LAUNCHER ] );
|
||||
op->getInt( "BOSS1_SHOT_BATTERY_LEFT_HITPOINTS",
|
||||
ENEMY_HITPOINTS[ BOSS_1_SHOT_BATTERY_LEFT ] );
|
||||
op->getInt( "BOSS1_SHOT_BATTERY_RIGHT_HITPOINTS",
|
||||
ENEMY_HITPOINTS[ BOSS_1_SHOT_BATTERY_RIGHT ] );
|
||||
|
||||
op->getInt( "COLLISION_DAMAGE_FIGHTER", ENEMY_COLLISION_DAMAGE[ FIGHTER ] );
|
||||
op->getInt( "COLLISION_DAMAGE_BOMBER", ENEMY_COLLISION_DAMAGE[ BOMBER ] );
|
||||
op->getInt( "ENEMY_DIES_ITEM_APPEAR_CHANCE_FIGHTER",
|
||||
ENEMY_DIES_ITEM_APPEAR_CHANCE[ FIGHTER ] );
|
||||
op->getInt( "ENEMY_DIES_ITEM_APPEAR_CHANCE_BOMBER",
|
||||
ENEMY_DIES_ITEM_APPEAR_CHANCE[ BOMBER ] );
|
||||
op->getInt( "ENEMY_DIES_ITEM_APPEAR_CHANCE_TURRET",
|
||||
ENEMY_DIES_ITEM_APPEAR_CHANCE[ TANK ] );
|
||||
|
||||
op->getInt( "ENEMY_APPEAR_CHANCE_FIGHTER",
|
||||
ENEMY_APPEAR_CHANCES[ FIGHTER ] );
|
||||
op->getInt( "ENEMY_APPEAR_CHANCE_BOMBER",
|
||||
ENEMY_APPEAR_CHANCES[ BOMBER ] );
|
||||
op->getInt( "ENEMY_APPEAR_CHANCE_TURRET",
|
||||
ENEMY_APPEAR_CHANCES[ TANK ] );
|
||||
|
||||
op->getInt( "ENEMY_COOLDOWN_FIGHTER",
|
||||
ENEMY_COOLDOWN_PRIMARY[ FIGHTER ] );
|
||||
op->getInt( "ENEMY_COOLDOWN_BOMBER",
|
||||
ENEMY_COOLDOWN_PRIMARY[ BOMBER ] );
|
||||
op->getInt( "ENEMY_COOLDOWN_TURRET",
|
||||
ENEMY_COOLDOWN_PRIMARY[ TANK ] );
|
||||
op->getInt( "ENEMY_COOLDOWN_BOSS1_MAIN_GUN",
|
||||
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_MAIN_GUN ] );
|
||||
op->getInt( "ENEMY_COOLDOWN_BOSS1_ROCKET_LAUNCHER",
|
||||
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_ROCKET_LAUNCHER] );
|
||||
op->getInt( "ENEMY_COOLDOWN_BOSS1_SHOT_BATTERY_LEFT",
|
||||
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_SHOT_BATTERY_LEFT] );
|
||||
op->getInt( "ENEMY_COOLDOWN_BOSS1_SHOT_BATTERY_RIGHT",
|
||||
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_SHOT_BATTERY_RIGHT ] );
|
||||
|
||||
op->getInt( "ENEMY_COOLDOWN_SECONDARY_TURRET", ENEMY_COOLDOWN_SECONDARY[ TANK ] );
|
||||
|
||||
op->getInt( "ENEMY_RAND_WAIT_FIGHTER",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ FIGHTER ] );
|
||||
op->getInt( "ENEMY_RAND_WAIT_BOMBER",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ BOMBER ] );
|
||||
op->getInt( "ENEMY_RAND_WAIT_TURRET",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ TANK ] );
|
||||
op->getInt( "ENEMY_RAND_WAIT_BOSS1_MAIN_GUN",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_MAIN_GUN ] );
|
||||
op->getInt( "ENEMY_RAND_WAIT_BOSS1_ROCKET_LAUNCHER",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_ROCKET_LAUNCHER ] );
|
||||
op->getInt( "ENEMY_RAND_WAIT_BOSS1_SHOT_BATTERY_LEFT",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_SHOT_BATTERY_LEFT ] );
|
||||
op->getInt( "ENEMY_RAND_WAIT_BOSS1_SHOT_BATTERY_RIGHT",
|
||||
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_SHOT_BATTERY_RIGHT ] );
|
||||
|
||||
op->getInt( "ENEMY_RAND_WAIT_SECONDARY_TURRET",
|
||||
ENEMY_RAND_WAIT_SECONDARY[ TANK ] );
|
||||
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_PRIMARY_UPGRADE",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_PRIMARY_UPGRADE ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_DUMBRIFE_DOUBLE",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_DUMBFIRE_DOUBLE ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_KICK_ASS_ROCKET",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_KICK_ASS_ROCKET ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_HELLFIRE",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_HELLFIRE ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_MACHINE_GUN",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_MACHINE_GUN ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_HEALTH",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_HEALTH ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_HEATSEEKER",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_HEATSEEKER ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_NUKE",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_NUKE ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_DEFLECTOR",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_DEFLECTOR ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_ENERGY_BEAM",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_ENERGY_BEAM ] );
|
||||
op->getInt( "ITEM_APPEAR_CHANCE_LASER",
|
||||
ITEM_APPEAR_CHANCES[ ITEM_LASER ] );
|
||||
|
||||
op->getInt( "GENERATE_FORMATION_DELAY", GENERATE_FORMATION_DELAY );
|
||||
op->getInt( "GENERATE_FORMATION_RAND_DELAY", GENERATE_FORMATION_RAND_DELAY );
|
||||
|
||||
op->getInt( "FORMATION_MAX_NR_ENEMYS_V",
|
||||
FORMATION_MAX_NR_ENEMYS[ FORMATION_V ] );
|
||||
op->getInt( "FORMATION_MAX_NR_ENEMYS_REVERSE_V",
|
||||
FORMATION_MAX_NR_ENEMYS[ FORMATION_REVERSE_V ] );
|
||||
op->getInt( "FORMATION_MAX_NR_ENEMYS_BLOCK",
|
||||
FORMATION_MAX_NR_ENEMYS[ FORMATION_BLOCK ] );
|
||||
op->getInt( "FORMATION_MAX_NR_ENEMYS_LINE",
|
||||
FORMATION_MAX_NR_ENEMYS[ FORMATION_LINE ] );
|
||||
for ( int i = 0; i < NR_FORMATION_TYPES; i++ ) {
|
||||
if ( FORMATION_MAX_NR_ENEMYS[ i ] > FORMATION_MAX_NR_ENEMYS_HARD_LIMIT[ i ] )
|
||||
FORMATION_MAX_NR_ENEMYS[ i ] = FORMATION_MAX_NR_ENEMYS_HARD_LIMIT[ i ];
|
||||
}
|
||||
|
||||
op->getInt( "FORMATION_SP_CHANCE_NONE",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_NONE ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_RAND_FAST",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_RAND_FAST ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_RAND_MEDIUM",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_RAND_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_RAND_SLOW",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_RAND_SLOW ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_VOLLEY_FAST",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_VOLLEY_FAST ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_VOLLEY_MEDIUM",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_VOLLEY_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_VOLLEY_SLOW",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_VOLLEY_SLOW ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_LEFT_RIGHT_FAST",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_LEFT_RIGHT_FAST ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_LEFT_RIGHT_MEDIUM",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_LEFT_RIGHT_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_RIGHT_LEFT_FAST",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_RIGHT_LEFT_FAST ] );
|
||||
op->getInt( "FORMATION_SP_CHANCE_RIGHT_LEFT_MEDIUM",
|
||||
FORMATION_SP_CHANCES[ FORMATION_SP_RIGHT_LEFT_MEDIUM ] );
|
||||
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_RAND_FAST",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RAND_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_RAND_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RAND_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_RAND_SLOW",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RAND_SLOW ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_VOLLEY_FAST",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_VOLLEY_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_VOLLEY_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_VOLLEY_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_VOLLEY_SLOW",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_VOLLEY_SLOW ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_LEFT_RIGHT_FAST",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_LEFT_RIGHT_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_LEFT_RIGHT_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_LEFT_RIGHT_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_RIGHT_LEFT_FAST",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RIGHT_LEFT_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_DELAY_RIGHT_LEFT_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RIGHT_LEFT_MEDIUM ] );
|
||||
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RAND_FAST",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RAND_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RAND_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RAND_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RAND_SLOW",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RAND_SLOW ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_VOLLEY_FAST",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_VOLLEY_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_VOLLEY_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_VOLLEY_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_VOLLEY_SLOW",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_VOLLEY_SLOW ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_LEFT_RIGHT_FAST",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_LEFT_RIGHT_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_LEFT_RIGHT_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_LEFT_RIGHT_MEDIUM ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RIGHT_LEFT_FAST",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RIGHT_LEFT_FAST ] );
|
||||
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RIGHT_LEFT_MEDIUM",
|
||||
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RIGHT_LEFT_MEDIUM ] );
|
||||
|
||||
delete op;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
|
||||
int getRandValue( const int *choicesWeights, int nrChoices, int sumWeights ) {
|
||||
int sum = 0;
|
||||
if ( sumWeights != 0 ) sum = sumWeights;
|
||||
else for ( int i = 0; i < nrChoices; i++ ) sum += choicesWeights[ i ];
|
||||
|
||||
if ( sum == 0 ) {
|
||||
cout << "Error in getRandValue: sum==0!" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int val = rand() % sum;
|
||||
|
||||
int idx = 0;
|
||||
int tmpSum = 0;
|
||||
while ( idx < nrChoices ) {
|
||||
tmpSum += choicesWeights[ idx ];
|
||||
if ( val < tmpSum ) {
|
||||
return idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
cout << "Error in getRandValue: val: " << val << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
void initAllSurfaces() {
|
||||
surfaceDB.loadSurface("./images/fighter.bmp" );
|
||||
surfaceDB.loadSurface("./images/fighterShadow.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bomber.bmp");
|
||||
surfaceDB.loadSurface("./images/bomberShadow.bmp", true);
|
||||
surfaceDB.loadSurface("./images/tank.bmp");
|
||||
surfaceDB.loadSurface("./images/boss1MainGun.bmp");
|
||||
surfaceDB.loadSurface("./images/boss1RocketLauncher.bmp");
|
||||
surfaceDB.loadSurface("./images/boss1ShotBatteryLeft.bmp");
|
||||
surfaceDB.loadSurface("./images/boss1ShotBatteryRight.bmp");
|
||||
surfaceDB.loadSurface("./images/wreckFighter.bmp");
|
||||
surfaceDB.loadSurface("./images/wreckBomber.bmp");
|
||||
surfaceDB.loadSurface("./images/wreckTank.bmp");
|
||||
surfaceDB.loadSurface("./images/wreckBoss1.bmp");
|
||||
surfaceDB.loadSurface("./images/wreckBossBackground.bmp");
|
||||
surfaceDB.loadSurface("./images/boss.bmp");
|
||||
surfaceDB.loadSurface("./images/normalShot.bmp");
|
||||
surfaceDB.loadSurface("./images/heavyShot.bmp");
|
||||
surfaceDB.loadSurface("./images/normalShotHF.bmp");
|
||||
surfaceDB.loadSurface("./images/dumbfire.bmp");
|
||||
surfaceDB.loadSurface("./images/kickAssRocket.bmp");
|
||||
surfaceDB.loadSurface("./images/kickAssRocketShadow.bmp", true);
|
||||
surfaceDB.loadSurface("./images/hellfire.bmp");
|
||||
surfaceDB.loadSurface("./images/hellfireShadow.bmp", true);
|
||||
surfaceDB.loadSurface("./images/machineGun.bmp");
|
||||
surfaceDB.loadSurface("./images/energyBeam.bmp", true);
|
||||
surfaceDB.loadSurface("./images/laser.bmp");
|
||||
surfaceDB.loadSurface("./images/enemyShotNormal.bmp");
|
||||
surfaceDB.loadSurface("./images/tankRocket.bmp");
|
||||
surfaceDB.loadSurface("./images/tankRocketShadow.bmp", true);
|
||||
surfaceDB.loadSurface("./images/heatseeker.bmp");
|
||||
surfaceDB.loadSurface("./images/shotNuke.bmp");
|
||||
surfaceDB.loadSurface("./images/shotNukeShadow.bmp", true);
|
||||
surfaceDB.loadSurface("./images/nukeEffect.bmp");
|
||||
surfaceDB.loadSurface("./images/sonic.bmp");
|
||||
surfaceDB.loadSurface("./images/itemPrimaryUpgrade.bmp");
|
||||
surfaceDB.loadSurface("./images/itemDumbfireDouble.bmp");
|
||||
surfaceDB.loadSurface("./images/itemKickAssRocket.bmp");
|
||||
surfaceDB.loadSurface("./images/itemHellfire.bmp");
|
||||
surfaceDB.loadSurface("./images/itemMachineGun.bmp");
|
||||
surfaceDB.loadSurface("./images/itemHealth.bmp");
|
||||
surfaceDB.loadSurface("./images/itemHeatseeker.bmp");
|
||||
surfaceDB.loadSurface("./images/itemNuke.bmp");
|
||||
surfaceDB.loadSurface("./images/itemDeflector.bmp");
|
||||
surfaceDB.loadSurface("./images/itemEnergyBeam.bmp");
|
||||
surfaceDB.loadSurface("./images/itemLaser.bmp");
|
||||
surfaceDB.loadSurface("./images/background.bmp");
|
||||
surfaceDB.loadSurface("./images/lightFighterShieldDamaged.bmp");
|
||||
surfaceDB.loadSurface("./images/heavyFighterShieldDamaged.bmp");
|
||||
surfaceDB.loadSurface("./images/heavyFighterDeflector.bmp", true);
|
||||
//surfaceDB.loadSurface("./images/font-20red");
|
||||
//surfaceDB.loadSurface("./images/font-20blue");
|
||||
surfaceDB.loadSurface("./images/explosion.bmp", true);
|
||||
surfaceDB.loadSurface("./images/explosionEnemy.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerExcellent.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerYouRule.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerHeiho.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerHealth.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerEnemysKilled.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerBonus100.bmp", true);
|
||||
surfaceDB.loadSurface("./images/bannerBonus200.bmp", true);
|
||||
}
|
||||
@@ -1,692 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#include <string>
|
||||
#include "SdlForwardCompat.h"
|
||||
|
||||
class Racers;
|
||||
class Enemys;
|
||||
class Shots;
|
||||
class Explosions;
|
||||
class Items;
|
||||
class Wrecks;
|
||||
class Banners;
|
||||
class SmokePuffs;
|
||||
class Options;
|
||||
|
||||
extern Racers *racers;
|
||||
extern Enemys *enemys;
|
||||
extern Shots *shots;
|
||||
extern Explosions *explosions;
|
||||
extern Items *items;
|
||||
extern Wrecks *wrecks;
|
||||
extern Banners *banners;
|
||||
extern SmokePuffs *smokePuffs;
|
||||
extern Options *levelConf;
|
||||
|
||||
extern int GAME_LENGTH;
|
||||
extern bool scrollingOn;
|
||||
extern bool nukeIsInPlace;
|
||||
extern bool playMusicOn;
|
||||
extern bool onePlayerGame;
|
||||
extern bool arcadeGame;
|
||||
extern int difficultyLevel;
|
||||
extern float actBackgroundPos;
|
||||
|
||||
void parseGlobalConfigValues( int difficultyLevel );
|
||||
int getRandValue( const int *choicesWeights, int nrChoices, int sumWeights=0 );
|
||||
void initAllSurfaces();
|
||||
|
||||
// screen options
|
||||
const int SCREEN_WIDTH = 640;
|
||||
const int SCREEN_HEIGHT = 480;
|
||||
const int BIT_DEPTH = 16;
|
||||
|
||||
const int MAX_PLAYER_CNT = 2;
|
||||
|
||||
// the speed of the background scrolling
|
||||
const float SCROLL_SPEED = 20;
|
||||
|
||||
// where is the absolute border of no return for the heatseeker?
|
||||
// they have a chance to return within SCREEN_BORDER pixels outside the screen...
|
||||
// outside this area shots are deleted
|
||||
const int SHOT_SCREEN_BORDER = 50;
|
||||
|
||||
|
||||
/********************************* ARCADE MODE ***********************************/
|
||||
|
||||
const int ARCADE_DIFFICULTY_LEVEL = 4;
|
||||
const int ARCADE_POINTS_PER_TEN_SECONDS = 30;
|
||||
|
||||
// BANNER_RANDOM: no real mode, just the value to choose one randomly
|
||||
enum BannerModes { BANNER_MODE_FLY_FROM_LEFT=0,
|
||||
BANNER_MODE_FROM_TOP,
|
||||
BANNER_MODE_ITEM_COLLECTED_SINGLE_PLAYER,
|
||||
BANNER_MODE_ITEM_COLLECTED_PLAYER_ONE,
|
||||
BANNER_MODE_ITEM_COLLECTED_PLAYER_TWO,
|
||||
BANNER_MODE_RANDOM=1000 };
|
||||
const int BANNER_MODE_LIFETIME[] = { 5000, 5000, 2000, 2000, 2000 };
|
||||
const int NR_BANNER_MODES = 2;
|
||||
|
||||
enum BannerTexts { BANNER_EXCELLENT=0, BANNER_YOU_RULE, BANNER_HEIHO,
|
||||
BANNER_HEALTH, BANNER_ENEMYS_KILLED,
|
||||
BANNER_ITEM_HEALTH_COLLECTED,
|
||||
BANNER_ITEM_PRIMARY_UPGRADE_COLLECTED,
|
||||
BANNER_ITEM_DUMBFIRE_DOUBLE_COLLECTED,
|
||||
BANNER_ITEM_KICK_ASS_ROCKET_COLLECTED,
|
||||
BANNER_ITEM_HELLFIRE_COLLECTED,
|
||||
BANNER_ITEM_MACHINE_GUN_COLLECTED,
|
||||
BANNER_ITEM_HEATSEEKER_COLLECTED,
|
||||
BANNER_ITEM_NUKE_COLLECTED,
|
||||
BANNER_ITEM_DEFLECTOR_COLLECTED,
|
||||
BANNER_ITEM_ENERGY_BEAM_COLLECTED,
|
||||
BANNER_ITEM_LASER_COLLECTED };
|
||||
const std::string FN_BANNER_TEXTS[] =
|
||||
{ "./images/bannerExcellent.bmp",
|
||||
"./images/bannerYouRule.bmp",
|
||||
"./images/bannerHeiho.bmp",
|
||||
"./images/bannerHealth.bmp",
|
||||
"./images/bannerEnemysKilled.bmp",
|
||||
"./images/bannerItemHealthCollected.bmp",
|
||||
"./images/bannerItemPrimaryUpgradeCollected.bmp",
|
||||
"./images/bannerItemDumbfireDoubleCollected.bmp",
|
||||
"./images/bannerItemKickAssRocketCollected.bmp",
|
||||
"./images/bannerItemHellfireCollected.bmp",
|
||||
"./images/bannerItemMachineGunCollected.bmp",
|
||||
"./images/bannerItemHeatseekerCollected.bmp",
|
||||
"./images/bannerItemNukeCollected.bmp",
|
||||
"./images/bannerItemDeflectorCollected.bmp",
|
||||
"./images/bannerItemEnergyBeamCollected.bmp",
|
||||
"./images/bannerItemLaserCollected.bmp" };
|
||||
const int NR_BANNER_TEXTS = 3;
|
||||
|
||||
enum BannerBoni { BANNER_BONUS_100=0,
|
||||
BANNER_BONUS_200,
|
||||
BANNER_BONUS_NONE=1000 };
|
||||
const std::string FN_BANNER_BONUS[] =
|
||||
{ "./images/bannerBonus100.bmp",
|
||||
"./images/bannerBonus200.bmp" };
|
||||
const int NR_BANNER_BONI = 2;
|
||||
|
||||
const float ARCADE_POINTS_FOR_FORMATION_DESTRUCTION = 100;
|
||||
const BannerBoni ARCADE_BONUS_FOR_FORMATION_DESTRUCTION = BANNER_BONUS_100;
|
||||
|
||||
const float ARCADE_POINTS_FOR_ENEMYS_KILLED = 200;
|
||||
const BannerBoni ARCADE_BONUS_FOR_ENEMYS_KILLED = BANNER_BONUS_200;
|
||||
|
||||
const int NR_ARCACE_POINTS_FOR_HEALTH_ITEM = 7;
|
||||
const float ARCADE_POINTS_FOR_HEALTH_ITEM[ NR_ARCACE_POINTS_FOR_HEALTH_ITEM ] =
|
||||
{ 2000, 5000, 10000, 15000, 25000, 35000, 50000 };
|
||||
|
||||
|
||||
/********************************** ITEMS ****************************************/
|
||||
|
||||
enum ItemTypes { ITEM_PRIMARY_UPGRADE=0,
|
||||
ITEM_DUMBFIRE_DOUBLE,
|
||||
ITEM_KICK_ASS_ROCKET,
|
||||
ITEM_HELLFIRE,
|
||||
ITEM_MACHINE_GUN,
|
||||
ITEM_HEALTH,
|
||||
ITEM_HEATSEEKER,
|
||||
ITEM_NUKE,
|
||||
ITEM_DEFLECTOR,
|
||||
ITEM_LASER,
|
||||
ITEM_ENERGY_BEAM };
|
||||
|
||||
const int NR_ITEM_TYPES = 11;
|
||||
|
||||
extern int ITEM_LIFETIME; // ms
|
||||
extern int ITEM_APPEAR_DELAY; // ms
|
||||
extern int ITEM_APPEAR_RAND_DELAY; // ms
|
||||
|
||||
// ITEM_HEALTH_REPAIR_AMOUNT points are restored, if collected
|
||||
extern int ITEM_HEALTH_REPAIR_AMOUNT;
|
||||
// if collected by heavy fighter the amount will be multiplied by this factor
|
||||
const float ITEM_HEALTH_REPAIR_FACTOR_HEAVY_FIGHTER = 2.0;
|
||||
|
||||
// if collected ITEM_HEATSEEKER_AMMO rockets can be fired
|
||||
extern int ITEM_HEATSEEKER_AMMO;
|
||||
extern int ITEM_NUKE_AMMO;
|
||||
extern int ITEM_DEFLECTOR_AMMO;
|
||||
|
||||
extern int ITEM_DEFLECTOR_DURATION;
|
||||
extern int ITEM_DEFLECTOR_ACTIVATION_DIST;
|
||||
extern int ITEM_DEFLECTOR_POWER;
|
||||
|
||||
// the items have different probabilities to appear.
|
||||
// bigger number -> greater chance
|
||||
extern int ITEM_APPEAR_CHANCES[];
|
||||
|
||||
enum ExplosionTypes { EXPLOSION_NORMAL_AIR=0, EXPLOSION_NORMAL_GROUND };
|
||||
const int NR_EXPLOSION_TYPES = 2;
|
||||
const int LIFETIME_EXPL_NORMAL = 1500;
|
||||
|
||||
const int NUKE_EFFECT_DURATION = 1000;
|
||||
const int NUKE_QUAKE_EFFECT = 40;
|
||||
|
||||
enum ShipTypes { LIGHT_FIGHTER=0, HEAVY_FIGHTER };
|
||||
const int NR_SHIPS = 2;
|
||||
|
||||
|
||||
/*********************************** SHOTS ********************************/
|
||||
|
||||
|
||||
enum ShotTypes { SHOT_NORMAL=0,
|
||||
SHOT_NORMAL_HEAVY,
|
||||
SHOT_DOUBLE,
|
||||
SHOT_DOUBLE_HEAVY,
|
||||
SHOT_TRIPLE,
|
||||
SHOT_HF_NORMAL,
|
||||
SHOT_HF_DOUBLE,
|
||||
SHOT_HF_TRIPLE,
|
||||
SHOT_HF_QUATTRO,
|
||||
SHOT_HF_QUINTO,
|
||||
SHOT_DUMBFIRE=100,
|
||||
SHOT_DUMBFIRE_DOUBLE,
|
||||
SHOT_KICK_ASS_ROCKET,
|
||||
SHOT_HELLFIRE,
|
||||
SHOT_MACHINE_GUN,
|
||||
SHOT_ENERGY_BEAM,
|
||||
SHOT_HF_DUMBFIRE,
|
||||
SHOT_HF_DUMBFIRE_DOUBLE,
|
||||
SHOT_HF_KICK_ASS_ROCKET,
|
||||
SHOT_HF_LASER,
|
||||
ENEMY_SHOT_NORMAL=1000,
|
||||
ENEMY_SHOT_TANK_ROCKET,
|
||||
SPECIAL_SHOT_HEATSEEKER=10000,
|
||||
SPECIAL_SHOT_NUKE };
|
||||
const int NR_SECONDARY_WEAPONS = 10;
|
||||
|
||||
enum SpecialTypes { SPECIAL_NONE=0, SPECIAL_NUKE, SPECIAL_HEATSEEKER, SPECIAL_DEFLECTOR };
|
||||
const int NR_SPECIALS = 4;
|
||||
|
||||
// after that many ms the shot is expired
|
||||
const int LIFETIME_SHOT_NORMAL = 5000;
|
||||
const int LIFETIME_SHOT_NORMAL_HEAVY = 5000;
|
||||
const int LIFETIME_SHOT_DOUBLE = 5000;
|
||||
const int LIFETIME_SHOT_DOUBLE_HEAVY = 5000;
|
||||
const int LIFETIME_SHOT_TRIPLE = 5000;
|
||||
const int LIFETIME_SHOT_HF_NORMAL = 6000;
|
||||
const int LIFETIME_SHOT_HF_DOUBLE = 6000;
|
||||
const int LIFETIME_SHOT_HF_TRIPLE = 6000;
|
||||
const int LIFETIME_SHOT_HF_QUATTRO = 6000;
|
||||
const int LIFETIME_SHOT_HF_QUINTO = 6000;
|
||||
|
||||
const int LIFETIME_SHOT_DUMBFIRE = 6000;
|
||||
const int LIFETIME_SHOT_DUMBFIRE_DOUBLE = 6000;
|
||||
const int LIFETIME_SHOT_KICK_ASS_ROCKET = 7000;
|
||||
const int LIFETIME_SHOT_HELLFIRE = 6000;
|
||||
const int LIFETIME_SHOT_MACHINE_GUN = 5000;
|
||||
const int LIFETIME_SHOT_ENERY_BEAM = 5000;
|
||||
|
||||
const int LIFETIME_SHOT_HF_DUMBFIRE = 6000;
|
||||
const int LIFETIME_SHOT_HF_DUMBFIRE_DOUBLE = 6000;
|
||||
const int LIFETIME_SHOT_HF_KICK_ASS_ROCKET = 7000;
|
||||
const int LIFETIME_SHOT_HF_LASER = 2000;
|
||||
|
||||
const int LIFETIME_SPECIAL_SHOT_HEATSEEKER = 10000;
|
||||
const int LIFETIME_SPECIAL_SHOT_NUKE = 10000;
|
||||
|
||||
const int VEL_SHOT_NORMAL = 150;
|
||||
const int VEL_SHOT_NORMAL_HEAVY = 150;
|
||||
const int VEL_SHOT_DOUBLE = 150;
|
||||
const int VEL_SHOT_DOUBLE_HEAVY = 150;
|
||||
const int VEL_SHOT_TRIPLE = 150;
|
||||
|
||||
const int VEL_SHOT_HF_NORMAL = 180;
|
||||
const int VEL_SHOT_HF_DOUBLE = 180;
|
||||
const int VEL_SHOT_HF_TRIPLE = 180;
|
||||
const int VEL_SHOT_HF_QUATTRO = 180;
|
||||
const int VEL_SHOT_HF_QUINTO = 180;
|
||||
|
||||
const int VEL_SHOT_DUMBFIRE = 100;
|
||||
const int VEL_SHOT_DUMBFIRE_DOUBLE = 100;
|
||||
const int VEL_SHOT_KICK_ASS_ROCKET = 80;
|
||||
const int VEL_SHOT_HELLFIRE = 110;
|
||||
const int VEL_SHOT_MACHINE_GUN = 130;
|
||||
const int VEL_SHOT_ENERGY_BEAM = 105;
|
||||
|
||||
const int VEL_SHOT_HF_DUMBFIRE = 160;
|
||||
const int VEL_SHOT_HF_DUMBFIRE_DOUBLE = 160;
|
||||
const int VEL_SHOT_HF_KICK_ASS_ROCKET = 80;
|
||||
const int VEL_SHOT_HF_LASER = 600;
|
||||
|
||||
const int VEL_SPECIAL_SHOT_HEATSEEKER = 130;
|
||||
const int VEL_SPECIAL_SHOT_NUKE = 180;
|
||||
|
||||
const float DAMAGE_SHOT_NORMAL = 5;
|
||||
const float DAMAGE_SHOT_NORMAL_HEAVY = 8;
|
||||
const float DAMAGE_SHOT_DOUBLE = 5;
|
||||
const float DAMAGE_SHOT_DOUBLE_HEAVY = 8;
|
||||
const float DAMAGE_SHOT_TRIPLE = 7;
|
||||
|
||||
const int DAMAGE_SHOT_HF_NORMAL = 20;
|
||||
const int DAMAGE_SHOT_HF_DOUBLE = 20;
|
||||
const int DAMAGE_SHOT_HF_TRIPLE = 20;
|
||||
const int DAMAGE_SHOT_HF_QUATTRO = 20;
|
||||
const int DAMAGE_SHOT_HF_QUINTO = 20;
|
||||
|
||||
const float DAMAGE_SHOT_DUMBFIRE = 40;
|
||||
const float DAMAGE_SHOT_DUMBFIRE_DOUBLE = 30;
|
||||
const float DAMAGE_SHOT_KICK_ASS_ROCKET = 151; // should kill a tank/turret with one shot
|
||||
const float DAMAGE_SHOT_HELLFIRE = 50;
|
||||
const float DAMAGE_SHOT_MACHINE_GUN = 8;
|
||||
const float DAMAGE_SHOT_ENERGY_BEAM = 80;
|
||||
|
||||
const int DAMAGE_SHOT_HF_DUMBFIRE = 40;
|
||||
const int DAMAGE_SHOT_HF_DUMBFIRE_DOUBLE = 40;
|
||||
const int DAMAGE_SHOT_HF_KICK_ASS_ROCKET = 151;
|
||||
const int DAMAGE_SHOT_HF_LASER = 70;
|
||||
|
||||
const float DAMAGE_SPECIAL_SHOT_HEATSEEKER = 20;
|
||||
const float DAMAGE_SPECIAL_SHOT_NUKE = 250;
|
||||
|
||||
const int SPREAD_ANGLE_SHOT_NORMAL = 6;
|
||||
|
||||
const int LIFETIME_ENEMY_SHOT_NORMAL = 6000;
|
||||
const int LIFETIME_ENEMY_SHOT_TANK_ROCKET = 10000;
|
||||
|
||||
const int VEL_ENEMY_SHOT_NORMAL = 130;
|
||||
const int VEL_ENEMY_SHOT_TANK_ROCKET = 70;
|
||||
|
||||
const float DAMAGE_ENEMY_SHOT_NORMAL = 8;
|
||||
const float DAMAGE_ENEMY_SHOT_TANK_ROCKET = 25;
|
||||
|
||||
/***************************** SMOKE PUFFS ***************************/
|
||||
|
||||
enum SmokePuffTypes { SMOKE_PUFF_SMALL=0, SMOKE_PUFF_MEDIUM };
|
||||
const int NR_SMOKE_PUFF_TYPES = 2;
|
||||
const std::string FN_SMOKE_PUFF[ NR_SMOKE_PUFF_TYPES ] =
|
||||
{ "./images/smokePuffSmall.bmp",
|
||||
"./images/smokePuffMedium.bmp" };
|
||||
const int LIFETIME_SMOKE_PUFF[ NR_SMOKE_PUFF_TYPES ] = { 500, 1000 };
|
||||
const int SMOKE_PUFF_DELAY_TO_NEXT_PUFF[ NR_SMOKE_PUFF_TYPES ] = { 100, 100 };
|
||||
const float SMOKE_PUFF_VELOCITY_FACTOR = 0.3;
|
||||
const bool SMOKE_PUFF_ALPHA_BLENDING = true;
|
||||
|
||||
/********************************** ENEMIES ********************************/
|
||||
|
||||
|
||||
enum EnemyTypes {
|
||||
FIGHTER=0,
|
||||
BOMBER,
|
||||
TANK,
|
||||
BOSS_1_MAIN_GUN,
|
||||
BOSS_1_ROCKET_LAUNCHER,
|
||||
BOSS_1_SHOT_BATTERY_RIGHT,
|
||||
BOSS_1_SHOT_BATTERY_LEFT,
|
||||
BOSS_2};
|
||||
const int NR_ENEMY_TYPES = 8;
|
||||
const int NR_ENEMY_TYPES_NORMAL = 3;
|
||||
const int NR_ENEMY_TYPES_BOSS_1 = 4;
|
||||
|
||||
const float BOSS_1_END_Y = 110;
|
||||
|
||||
enum WreckTypes {
|
||||
WRECK_FIGHTER=0,
|
||||
WRECK_BOMBER,
|
||||
WRECK_TANK,
|
||||
WRECK_BOSS_1_MAIN_GUN,
|
||||
WRECK_BOSS_1_ROCKET_LAUNCHER,
|
||||
WRECK_BOSS_1_BATTERY_RIGHT,
|
||||
WRECK_BOSS_1_BATTERY_LEFT,
|
||||
WRECK_BOSS_1_BACKGROUND,
|
||||
WRECK_BOSS_1_DESTROYED,
|
||||
WRECK_BOSS_2_DESTROYED };
|
||||
const int NR_WRECK_TYPES = 10;
|
||||
const WreckTypes WRECK_FOR_ENEMYTYPE[] = {
|
||||
WRECK_FIGHTER,
|
||||
WRECK_BOMBER,
|
||||
WRECK_TANK,
|
||||
WRECK_BOSS_1_MAIN_GUN,
|
||||
WRECK_BOSS_1_ROCKET_LAUNCHER,
|
||||
WRECK_BOSS_1_BATTERY_RIGHT,
|
||||
WRECK_BOSS_1_BATTERY_LEFT,
|
||||
WRECK_BOSS_2_DESTROYED };
|
||||
|
||||
extern int GENERATE_ENEMY_DELAY;
|
||||
extern int GENERATE_ENEMY_RAND_DELAY;
|
||||
|
||||
extern int ENEMY_HITPOINTS[];
|
||||
//const float ENEMY_HITPOINTS[] = { 80, 120, 150, 10, 10, 10, 10 };
|
||||
const bool ENEMY_FLYING[] = {true, true, false, false, false, false, false, true};
|
||||
// determines the difference between shadow and enemy plane
|
||||
const int ENEMY_FLYING_HEIGHT[] = {10, 15, 0, 0, 0, 0, 0, 10};
|
||||
const int ENEMY_POINTS_FOR_DEST[] = {10,20,20,0,0,0,0,0};
|
||||
|
||||
extern int ENEMY_COLLISION_DAMAGE[];
|
||||
|
||||
// the enemys have different probabilities to appear in the different levels.
|
||||
// bigger number -> greater chance
|
||||
extern int ENEMY_APPEAR_CHANCES[];
|
||||
|
||||
// on average one of that many enemys carries an item
|
||||
extern int ENEMY_DIES_ITEM_APPEAR_CHANCE[];
|
||||
|
||||
// minimal waittime (ms) between two shots
|
||||
extern int ENEMY_COOLDOWN_PRIMARY[];
|
||||
extern int ENEMY_COOLDOWN_SECONDARY[];
|
||||
// random additional waittime between two shots
|
||||
extern int ENEMY_RAND_WAIT_PRIMARY[];
|
||||
extern int ENEMY_RAND_WAIT_SECONDARY[];
|
||||
|
||||
|
||||
|
||||
/******************************** FORMATION ***************************************/
|
||||
|
||||
|
||||
enum FormationTypes { FORMATION_V=0, FORMATION_REVERSE_V,
|
||||
FORMATION_BLOCK,
|
||||
FORMATION_LINE };
|
||||
|
||||
const int NR_FORMATION_TYPES = 4;
|
||||
|
||||
const int FORMATION_MAX_NR_ENEMYS_HARD_LIMIT[] = {7,7,7,6};
|
||||
extern int FORMATION_MAX_NR_ENEMYS[];
|
||||
|
||||
enum FormationEnemySets { FORMATION_ENEMY_SET_DEFAULT=0,
|
||||
FORMATION_ENEMY_SET_FIGHTER,
|
||||
FORMATION_ENEMY_SET_BOMBER,
|
||||
FORMATION_ENEMY_SET_FIGHTER_BOMBER };
|
||||
const int NR_FORMATION_ENEMY_SETS = 4;
|
||||
|
||||
const int FORMATION_CHANGE_ON_KILL = 1;
|
||||
const int FORMATION_CHANGE_SPONTANEOUS = 2;
|
||||
const int FORMATION_CHANGE_SELDOM = 4;
|
||||
const int FORMATION_CHANGE_OFTEN = 8;
|
||||
|
||||
const int FORMATION_CHANGE_OFTEN_DELAY = 3000;
|
||||
const int FORMATION_CHANGE_OFTEN_RAND_DELAY = 8000;
|
||||
const int FORMATION_CHANGE_SELDOM_DELAY = 4000;
|
||||
const int FORMATION_CHANGE_SELDOM_RAND_DELAY = 15000;
|
||||
|
||||
|
||||
enum FormationShotPatterns { FORMATION_SP_NONE=0,
|
||||
FORMATION_SP_RAND_FAST,
|
||||
FORMATION_SP_RAND_MEDIUM,
|
||||
FORMATION_SP_RAND_SLOW,
|
||||
|
||||
FORMATION_SP_VOLLEY_FAST,
|
||||
FORMATION_SP_VOLLEY_MEDIUM,
|
||||
FORMATION_SP_VOLLEY_SLOW,
|
||||
|
||||
FORMATION_SP_LEFT_RIGHT_FAST,
|
||||
FORMATION_SP_LEFT_RIGHT_MEDIUM,
|
||||
FORMATION_SP_RIGHT_LEFT_FAST,
|
||||
FORMATION_SP_RIGHT_LEFT_MEDIUM };
|
||||
|
||||
const int NR_FORMATION_SP = 11;
|
||||
|
||||
extern int FORMATION_SP_CHANCES[];
|
||||
extern int FORMATION_SP_PRIMARY_DELAY[];
|
||||
extern int FORMATION_SP_PRIMARY_RAND_DELAY[];
|
||||
|
||||
extern int GENERATE_FORMATION_DELAY;
|
||||
extern int GENERATE_FORMATION_RAND_DELAY;
|
||||
|
||||
|
||||
|
||||
/************************* RACER *********************************/
|
||||
|
||||
|
||||
// max speed of the racer in pixels per second
|
||||
const float LIGHT_FIGHTER_VEL_MAX = 90;
|
||||
const float HEAVY_FIGHTER_VEL_MAX = 60;
|
||||
|
||||
// shield recharge points per 100 seconds
|
||||
extern int LIGHT_FIGHTER_SHIELD_RECHARGE;
|
||||
extern int HEAVY_FIGHTER_SHIELD_RECHARGE;
|
||||
|
||||
// Cooldown rates (in ms) of the weapons
|
||||
const int RACER_COOLDOWN_SHOT_NORMAL = 100;
|
||||
const int RACER_COOLDOWN_SHOT_NORMAL_HEAVY = 100;
|
||||
const int RACER_COOLDOWN_SHOT_DOUBLE = 130;
|
||||
const int RACER_COOLDOWN_SHOT_DOUBLE_HEAVY = 130;
|
||||
const int RACER_COOLDOWN_SHOT_TRIPLE = 130;
|
||||
|
||||
const int RACER_COOLDOWN_SHOT_HF_NORMAL = 300;
|
||||
const int RACER_COOLDOWN_SHOT_HF_DOUBLE = 300;
|
||||
const int RACER_COOLDOWN_SHOT_HF_TRIPLE = 300;
|
||||
const int RACER_COOLDOWN_SHOT_HF_QUATTRO = 350;
|
||||
const int RACER_COOLDOWN_SHOT_HF_QUINTO = 400;
|
||||
|
||||
const int RACER_COOLDOWN_DUMBFIRE = 600;
|
||||
const int RACER_COOLDOWN_DUMBFIRE_DOUBLE = 300;
|
||||
const int RACER_COOLDOWN_KICK_ASS_ROCKET = 1500;
|
||||
const int RACER_COOLDOWN_HELLFIRE = 600;
|
||||
const int RACER_COOLDOWN_MACHINE_GUN = 150;
|
||||
const int RACER_COOLDOWN_ENERGY_BEAM = 500;
|
||||
|
||||
const int RACER_COOLDOWN_HF_DUMBFIRE = 600;
|
||||
const int RACER_COOLDOWN_HF_DUMBFIRE_DOUBLE = 300;
|
||||
const int RACER_COOLDOWN_HF_KICK_ASS_ROCKET = 1300;
|
||||
const int RACER_COOLDOWN_HF_LASER = 700;
|
||||
|
||||
const int RACER_COOLDOWN_SPECIAL_HEATSEEKER = 400;
|
||||
const int RACER_COOLDOWN_SPECIAL_NUKE = 3000;
|
||||
|
||||
extern int RACER_DEFLECTOR_ACTIVATION_DIST;
|
||||
extern int RACER_DEFLECTOR_POWER;
|
||||
extern int RACER_SONIC_ACTIVATION_DIST;
|
||||
extern int RACER_SONIC_POWER;
|
||||
|
||||
// how long (in ms) does the shield glow, when the racer is hit
|
||||
const int RACER_SHIELD_DAMAGE_LIFETIME = 200;
|
||||
|
||||
// shields
|
||||
extern int LIGHT_FIGHTER_MAX_SHIELD;
|
||||
extern int HEAVY_FIGHTER_MAX_SHIELD;
|
||||
// hitpoints
|
||||
extern int LIGHT_FIGHTER_MAX_DAMAGE;
|
||||
extern int HEAVY_FIGHTER_MAX_DAMAGE;
|
||||
|
||||
const std::string FN_SOUND_SHOT_PRIMARY = "./sound/shotPrimary.wav";
|
||||
const std::string FN_SOUND_SHOT_SECONDARY = "./sound/shotSecondary.wav";
|
||||
const std::string FN_SOUND_EXPLOSION_NORMAL = "./sound/explosion.wav";
|
||||
const std::string FN_SOUND_EXPLOSION_BOSS = "./sound/explosionBoss.wav";
|
||||
const std::string FN_SOUND_BOSS_ALARM = "./sound/alarm.wav";
|
||||
const std::string FN_SOUND_ARCADE_CONFIRM = "./sound/alarm.wav";
|
||||
const std::string FN_SOUND_ARCADE_CHOOSE = "./sound/choose.wav";
|
||||
const std::string FN_SOUND_INTRO_CONFIRM = "./sound/confirm.wav";
|
||||
const std::string FN_SOUND_INTRO_CHOOSE = "./sound/choose.wav";
|
||||
|
||||
const std::string FN_ENEMY_FIGHTER = "./images/fighter.bmp";
|
||||
const std::string FN_ENEMY_FIGHTER_SHADOW = "./images/fighterShadow.bmp";
|
||||
const std::string FN_ENEMY_BOMBER = "./images/bomber.bmp";
|
||||
const std::string FN_ENEMY_BOMBER_SHADOW = "./images/bomberShadow.bmp";
|
||||
const std::string FN_ENEMY_TANK = "./images/tank.bmp";
|
||||
const std::string FN_ENEMY_BOSS_1_MAIN_GUN = "./images/boss1MainGun.bmp";
|
||||
const std::string FN_ENEMY_BOSS_1_ROCKET_LAUNCHER = "./images/boss1RocketLauncher.bmp";
|
||||
const std::string FN_ENEMY_BOSS_1_SHOT_BATTERY_LEFT = "./images/boss1ShotBatteryLeft.bmp";
|
||||
const std::string FN_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT = "./images/boss1ShotBatteryRight.bmp";
|
||||
const std::string FN_ENEMY_BOSS_2 = "./images/boss2.bmp";
|
||||
const std::string FN_ENEMY_BOSS_2_SHADOW = "./images/boss2Shadow.bmp";
|
||||
|
||||
const std::string FN_WRECK_FIGHTER = "./images/wreckFighter.bmp";
|
||||
const std::string FN_WRECK_BOMBER = "./images/wreckBomber.bmp";
|
||||
const std::string FN_WRECK_TANK = "./images/wreckTank.bmp";
|
||||
const std::string FN_WRECK_BOSS_1 = "./images/wreckBoss1.bmp";
|
||||
const std::string FN_WRECK_BOSS_1_BACKGROUND = "./images/wreckBossBackground.bmp";
|
||||
const std::string FN_WRECK_BOSS_1_DESTROYED = "./images/boss.bmp";
|
||||
const std::string FN_WRECK_BOSS_2_DESTROYED = "./images/wreckBoss2.bmp";
|
||||
|
||||
const std::string FN_SHOT_NORMAL = "./images/normalShot.bmp";
|
||||
const std::string FN_SHOT_NORMAL_HEAVY = "./images/heavyShot.bmp";
|
||||
const std::string FN_SHOT_DOUBLE = "./images/normalShot.bmp";
|
||||
const std::string FN_SHOT_DOUBLE_HEAVY = "./images/heavyShot.bmp";
|
||||
const std::string FN_SHOT_TRIPLE = "./images/heavyShot.bmp";
|
||||
|
||||
const std::string FN_SHOT_HF_NORMAL = "./images/normalShotHF.bmp";
|
||||
const std::string FN_SHOT_HF_DOUBLE = "./images/normalShotHF.bmp";
|
||||
const std::string FN_SHOT_HF_TRIPLE = "./images/normalShotHF.bmp";
|
||||
const std::string FN_SHOT_HF_QUATTRO = "./images/normalShotHF.bmp";
|
||||
const std::string FN_SHOT_HF_QUINTO = "./images/normalShotHF.bmp";
|
||||
|
||||
const std::string FN_SHOT_DUMBFIRE = "./images/dumbfire.bmp";
|
||||
const std::string FN_SHOT_DUMBFIRE_DOUBLE = "./images/dumbfire.bmp";
|
||||
const std::string FN_SHOT_KICK_ASS_ROCKET = "./images/kickAssRocket.bmp";
|
||||
const std::string FN_SHOT_KICK_ASS_ROCKET_SHADOW = "./images/kickAssRocketShadow.bmp";
|
||||
const std::string FN_SHOT_HELLFIRE = "./images/hellfire.bmp";
|
||||
const std::string FN_SHOT_HELLFIRE_SHADOW = "./images/hellfireShadow.bmp";
|
||||
const std::string FN_SHOT_MACHINE_GUN = "./images/machineGun.bmp";
|
||||
const std::string FN_SHOT_ENERGY_BEAM = "./images/energyBeam.bmp";
|
||||
|
||||
const std::string FN_SHOT_HF_DUMBFIRE = "./images/dumbfire.bmp";
|
||||
const std::string FN_SHOT_HF_DUMBFIRE_DOUBLE = "./images/dumbfire.bmp";
|
||||
const std::string FN_SHOT_HF_KICK_ASS_ROCKET = "./images/kickAssRocket.bmp";
|
||||
const std::string FN_SHOT_HF_KICK_ASS_ROCKET_SHADOW = "./images/kickAssRocketShadow.bmp";
|
||||
const std::string FN_SHOT_HF_LASER = "./images/laser.bmp";
|
||||
|
||||
const std::string FN_ENEMY_SHOT_NORMAL = "./images/enemyShotNormal.bmp";
|
||||
const std::string FN_ENEMY_SHOT_TANK_ROCKET = "./images/tankRocket.bmp";
|
||||
const std::string FN_ENEMY_SHOT_TANK_ROCKET_SHADOW = "./images/tankRocketShadow.bmp";
|
||||
|
||||
const std::string FN_SPECIAL_SHOT_HEATSEEKER = "./images/heatseeker.bmp";
|
||||
const std::string FN_SPECIAL_SHOT_NUKE = "./images/shotNuke.bmp";
|
||||
const std::string FN_SPECIAL_SHOT_NUKE_SHADOW = "./images/shotNukeShadow.bmp";
|
||||
const std::string FN_NUKE_EFFECT = "./images/nukeEffect.bmp";
|
||||
const std::string FN_SONIC_EFFECT = "./images/sonic.bmp";
|
||||
|
||||
const std::string FN_ITEM_PRIMARY_UPGRADE = "./images/itemPrimaryUpgrade.bmp";
|
||||
const std::string FN_ITEM_DUMBFIRE_DOUBLE = "./images/itemDumbfireDouble.bmp";
|
||||
const std::string FN_ITEM_KICK_ASS_ROCKET = "./images/itemKickAssRocket.bmp";
|
||||
const std::string FN_ITEM_HELLFIRE = "./images/itemHellfire.bmp";
|
||||
const std::string FN_ITEM_MACHINE_GUN = "./images/itemMachineGun.bmp";
|
||||
const std::string FN_ITEM_HEALTH = "./images/itemHealth.bmp";
|
||||
const std::string FN_ITEM_HEATSEEKER = "./images/itemHeatseeker.bmp";
|
||||
const std::string FN_ITEM_NUKE = "./images/itemNuke.bmp";
|
||||
const std::string FN_ITEM_DEFLECTOR = "./images/itemDeflector.bmp";
|
||||
const std::string FN_ITEM_ENERGY_BEAM = "./images/itemEnergyBeam.bmp";
|
||||
const std::string FN_ITEM_LASER = "./images/itemLaser.bmp";
|
||||
|
||||
const std::string FN_ALIENBLASTER_INTRO = "./images/alienblasterintro.bmp";
|
||||
const std::string FN_ALIENBLASTER_ICON = "./images/alienblastericon.bmp";
|
||||
const std::string FN_BACKGROUND = "./images/background.bmp";
|
||||
const std::string FN_PAUSED = "./images/paused.bmp";
|
||||
const std::string FN_YOU_LOSE = "./images/youLose.bmp";
|
||||
const std::string FN_YOU_WIN = "./images/youWin.bmp";
|
||||
const std::string FN_GAME_OVER = "./images/gameOver.bmp";
|
||||
const std::string FN_ARCADE_LOGO = "./images/arcadeLogo.bmp";
|
||||
|
||||
// numbers of images (animation-frames) per racer
|
||||
const int RACER_IMAGE_CNT = 9;
|
||||
|
||||
const std::string FN_LIGHT_FIGHTER_1 = "./images/lightFighter1.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_2 = "./images/lightFighter2.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_SHADOW = "./images/lightFighterShadow.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_SHIELD_DAMAGED = "./images/lightFighterShieldDamaged.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_1_ICON = "./images/lightFighter1Icon.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_2_ICON = "./images/lightFighter2Icon.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_1_SMALL = "./images/lightFighter1Small.bmp";
|
||||
const std::string FN_LIGHT_FIGHTER_2_SMALL = "./images/lightFighter2Small.bmp";
|
||||
|
||||
const std::string FN_HEAVY_FIGHTER_1 = "./images/heavyFighter1.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_2 = "./images/heavyFighter2.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_SHADOW = "./images/heavyFighterShadow.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_SHIELD_DAMAGED = "./images/heavyFighterShieldDamaged.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_DEFLECTOR = "./images/heavyFighterDeflector.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_1_ICON = "./images/heavyFighter1Icon.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_2_ICON = "./images/heavyFighter2Icon.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_1_SMALL = "./images/heavyFighter1Small.bmp";
|
||||
const std::string FN_HEAVY_FIGHTER_2_SMALL = "./images/heavyFighter2Small.bmp";
|
||||
|
||||
const std::string FN_ICONS_SPECIALS = "./images/iconsSpecials.bmp";
|
||||
const std::string FN_ICONS_SECONDARY_WEAPONS = "./images/iconsSecondaryWeapons.bmp";
|
||||
|
||||
const std::string FN_HITPOINTS_STAT = "./images/hpStat.bmp";
|
||||
|
||||
const std::string FN_INTRO_SHOW_CHOICE = "./images/menuIcon.bmp";
|
||||
|
||||
const std::string FN_FONT_PATH = "./images/";
|
||||
const std::string FN_FONT_SUFFIX_SURFACE = ".bmp";
|
||||
const std::string FN_FONT_INTRO = "./images/font-20white";
|
||||
const std::string FN_FONT_INTRO_HIGHLIGHTED = "./images/font-20lightblue";
|
||||
const std::string FN_FONT_NUMBERS_TIME = "./images/font-20red";
|
||||
const std::string FN_FONT_NUMBERS_LEFT = "./images/font-20red";
|
||||
const std::string FN_FONT_NUMBERS_RIGHT = "./images/font-20blue";
|
||||
const std::string FN_FONT_SETTINGS = "./images/font-20white";
|
||||
const std::string FN_FONT_SETTINGS_HIGHLIGHTED = "./images/font-20lightblue";
|
||||
const std::string FN_FONT_SETTINGS_SMALL = "./images/font-14white";
|
||||
const std::string FN_FONT_SETTINGS_SMALL_BLUE = "./images/font-14lightblue";
|
||||
const std::string FN_FONT_SETTINGS_SMALL_HIGHLIGHTED = "./images/font-14red";
|
||||
|
||||
const std::string FN_SETTINGS_BLUE = "./images/bluePlain.bmp";
|
||||
const std::string FN_SETTINGS_WHITE = "./images/whitePlain.bmp";
|
||||
|
||||
const std::string FN_EXPLOSION_NORMAL = "./images/explosion.bmp";
|
||||
const std::string FN_EXPLOSION_ENEMY = "./images/explosionEnemy.bmp";
|
||||
|
||||
const std::string FN_LOADING = "./images/loading.bmp";
|
||||
|
||||
const std::string FN_SETTINGS = "./cfg/alienBlaster.cfg";
|
||||
|
||||
const std::string FN_DIFFICULTY_CONFIG = "./cfg/alienBlasterDifficulty";
|
||||
const std::string FN_DIFFICULTY_CONFIG_SUFFIX = ".cfg";
|
||||
|
||||
const std::string FN_HIGHSCORE = "./cfg/highscore.dat";
|
||||
|
||||
enum MusicTracks { MUSIC_INTRO=0, MUSIC_PLAYON, MUSIC_BOSS1, MUSIC_NONE };
|
||||
const int NR_MUSIC_TRACKS = 3;
|
||||
const std::string FN_MUSIC[] = { "./sound/intro.wav",
|
||||
"./sound/playon.wav",
|
||||
"./sound/intro.wav" };
|
||||
|
||||
const std::string FN_LEVEL_ONE_PLAYER = "./cfg/level1.cfg";
|
||||
const std::string FN_LEVEL_TWO_PLAYER = "./cfg/level2.cfg";
|
||||
const std::string FN_LEVEL_ARCADEMODE = "./cfg/levelArcade.cfg";
|
||||
|
||||
const std::string FN_SCREENSHOT0 = "./intro/HellShot0.bmp";
|
||||
const std::string FN_SCREENSHOT1 = "./intro/HellShot1.bmp";
|
||||
const std::string FN_SCREENSHOT2 = "./intro/HellShot2.bmp";
|
||||
const std::string FN_SCREENSHOT3 = "./intro/HellShot3.bmp";
|
||||
const std::string FN_SCREENSHOT4 = "./intro/HellShot5.bmp";
|
||||
const std::string FN_SCREENSHOT5 = "./intro/HellShot4.bmp";
|
||||
const std::string FN_SCREENSHOT6 = "./intro/HellShot6.bmp";
|
||||
const std::string FN_SCREENSHOT7 = "./intro/HellShot7.bmp";
|
||||
const std::string FN_SCREENSHOT8 = "./intro/HellShot8.bmp";
|
||||
const std::string FN_SCREENSHOT9 = "./intro/HellShot9.bmp";
|
||||
|
||||
const std::string LVL_BACKG_TILE_CNT = "BACKG_TILES";
|
||||
const std::string LVL_BACKG_TILE = "BACKG_TILE";
|
||||
const std::string LVL_BACKG_LENGTH = "BACKG_LENGTH";
|
||||
|
||||
const std::string LVL_ENEMY_FIGHTER = "ENEMY_FIGHTER";
|
||||
const std::string LVL_ENEMY_BOMBER = "ENEMY_BOMBER";
|
||||
const std::string LVL_ENEMY_TANK = "ENEMY_TANK";
|
||||
const std::string LVL_ENEMY_BOSS_BACKGROUND = "ENEMY_BOSS_BACKGROUND";
|
||||
const std::string LVL_ENEMY_BOSS_DESTROYED = "ENEMY_BOSS_DESTROYED";
|
||||
|
||||
const std::string LVL_WRECK_FIGHTER = "WRECK_FIGHTER";
|
||||
const std::string LVL_WRECK_BOMBER = "WRECK_BOMBER";
|
||||
const std::string LVL_WRECK_TANK = "WRECK_TANK";
|
||||
const std::string LVL_WRECK_BOSS_BACKGROUND = "WRECK_BOSS_BACKGROUND";
|
||||
const std::string LVL_WRECK_BOSS_DESTROYED = "WRECK_BOSS_DESTROYED";
|
||||
|
||||
const std::string LVL_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT = "ENEMY_BOSS_1_SHOT_BATTERY_RIGHT";
|
||||
const std::string LVL_ENEMY_BOSS_1_SHOT_BATTERY_LEFT = "ENEMY_BOSS_1_SHOT_BATTERY_LEFT";
|
||||
const std::string LVL_ENEMY_BOSS_1_ROCKET_LAUNCHER = "ENEMY_BOSS_1_ROCKET_LAUNCHER";
|
||||
const std::string LVL_ENEMY_BOSS_1_MAIN_GUN = "ENEMY_BOSS_1_MAIN_GUN";
|
||||
|
||||
const std::string LVL_ENEMY_FIGHTER_SHADOW = "ENEMY_FIGHTER_SHADOW";
|
||||
const std::string LVL_ENEMY_BOMBER_SHADOW = "ENEMY_BOMBER_SHADOW";
|
||||
|
||||
#endif
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1,389 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "infoscreen.h"
|
||||
#include "global.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "mixer.h"
|
||||
#include "video.h"
|
||||
#include "font.h"
|
||||
#include "items.h"
|
||||
#include "item.h"
|
||||
|
||||
Items *infoscreenItems;
|
||||
|
||||
Infoscreen::Infoscreen( SdlCompat_AcceleratedSurface *scr ) {
|
||||
screen = scr;
|
||||
font = new Font( FN_FONT_INTRO );
|
||||
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
|
||||
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
|
||||
lightFighterIcon1 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_1_ICON );
|
||||
lightFighterIcon2 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_2_ICON );
|
||||
heavyFighterIcon1 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_1_ICON );
|
||||
heavyFighterIcon2 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_2_ICON );
|
||||
choose = Mixer::mixer().loadSample( FN_SOUND_INTRO_CHOOSE, 100 );
|
||||
confirm = Mixer::mixer().loadSample( FN_SOUND_INTRO_CONFIRM, 100 );
|
||||
if (infoscreenItems) delete infoscreenItems;
|
||||
infoscreenItems = new Items();
|
||||
activeChoice = 0;
|
||||
}
|
||||
|
||||
Infoscreen::~Infoscreen() {
|
||||
if (infoscreenItems) delete infoscreenItems;
|
||||
}
|
||||
|
||||
void Infoscreen::run() {
|
||||
draw();
|
||||
quitInfoscreen = false;
|
||||
activeChoice = 0;
|
||||
while ( !quitInfoscreen ) {
|
||||
handleEvents();
|
||||
draw();
|
||||
SDL_Delay( 50 );
|
||||
}
|
||||
}
|
||||
|
||||
void Infoscreen::putBitmapAtPosition( int x, int y, SdlCompat_AcceleratedSurface* bitmap ) {
|
||||
SDL_Rect d;
|
||||
d.x = x - bitmap->w / 2;
|
||||
d.y = y - bitmap->h / 2;
|
||||
d.w = bitmap->w;
|
||||
d.h = bitmap->h;
|
||||
SDL_BlitSurface( bitmap, 0, screen, &d );
|
||||
}
|
||||
|
||||
void Infoscreen::draw() {
|
||||
// clear the screen
|
||||
videoserver->clearScreen();
|
||||
// draw vertical green line
|
||||
SDL_Rect r;
|
||||
r.x = 250;
|
||||
r.y = 0;
|
||||
r.w = 2;
|
||||
r.h = screen->h;
|
||||
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 255, 0) );
|
||||
|
||||
for ( int i = 0; i < NR_INFOSCREEN_CHOICES; i++ ) {
|
||||
int ypos = 30 + i * 25;
|
||||
if ( i == INFO_CREDITS ) ypos += 15;
|
||||
if ( i == INFO_BACK_TO_MAIN_MENU ) ypos += 30;
|
||||
if( activeChoice == i ) {
|
||||
putBitmapAtPosition( 15, ypos + 8, activeChoiceSprite );
|
||||
fontHighlighted->drawStr( screen, 30, ypos, SET_INFOSCREEN_CHOICES[ i ] );
|
||||
} else {
|
||||
font->drawStr( screen, 30, ypos, SET_INFOSCREEN_CHOICES[ i ] );
|
||||
}
|
||||
}
|
||||
switch ( activeChoice ) {
|
||||
case INFO_LIGHT_FIGHTER:
|
||||
{
|
||||
putBitmapAtPosition( 386, 50, lightFighterIcon1 );
|
||||
putBitmapAtPosition( 502, 50, lightFighterIcon2 );
|
||||
font->drawStr( screen, 270, 100, "The Light Fighter is more");
|
||||
font->drawStr( screen, 270, 130, "vulnerable but smaller and");
|
||||
font->drawStr( screen, 270, 160, "faster than the Heavy Fighter.");
|
||||
font->drawStr( screen, 270, 200, "Possible Updates:");
|
||||
newItem = new Item( Vector2D ( 270, 240 ) , Vector2D(0,0), ITEM_PRIMARY_UPGRADE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 230, "Primary Weapon Upgrade");
|
||||
newItem = new Item( Vector2D ( 270, 270 ) , Vector2D(0,0), ITEM_MACHINE_GUN );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 260, "Machinegun");
|
||||
newItem = new Item( Vector2D ( 270, 300 ) , Vector2D(0,0), ITEM_DUMBFIRE_DOUBLE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 290, "Double Dumbfire");
|
||||
newItem = new Item( Vector2D ( 270, 330 ) , Vector2D(0,0), ITEM_KICK_ASS_ROCKET );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 320, "Kick-Ass Rocket");
|
||||
newItem = new Item( Vector2D ( 270, 360 ) , Vector2D(0,0), ITEM_HELLFIRE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 350, "Hellfire Rocket");
|
||||
newItem = new Item( Vector2D ( 270, 390 ) , Vector2D(0,0), ITEM_HEATSEEKER );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 380, "Heatseeker");
|
||||
newItem = new Item( Vector2D ( 270, 420 ) , Vector2D(0,0), ITEM_NUKE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 410, "The Great Nuke");
|
||||
newItem = new Item( Vector2D ( 270, 450 ) , Vector2D(0,0), ITEM_ENERGY_BEAM );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 440, "Energy Beam");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_HEAVY_FIGHTER:
|
||||
{
|
||||
putBitmapAtPosition( 386, 50, heavyFighterIcon1 );
|
||||
putBitmapAtPosition( 502, 50, heavyFighterIcon2 );
|
||||
font->drawStr( screen, 270, 100, "The Heavy Fighter has superior");
|
||||
font->drawStr( screen, 270, 130, "firepower and an energyweapon");
|
||||
font->drawStr( screen, 270, 160, "deflector. He lacks agility.");
|
||||
font->drawStr( screen, 270, 200, "Possible Updates:");
|
||||
newItem = new Item( Vector2D ( 270, 240 ) , Vector2D(0,0), ITEM_PRIMARY_UPGRADE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 230, "Primary Weapon Upgrade");
|
||||
newItem = new Item( Vector2D ( 270, 270 ) , Vector2D(0,0), ITEM_KICK_ASS_ROCKET );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 260, "Kick-Ass Rocket");
|
||||
newItem = new Item( Vector2D ( 270, 300 ) , Vector2D(0,0), ITEM_HEATSEEKER );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 290, "Heatseeker");
|
||||
newItem = new Item( Vector2D ( 270, 330 ) , Vector2D(0,0), ITEM_NUKE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 320, "The Great Nuke");
|
||||
newItem = new Item( Vector2D ( 270, 360 ) , Vector2D(0,0), ITEM_DEFLECTOR );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 350, "Energyweapon Deflector");
|
||||
newItem = new Item( Vector2D ( 270, 390 ) , Vector2D(0,0), ITEM_LASER );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 380, "Heavy Laser");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_PRIMARY_WEAPON:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_PRIMARY_UPGRADE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Primary Weapon Upgrade");
|
||||
font->drawStr( screen, 270, 100, "The Primary Weapon Upgrade can");
|
||||
font->drawStr( screen, 270, 130, "be used multiple times and each");
|
||||
font->drawStr( screen, 270, 160, "time the primary weapon will");
|
||||
font->drawStr( screen, 270, 190, "gain one extra shot or improve");
|
||||
font->drawStr( screen, 270, 220, "its damage. The maximum for the");
|
||||
font->drawStr( screen, 270, 250, "light fighter are three heavy");
|
||||
font->drawStr( screen, 270, 280, "shots and for the heavy figher");
|
||||
font->drawStr( screen, 270, 310, "five shots.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_MACHINE_GUN:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_MACHINE_GUN );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Machine Gun");
|
||||
font->drawStr( screen, 270, 100, "The Machine Gun fires a");
|
||||
font->drawStr( screen, 270, 130, "massive amount of steel per");
|
||||
font->drawStr( screen, 270, 160, "minute at the enemy on the");
|
||||
font->drawStr( screen, 270, 190, "ground and in the air.");
|
||||
font->drawStr( screen, 270, 220, "It has the ability to aim in a");
|
||||
font->drawStr( screen, 270, 250, "small angle at nearby enemys.");
|
||||
font->drawStr( screen, 270, 280, "This makes it useful to");
|
||||
font->drawStr( screen, 270, 310, "attack formations from the");
|
||||
font->drawStr( screen, 270, 340, "side.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_DUMBFIRE_DOUBLE:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_DUMBFIRE_DOUBLE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Double Dumbfire Rocket");
|
||||
font->drawStr( screen, 270, 100, "With this upgrade, you get one");
|
||||
font->drawStr( screen, 270, 130, "extra dumbfire missile for the");
|
||||
font->drawStr( screen, 270, 160, "light fighter. These rockets");
|
||||
font->drawStr( screen, 270, 190, "hit targets on the ground and");
|
||||
font->drawStr( screen, 270, 220, "in the air.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_KICK_ASS_ROCKET:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_KICK_ASS_ROCKET );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Kick-Ass Rocket");
|
||||
font->drawStr( screen, 270, 100, "This is the strongest air to");
|
||||
font->drawStr( screen, 270, 130, "ground rocket. It takes only");
|
||||
font->drawStr( screen, 270, 160, "one shot to let a turret");
|
||||
font->drawStr( screen, 270, 190, "explode but reloading takes");
|
||||
font->drawStr( screen, 270, 220, "longer.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_HELLFIRE:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_HELLFIRE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Hellfire Rocket");
|
||||
font->drawStr( screen, 270, 100, "Medium air to ground missiles");
|
||||
font->drawStr( screen, 270, 130, "that are fired in pairs and");
|
||||
font->drawStr( screen, 270, 160, "look much better than the");
|
||||
font->drawStr( screen, 270, 190, "fat clumsy Kick-Ass-Rocket.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
// heatseaker (für Paul :-)
|
||||
case INFO_HEATSEEKER:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_HEATSEEKER );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Heatseaker Rocket");
|
||||
font->drawStr( screen, 270, 100, "Just hit the trigger and this");
|
||||
font->drawStr( screen, 270, 130, "missile will find the enemy");
|
||||
font->drawStr( screen, 270, 160, "itself. Ground targets as well");
|
||||
font->drawStr( screen, 270, 190, "as air targets will be hit.");
|
||||
font->drawStr( screen, 270, 220, "Each item gives 70 of these.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_NUKE:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_NUKE );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "The Great Nuke");
|
||||
font->drawStr( screen, 270, 100, "Not much is known about this");
|
||||
font->drawStr( screen, 270, 130, "weapon because everyone who");
|
||||
font->drawStr( screen, 270, 160, "saw it exploding was dead in");
|
||||
font->drawStr( screen, 270, 190, "just that moment.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_DEFLECTOR:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_DEFLECTOR );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Energyweapon Deflector");
|
||||
font->drawStr( screen, 270, 100, "This is a very useful");
|
||||
font->drawStr( screen, 270, 130, "equipment for the heavy");
|
||||
font->drawStr( screen, 270, 160, "fighter. It amplifies the");
|
||||
font->drawStr( screen, 270, 190, "builtin deflector, so that");
|
||||
font->drawStr( screen, 270, 220, "it is very hard to be hit");
|
||||
font->drawStr( screen, 270, 250, "by an energy weapon.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_ENERGY_BEAM:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_ENERGY_BEAM );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Energy Beam");
|
||||
font->drawStr( screen, 270, 100, "The Energy Beam was built");
|
||||
font->drawStr( screen, 270, 130, "for the light fighter and");
|
||||
font->drawStr( screen, 270, 160, "its devastating power");
|
||||
font->drawStr( screen, 270, 190, "makes it the best choice");
|
||||
font->drawStr( screen, 270, 220, "against air targets. In");
|
||||
font->drawStr( screen, 270, 250, "addition its really hard");
|
||||
font->drawStr( screen, 270, 280, "to evade this weapon.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_LASER:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_LASER );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Heavy Laser");
|
||||
font->drawStr( screen, 270, 100, "This is the newest type");
|
||||
font->drawStr( screen, 270, 130, "of equipment for the heavy");
|
||||
font->drawStr( screen, 270, 160, "fighter. A skilled pilot");
|
||||
font->drawStr( screen, 270, 190, "can take down two air");
|
||||
font->drawStr( screen, 270, 220, "enemies at once with this");
|
||||
font->drawStr( screen, 270, 250, "heavy laser.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_SHIELD_UP:
|
||||
{
|
||||
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_HEALTH );
|
||||
infoscreenItems->addItem( newItem );
|
||||
font->drawStr( screen, 300, 40, "Health Powerup");
|
||||
font->drawStr( screen, 270, 100, "If your shield goes down");
|
||||
font->drawStr( screen, 270, 130, "this powerup is especially");
|
||||
font->drawStr( screen, 270, 160, "useful for instant repairs.");
|
||||
font->drawStr( screen, 270, 190, "Try to get it as often as");
|
||||
font->drawStr( screen, 270, 220, "you can.");
|
||||
infoscreenItems->draw( screen );
|
||||
break;
|
||||
}
|
||||
case INFO_CREDITS:
|
||||
{
|
||||
font->drawStr( screen, 445, 40, "Alien Blaster", FONT_ALIGN_CENTERED );
|
||||
font->drawStr( screen, 270, 100, "Programming:");
|
||||
font->drawStr( screen, 280, 130, "Arne Hormann, Daniel Kühn,");
|
||||
font->drawStr( screen, 280, 160, "Paul Grathwohl, Sönke Schwardt");
|
||||
font->drawStr( screen, 270, 210, "Art Work: Arne Hormann", FONT_MONOSPACE);
|
||||
font->drawStr( screen, 270, 240, "Music: Paul Grathwohl", FONT_MONOSPACE);
|
||||
font->drawStr( screen, 620, 440, "Contact: AlienBlaster@gmx.de", FONT_ALIGN_RIGHT);
|
||||
break;
|
||||
}
|
||||
case INFO_BACK_TO_MAIN_MENU:
|
||||
{
|
||||
font->drawStr( screen, 445, 220, "GO AND FIGHT !", FONT_ALIGN_CENTERED );
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_Flip( screen );
|
||||
}
|
||||
|
||||
void Infoscreen::handleEvents() {
|
||||
SDL_Event event;
|
||||
|
||||
while ( SDL_PollEvent(&event) ) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYDOWN: {
|
||||
switch ( event.key.keysym.sym ) {
|
||||
case SDLK_F5: {
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
case SDLK_F7: {
|
||||
if ( playMusicOn ) {
|
||||
playMusicOn = false;
|
||||
Mixer::mixer().stopMusic();
|
||||
} else {
|
||||
playMusicOn = true;
|
||||
Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_UP: {
|
||||
Mixer::mixer().playSample( choose, 0 );
|
||||
infoscreenItems->deleteAllItems();
|
||||
activeChoice--;
|
||||
if ( activeChoice < 0 ) activeChoice = NR_INFOSCREEN_CHOICES - 1;
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN: {
|
||||
Mixer::mixer().playSample( choose, 0 );
|
||||
infoscreenItems->deleteAllItems();
|
||||
activeChoice = (activeChoice + 1) % NR_INFOSCREEN_CHOICES;
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE: {
|
||||
quitInfoscreen = true;
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN: {
|
||||
Mixer::mixer().playSample( confirm, 0 );
|
||||
switch (activeChoice) {
|
||||
case INFO_BACK_TO_MAIN_MENU: {
|
||||
quitInfoscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef INFOSCREEN_H
|
||||
#define INFOSCREEN_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include <string>
|
||||
#include "item.h"
|
||||
|
||||
class Font;
|
||||
class Items;
|
||||
|
||||
enum INFOSCREEN_CHOICES {
|
||||
INFO_LIGHT_FIGHTER,
|
||||
INFO_HEAVY_FIGHTER,
|
||||
INFO_PRIMARY_WEAPON,
|
||||
INFO_MACHINE_GUN,
|
||||
INFO_DUMBFIRE_DOUBLE,
|
||||
INFO_KICK_ASS_ROCKET,
|
||||
INFO_HELLFIRE,
|
||||
INFO_HEATSEEKER,
|
||||
INFO_NUKE,
|
||||
INFO_DEFLECTOR,
|
||||
INFO_ENERGY_BEAM,
|
||||
INFO_LASER,
|
||||
INFO_SHIELD_UP,
|
||||
INFO_CREDITS,
|
||||
INFO_BACK_TO_MAIN_MENU
|
||||
};
|
||||
const std::string SET_INFOSCREEN_CHOICES[] = {
|
||||
"Light Fighter",
|
||||
"Heavy Fighter",
|
||||
"Primary Weapon",
|
||||
"Machine Gun",
|
||||
"Double Dumbfire",
|
||||
"Kick-Ass Rocket",
|
||||
"Hellfire Rocket",
|
||||
"Heatseaker Rocket",
|
||||
"The Great Nuke",
|
||||
"Deflector",
|
||||
"Energy Beam",
|
||||
"Heavy Laser",
|
||||
"Health Powerup",
|
||||
"Credits",
|
||||
"Back To Main Menu"
|
||||
};
|
||||
|
||||
const int NR_INFOSCREEN_CHOICES = 15;
|
||||
|
||||
class Infoscreen {
|
||||
private:
|
||||
SdlCompat_AcceleratedSurface *screen;
|
||||
SdlCompat_AcceleratedSurface *activeChoiceSprite;
|
||||
SdlCompat_AcceleratedSurface *lightFighterIcon1;
|
||||
SdlCompat_AcceleratedSurface *lightFighterIcon2;
|
||||
SdlCompat_AcceleratedSurface *heavyFighterIcon1;
|
||||
SdlCompat_AcceleratedSurface *heavyFighterIcon2;
|
||||
Font *font;
|
||||
Font *fontHighlighted;
|
||||
Item *newItem;
|
||||
|
||||
int activeChoice;
|
||||
bool quitInfoscreen;
|
||||
|
||||
// sounds
|
||||
int choose, confirm;
|
||||
|
||||
public:
|
||||
Infoscreen( SdlCompat_AcceleratedSurface *scr );
|
||||
~Infoscreen();
|
||||
void run();
|
||||
|
||||
private:
|
||||
void handleEvents();
|
||||
void draw();
|
||||
void putBitmapAtPosition( int x, int y, SdlCompat_AcceleratedSurface* bitmap );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,112 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include <vector>
|
||||
#include "input.h"
|
||||
#include "SDL.h"
|
||||
#include "settings.h"
|
||||
|
||||
Input input;
|
||||
|
||||
const int initialSensitivity = 4096;
|
||||
|
||||
Input::Input(){
|
||||
joystick = 0;
|
||||
getJoystick();
|
||||
}
|
||||
|
||||
Input::~Input(){
|
||||
freeJoystick();
|
||||
joystick = 0;
|
||||
}
|
||||
|
||||
void Input::getJoystick() {
|
||||
if (joystick) return;
|
||||
if (!SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
if (SDL_NumJoysticks() > 0) {
|
||||
joystick = SDL_JoystickOpen(0);
|
||||
} else {
|
||||
freeJoystick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Input::freeJoystick() {
|
||||
if (joystick) {
|
||||
SDL_JoystickClose(joystick);
|
||||
joystick = 0;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const bool pressed(const SDL_Event& event) {
|
||||
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_KEYDOWN) return true;
|
||||
if (event.type == SDL_JOYAXISMOTION) return event.jaxis.value / 3200;
|
||||
return false;
|
||||
}
|
||||
|
||||
void debugEvent(const SDL_Event& event, const SDLKey code) {
|
||||
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
|
||||
printf("Joystick button%d event: %s (%d)\n",
|
||||
event.jbutton.button, (pressed(event)) ? "pressed" : "released", code);
|
||||
} else if (event.type == SDL_JOYAXISMOTION && pressed(event)) {
|
||||
printf("Joystick axis%d event: %s (%d)\n",
|
||||
event.jaxis.axis, (event.jaxis.value > 0) ? "raised" : "lowered", code);
|
||||
}
|
||||
}
|
||||
|
||||
const SDLKey translateEvent(const SDL_Event& event) {
|
||||
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
|
||||
return event.key.keysym.sym;
|
||||
}
|
||||
if (event.type == SDL_JOYAXISMOTION) {
|
||||
return (SDLKey) (1024 + event.jaxis.axis * 2 + ((event.jaxis.value > 0) ? 1 : 0));
|
||||
}
|
||||
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
|
||||
return (SDLKey) (1040 + event.jbutton.button);
|
||||
}
|
||||
return (SDLKey) 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
const SDLKey Input::translate(const SDL_Event& event) {
|
||||
#ifdef DEBUG
|
||||
debugEvent(event, translateEvent(event));
|
||||
#endif
|
||||
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
|
||||
return event.key.keysym.sym;
|
||||
}
|
||||
if (event.type == SDL_JOYAXISMOTION) {
|
||||
return (SDLKey) (1024 + event.jaxis.axis * 2 + ((event.jaxis.value > 0) ? 1 : 0));
|
||||
}
|
||||
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
|
||||
return (SDLKey) (1040 + event.jbutton.button);
|
||||
}
|
||||
return (SDLKey) 0;
|
||||
}
|
||||
|
||||
const bool Input::isPressed(const SDL_Event& event) {
|
||||
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_KEYDOWN || event.type == SDL_MOUSEBUTTONDOWN) return true;
|
||||
if (event.type == SDL_JOYAXISMOTION) return event.jaxis.value / initialSensitivity;
|
||||
return false;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SdlForwardCompat.h"
|
||||
|
||||
class Input;
|
||||
|
||||
extern Input input;
|
||||
|
||||
class Input {
|
||||
|
||||
private:
|
||||
Uint16 currentJoystick;
|
||||
SDL_Joystick *joystick;
|
||||
|
||||
public:
|
||||
Input();
|
||||
~Input();
|
||||
void getJoystick();
|
||||
void freeJoystick();
|
||||
const SDLKey translate(const SDL_Event& event);
|
||||
const bool isPressed(const SDL_Event& event);
|
||||
|
||||
static const Input input();
|
||||
};
|
||||
|
||||
#endif //#ifndef INPUT_H
|
||||
@@ -1,250 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "intro.h"
|
||||
#include "global.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "mixer.h"
|
||||
#include "video.h"
|
||||
#include "font.h"
|
||||
#include "settings.h"
|
||||
#include "infoscreen.h"
|
||||
|
||||
Intro::Intro( SdlCompat_AcceleratedSurface *scr ) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 1");
|
||||
screen = scr;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 2");
|
||||
introSprite = surfaceDB.loadSurface( FN_ALIENBLASTER_INTRO );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 3");
|
||||
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 4");
|
||||
font = new Font( FN_FONT_INTRO );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 5");
|
||||
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 6");
|
||||
activeChoice = 0;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 7");
|
||||
choose = Mixer::mixer().loadSample( FN_SOUND_INTRO_CHOOSE, 100 );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 8");
|
||||
confirm = Mixer::mixer().loadSample( FN_SOUND_INTRO_CONFIRM, 100 );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 9");
|
||||
infoscreen = new Infoscreen( screen );
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 10");
|
||||
}
|
||||
|
||||
Intro::~Intro() {}
|
||||
|
||||
void Intro::run( GameStates &gameState ) {
|
||||
|
||||
if ( playMusicOn && Mixer::mixer().whichMusicPlaying() != MUSIC_INTRO ) {
|
||||
Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 );
|
||||
}
|
||||
|
||||
draw();
|
||||
while ( gameState == GS_INTRO ) {
|
||||
handleEvents( gameState );
|
||||
draw();
|
||||
SDL_Delay( 50 );
|
||||
}
|
||||
}
|
||||
|
||||
void Intro::draw() {
|
||||
videoserver->clearScreen();
|
||||
SDL_Rect r;
|
||||
r.x = screen->w / 2 - introSprite->w / 2;
|
||||
r.y = 0;
|
||||
r.w = introSprite->w;
|
||||
r.h = introSprite->h;
|
||||
SDL_BlitSurface( introSprite, 0, screen, &r );
|
||||
|
||||
for ( int i = 0; i < NR_INTRO_CHOICES; i++ ) {
|
||||
if ( activeChoice == i ) {
|
||||
r.x = 230 - activeChoiceSprite->w - 8;
|
||||
r.y = 258 + i * 35;
|
||||
r.w = activeChoiceSprite->w;
|
||||
r.h = activeChoiceSprite->h;
|
||||
SDL_BlitSurface(activeChoiceSprite, 0, screen, &r );
|
||||
fontHighlighted->drawStr( screen, 230, 260 + i * 35, INTRO_CHOICES[ i ] );
|
||||
} else {
|
||||
font->drawStr( screen, 230, 260 + i * 35, INTRO_CHOICES[ i ] );
|
||||
}
|
||||
}
|
||||
SDL_Flip( screen );
|
||||
}
|
||||
|
||||
void Intro::handleEvents( GameStates &gameState ) {
|
||||
SDL_Event event;
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYDOWN: {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_F5: {
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
case SDLK_F7: {
|
||||
if ( playMusicOn ) {
|
||||
playMusicOn = false;
|
||||
Mixer::mixer().stopMusic();
|
||||
} else {
|
||||
playMusicOn = true;
|
||||
Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_UP: {
|
||||
Mixer::mixer().playSample( choose, 0 );
|
||||
activeChoice--;
|
||||
if ( activeChoice < 0 ) activeChoice = NR_INTRO_CHOICES - 1;
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN: {
|
||||
Mixer::mixer().playSample( choose, 0 );
|
||||
activeChoice = (activeChoice + 1) % NR_INTRO_CHOICES;
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE: {
|
||||
gameState = GS_QUIT;
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN: {
|
||||
Mixer::mixer().playSample( confirm, 0 );
|
||||
switch (activeChoice) {
|
||||
case ONE_PLAYER_GAME: {
|
||||
onePlayerGame = true;
|
||||
arcadeGame = false;
|
||||
gameState = GS_SET_DIFFICULTY;
|
||||
break;
|
||||
}
|
||||
case TWO_PLAYER_GAME: {
|
||||
onePlayerGame = false;
|
||||
arcadeGame = false;
|
||||
gameState = GS_SET_DIFFICULTY;
|
||||
break;
|
||||
}
|
||||
case ARCADE_GAME: {
|
||||
onePlayerGame = true;
|
||||
arcadeGame = true;
|
||||
gameState = GS_ARCADE_MODE_SETUP;
|
||||
break;
|
||||
}
|
||||
case CONFIGURE_KEYS: {
|
||||
settings->settingsDialog(screen);
|
||||
draw();
|
||||
break;
|
||||
}
|
||||
case INFOSCREEN: {
|
||||
infoscreen->run();
|
||||
break;
|
||||
}
|
||||
case QUIT_AND_DIE: {
|
||||
gameState = GS_QUIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_QUIT: {
|
||||
gameState = GS_QUIT;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Intro::showScreenshots() {
|
||||
if ( playMusicOn && Mixer::mixer().whichMusicPlaying() != MUSIC_INTRO ) {
|
||||
Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 );
|
||||
}
|
||||
|
||||
// TODO: Too lazy to fix that
|
||||
/*
|
||||
SdlCompat_AcceleratedSurface *surfS = SDL_LoadBMP( FN_ALIENBLASTER_INTRO.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf0 = SDL_LoadBMP( FN_SCREENSHOT0.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf1 = SDL_LoadBMP( FN_SCREENSHOT1.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf2 = SDL_LoadBMP( FN_SCREENSHOT2.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf3 = SDL_LoadBMP( FN_SCREENSHOT3.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf4 = SDL_LoadBMP( FN_SCREENSHOT4.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf5 = SDL_LoadBMP( FN_SCREENSHOT5.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf6 = SDL_LoadBMP( FN_SCREENSHOT6.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf7 = SDL_LoadBMP( FN_SCREENSHOT7.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf8 = SDL_LoadBMP( FN_SCREENSHOT8.c_str() );
|
||||
SdlCompat_AcceleratedSurface *surf9 = SDL_LoadBMP( FN_SCREENSHOT9.c_str() );
|
||||
|
||||
SDL_BlitSurface( surfS, 0, screen, 0 );
|
||||
SDL_Flip(screen);
|
||||
SDL_Delay(3000);
|
||||
int sps = 50; // steps per second
|
||||
if (blendImages( screen, surfS, 0, surf0, 0, sps ))
|
||||
if (blendImages( screen, surf0, 0, surf1, 0, sps ))
|
||||
if (blendImages( screen, surf1, 0, surf2, 0, sps ))
|
||||
if (blendImages( screen, surf2, 0, surf3, 0, sps ))
|
||||
if (blendImages( screen, surf3, 0, surf4, 0, sps ))
|
||||
if (blendImages( screen, surf4, 0, surf5, 0, sps ))
|
||||
if (blendImages( screen, surf5, 0, surf6, 0,sps ))
|
||||
if (blendImages( screen, surf6, 0, surf7, 0, sps ))
|
||||
if (blendImages( screen, surf7, 0, surf8, 0, sps ))
|
||||
blendImages( screen, surf8, 0, surf9, 0, sps );
|
||||
*/
|
||||
}
|
||||
|
||||
// TODO: Too lazy to fix that
|
||||
/*
|
||||
bool Intro::blendImages( SdlCompat_AcceleratedSurface *screen, SdlCompat_AcceleratedSurface *surf0, SDL_Rect *r1, SdlCompat_AcceleratedSurface *surf1, SDL_Rect *r2, int sps ) {
|
||||
SDL_Event event;
|
||||
|
||||
int i = 0;
|
||||
int t = SDL_GetTicks();
|
||||
while (i < 255) {
|
||||
if (i>255) i=255;
|
||||
|
||||
SDL_SetAlpha( surf0, SDL_SRCALPHA, 255-i );
|
||||
SDL_SetAlpha( surf1, SDL_SRCALPHA, i );
|
||||
SDL_BlitSurface( surf0, 0, screen, r1 );
|
||||
SDL_BlitSurface( surf1, 0, screen, r2 );
|
||||
SDL_Flip( screen );
|
||||
int t2 = SDL_GetTicks();
|
||||
int dt= SDL_GetTicks() - t;
|
||||
t = t2;
|
||||
i += (dt * sps / 1000);
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYDOWN: {
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
@@ -1,65 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef INTRO_H
|
||||
#define INTRO_H
|
||||
|
||||
#include <string>
|
||||
#include "SDL.h"
|
||||
#include "SdlForwardCompat.h"
|
||||
#include "game.h"
|
||||
|
||||
class Font;
|
||||
class Infoscreen;
|
||||
|
||||
enum IntroChoices { ONE_PLAYER_GAME, TWO_PLAYER_GAME, ARCADE_GAME,
|
||||
CONFIGURE_KEYS, INFOSCREEN, QUIT_AND_DIE };
|
||||
const std::string INTRO_CHOICES[] = { "1-Player Action", "2-Player Fight",
|
||||
"Arcade",
|
||||
"Configure Keys", "Infoscreen", "Quit and Die" };
|
||||
const int NR_INTRO_CHOICES = 6;
|
||||
|
||||
class Intro {
|
||||
private:
|
||||
SdlCompat_AcceleratedSurface *screen;
|
||||
SdlCompat_AcceleratedSurface *introSprite;
|
||||
SdlCompat_AcceleratedSurface *activeChoiceSprite;
|
||||
Font *font;
|
||||
Font *fontHighlighted;
|
||||
Infoscreen *infoscreen;
|
||||
|
||||
int activeChoice;
|
||||
|
||||
// sound
|
||||
int choose;
|
||||
int confirm;
|
||||
|
||||
public:
|
||||
Intro( SdlCompat_AcceleratedSurface *scr );
|
||||
~Intro();
|
||||
void run( GameStates &gameState );
|
||||
void showScreenshots();
|
||||
// bool blendImages( SdlCompat_AcceleratedSurface *screen, SdlCompat_AcceleratedSurface *surf0, SDL_Rect *r1, SdlCompat_AcceleratedSurface *surf1, SDL_Rect *r2, int sps );
|
||||
|
||||
private:
|
||||
void handleEvents( GameStates &gameState );
|
||||
void draw();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,136 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include <iostream>
|
||||
#include "item.h"
|
||||
#include "boundingBox.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "global.h"
|
||||
|
||||
Item::Item(const Vector2D &position, const Vector2D &velocity, ItemTypes itemType) {
|
||||
|
||||
this->itemType = itemType;
|
||||
|
||||
pos = position;
|
||||
vel = velocity;
|
||||
timeLived = 0;
|
||||
|
||||
switch (itemType) {
|
||||
case ITEM_PRIMARY_UPGRADE:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_PRIMARY_UPGRADE );
|
||||
break;
|
||||
}
|
||||
case ITEM_DUMBFIRE_DOUBLE:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_DUMBFIRE_DOUBLE );
|
||||
break;
|
||||
}
|
||||
case ITEM_KICK_ASS_ROCKET:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_KICK_ASS_ROCKET );
|
||||
break;
|
||||
}
|
||||
case ITEM_HELLFIRE:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_HELLFIRE );
|
||||
break;
|
||||
}
|
||||
case ITEM_MACHINE_GUN:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_MACHINE_GUN );
|
||||
break;
|
||||
}
|
||||
case ITEM_HEALTH:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_HEALTH );
|
||||
break;
|
||||
}
|
||||
case ITEM_HEATSEEKER:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_HEATSEEKER );
|
||||
break;
|
||||
}
|
||||
case ITEM_NUKE:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_NUKE );
|
||||
break;
|
||||
}
|
||||
case ITEM_DEFLECTOR:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_DEFLECTOR );
|
||||
break;
|
||||
}
|
||||
case ITEM_LASER:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_LASER );
|
||||
break;
|
||||
}
|
||||
case ITEM_ENERGY_BEAM:
|
||||
{
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_ENERGY_BEAM );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
cout << "Item(): unexpected itemType: " << itemType << endl;
|
||||
sprite = surfaceDB.loadSurface( FN_ITEM_PRIMARY_UPGRADE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boundingBox = new BoundingBox( lroundf(pos.getX() - sprite->w / 2.0),
|
||||
lroundf(pos.getY() - sprite->h / 2.0),
|
||||
sprite->w, sprite->h );
|
||||
}
|
||||
|
||||
Item::~Item() {
|
||||
delete boundingBox;
|
||||
}
|
||||
|
||||
|
||||
void Item::update( int dT ) {
|
||||
pos += vel * dT / 1000.0;
|
||||
updateBoundingBox();
|
||||
timeLived += dT;
|
||||
}
|
||||
|
||||
void Item::deleteItem() {
|
||||
timeLived = ITEM_LIFETIME;
|
||||
}
|
||||
|
||||
void Item::updateBoundingBox() {
|
||||
boundingBox->moveUpperBound( lroundf(pos.getY() - sprite->h * 0.5) );
|
||||
boundingBox->moveLeftBound( lroundf(pos.getX() - sprite->w * 0.5) );
|
||||
}
|
||||
|
||||
void Item::draw(SdlCompat_AcceleratedSurface *screen) {
|
||||
SDL_Rect r;
|
||||
r.x = lroundf(pos.getX()) - sprite->w / 2;
|
||||
r.y = lroundf(pos.getY()) - sprite->h / 2;
|
||||
r.w = sprite->w;
|
||||
r.h = sprite->h;
|
||||
SDL_BlitSurface( sprite, 0, screen, &r );
|
||||
}
|
||||
|
||||
BoundingBox *Item::getBoundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef ITEM_H
|
||||
#define ITEM_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "geometry.h"
|
||||
#include <string>
|
||||
#include "global.h"
|
||||
|
||||
class BoundingBox;
|
||||
|
||||
class Item {
|
||||
SdlCompat_AcceleratedSurface *sprite;
|
||||
BoundingBox *boundingBox;
|
||||
|
||||
Vector2D pos;
|
||||
Vector2D vel;
|
||||
ItemTypes itemType;
|
||||
|
||||
int timeLived;
|
||||
|
||||
void updateBoundingBox();
|
||||
|
||||
public:
|
||||
Item( const Vector2D &position, const Vector2D &velocity, ItemTypes itemType );
|
||||
~Item();
|
||||
|
||||
void update( int dT );
|
||||
|
||||
void deleteItem();
|
||||
|
||||
void draw(SdlCompat_AcceleratedSurface *screen);
|
||||
|
||||
inline bool isExpired() { return (timeLived >= ITEM_LIFETIME); }
|
||||
inline Vector2D getPos() { return pos; }
|
||||
inline Vector2D getVel() { return vel; }
|
||||
inline void pickedUp() { timeLived = ITEM_LIFETIME; }
|
||||
inline ItemTypes getType() { return itemType; }
|
||||
BoundingBox *getBoundingBox();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,131 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "item.h"
|
||||
#include "items.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "geometry.h"
|
||||
#include "global.h"
|
||||
#include "racers.h"
|
||||
|
||||
Items::Items() {
|
||||
timeNextItemAppear =
|
||||
ITEM_APPEAR_DELAY +
|
||||
(rand() % ITEM_APPEAR_RAND_DELAY);
|
||||
}
|
||||
|
||||
Items::~Items() {
|
||||
vector<Item *>::iterator i;
|
||||
for (i = items.begin(); i != items.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
void Items::addItem(Item *item) {
|
||||
if (item) {
|
||||
items.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
void Items::expireItems() {
|
||||
unsigned int i = 0;
|
||||
while ( i < items.size() ) {
|
||||
if ( items[i]->isExpired() ) {
|
||||
delete items[i];
|
||||
items.erase(items.begin() + i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Items::update( int dT ) {
|
||||
vector<Item *>::iterator i;
|
||||
for (i = items.begin(); i != items.end(); ++i) {
|
||||
(*i)->update( dT );
|
||||
}
|
||||
}
|
||||
|
||||
void Items::draw(SdlCompat_AcceleratedSurface *screen) {
|
||||
vector<Item *>::iterator i;
|
||||
for (i = items.begin(); i != items.end(); ++i) {
|
||||
(*i)->draw(screen);
|
||||
}
|
||||
}
|
||||
|
||||
Item *Items::getItem(unsigned int idx) {
|
||||
return items[idx];
|
||||
}
|
||||
|
||||
|
||||
void Items::generateItemNow( Vector2D pos, Vector2D vel ) {
|
||||
if ( pos.getX() < 10 ) pos.setX( 10 );
|
||||
if ( pos.getX() > SCREEN_WIDTH-10 ) pos.setX( SCREEN_WIDTH-10 );
|
||||
if ( pos.getY() < 100 && vel.getY() < 5 ) vel.setY( 5 );
|
||||
|
||||
int itemType;
|
||||
// 10 tries for a correct item
|
||||
for ( int i = 0; i < 10; i++ ) {
|
||||
itemType = getRandValue( ITEM_APPEAR_CHANCES, NR_ITEM_TYPES );
|
||||
if ( ( racers->isShipTypeActive( LIGHT_FIGHTER ) &&
|
||||
racers->isShipTypeActive( HEAVY_FIGHTER ) ) ||
|
||||
( racers->isShipTypeActive( LIGHT_FIGHTER ) &&
|
||||
( itemType == ITEM_PRIMARY_UPGRADE ||
|
||||
itemType == ITEM_DUMBFIRE_DOUBLE ||
|
||||
itemType == ITEM_KICK_ASS_ROCKET ||
|
||||
itemType == ITEM_HELLFIRE ||
|
||||
itemType == ITEM_MACHINE_GUN ||
|
||||
itemType == ITEM_HEALTH ||
|
||||
itemType == ITEM_HEATSEEKER ||
|
||||
itemType == ITEM_NUKE ||
|
||||
itemType == ITEM_ENERGY_BEAM ) ) ||
|
||||
( racers->isShipTypeActive( HEAVY_FIGHTER ) &&
|
||||
( itemType == ITEM_PRIMARY_UPGRADE ||
|
||||
itemType == ITEM_DUMBFIRE_DOUBLE ||
|
||||
itemType == ITEM_KICK_ASS_ROCKET ||
|
||||
itemType == ITEM_HEALTH ||
|
||||
itemType == ITEM_HEATSEEKER ||
|
||||
itemType == ITEM_NUKE ||
|
||||
itemType == ITEM_DEFLECTOR ||
|
||||
itemType == ITEM_LASER ) ) ) {
|
||||
Item *item = new Item( pos, vel, (ItemTypes)itemType );
|
||||
addItem( item );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Items::generate( int dT ) {
|
||||
timeNextItemAppear -= dT;
|
||||
|
||||
if ( timeNextItemAppear < 0 ) {
|
||||
timeNextItemAppear = ITEM_APPEAR_DELAY + (rand() % ITEM_APPEAR_RAND_DELAY);
|
||||
generateItemNow( Vector2D( 150 + (rand() % 340), -20 ),
|
||||
Vector2D( (rand() % lroundf(SCROLL_SPEED)) - SCROLL_SPEED / 2,
|
||||
SCROLL_SPEED + (rand() % lroundf(SCROLL_SPEED)) ) );
|
||||
}
|
||||
}
|
||||
|
||||
void Items::deleteAllItems() {
|
||||
vector<Item *>::iterator i;
|
||||
for (i = items.begin(); i != items.end(); ++i) {
|
||||
(*i)->deleteItem();
|
||||
}
|
||||
expireItems();
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef ITEMS_H
|
||||
#define ITEMS_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include <vector>
|
||||
|
||||
class Item;
|
||||
class Vector2D;
|
||||
|
||||
class Items {
|
||||
vector<Item *> items;
|
||||
|
||||
int timeNextItemAppear;
|
||||
|
||||
public:
|
||||
Items();
|
||||
~Items();
|
||||
|
||||
void addItem(Item *item);
|
||||
void generateItemNow( Vector2D pos, Vector2D vel );
|
||||
void generate( int dT );
|
||||
void expireItems();
|
||||
void update( int dT );
|
||||
void draw(SdlCompat_AcceleratedSurface *screen);
|
||||
void deleteAllItems();
|
||||
|
||||
inline unsigned int getNrItems() { return items.size(); }
|
||||
Item *getItem(unsigned int idx);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,51 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include "game.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "SDL.h"
|
||||
#include <stdlib.h>
|
||||
#include <android/log.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void appPutToBackground()
|
||||
{
|
||||
SDL_ANDROID_PauseAudioPlayback();
|
||||
}
|
||||
static void appPutToForeground()
|
||||
{
|
||||
surfaceDB.reloadAllSurfacesToVideoMemory();
|
||||
SDL_ANDROID_ResumeAudioPlayback();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SDL_ANDROID_SetApplicationPutToBackgroundCallback(&appPutToBackground, &appPutToForeground);
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 0");
|
||||
SDL_Init(0);
|
||||
srand(0);
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 1");
|
||||
Game game;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 2");
|
||||
game.run();
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 3");
|
||||
SDL_Quit();
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 4");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "menuArcadeMode.h"
|
||||
#include "global.h"
|
||||
#include "surfaceDB.h"
|
||||
#include "mixer.h"
|
||||
#include "video.h"
|
||||
#include "font.h"
|
||||
#include "racer.h"
|
||||
#include "racers.h"
|
||||
#include "asstring.h"
|
||||
#include "options.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
MenuArcadeMode::MenuArcadeMode( SdlCompat_AcceleratedSurface *scr ) {
|
||||
screen = scr;
|
||||
arcadeSprite = surfaceDB.loadSurface( FN_ARCADE_LOGO );
|
||||
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
|
||||
|
||||
font = new Font( FN_FONT_INTRO );
|
||||
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
|
||||
lightFighterIcon1 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_1_ICON );
|
||||
heavyFighterIcon1 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_1_ICON );
|
||||
choose = Mixer::mixer().loadSample( FN_SOUND_ARCADE_CHOOSE, 100 );
|
||||
confirm = Mixer::mixer().loadSample( FN_SOUND_ARCADE_CONFIRM, 60 );
|
||||
activeChoice = 0;
|
||||
playerOneLightFighter = true;
|
||||
|
||||
op = new Options( FN_HIGHSCORE );
|
||||
|
||||
// check, if the highscore is open
|
||||
int highscoreTest;
|
||||
if ( !op->getInt( "POINTS_1", highscoreTest ) ) {
|
||||
cout << "Creating the highscore..." << endl;
|
||||
op->setStr( "ALIENBLASTER", "NAME_1" );
|
||||
op->setInt( 1666, "POINTS_1" );
|
||||
op->setStr( "GNOSTICAL", "NAME_2" );
|
||||
op->setInt( 1000, "POINTS_2" );
|
||||
op->setStr( "SLOBJOK", "NAME_3" );
|
||||
op->setInt( 1000, "POINTS_3" );
|
||||
op->setStr( "SNOWBALL", "NAME_4" );
|
||||
op->setInt( 1000, "POINTS_4" );
|
||||
op->setStr( "THUNDERBIRD", "NAME_5" );
|
||||
op->setInt( 1000, "POINTS_5" );
|
||||
op->setStr( "KaoT", "NAME_6" );
|
||||
op->setInt( 666, "POINTS_6" );
|
||||
op->setStr( "SDL", "NAME_7" );
|
||||
op->setInt( 500, "POINTS_7" );
|
||||
op->setStr( "DEBIAN", "NAME_8" );
|
||||
op->setInt( 400, "POINTS_8" );
|
||||
op->setStr( "DEV-CPP", "NAME_9" );
|
||||
op->setInt( 300, "POINTS_9" );
|
||||
op->setStr( "I RULE", "NAME_10" );
|
||||
op->setInt( 200, "POINTS_10" );
|
||||
op->saveFile( FN_HIGHSCORE );
|
||||
}
|
||||
}
|
||||
|
||||
MenuArcadeMode::~MenuArcadeMode() {
|
||||
op->saveFile( FN_HIGHSCORE );
|
||||
delete op;
|
||||
}
|
||||
|
||||
void MenuArcadeMode::run( GameStates &gameState, int points ) {
|
||||
activeChoice = 0;
|
||||
|
||||
if ( GS_ARCADE_MODE_FINISHED ) {
|
||||
updateHighScore( points );
|
||||
gameState = GS_ARCADE_MODE_SETUP;
|
||||
}
|
||||
|
||||
draw();
|
||||
while ( gameState == GS_ARCADE_MODE_SETUP ) {
|
||||
handleEvents( gameState );
|
||||
draw();
|
||||
SDL_Delay( 50 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MenuArcadeMode::getPlayerOneLightFighter() {
|
||||
return playerOneLightFighter;
|
||||
}
|
||||
|
||||
void MenuArcadeMode::draw() {
|
||||
videoserver->clearScreen();
|
||||
SDL_Rect r;
|
||||
r.x = screen->w / 2 - arcadeSprite->w / 2;
|
||||
r.y = 0;
|
||||
r.w = arcadeSprite->w;
|
||||
r.h = arcadeSprite->h;
|
||||
SDL_BlitSurface( arcadeSprite, 0, screen, &r );
|
||||
|
||||
string name = "UNKNOWN";
|
||||
int points = 0;
|
||||
op->getStr( "NAME_1", name );
|
||||
op->getInt( "POINTS_1", points );
|
||||
fontHighlighted->drawStr( screen, 230, 60, "1. " + name + ": " + asString(points) );
|
||||
for ( int i = 2; i <= 10; i++ ) {
|
||||
op->getStr( "NAME_" + asString( i ), name );
|
||||
op->getInt( "POINTS_" + asString( i ), points );
|
||||
font->drawStr( screen, 230, 40 + i * 25,
|
||||
asString( i ) + ". " + name + ": " + asString(points) );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < NR_MENU_ARCADE_CHOICES; i++ ) {
|
||||
if ( activeChoice == i ) {
|
||||
r.x = 230 - activeChoiceSprite->w - 8;
|
||||
r.y = 338 + i * 40;
|
||||
r.w = activeChoiceSprite->w;
|
||||
r.h = activeChoiceSprite->h;
|
||||
SDL_BlitSurface( activeChoiceSprite, 0, screen, &r );
|
||||
fontHighlighted->drawStr( screen, 230, 340 + i * 40, STRINGS_MENU_ARCADE_CHOICES[ i ] );
|
||||
} else {
|
||||
font->drawStr( screen, 230, 340 + i * 40, STRINGS_MENU_ARCADE_CHOICES[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
font->drawStr( screen, 50, 270, "Player 1" );
|
||||
if ( playerOneLightFighter ) {
|
||||
r.x = 100 - lightFighterIcon1->w / 2;
|
||||
r.y = 340 - lightFighterIcon1->h / 2;
|
||||
r.w = lightFighterIcon1->w;
|
||||
r.h = lightFighterIcon1->h;
|
||||
SDL_BlitSurface( lightFighterIcon1, 0, screen, &r );
|
||||
} else {
|
||||
r.x = 100 - heavyFighterIcon1->w / 2;
|
||||
r.y = 340 - heavyFighterIcon1->h / 2;
|
||||
r.w = heavyFighterIcon1->w;
|
||||
r.h = heavyFighterIcon1->h;
|
||||
SDL_BlitSurface( heavyFighterIcon1, 0, screen, &r );
|
||||
}
|
||||
fontHighlighted->drawStr( screen, 100, 400, "Press \"Volume Up\"", FONT_ALIGN_CENTERED );
|
||||
fontHighlighted->drawStr( screen, 100, 430, "To Change", FONT_ALIGN_CENTERED );
|
||||
|
||||
SDL_Flip( screen );
|
||||
}
|
||||
|
||||
|
||||
void MenuArcadeMode::handleEvents( GameStates &gameState ) {
|
||||
SDL_Event event;
|
||||
|
||||
while ( SDL_PollEvent(&event) ) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYDOWN: {
|
||||
switch ( event.key.keysym.sym ) {
|
||||
case SDLK_PAGEUP: {
|
||||
playerOneLightFighter = !playerOneLightFighter;
|
||||
break;
|
||||
}
|
||||
case SDLK_F5: {
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
case SDLK_F7: {
|
||||
if ( playMusicOn ) {
|
||||
playMusicOn = false;
|
||||
Mixer::mixer().stopMusic();
|
||||
} else {
|
||||
playMusicOn = true;
|
||||
Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_UP: {
|
||||
Mixer::mixer().playSample( choose, 0 );
|
||||
activeChoice--;
|
||||
if ( activeChoice < 0 ) activeChoice = NR_MENU_ARCADE_CHOICES - 1;
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN: {
|
||||
Mixer::mixer().playSample( choose, 0 );
|
||||
activeChoice = (activeChoice + 1) % NR_MENU_ARCADE_CHOICES;
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE: {
|
||||
gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN: {
|
||||
switch (activeChoice) {
|
||||
case ARCADE_FIGHT: {
|
||||
Mixer::mixer().playSample( confirm, 0 );
|
||||
difficultyLevel = ARCADE_DIFFICULTY_LEVEL;
|
||||
gameState = GS_PLAYON;
|
||||
break;
|
||||
}
|
||||
case ARCADE_BACK_TO_MAIN_MENU: {
|
||||
gameState = GS_INTRO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_QUIT: {
|
||||
gameState = GS_QUIT;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************** read the new name for the highscore ***********************/
|
||||
|
||||
|
||||
void MenuArcadeMode::updateHighScore( int points ) {
|
||||
int pointTenth = -1;
|
||||
op->getInt( "POINTS_10", pointTenth );
|
||||
// the player made it in the hall of fame!
|
||||
if ( points >= pointTenth ) {
|
||||
|
||||
int pointsOfEntry = -1;
|
||||
int newPos = -1;
|
||||
for ( int i = 1; i <= 10; i++ ) {
|
||||
op->getInt( "POINTS_" + asString( i ), pointsOfEntry );
|
||||
if ( pointsOfEntry <= points ) {
|
||||
newPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( newPos != -1 ) {
|
||||
// move the positions after newPos one position further down
|
||||
int pointsPrev;
|
||||
string namePrev;
|
||||
for ( int i = 10; i > newPos; i-- ) {
|
||||
op->getInt( "POINTS_" + asString( i-1 ), pointsPrev );
|
||||
op->getStr( "NAME_" + asString( i-1 ), namePrev );
|
||||
op->setInt( pointsPrev, "POINTS_" + asString ( i ) );
|
||||
op->setStr( namePrev, "NAME_" + asString( i ) );
|
||||
}
|
||||
op->setInt( points, "POINTS_" + asString( newPos ) );
|
||||
op->setStr( "? ? ? ?", "NAME_" + asString( newPos ) );
|
||||
readHighScoreName( newPos );
|
||||
}
|
||||
op->saveFile( FN_HIGHSCORE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MenuArcadeMode::readHighScoreName( int pos ) {
|
||||
videoserver->clearScreen();
|
||||
SDL_Rect r;
|
||||
r.x = screen->w / 2 - arcadeSprite->w / 2;
|
||||
r.y = 0;
|
||||
r.w = arcadeSprite->w;
|
||||
r.h = arcadeSprite->h;
|
||||
SDL_BlitSurface( arcadeSprite, 0, screen, &r );
|
||||
|
||||
string name = "UNKNOWN";
|
||||
int points = 0;
|
||||
for ( int i = 1; i <= 10; i++ ) {
|
||||
op->getStr( "NAME_" + asString( i ), name );
|
||||
op->getInt( "POINTS_" + asString( i ), points );
|
||||
if ( pos == i ) {
|
||||
fontHighlighted->drawStr( screen, 230, 40 + i * 25,
|
||||
asString( i ) + ". " + name + ": " + asString(points) );
|
||||
} else {
|
||||
font->drawStr( screen, 230, 40 + i * 25,
|
||||
asString( i ) + ". " + name + ": " + asString(points) );
|
||||
}
|
||||
}
|
||||
|
||||
fontHighlighted->drawStr( screen, 320, 340, "CONGRATULATION - Enter your worthy name!",
|
||||
FONT_ALIGN_CENTERED );
|
||||
|
||||
string newName = "";
|
||||
while ( handleEventsReadName( newName ) ) {
|
||||
drawReadName( newName );
|
||||
SDL_Flip( screen );
|
||||
SDL_Delay( 50 );
|
||||
}
|
||||
op->setStr( newName, "NAME_" + asString( pos ) );
|
||||
}
|
||||
|
||||
bool MenuArcadeMode::handleEventsReadName( string &newName ) {
|
||||
bool moreToRead = true;
|
||||
SDL_Event event;
|
||||
|
||||
while ( SDL_PollEvent(&event) ) {
|
||||
if ( event.type == SDL_KEYDOWN ) {
|
||||
switch ( event.key.keysym.sym ) {
|
||||
case SDLK_F5: {
|
||||
videoserver->toggleFullscreen();
|
||||
break;
|
||||
}
|
||||
case SDLK_F7:
|
||||
{
|
||||
if ( playMusicOn ) {
|
||||
playMusicOn = false;
|
||||
Mixer::mixer().stopMusic();
|
||||
} else {
|
||||
playMusicOn = true;
|
||||
Mixer::mixer().playMusic( MUSIC_INTRO, -1, 1000 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
moreToRead = false;
|
||||
break;
|
||||
}
|
||||
case SDLK_BACKSPACE:
|
||||
{
|
||||
if ( newName.length() > 0 ) {
|
||||
newName.resize( newName.length() - 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if ( newName.length() <= 15 ) {
|
||||
if ( SDLK_a <= event.key.keysym.sym &&
|
||||
event.key.keysym.sym <= SDLK_z ) {
|
||||
if ( ((SDL_GetModState()) & KMOD_LSHIFT != 0 ) ||
|
||||
((SDL_GetModState()) & KMOD_RSHIFT != 0 ) ) {
|
||||
newName += asString( (char)('A' + event.key.keysym.sym - SDLK_a ) );
|
||||
} else {
|
||||
newName += asString( (char)('a' + event.key.keysym.sym - SDLK_a ) );
|
||||
}
|
||||
} else if ( event.key.keysym.sym == SDLK_SPACE ) {
|
||||
newName += " ";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return moreToRead;
|
||||
}
|
||||
|
||||
void MenuArcadeMode::drawReadName( string &name ) {
|
||||
SDL_Rect r;
|
||||
r.x = 150;
|
||||
r.y = 380;
|
||||
r.w = 400;
|
||||
r.h = 40;
|
||||
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 0) );
|
||||
|
||||
fontHighlighted->drawStr( screen, 320, 380, name, FONT_ALIGN_CENTERED );
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef MENU_ARCADE_MODE_H
|
||||
#define MENU_ARCADE_MODE_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "game.h"
|
||||
#include <string>
|
||||
|
||||
class Font;
|
||||
class Options;
|
||||
|
||||
enum MENU_ARCADE_CHOICES { ARCADE_FIGHT, ARCADE_BACK_TO_MAIN_MENU };
|
||||
|
||||
const std::string STRINGS_MENU_ARCADE_CHOICES[] =
|
||||
{ "FIGHT",
|
||||
"Back to Main Menu" };
|
||||
const int NR_MENU_ARCADE_CHOICES = 2;
|
||||
|
||||
class MenuArcadeMode {
|
||||
private:
|
||||
SdlCompat_AcceleratedSurface *screen;
|
||||
SdlCompat_AcceleratedSurface *arcadeSprite;
|
||||
SdlCompat_AcceleratedSurface *activeChoiceSprite;
|
||||
SdlCompat_AcceleratedSurface *lightFighterIcon1;
|
||||
SdlCompat_AcceleratedSurface *heavyFighterIcon1;
|
||||
Font *font;
|
||||
Font *fontHighlighted;
|
||||
|
||||
Options *op;
|
||||
|
||||
int activeChoice;
|
||||
// sounds
|
||||
int choose;
|
||||
int confirm;
|
||||
|
||||
bool playerOneLightFighter;
|
||||
|
||||
public:
|
||||
MenuArcadeMode( SdlCompat_AcceleratedSurface *scr );
|
||||
~MenuArcadeMode();
|
||||
void run( GameStates &gameState, int points=-1 );
|
||||
bool getPlayerOneLightFighter();
|
||||
|
||||
private:
|
||||
void updateHighScore( int points );
|
||||
void readHighScoreName( int pos );
|
||||
void drawReadName( string &newName );
|
||||
bool handleEventsReadName( string &newName );
|
||||
|
||||
void handleEvents( GameStates &gameState );
|
||||
void draw();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,242 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "mixer.h"
|
||||
#include "SDL_mixer.h"
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
Mixer * mixerInstance = NULL;
|
||||
|
||||
Mixer & Mixer::mixer()
|
||||
{
|
||||
if( mixerInstance == NULL )
|
||||
mixerInstance = new Mixer();
|
||||
return *mixerInstance;
|
||||
}
|
||||
|
||||
Mixer::Mixer() {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio");
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
printf("Couldn't initialize SDL audio subsystem: %s\n", SDL_GetError());
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't initialize SDL audio subsystem: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 2");
|
||||
mixChunks = MixChunks(0);
|
||||
musics = Musics(0);
|
||||
enabled = false;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 3");
|
||||
initMixer();
|
||||
lastUsedReservedChannel = 0;
|
||||
reservedChannels = 0;
|
||||
musicPlaying = MUSIC_NONE;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio done");
|
||||
}
|
||||
|
||||
Mixer::~Mixer() {
|
||||
if (enabled) {
|
||||
freeMixer();
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::initMixer() {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 4");
|
||||
enabled = (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 1, 1024) >= 0);
|
||||
if (enabled) {
|
||||
Mix_AllocateChannels(MIXER_NUMBER_CHANNELS);
|
||||
reservedChannels = Mix_ReserveChannels( MIXER_RESERVED_CHANNELS );
|
||||
if ( MIXER_RESERVED_CHANNELS != reservedChannels )
|
||||
cout << "reserve channels not successfull: reserved: " << reservedChannels << endl;
|
||||
lastUsedReservedChannel = 0;
|
||||
fn2snd.clear();
|
||||
fn2mus.clear();
|
||||
playsOn.clear();
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 5");
|
||||
}
|
||||
|
||||
void Mixer::freeMixer() {
|
||||
if (enabled) {
|
||||
Mix_ExpireChannel(-1, 0);
|
||||
for (unsigned int index = 0; index < mixChunks.size(); index++) {
|
||||
Mix_FreeChunk(mixChunks[index]);
|
||||
}
|
||||
for (unsigned int index = 0; index < musics.size(); index++) {
|
||||
Mix_FreeMusic(musics[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Mixer::loadSample(string fileName, int volume) {
|
||||
if (enabled) {
|
||||
if (fn2snd.find(fileName) == fn2snd.end()) {
|
||||
|
||||
string fn = fileName;
|
||||
string fn1 = fn;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", (string( "Loading sound " ) + fn).c_str() );
|
||||
|
||||
// Check if file exist
|
||||
FILE * inputFile = fopen( fn1.c_str(), "rb");
|
||||
if (!inputFile) {
|
||||
if( fn1.size() > 4 && fn1.find(".wav") != string::npos ) {
|
||||
fn1 = fn1.substr( 0, fn1.size() - 4 ) + ".ogg";
|
||||
inputFile = fopen( fn1.c_str(), "rb");
|
||||
}
|
||||
if (!inputFile) {
|
||||
cout << "ERROR: file " << fn1 << " does not exist!" << endl;
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", (string( "Cannot load sound " ) + fn1).c_str() );
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fclose(inputFile);
|
||||
|
||||
// TODO: error-handling
|
||||
Mix_Chunk *newSound = Mix_LoadWAV(fn1.c_str());
|
||||
if( !newSound ) {
|
||||
cout << "ERROR: file " << fn1 << " cannot be loaded!" << endl;
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", (string( "Cannot load sound " ) + fn1).c_str() );
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mixChunks.push_back(newSound);
|
||||
fn2snd[ fileName ] = mixChunks.size() - 1;
|
||||
if ( 0 <= volume && volume < 128 ) {
|
||||
Mix_VolumeChunk( mixChunks[ mixChunks.size() - 1 ], volume );
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", (string( "Loading sound " ) + fn1 + " done").c_str() );
|
||||
return mixChunks.size() - 1;
|
||||
}
|
||||
return fn2snd[ fileName ];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool Mixer::playSample( int sampleId, int loop, bool withPriority ) {
|
||||
int ret = -1;
|
||||
if (enabled) {
|
||||
if ( !withPriority || reservedChannels == 0 ) {
|
||||
ret = Mix_PlayChannel(-1, mixChunks[sampleId], loop);
|
||||
playsOn[ sampleId ] = ret;
|
||||
} else {
|
||||
lastUsedReservedChannel = (lastUsedReservedChannel+1) % reservedChannels;
|
||||
ret = Mix_PlayChannel( lastUsedReservedChannel, mixChunks[sampleId], loop );
|
||||
playsOn[ sampleId ] = ret;
|
||||
}
|
||||
//if ( ret == -1 ) cout << "playSample: error: " << Mix_GetError() << endl;
|
||||
return ret != -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::stopSample(int sampleId) {
|
||||
if (enabled) {
|
||||
return Mix_HaltChannel( playsOn[sampleId] ) != -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mixer::reset() {
|
||||
freeMixer();
|
||||
if (enabled) {
|
||||
initMixer();
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::fadeOut(int mSecs) {
|
||||
if (enabled) {
|
||||
Mix_FadeOutChannel(-1, mSecs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Mixer::loadMusic( string fn ) {
|
||||
if (enabled) {
|
||||
if (fn2mus.find(fn) == fn2mus.end()) {
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", (string( "Loading music " ) + fn).c_str() );
|
||||
|
||||
string fn1 = fn;
|
||||
// Check if file exist
|
||||
FILE * inputFile = fopen( fn1.c_str(), "rb");
|
||||
if (!inputFile) {
|
||||
if( fn1.size() > 4 && fn1.find(".wav") != string::npos ) {
|
||||
fn1 = fn1.substr( 0, fn1.size() - 4 ) + ".ogg";
|
||||
inputFile = fopen( fn1.c_str(), "rb");
|
||||
}
|
||||
if (!inputFile) {
|
||||
cout << "ERROR: file " << fn1 << " does not exist!" << endl;
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", (string( "Cannot load sound " ) + fn1).c_str() );
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fclose(inputFile);
|
||||
|
||||
// TODO: error-handling
|
||||
Mix_Music *newSound = Mix_LoadMUS(fn1.c_str());
|
||||
if( !newSound ) {
|
||||
cout << "ERROR: file " << fn1 << " cannot be loaded!" << endl;
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", (string( "Cannot load sound " ) + fn1).c_str() );
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
musics.push_back(newSound);
|
||||
fn2mus[ fn ] = musics.size() - 1;
|
||||
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", (string( "Loading music " ) + fn1 + " done").c_str() );
|
||||
return musics.size() - 1;
|
||||
}
|
||||
return fn2mus[ fn ];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Mixer::playMusic( MusicTracks musNum, int loop, int fadeInTime ) {
|
||||
if (enabled) {
|
||||
if ( musNum < NR_MUSIC_TRACKS ) {
|
||||
Mix_FadeInMusic( musics[ loadMusic( FN_MUSIC[ (int)musNum ] ) ], loop, fadeInTime );
|
||||
musicPlaying = musNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::stopMusic( int fadeOutTime ) {
|
||||
if (enabled) {
|
||||
Mix_FadeOutMusic( fadeOutTime );
|
||||
}
|
||||
}
|
||||
|
||||
MusicTracks Mixer::whichMusicPlaying() {
|
||||
return musicPlaying;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef MIXER_HH
|
||||
#define MIXER_HH
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_mixer.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "global.h"
|
||||
|
||||
typedef vector<Mix_Chunk*> MixChunks;
|
||||
typedef vector<Mix_Music*> Musics;
|
||||
|
||||
class Mixer;
|
||||
|
||||
const int MIXER_NUMBER_CHANNELS = 32;
|
||||
// reserved for samples, which should play with priority
|
||||
const int MIXER_RESERVED_CHANNELS = 8;
|
||||
|
||||
class Mixer {
|
||||
|
||||
private:
|
||||
MixChunks mixChunks;
|
||||
Musics musics;
|
||||
|
||||
void initMixer();
|
||||
void freeMixer();
|
||||
|
||||
map< string, int > fn2mus;
|
||||
map< string, int > fn2snd;
|
||||
map< int, int > playsOn;
|
||||
|
||||
bool enabled;
|
||||
int reservedChannels;
|
||||
int lastUsedReservedChannel;
|
||||
|
||||
MusicTracks musicPlaying;
|
||||
|
||||
public:
|
||||
|
||||
Mixer();
|
||||
~Mixer();
|
||||
|
||||
/*
|
||||
Loads a sample, returns an id used for playSample
|
||||
0 as a return value indicates an error on loading
|
||||
param volume: use with care: if the sound is loaded
|
||||
for the first time, its volumevalue will be set to
|
||||
volume, else it will be ignored. (0..127)
|
||||
*/
|
||||
int loadSample(string fileName, int volume=10);
|
||||
|
||||
/*
|
||||
plays the sample with the given id
|
||||
if withPriority==true the sample will be played in one of the reserved channels
|
||||
returns true if successfull, false otherwise
|
||||
*/
|
||||
bool playSample(int sampleId, int loop, bool withPriority=false);
|
||||
|
||||
bool stopSample(int sampleId);
|
||||
|
||||
/*
|
||||
resets the Mixer (frees all samples and channels, inits new ones).
|
||||
Use with care:
|
||||
- samples still playing will be apruptly halted
|
||||
- keep in mind that there is only one mixer
|
||||
=> it is resetted globally!!!
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/*
|
||||
fades out all channels
|
||||
*/
|
||||
void fadeOut(int mSecs);
|
||||
|
||||
int loadMusic( string fileName );
|
||||
void playMusic( MusicTracks musNum, int loop, int fadeInTime=0 );
|
||||
void stopMusic( int fadeOutTime=0 );
|
||||
|
||||
MusicTracks whichMusicPlaying();
|
||||
|
||||
static Mixer & mixer();
|
||||
};
|
||||
|
||||
#endif //#define MIXER_HH
|
||||
@@ -1,183 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
using namespace std;
|
||||
|
||||
#include "options.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
Options::Options(const string lFilename) {
|
||||
if (lFilename == "") {
|
||||
cout << "Options: no filename given!" << endl;
|
||||
filename = string("config");
|
||||
} else {
|
||||
// save the filename for later use
|
||||
filename = lFilename;
|
||||
}
|
||||
|
||||
// open the file for reading
|
||||
ifstream inputFile (filename.c_str(), ios::in);
|
||||
|
||||
// TODO FIXME ordentliches Filelocking machen
|
||||
// fcntl(inputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_RDLCK));
|
||||
|
||||
if (inputFile.good()) {
|
||||
// while still data there
|
||||
while (!inputFile.eof()) {
|
||||
string newLine;
|
||||
getline( inputFile, newLine );
|
||||
// search delimiter
|
||||
unsigned int pos = newLine.find("=");
|
||||
// comment line or no delimiter found
|
||||
if (( newLine[0] != '#' ) && ( pos != string::npos )) {
|
||||
string key = newLine.substr(0,pos);
|
||||
string val = newLine.substr(pos+1);
|
||||
keymap[ key ] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << "Options: Error while opening " << filename << endl;
|
||||
}
|
||||
|
||||
// TODO FIXME ordentliches Filelocking machen
|
||||
// fcntl(inputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_UNLCK));
|
||||
|
||||
inputFile.close();
|
||||
// if (inputFile.fail()) {
|
||||
// cout << "Options: Error while closing " << filename << endl;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
Options::~Options() {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
// flock* Options::fileLock(const short type) {
|
||||
// static flock ret ;
|
||||
// ret.l_type = type ;
|
||||
// ret.l_start = 0 ;
|
||||
// ret.l_whence = SEEK_SET ;
|
||||
// ret.l_len = 0 ;
|
||||
// ret.l_pid = getpid() ;
|
||||
// return &ret ;
|
||||
// }
|
||||
|
||||
|
||||
int Options::saveFile( const string lFilename ) {
|
||||
// alternative filename given ?
|
||||
if (lFilename != "") {
|
||||
filename = lFilename;
|
||||
}
|
||||
|
||||
// delete original options-file
|
||||
remove(filename.c_str());
|
||||
|
||||
ofstream outputFile( filename.c_str(), ios::out );
|
||||
|
||||
// TODO FIXME ordentliches Filelocking machen
|
||||
// fcntl(outputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_WRLCK));
|
||||
|
||||
if (outputFile.good()) {
|
||||
map< string, string >::const_iterator iter;
|
||||
for(iter = keymap.begin(); iter != keymap.end(); iter++){
|
||||
outputFile << iter->first << "=" << iter->second << endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << "Options::saveFile(): error while opening file " << filename << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO FIXME ordentliches Filelocking machen
|
||||
// fcntl(outputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_UNLCK));
|
||||
|
||||
outputFile.close();
|
||||
if (!outputFile.good()) {
|
||||
cout << "Options::saveFile(): error while closing file " << filename << endl;
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0; // everything's fine
|
||||
}
|
||||
|
||||
|
||||
bool Options::exist(const string keyword) {
|
||||
return (keymap.find(keyword) != keymap.end());
|
||||
}
|
||||
|
||||
|
||||
bool Options::getStr(const string keyword, string &val) {
|
||||
if (exist(keyword)) {
|
||||
val = keymap[keyword];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Options::getInt(const string keyword, int &val) {
|
||||
if (exist(keyword)) {
|
||||
val = atoi( keymap[keyword].c_str() );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Options::getUInt(const string keyword, unsigned int &val) {
|
||||
if (exist(keyword)) {
|
||||
val = atoll( keymap[keyword].c_str() );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Options::setStr(const string newValue, const string keyword) {
|
||||
keymap[keyword] = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Options::setInt(const int newValue, const string keyword) {
|
||||
keymap[keyword] = asString( newValue );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Options::setUInt(const unsigned int newValue, const string keyword) {
|
||||
keymap[keyword] = asString( newValue );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Options::printall() {
|
||||
map< string, string >::const_iterator iter;
|
||||
for(iter = keymap.begin(); iter != keymap.end(); iter++){
|
||||
cout << iter->first << "=" << iter->second << endl;
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
* @file Options.h
|
||||
* @brief The Options-class can manage a configuration file.
|
||||
* @date 23.06.02
|
||||
* The Options-class can manage a configuration file of this style:
|
||||
* KEYWORD=value
|
||||
* Provides easy-access functions for the keywords.
|
||||
* $Id: options.h,v 1.2 2003/12/08 18:21:21 schwardt Exp $
|
||||
*/
|
||||
|
||||
#ifndef __OPTIONS_H__
|
||||
#define __OPTIONS_H__
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "asstring.h"
|
||||
|
||||
class Options {
|
||||
|
||||
private:
|
||||
std::map< std::string, std::string > keymap;
|
||||
std::string filename;
|
||||
|
||||
public:
|
||||
/// Constructor. Reads the configurationfile specified by lFilename.
|
||||
Options( const std::string lFilename );
|
||||
/// Destructor. Frees all memory allocated.
|
||||
~Options();
|
||||
|
||||
/// Returns structure used for filelocking
|
||||
// flock* Options::fileLock(const short type); // FIXME
|
||||
/// Returns true if the given keyword exist
|
||||
bool exist(const std::string keyword);
|
||||
/// Returns the int value of keyword.
|
||||
/// If keyword is not found returns 0.
|
||||
bool getInt( const std::string keyword, int &val );
|
||||
/// Returns the unsigned int value of keyword.
|
||||
/// If keyword is not found returns 0.
|
||||
bool getUInt( const std::string keyword, unsigned int &val );
|
||||
/// Returns a copy of the char* value of keyword.
|
||||
/// If keyword is not found returns NULL.
|
||||
bool getStr( const std::string keyword, std::string &val );
|
||||
|
||||
/// sets the value of the given keyword to newValue
|
||||
bool setInt( const int newValue, const std::string keyword );
|
||||
/// sets the value of the given keyword to newValue
|
||||
bool setUInt( const unsigned int newValue, const std::string keyword );
|
||||
/// sets the value of the given keyword to newValue
|
||||
bool setStr( const std::string newValue, const std::string keyword );
|
||||
|
||||
/// Stores the config-File to disk (filename as specified in the constructor).
|
||||
/// You should call this function after changing a value.
|
||||
int saveFile( const std::string lFilename );
|
||||
|
||||
/// Prints all lines of the actual configuration to cout.
|
||||
void printall();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,195 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef RACER_HH
|
||||
#define RACER_HH
|
||||
|
||||
#include "SDL.h"
|
||||
#include "geometry.h"
|
||||
#include <string>
|
||||
#include "global.h"
|
||||
#include "settings.h"
|
||||
|
||||
class SurfaceDB;
|
||||
class Gate;
|
||||
class Track;
|
||||
class Shot;
|
||||
class Shots;
|
||||
class Items;
|
||||
class Font;
|
||||
class BoundingBox;
|
||||
class ShieldGlow;
|
||||
|
||||
|
||||
/* The Racer is the vehicle, that the player can steer. */
|
||||
class Racer {
|
||||
|
||||
SdlCompat_AcceleratedSurface *spriteRacerBase;
|
||||
SDL_Rect drawRectBase;
|
||||
SdlCompat_AcceleratedSurface *spriteShadow;
|
||||
SdlCompat_AcceleratedSurface *spriteDeflector;
|
||||
SDL_Rect drawRectDeflector;
|
||||
SdlCompat_AcceleratedSurface *spriteHPStat;
|
||||
SdlCompat_AcceleratedSurface *spriteFighterIcon;
|
||||
|
||||
// for collision with other racers or shots.
|
||||
// A rectangle with racersize * 0.9 is used.
|
||||
BoundingBox *boundingBox;
|
||||
|
||||
int playerNr;
|
||||
int shipType;
|
||||
|
||||
Font *font; // font used for displaying ammo and lapcnt
|
||||
int fontSize;
|
||||
SdlCompat_AcceleratedSurface *spriteSecondaryWeapons;
|
||||
SdlCompat_AcceleratedSurface *spriteSpecials;
|
||||
|
||||
int sndShotPrimary;
|
||||
int sndShotSecondary;
|
||||
|
||||
float points;
|
||||
|
||||
// Movement-System
|
||||
Vector2D pos; // absolute position
|
||||
float shipAngle; // the orientation
|
||||
Vector2D vel; // the velocity vector
|
||||
// the boundary of the world (i.e. the reachable section of the screen)
|
||||
RectangleGeo *boundaryRect;
|
||||
|
||||
// Weapon-System
|
||||
ShotTypes primaryShotType;
|
||||
Uint32 timeLastShotPrimary;
|
||||
|
||||
ShotTypes activeSecondary;
|
||||
Uint32 timeLastShotSecondary;
|
||||
bool secondaryWeaponsAvailability[ NR_SECONDARY_WEAPONS ];
|
||||
bool lastDumbfireWasLeft;
|
||||
|
||||
SpecialTypes activeSpecial;
|
||||
int specialsAvailability[ NR_SPECIALS ];
|
||||
Uint32 timeLastNukeUsed;
|
||||
Uint32 timeLastHeatseekerUsed;
|
||||
bool lastHeatseekerWasLeft;
|
||||
|
||||
bool deflectorActive;
|
||||
int deflectorTimeLeft;
|
||||
|
||||
// Damage-System
|
||||
float shield;
|
||||
float damage;
|
||||
float pixPerHP;
|
||||
float maxShield;
|
||||
float maxDamage;
|
||||
// not used at the moment:
|
||||
// returns the maximum reachable velocity.
|
||||
// if damage < 100 the reachable velocity will be reduced linearly
|
||||
float getActVelMax();
|
||||
float maxVel;
|
||||
// needed for displaying the shield glow, when hit
|
||||
Uint32 shieldDamageEndTime;
|
||||
bool shieldDamageActive;
|
||||
ShieldGlow *shieldGlow;
|
||||
|
||||
Uint32 timeLastMove;
|
||||
|
||||
void repair( float amount );
|
||||
|
||||
bool thrust;
|
||||
bool backwards;
|
||||
bool left;
|
||||
bool right;
|
||||
bool fireWeapons;
|
||||
bool useSpecial;
|
||||
|
||||
void addBannerItemCollected( BannerTexts text );
|
||||
|
||||
public:
|
||||
// Input-System - which keys are pressed at the moment
|
||||
void handlePlayerEvent( PlayerEvent pEvent, bool keyDown );
|
||||
|
||||
Racer( string fnSprite, int whichPlayer, Vector2D startpos, int newShipType );
|
||||
~Racer();
|
||||
|
||||
bool isDeflectorSpecialActive() { return deflectorActive; }
|
||||
inline int getPlayerNr() { return playerNr; }
|
||||
inline int getShipType() { return shipType; }
|
||||
void setPos( const Vector2D &newPos );
|
||||
inline Vector2D getPos() { return pos; }
|
||||
inline Vector2D getVel() { return vel; }
|
||||
Vector2D setVel( const Vector2D &newVel ); // returns old vel
|
||||
|
||||
// moves the racer according to his velocity and the pressed keys.
|
||||
// Already collides with the boundaryRect (the border of the world)
|
||||
Vector2D move( int dT );
|
||||
void clipWorld();
|
||||
// move the boundingBox accordingly to the movement
|
||||
void updateBoundingBox();
|
||||
|
||||
// fire the Guns!
|
||||
void shootPrimary();
|
||||
void shootSecondary();
|
||||
void shootSpecial();
|
||||
// switch to the next available weapon
|
||||
// void switchPrimary();
|
||||
void switchSecondary();
|
||||
void switchSpecials();
|
||||
|
||||
// use the active special, if it should be used _once_ when keyDown-Event occurs
|
||||
void specialKeyDown();
|
||||
// switch special, if the activespecial is out of ammo
|
||||
void specialKeyUp();
|
||||
|
||||
void drawRacer( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawShadow( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawStats( SdlCompat_AcceleratedSurface *screen );
|
||||
|
||||
// collision system
|
||||
// return if the line between the two points collides with the boundingBox
|
||||
bool collidesWith( const Vector2D &shotPosOld, const Vector2D &shotPosNew );
|
||||
// return if the racers boundingBox overlaps with box
|
||||
bool collidesWith( BoundingBox *box );
|
||||
// return if the racers boundingBox overlaps with circle
|
||||
bool collidesWith( const Circle &circle );
|
||||
// returns if a inner circle around the racer overlaps with circle
|
||||
bool collidesWithAsCircle( const Circle &circle );
|
||||
// returns if a inner circle around the racer overlaps with circle
|
||||
bool collidesWithAsCircle( BoundingBox *box );
|
||||
// returns the boundingBox of the racer
|
||||
BoundingBox *getBoundingBox();
|
||||
|
||||
// the racer got hit -> do the damage according to the shotType
|
||||
void doDamage( ShotTypes shotType );
|
||||
// recharge the shield
|
||||
void rechargeShield( int dT );
|
||||
// the racer was hit
|
||||
void receiveDamage( float amount );
|
||||
|
||||
bool isDead();
|
||||
|
||||
|
||||
void receivePoints( float amount );
|
||||
|
||||
// picks up items, if flown over
|
||||
void pickUpItems();
|
||||
|
||||
// returns the number of laps completed by the racer
|
||||
int getPoints() { return (int)(points + 0.5); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,204 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#include <iostream>
|
||||
#include "racer.h"
|
||||
#include "racers.h"
|
||||
#include "shots.h"
|
||||
#include "items.h"
|
||||
#include "enemys.h"
|
||||
#include "enemy.h"
|
||||
#include "explosions.h"
|
||||
#include "explosion.h"
|
||||
#include "global.h"
|
||||
|
||||
Racers::Racers() {
|
||||
pointsInArcadeMode = 0;
|
||||
}
|
||||
|
||||
Racers::~Racers() {
|
||||
vector<Racer *>::iterator i;
|
||||
for ( i = racers.begin(); i != racers.end(); ++i ) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
bool Racers::isShipTypeActive( int shipType ) {
|
||||
vector<Racer *>::iterator i;
|
||||
for ( i = racers.begin(); i != racers.end(); ++i ) {
|
||||
if ( (*i)->getShipType() == shipType ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Racer *Racers::getRacer( unsigned int i ) {
|
||||
return racers[i];
|
||||
}
|
||||
|
||||
void Racers::addRacer( Racer *racer ) {
|
||||
if (racer) {
|
||||
racers.push_back(racer);
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::deleteRacers() {
|
||||
racers.clear();
|
||||
}
|
||||
|
||||
void Racers::collideWithEnemys() {
|
||||
for ( unsigned int i = 0; i < racers.size(); ++i ) {
|
||||
for ( unsigned int j = 0; j < enemys->getNrEnemys(); ++j ) {
|
||||
|
||||
// wurde noch nicht von einem anderen Racer gerammt und fliegt ebenfalls
|
||||
if ( !(enemys->getEnemy( j )->isExpired()) &&
|
||||
ENEMY_FLYING[ enemys->getEnemy( j )->getType() ] ) {
|
||||
// kollidiert
|
||||
if ( racers[i]->collidesWithAsCircle( enemys->getEnemy( j )->getBoundingCircle() ) ) {
|
||||
// explosion
|
||||
Explosion *newExplosion =
|
||||
new Explosion( FN_EXPLOSION_ENEMY, enemys->getEnemy( j )->getPos(), enemys->getEnemy( j )->getVel(), EXPLOSION_NORMAL_AIR );
|
||||
explosions->addExplosion( newExplosion );
|
||||
enemys->getEnemy( j )->expire();
|
||||
racers[i]->receiveDamage( ENEMY_COLLISION_DAMAGE[ enemys->getEnemy( j )->getType() ]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::moveAndCollide( int dT ) {
|
||||
for ( unsigned int i = 0; i < racers.size(); ++i ) {
|
||||
racers[i]->move( dT );
|
||||
collideWithEnemys();
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::pickUpItems() {
|
||||
vector<Racer *>::iterator i;
|
||||
for ( i = racers.begin(); i != racers.end(); ++i ) {
|
||||
(*i)->pickUpItems();
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::shoot() {
|
||||
for ( unsigned int i = 0; i < racers.size(); i++ ) {
|
||||
racers[i]->shootPrimary();
|
||||
racers[i]->shootSecondary();
|
||||
racers[i]->shootSpecial();
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::rechargeShield( int dT ) {
|
||||
vector<Racer *>::iterator i;
|
||||
for (i = racers.begin(); i != racers.end(); ++i) {
|
||||
(*i)->rechargeShield( dT );
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::drawRacers( SdlCompat_AcceleratedSurface *screen ) {
|
||||
vector<Racer *>::iterator i;
|
||||
for (i = racers.begin(); i != racers.end(); ++i) {
|
||||
(*i)->drawRacer(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::drawShadows( SdlCompat_AcceleratedSurface *screen ) {
|
||||
vector<Racer *>::iterator i;
|
||||
for (i = racers.begin(); i != racers.end(); ++i) {
|
||||
(*i)->drawShadow(screen);
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::drawStats( SdlCompat_AcceleratedSurface *screen ) {
|
||||
vector<Racer *>::iterator i;
|
||||
for (i = racers.begin(); i != racers.end(); ++i) {
|
||||
(*i)->drawStats(screen);
|
||||
}
|
||||
}
|
||||
|
||||
bool Racers::bothPlayersLost() {
|
||||
bool allLost = true;
|
||||
for ( unsigned int i = 0; i < racers.size(); ++i) {
|
||||
if ( !racers[i]->isDead() ) {
|
||||
allLost = false;
|
||||
}
|
||||
}
|
||||
return allLost;
|
||||
}
|
||||
|
||||
void Racers::receivePointsArcade( float amount ) {
|
||||
for ( unsigned int i = 0; i < racers.size(); ++i) {
|
||||
racers[i]->receivePoints( amount );
|
||||
}
|
||||
}
|
||||
|
||||
int Racers::getPointsArcadeMode() {
|
||||
if (!arcadeGame) return -1;
|
||||
if (!racers.empty()) {
|
||||
return racers[0]->getPoints();
|
||||
}
|
||||
else return pointsInArcadeMode;
|
||||
}
|
||||
|
||||
void Racers::expireRacers() {
|
||||
unsigned int i = 0;
|
||||
while ( i < racers.size() ) {
|
||||
if ( racers[i]->isDead() ) {
|
||||
// explode
|
||||
Explosion *newExplosion =
|
||||
new Explosion( FN_EXPLOSION_ENEMY, racers[i]->getPos(),
|
||||
racers[i]->getVel(), EXPLOSION_NORMAL_AIR );
|
||||
explosions->addExplosion( newExplosion );
|
||||
|
||||
if ( arcadeGame ) pointsInArcadeMode = racers[i]->getPoints();
|
||||
|
||||
delete racers[i];
|
||||
racers.erase(racers.begin() + i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::getKeyActionMaps() {
|
||||
playerKeys0 = settings->getPlayerKeys( 0 );
|
||||
playerKeys1 = settings->getPlayerKeys( 1 );
|
||||
}
|
||||
|
||||
void Racers::handleEvent( const SDLKey key, const bool pressed ) {
|
||||
PlayerEvent pEvent0 = playerKeys0[ key ];
|
||||
if ( pEvent0 != PE_UNKNOWN ) {
|
||||
handlePlayerEvent( pEvent0, 0, pressed );
|
||||
}
|
||||
PlayerEvent pEvent1 = playerKeys1[ key ];
|
||||
if ( pEvent1 != PE_UNKNOWN ) {
|
||||
handlePlayerEvent( pEvent1, 1, pressed );
|
||||
}
|
||||
}
|
||||
|
||||
void Racers::handlePlayerEvent( PlayerEvent pEvent, int playerNr, bool keyDown ) {
|
||||
for ( unsigned int i = 0; i < racers.size(); i++ )
|
||||
if ( racers[i]->getPlayerNr() == playerNr )
|
||||
racers[i]->handlePlayerEvent( pEvent, keyDown );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/***************************************************************************
|
||||
alienBlaster
|
||||
Copyright (C) 2004
|
||||
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
***************************************************************************/
|
||||
#ifndef RACER_H
|
||||
#define RACER_H
|
||||
|
||||
#include <vector>
|
||||
#include "SDL.h"
|
||||
#include "settings.h"
|
||||
|
||||
class Racer;
|
||||
class Shots;
|
||||
class Items;
|
||||
class Enemys;
|
||||
class Explosions;
|
||||
|
||||
/* A class, that manages the individual racers.
|
||||
It is used for everything, that the racers are capable of doing.
|
||||
*/
|
||||
class Racers {
|
||||
vector<Racer *> racers;
|
||||
|
||||
// points reached by racer 0 in arcade mode
|
||||
int pointsInArcadeMode;
|
||||
|
||||
void collideWithEnemys();
|
||||
|
||||
PlayerKeys playerKeys0;
|
||||
PlayerKeys playerKeys1;
|
||||
|
||||
public:
|
||||
|
||||
Racers();
|
||||
~Racers();
|
||||
|
||||
bool isShipTypeActive( int shipType );
|
||||
|
||||
void addRacer( Racer *racer );
|
||||
void deleteRacers();
|
||||
Racer *getRacer(unsigned int i);
|
||||
unsigned int getNrRacers() { return racers.size(); }
|
||||
|
||||
// Moves the racers. Calculates collisions between the racers and
|
||||
// collisions between a racer and enemies.
|
||||
void moveAndCollide( int dT );
|
||||
|
||||
// Checks if a racer has picked up an item by flying over it.
|
||||
void pickUpItems();
|
||||
// Checks if a racer was at his pitstop and is being repaired.
|
||||
// void repair( PitStops *pitStops );
|
||||
// Lets the racers shoot, if they want to.
|
||||
void shoot();
|
||||
// recharge the shields
|
||||
void rechargeShield( int dT );
|
||||
// draws the racers.
|
||||
void drawRacers( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawShadows( SdlCompat_AcceleratedSurface *screen );
|
||||
void drawStats( SdlCompat_AcceleratedSurface *screen );
|
||||
|
||||
// returns, which racer has shot more enemys
|
||||
//int getWinner();
|
||||
|
||||
void expireRacers();
|
||||
|
||||
bool bothPlayersLost();
|
||||
|
||||
void receivePointsArcade( float amount );
|
||||
int getPointsArcadeMode();
|
||||
|
||||
void getKeyActionMaps();
|
||||
void handleEvent( const SDLKey key, const bool pressed );
|
||||
private:
|
||||
void handlePlayerEvent( PlayerEvent pEvent, int playerNr, bool keyDown );
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user