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"]
|
[submodule "project/jni/iconv/src"]
|
||||||
path = project/jni/iconv/src
|
path = project/jni/iconv/src
|
||||||
url = https://github.com/pelya/libiconv-libicu-android.git
|
url = https://github.com/pelya/libiconv-libicu-android.git
|
||||||
@@ -42,48 +7,6 @@
|
|||||||
path = project/jni/application/openttd/src
|
path = project/jni/application/openttd/src
|
||||||
url = https://github.com/n-ice-community/openttd-android.git
|
url = https://github.com/n-ice-community/openttd-android.git
|
||||||
branch = 12
|
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"]
|
[submodule "project/jni/sdl2"]
|
||||||
path = project/jni/sdl2
|
path = project/jni/sdl2
|
||||||
url = https://github.com/libsdl-org/SDL.git
|
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