Repository: Rinnegatamante/vitaQuake
Branch: master
Commit: fbe7c5e7fe77
Files: 176
Total size: 1.4 MB
Directory structure:
gitextract_5ojh867z/
├── .gitattributes
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── LICENSE.txt
├── Makefile
├── README.md
├── build/
│ ├── sce_sys/
│ │ └── livearea/
│ │ └── contents/
│ │ └── template.xml
│ └── shaders/
│ ├── modulate_alpha_f.gxp
│ ├── modulate_alpha_fog_f.gxp
│ ├── modulate_f.gxp
│ ├── modulate_fog_f.gxp
│ ├── modulate_rgba_alpha_f.gxp
│ ├── modulate_rgba_alpha_fog_f.gxp
│ ├── modulate_rgba_f.gxp
│ ├── modulate_rgba_fog_f.gxp
│ ├── replace_alpha_f.gxp
│ ├── replace_alpha_fog_f.gxp
│ ├── replace_f.gxp
│ ├── replace_fog_f.gxp
│ ├── rgba_alpha_f.gxp
│ ├── rgba_f.gxp
│ ├── rgba_v.gxp
│ ├── texture2d_fog_v.gxp
│ ├── texture2d_rgba_fog_v.gxp
│ ├── texture2d_rgba_v.gxp
│ ├── texture2d_v.gxp
│ ├── vertex_f.gxp
│ └── vertex_v.gxp
├── shaders/
│ ├── modulate_alpha_f.cg
│ ├── modulate_alpha_fog_f.cg
│ ├── modulate_f.cg
│ ├── modulate_fog_f.cg
│ ├── modulate_rgba_alpha_f.cg
│ ├── modulate_rgba_alpha_fog_f.cg
│ ├── modulate_rgba_f.cg
│ ├── modulate_rgba_fog_f.cg
│ ├── replace_alpha_f.cg
│ ├── replace_alpha_fog_f.cg
│ ├── replace_f.cg
│ ├── replace_fog_f.cg
│ ├── rgba_alpha_f.cg
│ ├── rgba_f.cg
│ ├── rgba_v.cg
│ ├── texture2d_fog_v.cg
│ ├── texture2d_rgba_fog_v.cg
│ ├── texture2d_rgba_v.cg
│ ├── texture2d_v.cg
│ ├── vertex_f.cg
│ └── vertex_v.cg
└── source/
├── adivtab.h
├── anorm_dots.h
├── anorms.h
├── asm_draw.h
├── asm_i386.h
├── audiodec/
│ ├── audio_decoder.cpp
│ ├── audio_decoder.h
│ ├── audio_resampler.cpp
│ ├── audio_resampler.h
│ ├── cd_psp2.cpp
│ ├── decoder_mpg123.cpp
│ ├── decoder_mpg123.h
│ ├── decoder_oggvorbis.cpp
│ └── decoder_oggvorbis.h
├── block16.h
├── block8.h
├── bspfile.h
├── cdaudio.h
├── chase.c
├── cl_demo.c
├── cl_input.c
├── cl_main.c
├── cl_parse.c
├── cl_tent.c
├── client.h
├── cmd.c
├── cmd.h
├── common.c
├── common.h
├── console.c
├── console.h
├── crc.c
├── crc.h
├── cvar.c
├── cvar.h
├── draw.h
├── gl_draw.cpp
├── gl_fullbright.c
├── gl_fullbright.h
├── gl_mesh.c
├── gl_model.c
├── gl_model.h
├── gl_refrag.c
├── gl_rlight.c
├── gl_rmain.c
├── gl_rmisc.c
├── gl_rsurf.c
├── gl_screen.c
├── gl_vidpsp2.c
├── gl_warp.c
├── gl_warp_sin.h
├── glquake.h
├── glquake2.h
├── host.c
├── host_cmd.c
├── image.c
├── image.h
├── in_psp2.c
├── input.h
├── keys.c
├── keys.h
├── mathlib.c
├── mathlib.h
├── menu.c
├── menu.h
├── model.h
├── modelgen.h
├── mpdosock.h
├── neon_mathfun.c
├── neon_mathfun.h
├── net.h
├── net_adhoc.h
├── net_adhoc_psp2.c
├── net_dgrm.c
├── net_dgrm.h
├── net_loop.c
├── net_loop.h
├── net_main.c
├── net_none.c
├── net_psp2.c
├── net_udp.h
├── net_udp_psp2.c
├── net_vcr.c
├── net_vcr.h
├── nonintel.c
├── pr_cmds.c
├── pr_comp.h
├── pr_edict.c
├── pr_exec.c
├── progdefs.h
├── progdefs.q1
├── progdefs.q2
├── progs.h
├── protocol.h
├── quakeasm.h
├── quakedef.h
├── r_local.h
├── r_part.c
├── r_shared.h
├── render.h
├── sbar.c
├── sbar.h
├── screen.h
├── server.h
├── snd_dma.c
├── snd_mem.c
├── snd_mix.c
├── snd_psp2.c
├── sound.h
├── spritegn.h
├── sv_main.c
├── sv_move.c
├── sv_phys.c
├── sv_user.c
├── sys.h
├── sys_psp2.c
├── vid.h
├── view.c
├── view.h
├── wad.c
├── wad.h
├── webdownload.c
├── webdownload.h
├── world.c
├── world.h
├── zone.c
└── zone.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
================================================
FILE: .github/FUNDING.yml
================================================
patreon: Rinnegatamante
================================================
FILE: .gitignore
================================================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# c object files and other build files
*.o
*.elf
build/eboot.bin
build/sce_sys/param.sfo
buildeboot.bin
param.sfo
*.velf
*.vpk
================================================
FILE: LICENSE.txt
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. 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
them 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 prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. 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.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey 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;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU 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 that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
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.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
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.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
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
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
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 3 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, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program 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, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU 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 Lesser General
Public License instead of this License. But first, please read
.
================================================
FILE: Makefile
================================================
TARGET := vitaQuake
TITLE := QUAK00001
GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags)
SHADERS := shaders
LIBS = -lvitaGL -lvitashark -lSceShaccCgExt -ltaihen_stub -lvorbisfile -lvorbis -logg \
-lspeexdsp -lmpg123 -lScePspnetAdhoc_stub -lSceShaccCg_stub -lSceKernelDmacMgr_stub \
-lc -lSceCommonDialog_stub -lSceAudio_stub -lSceLibKernel_stub -lmathneon \
-lSceNet_stub -lSceNetCtl_stub -lpng -lSceDisplay_stub -lSceGxm_stub \
-Wl,--whole-archive -lSceSysmodule_stub -Wl,--no-whole-archive \
-lSceCtrl_stub -lSceTouch_stub -lSceMotion_stub -lm -lSceAppMgr_stub \
-lSceAppUtil_stub -lScePgf_stub -ljpeg -lSceRtc_stub -lScePower_stub -lcurl -lssl -lcrypto -lz
COMMON_OBJS = source/chase.o \
source/cl_demo.o \
source/cl_input.o \
source/cl_main.o \
source/cl_parse.o \
source/cl_tent.o \
source/chase.o \
source/cmd.o \
source/common.o \
source/console.o \
source/crc.o \
source/cvar.o \
source/host.o \
source/host_cmd.o \
source/image.o \
source/keys.o \
source/mathlib.o \
source/menu.o \
source/net_dgrm.o \
source/net_loop.o \
source/net_main.o \
source/net_vcr.o \
source/pr_cmds.o \
source/pr_edict.o \
source/pr_exec.o \
source/r_part.o \
source/sbar.o \
source/sv_main.o \
source/sv_move.o \
source/sv_phys.o \
source/sv_user.o \
source/view.o \
source/wad.o \
source/world.o \
source/zone.o \
source/sys_psp2.o \
source/gl_draw.o \
source/gl_mesh.o \
source/gl_model.o \
source/gl_refrag.o \
source/gl_rlight.o \
source/gl_rmain.o \
source/gl_rmisc.o \
source/gl_rsurf.o \
source/gl_screen.o \
source/gl_warp.o \
source/gl_fullbright.o \
source/r_part.o \
source/snd_dma.o \
source/snd_mix.o \
source/snd_mem.o \
source/snd_psp2.o \
source/net_psp2.o \
source/net_adhoc_psp2.o \
source/net_udp_psp2.o \
source/in_psp2.o \
source/gl_vidpsp2.o \
source/neon_mathfun.o \
source/webdownload.o
CPPSOURCES := source/audiodec
CFILES := $(COMMON_OBJS)
CPPFILES := $(foreach dir,$(CPPSOURCES), $(wildcard $(dir)/*.cpp))
CGFILES := $(foreach dir,$(SHADERS), $(wildcard $(dir)/*.cg))
CGSHADERS := $(CGFILES:.cg=.h)
OBJS := $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++
CFLAGS = -fsigned-char -Wl,-q -O3 -g -fno-optimize-sibling-calls \
-ffast-math -mtune=cortex-a9 -mfpu=neon \
-DGLQUAKE -DHAVE_OGGVORBIS -DHAVE_MPG123 -DHAVE_LIBSPEEXDSP \
-DUSE_AUDIO_RESAMPLER -DGIT_VERSION=\"$(GIT_VERSION)\"
CXXFLAGS = $(CFLAGS) -fno-exceptions -std=gnu++11
ASFLAGS = $(CFLAGS)
all: $(TARGET).vpk
$(TARGET).vpk: $(TARGET).velf
vita-make-fself -c -s $< build/eboot.bin
vita-mksfoex -s TITLE_ID=$(TITLE) -d ATTRIBUTE2=12 "$(TARGET)" param.sfo
cp -f param.sfo build/sce_sys/param.sfo
vita-pack-vpk -s param.sfo -b build/eboot.bin $(TARGET).vpk \
-a build/shaders=shaders \
-a build/sce_sys=sce_sys
%_f.h:
psp2cgc -profile sce_fp_psp2 $(@:_f.h=_f.cg) -Wperf -fastprecision -O3 -o build/$(@:_f.h=_f.gxp)
%_v.h:
psp2cgc -profile sce_vp_psp2 $(@:_v.h=_v.cg) -Wperf -fastprecision -O3 -o build/$(@:_v.h=_v.gxp)
shaders: $(CGSHADERS)
%.velf: %.elf
cp $< $<.unstripped.elf
$(PREFIX)-strip -g $<
vita-elf-create $< $@
$(TARGET).elf: $(OBJS)
$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
clean:
@rm -rf $(TARGET).velf $(TARGET).elf $(OBJS) $(TARGET).elf.unstripped.elf $(TARGET).vpk build/eboot.bin build/sce_sys/param.sfo ./param.sfo
================================================
FILE: README.md
================================================
# Introduction
vitaQuake is a Quake engine source port for PSVITA.
An official channel to discuss the development of this source port can be found on [Vita Nuova discord server](https://discord.gg/PyCaBx9).
# Features
- Hardware accelerated GPU rendering
- Native 960x544 resolution
- Rendering resolution up to 1920x1080 on the PSTV with [Sharpscale](https://git.shotatoshounenwachigau.moe/vita/sharpscale)
- MSAA 2x and MSAA 4x support
- Dual analogs support
- Native IME for inputing commands/text
- Sounds and Musics (CDTracks) support in OGG, MP3, WAV formats
- Gyroscope and touchscreen support for camera movement
- Custom arguments support and mods support
- Support for both official missionpacks
- Support for transparent surfaces (.alpha and .renderamt)
- Increased Quake Engine limits (max vertices, max entities, max static entities, etc...)
- LAN Multiplayer support (locale and online)
- AdHoc Multiplayer support
- ProQuake net protocol support
- Savegames fully working
- Support for colored lights with .lit files support
- Support for Half-Life BSP
- Supprt for BSP2 and 2BSP formats
- Smooth animations thanks to interpolation techniques
- Crosshair and custom crosshairs support
- Mirrors support
- Specular mode support
- Fog support
- Cel Shading support
- Bilinear filtering support
- Dynamic shadows support
- Several different improvements in the renderer quality
- Several different miscellaneous features (eg: transparent statusbar, benchmark feature, working gamma, etc...)
- Map downloader support if you try to join an online server and you don't own the running map
# Supported DarkPlaces extensions
- DP_CON_SET
- DP_CON_SETA
- DP_EF_BLUE
- DP_EF_NODRAW
- DP_EF_RED
- DP_ENT_ALPHA
- DP_GFX_EXTERNALTEXTURES
- DP_GFX_EXTERNALTEXTURES_PERMAPTEXTURES
- DP_HALFLIFE_MAP
- DP_LITSUPPORT
- DP_QC_ASINACOSATANATAN2TAN
- DP_QC_COPYENTITY
- DP_QC_CVAR_STRING
- DP_QC_EDICT_NUM
- DP_QC_ETOS
- DP_QC_FINDCHAIN
- DP_QC_FINDCHAINFLOAT
- DP_QC_MINMAXBOUND
- DP_QC_NUM_FOR_EDICT
- DP_QC_RANDOMVEC
- DP_QC_SINCOSSQRTPOW
- DP_QC_TRACEBOX
- DP_SND_FAKETRACKS
- DP_SV_MODELFLAGS_AS_EFFECTS
- DP_SV_NODRAWTOCLIENT
- DP_SV_DRAWONLYTOCLIENT
- EXT_BITSHIFT
- FRIK_FILE
# CDAudio Support
vitaQuake supports all soundtrack packs for Quake and its two official mission packs, "Scourge of Armagon" and "Dissolution of Eternity." In order for the soundtrack to work, files must be placed in a folder named /cdtracks/ in each campaign folder (main game for example will be ux0:data/Quake/id1/cdtracks).
By default, the music folder has tracks named as track02, track03, etc. For vitaQuake, add an extra "0" after "track" in order for them to be loaded properly and in order. **Ex.: track02 -> track002**
You can find the official soundtrack for the main campaign in .ogg format [here](https://www.quaddicted.com/files/music/quake_music.zip).
# Loading Expansions and Mods
vitaQuake supports the official Quake expansions, "Scourge of Armagon" and "Dissolution of Eternity." These were offical expansions, so they can be found usually wherever the full base game is sold (GOG, Steam). In order to get them to load properly, place them in the "ux0:/data/quake/" folder alongside "id1".
Both official mission packs support their own soundtracks as long as they are placed properly in their respective "/cdtracks/" folder.
Mod compatibility is varied, but as a general rule of thumb, mods compatible with winQuake will be compatible with vitaQuake.
Here's a list of some popular mods and their actual working state:
Expansion/Mod | Link | Status
---|---|---|
Dissolution of Eternity | Official Expansion |  `Fully Working`
dopa | [Free](https://twitter.com/machinegames/status/746363189768650752?lang=en) |  `Fully Working`
Halo Revamped | [Free](https://wololo.net/downloads/index.php/download/1376) |  `Boots, lots of bugs`
Kurok | [Free](http://www.bladebattles.com/kurok/) |  `Playable with glitches`
Nazi Zombies Portable | [Free](https://www.moddb.com/games/nazi-zombies-portable/news/nazi-zombies-portable-ps-vita-info) |  `Not Working`
Quake Rally | [Free](https://www.moddb.com/mods/quake-rally) |  `Fully Working`
Scourge of Armagon | Official Expansion |  `Fully Working`
Slayer's Testament | [Free](https://www.youtube.com/watch?v=abn9aCiJ3pY) |  `Crash on models loading`
SUPERHOT Quake | [Free](https://www.moddb.com/mods/superhot-quake) |  `Working without monochromatic graphics`
SUPERQOT | [Free](https://superhotgame.com/SUPERQOT/) |  `Not Working`
YPOD | [Free](https://www.quakewiki.net/archives/doom/) |  `Fully Working`
# Credits
- idSoftware for winQuake sourcecode
- MasterFeizz for ctrQuake sourcecode i studied to understand how winQuake works
- EasyRPG Team for the audio decoder used for CDAudio support
- Ch0wW for various improvements and code cleanup
- JPG for ProQuake and some various fixes.
- Cuevavirus for 1920x1080 rendering
================================================
FILE: build/sce_sys/livearea/contents/template.xml
================================================
bg.png
startup.png
psla:-hipnotic
hipnotic.png
psla:-rogue
rogue.png
psla:-custom
Click here to launch with custom args
================================================
FILE: shaders/modulate_alpha_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
uniform float4 vColor,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord) * vColor;
if (c.a > 0.666) return c;
else discard;
}
================================================
FILE: shaders/modulate_alpha_fog_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float vFog : FOG,
uniform float4 vColor,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord) * vColor;
c.rgb = c.rgb * vFog;
if (c.a > 0.666) return c;
else discard;
}
================================================
FILE: shaders/modulate_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
uniform float4 vColor,
uniform sampler2D tex
)
{
return tex2D(tex, vTexcoord) * vColor;
}
================================================
FILE: shaders/modulate_fog_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float vFog : FOG,
uniform float4 vColor,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord) * vColor;
c.rgb = c.rgb * vFog;
return c;
}
================================================
FILE: shaders/modulate_rgba_alpha_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float4 vColor : COLOR,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord) * vColor;
if (c.a > 0.666) return c;
else discard;
}
================================================
FILE: shaders/modulate_rgba_alpha_fog_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float vFog : FOG,
float4 vColor : COLOR,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord) * vColor;
c.rgb = c.rgb * vFog;
if (c.a > 0.666) return c;
else discard;
}
================================================
FILE: shaders/modulate_rgba_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float4 vColor : COLOR,
uniform sampler2D tex
)
{
return tex2D(tex, vTexcoord) * vColor;
}
================================================
FILE: shaders/modulate_rgba_fog_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float vFog : FOG,
float4 vColor : COLOR,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord) * vColor;
c.rgb = c.rgb * vFog;
return c;
}
================================================
FILE: shaders/replace_alpha_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord);
if (c.a > 0.666) return c;
else discard;
}
================================================
FILE: shaders/replace_alpha_fog_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float vFog : FOG,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord);
c.rgb = c.rgb * vFog;
if (c.a > 0.666) return c;
else discard;
}
================================================
FILE: shaders/replace_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
uniform sampler2D tex
)
{
return tex2D(tex, vTexcoord);
}
================================================
FILE: shaders/replace_fog_f.cg
================================================
float4 main(
float2 vTexcoord : TEXCOORD0,
float vFog : FOG,
uniform sampler2D tex
)
{
float4 c = tex2D(tex, vTexcoord);
c.rgb = c.rgb * vFog;
return c;
}
================================================
FILE: shaders/rgba_alpha_f.cg
================================================
float4 main(float4 vColor : COLOR) : COLOR
{
if (vColor.a > 0.666) return vColor;
else discard;
}
================================================
FILE: shaders/rgba_f.cg
================================================
float4 main(float4 vColor : COLOR) : COLOR
{
return vColor;
}
================================================
FILE: shaders/rgba_v.cg
================================================
void main(
float3 aPosition,
float4 aColor,
uniform float4x4 gl_ModelViewProjectionMatrix,
float4 out vPosition: POSITION,
float4 out vColor: COLOR)
{
vPosition = mul(gl_ModelViewProjectionMatrix, float4(aPosition, 1.f));
vColor = aColor;
}
================================================
FILE: shaders/texture2d_fog_v.cg
================================================
void main(
float3 position,
float2 texcoord,
uniform float4x4 gl_ModelViewProjectionMatrix,
float4 out vPosition : POSITION,
float out vFog : FOG,
float2 out vTexcoord : TEXCOORD0)
{
vPosition = mul(gl_ModelViewProjectionMatrix, float4(position, 1.f));
float dist = distance(vPosition,float4(0.0,0.0,0.0,1.0));
vFog = ((512.0 - dist) / (512.0));
vTexcoord = texcoord;
}
================================================
FILE: shaders/texture2d_rgba_fog_v.cg
================================================
void main(
float3 position,
float2 texcoord,
float4 color,
uniform float4x4 gl_ModelViewProjectionMatrix,
float4 out vPosition : POSITION,
float out vFog : FOG,
float2 out vTexcoord : TEXCOORD0,
float4 out vColor : COLOR)
{
vPosition = mul(gl_ModelViewProjectionMatrix, float4(position, 1.f));
float dist = distance(vPosition,float4(0.0,0.0,0.0,1.0));
vFog = ((512.0 - dist) / (512.0));
vTexcoord = texcoord;
vColor = color;
}
================================================
FILE: shaders/texture2d_rgba_v.cg
================================================
void main(
float3 position,
float2 texcoord,
float4 color,
uniform float4x4 gl_ModelViewProjectionMatrix,
float4 out vPosition : POSITION,
float2 out vTexcoord : TEXCOORD0,
float4 out vColor : COLOR)
{
vPosition = mul(gl_ModelViewProjectionMatrix, float4(position, 1.f));
vTexcoord = texcoord;
vColor = color;
}
================================================
FILE: shaders/texture2d_v.cg
================================================
void main(
float3 position,
float2 texcoord,
uniform float4x4 gl_ModelViewProjectionMatrix,
float4 out vPosition : POSITION,
float2 out vTexcoord : TEXCOORD0)
{
vPosition = mul(gl_ModelViewProjectionMatrix, float4(position, 1.f));
vTexcoord = texcoord;
}
================================================
FILE: shaders/vertex_f.cg
================================================
float4 main(uniform float4 color) : COLOR
{
return color;
}
================================================
FILE: shaders/vertex_v.cg
================================================
void main(
float3 aPosition,
uniform float4x4 gl_ModelViewProjectionMatrix,
float4 out vPosition: POSITION)
{
vPosition = mul(gl_ModelViewProjectionMatrix, float4(aPosition, 1.f));
}
================================================
FILE: source/adivtab.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
// table of quotients and remainders for [-15...16] / [-15...16]
// numerator = -15
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{1, -5},
{1, -6},
{1, -7},
{2, -1},
{2, -3},
{3, 0},
{3, -3},
{5, 0},
{7, -1},
{15, 0},
{0, 0},
{-15, 0},
{-8, 1},
{-5, 0},
{-4, 1},
{-3, 0},
{-3, 3},
{-3, 6},
{-2, 1},
{-2, 3},
{-2, 5},
{-2, 7},
{-2, 9},
{-2, 11},
{-2, 13},
{-1, 0},
{-1, 1},
// numerator = -14
{0, -14},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{1, -5},
{1, -6},
{2, 0},
{2, -2},
{2, -4},
{3, -2},
{4, -2},
{7, 0},
{14, 0},
{0, 0},
{-14, 0},
{-7, 0},
{-5, 1},
{-4, 2},
{-3, 1},
{-3, 4},
{-2, 0},
{-2, 2},
{-2, 4},
{-2, 6},
{-2, 8},
{-2, 10},
{-2, 12},
{-1, 0},
{-1, 1},
{-1, 2},
// numerator = -13
{0, -13},
{0, -13},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{1, -5},
{1, -6},
{2, -1},
{2, -3},
{3, -1},
{4, -1},
{6, -1},
{13, 0},
{0, 0},
{-13, 0},
{-7, 1},
{-5, 2},
{-4, 3},
{-3, 2},
{-3, 5},
{-2, 1},
{-2, 3},
{-2, 5},
{-2, 7},
{-2, 9},
{-2, 11},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
// numerator = -12
{0, -12},
{0, -12},
{0, -12},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{1, -5},
{2, 0},
{2, -2},
{3, 0},
{4, 0},
{6, 0},
{12, 0},
{0, 0},
{-12, 0},
{-6, 0},
{-4, 0},
{-3, 0},
{-3, 3},
{-2, 0},
{-2, 2},
{-2, 4},
{-2, 6},
{-2, 8},
{-2, 10},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
// numerator = -11
{0, -11},
{0, -11},
{0, -11},
{0, -11},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{1, -5},
{2, -1},
{2, -3},
{3, -2},
{5, -1},
{11, 0},
{0, 0},
{-11, 0},
{-6, 1},
{-4, 1},
{-3, 1},
{-3, 4},
{-2, 1},
{-2, 3},
{-2, 5},
{-2, 7},
{-2, 9},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
// numerator = -10
{0, -10},
{0, -10},
{0, -10},
{0, -10},
{0, -10},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{2, 0},
{2, -2},
{3, -1},
{5, 0},
{10, 0},
{0, 0},
{-10, 0},
{-5, 0},
{-4, 2},
{-3, 2},
{-2, 0},
{-2, 2},
{-2, 4},
{-2, 6},
{-2, 8},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
// numerator = -9
{0, -9},
{0, -9},
{0, -9},
{0, -9},
{0, -9},
{0, -9},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{1, -4},
{2, -1},
{3, 0},
{4, -1},
{9, 0},
{0, 0},
{-9, 0},
{-5, 1},
{-3, 0},
{-3, 3},
{-2, 1},
{-2, 3},
{-2, 5},
{-2, 7},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
// numerator = -8
{0, -8},
{0, -8},
{0, -8},
{0, -8},
{0, -8},
{0, -8},
{0, -8},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{2, 0},
{2, -2},
{4, 0},
{8, 0},
{0, 0},
{-8, 0},
{-4, 0},
{-3, 1},
{-2, 0},
{-2, 2},
{-2, 4},
{-2, 6},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
// numerator = -7
{0, -7},
{0, -7},
{0, -7},
{0, -7},
{0, -7},
{0, -7},
{0, -7},
{0, -7},
{1, 0},
{1, -1},
{1, -2},
{1, -3},
{2, -1},
{3, -1},
{7, 0},
{0, 0},
{-7, 0},
{-4, 1},
{-3, 2},
{-2, 1},
{-2, 3},
{-2, 5},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
// numerator = -6
{0, -6},
{0, -6},
{0, -6},
{0, -6},
{0, -6},
{0, -6},
{0, -6},
{0, -6},
{0, -6},
{1, 0},
{1, -1},
{1, -2},
{2, 0},
{3, 0},
{6, 0},
{0, 0},
{-6, 0},
{-3, 0},
{-2, 0},
{-2, 2},
{-2, 4},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
{-1, 10},
// numerator = -5
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{0, -5},
{1, 0},
{1, -1},
{1, -2},
{2, -1},
{5, 0},
{0, 0},
{-5, 0},
{-3, 1},
{-2, 1},
{-2, 3},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
{-1, 10},
{-1, 11},
// numerator = -4
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{0, -4},
{1, 0},
{1, -1},
{2, 0},
{4, 0},
{0, 0},
{-4, 0},
{-2, 0},
{-2, 2},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
{-1, 10},
{-1, 11},
{-1, 12},
// numerator = -3
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{0, -3},
{1, 0},
{1, -1},
{3, 0},
{0, 0},
{-3, 0},
{-2, 1},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
{-1, 10},
{-1, 11},
{-1, 12},
{-1, 13},
// numerator = -2
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{0, -2},
{1, 0},
{2, 0},
{0, 0},
{-2, 0},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
{-1, 10},
{-1, 11},
{-1, 12},
{-1, 13},
{-1, 14},
// numerator = -1
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{0, -1},
{1, 0},
{0, 0},
{-1, 0},
{-1, 1},
{-1, 2},
{-1, 3},
{-1, 4},
{-1, 5},
{-1, 6},
{-1, 7},
{-1, 8},
{-1, 9},
{-1, 10},
{-1, 11},
{-1, 12},
{-1, 13},
{-1, 14},
{-1, 15},
// numerator = 0
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
// numerator = 1
{-1, -14},
{-1, -13},
{-1, -12},
{-1, -11},
{-1, -10},
{-1, -9},
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{0, 0},
{1, 0},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
{0, 1},
// numerator = 2
{-1, -13},
{-1, -12},
{-1, -11},
{-1, -10},
{-1, -9},
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, 0},
{0, 0},
{2, 0},
{1, 0},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
{0, 2},
// numerator = 3
{-1, -12},
{-1, -11},
{-1, -10},
{-1, -9},
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -1},
{-3, 0},
{0, 0},
{3, 0},
{1, 1},
{1, 0},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
{0, 3},
// numerator = 4
{-1, -11},
{-1, -10},
{-1, -9},
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -2},
{-2, 0},
{-4, 0},
{0, 0},
{4, 0},
{2, 0},
{1, 1},
{1, 0},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
{0, 4},
// numerator = 5
{-1, -10},
{-1, -9},
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -3},
{-2, -1},
{-3, -1},
{-5, 0},
{0, 0},
{5, 0},
{2, 1},
{1, 2},
{1, 1},
{1, 0},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
{0, 5},
// numerator = 6
{-1, -9},
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -4},
{-2, -2},
{-2, 0},
{-3, 0},
{-6, 0},
{0, 0},
{6, 0},
{3, 0},
{2, 0},
{1, 2},
{1, 1},
{1, 0},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
{0, 6},
// numerator = 7
{-1, -8},
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -5},
{-2, -3},
{-2, -1},
{-3, -2},
{-4, -1},
{-7, 0},
{0, 0},
{7, 0},
{3, 1},
{2, 1},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 7},
{0, 7},
{0, 7},
{0, 7},
{0, 7},
{0, 7},
{0, 7},
{0, 7},
{0, 7},
// numerator = 8
{-1, -7},
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -6},
{-2, -4},
{-2, -2},
{-2, 0},
{-3, -1},
{-4, 0},
{-8, 0},
{0, 0},
{8, 0},
{4, 0},
{2, 2},
{2, 0},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 8},
{0, 8},
{0, 8},
{0, 8},
{0, 8},
{0, 8},
{0, 8},
{0, 8},
// numerator = 9
{-1, -6},
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -7},
{-2, -5},
{-2, -3},
{-2, -1},
{-3, -3},
{-3, 0},
{-5, -1},
{-9, 0},
{0, 0},
{9, 0},
{4, 1},
{3, 0},
{2, 1},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 9},
{0, 9},
{0, 9},
{0, 9},
{0, 9},
{0, 9},
{0, 9},
// numerator = 10
{-1, -5},
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -8},
{-2, -6},
{-2, -4},
{-2, -2},
{-2, 0},
{-3, -2},
{-4, -2},
{-5, 0},
{-10, 0},
{0, 0},
{10, 0},
{5, 0},
{3, 1},
{2, 2},
{2, 0},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 10},
{0, 10},
{0, 10},
{0, 10},
{0, 10},
{0, 10},
// numerator = 11
{-1, -4},
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -9},
{-2, -7},
{-2, -5},
{-2, -3},
{-2, -1},
{-3, -4},
{-3, -1},
{-4, -1},
{-6, -1},
{-11, 0},
{0, 0},
{11, 0},
{5, 1},
{3, 2},
{2, 3},
{2, 1},
{1, 5},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 11},
{0, 11},
{0, 11},
{0, 11},
{0, 11},
// numerator = 12
{-1, -3},
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -10},
{-2, -8},
{-2, -6},
{-2, -4},
{-2, -2},
{-2, 0},
{-3, -3},
{-3, 0},
{-4, 0},
{-6, 0},
{-12, 0},
{0, 0},
{12, 0},
{6, 0},
{4, 0},
{3, 0},
{2, 2},
{2, 0},
{1, 5},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 12},
{0, 12},
{0, 12},
{0, 12},
// numerator = 13
{-1, -2},
{-1, -1},
{-1, 0},
{-2, -11},
{-2, -9},
{-2, -7},
{-2, -5},
{-2, -3},
{-2, -1},
{-3, -5},
{-3, -2},
{-4, -3},
{-5, -2},
{-7, -1},
{-13, 0},
{0, 0},
{13, 0},
{6, 1},
{4, 1},
{3, 1},
{2, 3},
{2, 1},
{1, 6},
{1, 5},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 13},
{0, 13},
{0, 13},
// numerator = 14
{-1, -1},
{-1, 0},
{-2, -12},
{-2, -10},
{-2, -8},
{-2, -6},
{-2, -4},
{-2, -2},
{-2, 0},
{-3, -4},
{-3, -1},
{-4, -2},
{-5, -1},
{-7, 0},
{-14, 0},
{0, 0},
{14, 0},
{7, 0},
{4, 2},
{3, 2},
{2, 4},
{2, 2},
{2, 0},
{1, 6},
{1, 5},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 14},
{0, 14},
// numerator = 15
{-1, 0},
{-2, -13},
{-2, -11},
{-2, -9},
{-2, -7},
{-2, -5},
{-2, -3},
{-2, -1},
{-3, -6},
{-3, -3},
{-3, 0},
{-4, -1},
{-5, 0},
{-8, -1},
{-15, 0},
{0, 0},
{15, 0},
{7, 1},
{5, 0},
{3, 3},
{3, 0},
{2, 3},
{2, 1},
{1, 7},
{1, 6},
{1, 5},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
{0, 15},
// numerator = 16
{-2, -14},
{-2, -12},
{-2, -10},
{-2, -8},
{-2, -6},
{-2, -4},
{-2, -2},
{-2, 0},
{-3, -5},
{-3, -2},
{-4, -4},
{-4, 0},
{-6, -2},
{-8, 0},
{-16, 0},
{0, 0},
{16, 0},
{8, 0},
{5, 1},
{4, 0},
{3, 1},
{2, 4},
{2, 2},
{2, 0},
{1, 7},
{1, 6},
{1, 5},
{1, 4},
{1, 3},
{1, 2},
{1, 1},
{1, 0},
================================================
FILE: source/anorm_dots.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
{
{1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
{1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}
}
================================================
FILE: source/anorms.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
{-0.525731, 0.000000, 0.850651},
{-0.442863, 0.238856, 0.864188},
{-0.295242, 0.000000, 0.955423},
{-0.309017, 0.500000, 0.809017},
{-0.162460, 0.262866, 0.951056},
{0.000000, 0.000000, 1.000000},
{0.000000, 0.850651, 0.525731},
{-0.147621, 0.716567, 0.681718},
{0.147621, 0.716567, 0.681718},
{0.000000, 0.525731, 0.850651},
{0.309017, 0.500000, 0.809017},
{0.525731, 0.000000, 0.850651},
{0.295242, 0.000000, 0.955423},
{0.442863, 0.238856, 0.864188},
{0.162460, 0.262866, 0.951056},
{-0.681718, 0.147621, 0.716567},
{-0.809017, 0.309017, 0.500000},
{-0.587785, 0.425325, 0.688191},
{-0.850651, 0.525731, 0.000000},
{-0.864188, 0.442863, 0.238856},
{-0.716567, 0.681718, 0.147621},
{-0.688191, 0.587785, 0.425325},
{-0.500000, 0.809017, 0.309017},
{-0.238856, 0.864188, 0.442863},
{-0.425325, 0.688191, 0.587785},
{-0.716567, 0.681718, -0.147621},
{-0.500000, 0.809017, -0.309017},
{-0.525731, 0.850651, 0.000000},
{0.000000, 0.850651, -0.525731},
{-0.238856, 0.864188, -0.442863},
{0.000000, 0.955423, -0.295242},
{-0.262866, 0.951056, -0.162460},
{0.000000, 1.000000, 0.000000},
{0.000000, 0.955423, 0.295242},
{-0.262866, 0.951056, 0.162460},
{0.238856, 0.864188, 0.442863},
{0.262866, 0.951056, 0.162460},
{0.500000, 0.809017, 0.309017},
{0.238856, 0.864188, -0.442863},
{0.262866, 0.951056, -0.162460},
{0.500000, 0.809017, -0.309017},
{0.850651, 0.525731, 0.000000},
{0.716567, 0.681718, 0.147621},
{0.716567, 0.681718, -0.147621},
{0.525731, 0.850651, 0.000000},
{0.425325, 0.688191, 0.587785},
{0.864188, 0.442863, 0.238856},
{0.688191, 0.587785, 0.425325},
{0.809017, 0.309017, 0.500000},
{0.681718, 0.147621, 0.716567},
{0.587785, 0.425325, 0.688191},
{0.955423, 0.295242, 0.000000},
{1.000000, 0.000000, 0.000000},
{0.951056, 0.162460, 0.262866},
{0.850651, -0.525731, 0.000000},
{0.955423, -0.295242, 0.000000},
{0.864188, -0.442863, 0.238856},
{0.951056, -0.162460, 0.262866},
{0.809017, -0.309017, 0.500000},
{0.681718, -0.147621, 0.716567},
{0.850651, 0.000000, 0.525731},
{0.864188, 0.442863, -0.238856},
{0.809017, 0.309017, -0.500000},
{0.951056, 0.162460, -0.262866},
{0.525731, 0.000000, -0.850651},
{0.681718, 0.147621, -0.716567},
{0.681718, -0.147621, -0.716567},
{0.850651, 0.000000, -0.525731},
{0.809017, -0.309017, -0.500000},
{0.864188, -0.442863, -0.238856},
{0.951056, -0.162460, -0.262866},
{0.147621, 0.716567, -0.681718},
{0.309017, 0.500000, -0.809017},
{0.425325, 0.688191, -0.587785},
{0.442863, 0.238856, -0.864188},
{0.587785, 0.425325, -0.688191},
{0.688191, 0.587785, -0.425325},
{-0.147621, 0.716567, -0.681718},
{-0.309017, 0.500000, -0.809017},
{0.000000, 0.525731, -0.850651},
{-0.525731, 0.000000, -0.850651},
{-0.442863, 0.238856, -0.864188},
{-0.295242, 0.000000, -0.955423},
{-0.162460, 0.262866, -0.951056},
{0.000000, 0.000000, -1.000000},
{0.295242, 0.000000, -0.955423},
{0.162460, 0.262866, -0.951056},
{-0.442863, -0.238856, -0.864188},
{-0.309017, -0.500000, -0.809017},
{-0.162460, -0.262866, -0.951056},
{0.000000, -0.850651, -0.525731},
{-0.147621, -0.716567, -0.681718},
{0.147621, -0.716567, -0.681718},
{0.000000, -0.525731, -0.850651},
{0.309017, -0.500000, -0.809017},
{0.442863, -0.238856, -0.864188},
{0.162460, -0.262866, -0.951056},
{0.238856, -0.864188, -0.442863},
{0.500000, -0.809017, -0.309017},
{0.425325, -0.688191, -0.587785},
{0.716567, -0.681718, -0.147621},
{0.688191, -0.587785, -0.425325},
{0.587785, -0.425325, -0.688191},
{0.000000, -0.955423, -0.295242},
{0.000000, -1.000000, 0.000000},
{0.262866, -0.951056, -0.162460},
{0.000000, -0.850651, 0.525731},
{0.000000, -0.955423, 0.295242},
{0.238856, -0.864188, 0.442863},
{0.262866, -0.951056, 0.162460},
{0.500000, -0.809017, 0.309017},
{0.716567, -0.681718, 0.147621},
{0.525731, -0.850651, 0.000000},
{-0.238856, -0.864188, -0.442863},
{-0.500000, -0.809017, -0.309017},
{-0.262866, -0.951056, -0.162460},
{-0.850651, -0.525731, 0.000000},
{-0.716567, -0.681718, -0.147621},
{-0.716567, -0.681718, 0.147621},
{-0.525731, -0.850651, 0.000000},
{-0.500000, -0.809017, 0.309017},
{-0.238856, -0.864188, 0.442863},
{-0.262866, -0.951056, 0.162460},
{-0.864188, -0.442863, 0.238856},
{-0.809017, -0.309017, 0.500000},
{-0.688191, -0.587785, 0.425325},
{-0.681718, -0.147621, 0.716567},
{-0.442863, -0.238856, 0.864188},
{-0.587785, -0.425325, 0.688191},
{-0.309017, -0.500000, 0.809017},
{-0.147621, -0.716567, 0.681718},
{-0.425325, -0.688191, 0.587785},
{-0.162460, -0.262866, 0.951056},
{0.442863, -0.238856, 0.864188},
{0.162460, -0.262866, 0.951056},
{0.309017, -0.500000, 0.809017},
{0.147621, -0.716567, 0.681718},
{0.000000, -0.525731, 0.850651},
{0.425325, -0.688191, 0.587785},
{0.587785, -0.425325, 0.688191},
{0.688191, -0.587785, 0.425325},
{-0.955423, 0.295242, 0.000000},
{-0.951056, 0.162460, 0.262866},
{-1.000000, 0.000000, 0.000000},
{-0.850651, 0.000000, 0.525731},
{-0.955423, -0.295242, 0.000000},
{-0.951056, -0.162460, 0.262866},
{-0.864188, 0.442863, -0.238856},
{-0.951056, 0.162460, -0.262866},
{-0.809017, 0.309017, -0.500000},
{-0.864188, -0.442863, -0.238856},
{-0.951056, -0.162460, -0.262866},
{-0.809017, -0.309017, -0.500000},
{-0.681718, 0.147621, -0.716567},
{-0.681718, -0.147621, -0.716567},
{-0.850651, 0.000000, -0.525731},
{-0.688191, 0.587785, -0.425325},
{-0.587785, 0.425325, -0.688191},
{-0.425325, 0.688191, -0.587785},
{-0.425325, -0.688191, -0.587785},
{-0.587785, -0.425325, -0.688191},
{-0.688191, -0.587785, -0.425325},
================================================
FILE: source/asm_draw.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
//
// asm_draw.h
//
// Include file for asm drawing routines.
//
//
// !!! note that this file must match the corresponding C structures at all
// times !!!
//
// !!! if this is changed, it must be changed in r_local.h too !!!
#define NEAR_CLIP 0.01
// !!! if this is changed, it must be changed in r_local.h too !!!
#define CYCLE 128
// espan_t structure
// !!! if this is changed, it must be changed in r_shared.h too !!!
#define espan_t_u 0
#define espan_t_v 4
#define espan_t_count 8
#define espan_t_pnext 12
#define espan_t_size 16
// sspan_t structure
// !!! if this is changed, it must be changed in d_local.h too !!!
#define sspan_t_u 0
#define sspan_t_v 4
#define sspan_t_count 8
#define sspan_t_size 12
// spanpackage_t structure
// !!! if this is changed, it must be changed in d_polyset.c too !!!
#define spanpackage_t_pdest 0
#define spanpackage_t_pz 4
#define spanpackage_t_count 8
#define spanpackage_t_ptex 12
#define spanpackage_t_sfrac 16
#define spanpackage_t_tfrac 20
#define spanpackage_t_light 24
#define spanpackage_t_zi 28
#define spanpackage_t_size 32
// edge_t structure
// !!! if this is changed, it must be changed in r_shared.h too !!!
#define et_u 0
#define et_u_step 4
#define et_prev 8
#define et_next 12
#define et_surfs 16
#define et_nextremove 20
#define et_nearzi 24
#define et_owner 28
#define et_size 32
// surf_t structure
// !!! if this is changed, it must be changed in r_shared.h too !!!
#define SURF_T_SHIFT 6
#define st_next 0
#define st_prev 4
#define st_spans 8
#define st_key 12
#define st_last_u 16
#define st_spanstate 20
#define st_flags 24
#define st_data 28
#define st_entity 32
#define st_nearzi 36
#define st_insubmodel 40
#define st_d_ziorigin 44
#define st_d_zistepu 48
#define st_d_zistepv 52
#define st_pad 56
#define st_size 64
// clipplane_t structure
// !!! if this is changed, it must be changed in r_local.h too !!!
#define cp_normal 0
#define cp_dist 12
#define cp_next 16
#define cp_leftedge 20
#define cp_rightedge 21
#define cp_reserved 22
#define cp_size 24
// medge_t structure
// !!! if this is changed, it must be changed in model.h too !!!
#define me_v 0
#define me_cachededgeoffset 4
#define me_size 8
// mvertex_t structure
// !!! if this is changed, it must be changed in model.h too !!!
#define mv_position 0
#define mv_size 12
// refdef_t structure
// !!! if this is changed, it must be changed in render.h too !!!
#define rd_vrect 0
#define rd_aliasvrect 20
#define rd_vrectright 40
#define rd_vrectbottom 44
#define rd_aliasvrectright 48
#define rd_aliasvrectbottom 52
#define rd_vrectrightedge 56
#define rd_fvrectx 60
#define rd_fvrecty 64
#define rd_fvrectx_adj 68
#define rd_fvrecty_adj 72
#define rd_vrect_x_adj_shift20 76
#define rd_vrectright_adj_shift20 80
#define rd_fvrectright_adj 84
#define rd_fvrectbottom_adj 88
#define rd_fvrectright 92
#define rd_fvrectbottom 96
#define rd_horizontalFieldOfView 100
#define rd_xOrigin 104
#define rd_yOrigin 108
#define rd_vieworg 112
#define rd_viewangles 124
#define rd_ambientlight 136
#define rd_size 140
// mtriangle_t structure
// !!! if this is changed, it must be changed in model.h too !!!
#define mtri_facesfront 0
#define mtri_vertindex 4
#define mtri_size 16 // !!! if this changes, array indexing in !!!
// !!! d_polysa.s must be changed to match !!!
#define mtri_shift 4
================================================
FILE: source/asm_i386.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
#ifndef __ASM_I386__
#define __ASM_I386__
#ifdef ELF
#define C(label) label
#else
#define C(label) _##label
#endif
//
// !!! note that this file must match the corresponding C structures at all
// times !!!
//
// plane_t structure
// !!! if this is changed, it must be changed in model.h too !!!
// !!! if the size of this is changed, the array lookup in SV_HullPointContents
// must be changed too !!!
#define pl_normal 0
#define pl_dist 12
#define pl_type 16
#define pl_signbits 17
#define pl_pad 18
#define pl_size 20
// hull_t structure
// !!! if this is changed, it must be changed in model.h too !!!
#define hu_clipnodes 0
#define hu_planes 4
#define hu_firstclipnode 8
#define hu_lastclipnode 12
#define hu_clip_mins 16
#define hu_clip_maxs 28
#define hu_size 40
// dnode_t structure
// !!! if this is changed, it must be changed in bspfile.h too !!!
#define nd_planenum 0
#define nd_children 4
#define nd_mins 8
#define nd_maxs 20
#define nd_firstface 32
#define nd_numfaces 36
#define nd_size 40
// sfxcache_t structure
// !!! if this is changed, it much be changed in sound.h too !!!
#define sfxc_length 0
#define sfxc_loopstart 4
#define sfxc_speed 8
#define sfxc_width 12
#define sfxc_stereo 16
#define sfxc_data 20
// channel_t structure
// !!! if this is changed, it much be changed in sound.h too !!!
#define ch_sfx 0
#define ch_leftvol 4
#define ch_rightvol 8
#define ch_end 12
#define ch_pos 16
#define ch_looping 20
#define ch_entnum 24
#define ch_entchannel 28
#define ch_origin 32
#define ch_dist_mult 44
#define ch_master_vol 48
#define ch_size 52
// portable_samplepair_t structure
// !!! if this is changed, it much be changed in sound.h too !!!
#define psp_left 0
#define psp_right 4
#define psp_size 8
#endif
================================================
FILE: source/audiodec/audio_decoder.cpp
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
// Headers
#include
#include
#include "audio_decoder.h"
#include "decoder_mpg123.h"
#include "decoder_oggvorbis.h"
#include "audio_resampler.h"
void AudioDecoder::Pause() {
paused = true;
}
void AudioDecoder::Resume() {
paused = false;
}
int AudioDecoder::Decode(uint8_t* buffer, int length) {
if (paused) {
memset(buffer, '\0', length);
return length;
}
int res = FillBuffer(buffer, length);
if (res < 0) {
memset(buffer, '\0', length);
} else if (res < length) {
memset(&buffer[res], '\0', length - res);
}
if (IsFinished() && looping) {
++loop_count;
Rewind();
if (length - res > 0) {
int res2 = Decode(&buffer[res], length - res);
if (res2 <= 0) {
return res;
}
return res + res2;
}
}
return res;
}
int AudioDecoder::DecodeAsMono(uint8_t* left, uint8_t* right, int size) {
int freq; Format format; int channels;
GetFormat(freq, format, channels);
if (channels == 1) {
return Decode(left, size);
}
if ((int)mono_buffer.size() < size * 2) {
mono_buffer.resize(size * 2);
}
int read = Decode(mono_buffer.data(), size * 2);
if (read < 0) {
memset(left, '\0', size);
memset(right, '\0', size);
return -1;
}
int sample_size = GetSamplesizeForFormat(format);
for (int i = 0; i <= read / 2; i += sample_size) {
memcpy(&left[i], &mono_buffer.data()[i * channels], sample_size);
memcpy(&right[i], &mono_buffer.data()[i * channels + sample_size], sample_size);
}
if (read < size / 2) {
memset(&left[read / 2], '\0', size);
memset(&right[read / 2], '\0', size);
}
return read / 2;
}
class WMAUnsupportedFormatDecoder : public AudioDecoder {
public:
WMAUnsupportedFormatDecoder() {
error_message = std::string("WMA audio files are not supported. Reinstall the\n") +
"game and don't convert them when asked by Windows!\n";
}
bool Open(FILE*) override { return false; }
bool IsFinished() const override { return true; }
void GetFormat(int&, Format&, int&) const override {}
private:
int FillBuffer(uint8_t*, int) override { return -1; };
};
const char wma_magic[] = { (char)0x30, (char)0x26, (char)0xB2, (char)0x75 };
std::unique_ptr AudioDecoder::Create(FILE* file, const std::string& filename) {
char magic[4] = { 0 };
fread(magic, 4, 1, file);
fseek(file, 0, SEEK_SET);
// Try to use MIDI decoder, use fallback(s) if available
if (!strncmp(magic, "MThd", 4)) {
#ifdef HAVE_WILDMIDI
static bool wildmidi_works = true;
if (wildmidi_works) {
AudioDecoder *mididec = nullptr;
# ifdef USE_AUDIO_RESAMPLER
mididec = new AudioResampler(new WildMidiDecoder(filename));
# else
mididec = new WildMidiDecoder(filename);
# endif
if (mididec) {
if (mididec->WasInited())
return std::unique_ptr(mididec);
delete mididec;
}
wildmidi_works = false;
}
#endif
#if WANT_FMMIDI == 1
# ifdef USE_AUDIO_RESAMPLER
return std::unique_ptr(new AudioResampler(new FmMidiDecoder(), true, AudioResampler::Quality::Low));
# else
return std::unique_ptr(new FmMidiDecoder());
# endif
#endif
// No MIDI decoder available
return nullptr;
}
// Try to use internal OGG decoder
if (!strncmp(magic, "OggS", 4)) { // OGG
#if defined(HAVE_TREMOR) || defined(HAVE_OGGVORBIS)
# ifdef USE_AUDIO_RESAMPLER
return std::unique_ptr(new AudioResampler(new OggVorbisDecoder()));
# else
return std::unique_ptr(new OggVorbisDecoder());
# endif
#endif
}
#ifdef HAVE_SLOW_CPU
// Try to use a basic decoder for faster wav decoding if not ADPCM
if (!strncmp(magic, "RIFF", 4)){
fseek(file, 20, SEEK_SET);
uint16_t raw_enc;
fread(&raw_enc, 2, 1, file);
fseek(file, 0, SEEK_SET);
if (raw_enc == 0x01){ // Codec is normal PCM
# ifdef USE_AUDIO_RESAMPLER
return std::unique_ptr(new AudioResampler(new WavDecoder()));
# else
return std::unique_ptr(new WavDecoder());
# endif
}
}
#endif
// Try to use libsndfile for common formats
if (!strncmp(magic, "RIFF", 4) || // WAV
!strncmp(magic, "FORM", 4) || // WAV AIFF
!strncmp(magic, "OggS", 4) || // OGG
!strncmp(magic, "fLaC", 4)) { // FLAC
#ifdef HAVE_LIBSNDFILE
# ifdef USE_AUDIO_RESAMPLER
return std::unique_ptr(new AudioResampler(new LibsndfileDecoder()));
# else
return std::unique_ptr(new LibsndfileDecoder());
# endif
#endif
return nullptr;
}
// Inform about WMA issue
if (!memcmp(magic, wma_magic, 4)) {
return std::unique_ptr(new WMAUnsupportedFormatDecoder());
}
// False positive MP3s should be prevented before by checking for common headers
#ifdef HAVE_MPG123
static bool mpg123_works = true;
if (mpg123_works) {
AudioDecoder *mp3dec = nullptr;
if (strncmp(magic, "ID3", 3) == 0) {
# ifdef USE_AUDIO_RESAMPLER
mp3dec = new AudioResampler(new Mpg123Decoder());
# else
mp3dec = new Mpg123Decoder();
# endif
if (mp3dec) {
if (mp3dec->WasInited())
return std::unique_ptr(mp3dec);
delete mp3dec;
}
mpg123_works = false;
return nullptr;
}
// Parsing MP3s seems to be the only reliable way to detect them
if (Mpg123Decoder::IsMp3(file)) {
fseek(file, 0, SEEK_SET);
# ifdef USE_AUDIO_RESAMPLER
mp3dec = new AudioResampler(new Mpg123Decoder());
# else
mp3dec = new Mpg123Decoder();
# endif
if (mp3dec) {
if(mp3dec->WasInited())
return std::unique_ptr(mp3dec);
delete mp3dec;
}
mpg123_works = false;
return nullptr;
}
}
#endif
fseek(file, 0, SEEK_SET);
return nullptr;
}
void AudioDecoder::SetFade(int begin, int end, int duration) {
fade_time = 0.0;
if (duration <= 0.0) {
volume = end;
return;
}
if (begin == end) {
volume = end;
return;
}
volume = (double)begin;
fade_end = (double)end;
fade_time = (double)duration;
delta_step = (fade_end - volume) / fade_time;
}
void AudioDecoder::Update(int delta) {
if (fade_time <= 0.0) {
return;
}
fade_time -= delta;
volume += delta * delta_step;
volume = volume > 100.0 ? 100.0 :
volume < 0.0 ? 0.0 :
volume;
}
void AudioDecoder::SetVolume(int volume) {
this->volume = (double)volume;
}
int AudioDecoder::GetVolume() const {
return (int)volume;
}
void AudioDecoder::Rewind() {
if (!Seek(0, Origin::Begin)) {
// The libs guarantee that Rewind works
assert(false && "Rewind");
}
}
bool AudioDecoder::GetLooping() const {
return looping;
}
void AudioDecoder::SetLooping(bool enable) {
looping = enable;
}
int AudioDecoder::GetLoopCount() const {
return loop_count;
}
bool AudioDecoder::WasInited() const {
return true;
}
std::string AudioDecoder::GetError() const {
return error_message;
}
std::string AudioDecoder::GetType() const {
return music_type;
}
bool AudioDecoder::SetFormat(int, Format, int) {
return false;
}
int AudioDecoder::GetPitch() const {
return 0;
}
bool AudioDecoder::SetPitch(int) {
return false;
}
bool AudioDecoder::Seek(size_t, Origin) {
return false;
}
size_t AudioDecoder::Tell() const {
return -1;
}
int AudioDecoder::GetTicks() const {
return 0;
}
int AudioDecoder::GetSamplesizeForFormat(AudioDecoder::Format format) {
switch (format) {
case Format::S8:
case Format::U8:
return 1;
case Format::S16:
case Format::U16:
return 2;
case Format::S32:
case Format::U32:
case Format::F32:
return 4;
}
assert(false && "Bad format");
return -1;
}
================================================
FILE: source/audiodec/audio_decoder.h
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#ifndef EASYRPG_AUDIO_DECODER_H
#define EASYRPG_AUDIO_DECODER_H
// Headers
#include
#include
#include
#include
/**
* The AudioDecoder class provides an abstraction over the decoding of
* common audio formats.
* Create will instantitate a proper audio decoder and calling Decode will
* fill a buffer with audio data which must be passed to the audio hardware.
*/
class AudioDecoder {
public:
virtual ~AudioDecoder() {}
/** Sample format */
enum class Format {
S8,
U8,
S16,
U16,
S32,
U32,
F32
};
/** Seek origin for Seek command */
enum class Origin {
Begin = 0,
Current = 1,
End = 2
};
/**
* Writes 'size' bytes in the specified buffer. The data matches the format
* reported by GetFormat.
* When size is is smaller then the amount of written bytes or an error occurs
* the remaining buffer space is cleared.
*
* @param buffer Output buffer
* @param size Size of the buffer in bytes
* @return Number of bytes written to the buffer or -1 on error
*/
int Decode(uint8_t* buffer, int size);
/**
* Splits stereo into mono and Writes 'size' bytes in each of the buffers.
* The data matches the format reported by GetFormat, except that both
* buffers will contain Mono audio. When the source format was already mono
* the 'right' buffer is ignored (and not cleared)
* When size is is smaller then the amount of written bytes or an error occurs
* the remaining buffer space is cleared.
*
* @param left Output buffer of the left channel
* @param right Output buffer of the right channel (or nothing if source is mono)
* @param size Size of each of the buffers
* @return Number of bytes written in one of the buffers or -1 on error
*/
int DecodeAsMono(uint8_t* left, uint8_t* right, int size);
/**
* Parses the specified file handle and open a proper audio decoder to handle
* the audio file.
* Upon success the file handle is owned by the audio decoder and further
* operations on it will be undefined! Upon failure the file handle points at
* the beginning.
* The filename is used for debug purposes but should match the FILE handle.
* Upon failure the FILE handle is valid and points at the beginning.
*
* @param file File handle to parse
* @param filename Path to the file handle
* @return An audio decoder instance when the format was detected, otherwise null
*/
static std::unique_ptr Create(FILE* file, const std::string& filename);
/**
* Updates the volume for the fade in/out effect.
* Volume changes will not really modify the volume but are only helper
* functions for retrieving the volume information for the audio hardware.
*
* @param delta Time in ms since the last call of this function.
*/
void Update(int delta);
/**
* Prepares a volume fade in/out effect.
* To do a fade out begin must be larger then end.
* Call Update to do the fade.
* Volume changes will not really modify the volume but are only helper
* functions for retrieving the volume information for the audio hardware.
*
* @param begin Begin volume (from 0-100)
* @param end End volume (from 0-100)
* @param duration Fade duration in ms
*/
void SetFade(int begin, int end, int duration);
/**
* Sets the volume of the audio decoder.
* Volume changes will not really modify the volume but are only helper
* functions for retrieving the volume information for the audio hardware.
*
* @param volume (from 0-100)
*/
void SetVolume(int volume);
/**
* Gets the volume of the audio decoder.
* Volume changes will not really modify the volume but are only helper
* functions for retrieving the volume information for the audio hardware.
*/
int GetVolume() const;
/**
* Pauses the audio decoding.
* Calling any Decode function will return a 0-buffer.
*/
void Pause();
/**
* Resumes the audio decoding.
* The decode function will continue behaving as expected.
*/
void Resume();
/**
* Rewinds the audio stream to the beginning.
*/
void Rewind();
/**
* Gets if the audio stream will loop when the stream finishes.
*
* @return if looping
*/
bool GetLooping() const;
/**
* Enables/Disables audio stream looping.
* When looping is enabled IsFinished will never return true and the stream
* auto-rewinds (assuming Rewind is supported)
*
* @param enable Enable/Disable looping
*/
void SetLooping(bool enable);
/**
* Gets the number of loops
*
* @return loop count
*/
int GetLoopCount() const;
/**
* Gets the status of the newly created audio decoder.
* Used to make sure the underlying library is properly initialized.
*
* @return true if initializing was succesful, false otherwise
*/
virtual bool WasInited() const;
/**
* Provides an error message when Open or a Decode function fail.
*
* @return Human readable error message
*/
virtual std::string GetError() const;
/**
* Returns the name of the format the current audio decoder decodes in
* lower case.
*
* @return Format name
*/
virtual std::string GetType() const;
// Functions to be implemented by the audio decoder
/**
* Assigns a file handle to the audio decoder.
* Open should be only called once per audio decoder instance.
* Use GetError to get the error reason on failure.
*
* @return true if inititalizing was succesful, false otherwise
*/
virtual bool Open(FILE* file) = 0;
/**
* Determines whether the stream is finished.
*
* @return true stream ended
*/
virtual bool IsFinished() const = 0;
/**
* Retrieves the format of the audio decoder.
* It is guaranteed that these settings will stay constant the whole time.
*
* @param frequency Filled with the audio frequency
* @param format Filled with the audio format
* @param channel Filled with the amount of channels
*/
virtual void GetFormat(int& frequency, Format& format, int& channels) const = 0;
/**
* Requests a prefered format from the audio decoder. Not all decoders
* support everything and it's recommended to use the audio hardware
* for audio processing.
* When false is returned use GetFormat to get the real format of the
* output data.
*
* @param frequency Audio frequency
* @param format Audio format
* @param channel Number of channels
* @return true when all settings were set, otherwise false (use GetFormat)
*/
virtual bool SetFormat(int frequency, Format format, int channels);
/**
* Gets the pitch multiplier.
*
* @return pitch multiplier
*/
virtual int GetPitch() const;
/**
* Sets the pitch multiplier.
* 100 = normal speed
* 200 = double speed and so on
* Not all audio decoders support this. Using the audio hardware is
* recommended.
*
* @param pitch Pitch multiplier to use
* @return true if pitch was set, false otherwise
*/
virtual bool SetPitch(int pitch);
/**
* Seeks in the audio stream. The value of offset is implementation
* defined but is guaranteed to match the result of Tell.
* Only Rewinding is guaranteed to work.
*
* @param offset Offset to seek to
* @param origin Position to seek from
* @return Whether seek was successful
*/
virtual bool Seek(size_t offset, Origin origin);
/**
* Tells the current stream position. The value is implementation
* defined.
*
* @return Position in the stream
*/
virtual size_t Tell() const;
/**
* Returns amount of executed ticks. Only useful for MIDI format.
*
* @return Amount of MIDI ticks.
*/
virtual int GetTicks() const;
/**
* Returns the amount of bytes per sample.
*
* @param Sample format
* @return Bytes per sample
*/
static int GetSamplesizeForFormat(AudioDecoder::Format format);
protected:
/**
* Called by the Decode functions to fill the buffer.
*
* @param buffer Buffer to fill
* @param size Buffer size
* @return number of bytes read or -1 on error
*/
virtual int FillBuffer(uint8_t* buffer, int size) = 0;
std::string error_message;
std::string music_type;
private:
bool paused = false;
double volume = 0;
double fade_end = 0;
double fade_time = -1;
double delta_step = 0;
bool looping = false;
int loop_count = 0;
std::vector mono_buffer;
};
#endif
================================================
FILE: source/audiodec/audio_resampler.cpp
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#if defined(HAVE_LIBSPEEXDSP) || defined(HAVE_LIBSAMPLERATE)
#include
#include "audio_resampler.h"
#define ERROR -1
#define STANDARD_PITCH 100
/**
* Utility function used to convert a buffer of a arbitrary AudioDecoder::Format to a float buffer
*
* @param[in] wrapped_decoder The decoder from which audio samples are read
* @param[inout] buffer The buffer which will receive the converted samples,
* has to be at least amount_of_samples_to_read*sizeof(float) bytes big.
* @param[in] amount_of_samples_to_read The number of samples to read.
* @param[in] input_samplesize The size of one sample of the decoder in it's original format - given in bytes
* @param[in] input_format The original format of the samples
*
* @return The number of converted samples - if this number is smaller than amount_of_samples_to_read the wrapped decoder has reaches it's end.
* If the returned value has a negative value an error occured.
*/
inline static int DecodeAndConvertFloat(AudioDecoder * wrapped_decoder,
uint8_t * buffer,
int amount_of_samples_to_read,
const int input_samplesize,
const AudioDecoder::Format input_format){
float* bufferAsFloat = (float*)buffer;
if (wrapped_decoder->IsFinished()) return 0; //Workaround for decoders which don't detect there own end
int amount_of_samples_read = wrapped_decoder->Decode(buffer, amount_of_samples_to_read*input_samplesize);
if (amount_of_samples_read <= 0) {
return amount_of_samples_read; //error occured - or nothing read
} else {
amount_of_samples_read /= input_samplesize;
}
//Convert the read data (amount_of_data_read is at least one at this moment)
switch (input_format) {
case AudioDecoder::Format::S8:
//Convert inplace (the last frames are unused if smaller)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsFloat[i] = ((int8_t*)bufferAsFloat)[i] / 128.0;
}
break;
case AudioDecoder::Format::U8:
//Convert inplace (the last frames are unused if smaller)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsFloat[i] = ((uint8_t*)bufferAsFloat)[i] / 128.0 - 1.0;
}
break;
case AudioDecoder::Format::S16:
//Convert inplace (the last frames are unused if smaller)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsFloat[i] = ((int16_t*)bufferAsFloat)[i] / 32768.0;
}
break;
case AudioDecoder::Format::U16:
//Convert inplace (the last frames are unused if smaller)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsFloat[i] = ((uint16_t*)bufferAsFloat)[i] / 32768.0 - 1.0;
}
break;
case AudioDecoder::Format::S32:
//Convert inplace (same size)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsFloat[i] = ((int32_t*)bufferAsFloat)[i] / 2147483648.0;
}
break;
case AudioDecoder::Format::U32:
//Convert inplace (same size)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsFloat[i] = ((uint32_t*)bufferAsFloat)[i] / 2147483648.0 - 1.0;
}
break;
case AudioDecoder::Format::F32:
//Nothing to convert
break;
}
return amount_of_samples_read;
}
#if defined(HAVE_LIBSPEEXDSP)
/**
* Utility function used to convert a buffer of a arbitrary AudioDecoder::Format to a int16 buffer
*
* @param[in] wrapped_decoder The decoder from which audio samples are read
* @param[inout] buffer The buffer which will receive the converted samples,
* has to be at least amount_of_samples_to_read*max(sizeof(int16_t),input_samplesize) bytes big.
* @param[in] amount_of_samples_to_read The number of samples to read.
* @param[in] input_samplesize The size of one sample of the decoder in it's original format - given in bytes
* @param[in] input_format The original format of the samples
*
* @return The number of converted samples - if this number is smaller than amount_of_samples_to_read the wrapped decoder has reaches it's end.
* If the returned value has a negative value an error occured.
*/
inline static int DecodeAndConvertInt16(AudioDecoder * wrapped_decoder,
uint8_t * buffer,
int amount_of_samples_to_read,
const int input_samplesize,
const AudioDecoder::Format input_format){
int16_t* bufferAsInt16 = (int16_t*)buffer;
if (wrapped_decoder->IsFinished()) return 0; //Workaround for decoders which don't detect there own end
int amount_of_samples_read = wrapped_decoder->Decode(buffer, amount_of_samples_to_read*input_samplesize);
if (amount_of_samples_read <= 0) {
return amount_of_samples_read; //error occured - or nothing read
} else {
//Convert the number of bytes to the number of samples
amount_of_samples_read /= input_samplesize;
}
//Convert the read data (amount_of_data_read is at least one at this moment)
switch (input_format) {
case AudioDecoder::Format::S8:
//Convert inplace (the last frames are unused if smaller)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsInt16[i] = ((int8_t*)bufferAsInt16)[i] << 8;
}
break;
case AudioDecoder::Format::U8:
//Convert inplace (the last frames are unused if smaller)
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsInt16[i] = (((int16_t)(((uint8_t*)bufferAsInt16)[i])) - 128) << 8;
}
break;
case AudioDecoder::Format::S16:
//Nothing to convert
break;
case AudioDecoder::Format::U16:
//Convert unsigned to signed
for (int i = amount_of_samples_read - 1; i >= 0; i--) {
bufferAsInt16[i] = (int16_t)(((int32_t)(((uint16_t*)bufferAsInt16)[i])) - 32768);
}
break;
case AudioDecoder::Format::S32:
//Convert inplace (from front to back to prevent overwriting the buffer)
for (int i = 0; i < amount_of_samples_read; i++) {
bufferAsInt16[i] = (int16_t)((((int32_t*)bufferAsInt16)[i]) >> 16);
}
break;
case AudioDecoder::Format::U32:
//Convert inplace (from front to back to prevent overwriting the buffer)
for (int i = 0; i < amount_of_samples_read; i++) {
bufferAsInt16[i] = (int16_t)(((int32_t)((((uint32_t*)bufferAsInt16)[i]) >> 16)) - 32768);
}
break;
case AudioDecoder::Format::F32:
//Convert inplace (from front to back to prevent overwriting the buffer)
for (int i = 0; i < amount_of_samples_read; i++) {
float number = ((((float*)bufferAsInt16)[i])*32768.0);
bufferAsInt16[i] = (number <= 32767.0) ? ((number >= -32768.0) ? number : -32768) : 32767;
}
break;
}
return amount_of_samples_read;
}
#endif
AudioResampler::AudioResampler(AudioDecoder * wrapped, bool pitch_handled, AudioResampler::Quality quality)
{
//There is no need for a standalone resampler decoder
assert(wrapped != 0);
wrapped_decoder = wrapped;
music_type = wrapped->GetType();
lasterror = 0;
pitch_handled_by_decoder = pitch_handled;
#if defined(HAVE_LIBSPEEXDSP)
switch (quality) {
case Quality::Low:
sampling_quality = 1;
break;
case Quality::Medium:
sampling_quality = 3;
break;
case Quality::High:
sampling_quality = 5;
break;
}
#elif defined(HAVE_LIBSAMPLERATE)
switch (quality) {
case Quality::Low:
sampling_quality = SRC_SINC_FASTEST;
break;
case Quality::Medium:
sampling_quality = SRC_SINC_MEDIUM_QUALITY;
break;
case Quality::High:
sampling_quality = SRC_SINC_BEST_QUALITY;
break;
}
#endif
finished = false;
pitch = 100;
}
AudioResampler::~AudioResampler() {
if (conversion_state != 0) {
#if defined(HAVE_LIBSPEEXDSP)
speex_resampler_destroy(conversion_state);
#elif defined(HAVE_LIBSAMPLERATE)
src_delete(conversion_state);
#endif
}
if (wrapped_decoder != 0) {
delete wrapped_decoder;
}
}
bool AudioResampler::WasInited() const {
return wrapped_decoder->WasInited();
}
bool AudioResampler::Open(FILE* file) {
if (wrapped_decoder->Open(file)) {
wrapped_decoder->GetFormat(input_rate, input_format, nr_of_channels);
//determine if the input format is supported by the resampler
switch (input_format) {
case Format::F32: output_format = input_format; break;
#ifdef HAVE_LIBSPEEXDSP
case Format::S16: output_format = input_format; break;
#endif
default: output_format = Format::F32; break;
}
//Set input format to output_format if possible
wrapped_decoder->SetFormat(input_rate, output_format, nr_of_channels);
//Reread format to get new values
wrapped_decoder->GetFormat(input_rate, input_format, nr_of_channels);
output_rate = input_rate;
#if defined(HAVE_LIBSPEEXDSP)
conversion_state = speex_resampler_init(nr_of_channels, input_rate, output_rate, sampling_quality, &lasterror);
conversion_data.ratio_num = input_rate;
conversion_data.ratio_denom = output_rate;
speex_resampler_skip_zeros(conversion_state);
#elif defined(HAVE_LIBSAMPLERATE)
conversion_state = src_new(sampling_quality, nr_of_channels, &lasterror);
#endif
//Init the conversion data structure
conversion_data.input_frames = 0;
conversion_data.input_frames_used = 0;
finished = false;
return conversion_state != 0;
} else {
return false;
}
}
bool AudioResampler::Seek(size_t offset, Origin origin) {
if (wrapped_decoder->Seek(offset, origin)) {
//reset conversio data
conversion_data.input_frames = 0;
conversion_data.input_frames_used = 0;
finished = wrapped_decoder->IsFinished();
#if defined(HAVE_LIBSPEEXDSP)
speex_resampler_reset_mem(conversion_state);
#elif defined(HAVE_LIBSAMPLERATE)
src_reset(conversion_state);
#endif
return true;
}
return false;
}
size_t AudioResampler::Tell() const {
return wrapped_decoder->Tell();
}
int AudioResampler::GetTicks() const {
return wrapped_decoder->GetTicks();
}
bool AudioResampler::IsFinished() const {
return finished;
}
void AudioResampler::GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const {
frequency = output_rate;
format = output_format;
channels = nr_of_channels;
}
bool AudioResampler::SetFormat(int freq, AudioDecoder::Format fmt, int channels) {
//Check whether requested format is supported by the resampler
switch (fmt) {
case Format::F32: output_format = fmt; break;
#ifdef HAVE_LIBSPEEXDSP
case Format::S16: output_format = fmt; break;
#endif
default: break;
}
wrapped_decoder->SetFormat(input_rate, output_format, channels);
wrapped_decoder->GetFormat(input_rate, input_format, nr_of_channels);
output_rate = freq;
return (nr_of_channels == channels&&output_format == fmt);
}
int AudioResampler::GetPitch() const {
if (pitch_handled_by_decoder) {
return wrapped_decoder->GetPitch();
} else {
return pitch;
}
}
bool AudioResampler::SetPitch(int pitch_) {
if (pitch_handled_by_decoder) {
return wrapped_decoder->SetPitch(pitch_);
} else {
pitch = pitch_;
return true;
}
}
int AudioResampler::FillBuffer(uint8_t* buffer, int length) {
int amount_filled = 0;
if((input_rate == output_rate) && ((pitch == STANDARD_PITCH) || pitch_handled_by_decoder)) {
//Do only format conversion
amount_filled = FillBufferSameRate(buffer, length);
} else {
if (conversion_state == 0) {
error_message = "internal error: state pointer is a nullptr";
amount_filled = ERROR;
} else {
//Do samplerate conversion
amount_filled = FillBufferDifferentRate(buffer, length);
}
}
//Clear the remaining buffer as specified in audio_decoder.h
for (int i = (amount_filled > 0) ? amount_filled : 0; i < length; i++) {
buffer[i] = 0;
}
return amount_filled;
}
int AudioResampler::FillBufferSameRate(uint8_t* buffer, int length) {
const int input_samplesize = GetSamplesizeForFormat(input_format);
const int output_samplesize = GetSamplesizeForFormat(output_format);
//The buffer size has to be a multiple of a frame
const int buffer_size=sizeof(internal_buffer) - sizeof(internal_buffer)%(nr_of_channels*input_samplesize);
int total_output_frames = length / (output_samplesize*nr_of_channels);
int amount_of_data_to_read = 0;
int amount_of_data_read = total_output_frames*nr_of_channels;
int decoded = 0;
if (input_samplesize > output_samplesize) {
//It is necessary to use the internal_buffer to convert the samples.
while (total_output_frames > 0) {
amount_of_data_to_read = buffer_size / input_samplesize;
//limit amount_of_data_to_read in the last loop
amount_of_data_to_read = (amount_of_data_to_read > total_output_frames) ? total_output_frames : amount_of_data_to_read;
switch (output_format) {
case AudioDecoder::Format::F32:
amount_of_data_read = DecodeAndConvertFloat(wrapped_decoder, internal_buffer, amount_of_data_to_read, input_samplesize, input_format);
break;
#ifdef HAVE_LIBSPEEXDSP
case AudioDecoder::Format::S16:
amount_of_data_read = DecodeAndConvertInt16(wrapped_decoder, internal_buffer, amount_of_data_to_read, input_samplesize, input_format);
break;
#endif
default: error_message = "internal error: output_format is not convertable"; return ERROR;
}
if (amount_of_data_read < 0) {
error_message = wrapped_decoder->GetError();
return amount_of_data_read; //error occured
}
//Copy the converted samples
for (int i = 0; i < amount_of_data_read*output_samplesize; i++) {
buffer[i] = internal_buffer[i];
}
//Prepare next loop
total_output_frames -= amount_of_data_read;
decoded += amount_of_data_read;
buffer += amount_of_data_read*output_samplesize;
//If the end of the decoder is reached (it has finished)
if (amount_of_data_read < amount_of_data_to_read) {
break;
}
}
} else {
//It is possible to work inplace as length is specified for the output samplesize.
switch (output_format) {
case AudioDecoder::Format::F32:
decoded = DecodeAndConvertFloat(wrapped_decoder, buffer, amount_of_data_read, input_samplesize, input_format);
break;
#ifdef HAVE_LIBSPEEXDSP
case AudioDecoder::Format::S16:
decoded = DecodeAndConvertInt16(wrapped_decoder, buffer, amount_of_data_read, input_samplesize, input_format);
break;
#endif
default: error_message = "internal error: output_format is not convertable"; return ERROR;
}
}
finished = wrapped_decoder->IsFinished();
if (decoded < 0) {
error_message = wrapped_decoder->GetError();
return decoded;
} else {
return decoded*output_samplesize;
}
}
int AudioResampler::FillBufferDifferentRate(uint8_t* buffer, int length) {
const int input_samplesize = GetSamplesizeForFormat(input_format);
const int output_samplesize = GetSamplesizeForFormat(output_format);
//The buffer size has to be a multiple of a frame
const int buffer_size=sizeof(internal_buffer) - sizeof(internal_buffer)%(nr_of_channels*((input_samplesize>output_samplesize) ? input_samplesize : output_samplesize));
int total_output_frames = length / (output_samplesize*nr_of_channels);
int amount_of_samples_to_read = 0;
int amount_of_samples_read = 0;
uint8_t * advanced_input_buffer = internal_buffer;
int unused_frames = 0;
int empty_buffer_space = 0;
int error = 0;
#ifdef HAVE_LIBSPEEXDSP
spx_uint32_t numerator = 0;
spx_uint32_t denominator = 0;
#endif
while (total_output_frames > 0) {
//Calculate how much frames of the last cycle are unused - to reuse them
unused_frames = conversion_data.input_frames - conversion_data.input_frames_used;
empty_buffer_space = buffer_size / output_samplesize - unused_frames*nr_of_channels;
advanced_input_buffer = internal_buffer;
//If there is still unused data in the input_buffer order it to the front
for (int i = 0; i < unused_frames*nr_of_channels*output_samplesize; i++) {
*advanced_input_buffer = *(advanced_input_buffer + empty_buffer_space*output_samplesize);
advanced_input_buffer++;
}
//advanced_input_buffer is now offset to the first frame of new data!
//ensure that the input buffer is not able to overrun
amount_of_samples_to_read = (input_samplesize > output_samplesize) ? (empty_buffer_space*output_samplesize) / input_samplesize : empty_buffer_space;
//Read as many frames as needed to refill the buffer (filled after the conversion to float)
if (amount_of_samples_to_read != 0) {
switch (output_format) {
case AudioDecoder::Format::F32: amount_of_samples_read = DecodeAndConvertFloat(wrapped_decoder, advanced_input_buffer, amount_of_samples_to_read, input_samplesize, input_format); break;
#ifdef HAVE_LIBSPEEXDSP
case AudioDecoder::Format::S16: amount_of_samples_read = DecodeAndConvertInt16(wrapped_decoder, advanced_input_buffer, amount_of_samples_to_read, input_samplesize, input_format); break;
#endif
default: error_message = "internal error: output_format is not convertable"; return ERROR;
}
if (amount_of_samples_read < 0) {
error_message = wrapped_decoder->GetError();
return amount_of_samples_read; //error occured
}
}
//Now we have a prepared full buffer of converted values
//Prepare the source data
conversion_data.input_frames = amount_of_samples_read / nr_of_channels + unused_frames;
conversion_data.output_frames = total_output_frames;
#if defined(HAVE_LIBSPEEXDSP)
conversion_data.input_frames_used = conversion_data.input_frames;
conversion_data.output_frames_gen = conversion_data.output_frames;
//libspeexdsp defines a sample rate conversion with a fraction (input/output)
numerator = input_rate*pitch;
denominator = output_rate * STANDARD_PITCH;
if (pitch_handled_by_decoder) {
numerator = input_rate;
denominator = output_rate;
}
if (conversion_data.ratio_num != numerator || conversion_data.ratio_denom != denominator) {
int err=speex_resampler_set_rate_frac(conversion_state, numerator, denominator, input_rate, output_rate);
conversion_data.ratio_num = numerator;
conversion_data.ratio_denom = denominator;
}
//A pitfall from libspeexdsp if the output buffer is defined to big - everything stutters -achieved good values with the same size as the input buffer for a maximum
conversion_data.output_frames_gen=(conversion_data.input_framesIsFinished()) ? 1 : 0;
//Now let libsamplerate filter the data
error = src_process(conversion_state, &conversion_data);
if (error != 0) {
error_message = src_strerror(error);
return ERROR;
}
#endif
total_output_frames -= conversion_data.output_frames_gen;
buffer += conversion_data.output_frames_gen*nr_of_channels*output_samplesize;
if ((conversion_data.input_frames == 0 && conversion_data.output_frames_gen <= conversion_data.output_frames) || conversion_data.output_frames_gen == 0) {
finished = true;
//There is nothing left to convert - return how much samples (in bytes) are converted!
return length - total_output_frames*(output_samplesize*nr_of_channels);
}
}
return length;
}
#endif
================================================
FILE: source/audiodec/audio_resampler.h
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#ifndef EASYRPG_AUDIO_RESAMPLER_H
#define EASYRPG_AUDIO_RESAMPLER_H
// Headers
#include "audio_decoder.h"
#include
#include
#if defined(HAVE_LIBSPEEXDSP)
#include
#elif defined(HAVE_LIBSAMPLERATE)
#include
#endif
/**
* Audio resampler powered by Libspeexdsp or Libsamplerate
* Wraps another decoder and provides resampling.
*/
class AudioResampler : public AudioDecoder {
public:
/** Resampling quality */
enum class Quality {
High,
Medium,
Low
};
/**
* Constructs a resampler
*
* @param[in] decoder The decoder which provides samples to the resampler - will be owned by the resampler
* @param[in] pitch_handled Defines whether the decoder handles pitch changes by itself or not.
* @param[in] quality Sets the quality rting of the resampler - higher quality implies slower filtering
*/
AudioResampler(AudioDecoder * decoder, bool pitch_handled=false, Quality quality=Quality::Medium);
/**
* Destroys the resampler as well as its owned ressources
*/
~AudioResampler();
/**
* Wraps the status querying of the contained decoder.
* Used to make sure the underlying library is properly initialized.
*
* @return true if initializing was succesful, false otherwise
*/
bool WasInited() const;
/**
* Wraps the opening function of the contained decoder
*
* @param[in] file Filepointer to a file readable by the wrapped decoder
*
* @return Whether the operation was successful or not
*/
bool Open(FILE* file) override;
/**
* Wraps the seek function of the contained decoder
* @note If the seek function of the wrapped decoder is
* somewhat corelated to time the offset is not influenced by the resampling ratio
*
* @param offset Offset to seek to
* @param origin Position to seek from
*
* @return Whether seek was successful
*/
bool Seek(size_t offset, Origin origin) override;
/**
* Wraps the tell function of the contained decoder
*
* @return Position in the stream
*/
size_t Tell() const override;
/**
* Wraps the GetTicks Function of the contained decoder
*
* @return Amount of MIDI ticks.
*/
int GetTicks() const override;
/**
* Returns wheter the resampled audio stream is finished
*
* @return true if the stream has reached it's end
*/
bool IsFinished() const override;
/**
* Retrieves the format of the audio decoder.
*
* @param frequency Filled with the audio frequency
* @param format Filled with the audio format
* @param channel Filled with the amount of channels
*/
void GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const override;
/**
* Requests a certain frame format from the resampler.
* Supported formats are:
* * float,int16_t for libspeexdsp
* * float for libsamplerate
* The channel setting is redirected to the wrapped decoder.
* The frequency setting controls the resampler.
*
* @param frequency Sample rate the resampler should output
* @param format Audio format the resampler should output
* @param channel Number of channels
* @return true when all settings were set, otherwise false (use GetFormat)
*/
bool SetFormat(int frequency, AudioDecoder::Format format, int channels) override;
/**
* Gets the pitch multiplier.
*
* @return pitch multiplier
*/
int GetPitch() const override;
/**
* Sets the pitch multiplier.
* 100 = normal speed
* 200 = double speed and so on
* If the pitch is handled by the resampler this setting controls the resampling in conjunction with the frequency.
*
* @param pitch Pitch multiplier to use
* @return true if pitch was set, false otherwise
*/
bool SetPitch(int pitch) override;
private:
/**
* Called by the Decode functions to fill the buffer.
*
* @param buffer Buffer to fill
* @param size Buffer size
* @return number of bytes read or -1 on error
*/
int FillBuffer(uint8_t* buffer, int length) override;
/**
* Internally used by the FillBuffer function if the output rate equals the input rate
*/
int FillBufferSameRate(uint8_t* buffer, int length);
/**
* Internally used by the FillBuffer function if resampling is necessary
*/
int FillBufferDifferentRate(uint8_t* buffer, int length);
AudioDecoder * wrapped_decoder;
bool pitch_handled_by_decoder;
int pitch;
int sampling_quality;
int lasterror;
bool finished;
int nr_of_channels;
Format input_format;
int input_rate;
Format output_format;
int output_rate;
#if defined(HAVE_LIBSPEEXDSP)
struct {
spx_uint32_t input_frames, output_frames;
spx_uint32_t input_frames_used, output_frames_gen;
spx_uint32_t ratio_num, ratio_denom;
} conversion_data;
SpeexResamplerState * conversion_state;
#elif defined(HAVE_LIBSAMPLERATE)
SRC_DATA conversion_data;
SRC_STATE * conversion_state;
#endif
/**
* A buffer needed for operations which can't be performed in place (e.g resampling)
* The size of the buffer defines the number of calls to the resampling algorithmn
* (In the cpp file sizeof is used therefore it can be adjusted to fit the available memory)
*/
uint8_t internal_buffer[256*sizeof(float)];
};
#endif
================================================
FILE: source/audiodec/cd_psp2.cpp
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
#include
#include
#include
#include
#define min
#define max
extern "C"{
#include "../quakedef.h"
}
#undef min
#undef max
#include "audio_decoder.h"
extern char* mod_path;
#define BUFSIZE 8192 // Max dimension of audio buffer size
#define NSAMPLES 2048 // Number of samples for output
// Music block struct
struct DecodedMusic{
uint8_t* audiobuf;
uint8_t* audiobuf2;
uint8_t* cur_audiobuf;
FILE* handle;
bool isPlaying;
bool loop;
volatile bool pauseTrigger;
volatile bool closeTrigger;
volatile bool changeVol;
};
// Internal stuffs
DecodedMusic* BGM = NULL;
std::unique_ptr audio_decoder;
SceUID thread, Audio_Mutex, Talk_Mutex;
volatile bool mustExit = false;
float old_vol = 1.0;
// Audio thread code
static int bgmThread(unsigned int args, void* arg){
// Initializing audio port
int ch = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, NSAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO);
sceAudioOutSetConfig(ch, -1, -1, (SceAudioOutMode)-1);
old_vol = bgmvolume.value;
int vol = 32767 * bgmvolume.value;
int vol_stereo[] = {vol, vol};
sceAudioOutSetVolume(ch, (SceAudioOutChannelFlag)(SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH), vol_stereo);
DecodedMusic* mus;
for (;;){
// Waiting for an audio output request
sceKernelWaitSema(Audio_Mutex, 1, NULL);
// Fetching track
mus = BGM;
// Checking if a new track is available
if (mus == NULL){
//If we enter here, we probably are in the exiting procedure
if (mustExit){
sceAudioOutReleasePort(ch);
mustExit = false;
sceKernelExitDeleteThread(0);
}
}
// Initializing audio decoder
audio_decoder = AudioDecoder::Create(mus->handle, "Track");
audio_decoder->Open(mus->handle);
audio_decoder->SetLooping(mus->loop);
audio_decoder->SetFormat(48000, AudioDecoder::Format::S16, 2);
// Initializing audio buffers
mus->audiobuf = (uint8_t*)malloc(BUFSIZE);
mus->audiobuf2 = (uint8_t*)malloc(BUFSIZE);
mus->cur_audiobuf = mus->audiobuf;
// Audio playback loop
for (;;){
// Check if the music must be paused
if (mus->pauseTrigger || mustExit){
// Check if the music must be closed
if (mus->closeTrigger){
audio_decoder.reset();
free(mus->audiobuf);
free(mus->audiobuf2);
free(mus);
BGM = NULL;
mus = NULL;
if (!mustExit){
sceKernelSignalSema(Talk_Mutex, 1);
break;
}
}
// Check if the thread must be closed
if (mustExit){
// Check if the audio stream has already been closed
if (mus != NULL){
mus->closeTrigger = true;
continue;
}
// Recursively closing all the threads
sceAudioOutReleasePort(ch);
mustExit = false;
sceKernelExitDeleteThread(0);
}
mus->isPlaying = !mus->isPlaying;
mus->pauseTrigger = false;
}
// Check if a volume change is required
if (mus->changeVol){
old_vol = bgmvolume.value;
int vol = 32767 * bgmvolume.value;
int vol_stereo[] = {vol, vol};
sceAudioOutSetVolume(ch, (SceAudioOutChannelFlag)(SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH), vol_stereo);
mus->changeVol = false;
}
if (mus->isPlaying){
// Check if audio playback finished
if ((!mus->loop) && audio_decoder->IsFinished()) mus->isPlaying = false;
// Update audio output
if (mus->cur_audiobuf == mus->audiobuf) mus->cur_audiobuf = mus->audiobuf2;
else mus->cur_audiobuf = mus->audiobuf;
audio_decoder->Decode(mus->cur_audiobuf, BUFSIZE);
sceAudioOutOutput(ch, mus->cur_audiobuf);
}
}
}
}
void CDAudio_Play(byte track, bool looping)
{
CDAudio_Stop();
char fname[256];
sprintf (fname, "%s/%s/cdtracks/track", host_parms.basedir, (mod_path == NULL) ? GAMENAME_DIR : mod_path);
if (track < 100){
sprintf(fname, "%s0", fname);
if (track < 10){
sprintf(fname, "%s0", fname);
}
}
sprintf(fname,"%s%d",fname,track);
char tmp[256];
sprintf(tmp,"%s.ogg",fname);
FILE* fd = fopen(tmp,"rb");
if (fd == NULL){
sprintf(tmp,"%s.mp3",fname);
fd = fopen(tmp,"rb");
}
if (fd == NULL) return;
DecodedMusic* memblock = (DecodedMusic*)malloc(sizeof(DecodedMusic));
memblock->handle = fd;
memblock->pauseTrigger = false;
memblock->closeTrigger = false;
memblock->isPlaying = true;
memblock->loop = looping;
BGM = memblock;
sceKernelSignalSema(Audio_Mutex, 1);
}
void CDAudio_Stop(void)
{
if (BGM != NULL){
BGM->closeTrigger = true;
BGM->pauseTrigger = true;
sceKernelWaitSema(Talk_Mutex, 1, NULL);
}
}
void CDAudio_Pause(void)
{
if (BGM != NULL) BGM->pauseTrigger = true;
}
void CDAudio_Resume(void)
{
if (BGM != NULL) BGM->pauseTrigger = true;
}
void CDAudio_Update(void)
{
if (BGM != NULL){
if (old_vol != bgmvolume.value) BGM->changeVol = true;
}
}
int CDAudio_Init(void)
{
int res;
// Creating audio mutex
Audio_Mutex = sceKernelCreateSema("Audio Mutex", 0, 0, 1, NULL);
Talk_Mutex = sceKernelCreateSema("Talk Mutex", 0, 0, 1, NULL);
// Creating audio thread
thread = sceKernelCreateThread("Audio Thread", &bgmThread, 0x10000100, 0x10000, 0, 0, NULL);
sceKernelStartThread(thread, sizeof(thread), &thread);
return 0;
}
void CDAudio_Shutdown(void)
{
mustExit = true;
sceKernelSignalSema(Audio_Mutex, 1);
sceKernelWaitThreadEnd(thread, NULL, NULL);
sceKernelDeleteSema(Audio_Mutex);
sceKernelDeleteSema(Talk_Mutex);
}
================================================
FILE: source/audiodec/decoder_mpg123.cpp
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#ifdef HAVE_MPG123
// Headers
#include
#include "decoder_mpg123.h"
static bool init = false;
static void Mpg123Decoder_deinit(void) {
mpg123_exit();
}
static ssize_t custom_read(void* io, void* buffer, size_t nbyte) {
FILE* f = reinterpret_cast(io);
return fread(buffer, 1, nbyte, f);
}
static off_t custom_seek(void* io, off_t offset, int seek_type) {
FILE* f = reinterpret_cast(io);
fseek(f, offset, seek_type);
return ftell(f);
}
static void custom_close(void* io) {
FILE* f = reinterpret_cast(io);
fclose(f);
}
static void noop_close(void*) {}
Mpg123Decoder::Mpg123Decoder() :
handle(nullptr, mpg123_delete)
{
music_type = "mp3";
// only initialize library once
if (!init) {
err = mpg123_init();
if (err != MPG123_OK) {
error_message = "mpg123: " + std::string(mpg123_plain_strerror(err));
return;
}
// setup deinitialization
atexit(Mpg123Decoder_deinit);
}
handle.reset(mpg123_new(nullptr, &err));
mpg123_replace_reader_handle(handle.get(), custom_read, custom_seek, custom_close);
if (!handle) {
error_message = "mpg123: " + std::string(mpg123_plain_strerror(err));
return;
}
init = true;
}
Mpg123Decoder::~Mpg123Decoder() {
}
bool Mpg123Decoder::WasInited() const {
return init;
}
bool Mpg123Decoder::Open(FILE* file) {
if (!init) {
return false;
}
finished = false;
err = mpg123_open_handle(handle.get(), file);
if (err != MPG123_OK) {
error_message = "mpg123: " + std::string(mpg123_plain_strerror(err));
return false;
}
return true;
}
bool Mpg123Decoder::Seek(size_t offset, Origin origin) {
finished = false;
mpg123_seek_frame(handle.get(), offset, (int)origin);
return true;
}
bool Mpg123Decoder::IsFinished() const {
return finished;
}
static int format_to_mpg123_format(AudioDecoder::Format format) {
switch (format) {
case AudioDecoder::Format::U8:
return MPG123_ENC_UNSIGNED_8;
case AudioDecoder::Format::S8:
return MPG123_ENC_SIGNED_8;
case AudioDecoder::Format::U16:
return MPG123_ENC_UNSIGNED_16;
case AudioDecoder::Format::S16:
return MPG123_ENC_SIGNED_16;
case AudioDecoder::Format::U32:
return MPG123_ENC_UNSIGNED_32;
case AudioDecoder::Format::S32:
return MPG123_ENC_SIGNED_32;
case AudioDecoder::Format::F32:
return MPG123_ENC_FLOAT_32;
default:
assert(false);
}
return -1;
}
static AudioDecoder::Format mpg123_format_to_format(int format) {
switch (format) {
case MPG123_ENC_UNSIGNED_8:
return AudioDecoder::Format::U8;
case MPG123_ENC_SIGNED_8:
return AudioDecoder::Format::S8;
case MPG123_ENC_UNSIGNED_16:
return AudioDecoder::Format::U16;
case MPG123_ENC_SIGNED_16:
return AudioDecoder::Format::S16;
case MPG123_ENC_UNSIGNED_32:
return AudioDecoder::Format::U32;
case MPG123_ENC_SIGNED_32:
return AudioDecoder::Format::S32;
case MPG123_ENC_FLOAT_32:
return AudioDecoder::Format::F32;
default:
assert(false);
}
return (AudioDecoder::Format)-1;
}
void Mpg123Decoder::GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const {
long freq;
int ch;
int fmt;
mpg123_getformat(handle.get(), &freq, &ch, &fmt);
frequency = (int)freq;
channels = ch;
format = mpg123_format_to_format(fmt);
}
bool Mpg123Decoder::SetFormat(int freq, AudioDecoder::Format fmt, int channels) {
// mpg123 has a built-in pseudo-resampler, not needing SDL_ConvertAudio later
// Remove all available conversion formats
// Add just one format to force mpg123 pseudo-resampler work
mpg123_format_none(handle.get());
err = mpg123_format(handle.get(), (long)freq, (int)channels, (int)format_to_mpg123_format(fmt));
if (err != MPG123_OK) {
err = mpg123_format(handle.get(), (long)44100, (int)channels, (int)format_to_mpg123_format(fmt));
if (err != MPG123_OK) {
mpg123_format(handle.get(), (long)44100, (int)2, (int)MPG123_ENC_SIGNED_16);
}
return false;
}
return err == MPG123_OK;
}
bool Mpg123Decoder::IsMp3(FILE* stream) {
Mpg123Decoder decoder;
// Prevent stream handle destruction
mpg123_replace_reader_handle(decoder.handle.get(), custom_read, custom_seek, noop_close);
// Prevent skipping of too many garbage, breaks heuristic
mpg123_param(decoder.handle.get(), MPG123_RESYNC_LIMIT, 64, 0.0);
if (!decoder.Open(stream)) {
return false;
}
unsigned char buffer[1024];
int err = 0;
size_t done = 0;
int err_count = 0;
// Read beginning of assumed MP3 file and count errors as an heuristic to detect MP3
for (int i = 0; i < 10; ++i) {
err = mpg123_read(decoder.handle.get(), buffer, 1024, &done);
if (err != MPG123_OK) {
err_count += 1;
}
if (err_count >= 3) {
break;
}
}
return err_count < 3;
}
int Mpg123Decoder::FillBuffer(uint8_t* buffer, int length) {
int err;
size_t done = 0;
size_t decoded = 0;
// Skip invalid frames until getting a valid one
do {
err = mpg123_read(handle.get(), reinterpret_cast(buffer), length, &done);
decoded += done;
} while (done && err != MPG123_OK);
if (err == MPG123_DONE) {
finished = true;
}
return (int)decoded;
}
#endif
================================================
FILE: source/audiodec/decoder_mpg123.h
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#ifndef EASYRPG_AUDIO_DECODER_MPG123_H
#define EASYRPG_AUDIO_DECODER_MPG123_H
// Headers
#include "audio_decoder.h"
#include
#ifdef HAVE_MPG123
#include
#endif
#include
/**
* Audio decoder for MP3 powered by mpg123
*/
class Mpg123Decoder : public AudioDecoder {
public:
Mpg123Decoder();
~Mpg123Decoder();
bool WasInited() const override;
bool Open(FILE* file) override;
bool Seek(size_t offset, Origin origin) override;
bool IsFinished() const override;
void GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const override;
bool SetFormat(int frequency, AudioDecoder::Format format, int channels) override;
static bool IsMp3(FILE* stream);
private:
int FillBuffer(uint8_t* buffer, int length) override;
#ifdef HAVE_MPG123
std::unique_ptr handle;
#endif
FILE* file_handle;
int err = 0;
bool finished = false;
int frequency = 44100;
};
#endif
================================================
FILE: source/audiodec/decoder_oggvorbis.cpp
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#if defined(HAVE_TREMOR) || defined(HAVE_OGGVORBIS)
// Headers
#include
#ifdef HAVE_TREMOR
#include
#include
#else
#include
#include
#endif
#include "audio_decoder.h"
#include "decoder_oggvorbis.h"
OggVorbisDecoder::OggVorbisDecoder() {
music_type = "ogg";
}
OggVorbisDecoder::~OggVorbisDecoder() {
if (ovf) {
ov_clear(ovf);
delete ovf;
}
}
bool OggVorbisDecoder::Open(FILE* file) {
finished = false;
if (ovf) {
ov_clear(ovf);
delete ovf;
}
ovf = new OggVorbis_File;
int res = ov_open(file, ovf, NULL, 0);
if (res < 0) {
error_message = "OggVorbis: Error reading file";
delete ovf;
fclose(file);
return false;
}
vorbis_info *vi = ov_info(ovf, -1);
if (!vi) {
error_message = "OggVorbis: Error getting file information";
ov_clear(ovf);
delete ovf;
return false;
}
// (long)ov_pcm_total(ovf, -1)) -> decoded length in samples, maybe useful for ticks later?
frequency = vi->rate;
channels = vi->channels;
return true;
}
bool OggVorbisDecoder::Seek(size_t offset, Origin origin) {
if (offset == 0 && origin == Origin::Begin) {
if (ovf) {
ov_raw_seek(ovf, 0);
}
finished = false;
return true;
}
return false;
}
bool OggVorbisDecoder::IsFinished() const {
if (!ovf)
return false;
return finished;
}
void OggVorbisDecoder::GetFormat(int& freq, AudioDecoder::Format& format, int& chans) const {
freq = frequency;
format = Format::S16;
chans = channels;
}
bool OggVorbisDecoder::SetFormat(int freq, AudioDecoder::Format format, int chans) {
if (freq != frequency || chans != channels || format != Format::S16)
return false;
return true;
}
bool OggVorbisDecoder::SetPitch(int pitch) {
if (pitch != 100) {
return false;
}
return true;
}
int OggVorbisDecoder::FillBuffer(uint8_t* buffer, int length) {
if (!ovf)
return -1;
static int section;
int read = 0;
int to_read = length;
do {
#ifdef HAVE_TREMOR
read = ov_read(ovf, reinterpret_cast(buffer + length - to_read), to_read, §ion);
#else
read = ov_read(ovf, reinterpret_cast(buffer + length - to_read), to_read, 0/*LE*/, 2/*16bit*/, 1/*signed*/, §ion);
#endif
// stop decoding when error or end of file
if (read <= 0)
break;
to_read -= read;
} while(to_read > 0);
// end of file
if (read == 0)
finished = true;
// error
if (read < 0)
return -1;
return length - to_read;
}
#endif
================================================
FILE: source/audiodec/decoder_oggvorbis.h
================================================
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player 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 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player 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 EasyRPG Player. If not, see .
*/
#ifndef EASYRPG_AUDIO_DECODER_OGGVORBIS_H
#define EASYRPG_AUDIO_DECODER_OGGVORBIS_H
// Headers
#include
#include
#ifdef HAVE_TREMOR
#include
#include
#elif HAVE_OGGVORBIS
#include
#include
#endif
#include "audio_decoder.h"
/**
* Audio decoder for Ogg Vorbis powered by libTremor/libOgg+libVorbis
*/
class OggVorbisDecoder : public AudioDecoder {
public:
OggVorbisDecoder();
~OggVorbisDecoder();
// Audio Decoder interface
bool Open(FILE* file) override;
bool Seek(size_t offset, Origin origin) override;
bool IsFinished() const override;
void GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const override;
bool SetFormat(int frequency, AudioDecoder::Format format, int channels) override;
bool SetPitch(int pitch) override;
private:
int FillBuffer(uint8_t* buffer, int length) override;
#if defined(HAVE_TREMOR) || defined(HAVE_OGGVORBIS)
OggVorbis_File *ovf = NULL;
#endif
bool finished = false;
int frequency = 44100;
int channels = 2;
};
#endif
================================================
FILE: source/block16.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
LEnter16_16:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch0:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch1:
movw %cx,2(%edi)
addl $0x4,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch2:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch3:
movw %cx,2(%edi)
addl $0x4,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch4:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch5:
movw %cx,2(%edi)
addl $0x4,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch6:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch7:
movw %cx,2(%edi)
addl $0x4,%edi
LEnter8_16:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch8:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch9:
movw %cx,2(%edi)
addl $0x4,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch10:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch11:
movw %cx,2(%edi)
addl $0x4,%edi
LEnter4_16:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch12:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch13:
movw %cx,2(%edi)
addl $0x4,%edi
LEnter2_16:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movw 0x12345678(,%eax,2),%ax
LBPatch14:
addl %ebp,%edx
movw %ax,(%edi)
movw 0x12345678(,%ecx,2),%cx
LBPatch15:
movw %cx,2(%edi)
addl $0x4,%edi
================================================
FILE: source/block8.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
LEnter16_8:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch0:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch1:
movb %cl,1(%edi)
addl $0x2,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch2:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch3:
movb %cl,1(%edi)
addl $0x2,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch4:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch5:
movb %cl,1(%edi)
addl $0x2,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch6:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch7:
movb %cl,1(%edi)
addl $0x2,%edi
LEnter8_8:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch8:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch9:
movb %cl,1(%edi)
addl $0x2,%edi
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch10:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch11:
movb %cl,1(%edi)
addl $0x2,%edi
LEnter4_8:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch12:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch13:
movb %cl,1(%edi)
addl $0x2,%edi
LEnter2_8:
movb (%esi),%al
movb (%esi,%ebx,),%cl
movb %dh,%ah
addl %ebp,%edx
movb %dh,%ch
leal (%esi,%ebx,2),%esi
movb 0x12345678(%eax),%al
LBPatch14:
addl %ebp,%edx
movb %al,(%edi)
movb 0x12345678(%ecx),%cl
LBPatch15:
movb %cl,1(%edi)
addl $0x2,%edi
================================================
FILE: source/bspfile.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
// upper design bounds
#define MAX_MAP_HULLS 4
#define MAX_MAP_MODELS 256
#define MAX_MAP_BRUSHES 4096
#define MAX_MAP_ENTITIES 1024
#define MAX_MAP_ENTSTRING 65536
#define MAX_MAP_PLANES 32767
#define MAX_MAP_NODES 32767 // because negative shorts are contents
#define MAX_MAP_CLIPNODES 32767
#define MAX_MAP_LEAFS 65535
#define MAX_MAP_VERTS 65535
#define MAX_MAP_FACES 65535
#define MAX_MAP_MARKSURFACES 65535
#define MAX_MAP_TEXINFO 4096
#define MAX_MAP_EDGES 256000
#define MAX_MAP_SURFEDGES 512000
#define MAX_MAP_TEXTURES 512
#define MAX_MAP_MIPTEX 0x200000
#define MAX_MAP_LIGHTING 0x100000
#define MAX_MAP_VISIBILITY 0x100000
#define MAX_MAP_PORTALS 65536
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
//=============================================================================
#define Q1_BSPVERSION 29
#define HL_BSPVERSION 30
// RMQ support (2PSB). 32bits instead of shorts for all but bbox sizes (which still use shorts)
#define BSP2VERSION_2PSB (('B' << 24) | ('S' << 16) | ('P' << 8) | '2')
// BSP2 support. 32bits instead of shorts for everything (bboxes use floats)
#define BSP2VERSION_BSP2 (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24))
#define TOOLVERSION 2
typedef struct
{
int fileofs, filelen;
} lump_t;
#define LUMP_ENTITIES 0
#define LUMP_PLANES 1
#define LUMP_TEXTURES 2
#define LUMP_VERTEXES 3
#define LUMP_VISIBILITY 4
#define LUMP_NODES 5
#define LUMP_TEXINFO 6
#define LUMP_FACES 7
#define LUMP_LIGHTING 8
#define LUMP_CLIPNODES 9
#define LUMP_LEAFS 10
#define LUMP_MARKSURFACES 11
#define LUMP_EDGES 12
#define LUMP_SURFEDGES 13
#define LUMP_MODELS 14
#define HEADER_LUMPS 15
typedef struct
{
float mins[3], maxs[3];
float origin[3];
int headnode[MAX_MAP_HULLS];
int visleafs; // not including the solid leaf 0
int firstface, numfaces;
} dmodel_t;
typedef struct
{
int version;
lump_t lumps[HEADER_LUMPS];
} dheader_t;
typedef struct
{
int nummiptex;
int dataofs[4]; // [nummiptex]
} dmiptexlump_t;
#define MIPLEVELS 4
typedef struct miptex_s
{
char name[16];
unsigned width, height;
unsigned offsets[MIPLEVELS]; // four mip maps stored
} miptex_t;
typedef struct
{
float point[3];
} dvertex_t;
// 0-2 are axial planes
#define PLANE_X 0
#define PLANE_Y 1
#define PLANE_Z 2
// 3-5 are non-axial planes snapped to the nearest
#define PLANE_ANYX 3
#define PLANE_ANYY 4
#define PLANE_ANYZ 5
typedef struct
{
float normal[3];
float dist;
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
} dplane_t;
#define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2
#define CONTENTS_WATER -3
#define CONTENTS_SLIME -4
#define CONTENTS_LAVA -5
#define CONTENTS_SKY -6
#define CONTENTS_ORIGIN -7 // removed at csg time
#define CONTENTS_CLIP -8 // changed to contents_solid
#define CONTENTS_CURRENT_0 -9
#define CONTENTS_CURRENT_90 -10
#define CONTENTS_CURRENT_180 -11
#define CONTENTS_CURRENT_270 -12
#define CONTENTS_CURRENT_UP -13
#define CONTENTS_CURRENT_DOWN -14
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
{
int planenum;
short children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for sphere culling
short maxs[3];
unsigned short firstface;
unsigned short numfaces; // counting both sides
} dsnode_t;
typedef struct
{
int planenum;
int children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for sphere culling
short maxs[3];
unsigned int firstface;
unsigned int numfaces; // counting both sides
} dl1node_t;
typedef struct
{
int planenum;
int children[2]; // negative numbers are -(leafs+1), not nodes
float mins[3]; // for sphere culling
float maxs[3];
unsigned int firstface;
unsigned int numfaces; // counting both sides
} dl2node_t;
typedef struct
{
int planenum;
short children[2]; // negative numbers are contents
} dsclipnode_t;
typedef struct
{
int planenum;
int children[2]; // negative numbers are contents
} dlclipnode_t;
typedef struct texinfo_s
{
float vecs[2][4]; // [s/t][xyz offset]
int miptex;
int flags;
} texinfo_t;
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
// note that edge 0 is never used, because negative edge nums are used for
// counterclockwise use of the edge in a face
typedef struct
{
unsigned short v[2]; // vertex numbers
} dsedge_t;
typedef struct
{
unsigned int v[2]; // vertex numbers
} dledge_t;
#define MAXLIGHTMAPS 4
typedef struct
{
short planenum;
short side;
int firstedge; // we must support > 64k edges
short numedges;
short texinfo;
// lighting info
byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} dsface_t;
typedef struct
{
int planenum;
int side;
int firstedge; // we must support > 64k edges
int numedges;
int texinfo;
// lighting info
byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} dlface_t;
#define AMBIENT_WATER 0
#define AMBIENT_SKY 1
#define AMBIENT_SLIME 2
#define AMBIENT_LAVA 3
#define NUM_AMBIENTS 4 // automatic ambient sounds
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
// all other leafs need visibility info
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstmarksurface;
unsigned short nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dsleaf_t;
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
short mins[3]; // for frustum culling
short maxs[3];
unsigned int firstmarksurface;
unsigned int nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dl1leaf_t;
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
float mins[3]; // for frustum culling
float maxs[3];
unsigned int firstmarksurface;
unsigned int nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dl2leaf_t;
//============================================================================
#ifndef QUAKE_GAME
#define ANGLE_UP -1
#define ANGLE_DOWN -2
// the utilities get to be lazy and just use large static arrays
extern int nummodels;
extern dmodel_t dmodels[MAX_MAP_MODELS];
extern int visdatasize;
extern byte dvisdata[MAX_MAP_VISIBILITY];
extern int lightdatasize;
extern byte dlightdata[MAX_MAP_LIGHTING];
extern int texdatasize;
extern byte dtexdata[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
extern int entdatasize;
extern char dentdata[MAX_MAP_ENTSTRING];
extern int numleafs;
extern dleaf_t dleafs[MAX_MAP_LEAFS];
extern int numplanes;
extern dplane_t dplanes[MAX_MAP_PLANES];
extern int numvertexes;
extern dvertex_t dvertexes[MAX_MAP_VERTS];
extern int numnodes;
extern dnode_t dnodes[MAX_MAP_NODES];
extern int numtexinfo;
extern texinfo_t texinfo[MAX_MAP_TEXINFO];
extern int numfaces;
extern dface_t dfaces[MAX_MAP_FACES];
extern int numclipnodes;
extern dclipnode_t dclipnodes[MAX_MAP_CLIPNODES];
extern int numedges;
extern dedge_t dedges[MAX_MAP_EDGES];
extern int nummarksurfaces;
extern unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES];
extern int numsurfedges;
extern int dsurfedges[MAX_MAP_SURFEDGES];
void DecompressVis (byte *in, byte *decompressed);
int CompressVis (byte *vis, byte *dest);
void LoadBSPFile (char *filename);
void WriteBSPFile (char *filename);
void PrintBSPFileSizes (void);
//===============
typedef struct epair_s
{
struct epair_s *next;
char *key;
char *value;
} epair_t;
typedef struct
{
vec3_t origin;
int firstbrush;
int numbrushes;
epair_t *epairs;
} entity_t;
extern int num_entities;
extern entity_t entities[MAX_MAP_ENTITIES];
void ParseEntities (void);
void UnparseEntities (void);
void SetKeyValue (entity_t *ent, signed char *key, signed char *value);
signed char *ValueForKey (entity_t *ent, signed char *key);
// will return "" if not present
vec_t FloatForKey (entity_t *ent, signed char *key);
void GetVectorForKey (entity_t *ent, signed char *key, vec3_t vec);
epair_t *ParseEpair (void);
#endif
================================================
FILE: source/cdaudio.h
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
int CDAudio_Init(void);
void CDAudio_Play(byte track, bool looping);
void CDAudio_Stop(void);
void CDAudio_Pause(void);
void CDAudio_Resume(void);
void CDAudio_Shutdown(void);
void CDAudio_Update(void);
================================================
FILE: source/chase.c
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
// chase.c -- chase camera code
#include "quakedef.h"
CVAR(chase_active, 0, CVAR_NONE) // CVAR enabling thirdperson
CVAR(chase_back, 100, CVAR_NONE)
CVAR(chase_up, 16, CVAR_NONE)
CVAR(chase_right, 0, CVAR_NONE)
//----------------------------------------------
vec3_t chase_pos;
vec3_t chase_angles;
vec3_t chase_dest;
vec3_t chase_dest_angles;
void Chase_Init (void)
{
Cvar_RegisterVariable (&chase_back);
Cvar_RegisterVariable (&chase_up);
Cvar_RegisterVariable (&chase_right);
Cvar_RegisterVariable (&chase_active);
}
void Chase_Reset (void)
{
// for respawning and teleporting
// start position 12 units behind head
}
void TraceLine (vec3_t start, vec3_t end, vec3_t impact)
{
trace_t trace;
memset (&trace, 0, sizeof(trace));
SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
VectorCopy (trace.endpos, impact);
}
void Chase_Update (void)
{
int i;
float dist;
vec3_t forward, up, right;
vec3_t dest, stop;
// if can't see player, reset
AngleVectors (cl.viewangles, forward, right, up);
// calc exact destination
for (i=0 ; i<3 ; i++)
chase_dest[i] = r_refdef.vieworg[i]
- forward[i]*chase_back.value
- right[i]*chase_right.value;
chase_dest[2] = r_refdef.vieworg[2] + chase_up.value;
// find the spot the player is looking at
VectorMA (r_refdef.vieworg, 4096, forward, dest);
TraceLine (r_refdef.vieworg, dest, stop);
// calculate pitch to look at the same spot from camera
VectorSubtract (stop, r_refdef.vieworg, stop);
dist = DotProduct (stop, forward);
if (dist < 1)
dist = 1;
r_refdef.viewangles[PITCH] = -atan(stop[2] / dist) / M_PI * 180;
// move towards destination
VectorCopy (chase_dest, r_refdef.vieworg);
}
================================================
FILE: source/cl_demo.c
================================================
/*
Copyright (C) 1996-1997 Id Software, Inc.
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.
*/
#include "quakedef.h"
bool benchmark;
void CL_FinishTimeDemo (void);
/*
==============================================================================
DEMO CODE
When a demo is playing back, all NET_SendMessages are skipped, and
NET_GetMessages are read from the demo file.
Whenever cl.time gets past the last received message, another message is
read from the demo file.
==============================================================================
*/
/*
==============
CL_StopPlayback
Called when a demo file runs out, or the user starts a game
==============
*/
void CL_StopPlayback (void)
{
if (!cls.demoplayback)
return;
fclose (cls.demofile);
cls.demoplayback = false;
cls.demofile = NULL;
cls.state = ca_disconnected;
if (cls.timedemo || benchmark)
CL_FinishTimeDemo ();
}
/*
====================
CL_WriteDemoMessage
Dumps the current net message, prefixed by the length and view angles
====================
*/
void CL_WriteDemoMessage (void)
{
int len;
int i;
float f;
len = LittleLong (net_message.cursize);
fwrite (&len, 4, 1, cls.demofile);
for (i=0 ; i<3 ; i++)
{
f = LittleFloat (cl.viewangles[i]);
fwrite (&f, 4, 1, cls.demofile);
}
fwrite (net_message.data, net_message.cursize, 1, cls.demofile);
fflush (cls.demofile);
}
/*
====================
CL_GetMessage
Handles recording and playback of demos, on top of NET_ code
====================
*/
bool bBenchmarkStarted;
int CL_GetMessage (void)
{
int r, i;
float f;
if (cls.demoplayback)
{
// decide if it is time to grab the next message
if (cls.signon == SIGNONS) // always grab until fully connected
{
if (cls.timedemo && !benchmark)
{
if (host_framecount == cls.td_lastframe)
return 0; // already read this frame's message
cls.td_lastframe = host_framecount;
// if this is the second frame, grab the real td_starttime
// so the bogus time on the first frame doesn't count
if (host_framecount == cls.td_startframe + 1 && !benchmark){
cls.td_starttime = realtime;
}
else if (host_framecount == cls.td_startframe + 30 && key_dest == key_benchmark) { bBenchmarkStarted = true; benchmark = true; }// Ignore first sec for the benchmark
}
else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0])
{
return 0; // don't need another message yet
}
}
// get the next message
fread (&net_message.cursize, 4, 1, cls.demofile);
VectorCopy (cl.mviewangles[0], cl.mviewangles[1]);
for (i=0 ; i<3 ; i++)
{
r = fread (&f, 4, 1, cls.demofile);
cl.mviewangles[0][i] = LittleFloat (f);
}
net_message.cursize = LittleLong (net_message.cursize);
if (net_message.cursize > MAX_MSGLEN)
Sys_Error ("Demo message > MAX_MSGLEN");
r = fread (net_message.data, net_message.cursize, 1, cls.demofile);
if (r != 1)
{
CL_StopPlayback ();
return 0;
}
return 1;
}
while (1)
{
r = NET_GetMessage (cls.netcon);
if (r != 1 && r != 2)
return r;
// discard nop keepalive message
if (net_message.cursize == 1 && net_message.data[0] == svc_nop)
Con_Printf ("<-- server to client keepalive\n");
else
break;
}
if (cls.demorecording)
CL_WriteDemoMessage ();
return r;
}
/*
====================
CL_Stop_f
stop recording a demo
====================
*/
void CL_Stop_f (void)
{
if (cmd_source != src_command)
return;
if (!cls.demorecording)
{
Con_Printf ("Not recording a demo.\n");
return;
}
// write a disconnect message to the demo file
SZ_Clear (&net_message);
MSG_WriteByte (&net_message, svc_disconnect);
CL_WriteDemoMessage ();
// finish up
fclose (cls.demofile);
cls.demofile = NULL;
cls.demorecording = false;
Con_Printf ("Completed demo\n");
}
/*
====================
CL_Record_f
record