mirror of
https://github.com/nzp-team/dquakeplus.git
synced 2024-11-10 06:31:40 +00:00
Initial commit
This commit is contained in:
commit
9314ffb79d
218 changed files with 83477 additions and 0 deletions
69
.github/workflows/build-eboot-and-release.yml
vendored
Normal file
69
.github/workflows/build-eboot-and-release.yml
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
name: Build EBOOTs and Publish Release
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
Compile-EBOOTs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: bmaupin/pspdev
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Get apt ready
|
||||||
|
run: |
|
||||||
|
apt update
|
||||||
|
apt install -y zip
|
||||||
|
- name: Build
|
||||||
|
working-directory: ./
|
||||||
|
run: |
|
||||||
|
cd source/libpspmath
|
||||||
|
make && make install
|
||||||
|
cd ../../
|
||||||
|
make -f MakePHAT install
|
||||||
|
make -f MakePHAT clean
|
||||||
|
make -f MakeSLIM install
|
||||||
|
- name: Generate Build Date
|
||||||
|
id: date
|
||||||
|
run: echo "::set-output name=date::$(date +'%Y-%m-%d-%H-%M-%S')"
|
||||||
|
- name: Zip EBOOTs
|
||||||
|
working-directory: ./build
|
||||||
|
run: |
|
||||||
|
zip -r psp-nzp-eboots.zip EBOOT.PBP EBOOT2000.PBP
|
||||||
|
- name: Delete Old Release
|
||||||
|
uses: dev-drprasad/delete-tag-and-release@v0.2.0
|
||||||
|
with:
|
||||||
|
delete_release: true
|
||||||
|
tag_name: bleeding-edge
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Create Release
|
||||||
|
id: create_release
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: bleeding-edge
|
||||||
|
release_name: Automated Release ${{ steps.date.outputs.date }}
|
||||||
|
body: |
|
||||||
|
This is a **bleeding edge** NZ:P PSP EBOOT release, stability is not guarenteed.
|
||||||
|
|
||||||
|
To install:
|
||||||
|
- Grab the .ZIP archive (psp-nzp-eboots.zip)
|
||||||
|
- Extract the contents of the .ZIP archive to `PSP/GAME/nzportable`.
|
||||||
|
- If on PSP SLIM, delete `EBOOT.PBP` and rename `EBOOT2000.PBP` to `EBOOT.PBP`.
|
||||||
|
draft: true
|
||||||
|
prerelease: false
|
||||||
|
- name: Upload EBOOT Archive
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./build/psp-nzp-eboots.zip
|
||||||
|
asset_name: psp-nzp-eboots.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
|
- name: Publish Release
|
||||||
|
uses: StuYarrow/publish-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
id: ${{ steps.create_release.outputs.id }}
|
||||||
|
|
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
build/*
|
||||||
|
*.o
|
||||||
|
*.elf
|
||||||
|
*.PBP
|
||||||
|
*.prx
|
||||||
|
*.SFO
|
||||||
|
PARAM.SFO
|
||||||
|
EBOOT.PBP
|
||||||
|
EBOOT2000.PBP
|
87
LICENSE
Normal file
87
LICENSE
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
Preamble
|
||||||
|
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
|
||||||
|
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
|
||||||
|
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
|
||||||
|
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
134
MakePHAT
Normal file
134
MakePHAT
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
PSPSDK = $(shell psp-config --pspsdk-path)
|
||||||
|
PSPLIBSDIR = $(PSPSDK)/..
|
||||||
|
|
||||||
|
TARGET = nzportable
|
||||||
|
|
||||||
|
PSP_EBOOT_TITLE = Nazi Zombies Portable Reboot
|
||||||
|
|
||||||
|
PSP_EBOOT_ICON = source/psp/pics/icon.png
|
||||||
|
PSP_EBOOT_SND0 = source/psp/pics/snd0.at3
|
||||||
|
PSP_EBOOT_PIC1 = source/psp/pics/pic.png
|
||||||
|
|
||||||
|
PSP_FW_VERSION=660
|
||||||
|
|
||||||
|
MODE=-DKERNEL_MODE
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_PRX = 1
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
source/psp/battery.o \
|
||||||
|
source/thread.o \
|
||||||
|
source/psp/VramExt.o \
|
||||||
|
source/psp/input.o \
|
||||||
|
source/psp/main.o \
|
||||||
|
source/psp/math.o \
|
||||||
|
source/psp/sound.o \
|
||||||
|
source/psp/system.o \
|
||||||
|
source/psp/module.o \
|
||||||
|
source/psp/network.o \
|
||||||
|
source/psp/network_psp.o \
|
||||||
|
source/psp/gethost.o \
|
||||||
|
source/psp/fnmatch.o \
|
||||||
|
source/psp/cd.o \
|
||||||
|
source/psp/mp3.o \
|
||||||
|
source/psp/Random.o \
|
||||||
|
\
|
||||||
|
source/chase.o \
|
||||||
|
source/cl_demo.o \
|
||||||
|
source/cl_input.o \
|
||||||
|
source/cl_main.o \
|
||||||
|
source/cl_parse.o \
|
||||||
|
source/cl_tent.o \
|
||||||
|
source/cl_slist.o \
|
||||||
|
source/cmd.o \
|
||||||
|
source/common.o \
|
||||||
|
source/console.o \
|
||||||
|
source/crc.o \
|
||||||
|
source/cvar.o \
|
||||||
|
source/host.o \
|
||||||
|
source/host_cmd.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/snd_dma.o \
|
||||||
|
source/snd_mem.o \
|
||||||
|
source/snd_mix.o \
|
||||||
|
source/cl_hud.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/crypter.o
|
||||||
|
|
||||||
|
HARDWARE_VIDEO_ONLY_OBJS = \
|
||||||
|
source/psp/wad3.o \
|
||||||
|
source/psp/clipping.o \
|
||||||
|
source/psp/vram.o \
|
||||||
|
source/psp/video_hardware.o \
|
||||||
|
source/psp/video_hardware_resample.o \
|
||||||
|
source/psp/video_hardware_images.o \
|
||||||
|
source/psp/video_hardware_fullbright.o \
|
||||||
|
source/psp/video_hardware_hlmdl.o \
|
||||||
|
source/psp/video_hardware_draw.o \
|
||||||
|
source/psp/video_hardware_entity_fragment.o \
|
||||||
|
source/psp/video_hardware_QMB.o \
|
||||||
|
source/psp/video_hardware_decals_QMB.o \
|
||||||
|
source/psp/video_hardware_part.o \
|
||||||
|
source/psp/video_hardware_light.o \
|
||||||
|
source/psp/video_hardware_main.o \
|
||||||
|
source/psp/video_hardware_mesh.o \
|
||||||
|
source/psp/video_hardware_mhex2.o \
|
||||||
|
source/psp/video_hardware_misc.o \
|
||||||
|
source/psp/video_hardware_model.o \
|
||||||
|
source/psp/video_hardware_screen.o \
|
||||||
|
source/psp/video_hardware_surface.o \
|
||||||
|
source/psp/video_hardware_warp.o \
|
||||||
|
source/psp/video_hardware_fog.o \
|
||||||
|
source/psp/video_hardware_dxtn.o
|
||||||
|
HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OBJS = $(COMMON_OBJS) $(HARDWARE_VIDEO_ONLY_OBJS)
|
||||||
|
|
||||||
|
|
||||||
|
#LIBS = -lpspaudiolib -lpspaudio -lpspgum -lpspgu -lpsprtc -lpsppower -lpspwlan -lstdc++ -lm
|
||||||
|
|
||||||
|
GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu -lpspvram
|
||||||
|
AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspmp3 source/psp/m33libs/libpspaudiocodec.a source/psp/m33libs/libpspkubridge.a
|
||||||
|
|
||||||
|
MISC_LIBS = -lpsprtc -lpspmath -lpsppower -lpsphprm -ljpeg -lpng source/psp/m33libs/libz.a source/psp/iridlibs/libPerf.a
|
||||||
|
NET_LIBS = -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl
|
||||||
|
STD_LIBS = -lstdc++ -lm -lc
|
||||||
|
LIBS = $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) $(NET_LIBS)
|
||||||
|
|
||||||
|
CFLAGS = -ffast-math -O3 -G0 -Wall -Did386="0" -DPSP $(MODE) $(HARDWARE_VIDEO_ONLY_FLAGS) -DSWIZZLE32 -DPSP_MP3_HWDECODE -DFULLBRIGHT -DHL_RENDER -Wno-strict-aliasing -DPSP_VFPU
|
||||||
|
CXXFLAGS = -fno-rtti -Wcast-qual -Wno-write-strings -Wno-sign-compare -Wno-strict-aliasing
|
||||||
|
ASFLAGS = $(CFLAGS) -c
|
||||||
|
|
||||||
|
include $(PSPSDK)/lib/build.mak
|
||||||
|
|
||||||
|
ifneq ($(VS_PATH),)
|
||||||
|
CC = vs-psp-gcc
|
||||||
|
CXX = vs-psp-g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
install: EBOOT.PBP
|
||||||
|
mkdir -p build/exec/
|
||||||
|
mv EBOOT.PBP build/
|
||||||
|
mv *.elf build/exec/
|
||||||
|
mv *.prx build/exec/
|
||||||
|
mv *.SFO build/exec/
|
||||||
|
@echo DONE
|
136
MakeSLIM
Normal file
136
MakeSLIM
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
PSPSDK = $(shell psp-config --pspsdk-path)
|
||||||
|
PSPLIBSDIR = $(PSPSDK)/..
|
||||||
|
|
||||||
|
TARGET = nzportable
|
||||||
|
|
||||||
|
PSP_EBOOT_TITLE = Nazi Zombies Portable Reboot
|
||||||
|
|
||||||
|
PSP_EBOOT_ICON = source/psp/pics/icon.png
|
||||||
|
PSP_EBOOT_SND0 = source/psp/pics/snd0.at3
|
||||||
|
PSP_EBOOT_PIC1 = source/psp/pics/pic.png
|
||||||
|
|
||||||
|
PSP_FW_VERSION=660
|
||||||
|
|
||||||
|
PSP_LARGE_MEMORY = 1
|
||||||
|
|
||||||
|
MODE=-DKERNEL_MODE
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_PRX = 1
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
source/psp/battery.o \
|
||||||
|
source/thread.o \
|
||||||
|
source/psp/VramExt.o \
|
||||||
|
source/psp/input.o \
|
||||||
|
source/psp/main.o \
|
||||||
|
source/psp/math.o \
|
||||||
|
source/psp/sound.o \
|
||||||
|
source/psp/system.o \
|
||||||
|
source/psp/module.o \
|
||||||
|
source/psp/network.o \
|
||||||
|
source/psp/network_psp.o \
|
||||||
|
source/psp/gethost.o \
|
||||||
|
source/psp/fnmatch.o \
|
||||||
|
source/psp/cd.o \
|
||||||
|
source/psp/mp3.o \
|
||||||
|
source/psp/Random.o \
|
||||||
|
\
|
||||||
|
source/chase.o \
|
||||||
|
source/cl_demo.o \
|
||||||
|
source/cl_input.o \
|
||||||
|
source/cl_main.o \
|
||||||
|
source/cl_parse.o \
|
||||||
|
source/cl_tent.o \
|
||||||
|
source/cl_slist.o \
|
||||||
|
source/cmd.o \
|
||||||
|
source/common.o \
|
||||||
|
source/console.o \
|
||||||
|
source/crc.o \
|
||||||
|
source/cvar.o \
|
||||||
|
source/host.o \
|
||||||
|
source/host_cmd.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/snd_dma.o \
|
||||||
|
source/snd_mem.o \
|
||||||
|
source/snd_mix.o \
|
||||||
|
source/cl_hud.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/crypter.o
|
||||||
|
|
||||||
|
HARDWARE_VIDEO_ONLY_OBJS = \
|
||||||
|
source/psp/wad3.o \
|
||||||
|
source/psp/clipping.o \
|
||||||
|
source/psp/vram.o \
|
||||||
|
source/psp/video_hardware.o \
|
||||||
|
source/psp/video_hardware_resample.o \
|
||||||
|
source/psp/video_hardware_images.o \
|
||||||
|
source/psp/video_hardware_fullbright.o \
|
||||||
|
source/psp/video_hardware_hlmdl.o \
|
||||||
|
source/psp/video_hardware_draw.o \
|
||||||
|
source/psp/video_hardware_entity_fragment.o \
|
||||||
|
source/psp/video_hardware_QMB.o \
|
||||||
|
source/psp/video_hardware_decals_QMB.o \
|
||||||
|
source/psp/video_hardware_part.o \
|
||||||
|
source/psp/video_hardware_light.o \
|
||||||
|
source/psp/video_hardware_main.o \
|
||||||
|
source/psp/video_hardware_mesh.o \
|
||||||
|
source/psp/video_hardware_mhex2.o \
|
||||||
|
source/psp/video_hardware_misc.o \
|
||||||
|
source/psp/video_hardware_model.o \
|
||||||
|
source/psp/video_hardware_screen.o \
|
||||||
|
source/psp/video_hardware_surface.o \
|
||||||
|
source/psp/video_hardware_warp.o \
|
||||||
|
source/psp/video_hardware_fog.o \
|
||||||
|
source/psp/video_hardware_dxtn.o
|
||||||
|
HARDWARE_VIDEO_ONLY_FLAGS = -DPSP_HARDWARE_VIDEO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OBJS = $(COMMON_OBJS) $(HARDWARE_VIDEO_ONLY_OBJS)
|
||||||
|
|
||||||
|
|
||||||
|
#LIBS = -lpspaudiolib -lpspaudio -lpspgum -lpspgu -lpsprtc -lpsppower -lpspwlan -lstdc++ -lm
|
||||||
|
|
||||||
|
GU_LIBS = -lpspgum_vfpu -lpspvfpu -lpspgu -lpspvram
|
||||||
|
AUDIO_LIBS = -lpspaudiolib -lpspaudio -lpspmp3 source/psp/m33libs/libpspaudiocodec.a source/psp/m33libs/libpspkubridge.a
|
||||||
|
|
||||||
|
MISC_LIBS = -lpsprtc -lpsppower -lpspmath -lpsphprm -ljpeg -lpng source/psp/m33libs/libz.a source/psp/iridlibs/libPerf.a
|
||||||
|
NET_LIBS = -lpspwlan -lpspnet_adhoc -lpspnet_adhocctl
|
||||||
|
STD_LIBS = -lstdc++ -lm -lc
|
||||||
|
LIBS = $(GU_LIBS) $(AUDIO_LIBS) $(MISC_LIBS) $(STD_LIBS) $(NET_LIBS)
|
||||||
|
|
||||||
|
CFLAGS = -ffast-math -O3 -G0 -Wall -Did386="0" -DPSP $(MODE) $(HARDWARE_VIDEO_ONLY_FLAGS) -DSWIZZLE32 -DSLIM -DPSP_MP3_HWDECODE -DFULLBRIGHT -DHL_RENDER -Wno-strict-aliasing -DPSP_VFPU
|
||||||
|
CXXFLAGS = -fno-rtti -Wcast-qual -Wno-write-strings -Wno-sign-compare -Wno-strict-aliasing
|
||||||
|
ASFLAGS = $(CFLAGS) -c
|
||||||
|
|
||||||
|
include $(PSPSDK)/lib/build.mak
|
||||||
|
|
||||||
|
ifneq ($(VS_PATH),)
|
||||||
|
CC = vs-psp-gcc
|
||||||
|
CXX = vs-psp-g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
install: EBOOT.PBP
|
||||||
|
mkdir -p build/exec/
|
||||||
|
mv EBOOT.PBP build/EBOOT2000.PBP
|
||||||
|
mv *.elf build/exec/
|
||||||
|
mv *.prx build/exec/
|
||||||
|
mv *.SFO build/exec/
|
||||||
|
@echo DONE
|
22
README.md
Normal file
22
README.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Nazi Zombies: Portable dQuakePlus
|
||||||
|
|
||||||
|
## About
|
||||||
|
This repository contains the PSP engine for NZ:P, based on dQuakePlus and containing optimizations from the NZ:P Team, adQuake, and Xash3D-PSP, as well as NZ:P-specific feature implementation. It has also been modified to build on the latest versions of the [PSPSDK](https://github.com/pspdev/pspsdk).
|
||||||
|
|
||||||
|
## Building (Advanced)
|
||||||
|
Building requires a full install of [psptoolchain](https://github.com/pspdev/psptoolchain/). You can either follow the instructions on the GitHub repository or use a Docker container (we recommend [bmaupin](https://hub.docker.com/r/bmaupin/pspdev)'s)!
|
||||||
|
|
||||||
|
With the psptoolchain installed, you now need to install `libpspmath`, which we have included in the GitHub repository:
|
||||||
|
```bash
|
||||||
|
cd source/libpspmath
|
||||||
|
make && make install
|
||||||
|
```
|
||||||
|
Now you can navigate back to the root of the repository and build an `EBOOT`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ../../
|
||||||
|
make -f MakePHAT install # for PSP PHAT/1000
|
||||||
|
make -f MakeSLIM install # for any other model
|
||||||
|
```
|
||||||
|
|
||||||
|
We also provide prebuilt EBOOTs on the [Releases](https://github.com/nzp-team/dquakeplus/releases/tag/bleeding-edge) page.
|
37
source/anorm_dots.h
Normal file
37
source/anorm_dots.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
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}
|
||||||
|
}
|
181
source/anorms.h
Normal file
181
source/anorms.h
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
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},
|
326
source/bspfile.h
Normal file
326
source/bspfile.h
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
/*
|
||||||
|
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 8192
|
||||||
|
#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 BSPVERSION 29
|
||||||
|
#define HL_BSPVERSION 30
|
||||||
|
#define NZP_BSPVERSION 1337
|
||||||
|
#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
|
||||||
|
} dnode_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int planenum;
|
||||||
|
short children[2]; // negative numbers are contents
|
||||||
|
} dclipnode_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
|
||||||
|
} dedge_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
|
||||||
|
} dface_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];
|
||||||
|
} dleaf_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, char *key, char *value);
|
||||||
|
char *ValueForKey (entity_t *ent, char *key);
|
||||||
|
// will return "" if not present
|
||||||
|
|
||||||
|
vec_t FloatForKey (entity_t *ent, char *key);
|
||||||
|
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec);
|
||||||
|
|
||||||
|
epair_t *ParseEpair (void);
|
||||||
|
|
||||||
|
#endif
|
31
source/cdaudio.h
Normal file
31
source/cdaudio.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
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, qboolean looping);
|
||||||
|
void CDAudio_Stop(void);
|
||||||
|
void CDAudio_Pause(void);
|
||||||
|
void CDAudio_Resume(void);
|
||||||
|
void CDAudio_Shutdown(void);
|
||||||
|
void CDAudio_Update(void);
|
||||||
|
void CDAudio_Next(void);
|
||||||
|
void CDAudio_Prev(void);
|
||||||
|
void CDAudio_PrintMusicList(void);
|
||||||
|
void CDAudio_Track(char* trackname);
|
182
source/chase.c
Normal file
182
source/chase.c
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
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_t chase_back = {"chase_back", "100"};
|
||||||
|
cvar_t chase_up = {"chase_up", "16"};
|
||||||
|
cvar_t chase_right = {"chase_right", "0"};
|
||||||
|
cvar_t chase_active = {"chase_active", "0"};
|
||||||
|
cvar_t chase_roll = {"chase_roll", "0"};
|
||||||
|
cvar_t chase_yaw = {"chase_yaw", "0"};
|
||||||
|
cvar_t chase_pitch = {"chase_pitch", "0"};
|
||||||
|
|
||||||
|
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);
|
||||||
|
Cvar_RegisterVariable (&chase_roll);
|
||||||
|
Cvar_RegisterVariable (&chase_yaw);
|
||||||
|
Cvar_RegisterVariable (&chase_pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define NUM_TESTS 64 (delete)
|
||||||
|
#define CHASE_DEST_OFFSET 2.0f
|
||||||
|
*/
|
||||||
|
|
||||||
|
qboolean chase_nodraw;
|
||||||
|
|
||||||
|
#define NUM_TESTS 64
|
||||||
|
#define CHASE_DEST_OFFSET 2.0f
|
||||||
|
|
||||||
|
void Chase_Update (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float dist;
|
||||||
|
vec3_t forward, up, right;
|
||||||
|
vec3_t dest, stop;
|
||||||
|
int best;
|
||||||
|
int viewcontents;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// take the contents of the view leaf
|
||||||
|
viewcontents = (Mod_PointInLeaf (r_refdef.vieworg, cl.worldmodel))->contents;
|
||||||
|
|
||||||
|
for (best = 0; best < NUM_TESTS; best++)
|
||||||
|
{
|
||||||
|
float chase_newdest[3];
|
||||||
|
|
||||||
|
chase_newdest[0] = r_refdef.vieworg[0] + (chase_dest[0] - r_refdef.vieworg[0]) * best / NUM_TESTS;
|
||||||
|
chase_newdest[1] = r_refdef.vieworg[1] + (chase_dest[1] - r_refdef.vieworg[1]) * best / NUM_TESTS;
|
||||||
|
chase_newdest[2] = r_refdef.vieworg[2] + (chase_dest[2] - r_refdef.vieworg[2]) * best / NUM_TESTS;
|
||||||
|
|
||||||
|
// check for a leaf hit with different contents
|
||||||
|
if ((Mod_PointInLeaf (chase_newdest, cl.worldmodel))->contents != viewcontents)
|
||||||
|
{
|
||||||
|
// go back to the previous best as this one is bad
|
||||||
|
// unless the first one was also bad, (viewleaf contents != viewleaf contents!!!)
|
||||||
|
if (best > 0)
|
||||||
|
best--;
|
||||||
|
else best = NUM_TESTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// certain surfaces can be viewed at an oblique enough angle that they are partially clipped
|
||||||
|
// by znear, so now we fix that too...
|
||||||
|
for (; best >= 0; best--)
|
||||||
|
{
|
||||||
|
// number of matches
|
||||||
|
int nummatches = 0;
|
||||||
|
|
||||||
|
// adjust
|
||||||
|
chase_dest[0] = r_refdef.vieworg[0] + (chase_dest[0] - r_refdef.vieworg[0]) * best / NUM_TESTS;
|
||||||
|
chase_dest[1] = r_refdef.vieworg[1] + (chase_dest[1] - r_refdef.vieworg[1]) * best / NUM_TESTS;
|
||||||
|
chase_dest[2] = r_refdef.vieworg[2] + (chase_dest[2] - r_refdef.vieworg[2]) * best / NUM_TESTS;
|
||||||
|
|
||||||
|
// move x to neg
|
||||||
|
chase_dest[0] -= CHASE_DEST_OFFSET;
|
||||||
|
if ((Mod_PointInLeaf (chase_dest, cl.worldmodel))->contents == viewcontents) nummatches++;
|
||||||
|
chase_dest[0] += CHASE_DEST_OFFSET;
|
||||||
|
|
||||||
|
// move x to pos
|
||||||
|
chase_dest[0] += CHASE_DEST_OFFSET;
|
||||||
|
if ((Mod_PointInLeaf (chase_dest, cl.worldmodel))->contents == viewcontents) nummatches++;
|
||||||
|
chase_dest[0] -= CHASE_DEST_OFFSET;
|
||||||
|
|
||||||
|
// move y to neg
|
||||||
|
chase_dest[1] -= CHASE_DEST_OFFSET;
|
||||||
|
if ((Mod_PointInLeaf (chase_dest, cl.worldmodel))->contents == viewcontents) nummatches++;
|
||||||
|
chase_dest[1] += CHASE_DEST_OFFSET;
|
||||||
|
|
||||||
|
// move y to pos
|
||||||
|
chase_dest[1] += CHASE_DEST_OFFSET;
|
||||||
|
if ((Mod_PointInLeaf (chase_dest, cl.worldmodel))->contents == viewcontents) nummatches++;
|
||||||
|
chase_dest[1] -= CHASE_DEST_OFFSET;
|
||||||
|
|
||||||
|
// move z to neg
|
||||||
|
chase_dest[2] -= CHASE_DEST_OFFSET;
|
||||||
|
if ((Mod_PointInLeaf (chase_dest, cl.worldmodel))->contents == viewcontents) nummatches++;
|
||||||
|
chase_dest[2] += CHASE_DEST_OFFSET;
|
||||||
|
|
||||||
|
// move z to pos
|
||||||
|
chase_dest[2] += CHASE_DEST_OFFSET;
|
||||||
|
if ((Mod_PointInLeaf (chase_dest, cl.worldmodel))->contents == viewcontents) nummatches++;
|
||||||
|
chase_dest[2] -= CHASE_DEST_OFFSET;
|
||||||
|
|
||||||
|
// all tests passed so we're good!
|
||||||
|
if (nummatches == 6) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
r_refdef.viewangles[PITCH] = -vfpu_atanf(stop[2] / dist) / M_PI * 180;
|
||||||
|
#else
|
||||||
|
r_refdef.viewangles[PITCH] = -atan(stop[2] / dist) / M_PI * 180;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// move towards destination
|
||||||
|
VectorCopy (chase_dest, r_refdef.vieworg);
|
||||||
|
}
|
||||||
|
|
380
source/cl_demo.c
Normal file
380
source/cl_demo.c
Normal file
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Sys_FileClose(cls.demofile);
|
||||||
|
cls.demoplayback = false;
|
||||||
|
cls.demofile = -1;
|
||||||
|
cls.state = ca_disconnected;
|
||||||
|
|
||||||
|
if (cls.timedemo)
|
||||||
|
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);
|
||||||
|
Sys_FileWrite(cls.demofile, &len, 4);
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
f = LittleFloat (cl.viewangles[i]);
|
||||||
|
Sys_FileWrite(cls.demofile, &f, 4);
|
||||||
|
}
|
||||||
|
Sys_FileWrite(cls.demofile, net_message.data, net_message.cursize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
CL_GetMessage
|
||||||
|
|
||||||
|
Handles recording and playback of demos, on top of NET_ code
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
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) // allways grab until fully connected
|
||||||
|
{
|
||||||
|
if (cls.timedemo)
|
||||||
|
{
|
||||||
|
if (host_framecount == cls.td_lastframe)
|
||||||
|
return 0; // allready 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)
|
||||||
|
cls.td_starttime = realtime;
|
||||||
|
}
|
||||||
|
else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0])
|
||||||
|
{
|
||||||
|
return 0; // don't need another message yet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the next message
|
||||||
|
Sys_FileRead(cls.demofile, &net_message.cursize, 4);
|
||||||
|
VectorCopy (cl.mviewangles[0], cl.mviewangles[1]);
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
r = Sys_FileRead(cls.demofile, &f, 4) / 4;
|
||||||
|
cl.mviewangles[0][i] = LittleFloat (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
net_message.cursize = LittleLong (net_message.cursize);
|
||||||
|
if (net_message.cursize > MAX_MSGLEN)
|
||||||
|
Sys_Error ("Demo message (0x%08x) > MAX_MSGLEN (%d)", net_message.cursize, MAX_MSGLEN);
|
||||||
|
r = Sys_FileRead(cls.demofile, net_message.data, net_message.cursize) / net_message.cursize;
|
||||||
|
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
|
||||||
|
Sys_FileClose(cls.demofile);
|
||||||
|
cls.demofile = -1;
|
||||||
|
cls.demorecording = false;
|
||||||
|
Con_Printf ("Completed demo\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
CL_Record_f
|
||||||
|
|
||||||
|
record <demoname> <map> [cd track]
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
void CL_Record_f (void)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
char name[MAX_OSPATH];
|
||||||
|
int track;
|
||||||
|
char forcetrack[16];
|
||||||
|
|
||||||
|
if (cmd_source != src_command)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c = Cmd_Argc();
|
||||||
|
if (c != 2 && c != 3 && c != 4)
|
||||||
|
{
|
||||||
|
Con_Printf ("record <demoname> [<map> [cd track]]\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strstr(Cmd_Argv(1), ".."))
|
||||||
|
{
|
||||||
|
Con_Printf ("Relative pathnames are not allowed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 2 && cls.state == ca_connected)
|
||||||
|
{
|
||||||
|
Con_Printf("Can not record - already connected to server\nClient demo recording must be started before connecting\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the forced cd track number, or -1
|
||||||
|
if (c == 4)
|
||||||
|
{
|
||||||
|
track = atoi(Cmd_Argv(3));
|
||||||
|
Con_Printf ("Forcing CD track to %i\n", cls.forcetrack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
track = -1;
|
||||||
|
|
||||||
|
sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
|
||||||
|
|
||||||
|
//
|
||||||
|
// start the map up
|
||||||
|
//
|
||||||
|
if (c > 2)
|
||||||
|
Cmd_ExecuteString ( va("map %s", Cmd_Argv(2)), src_command);
|
||||||
|
|
||||||
|
//
|
||||||
|
// open the demo file
|
||||||
|
//
|
||||||
|
COM_DefaultExtension (name, ".dem");
|
||||||
|
|
||||||
|
Con_Printf ("recording to %s.\n", name);
|
||||||
|
cls.demofile = Sys_FileOpenWrite(name);
|
||||||
|
if (cls.demofile < 0)
|
||||||
|
{
|
||||||
|
Con_Printf ("ERROR: couldn't open demo for writing.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.forcetrack = track;
|
||||||
|
sprintf(forcetrack, "%i\n", cls.forcetrack);
|
||||||
|
Sys_FileWrite(cls.demofile, forcetrack, strlen(forcetrack));
|
||||||
|
|
||||||
|
cls.demorecording = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
CL_PlayDemo_f
|
||||||
|
|
||||||
|
play [demoname]
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
static int CL_FileGetChar(int handle)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
if (Sys_FileRead(handle, &c, 1) != 1)
|
||||||
|
{
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_PlayDemo_f (void)
|
||||||
|
{
|
||||||
|
char name[256];
|
||||||
|
int c;
|
||||||
|
qboolean neg = false;
|
||||||
|
|
||||||
|
if (cmd_source != src_command)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Cmd_Argc() != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("play <demoname> : plays a demo\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// disconnect from server
|
||||||
|
//
|
||||||
|
CL_Disconnect ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// open the demo file
|
||||||
|
//
|
||||||
|
strcpy (name, Cmd_Argv(1));
|
||||||
|
COM_DefaultExtension (name, ".dem");
|
||||||
|
|
||||||
|
Con_Printf ("Playing demo from %s.\n", name);
|
||||||
|
COM_FOpenFile (name, &cls.demofile);
|
||||||
|
if (cls.demofile < 0)
|
||||||
|
{
|
||||||
|
Con_Printf ("ERROR: couldn't open demo for reading.\n");
|
||||||
|
cls.demonum = -1; // stop demo loop
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.demoplayback = true;
|
||||||
|
cls.state = ca_connected;
|
||||||
|
cls.forcetrack = 0;
|
||||||
|
|
||||||
|
while ((c = CL_FileGetChar(cls.demofile)) != '\n')
|
||||||
|
if (c == '-')
|
||||||
|
neg = true;
|
||||||
|
else
|
||||||
|
cls.forcetrack = cls.forcetrack * 10 + (c - '0');
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
cls.forcetrack = -cls.forcetrack;
|
||||||
|
// ZOID, fscanf is evil
|
||||||
|
// fscanf (cls.demofile, "%i\n", &cls.forcetrack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
CL_FinishTimeDemo
|
||||||
|
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
void CL_FinishTimeDemo (void)
|
||||||
|
{
|
||||||
|
int frames;
|
||||||
|
double time;
|
||||||
|
|
||||||
|
cls.timedemo = false;
|
||||||
|
|
||||||
|
// the first frame didn't count
|
||||||
|
frames = (host_framecount - cls.td_startframe) - 1;
|
||||||
|
time = realtime - cls.td_starttime;
|
||||||
|
if (time < 1)
|
||||||
|
time = 1;
|
||||||
|
Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
CL_TimeDemo_f
|
||||||
|
|
||||||
|
timedemo [demoname]
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
void CL_TimeDemo_f (void)
|
||||||
|
{
|
||||||
|
if (cmd_source != src_command)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Cmd_Argc() != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("timedemo <demoname> : gets demo speeds\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CL_PlayDemo_f ();
|
||||||
|
|
||||||
|
// cls.td_starttime will be grabbed at the second frame of the demo, so
|
||||||
|
// all the loading time doesn't get counted
|
||||||
|
|
||||||
|
cls.timedemo = true;
|
||||||
|
cls.td_startframe = host_framecount;
|
||||||
|
cls.td_lastframe = -1; // get a new message this frame
|
||||||
|
}
|
||||||
|
|
1423
source/cl_hud.c
Normal file
1423
source/cl_hud.c
Normal file
File diff suppressed because it is too large
Load diff
53
source/cl_hud.h
Normal file
53
source/cl_hud.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// the status bar is only redrawn if something has changed, but if anything
|
||||||
|
// does, the entire thing will be redrawn for the next vid.numpages frames.
|
||||||
|
|
||||||
|
void HUD_Init (void);
|
||||||
|
|
||||||
|
// call whenever any of the client stats represented on the sbar changes
|
||||||
|
|
||||||
|
void HUD_Draw (void);
|
||||||
|
// called every frame by screen
|
||||||
|
|
||||||
|
// called each frame after the level has been completed
|
||||||
|
void HUD_NewMap (void);
|
||||||
|
|
||||||
|
extern double HUD_Change_time;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//achievement stuff
|
||||||
|
#define MAX_ACHIEVEMENTS 5//23
|
||||||
|
typedef struct achievement_list_s
|
||||||
|
{
|
||||||
|
qpic_t *img;
|
||||||
|
int unlocked;
|
||||||
|
char name[64];
|
||||||
|
char description[256];
|
||||||
|
int progress;
|
||||||
|
} achievement_list_t;
|
||||||
|
|
||||||
|
void Achievement_Init (void);
|
||||||
|
extern achievement_list_t achievement_list[MAX_ACHIEVEMENTS];
|
||||||
|
extern qpic_t *achievement_locked;
|
||||||
|
|
||||||
|
void HUD_Parse_Achievement (int ach);
|
696
source/cl_input.c
Normal file
696
source/cl_input.c
Normal file
|
@ -0,0 +1,696 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// cl.input.c -- builds an intended movement command to send to the server
|
||||||
|
|
||||||
|
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
|
||||||
|
// rights reserved.
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
KEY BUTTONS
|
||||||
|
|
||||||
|
Continuous button event tracking is complicated by the fact that two different
|
||||||
|
input sources (say, mouse button 1 and the control key) can both press the
|
||||||
|
same button, but the button should only be released when both of the
|
||||||
|
pressing key have been released.
|
||||||
|
|
||||||
|
When a key event issues a button command (+forward, +attack, etc), it appends
|
||||||
|
its key number as a parameter to the command so it can be matched up with
|
||||||
|
the release.
|
||||||
|
|
||||||
|
state bit 0 is the current state of the key
|
||||||
|
state bit 1 is edge triggered on the up to down transition
|
||||||
|
state bit 2 is edge triggered on the down to up transition
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
kbutton_t in_klook;//Heffo - mlook cvar
|
||||||
|
kbutton_t in_left, in_right, in_forward, in_back;
|
||||||
|
kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright;
|
||||||
|
kbutton_t in_strafe, in_speed, in_use, in_jump, in_attack, in_grenade, in_reload, in_switch, in_knife, in_aim;
|
||||||
|
kbutton_t in_up, in_down;
|
||||||
|
|
||||||
|
int in_impulse;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void KeyDown (kbutton_t *b)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
c = Cmd_Argv(1);
|
||||||
|
if (c[0])
|
||||||
|
k = atoi(c);
|
||||||
|
else
|
||||||
|
k = -1; // typed manually at the console for continuous down
|
||||||
|
|
||||||
|
if (k == b->down[0] || k == b->down[1])
|
||||||
|
return; // repeating key
|
||||||
|
|
||||||
|
if (!b->down[0])
|
||||||
|
b->down[0] = k;
|
||||||
|
else if (!b->down[1])
|
||||||
|
b->down[1] = k;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con_Printf ("Three keys down for a button!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b->state & 1)
|
||||||
|
return; // still down
|
||||||
|
b->state |= 1 + 2; // down + impulse down
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyUp (kbutton_t *b)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
c = Cmd_Argv(1);
|
||||||
|
if (c[0])
|
||||||
|
k = atoi(c);
|
||||||
|
else
|
||||||
|
{ // typed manually at the console, assume for unsticking, so clear all
|
||||||
|
b->down[0] = b->down[1] = 0;
|
||||||
|
b->state = 4; // impulse up
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b->down[0] == k)
|
||||||
|
b->down[0] = 0;
|
||||||
|
else if (b->down[1] == k)
|
||||||
|
b->down[1] = 0;
|
||||||
|
else
|
||||||
|
return; // key up without coresponding down (menu pass through)
|
||||||
|
if (b->down[0] || b->down[1])
|
||||||
|
return; // some other key is still holding it down
|
||||||
|
|
||||||
|
if (!(b->state & 1))
|
||||||
|
return; // still up (this should not happen)
|
||||||
|
b->state &= ~1; // now up
|
||||||
|
b->state |= 4; // impulse up
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean croshhairmoving = false;
|
||||||
|
|
||||||
|
void IN_KLookDown (void) {KeyDown(&in_klook);}
|
||||||
|
void IN_KLookUp (void) {KeyUp(&in_klook);}
|
||||||
|
|
||||||
|
/*void IN_MLookDown (void) {KeyDown(&in_mlook);}
|
||||||
|
void IN_MLookUp (void){
|
||||||
|
KeyUp(&in_mlook);
|
||||||
|
if ( !(in_mlook.state&1) && lookspring.value)
|
||||||
|
V_StartPitchDrift();
|
||||||
|
} Heffo - mlook cvar*/
|
||||||
|
|
||||||
|
void IN_UpDown(void) {KeyDown(&in_up);}
|
||||||
|
void IN_UpUp(void) {KeyUp(&in_up);}
|
||||||
|
void IN_DownDown(void) {KeyDown(&in_down);}
|
||||||
|
void IN_DownUp(void) {KeyUp(&in_down);}
|
||||||
|
void IN_LeftDown(void) {KeyDown(&in_left);}
|
||||||
|
void IN_LeftUp(void) {KeyUp(&in_left);}
|
||||||
|
void IN_RightDown(void) {KeyDown(&in_right);}
|
||||||
|
void IN_RightUp(void) {KeyUp(&in_right);}
|
||||||
|
void IN_ForwardDown(void) {KeyDown(&in_forward);}
|
||||||
|
void IN_ForwardUp(void) {KeyUp(&in_forward);Cbuf_AddText("impulse 24\n");}
|
||||||
|
void IN_BackDown(void) {KeyDown(&in_back);}
|
||||||
|
void IN_BackUp(void) {KeyUp(&in_back);}
|
||||||
|
void IN_LookupDown(void) {KeyDown(&in_lookup);}
|
||||||
|
void IN_LookupUp(void) {KeyUp(&in_lookup);}
|
||||||
|
void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
|
||||||
|
void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
|
||||||
|
void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
|
||||||
|
void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
|
||||||
|
void IN_MoverightDown(void) {KeyDown(&in_moveright);}
|
||||||
|
void IN_MoverightUp(void) {KeyUp(&in_moveright);}
|
||||||
|
|
||||||
|
void IN_SpeedDown(void) {KeyDown(&in_speed);}
|
||||||
|
void IN_SpeedUp(void) {KeyUp(&in_speed);}
|
||||||
|
void IN_StrafeDown(void) {KeyDown(&in_strafe);}
|
||||||
|
void IN_StrafeUp(void) {KeyUp(&in_strafe);}
|
||||||
|
|
||||||
|
void IN_AttackDown(void) {KeyDown(&in_attack);}
|
||||||
|
void IN_AttackUp(void) {KeyUp(&in_attack);}
|
||||||
|
|
||||||
|
void IN_UseDown (void) {KeyDown(&in_use);}
|
||||||
|
void IN_UseUp (void) {KeyUp(&in_use);}
|
||||||
|
void IN_JumpDown (void) {KeyDown(&in_jump);}
|
||||||
|
void IN_JumpUp (void) {KeyUp(&in_jump);}
|
||||||
|
void IN_GrenadeDown (void) {KeyDown(&in_grenade);}
|
||||||
|
void IN_GrenadeUp (void) {KeyUp(&in_grenade);}
|
||||||
|
void IN_SwitchDown (void) {KeyDown(&in_switch);}
|
||||||
|
void IN_SwitchUp (void) {KeyUp(&in_switch);}
|
||||||
|
void IN_ReloadDown (void) {KeyDown(&in_reload);}
|
||||||
|
void IN_ReloadUp (void) {KeyUp(&in_reload);}
|
||||||
|
void IN_KnifeDown (void) {KeyDown(&in_knife);}
|
||||||
|
void IN_KnifeUp (void) {KeyUp(&in_knife);}
|
||||||
|
void IN_AimDown (void) {KeyDown(&in_aim);}
|
||||||
|
void IN_AimUp (void) {KeyUp(&in_aim);}
|
||||||
|
|
||||||
|
void IN_Impulse (void) {in_impulse=Q_atoi(Cmd_Argv(1));}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
CL_KeyState
|
||||||
|
|
||||||
|
Returns 0.25 if a key was pressed and released during the frame,
|
||||||
|
0.5 if it was pressed and held
|
||||||
|
0 if held then released, and
|
||||||
|
1.0 if held for the entire time
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
float CL_KeyState (kbutton_t *key)
|
||||||
|
{
|
||||||
|
float val;
|
||||||
|
qboolean impulsedown, impulseup, down;
|
||||||
|
|
||||||
|
impulsedown = key->state & 2;
|
||||||
|
impulseup = key->state & 4;
|
||||||
|
down = key->state & 1;
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
if (impulsedown && !impulseup)
|
||||||
|
{
|
||||||
|
if (down)
|
||||||
|
val = 0.5; // pressed and held this frame
|
||||||
|
else
|
||||||
|
val = 0; // I_Error ();
|
||||||
|
}
|
||||||
|
if (impulseup && !impulsedown)
|
||||||
|
{
|
||||||
|
if (down)
|
||||||
|
val = 0; // I_Error ();
|
||||||
|
else
|
||||||
|
val = 0; // released this frame
|
||||||
|
}
|
||||||
|
if (!impulsedown && !impulseup)
|
||||||
|
{
|
||||||
|
if (down)
|
||||||
|
val = 1.0; // held the entire frame
|
||||||
|
else
|
||||||
|
val = 0; // up the entire frame
|
||||||
|
}
|
||||||
|
if (impulsedown && impulseup)
|
||||||
|
{
|
||||||
|
if (down)
|
||||||
|
val = 0.75; // released and re-pressed this frame
|
||||||
|
else
|
||||||
|
val = 0.25; // pressed and released this frame
|
||||||
|
}
|
||||||
|
|
||||||
|
key->state &= 1; // clear impulses
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
cvar_t cl_upspeed = {"cl_upspeed","200"};
|
||||||
|
float cl_forwardspeed;
|
||||||
|
float cl_backspeed;
|
||||||
|
float cl_sidespeed;
|
||||||
|
|
||||||
|
cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"};
|
||||||
|
|
||||||
|
cvar_t cl_yawspeed = {"cl_yawspeed","140"};
|
||||||
|
cvar_t cl_pitchspeed = {"cl_pitchspeed","150"};
|
||||||
|
|
||||||
|
cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"};
|
||||||
|
|
||||||
|
cvar_t in_mlook = {"in_mlook", "1", true}; //Heffo - mlook cvar
|
||||||
|
cvar_t in_aimassist = {"in_aimassist", "1", true};
|
||||||
|
|
||||||
|
|
||||||
|
//Shpuld - Porting over lower sens for lower fov
|
||||||
|
extern cvar_t scr_fov;
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
CL_AdjustAngles
|
||||||
|
|
||||||
|
Moves the local angle positions
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
extern int original_fov, final_fov;
|
||||||
|
void CL_AdjustAngles (void)
|
||||||
|
{
|
||||||
|
float speed;
|
||||||
|
float up, down;
|
||||||
|
|
||||||
|
if (in_speed.state & 1)
|
||||||
|
speed = host_frametime * cl_anglespeedkey.value;
|
||||||
|
else
|
||||||
|
speed = host_frametime;
|
||||||
|
|
||||||
|
//shpuld begin
|
||||||
|
speed = speed * scr_fov.value/90;
|
||||||
|
//speed = speed*final_fov/original_fov;
|
||||||
|
//shpuld end
|
||||||
|
|
||||||
|
|
||||||
|
if (!(in_strafe.state & 1))
|
||||||
|
{
|
||||||
|
cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right);
|
||||||
|
cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left);
|
||||||
|
cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
|
||||||
|
}
|
||||||
|
if (in_klook.state & 1)
|
||||||
|
{
|
||||||
|
V_StopPitchDrift ();
|
||||||
|
cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * CL_KeyState (&in_forward);
|
||||||
|
cl.viewangles[PITCH] += speed*cl_pitchspeed.value * CL_KeyState (&in_back);
|
||||||
|
}
|
||||||
|
|
||||||
|
up = CL_KeyState (&in_lookup);
|
||||||
|
down = CL_KeyState(&in_lookdown);
|
||||||
|
|
||||||
|
cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * up;
|
||||||
|
cl.viewangles[PITCH] += speed*cl_pitchspeed.value * down;
|
||||||
|
|
||||||
|
if (up || down)
|
||||||
|
V_StopPitchDrift ();
|
||||||
|
|
||||||
|
if (cl.viewangles[PITCH] > 80)
|
||||||
|
cl.viewangles[PITCH] = 80;
|
||||||
|
if (cl.viewangles[PITCH] < -70)
|
||||||
|
cl.viewangles[PITCH] = -70;
|
||||||
|
|
||||||
|
if (cl.viewangles[ROLL] > 50)
|
||||||
|
cl.viewangles[ROLL] = 50;
|
||||||
|
if (cl.viewangles[ROLL] < -50)
|
||||||
|
cl.viewangles[ROLL] = -50;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
CL_BaseMove
|
||||||
|
|
||||||
|
Send the intended movement message to the server
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
|
||||||
|
cvar_t waypoint_mode;
|
||||||
|
float crosshair_opacity;
|
||||||
|
void CL_BaseMove (usercmd_t *cmd)
|
||||||
|
{
|
||||||
|
if (cls.signon != SIGNONS)//BLUBS CHANGED HERE
|
||||||
|
return;
|
||||||
|
|
||||||
|
CL_AdjustAngles ();
|
||||||
|
|
||||||
|
Q_memset (cmd, 0, sizeof(*cmd));
|
||||||
|
|
||||||
|
// Moto - we handle movespeed in QC now.
|
||||||
|
cl_backspeed = cl_forwardspeed = cl_sidespeed = sv_player->v.maxspeed;
|
||||||
|
|
||||||
|
// Throttle side and back speeds
|
||||||
|
cl_sidespeed *= 0.8;
|
||||||
|
cl_backspeed *= 0.7;
|
||||||
|
|
||||||
|
if (waypoint_mode.value)
|
||||||
|
cl_backspeed = cl_forwardspeed = cl_sidespeed *= 1.5;
|
||||||
|
|
||||||
|
if (in_strafe.state & 1)
|
||||||
|
{
|
||||||
|
cmd->sidemove += cl_sidespeed * CL_KeyState (&in_right);
|
||||||
|
cmd->sidemove -= cl_sidespeed * CL_KeyState (&in_left);
|
||||||
|
}
|
||||||
|
|
||||||
|
// crosshair stuff
|
||||||
|
croshhairmoving = true;
|
||||||
|
crosshair_opacity -= 8;
|
||||||
|
if (crosshair_opacity <= 128)
|
||||||
|
crosshair_opacity = 128;
|
||||||
|
|
||||||
|
cmd->sidemove += cl_sidespeed * CL_KeyState (&in_moveright);
|
||||||
|
cmd->sidemove -= cl_sidespeed * CL_KeyState (&in_moveleft);
|
||||||
|
|
||||||
|
cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up);
|
||||||
|
cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down);
|
||||||
|
|
||||||
|
if (! (in_klook.state & 1) )
|
||||||
|
{
|
||||||
|
cmd->forwardmove += cl_forwardspeed * CL_KeyState (&in_forward);
|
||||||
|
cmd->forwardmove -= cl_backspeed * CL_KeyState (&in_back);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// adjust for speed key
|
||||||
|
//
|
||||||
|
if (in_speed.state & 1)
|
||||||
|
{
|
||||||
|
cmd->forwardmove *= cl_movespeedkey.value;
|
||||||
|
cmd->sidemove *= cl_movespeedkey.value;
|
||||||
|
cmd->upmove *= cl_movespeedkey.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset crosshair
|
||||||
|
if (!CL_KeyState (&in_moveright) && !CL_KeyState (&in_moveleft) && !CL_KeyState (&in_forward) && !CL_KeyState (&in_back)) {
|
||||||
|
croshhairmoving = false;
|
||||||
|
|
||||||
|
crosshair_opacity += 22;
|
||||||
|
|
||||||
|
if (crosshair_opacity >= 255)
|
||||||
|
crosshair_opacity = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int infront(edict_t *ent1, edict_t *ent2)
|
||||||
|
{
|
||||||
|
vec3_t vec;
|
||||||
|
float dot;
|
||||||
|
VectorSubtract(ent2->v.origin,ent1->v.origin,vec);
|
||||||
|
VectorNormalize(vec);
|
||||||
|
|
||||||
|
vec3_t temp_angle,temp_forward,temp_right,temp_up;
|
||||||
|
VectorCopy(cl.viewangles,temp_angle);
|
||||||
|
|
||||||
|
AngleVectors(temp_angle,temp_forward,temp_right,temp_up);
|
||||||
|
|
||||||
|
dot = DotProduct(vec,temp_forward);
|
||||||
|
if(dot > 0.98)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EN_Find(int num,char *string)
|
||||||
|
{
|
||||||
|
edict_t *ed;
|
||||||
|
|
||||||
|
int e;
|
||||||
|
e = num;
|
||||||
|
|
||||||
|
for(e++; e < sv.num_edicts; e++)
|
||||||
|
{
|
||||||
|
ed = EDICT_NUM(e);
|
||||||
|
if(ed->free)
|
||||||
|
continue;
|
||||||
|
if(!strcmp(pr_strings + ed->v.classname,string))
|
||||||
|
{
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_Aim_Snap(void)
|
||||||
|
{
|
||||||
|
edict_t *z,*bz,*player;
|
||||||
|
int znum;
|
||||||
|
trace_t trace;
|
||||||
|
float bestDist = 10000;
|
||||||
|
vec3_t distVec, zOrg, pOrg;
|
||||||
|
//32 is v_ofs num
|
||||||
|
|
||||||
|
bz = sv.edicts;
|
||||||
|
|
||||||
|
int vofs = 32;//32 is actual v_ofs num
|
||||||
|
int aimOfs = -10;//30 is top of bbox, 20 is our goal, so -10
|
||||||
|
//Zombie body bbox vert max = 30
|
||||||
|
//20 is the offset of the height of the zombie that we're aiming at, 20 above the origin
|
||||||
|
//Crawler body bbox vert max = -15
|
||||||
|
|
||||||
|
//Equation = origin + bbox vertical offset - 20
|
||||||
|
|
||||||
|
player = EDICT_NUM(cl.viewentity);
|
||||||
|
VectorCopy(player->v.origin,pOrg);
|
||||||
|
pOrg[2] += vofs;
|
||||||
|
|
||||||
|
if (cl.perks & 64)
|
||||||
|
znum = EN_Find(0,"ai_zombie_head");
|
||||||
|
else
|
||||||
|
znum = EN_Find(0,"ai_zombie");
|
||||||
|
|
||||||
|
z = EDICT_NUM(znum);
|
||||||
|
VectorCopy(z->v.origin,zOrg);
|
||||||
|
zOrg[2] += z->v.maxs[2];//Setting to top of zomb ent
|
||||||
|
zOrg[2] += aimOfs;
|
||||||
|
|
||||||
|
while(znum != 0)
|
||||||
|
{
|
||||||
|
if((z->v.health > 0) && infront(player,z))
|
||||||
|
{
|
||||||
|
VectorCopy(z->v.origin,zOrg);
|
||||||
|
zOrg[2] += aimOfs;
|
||||||
|
VectorSubtract(pOrg,zOrg,distVec);
|
||||||
|
if(VectorLength(distVec) < bestDist)
|
||||||
|
{
|
||||||
|
trace = SV_Move (pOrg, vec3_origin, vec3_origin,zOrg, 1, player);
|
||||||
|
if (trace.fraction >= 1)
|
||||||
|
{
|
||||||
|
bestDist = VectorLength(distVec);
|
||||||
|
bz = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cl.perks & 64)
|
||||||
|
znum = EN_Find(znum,"ai_zombie_head");
|
||||||
|
else
|
||||||
|
znum = EN_Find(znum,"ai_zombie");
|
||||||
|
z = EDICT_NUM(znum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bz != sv.edicts)
|
||||||
|
{
|
||||||
|
VectorCopy(bz->v.origin,zOrg);
|
||||||
|
zOrg[2] += bz->v.maxs[2];//Setting to top of bbox
|
||||||
|
zOrg[2] += aimOfs;
|
||||||
|
VectorSubtract(zOrg,pOrg,distVec);
|
||||||
|
VectorNormalize(distVec);
|
||||||
|
vectoangles(distVec,distVec);
|
||||||
|
distVec[0] += (distVec[0] > 180)? -360 : 0;//Need to bound pitch around 0, from -180, to + 180
|
||||||
|
distVec[0] *= -1;//inverting pitch
|
||||||
|
|
||||||
|
if(distVec[0] < -70 || distVec[0] > 80)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VectorCopy(distVec,cl.viewangles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
CL_SendMove
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
int zoom_snap;
|
||||||
|
float angledelta(float a);
|
||||||
|
float deltaPitch,deltaYaw;
|
||||||
|
void CL_SendMove (usercmd_t *cmd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long int bits;
|
||||||
|
sizebuf_t buf;
|
||||||
|
byte data[128];
|
||||||
|
vec3_t tempv;
|
||||||
|
buf.maxsize = 128;
|
||||||
|
buf.cursize = 0;
|
||||||
|
buf.data = data;
|
||||||
|
|
||||||
|
cl.cmd = *cmd;
|
||||||
|
|
||||||
|
//==== Aim Assist Code ====
|
||||||
|
if((cl.stats[STAT_ZOOM]==1 || cl.stats[STAT_ZOOM]==2) && ((in_aimassist.value) || (cl.perks & 64)))
|
||||||
|
{
|
||||||
|
if(!zoom_snap)
|
||||||
|
{
|
||||||
|
|
||||||
|
CL_Aim_Snap();
|
||||||
|
zoom_snap = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
zoom_snap = 0;
|
||||||
|
|
||||||
|
//==== Sniper Scope Swaying ====
|
||||||
|
if(cl.stats[STAT_ZOOM] == 2)
|
||||||
|
{
|
||||||
|
vec3_t vang;
|
||||||
|
|
||||||
|
VectorCopy(cl.viewangles,vang);
|
||||||
|
|
||||||
|
vang[0] -= deltaPitch;
|
||||||
|
vang[1] -= deltaYaw;
|
||||||
|
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
deltaPitch =(vfpu_cosf(cl.time/0.7) + vfpu_cosf(cl.time) + vfpu_sinf(cl.time/1.1)) * 0.5;
|
||||||
|
deltaYaw = (vfpu_sinf(cl.time/0.4) + vfpu_cosf(cl.time/0.56) + vfpu_sinf(cl.time)) * 0.5;
|
||||||
|
#else
|
||||||
|
deltaPitch =(cos(cl.time/0.7) + cos(cl.time) + sin(cl.time/1.1)) * 0.5;
|
||||||
|
deltaYaw = (sin(cl.time/0.4) + cos(cl.time/0.56) + sin(cl.time)) * 0.5;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vang[0] += deltaPitch;
|
||||||
|
vang[1] += deltaYaw;
|
||||||
|
vang[0] = angledelta(vang[0]);
|
||||||
|
vang[1] = angledelta(vang[1]);
|
||||||
|
|
||||||
|
VectorCopy(vang,cl.viewangles);
|
||||||
|
//return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// send the movement message
|
||||||
|
//
|
||||||
|
MSG_WriteByte (&buf, clc_move);
|
||||||
|
|
||||||
|
MSG_WriteFloat (&buf, cl.mtime[0]); // so server can get ping times
|
||||||
|
|
||||||
|
VectorAdd(cl.gun_kick, cl.viewangles, tempv);
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
MSG_WriteFloat (&buf, tempv[i]);
|
||||||
|
|
||||||
|
MSG_WriteShort (&buf, cmd->forwardmove);
|
||||||
|
MSG_WriteShort (&buf, cmd->sidemove);
|
||||||
|
MSG_WriteShort (&buf, cmd->upmove);
|
||||||
|
|
||||||
|
//
|
||||||
|
// send button bits
|
||||||
|
//
|
||||||
|
bits = 0;
|
||||||
|
|
||||||
|
if (in_attack.state & 3 )
|
||||||
|
bits |= 1;
|
||||||
|
in_attack.state &= ~2;
|
||||||
|
|
||||||
|
if (in_jump.state & 3)
|
||||||
|
bits |= 2;
|
||||||
|
in_jump.state &= ~2;
|
||||||
|
|
||||||
|
if (in_grenade.state & 3)
|
||||||
|
bits |= 8;
|
||||||
|
in_grenade.state &= ~2;
|
||||||
|
|
||||||
|
if (in_switch.state & 3)
|
||||||
|
bits |= 16;
|
||||||
|
in_switch.state &= ~2;
|
||||||
|
|
||||||
|
if (in_reload.state & 3)
|
||||||
|
bits |= 32;
|
||||||
|
in_reload.state &= ~2;
|
||||||
|
|
||||||
|
if (in_knife.state & 3)
|
||||||
|
bits |= 64;
|
||||||
|
in_knife.state &= ~2;
|
||||||
|
|
||||||
|
if (in_use.state & 3)
|
||||||
|
bits |= 128;
|
||||||
|
in_use.state &= ~2;
|
||||||
|
|
||||||
|
if (in_aim.state & 3)
|
||||||
|
bits |= 256;
|
||||||
|
in_aim.state &= ~2;
|
||||||
|
|
||||||
|
MSG_WriteLong (&buf, bits);
|
||||||
|
|
||||||
|
MSG_WriteByte (&buf, in_impulse);
|
||||||
|
in_impulse = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// deliver the message
|
||||||
|
//
|
||||||
|
if (cls.demoplayback)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allways dump the first two message, because it may contain leftover inputs
|
||||||
|
// from the last level
|
||||||
|
//
|
||||||
|
if (++cl.movemessages <= 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1)
|
||||||
|
{
|
||||||
|
Con_Printf ("CL_SendMove: lost server connection\n");
|
||||||
|
CL_Disconnect ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
CL_InitInput
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void CL_InitInput (void)
|
||||||
|
{
|
||||||
|
Cmd_AddCommand ("+moveup",IN_UpDown);
|
||||||
|
Cmd_AddCommand ("-moveup",IN_UpUp);
|
||||||
|
Cmd_AddCommand ("+movedown",IN_DownDown);
|
||||||
|
Cmd_AddCommand ("-movedown",IN_DownUp);
|
||||||
|
Cmd_AddCommand ("+left",IN_LeftDown);
|
||||||
|
Cmd_AddCommand ("-left",IN_LeftUp);
|
||||||
|
Cmd_AddCommand ("+right",IN_RightDown);
|
||||||
|
Cmd_AddCommand ("-right",IN_RightUp);
|
||||||
|
Cmd_AddCommand ("+forward",IN_ForwardDown);
|
||||||
|
Cmd_AddCommand ("-forward",IN_ForwardUp);
|
||||||
|
Cmd_AddCommand ("+back",IN_BackDown);
|
||||||
|
Cmd_AddCommand ("-back",IN_BackUp);
|
||||||
|
Cmd_AddCommand ("+lookup", IN_LookupDown);
|
||||||
|
Cmd_AddCommand ("-lookup", IN_LookupUp);
|
||||||
|
Cmd_AddCommand ("+lookdown", IN_LookdownDown);
|
||||||
|
Cmd_AddCommand ("-lookdown", IN_LookdownUp);
|
||||||
|
Cmd_AddCommand ("+strafe", IN_StrafeDown);
|
||||||
|
Cmd_AddCommand ("-strafe", IN_StrafeUp);
|
||||||
|
Cmd_AddCommand ("+moveleft", IN_MoveleftDown);
|
||||||
|
Cmd_AddCommand ("-moveleft", IN_MoveleftUp);
|
||||||
|
Cmd_AddCommand ("+moveright", IN_MoverightDown);
|
||||||
|
Cmd_AddCommand ("-moveright", IN_MoverightUp);
|
||||||
|
Cmd_AddCommand ("+speed", IN_SpeedDown);
|
||||||
|
Cmd_AddCommand ("-speed", IN_SpeedUp);
|
||||||
|
Cmd_AddCommand ("+attack", IN_AttackDown);
|
||||||
|
Cmd_AddCommand ("-attack", IN_AttackUp);
|
||||||
|
Cmd_AddCommand ("+use", IN_UseDown);
|
||||||
|
Cmd_AddCommand ("-use", IN_UseUp);
|
||||||
|
Cmd_AddCommand ("+jump", IN_JumpDown);
|
||||||
|
Cmd_AddCommand ("-jump", IN_JumpUp);
|
||||||
|
Cmd_AddCommand ("+grenade", IN_GrenadeDown);
|
||||||
|
Cmd_AddCommand ("-grenade", IN_GrenadeUp);
|
||||||
|
Cmd_AddCommand ("+switch", IN_SwitchDown);
|
||||||
|
Cmd_AddCommand ("-switch", IN_SwitchUp);
|
||||||
|
Cmd_AddCommand ("+reload", IN_ReloadDown);
|
||||||
|
Cmd_AddCommand ("-reload", IN_ReloadUp);
|
||||||
|
Cmd_AddCommand ("+knife", IN_KnifeDown);
|
||||||
|
Cmd_AddCommand ("-knife", IN_KnifeUp);
|
||||||
|
Cmd_AddCommand ("+aim", IN_AimDown);
|
||||||
|
Cmd_AddCommand ("-aim", IN_AimUp);
|
||||||
|
Cmd_AddCommand ("impulse", IN_Impulse);
|
||||||
|
Cmd_AddCommand ("+klook", IN_KLookDown);
|
||||||
|
Cmd_AddCommand ("-klook", IN_KLookUp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
1106
source/cl_main.c
Normal file
1106
source/cl_main.c
Normal file
File diff suppressed because it is too large
Load diff
1382
source/cl_parse.c
Normal file
1382
source/cl_parse.c
Normal file
File diff suppressed because it is too large
Load diff
196
source/cl_slist.c
Normal file
196
source/cl_slist.c
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 1999,2000 contributors of the QuakeForge project
|
||||||
|
|
||||||
|
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"
|
||||||
|
#include "cl_slist.h"
|
||||||
|
|
||||||
|
server_entry_t slist[MAX_SERVER_LIST];
|
||||||
|
//--------------------------------------UTILS-----------------------------------
|
||||||
|
char *Cmd_MakeArgs (int start)
|
||||||
|
{
|
||||||
|
int i, c;
|
||||||
|
|
||||||
|
static char text[1024];
|
||||||
|
|
||||||
|
text[0] = 0;
|
||||||
|
c = Cmd_Argc();
|
||||||
|
for (i = start; i < c; i++) {
|
||||||
|
if (i > start)
|
||||||
|
strncat (text, " ", sizeof(text) - strlen(text) - 1);
|
||||||
|
strncat (text, Cmd_Argv(i), sizeof(text) - strlen(text) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *CreateSpaces(int amount)
|
||||||
|
{
|
||||||
|
static char spaces[1024];
|
||||||
|
int size;
|
||||||
|
|
||||||
|
size = bound(1, amount, sizeof(spaces) - 1);
|
||||||
|
memset(spaces, ' ', size);
|
||||||
|
spaces[size] = 0;
|
||||||
|
|
||||||
|
return spaces;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void SList_Init (void)
|
||||||
|
{
|
||||||
|
memset (&slist, 0, sizeof(slist));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Shutdown (void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
// if the first is empty already that means there isn't a single entry
|
||||||
|
if (!slist[0].server)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if (!(f = fopen("servers.lst", "wt")))
|
||||||
|
if (!(f = fopen(va("%s/servers.lst", com_gamedir), "wt")))
|
||||||
|
{
|
||||||
|
Con_DPrintf ("Couldn't open servers.lst\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SList_Save (f);
|
||||||
|
fclose (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Set (int i, char *addr, char *desc)
|
||||||
|
{
|
||||||
|
if (i >= MAX_SERVER_LIST || i < 0)
|
||||||
|
Sys_Error ("SList_Set: Bad index %d", i);
|
||||||
|
|
||||||
|
if (slist[i].server)
|
||||||
|
Z_Free (slist[i].server);
|
||||||
|
if (slist[i].description)
|
||||||
|
Z_Free (slist[i].description);
|
||||||
|
|
||||||
|
slist[i].server = CopyString (addr);
|
||||||
|
slist[i].description = CopyString (desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Reset_NoFree (int i)
|
||||||
|
{
|
||||||
|
if (i >= MAX_SERVER_LIST || i < 0)
|
||||||
|
Sys_Error ("SList_Reset_NoFree: Bad index %d", i);
|
||||||
|
|
||||||
|
slist[i].description = slist[i].server = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Reset (int i)
|
||||||
|
{
|
||||||
|
if (i >= MAX_SERVER_LIST || i < 0)
|
||||||
|
Sys_Error ("SList_Reset: Bad index %d", i);
|
||||||
|
|
||||||
|
if (slist[i].server)
|
||||||
|
{
|
||||||
|
Z_Free (slist[i].server);
|
||||||
|
slist[i].server = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slist[i].description)
|
||||||
|
{
|
||||||
|
Z_Free (slist[i].description);
|
||||||
|
slist[i].description = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Switch (int a, int b)
|
||||||
|
{
|
||||||
|
server_entry_t temp;
|
||||||
|
|
||||||
|
if (a >= MAX_SERVER_LIST || a < 0)
|
||||||
|
Sys_Error ("SList_Switch: Bad index %d", a);
|
||||||
|
if (b >= MAX_SERVER_LIST || b < 0)
|
||||||
|
Sys_Error ("SList_Switch: Bad index %d", b);
|
||||||
|
|
||||||
|
memcpy (&temp, &slist[a], sizeof(temp));
|
||||||
|
memcpy (&slist[a], &slist[b], sizeof(temp));
|
||||||
|
memcpy (&slist[b], &temp, sizeof(temp));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SList_Length (void)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
for (count = 0 ; count < MAX_SERVER_LIST && slist[count].server ; count++)
|
||||||
|
;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Load (void)
|
||||||
|
{
|
||||||
|
int c, len, argc, count;
|
||||||
|
char line[128], *desc, *addr;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (!(f = fopen (va("%s/servers.lst", com_gamedir), "rt")))
|
||||||
|
//if (!(f = fopen("servers.lst", "rt")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
count = len = 0;
|
||||||
|
while ((c = getc(f)))
|
||||||
|
{
|
||||||
|
if (c == '\n' || c == '\r' || c == EOF)
|
||||||
|
{
|
||||||
|
if (c == '\r' && (c = getc(f)) != '\n' && c != EOF)
|
||||||
|
ungetc (c, f);
|
||||||
|
|
||||||
|
line[len] = 0;
|
||||||
|
len = 0;
|
||||||
|
Cmd_TokenizeString (line);
|
||||||
|
|
||||||
|
if ((argc = Cmd_Argc()) >= 1)
|
||||||
|
{
|
||||||
|
addr = Cmd_Argv(0);
|
||||||
|
desc = (argc >= 2) ? Cmd_Args() : "Unknown";
|
||||||
|
SList_Set (count, addr, desc);
|
||||||
|
if (++count == MAX_SERVER_LIST)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == EOF)
|
||||||
|
break; //just in case an EOF follows a '\r'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (len + 1 < sizeof(line))
|
||||||
|
line[len++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SList_Save (FILE *f)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0 ; i<MAX_SERVER_LIST ; i++)
|
||||||
|
{
|
||||||
|
if (!slist[i].server)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fprintf (f, "%s\t%s\n", slist[i].server, slist[i].description);
|
||||||
|
}
|
||||||
|
}
|
38
source/cl_slist.h
Normal file
38
source/cl_slist.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 1999,2000 contributors of the QuakeForge project
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAX_SERVER_LIST 256
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *server;
|
||||||
|
char *description;
|
||||||
|
} server_entry_t;
|
||||||
|
|
||||||
|
extern server_entry_t slist[MAX_SERVER_LIST];
|
||||||
|
|
||||||
|
void SList_Init(void);
|
||||||
|
void SList_Shutdown(void);
|
||||||
|
void SList_Set(int i,char *addr,char *desc);
|
||||||
|
void SList_Reset_NoFree(int i);
|
||||||
|
void SList_Reset(int i);
|
||||||
|
void SList_Switch(int a,int b);
|
||||||
|
int SList_Length(void);
|
||||||
|
void SList_Load(void);
|
||||||
|
void SList_Save(FILE *f);
|
548
source/cl_tent.c
Normal file
548
source/cl_tent.c
Normal file
|
@ -0,0 +1,548 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// cl_tent.c -- client side temporary entities
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
static vec3_t playerbeam_end; // added by joe
|
||||||
|
|
||||||
|
int num_temp_entities;
|
||||||
|
entity_t cl_temp_entities[MAX_TEMP_ENTITIES];
|
||||||
|
beam_t cl_beams[MAX_BEAMS];
|
||||||
|
|
||||||
|
model_t *cl_q3gunshot_mod, *cl_q3teleport_mod;
|
||||||
|
|
||||||
|
sfx_t *cl_sfx_r_exp3;
|
||||||
|
|
||||||
|
extern sfx_t *cl_sfx_step[4];
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
CL_ParseTEnt
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void CL_InitTEnts (void)
|
||||||
|
{
|
||||||
|
cl_sfx_r_exp3 = S_PrecacheSound ("sounds/weapons/r_exp3.wav");
|
||||||
|
cl_sfx_step[0] = S_PrecacheSound ("sounds/player/steps/step_1.wav");
|
||||||
|
cl_sfx_step[1] = S_PrecacheSound ("sounds/player/steps/step_2.wav");
|
||||||
|
cl_sfx_step[2] = S_PrecacheSound ("sounds/player/steps/step_3.wav");
|
||||||
|
cl_sfx_step[3] = S_PrecacheSound ("sounds/player/steps/step_4.wav");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
CL_ClearTEnts
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void CL_ClearTEnts (void)
|
||||||
|
{
|
||||||
|
//cl_bolt1_mod = cl_bolt2_mod = cl_bolt3_mod = cl_beam_mod = NULL;
|
||||||
|
cl_q3gunshot_mod = cl_q3teleport_mod = NULL;
|
||||||
|
|
||||||
|
memset (&cl_beams, 0, sizeof(cl_beams));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
CL_ParseBeam
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void CL_ParseBeam (model_t *m)
|
||||||
|
{
|
||||||
|
int ent;
|
||||||
|
vec3_t start, end;
|
||||||
|
beam_t *b;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ent = MSG_ReadShort ();
|
||||||
|
|
||||||
|
start[0] = MSG_ReadCoord ();
|
||||||
|
start[1] = MSG_ReadCoord ();
|
||||||
|
start[2] = MSG_ReadCoord ();
|
||||||
|
|
||||||
|
end[0] = MSG_ReadCoord ();
|
||||||
|
end[1] = MSG_ReadCoord ();
|
||||||
|
end[2] = MSG_ReadCoord ();
|
||||||
|
|
||||||
|
if (ent == cl.viewentity)
|
||||||
|
VectorCopy(end, playerbeam_end); // for cl_truelightning
|
||||||
|
|
||||||
|
// override any beam with the same entity
|
||||||
|
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
|
||||||
|
if (b->entity == ent)
|
||||||
|
{
|
||||||
|
b->entity = ent;
|
||||||
|
b->model = m;
|
||||||
|
b->endtime = cl.time + 0.2;
|
||||||
|
VectorCopy (start, b->start);
|
||||||
|
VectorCopy (end, b->end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a free beam
|
||||||
|
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
|
||||||
|
{
|
||||||
|
if (!b->model || b->endtime < cl.time)
|
||||||
|
{
|
||||||
|
b->entity = ent;
|
||||||
|
b->model = m;
|
||||||
|
b->endtime = cl.time + 0.2;
|
||||||
|
VectorCopy (start, b->start);
|
||||||
|
VectorCopy (end, b->end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Con_Printf ("beam list overflow!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DECAL_NONE,
|
||||||
|
DECAL_BULLTMRK,
|
||||||
|
DECAL_BLOODMRK1,
|
||||||
|
DECAL_BLOODMRK2,
|
||||||
|
DECAL_BLOODMRK3,
|
||||||
|
DECAL_EXPLOMRK
|
||||||
|
};
|
||||||
|
//==============================================================================
|
||||||
|
extern cvar_t r_decal_bullets;
|
||||||
|
extern cvar_t r_decal_explosions;
|
||||||
|
|
||||||
|
extern int decal_blood1, decal_blood2, decal_blood3, decal_burn, decal_mark, decal_glow;
|
||||||
|
//==============================================================================
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
CL_ParseTEnt
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void CL_ParseTEnt (void)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
vec3_t pos;
|
||||||
|
dlight_t *dl;
|
||||||
|
//int rnd;
|
||||||
|
int colorStart, colorLength;
|
||||||
|
|
||||||
|
type = MSG_ReadByte ();
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case TE_WIZSPIKE: // spike hitting wall
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
if (r_part_spikes.value == 2 && !cl_q3gunshot_mod)
|
||||||
|
cl_q3gunshot_mod = Mod_ForName ("progs/bullet.md3", true);
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 20, 30);
|
||||||
|
//S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_KNIGHTSPIKE: // spike hitting wall
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
if (r_part_spikes.value == 2 && !cl_q3gunshot_mod)
|
||||||
|
cl_q3gunshot_mod = Mod_ForName ("progs/bullet.md3", true);
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 226, 20);
|
||||||
|
//S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_SPIKE: // spike hitting wall
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
if (r_part_spikes.value == 2 && !cl_q3gunshot_mod)
|
||||||
|
cl_q3gunshot_mod = Mod_ForName ("progs/bullet.md3", true);
|
||||||
|
//R00k--start
|
||||||
|
if (r_decal_bullets.value)
|
||||||
|
{
|
||||||
|
R_SpawnDecalStatic(pos, decal_mark, 8);
|
||||||
|
}
|
||||||
|
//R00k--end
|
||||||
|
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 0, 10);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TE_SUPERSPIKE: // super spike hitting wall
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
if (r_part_spikes.value == 2 && !cl_q3gunshot_mod)
|
||||||
|
cl_q3gunshot_mod = Mod_ForName ("progs/bullet.md3", true);
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 0, 20);
|
||||||
|
|
||||||
|
//R00k--start
|
||||||
|
if (r_decal_bullets.value)
|
||||||
|
{
|
||||||
|
R_SpawnDecalStatic(pos, decal_mark, 10);
|
||||||
|
}
|
||||||
|
//R00k--end
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_GUNSHOT: // bullet hitting wall
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
if (r_part_gunshots.value == 2 && !cl_q3gunshot_mod)
|
||||||
|
cl_q3gunshot_mod = Mod_ForName ("progs/bullet.md3", true);
|
||||||
|
|
||||||
|
//R00k--start
|
||||||
|
if (r_decal_bullets.value)
|
||||||
|
{
|
||||||
|
R_SpawnDecalStatic(pos, decal_mark, 8);
|
||||||
|
}
|
||||||
|
//R00k--end
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 0, 20);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_EXPLOSION: // rocket explosion
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
R_ParticleExplosion (pos);
|
||||||
|
if (r_decal_explosions.value)
|
||||||
|
{
|
||||||
|
R_SpawnDecalStatic(pos, decal_burn, 100);
|
||||||
|
}
|
||||||
|
dl = CL_AllocDlight (0);
|
||||||
|
VectorCopy (pos, dl->origin);
|
||||||
|
dl->radius = 350;
|
||||||
|
dl->die = cl.time + 0.5;
|
||||||
|
dl->decay = 300;
|
||||||
|
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 0.5);
|
||||||
|
break;
|
||||||
|
case TE_RAYSPLASHGREEN:
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
dl = CL_AllocDlight (0);
|
||||||
|
VectorCopy (pos, dl->origin);
|
||||||
|
dl->radius = 65;
|
||||||
|
dl->die = cl.time + 0.3;
|
||||||
|
dl->decay = 300;
|
||||||
|
dl->color[0] = 0;
|
||||||
|
dl->color[1] = 255;
|
||||||
|
dl->color[2] = 0;
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 0, 256);
|
||||||
|
//S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 0.5); // NZPFIXME - add raygun hum
|
||||||
|
break;
|
||||||
|
case TE_RAYSPLASHRED:
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
dl = CL_AllocDlight (0);
|
||||||
|
VectorCopy (pos, dl->origin);
|
||||||
|
dl->radius = 65;
|
||||||
|
dl->die = cl.time + 0.3;
|
||||||
|
dl->decay = 300;
|
||||||
|
dl->color[0] = 255;
|
||||||
|
dl->color[1] = 0;
|
||||||
|
dl->color[2] = 0;
|
||||||
|
R_RunParticleEffect (pos, vec3_origin, 0, 512);
|
||||||
|
//S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 0.5); // NZPFIXME - add raygun hum
|
||||||
|
break;
|
||||||
|
case TE_TAREXPLOSION: // tarbaby explosion
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
R_BlobExplosion (pos);
|
||||||
|
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_LIGHTNING1: // lightning bolts
|
||||||
|
CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_LIGHTNING2: // lightning bolts
|
||||||
|
CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_LIGHTNING3: // lightning bolts
|
||||||
|
CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// PGM 01/21/97
|
||||||
|
case TE_BEAM: // grappling hook beam
|
||||||
|
CL_ParseBeam (Mod_ForName("progs/beam.mdl", true));
|
||||||
|
break;
|
||||||
|
// PGM 01/21/97
|
||||||
|
|
||||||
|
case TE_LAVASPLASH:
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
R_LavaSplash (pos);
|
||||||
|
dl = CL_AllocDlight (0);
|
||||||
|
VectorCopy (pos, dl->origin);
|
||||||
|
dl->radius = 150;
|
||||||
|
dl->die = cl.time + 0.75;
|
||||||
|
dl->decay = 200;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_TELEPORT:
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
if (r_part_telesplash.value == 2 && !cl_q3teleport_mod)
|
||||||
|
cl_q3teleport_mod = Mod_ForName ("progs/telep.md3", true);
|
||||||
|
R_TeleportSplash (pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TE_EXPLOSION2: // color mapped explosion
|
||||||
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
colorStart = MSG_ReadByte ();
|
||||||
|
colorLength = MSG_ReadByte ();
|
||||||
|
R_ParticleExplosion2 (pos, colorStart, colorLength);
|
||||||
|
|
||||||
|
if (r_decal_explosions.value)
|
||||||
|
{
|
||||||
|
R_SpawnDecalStatic(pos, decal_burn, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
dl = CL_AllocDlight (0);
|
||||||
|
VectorCopy (pos, dl->origin);
|
||||||
|
dl->radius = 350;
|
||||||
|
dl->die = cl.time + 0.5;
|
||||||
|
dl->decay = 300;
|
||||||
|
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Sys_Error ("CL_ParseTEnt: bad type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
CL_NewTempEntity
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
entity_t *CL_NewTempEntity (void)
|
||||||
|
{
|
||||||
|
entity_t *ent;
|
||||||
|
|
||||||
|
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||||
|
return NULL;
|
||||||
|
if (num_temp_entities == MAX_TEMP_ENTITIES)
|
||||||
|
return NULL;
|
||||||
|
ent = &cl_temp_entities[num_temp_entities];
|
||||||
|
memset (ent, 0, sizeof(*ent));
|
||||||
|
num_temp_entities++;
|
||||||
|
cl_visedicts[cl_numvisedicts] = ent;
|
||||||
|
cl_numvisedicts++;
|
||||||
|
|
||||||
|
ent->colormap = vid.colormap;
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
TraceLineN
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
|
||||||
|
{
|
||||||
|
trace_t trace;
|
||||||
|
|
||||||
|
memset (&trace, 0, sizeof(trace));
|
||||||
|
if (!SV_RecursiveHullCheck(cl.worldmodel->hulls, 0, 0, 1, start, end, &trace))
|
||||||
|
{
|
||||||
|
if (trace.fraction < 1)
|
||||||
|
{
|
||||||
|
VectorCopy (trace.endpos, impact);
|
||||||
|
if (normal)
|
||||||
|
VectorCopy (trace.plane.normal, normal);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMB_Lightning_Splash (vec3_t org);
|
||||||
|
extern cvar_t scr_ofsy;
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
CL_UpdateTEnts
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void CL_UpdateTEnts (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
beam_t *b;
|
||||||
|
vec3_t dist, org, beamstart;
|
||||||
|
float d;
|
||||||
|
entity_t *ent;
|
||||||
|
float yaw, pitch;
|
||||||
|
float forward;
|
||||||
|
|
||||||
|
int j;
|
||||||
|
vec3_t beamend;
|
||||||
|
// qboolean sparks = false;
|
||||||
|
|
||||||
|
num_temp_entities = 0;
|
||||||
|
|
||||||
|
// update lightning
|
||||||
|
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
|
||||||
|
{
|
||||||
|
if (!b->model || b->endtime < cl.time)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if coming from the player, update the start position
|
||||||
|
if (b->entity == cl.viewentity)
|
||||||
|
{
|
||||||
|
VectorCopy (cl_entities[cl.viewentity].origin, b->start);
|
||||||
|
|
||||||
|
b->start[2] += cl.crouch + bound(-7, scr_ofsy.value, 4);
|
||||||
|
b->start[2] += bound(0, cl_lightning_zadjust.value, 20);//progs.dat aims from 20 for traceline
|
||||||
|
|
||||||
|
if (cl_truelightning.value)
|
||||||
|
{
|
||||||
|
vec3_t forward, v, org, ang;
|
||||||
|
float f, delta;
|
||||||
|
trace_t trace;
|
||||||
|
|
||||||
|
f = fmax(0, fmin(1, cl_truelightning.value));
|
||||||
|
|
||||||
|
VectorSubtract (playerbeam_end, cl_entities[cl.viewentity].origin, v);
|
||||||
|
//v[2] -= 22; // adjust for view height
|
||||||
|
v[2] -= cl.crouch; //
|
||||||
|
v[2] -= bound(0, cl_lightning_zadjust.value, 20);
|
||||||
|
|
||||||
|
vectoangles (v, ang);
|
||||||
|
|
||||||
|
// lerp pitch
|
||||||
|
ang[0] = -ang[0];
|
||||||
|
if (ang[0] < -180)
|
||||||
|
ang[0] += 360;
|
||||||
|
ang[0] += (cl.viewangles[0] - ang[0]) * f;
|
||||||
|
|
||||||
|
// lerp yaw
|
||||||
|
delta = cl.viewangles[1] - ang[1];
|
||||||
|
if (delta > 180)
|
||||||
|
delta -= 360;
|
||||||
|
if (delta < -180)
|
||||||
|
delta += 360;
|
||||||
|
ang[1] += delta * f;
|
||||||
|
ang[2] = 0;
|
||||||
|
|
||||||
|
AngleVectors (ang, forward, NULLVEC, NULLVEC);
|
||||||
|
VectorScale(forward, 600, forward);
|
||||||
|
VectorCopy(cl_entities[cl.viewentity].origin, org);
|
||||||
|
org[2] += bound(0, cl_lightning_zadjust.value, 20);//progs.dat aims from 20 for teaceline
|
||||||
|
VectorAdd(org, forward, b->end);
|
||||||
|
|
||||||
|
memset (&trace, 0, sizeof(trace_t));
|
||||||
|
if (!SV_RecursiveHullCheck(cl.worldmodel->hulls, 0, 0, 1, org, b->end, &trace))
|
||||||
|
VectorCopy(trace.endpos, b->end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// if coming from the player, update the start position
|
||||||
|
if (b->entity == cl.viewentity)
|
||||||
|
{
|
||||||
|
VectorCopy (cl_entities[cl.viewentity].origin, b->start);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// calculate pitch and yaw
|
||||||
|
VectorSubtract (b->end, b->start, dist);
|
||||||
|
|
||||||
|
if (dist[1] == 0 && dist[0] == 0)
|
||||||
|
{
|
||||||
|
yaw = 0;
|
||||||
|
if (dist[2] > 0)
|
||||||
|
pitch = 90;
|
||||||
|
else
|
||||||
|
pitch = 270;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yaw = (int) (atan2f(dist[1], dist[0]) * 180 / M_PI);
|
||||||
|
if (yaw < 0)
|
||||||
|
yaw += 360;
|
||||||
|
|
||||||
|
forward = sqrtf (dist[0]*dist[0] + dist[1]*dist[1]);
|
||||||
|
pitch = (int) (atan2f(dist[2], forward) * 180 / M_PI);
|
||||||
|
if (pitch < 0)
|
||||||
|
pitch += 360;
|
||||||
|
}
|
||||||
|
// add new entities for the lightning
|
||||||
|
VectorCopy(b->start, org);
|
||||||
|
VectorCopy(b->start, beamstart);
|
||||||
|
d = VectorNormalize (dist);
|
||||||
|
VectorScale (dist, 30, dist);
|
||||||
|
|
||||||
|
if (key_dest == key_game)
|
||||||
|
{
|
||||||
|
for ( ; d > 0 ; d -= 30)
|
||||||
|
{
|
||||||
|
if ((qmb_initialized && r_part_lightning.value) && (!cl.paused))
|
||||||
|
{
|
||||||
|
VectorAdd(org, dist, beamend);
|
||||||
|
for (j=0 ; j<3 ; j++)
|
||||||
|
beamend[j] += ((rand()%10)-5);
|
||||||
|
QMB_LightningBeam (beamstart, beamend);
|
||||||
|
//if ((r_glowlg.value) && (r_dynamic.value))
|
||||||
|
// CL_NewDlight (i, beamstart, 100, 0.1, lt_blue);
|
||||||
|
VectorCopy(beamend, beamstart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(ent = CL_NewTempEntity()))
|
||||||
|
return;
|
||||||
|
VectorCopy(org, ent->origin);
|
||||||
|
ent->model = b->model;
|
||||||
|
ent->angles[0] = pitch;
|
||||||
|
ent->angles[1] = yaw;
|
||||||
|
ent->angles[2] = rand() % 360;
|
||||||
|
}
|
||||||
|
VectorAdd(org, dist, org);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// add new entities for the lightning
|
||||||
|
VectorCopy (b->start, org);
|
||||||
|
d = VectorNormalize(dist);
|
||||||
|
while (d > 0)
|
||||||
|
{
|
||||||
|
ent = CL_NewTempEntity ();
|
||||||
|
if (!ent)
|
||||||
|
return;
|
||||||
|
VectorCopy (org, ent->origin);
|
||||||
|
ent->model = b->model;
|
||||||
|
ent->angles[0] = pitch;
|
||||||
|
ent->angles[1] = yaw;
|
||||||
|
ent->angles[2] = rand()%360;
|
||||||
|
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
org[i] += dist[i]*30;
|
||||||
|
d -= 30;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
433
source/client.h
Normal file
433
source/client.h
Normal file
|
@ -0,0 +1,433 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// client.h
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vec3_t viewangles;
|
||||||
|
|
||||||
|
// intended velocities
|
||||||
|
float forwardmove;
|
||||||
|
float sidemove;
|
||||||
|
float upmove;
|
||||||
|
} usercmd_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
char map[MAX_STYLESTRING];
|
||||||
|
} lightstyle_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[MAX_SCOREBOARDNAME];
|
||||||
|
float entertime;
|
||||||
|
int points;
|
||||||
|
int maxpoints;
|
||||||
|
int kills;
|
||||||
|
int headshots;
|
||||||
|
} scoreboard_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int destcolor[3];
|
||||||
|
int percent; // 0-256
|
||||||
|
} cshift_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
lt_default, lt_muzzleflash, lt_explosion, lt_rocket,
|
||||||
|
lt_red, lt_blue, lt_redblue, lt_green, NUM_DLIGHTTYPES,
|
||||||
|
lt_explosion2, lt_explosion3, lt_rayred, lt_raygreen
|
||||||
|
} dlighttype_t;
|
||||||
|
|
||||||
|
#define CSHIFT_CONTENTS 0
|
||||||
|
#define CSHIFT_DAMAGE 1
|
||||||
|
#define CSHIFT_BONUS 2
|
||||||
|
#define CSHIFT_POWERUP 3
|
||||||
|
#define NUM_CSHIFTS 4
|
||||||
|
|
||||||
|
#define NAME_LENGTH 64
|
||||||
|
|
||||||
|
//
|
||||||
|
// client_state_t should hold all pieces of the client state
|
||||||
|
//
|
||||||
|
|
||||||
|
#define SIGNONS 4 // signon messages to receive before connected
|
||||||
|
|
||||||
|
#define MAX_DLIGHTS 32
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vec3_t origin;
|
||||||
|
float radius;
|
||||||
|
float die; // stop lighting after this time
|
||||||
|
float decay; // drop this each second
|
||||||
|
float minlight; // don't add when contributing less
|
||||||
|
int key;
|
||||||
|
qboolean dark; // subtracts light instead of adding
|
||||||
|
vec3_t color; //LordHavoc Lit. Support
|
||||||
|
int type; // color
|
||||||
|
} dlight_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_BEAMS 24
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int entity;
|
||||||
|
struct model_s *model;
|
||||||
|
float endtime;
|
||||||
|
vec3_t start, end;
|
||||||
|
} beam_t;
|
||||||
|
|
||||||
|
#define MAX_EFRAGS 640
|
||||||
|
|
||||||
|
#define MAX_MAPSTRING 2048
|
||||||
|
#define MAX_DEMOS 8
|
||||||
|
#define MAX_DEMONAME 16
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ca_dedicated, // a dedicated server with no ability to start a client
|
||||||
|
ca_disconnected, // full screen console with no connection
|
||||||
|
ca_connected // valid netcon, talking to a server
|
||||||
|
} cactive_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// the client_static_t structure is persistant through an arbitrary number
|
||||||
|
// of server connections
|
||||||
|
//
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cactive_t state;
|
||||||
|
|
||||||
|
// personalization data sent to server
|
||||||
|
char mapstring[MAX_QPATH];
|
||||||
|
char spawnparms[MAX_MAPSTRING]; // to restart a level
|
||||||
|
// demo loop control
|
||||||
|
int demonum; // -1 = don't play demos
|
||||||
|
char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing
|
||||||
|
|
||||||
|
// demo recording info must be here, because record is started before
|
||||||
|
// entering a map (and clearing client_state_t)
|
||||||
|
qboolean demorecording;
|
||||||
|
qboolean demoplayback;
|
||||||
|
qboolean timedemo;
|
||||||
|
int forcetrack; // -1 = use normal cd track
|
||||||
|
int demofile;
|
||||||
|
int td_lastframe; // to meter out one message a frame
|
||||||
|
int td_startframe; // host_framecount at start
|
||||||
|
float td_starttime; // realtime at second frame of timedemo
|
||||||
|
|
||||||
|
|
||||||
|
// connection information
|
||||||
|
int signon; // 0 to SIGNONS
|
||||||
|
struct qsocket_s *netcon;
|
||||||
|
sizebuf_t message; // writing buffer to send to server
|
||||||
|
|
||||||
|
} client_static_t;
|
||||||
|
|
||||||
|
extern client_static_t cls;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float lerptime;
|
||||||
|
float framechange; //marks time of last frame change - for halflife model sequencing.
|
||||||
|
float oldframechange;
|
||||||
|
float lerprate; //inverse rate...
|
||||||
|
vec3_t origin;
|
||||||
|
vec3_t angles;
|
||||||
|
//trailstate_t *trailstate; //when to next throw out a trail
|
||||||
|
// trailstate_t *emitstate; //when to next emit
|
||||||
|
unsigned short frame;
|
||||||
|
} lerpents_t;
|
||||||
|
//
|
||||||
|
// the client_state_t structure is wiped completely at every
|
||||||
|
// server signon
|
||||||
|
//
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int movemessages; // since connecting to this server
|
||||||
|
// throw out the first couple, so the player
|
||||||
|
// doesn't accidentally do something the
|
||||||
|
// first frame
|
||||||
|
usercmd_t cmd; // last command sent to the server
|
||||||
|
|
||||||
|
// information for local display
|
||||||
|
int stats[MAX_CL_STATS]; // health, etc
|
||||||
|
int perks; // Perk icons.
|
||||||
|
int progress_bar; // Perk icons.
|
||||||
|
float item_gettime[32]; // cl.time of aquiring item, for blinking
|
||||||
|
float faceanimtime; // use anim frame if cl.time < this
|
||||||
|
|
||||||
|
cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups
|
||||||
|
cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types
|
||||||
|
|
||||||
|
// the client maintains its own idea of view angles, which are
|
||||||
|
// sent to the server each frame. The server sets punchangle when
|
||||||
|
// the view is temporarliy offset, and an angle reset commands at the start
|
||||||
|
// of each level and after teleporting.
|
||||||
|
vec3_t mviewangles[2]; // during demo playback viewangles is lerped
|
||||||
|
// between these
|
||||||
|
vec3_t viewangles;
|
||||||
|
|
||||||
|
vec3_t mvelocity[2]; // update by server, used for lean+bob
|
||||||
|
// (0 is newest)
|
||||||
|
vec3_t velocity; // lerped between mvelocity[0] and [1]
|
||||||
|
|
||||||
|
vec3_t punchangle; // temporary offset
|
||||||
|
vec3_t gun_kick; // temporary kick
|
||||||
|
|
||||||
|
// pitch drifting vars
|
||||||
|
float idealpitch;
|
||||||
|
float pitchvel;
|
||||||
|
qboolean nodrift;
|
||||||
|
float driftmove;
|
||||||
|
double laststop;
|
||||||
|
|
||||||
|
float viewheight;
|
||||||
|
float crouch; // local amount for smoothing stepups
|
||||||
|
|
||||||
|
qboolean paused; // send over by server
|
||||||
|
qboolean onground;
|
||||||
|
qboolean inwater;
|
||||||
|
|
||||||
|
int intermission; // don't change view angle, full screen, etc
|
||||||
|
int completed_time; // latched at intermission start
|
||||||
|
|
||||||
|
double mtime[2]; // the timestamp of last two messages
|
||||||
|
double time; // clients view of time, should be between
|
||||||
|
// servertime and oldservertime to generate
|
||||||
|
// a lerp point for other data
|
||||||
|
double oldtime; // previous cl.time, time-oldtime is used
|
||||||
|
// to decay light values and smooth step ups
|
||||||
|
double ctime; // joe: copy of cl.time, to avoid incidents caused by rewind
|
||||||
|
double thundertime; // R00k
|
||||||
|
double laser_point_time;
|
||||||
|
float last_received_message; // (realtime) for net trouble icon
|
||||||
|
|
||||||
|
//
|
||||||
|
// information that is static for the entire time connected to a server
|
||||||
|
//
|
||||||
|
struct model_s *model_precache[MAX_MODELS];
|
||||||
|
struct sfx_s *sound_precache[MAX_SOUNDS];
|
||||||
|
|
||||||
|
char levelname[40]; // for display on solo scoreboard
|
||||||
|
int viewentity; // cl_entities[cl.viewentity] = player
|
||||||
|
int maxclients;
|
||||||
|
int gametype;
|
||||||
|
|
||||||
|
lerpents_t *lerpents;
|
||||||
|
|
||||||
|
// refresh related state
|
||||||
|
struct model_s *worldmodel; // cl_entities[0].model
|
||||||
|
struct efrag_s *free_efrags;
|
||||||
|
int num_entities; // held in cl_entities array
|
||||||
|
int num_statics; // held in cl_staticentities array
|
||||||
|
entity_t viewent; // the gun model
|
||||||
|
entity_t viewent2; // the second gun model
|
||||||
|
|
||||||
|
int cdtrack, looptrack; // cd audio
|
||||||
|
|
||||||
|
// frag scoreboard
|
||||||
|
scoreboard_t *scores; // [cl.maxclients]
|
||||||
|
} client_state_t;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// cvars
|
||||||
|
//
|
||||||
|
extern cvar_t cl_name;
|
||||||
|
extern cvar_t cl_maxfps; // dr_mabuse1981: maxfps setting
|
||||||
|
|
||||||
|
extern cvar_t cl_upspeed;
|
||||||
|
extern float cl_forwardspeed;
|
||||||
|
extern float cl_backspeed;
|
||||||
|
extern float cl_sidespeed;
|
||||||
|
|
||||||
|
extern cvar_t cl_movespeedkey;
|
||||||
|
|
||||||
|
extern cvar_t cl_yawspeed;
|
||||||
|
extern cvar_t cl_pitchspeed;
|
||||||
|
extern cvar_t r_hlbsponly;
|
||||||
|
extern cvar_t cl_anglespeedkey;
|
||||||
|
|
||||||
|
extern cvar_t cl_lightning_zadjust;
|
||||||
|
extern cvar_t cl_truelightning;
|
||||||
|
|
||||||
|
extern cvar_t cl_autofire;
|
||||||
|
|
||||||
|
extern cvar_t cl_shownet;
|
||||||
|
extern cvar_t cl_nolerp;
|
||||||
|
|
||||||
|
extern cvar_t cl_pitchdriftspeed;
|
||||||
|
extern cvar_t lookspring;
|
||||||
|
extern cvar_t lookstrafe;
|
||||||
|
extern cvar_t in_sensitivity;
|
||||||
|
extern cvar_t in_tolerance;
|
||||||
|
extern cvar_t in_acceleration;
|
||||||
|
extern cvar_t in_analog_strafe;
|
||||||
|
extern cvar_t in_x_axis_adjust;
|
||||||
|
extern cvar_t in_y_axis_adjust;
|
||||||
|
|
||||||
|
extern cvar_t in_mlook; //Heffo - mlook cvar
|
||||||
|
|
||||||
|
extern cvar_t in_aimassist;
|
||||||
|
|
||||||
|
extern cvar_t m_pitch;
|
||||||
|
extern cvar_t m_yaw;
|
||||||
|
extern cvar_t m_forward;
|
||||||
|
extern cvar_t m_side;
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_TEMP_ENTITIES 64 // lightning bolts, etc
|
||||||
|
#define MAX_STATIC_ENTITIES 128 // torches, etc
|
||||||
|
|
||||||
|
extern client_state_t cl;
|
||||||
|
|
||||||
|
// FIXME, allocate dynamically
|
||||||
|
extern efrag_t cl_efrags[MAX_EFRAGS];
|
||||||
|
extern entity_t cl_entities[MAX_EDICTS];
|
||||||
|
extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
|
||||||
|
extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
|
||||||
|
extern dlight_t cl_dlights[MAX_DLIGHTS];
|
||||||
|
extern entity_t cl_temp_entities[MAX_TEMP_ENTITIES];
|
||||||
|
extern beam_t cl_beams[MAX_BEAMS];
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
//
|
||||||
|
// cl_main
|
||||||
|
//
|
||||||
|
dlight_t *CL_AllocDlight (int key);
|
||||||
|
void CL_NewDlight (int key, vec3_t origin, float radius, float time, int type);
|
||||||
|
void CL_DecayLights (void);
|
||||||
|
|
||||||
|
void CL_Init (void);
|
||||||
|
|
||||||
|
void CL_EstablishConnection (char *host);
|
||||||
|
void CL_Signon1 (void);
|
||||||
|
void CL_Signon2 (void);
|
||||||
|
void CL_Signon3 (void);
|
||||||
|
void CL_Signon4 (void);
|
||||||
|
|
||||||
|
void CL_Disconnect (void);
|
||||||
|
void CL_Disconnect_f (void);
|
||||||
|
void CL_NextDemo (void);
|
||||||
|
|
||||||
|
#define MAX_VISEDICTS 256
|
||||||
|
extern int cl_numvisedicts;
|
||||||
|
extern entity_t *cl_visedicts[MAX_VISEDICTS];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern tagentity_t q3player_body, q3player_head;
|
||||||
|
|
||||||
|
// model indexes
|
||||||
|
typedef enum modelindex_s
|
||||||
|
{
|
||||||
|
mi_player,
|
||||||
|
mi_eyes,
|
||||||
|
mi_flame0,
|
||||||
|
mi_flame1,
|
||||||
|
mi_flame2,
|
||||||
|
mi_q3torso,
|
||||||
|
mi_q3head,
|
||||||
|
/*
|
||||||
|
mi_vw_light,
|
||||||
|
mi_vw_nail1,
|
||||||
|
mi_vw_nail2,
|
||||||
|
mi_vw_rock1,
|
||||||
|
mi_vw_rock2,
|
||||||
|
mi_vw_shot1,
|
||||||
|
mi_vw_shot2,
|
||||||
|
mi_vw_player,
|
||||||
|
*/
|
||||||
|
NUM_MODELINDEX
|
||||||
|
} modelindex_t;
|
||||||
|
|
||||||
|
extern modelindex_t cl_modelindex[NUM_MODELINDEX];
|
||||||
|
extern char *cl_modelnames[NUM_MODELINDEX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// cl_input
|
||||||
|
//
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int down[2]; // key nums holding it down
|
||||||
|
int state; // low bit is down state
|
||||||
|
} kbutton_t;
|
||||||
|
|
||||||
|
extern kbutton_t in_klook;//Heffo - mlook cvar
|
||||||
|
extern kbutton_t in_strafe;
|
||||||
|
extern kbutton_t in_speed;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CL_InitInput (void);
|
||||||
|
void CL_SendCmd (void);
|
||||||
|
void CL_SendMove (usercmd_t *cmd);
|
||||||
|
|
||||||
|
void CL_ParseTEnt (void);
|
||||||
|
void CL_UpdateTEnts (void);
|
||||||
|
|
||||||
|
void CL_ClearState (void);
|
||||||
|
|
||||||
|
|
||||||
|
int CL_ReadFromServer (void);
|
||||||
|
void CL_WriteToServer (usercmd_t *cmd);
|
||||||
|
void CL_BaseMove (usercmd_t *cmd);
|
||||||
|
|
||||||
|
|
||||||
|
float CL_KeyState (kbutton_t *key);
|
||||||
|
char *Key_KeynumToString (int keynum);
|
||||||
|
|
||||||
|
//
|
||||||
|
// cl_demo.c
|
||||||
|
//
|
||||||
|
void CL_StopPlayback (void);
|
||||||
|
int CL_GetMessage (void);
|
||||||
|
|
||||||
|
void CL_Stop_f (void);
|
||||||
|
void CL_Record_f (void);
|
||||||
|
void CL_PlayDemo_f (void);
|
||||||
|
void CL_TimeDemo_f (void);
|
||||||
|
|
||||||
|
//
|
||||||
|
// cl_parse.c
|
||||||
|
//
|
||||||
|
void CL_ParseServerMessage (void);
|
||||||
|
|
||||||
|
//
|
||||||
|
// view
|
||||||
|
//
|
||||||
|
void V_StartPitchDrift (void);
|
||||||
|
void V_StopPitchDrift (void);
|
||||||
|
|
||||||
|
void V_RenderView (void);
|
||||||
|
void V_UpdatePalette (void);
|
||||||
|
void V_Register (void);
|
||||||
|
void V_SetContentsColor (int contents);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// cl_tent
|
||||||
|
//
|
||||||
|
void CL_InitTEnts (void);
|
||||||
|
void CL_SignonReply (void);
|
||||||
|
entity_t *CL_NewTempEntity (void);
|
||||||
|
qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
|
874
source/cmd.c
Normal file
874
source/cmd.c
Normal file
|
@ -0,0 +1,874 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// cmd.c -- Quake script command processing module
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
void Cmd_ForwardToServer (void);
|
||||||
|
|
||||||
|
#define MAX_ALIAS_NAME 32
|
||||||
|
|
||||||
|
typedef struct cmdalias_s
|
||||||
|
{
|
||||||
|
struct cmdalias_s *next;
|
||||||
|
char name[MAX_ALIAS_NAME];
|
||||||
|
char *value;
|
||||||
|
} cmdalias_t;
|
||||||
|
|
||||||
|
cmdalias_t *cmd_alias;
|
||||||
|
|
||||||
|
int trashtest;
|
||||||
|
int *trashspot;
|
||||||
|
|
||||||
|
qboolean cmd_wait;
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_Wait_f
|
||||||
|
|
||||||
|
Causes execution of the remainder of the command buffer to be delayed until
|
||||||
|
next frame. This allows commands like:
|
||||||
|
bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2"
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cmd_Wait_f (void)
|
||||||
|
{
|
||||||
|
cmd_wait = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============================================================================
|
||||||
|
|
||||||
|
COMMAND BUFFER
|
||||||
|
|
||||||
|
=============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
sizebuf_t cmd_text;
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cbuf_Init
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cbuf_Init (void)
|
||||||
|
{
|
||||||
|
SZ_Alloc (&cmd_text, 8192); // space for commands and script files
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cbuf_AddText
|
||||||
|
|
||||||
|
Adds command text at the end of the buffer
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cbuf_AddText (char *text)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
|
||||||
|
l = Q_strlen (text);
|
||||||
|
|
||||||
|
if (cmd_text.cursize + l >= cmd_text.maxsize)
|
||||||
|
{
|
||||||
|
Con_Printf ("Cbuf_AddText: overflow\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SZ_Write (&cmd_text, text, Q_strlen (text));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cbuf_InsertText
|
||||||
|
|
||||||
|
Adds command text immediately after the current command
|
||||||
|
Adds a \n to the text
|
||||||
|
FIXME: actually change the command buffer to do less copying
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cbuf_InsertText (char *text)
|
||||||
|
{
|
||||||
|
char *temp;
|
||||||
|
int templen;
|
||||||
|
|
||||||
|
// copy off any commands still remaining in the exec buffer
|
||||||
|
templen = cmd_text.cursize;
|
||||||
|
if (templen)
|
||||||
|
{
|
||||||
|
temp = Z_Malloc (templen);
|
||||||
|
Q_memcpy (temp, cmd_text.data, templen);
|
||||||
|
SZ_Clear (&cmd_text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
temp = NULL; // shut up compiler
|
||||||
|
|
||||||
|
// add the entire text of the file
|
||||||
|
Cbuf_AddText (text);
|
||||||
|
|
||||||
|
// add the copied off data
|
||||||
|
if (templen)
|
||||||
|
{
|
||||||
|
SZ_Write (&cmd_text, temp, templen);
|
||||||
|
Z_Free (temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cbuf_Execute
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cbuf_Execute (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *text;
|
||||||
|
char line[1024];
|
||||||
|
int quotes;
|
||||||
|
|
||||||
|
while (cmd_text.cursize)
|
||||||
|
{
|
||||||
|
// find a \n or ; line break
|
||||||
|
text = (char *)cmd_text.data;
|
||||||
|
|
||||||
|
quotes = 0;
|
||||||
|
for (i=0 ; i< cmd_text.cursize ; i++)
|
||||||
|
{
|
||||||
|
if (text[i] == '"')
|
||||||
|
quotes++;
|
||||||
|
if ( !(quotes&1) && text[i] == ';')
|
||||||
|
break; // don't break if inside a quoted string
|
||||||
|
if (text[i] == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy (line, text, i);
|
||||||
|
line[i] = 0;
|
||||||
|
|
||||||
|
// delete the text from the command buffer and move remaining commands down
|
||||||
|
// this is necessary because commands (exec, alias) can insert data at the
|
||||||
|
// beginning of the text buffer
|
||||||
|
|
||||||
|
if (i == cmd_text.cursize)
|
||||||
|
cmd_text.cursize = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
cmd_text.cursize -= i;
|
||||||
|
Q_memcpy (text, text+i, cmd_text.cursize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the command line
|
||||||
|
Cmd_ExecuteString (line, src_command);
|
||||||
|
|
||||||
|
if (cmd_wait)
|
||||||
|
{ // skip out while text still remains in buffer, leaving it
|
||||||
|
// for next frame
|
||||||
|
cmd_wait = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
SCRIPT COMMANDS
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Cmd_StuffCmds_f
|
||||||
|
|
||||||
|
Adds command line parameters as script statements
|
||||||
|
Commands lead with a +, and continue until a - or another +
|
||||||
|
quake +prog jctest.qp +cmd amlev1
|
||||||
|
quake -nosound +cmd amlev1
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Cmd_StuffCmds_f (void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int s;
|
||||||
|
char *text, *build, c;
|
||||||
|
|
||||||
|
if (Cmd_Argc () != 1)
|
||||||
|
{
|
||||||
|
Con_Printf ("stuffcmds : execute command line parameters\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the combined string to parse from
|
||||||
|
s = 0;
|
||||||
|
for (i=1 ; i<com_argc ; i++)
|
||||||
|
{
|
||||||
|
if (!com_argv[i])
|
||||||
|
continue; // NEXTSTEP nulls out -NXHost
|
||||||
|
s += Q_strlen (com_argv[i]) + 1;
|
||||||
|
}
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
text = Z_Malloc (s+1);
|
||||||
|
text[0] = 0;
|
||||||
|
for (i=1 ; i<com_argc ; i++)
|
||||||
|
{
|
||||||
|
if (!com_argv[i])
|
||||||
|
continue; // NEXTSTEP nulls out -NXHost
|
||||||
|
Q_strcat (text,com_argv[i]);
|
||||||
|
if (i != com_argc-1)
|
||||||
|
Q_strcat (text, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// pull out the commands
|
||||||
|
build = Z_Malloc (s+1);
|
||||||
|
build[0] = 0;
|
||||||
|
|
||||||
|
for (i=0 ; i<s-1 ; i++)
|
||||||
|
{
|
||||||
|
if (text[i] == '+')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
|
||||||
|
for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++)
|
||||||
|
;
|
||||||
|
|
||||||
|
c = text[j];
|
||||||
|
text[j] = 0;
|
||||||
|
|
||||||
|
Q_strcat (build, text+i);
|
||||||
|
Q_strcat (build, "\n");
|
||||||
|
text[j] = c;
|
||||||
|
i = j-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build[0])
|
||||||
|
Cbuf_InsertText (build);
|
||||||
|
|
||||||
|
Z_Free (text);
|
||||||
|
Z_Free (build);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Cmd_Exec_f
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Cmd_Exec_f (void)
|
||||||
|
{
|
||||||
|
char *f;
|
||||||
|
int mark;
|
||||||
|
|
||||||
|
if (Cmd_Argc () != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("exec <filename> : execute a script file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark = Hunk_LowMark ();
|
||||||
|
f = (char *)COM_LoadHunkFile (Cmd_Argv(1));
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
Con_Printf ("couldn't exec %s\n",Cmd_Argv(1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Con_Printf ("execing %s\n",Cmd_Argv(1));
|
||||||
|
|
||||||
|
Cbuf_InsertText (f);
|
||||||
|
Hunk_FreeToLowMark (mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Cmd_Echo_f
|
||||||
|
|
||||||
|
Just prints the rest of the line to the console
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Cmd_Echo_f (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=1 ; i<Cmd_Argc() ; i++)
|
||||||
|
Con_Printf ("%s ",Cmd_Argv(i));
|
||||||
|
Con_Printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Cmd_Alias_f
|
||||||
|
|
||||||
|
Creates a new command that executes a command string (possibly ; seperated)
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *CopyString (char *in)
|
||||||
|
{
|
||||||
|
char *out;
|
||||||
|
|
||||||
|
out = Z_Malloc (strlen(in)+1);
|
||||||
|
strcpy (out, in);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cmd_Alias_f (void)
|
||||||
|
{
|
||||||
|
cmdalias_t *a;
|
||||||
|
char cmd[1024];
|
||||||
|
int i, c;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (Cmd_Argc() == 1)
|
||||||
|
{
|
||||||
|
Con_Printf ("Current alias commands:\n");
|
||||||
|
for (a = cmd_alias ; a ; a=a->next)
|
||||||
|
Con_Printf ("%s : %s\n", a->name, a->value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Cmd_Argv(1);
|
||||||
|
if (strlen(s) >= MAX_ALIAS_NAME)
|
||||||
|
{
|
||||||
|
Con_Printf ("Alias name is too long\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the alias allready exists, reuse it
|
||||||
|
for (a = cmd_alias ; a ; a=a->next)
|
||||||
|
{
|
||||||
|
if (!strcmp(s, a->name))
|
||||||
|
{
|
||||||
|
Z_Free (a->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!a)
|
||||||
|
{
|
||||||
|
a = Z_Malloc (sizeof(cmdalias_t));
|
||||||
|
a->next = cmd_alias;
|
||||||
|
cmd_alias = a;
|
||||||
|
}
|
||||||
|
strcpy (a->name, s);
|
||||||
|
|
||||||
|
// copy the rest of the command line
|
||||||
|
cmd[0] = 0; // start out with a null string
|
||||||
|
c = Cmd_Argc();
|
||||||
|
for (i=2 ; i< c ; i++)
|
||||||
|
{
|
||||||
|
strcat (cmd, Cmd_Argv(i));
|
||||||
|
if (i != c)
|
||||||
|
strcat (cmd, " ");
|
||||||
|
}
|
||||||
|
strcat (cmd, "\n");
|
||||||
|
|
||||||
|
a->value = CopyString (cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Cmd_Maps_f
|
||||||
|
|
||||||
|
Listing maps by Crow_bar(c).
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
#include <pspiofilemgr.h>
|
||||||
|
void Cmd_Maps_f (void)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (Cmd_Argc() < 2)
|
||||||
|
{
|
||||||
|
Con_Printf("Usage: maps <substring>\n");
|
||||||
|
Con_Printf("maps * for full listing\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con_Printf("-------------\n");
|
||||||
|
|
||||||
|
s = Cmd_Argv(1);
|
||||||
|
|
||||||
|
SceUID dir = sceIoDopen(va("%s/maps", com_gamedir));
|
||||||
|
|
||||||
|
if(dir < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceIoDirent dirent;
|
||||||
|
|
||||||
|
memset(&dirent, 0, sizeof(SceIoDirent));
|
||||||
|
|
||||||
|
while(sceIoDread(dir, &dirent) > 0)
|
||||||
|
{
|
||||||
|
if(dirent.d_name[0] == '.')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!strcasecmp(COM_FileExtension (dirent.d_name),"bsp"))
|
||||||
|
{
|
||||||
|
if(s[0] == '*')
|
||||||
|
{
|
||||||
|
Con_Printf("%s\n",dirent.d_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(s[i] == 0)
|
||||||
|
{
|
||||||
|
Con_Printf("%s\n",dirent.d_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if(toupper(dirent.d_name[i]) != toupper(s[i]))
|
||||||
|
#else
|
||||||
|
if(dirent.d_name[i] != s[i])
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(&dirent, 0, sizeof(SceIoDirent));
|
||||||
|
}
|
||||||
|
sceIoDclose(dir);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============================================================================
|
||||||
|
|
||||||
|
COMMAND EXECUTION
|
||||||
|
|
||||||
|
=============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct cmd_function_s
|
||||||
|
{
|
||||||
|
struct cmd_function_s *next;
|
||||||
|
char *name;
|
||||||
|
xcommand_t function;
|
||||||
|
} cmd_function_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_ARGS 80
|
||||||
|
|
||||||
|
static int cmd_argc;
|
||||||
|
static char *cmd_argv[MAX_ARGS];
|
||||||
|
static char *cmd_null_string = "";
|
||||||
|
static char *cmd_args = NULL;
|
||||||
|
|
||||||
|
cmd_source_t cmd_source;
|
||||||
|
|
||||||
|
|
||||||
|
static cmd_function_t *cmd_functions; // possible commands to execute
|
||||||
|
|
||||||
|
// 2000-01-09 CmdList command by Maddes start
|
||||||
|
/*
|
||||||
|
========
|
||||||
|
Cmd_List
|
||||||
|
========
|
||||||
|
*/
|
||||||
|
void Cmd_List_f (void)
|
||||||
|
{
|
||||||
|
cmd_function_t *cmd;
|
||||||
|
char *partial;
|
||||||
|
int len;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (Cmd_Argc() > 1)
|
||||||
|
{
|
||||||
|
partial = Cmd_Argv (1);
|
||||||
|
len = Q_strlen(partial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
partial = NULL;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
count=0;
|
||||||
|
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||||
|
{
|
||||||
|
if (partial && Q_strncmp (partial,cmd->name, len))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Con_Printf ("\"%s\"\n", cmd->name);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con_Printf ("%i command(s)", count);
|
||||||
|
if (partial)
|
||||||
|
{
|
||||||
|
Con_Printf (" beginning with \"%s\"", partial);
|
||||||
|
}
|
||||||
|
Con_Printf ("\n");
|
||||||
|
}
|
||||||
|
// 2000-01-09 CmdList command by Maddes end
|
||||||
|
|
||||||
|
// 2000-01-09 CvarList command by Maddes start
|
||||||
|
/*
|
||||||
|
=========
|
||||||
|
Cvar_List
|
||||||
|
=========
|
||||||
|
*/
|
||||||
|
void Cvar_List_f (void)
|
||||||
|
{
|
||||||
|
cvar_t *cvar;
|
||||||
|
char *partial;
|
||||||
|
int len;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (Cmd_Argc() > 1)
|
||||||
|
{
|
||||||
|
partial = Cmd_Argv (1);
|
||||||
|
len = Q_strlen(partial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
partial = NULL;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
count=0;
|
||||||
|
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
||||||
|
{
|
||||||
|
if (partial && Q_strncmp (partial,cvar->name, len))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Con_Printf ("\"%s\" is \"%s\"\n", cvar->name, cvar->string);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con_Printf ("%i cvar(s)", count);
|
||||||
|
if (partial)
|
||||||
|
{
|
||||||
|
Con_Printf (" beginning with \"%s\"", partial);
|
||||||
|
}
|
||||||
|
Con_Printf ("\n");
|
||||||
|
}
|
||||||
|
// 2000-01-09 CvarList command by Maddes end
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_Init
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cmd_Init (void)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// register our commands
|
||||||
|
//
|
||||||
|
Cmd_AddCommand ("cmdlist", Cmd_List_f); // 2000-01-09 CmdList command by Maddes
|
||||||
|
Cmd_AddCommand ("cvarlist", Cvar_List_f); // 2000-01-09 CvarList command by Maddes
|
||||||
|
Cmd_AddCommand ("stuffcmds",Cmd_StuffCmds_f);
|
||||||
|
Cmd_AddCommand ("exec",Cmd_Exec_f);
|
||||||
|
Cmd_AddCommand ("echo",Cmd_Echo_f);
|
||||||
|
Cmd_AddCommand ("alias",Cmd_Alias_f);
|
||||||
|
Cmd_AddCommand ("cmd", Cmd_ForwardToServer);
|
||||||
|
Cmd_AddCommand ("wait", Cmd_Wait_f);
|
||||||
|
Cmd_AddCommand ("maps", Cmd_Maps_f); //Crow_bar
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_Argc
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
int Cmd_Argc (void)
|
||||||
|
{
|
||||||
|
return cmd_argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_Argv
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
char *Cmd_Argv (int arg)
|
||||||
|
{
|
||||||
|
if ( (unsigned)arg >= cmd_argc )
|
||||||
|
return cmd_null_string;
|
||||||
|
return cmd_argv[arg];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_Args
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
char *Cmd_Args (void)
|
||||||
|
{
|
||||||
|
return cmd_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_TokenizeString
|
||||||
|
|
||||||
|
Parses the given string into command line tokens.
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cmd_TokenizeString (char *text)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// clear the args from the last string
|
||||||
|
for (i=0 ; i<cmd_argc ; i++)
|
||||||
|
Z_Free (cmd_argv[i]);
|
||||||
|
|
||||||
|
cmd_argc = 0;
|
||||||
|
cmd_args = NULL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
// skip whitespace up to a /n
|
||||||
|
while (*text && *text <= ' ' && *text != '\n')
|
||||||
|
{
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*text == '\n')
|
||||||
|
{ // a newline seperates commands in the buffer
|
||||||
|
text++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cmd_argc == 1)
|
||||||
|
cmd_args = text;
|
||||||
|
|
||||||
|
text = COM_Parse (text);
|
||||||
|
if (!text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cmd_argc < MAX_ARGS)
|
||||||
|
{
|
||||||
|
cmd_argv[cmd_argc] = Z_Malloc (Q_strlen(com_token)+1);
|
||||||
|
Q_strcpy (cmd_argv[cmd_argc], com_token);
|
||||||
|
cmd_argc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_AddCommand
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cmd_AddCommand (char *cmd_name, xcommand_t function)
|
||||||
|
{
|
||||||
|
cmd_function_t *cmd;
|
||||||
|
|
||||||
|
if (host_initialized) // because hunk allocation would get stomped
|
||||||
|
Sys_Error ("Cmd_AddCommand after host_initialized");
|
||||||
|
|
||||||
|
// fail if the command is a variable name
|
||||||
|
if (Cvar_VariableString(cmd_name)[0])
|
||||||
|
{
|
||||||
|
Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail if the command already exists
|
||||||
|
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||||
|
{
|
||||||
|
if (!Q_strcmp (cmd_name, cmd->name))
|
||||||
|
{
|
||||||
|
Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = Hunk_Alloc (sizeof(cmd_function_t));
|
||||||
|
cmd->name = cmd_name;
|
||||||
|
cmd->function = function;
|
||||||
|
cmd->next = cmd_functions;
|
||||||
|
cmd_functions = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_Exists
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
qboolean Cmd_Exists (char *cmd_name)
|
||||||
|
{
|
||||||
|
cmd_function_t *cmd;
|
||||||
|
|
||||||
|
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||||
|
{
|
||||||
|
if (!Q_strcmp (cmd_name,cmd->name))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_CompleteCommand
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
char *Cmd_CompleteCommand (char *partial)
|
||||||
|
{
|
||||||
|
cmd_function_t *cmd;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = Q_strlen(partial);
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// check functions
|
||||||
|
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||||
|
if (!Q_strncmp (partial,cmd->name, len))
|
||||||
|
return cmd->name;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cmd_ExecuteString
|
||||||
|
|
||||||
|
A complete command line has been parsed, so try to execute it
|
||||||
|
FIXME: lookupnoadd the token to speed search?
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cmd_ExecuteString (char *text, cmd_source_t src)
|
||||||
|
{
|
||||||
|
cmd_function_t *cmd;
|
||||||
|
cmdalias_t *a;
|
||||||
|
|
||||||
|
cmd_source = src;
|
||||||
|
Cmd_TokenizeString (text);
|
||||||
|
|
||||||
|
// execute the command line
|
||||||
|
if (!Cmd_Argc())
|
||||||
|
return; // no tokens
|
||||||
|
|
||||||
|
// check functions
|
||||||
|
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
|
||||||
|
{
|
||||||
|
if (!Q_strcasecmp (cmd_argv[0],cmd->name))
|
||||||
|
{
|
||||||
|
cmd->function ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check alias
|
||||||
|
for (a=cmd_alias ; a ; a=a->next)
|
||||||
|
{
|
||||||
|
if (!Q_strcasecmp (cmd_argv[0], a->name))
|
||||||
|
{
|
||||||
|
Cbuf_InsertText (a->value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check cvars
|
||||||
|
if (!Cvar_Command ())
|
||||||
|
Con_Printf ("Command \"%s\" not found, check QC...\n", Cmd_Argv(0));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
Cmd_ForwardToServer
|
||||||
|
|
||||||
|
Sends the entire command line over to the server
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
void Cmd_ForwardToServer (void)
|
||||||
|
{
|
||||||
|
if (cls.state != ca_connected)
|
||||||
|
{
|
||||||
|
Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cls.demoplayback)
|
||||||
|
return; // not really connected
|
||||||
|
|
||||||
|
MSG_WriteByte (&cls.message, clc_stringcmd);
|
||||||
|
if (Q_strcasecmp(Cmd_Argv(0), "cmd") != 0)
|
||||||
|
{
|
||||||
|
SZ_Print (&cls.message, Cmd_Argv(0));
|
||||||
|
SZ_Print (&cls.message, " ");
|
||||||
|
}
|
||||||
|
if (Cmd_Argc() > 1)
|
||||||
|
SZ_Print (&cls.message, Cmd_Args());
|
||||||
|
else
|
||||||
|
SZ_Print (&cls.message, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Cmd_CheckParm
|
||||||
|
|
||||||
|
Returns the position (1 to argc-1) in the command's argument list
|
||||||
|
where the given parameter apears, or 0 if not present
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Cmd_CheckParm (char *parm)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!parm)
|
||||||
|
Sys_Error ("Cmd_CheckParm: NULL");
|
||||||
|
|
||||||
|
for (i = 1; i < Cmd_Argc (); i++)
|
||||||
|
if (! Q_strcasecmp (parm, Cmd_Argv (i)))
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
125
source/cmd.h
Normal file
125
source/cmd.h
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// cmd.h -- Command buffer and command execution
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Any number of commands can be added in a frame, from several different sources.
|
||||||
|
Most commands come from either keybindings or console line input, but remote
|
||||||
|
servers can also send across commands and entire text files can be execed.
|
||||||
|
|
||||||
|
The + command line options are also added to the command buffer.
|
||||||
|
|
||||||
|
The game starts with a Cbuf_AddText ("exec nzp.rc\n"); Cbuf_Execute ();
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void Cbuf_Init (void);
|
||||||
|
// allocates an initial text buffer that will grow as needed
|
||||||
|
|
||||||
|
void Cbuf_AddText (char *text);
|
||||||
|
// as new commands are generated from the console or keybindings,
|
||||||
|
// the text is added to the end of the command buffer.
|
||||||
|
|
||||||
|
void Cbuf_InsertText (char *text);
|
||||||
|
// when a command wants to issue other commands immediately, the text is
|
||||||
|
// inserted at the beginning of the buffer, before any remaining unexecuted
|
||||||
|
// commands.
|
||||||
|
|
||||||
|
void Cbuf_Execute (void);
|
||||||
|
// Pulls off \n terminated lines of text from the command buffer and sends
|
||||||
|
// them through Cmd_ExecuteString. Stops when the buffer is empty.
|
||||||
|
// Normally called once per frame, but may be explicitly invoked.
|
||||||
|
// Do not call inside a command function!
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Command execution takes a null terminated string, breaks it into tokens,
|
||||||
|
then searches for a command or variable that matches the first token.
|
||||||
|
|
||||||
|
Commands can come from three sources, but the handler functions may choose
|
||||||
|
to dissallow the action or forward it to a remote server if the source is
|
||||||
|
not apropriate.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void (*xcommand_t) (void);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
src_client, // came in over a net connection as a clc_stringcmd
|
||||||
|
// host_client will be valid during this state.
|
||||||
|
src_command // from the command buffer
|
||||||
|
} cmd_source_t;
|
||||||
|
|
||||||
|
extern cmd_source_t cmd_source;
|
||||||
|
|
||||||
|
#define MAX_FILELENGTH 64
|
||||||
|
|
||||||
|
#define MAXCMDLINE 256
|
||||||
|
|
||||||
|
void Cmd_Init (void);
|
||||||
|
|
||||||
|
void Cmd_AddCommand (char *cmd_name, xcommand_t function);
|
||||||
|
// called by the init functions of other parts of the program to
|
||||||
|
// register commands and functions to call for them.
|
||||||
|
// The cmd_name is referenced later, so it should not be in temp memory
|
||||||
|
|
||||||
|
qboolean Cmd_Exists (char *cmd_name);
|
||||||
|
// used by the cvar code to check for cvar / command name overlap
|
||||||
|
|
||||||
|
char *Cmd_CompleteCommand (char *partial);
|
||||||
|
// attempts to match a partial command for automatic command line completion
|
||||||
|
// returns NULL if nothing fits
|
||||||
|
|
||||||
|
int Cmd_Argc (void);
|
||||||
|
char *Cmd_Argv (int arg);
|
||||||
|
char *Cmd_Args (void);
|
||||||
|
// The functions that execute commands get their parameters with these
|
||||||
|
// functions. Cmd_Argv () will return an empty string, not a NULL
|
||||||
|
// if arg > argc, so string operations are allways safe.
|
||||||
|
|
||||||
|
int Cmd_CheckParm (char *parm);
|
||||||
|
// Returns the position (1 to argc-1) in the command's argument list
|
||||||
|
// where the given parameter apears, or 0 if not present
|
||||||
|
|
||||||
|
void Cmd_TokenizeString (char *text);
|
||||||
|
// Takes a null terminated string. Does not need to be /n terminated.
|
||||||
|
// breaks the string up into arg tokens.
|
||||||
|
|
||||||
|
void Cmd_ExecuteString (char *text, cmd_source_t src);
|
||||||
|
// Parses a single line of text into arguments and tries to execute it.
|
||||||
|
// The text can come from the command buffer, a remote client, or stdin.
|
||||||
|
|
||||||
|
void Cmd_ForwardToServer (void);
|
||||||
|
// adds the current command line as a clc_stringcmd to the client message.
|
||||||
|
// things like godmode, noclip, etc, are commands directed to the server,
|
||||||
|
// so when they are typed in at the console, they will need to be forwarded.
|
||||||
|
|
||||||
|
void Cmd_Print (char *text);
|
||||||
|
// used by command functions to send output to either the graphics console or
|
||||||
|
// passed as a print message to the client
|
||||||
|
|
2040
source/common.c
Normal file
2040
source/common.c
Normal file
File diff suppressed because it is too large
Load diff
203
source/common.h
Normal file
203
source/common.h
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// comndef.h -- general definitions
|
||||||
|
|
||||||
|
#if !defined BYTE_DEFINED
|
||||||
|
typedef unsigned char byte;
|
||||||
|
#define BYTE_DEFINED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef true
|
||||||
|
#undef false
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
typedef enum {qfalse, qtrue} qboolean;
|
||||||
|
#else
|
||||||
|
typedef enum {false, true} qboolean;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef fmin
|
||||||
|
#define fmin(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef fmax
|
||||||
|
#define fmax(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define bound(a, b, c) ((a) >= (c) ? (a) : (b) < (a) ? (a) : (b) > (c) ? (c) : (b))
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
typedef struct sizebuf_s
|
||||||
|
{
|
||||||
|
qboolean allowoverflow; // if false, do a Sys_Error
|
||||||
|
qboolean overflowed; // set to true if the buffer size failed
|
||||||
|
byte *data;
|
||||||
|
int maxsize;
|
||||||
|
int cursize;
|
||||||
|
} sizebuf_t;
|
||||||
|
|
||||||
|
void SZ_Alloc (sizebuf_t *buf, int startsize);
|
||||||
|
void SZ_Free (sizebuf_t *buf);
|
||||||
|
void SZ_Clear (sizebuf_t *buf);
|
||||||
|
void *SZ_GetSpace (sizebuf_t *buf, int length);
|
||||||
|
void SZ_Write (sizebuf_t *buf, void *data, int length);
|
||||||
|
void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
typedef struct link_s
|
||||||
|
{
|
||||||
|
struct link_s *prev, *next;
|
||||||
|
} link_t;
|
||||||
|
|
||||||
|
|
||||||
|
void ClearLink (link_t *l);
|
||||||
|
void RemoveLink (link_t *l);
|
||||||
|
void InsertLinkBefore (link_t *l, link_t *before);
|
||||||
|
void InsertLinkAfter (link_t *l, link_t *after);
|
||||||
|
|
||||||
|
// (type *)STRUCT_FROM_LINK(link_t *link, type, member)
|
||||||
|
// ent = STRUCT_FROM_LINK(link,entity_t,order)
|
||||||
|
// FIXME: remove this mess!
|
||||||
|
#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m)))
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define Q_MAXCHAR ((char)0x7f)
|
||||||
|
#define Q_MAXSHORT ((short)0x7fff)
|
||||||
|
#define Q_MAXINT ((int)0x7fffffff)
|
||||||
|
#define Q_MAXLONG ((int)0x7fffffff)
|
||||||
|
#define Q_MAXFLOAT ((int)0x7fffffff)
|
||||||
|
|
||||||
|
#define Q_MINCHAR ((char)0x80)
|
||||||
|
#define Q_MINSHORT ((short)0x8000)
|
||||||
|
#define Q_MININT ((int)0x80000000)
|
||||||
|
#define Q_MINLONG ((int)0x80000000)
|
||||||
|
#define Q_MINFLOAT ((int)0x7fffffff)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_TOKEN_CHARS 128 // max length of an individual token
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
extern qboolean bigendien;
|
||||||
|
|
||||||
|
extern short (*BigShort) (short l);
|
||||||
|
extern short (*LittleShort) (short l);
|
||||||
|
extern int (*BigLong) (int l);
|
||||||
|
extern int (*LittleLong) (int l);
|
||||||
|
extern float (*BigFloat) (float l);
|
||||||
|
extern float (*LittleFloat) (float l);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void MSG_WriteChar (sizebuf_t *sb, int c);
|
||||||
|
void MSG_WriteByte (sizebuf_t *sb, int c);
|
||||||
|
void MSG_WriteShort (sizebuf_t *sb, int c);
|
||||||
|
void MSG_WriteLong (sizebuf_t *sb, int c);
|
||||||
|
void MSG_WriteFloat (sizebuf_t *sb, float f);
|
||||||
|
void MSG_WriteString (sizebuf_t *sb, char *s);
|
||||||
|
void MSG_WriteCoord (sizebuf_t *sb, float f);
|
||||||
|
void MSG_WriteAngle (sizebuf_t *sb, float f);
|
||||||
|
|
||||||
|
extern int msg_readcount;
|
||||||
|
extern qboolean msg_badread; // set if a read goes beyond end of message
|
||||||
|
|
||||||
|
void MSG_BeginReading (void);
|
||||||
|
int MSG_ReadChar (void);
|
||||||
|
int MSG_ReadByte (void);
|
||||||
|
int MSG_ReadShort (void);
|
||||||
|
int MSG_ReadLong (void);
|
||||||
|
float MSG_ReadFloat (void);
|
||||||
|
char *MSG_ReadString (void);
|
||||||
|
|
||||||
|
float MSG_ReadCoord (void);
|
||||||
|
float MSG_ReadAngle (void);
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void Q_strncpyz (char *dest, char *src, size_t size);
|
||||||
|
void Q_snprintfz (char *dest, size_t size, char *fmt, ...);
|
||||||
|
void Q_memset (void *dest, int fill, int count);
|
||||||
|
void Q_memcpy (void *dest, void *src, int count);
|
||||||
|
int Q_memcmp (void *m1, void *m2, int count);
|
||||||
|
void Q_strcpy (char *dest, char *src);
|
||||||
|
void Q_strncpy (char *dest, char *src, int count);
|
||||||
|
int Q_strlen (char *str);
|
||||||
|
char *Q_strrchr (char *s, char c);
|
||||||
|
void Q_strcat (char *dest, char *src);
|
||||||
|
int Q_strcmp (char *s1, char *s2);
|
||||||
|
int Q_strncmp (char *s1, char *s2, int count);
|
||||||
|
int Q_strcasecmp (char *s1, char *s2);
|
||||||
|
int Q_strncasecmp (char *s1, char *s2, int n);
|
||||||
|
int Q_atoi (char *str);
|
||||||
|
float Q_atof (char *str);
|
||||||
|
|
||||||
|
extern char com_token[1024];
|
||||||
|
extern qboolean com_eof;
|
||||||
|
|
||||||
|
char *COM_Parse (char *data);
|
||||||
|
char *COM_ParseQ2 (char **data_p);
|
||||||
|
|
||||||
|
extern int com_argc;
|
||||||
|
extern char **com_argv;
|
||||||
|
|
||||||
|
int COM_CheckParm (char *parm);
|
||||||
|
void COM_Init (char *path);
|
||||||
|
void COM_InitArgv (int argc, char **argv);
|
||||||
|
|
||||||
|
char *COM_SkipPath (char *pathname);
|
||||||
|
char *COM_SkipPathWritable (char *pathname);
|
||||||
|
void COM_StripExtension (char *in, char *out);
|
||||||
|
void COM_FileBase (char *in, char *out);
|
||||||
|
void COM_DefaultExtension (char *path, char *extension);
|
||||||
|
|
||||||
|
char *va(char *format, ...);
|
||||||
|
char *CopyString (char *in);
|
||||||
|
// does a varargs printf into a temp buffer
|
||||||
|
|
||||||
|
extern int com_filesize;
|
||||||
|
struct cache_user_s;
|
||||||
|
|
||||||
|
extern char com_gamedir[MAX_OSPATH];
|
||||||
|
|
||||||
|
void COM_WriteFile (char *filename, void *data, int len);
|
||||||
|
int COM_OpenFile (char *filename, int *hndl);
|
||||||
|
int COM_FOpenFile (char *filename, int *file);
|
||||||
|
void COM_CloseFile (int h);
|
||||||
|
void COM_CreatePath (char *path);
|
||||||
|
char *COM_FileExtension (char *in);
|
||||||
|
byte *COM_LoadStackFile (char *path, void *buffer, int bufsize);
|
||||||
|
byte *COM_LoadTempFile (char *path);
|
||||||
|
byte *COM_LoadHunkFile (char *path);
|
||||||
|
byte *COM_LoadFile (char *path, int usehunk);
|
||||||
|
void COM_LoadCacheFile (char *path, struct cache_user_s *cu);
|
||||||
|
//============================================================================
|
||||||
|
qboolean FS_FindFile (char *filename);
|
||||||
|
int FS_FOpenFile (char *filename, FILE **file);
|
||||||
|
extern char com_netpath[MAX_OSPATH];
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
extern qboolean user_maps;
|
679
source/console.c
Normal file
679
source/console.c
Normal file
|
@ -0,0 +1,679 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// console.c
|
||||||
|
|
||||||
|
#ifdef NeXT
|
||||||
|
#include <libc.h>
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
int con_linewidth;
|
||||||
|
|
||||||
|
float con_cursorspeed = 4;
|
||||||
|
|
||||||
|
#define CON_TEXTSIZE 16384
|
||||||
|
|
||||||
|
qboolean con_forcedup; // because no entities to refresh
|
||||||
|
|
||||||
|
int con_totallines; // total lines in console scrollback
|
||||||
|
int con_backscroll; // lines up from bottom to display
|
||||||
|
int con_current; // where next message will be printed
|
||||||
|
int con_x; // offset in current line for next print
|
||||||
|
char *con_text=0;
|
||||||
|
|
||||||
|
cvar_t con_notifytime = {"con_notifytime","3"}; //seconds
|
||||||
|
|
||||||
|
#define NUM_CON_TIMES 4
|
||||||
|
float con_times[NUM_CON_TIMES]; // realtime time the line was generated
|
||||||
|
// for transparent notify lines
|
||||||
|
|
||||||
|
int con_vislines;
|
||||||
|
|
||||||
|
qboolean con_debuglog;
|
||||||
|
|
||||||
|
#define MAXCMDLINE 256
|
||||||
|
extern char key_lines[32][MAXCMDLINE];
|
||||||
|
extern int edit_line;
|
||||||
|
extern int key_linepos;
|
||||||
|
|
||||||
|
|
||||||
|
qboolean con_initialized;
|
||||||
|
|
||||||
|
int con_notifylines; // scan lines to clear for notify lines
|
||||||
|
|
||||||
|
extern void M_Menu_Main_f (void);
|
||||||
|
|
||||||
|
void M_OSK_Draw (void);
|
||||||
|
void Con_OSK_f (char *input, char *output, int outlen);
|
||||||
|
void Con_OSK_Key(int key);
|
||||||
|
void Con_DrawOSK(void);
|
||||||
|
extern qboolean console_enabled;
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_ToggleConsole_f
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_ToggleConsole_f (void)
|
||||||
|
{
|
||||||
|
if (key_dest == key_console)
|
||||||
|
{
|
||||||
|
if (cls.state == ca_connected)
|
||||||
|
{
|
||||||
|
key_dest = key_game;
|
||||||
|
console_enabled = false;
|
||||||
|
key_lines[edit_line][1] = 0; // clear any typing
|
||||||
|
key_linepos = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console_enabled = false;
|
||||||
|
M_Menu_Main_f ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
key_dest = key_console;
|
||||||
|
|
||||||
|
SCR_EndLoadingPlaque ();
|
||||||
|
memset (con_times, 0, sizeof(con_times));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_Clear_f
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_Clear_f (void)
|
||||||
|
{
|
||||||
|
if (con_text)
|
||||||
|
Q_memset (con_text, ' ', CON_TEXTSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_ClearNotify
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_ClearNotify (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0 ; i<NUM_CON_TIMES ; i++)
|
||||||
|
con_times[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_MessageMode_f
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
extern qboolean team_message;
|
||||||
|
|
||||||
|
void Con_MessageMode_f (void)
|
||||||
|
{
|
||||||
|
key_dest = key_message;
|
||||||
|
team_message = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_MessageMode2_f
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_MessageMode2_f (void)
|
||||||
|
{
|
||||||
|
key_dest = key_message;
|
||||||
|
team_message = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_CheckResize
|
||||||
|
|
||||||
|
If the line width has changed, reformat the buffer.
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_CheckResize (void)
|
||||||
|
{
|
||||||
|
int i, j, width, oldwidth, oldtotallines, numlines, numchars;
|
||||||
|
char tbuf[CON_TEXTSIZE];
|
||||||
|
|
||||||
|
width = (vid.width >> 3) - 2;
|
||||||
|
|
||||||
|
if (width == con_linewidth)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (width < 1) // video hasn't been initialized yet
|
||||||
|
{
|
||||||
|
width = 38;
|
||||||
|
con_linewidth = width;
|
||||||
|
con_totallines = CON_TEXTSIZE / con_linewidth;
|
||||||
|
Q_memset (con_text, ' ', CON_TEXTSIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldwidth = con_linewidth;
|
||||||
|
con_linewidth = width;
|
||||||
|
oldtotallines = con_totallines;
|
||||||
|
con_totallines = CON_TEXTSIZE / con_linewidth;
|
||||||
|
numlines = oldtotallines;
|
||||||
|
|
||||||
|
if (con_totallines < numlines)
|
||||||
|
numlines = con_totallines;
|
||||||
|
|
||||||
|
numchars = oldwidth;
|
||||||
|
|
||||||
|
if (con_linewidth < numchars)
|
||||||
|
numchars = con_linewidth;
|
||||||
|
|
||||||
|
Q_memcpy (tbuf, con_text, CON_TEXTSIZE);
|
||||||
|
Q_memset (con_text, ' ', CON_TEXTSIZE);
|
||||||
|
|
||||||
|
for (i=0 ; i<numlines ; i++)
|
||||||
|
{
|
||||||
|
for (j=0 ; j<numchars ; j++)
|
||||||
|
{
|
||||||
|
con_text[(con_totallines - 1 - i) * con_linewidth + j] =
|
||||||
|
tbuf[((con_current - i + oldtotallines) %
|
||||||
|
oldtotallines) * oldwidth + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Con_ClearNotify ();
|
||||||
|
}
|
||||||
|
|
||||||
|
con_backscroll = 0;
|
||||||
|
con_current = con_totallines - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_Init
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_Init (void)
|
||||||
|
{
|
||||||
|
#define MAXGAMEDIRLEN 1000
|
||||||
|
char temp[MAXGAMEDIRLEN+1];
|
||||||
|
char *t2 = "/condebug.log";
|
||||||
|
|
||||||
|
con_debuglog = COM_CheckParm("-condebug");
|
||||||
|
|
||||||
|
if (con_debuglog)
|
||||||
|
{
|
||||||
|
if (strlen (com_gamedir) < (MAXGAMEDIRLEN - strlen (t2)))
|
||||||
|
{
|
||||||
|
sprintf (temp, "%s%s", com_gamedir, t2);
|
||||||
|
unlink (temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
con_text = Hunk_AllocName (CON_TEXTSIZE, "context");
|
||||||
|
Q_memset (con_text, ' ', CON_TEXTSIZE);
|
||||||
|
con_linewidth = -1;
|
||||||
|
Con_CheckResize ();
|
||||||
|
|
||||||
|
Con_Printf ("Console initialized.\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// register our commands
|
||||||
|
//
|
||||||
|
Cvar_RegisterVariable (&con_notifytime);
|
||||||
|
|
||||||
|
Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
|
||||||
|
Cmd_AddCommand ("messagemode", Con_MessageMode_f);
|
||||||
|
Cmd_AddCommand ("messagemode2", Con_MessageMode2_f);
|
||||||
|
Cmd_AddCommand ("clear", Con_Clear_f);
|
||||||
|
con_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Con_Linefeed
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Con_Linefeed (void)
|
||||||
|
{
|
||||||
|
con_x = 0;
|
||||||
|
con_current++;
|
||||||
|
Q_memset (&con_text[(con_current%con_totallines)*con_linewidth]
|
||||||
|
, ' ', con_linewidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_Print
|
||||||
|
|
||||||
|
Handles cursor positioning, line wrapping, etc
|
||||||
|
All console printing must go through this in order to be logged to disk
|
||||||
|
If no console is visible, the notify window will pop up.
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_Print (char *txt)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
int c, l;
|
||||||
|
static int cr;
|
||||||
|
int mask;
|
||||||
|
|
||||||
|
con_backscroll = 0;
|
||||||
|
|
||||||
|
if (txt[0] == 1)
|
||||||
|
{
|
||||||
|
mask = 128; // go to colored text
|
||||||
|
S_LocalSound ("misc/talk.wav");
|
||||||
|
// play talk wav
|
||||||
|
txt++;
|
||||||
|
}
|
||||||
|
else if (txt[0] == 2)
|
||||||
|
{
|
||||||
|
mask = 128; // go to colored text
|
||||||
|
txt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
|
||||||
|
while ( (c = *txt) )
|
||||||
|
{
|
||||||
|
// count word length
|
||||||
|
for (l=0 ; l< con_linewidth ; l++)
|
||||||
|
if ( txt[l] <= ' ')
|
||||||
|
break;
|
||||||
|
|
||||||
|
// word wrap
|
||||||
|
if (l != con_linewidth && (con_x + l > con_linewidth) )
|
||||||
|
con_x = 0;
|
||||||
|
|
||||||
|
txt++;
|
||||||
|
|
||||||
|
if (cr)
|
||||||
|
{
|
||||||
|
con_current--;
|
||||||
|
cr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!con_x)
|
||||||
|
{
|
||||||
|
Con_Linefeed ();
|
||||||
|
// mark time for transparent overlay
|
||||||
|
if (con_current >= 0)
|
||||||
|
con_times[con_current % NUM_CON_TIMES] = realtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
con_x = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\r':
|
||||||
|
con_x = 0;
|
||||||
|
cr = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // display character and advance
|
||||||
|
y = con_current % con_totallines;
|
||||||
|
con_text[y*con_linewidth+con_x] = c | mask;
|
||||||
|
con_x++;
|
||||||
|
if (con_x >= con_linewidth)
|
||||||
|
con_x = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_DebugLog
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_DebugLog(char *file, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
static char data[1024];
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
va_start(argptr, fmt);
|
||||||
|
vsprintf(data, fmt, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
|
||||||
|
write(fd, data, strlen(data));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_Printf
|
||||||
|
|
||||||
|
Handles cursor positioning, line wrapping, etc
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
#define MAXPRINTMSG 4096
|
||||||
|
// FIXME: make a buffer size safe vsprintf?
|
||||||
|
void Con_Printf (char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char msg[MAXPRINTMSG];
|
||||||
|
static qboolean inupdate;
|
||||||
|
|
||||||
|
va_start (argptr,fmt);
|
||||||
|
vsprintf (msg,fmt,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
|
||||||
|
// also echo to debugging console
|
||||||
|
Sys_Printf ("%s", msg); // also echo to debugging console
|
||||||
|
|
||||||
|
// log all messages to file
|
||||||
|
if (con_debuglog)
|
||||||
|
Con_DebugLog(va("%s/condebug.log",com_gamedir), "%s", msg);
|
||||||
|
|
||||||
|
if (!con_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cls.state == ca_dedicated)
|
||||||
|
return; // no graphics mode
|
||||||
|
|
||||||
|
// write it to the scrollable buffer
|
||||||
|
Con_Print (msg);
|
||||||
|
|
||||||
|
// update the screen if the console is displayed
|
||||||
|
if (cls.signon != SIGNONS && !scr_disabled_for_loading )
|
||||||
|
{
|
||||||
|
// protect against infinite loop if something in SCR_UpdateScreen calls
|
||||||
|
// Con_Printd
|
||||||
|
if (!inupdate)
|
||||||
|
{
|
||||||
|
inupdate = true;
|
||||||
|
SCR_UpdateScreen ();
|
||||||
|
inupdate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_DPrintf
|
||||||
|
|
||||||
|
A Con_Printf that only shows up if the "developer" cvar is set
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_DPrintf (char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char msg[MAXPRINTMSG];
|
||||||
|
|
||||||
|
if (!developer.value)
|
||||||
|
return; // don't confuse non-developers with techie stuff...
|
||||||
|
|
||||||
|
va_start (argptr,fmt);
|
||||||
|
vsprintf (msg,fmt,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
|
||||||
|
Con_Printf ("%s", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Con_SafePrintf
|
||||||
|
|
||||||
|
Okay to call even when the screen can't be updated
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Con_SafePrintf (char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char msg[1024];
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
va_start (argptr,fmt);
|
||||||
|
vsprintf (msg,fmt,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
|
||||||
|
temp = scr_disabled_for_loading;
|
||||||
|
scr_disabled_for_loading = true;
|
||||||
|
Con_Printf ("%s", msg);
|
||||||
|
scr_disabled_for_loading = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
DRAWING
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_DrawInput
|
||||||
|
|
||||||
|
The input line scrolls horizontally if typing goes beyond the right edge
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_DrawInput (void)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
int i;
|
||||||
|
char *text;
|
||||||
|
|
||||||
|
if (key_dest != key_console && !con_forcedup)
|
||||||
|
return; // don't draw anything
|
||||||
|
|
||||||
|
text = key_lines[edit_line];
|
||||||
|
|
||||||
|
// add the cursor frame
|
||||||
|
text[key_linepos] = 10+((int)(realtime*con_cursorspeed)&1);
|
||||||
|
|
||||||
|
// fill out remainder with spaces
|
||||||
|
for (i=key_linepos+1 ; i< con_linewidth ; i++)
|
||||||
|
text[i] = ' ';
|
||||||
|
|
||||||
|
// prestep if horizontally scrolling
|
||||||
|
if (key_linepos >= con_linewidth)
|
||||||
|
text += 1 + key_linepos - con_linewidth;
|
||||||
|
|
||||||
|
// draw it
|
||||||
|
y = con_vislines-16;
|
||||||
|
|
||||||
|
for (i=0 ; i<con_linewidth ; i++)
|
||||||
|
Draw_Character ( (i+1)<<3, con_vislines - 16, text[i]);
|
||||||
|
|
||||||
|
// remove cursor
|
||||||
|
key_lines[edit_line][key_linepos] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_DrawNotify
|
||||||
|
|
||||||
|
Draws the last few lines of output transparently over the game top
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Con_DrawNotify (void)
|
||||||
|
{
|
||||||
|
int x, v;
|
||||||
|
char *text;
|
||||||
|
int i;
|
||||||
|
float time;
|
||||||
|
extern char chat_buffer[];
|
||||||
|
|
||||||
|
v = 0;
|
||||||
|
for (i= con_current-NUM_CON_TIMES+1 ; i<=con_current ; i++)
|
||||||
|
{
|
||||||
|
if (i < 0)
|
||||||
|
continue;
|
||||||
|
time = con_times[i % NUM_CON_TIMES];
|
||||||
|
if (time == 0)
|
||||||
|
continue;
|
||||||
|
time = realtime - time;
|
||||||
|
if (time > con_notifytime.value)
|
||||||
|
continue;
|
||||||
|
text = con_text + (i % con_totallines)*con_linewidth;
|
||||||
|
|
||||||
|
clearnotify = 0;
|
||||||
|
scr_copytop = 1;
|
||||||
|
|
||||||
|
for (x = 0 ; x < con_linewidth ; x++)
|
||||||
|
Draw_Character ( (x+1)<<3, v, text[x]);
|
||||||
|
|
||||||
|
v += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (key_dest == key_message)
|
||||||
|
{
|
||||||
|
clearnotify = 0;
|
||||||
|
scr_copytop = 1;
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
|
||||||
|
Draw_String (8, v, "say:");
|
||||||
|
while(chat_buffer[x])
|
||||||
|
{
|
||||||
|
Draw_Character ( (x+5)<<3, v, chat_buffer[x]);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
Draw_Character ( (x+5)<<3, v, 10+((int)(realtime*con_cursorspeed)&1));
|
||||||
|
v += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v > con_notifylines)
|
||||||
|
con_notifylines = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Con_DrawConsole
|
||||||
|
|
||||||
|
Draws the console with the solid background
|
||||||
|
The typing input line at the bottom should only be drawn if typing is allowed
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
qboolean console_enabled;
|
||||||
|
void Con_DrawConsole (int lines, qboolean drawinput)
|
||||||
|
{
|
||||||
|
int i, x, y;
|
||||||
|
int rows;
|
||||||
|
char *text;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (lines <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// draw the background
|
||||||
|
Draw_ConsoleBackground (lines);
|
||||||
|
if (!console_enabled && !developer.value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// draw the text
|
||||||
|
con_vislines = lines;
|
||||||
|
|
||||||
|
rows = (lines-16)>>3; // rows of text to draw
|
||||||
|
y = lines - 16 - (rows<<3); // may start slightly negative
|
||||||
|
|
||||||
|
for (i= con_current - rows + 1 ; i<=con_current ; i++, y+=8 )
|
||||||
|
{
|
||||||
|
j = i - con_backscroll;
|
||||||
|
if (j<0)
|
||||||
|
j = 0;
|
||||||
|
text = con_text + (j % con_totallines)*con_linewidth;
|
||||||
|
|
||||||
|
for (x=0 ; x<con_linewidth ; x++)
|
||||||
|
Draw_Character ( (x+1)<<3, y, text[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the input prompt, user text, and cursor if desired
|
||||||
|
if (drawinput)
|
||||||
|
Con_DrawInput ();
|
||||||
|
|
||||||
|
Con_DrawOSK();
|
||||||
|
}
|
||||||
|
|
||||||
|
static qboolean scr_osk_active = false;
|
||||||
|
|
||||||
|
|
||||||
|
void Con_SetOSKActive(qboolean active)
|
||||||
|
{
|
||||||
|
scr_osk_active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean Con_isSetOSKActive(void)
|
||||||
|
{
|
||||||
|
return scr_osk_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Con_DrawOSK(void) {
|
||||||
|
if (scr_osk_active) {
|
||||||
|
M_OSK_Draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Con_NotifyBox
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Con_NotifyBox (char *text)
|
||||||
|
{
|
||||||
|
double t1, t2;
|
||||||
|
|
||||||
|
// during startup for sound / cd warnings
|
||||||
|
Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
|
||||||
|
|
||||||
|
Con_Printf (text);
|
||||||
|
|
||||||
|
Con_Printf ("Press a key.\n");
|
||||||
|
Con_Printf("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
|
||||||
|
|
||||||
|
key_count = -2; // wait for a key down and up
|
||||||
|
key_dest = key_console;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
t1 = Sys_FloatTime ();
|
||||||
|
SCR_UpdateScreen ();
|
||||||
|
Sys_SendKeyEvents ();
|
||||||
|
t2 = Sys_FloatTime ();
|
||||||
|
realtime += t2-t1; // make the cursor blink
|
||||||
|
} while (key_count < 0);
|
||||||
|
|
||||||
|
Con_Printf ("\n");
|
||||||
|
key_dest = key_game;
|
||||||
|
realtime = 0; // put the cursor back to invisible
|
||||||
|
}
|
||||||
|
|
46
source/console.h
Normal file
46
source/console.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// console
|
||||||
|
//
|
||||||
|
extern int con_totallines;
|
||||||
|
extern int con_backscroll;
|
||||||
|
extern qboolean con_forcedup; // because no entities to refresh
|
||||||
|
extern qboolean con_initialized;
|
||||||
|
extern byte *con_chars;
|
||||||
|
extern int con_notifylines; // scan lines to clear for notify lines
|
||||||
|
|
||||||
|
void Con_DrawCharacter (int cx, int line, int num);
|
||||||
|
|
||||||
|
void Con_CheckResize (void);
|
||||||
|
void Con_Init (void);
|
||||||
|
void Con_DrawConsole (int lines, qboolean drawinput);
|
||||||
|
void Con_Print (char *txt);
|
||||||
|
void Con_Printf (char *fmt, ...);
|
||||||
|
void Con_DPrintf (char *fmt, ...);
|
||||||
|
void Con_SafePrintf (char *fmt, ...);
|
||||||
|
void Con_Clear_f (void);
|
||||||
|
void Con_DrawNotify (void);
|
||||||
|
void Con_ClearNotify (void);
|
||||||
|
void Con_ToggleConsole_f (void);
|
||||||
|
|
||||||
|
void Con_NotifyBox (char *text); // during startup for sound / cd warnings
|
||||||
|
|
81
source/crc.c
Normal file
81
source/crc.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/* crc.c */
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
#include "crc.h"
|
||||||
|
|
||||||
|
// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
|
||||||
|
// and the initial and final xor values shown below... in other words, the
|
||||||
|
// CCITT standard CRC used by XMODEM
|
||||||
|
|
||||||
|
#define CRC_INIT_VALUE 0xffff
|
||||||
|
#define CRC_XOR_VALUE 0x0000
|
||||||
|
|
||||||
|
static unsigned short crctable[256] =
|
||||||
|
{
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||||
|
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||||
|
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||||
|
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||||
|
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||||
|
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||||
|
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||||
|
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||||
|
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||||
|
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||||
|
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||||
|
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||||
|
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||||
|
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||||
|
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||||
|
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||||
|
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||||
|
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||||
|
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||||
|
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||||
|
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||||
|
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||||
|
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||||
|
};
|
||||||
|
|
||||||
|
void CRC_Init(unsigned short *crcvalue)
|
||||||
|
{
|
||||||
|
*crcvalue = CRC_INIT_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRC_ProcessByte(unsigned short *crcvalue, byte data)
|
||||||
|
{
|
||||||
|
*crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short CRC_Value(unsigned short crcvalue)
|
||||||
|
{
|
||||||
|
return crcvalue ^ CRC_XOR_VALUE;
|
||||||
|
}
|
24
source/crc.h
Normal file
24
source/crc.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/* crc.h */
|
||||||
|
|
||||||
|
void CRC_Init(unsigned short *crcvalue);
|
||||||
|
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
|
||||||
|
unsigned short CRC_Value(unsigned short crcvalue);
|
65
source/crypter.c
Normal file
65
source/crypter.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
DATA Decrypt
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
char rotate(char c, int key)
|
||||||
|
{
|
||||||
|
int l = 'Z' - 'A';
|
||||||
|
|
||||||
|
c += key % l;
|
||||||
|
|
||||||
|
if(c < 'A')
|
||||||
|
c += l;
|
||||||
|
|
||||||
|
if(c > 'Z')
|
||||||
|
c -= l;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char encrypt(char c, int key)
|
||||||
|
{
|
||||||
|
if(c >= 'a' && c <= 'z')
|
||||||
|
c = toupper(c);
|
||||||
|
|
||||||
|
if(c >= 'A' && c <= 'Z')
|
||||||
|
c = rotate(c, key);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char decrypt(char c, int key)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(c < 'A' || c > 'Z')
|
||||||
|
return c;
|
||||||
|
else
|
||||||
|
return rotate(c, key);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strencrypt(char *s, int key, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *result = malloc(len);
|
||||||
|
for(i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
result[i] = encrypt(s[i], key);
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strdecrypt(char *s, int key, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *result = malloc(len);
|
||||||
|
for(i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
result[i] = decrypt(s[i], -key);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
12
source/crypter.h
Normal file
12
source/crypter.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
RSA DATA Decrypt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RSA_H
|
||||||
|
#define RSA_H
|
||||||
|
|
||||||
|
char *strencrypt(char *s, int key, int len);
|
||||||
|
char *strdecrypt(char *s, int key, int len);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
223
source/cvar.c
Normal file
223
source/cvar.c
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// cvar.c -- dynamic variable tracking
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
cvar_t *cvar_vars;
|
||||||
|
char *cvar_null_string = "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_FindVar
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
cvar_t *Cvar_FindVar (char *var_name)
|
||||||
|
{
|
||||||
|
cvar_t *var;
|
||||||
|
|
||||||
|
for (var=cvar_vars ; var ; var=var->next)
|
||||||
|
if (!Q_strcmp (var_name, var->name))
|
||||||
|
return var;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_VariableValue
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
float Cvar_VariableValue (char *var_name)
|
||||||
|
{
|
||||||
|
cvar_t *var;
|
||||||
|
|
||||||
|
var = Cvar_FindVar (var_name);
|
||||||
|
if (!var)
|
||||||
|
return 0;
|
||||||
|
return Q_atof (var->string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_VariableString
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
char *Cvar_VariableString (char *var_name)
|
||||||
|
{
|
||||||
|
cvar_t *var;
|
||||||
|
|
||||||
|
var = Cvar_FindVar (var_name);
|
||||||
|
if (!var)
|
||||||
|
return cvar_null_string;
|
||||||
|
return var->string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_CompleteVariable
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
char *Cvar_CompleteVariable (char *partial)
|
||||||
|
{
|
||||||
|
cvar_t *cvar;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = Q_strlen(partial);
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// check functions
|
||||||
|
for (cvar=cvar_vars ; cvar ; cvar=cvar->next)
|
||||||
|
if (!Q_strncmp (partial,cvar->name, len))
|
||||||
|
return cvar->name;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_Set
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cvar_Set (char *var_name, char *value)
|
||||||
|
{
|
||||||
|
cvar_t *var;
|
||||||
|
qboolean changed;
|
||||||
|
|
||||||
|
var = Cvar_FindVar (var_name);
|
||||||
|
if (!var)
|
||||||
|
{ // there is an error in C code if this happens
|
||||||
|
Con_Printf ("Cvar_Set: variable %s not found\n", var_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = Q_strcmp(var->string, value);
|
||||||
|
|
||||||
|
Z_Free (var->string); // free the old value string
|
||||||
|
|
||||||
|
var->string = Z_Malloc (Q_strlen(value)+1);
|
||||||
|
Q_strcpy (var->string, value);
|
||||||
|
var->value = Q_atof (var->string);
|
||||||
|
if (var->server && changed)
|
||||||
|
{
|
||||||
|
if (sv.active)
|
||||||
|
SV_BroadcastPrintf ("\"%s\" changed to \"%s\"\n", var->name, var->string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_SetValue
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cvar_SetValue (char *var_name, float value)
|
||||||
|
{
|
||||||
|
char val[32];
|
||||||
|
|
||||||
|
sprintf (val, "%f",value);
|
||||||
|
Cvar_Set (var_name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_RegisterVariable
|
||||||
|
|
||||||
|
Adds a freestanding variable to the variable list.
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cvar_RegisterVariable (cvar_t *variable)
|
||||||
|
{
|
||||||
|
char *oldstr;
|
||||||
|
|
||||||
|
// first check to see if it has allready been defined
|
||||||
|
if (Cvar_FindVar (variable->name))
|
||||||
|
{
|
||||||
|
Con_Printf ("Can't register variable %s, allready defined\n", variable->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for overlap with a command
|
||||||
|
if (Cmd_Exists (variable->name))
|
||||||
|
{
|
||||||
|
Con_Printf ("Cvar_RegisterVariable: %s is a command\n", variable->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the value off, because future sets will Z_Free it
|
||||||
|
oldstr = variable->string;
|
||||||
|
variable->string = Z_Malloc (Q_strlen(variable->string)+1);
|
||||||
|
Q_strcpy (variable->string, oldstr);
|
||||||
|
variable->value = Q_atof (variable->string);
|
||||||
|
|
||||||
|
// link the variable in
|
||||||
|
variable->next = cvar_vars;
|
||||||
|
cvar_vars = variable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_Command
|
||||||
|
|
||||||
|
Handles variable inspection and changing from the console
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
qboolean Cvar_Command (void)
|
||||||
|
{
|
||||||
|
cvar_t *v;
|
||||||
|
|
||||||
|
// check variables
|
||||||
|
v = Cvar_FindVar (Cmd_Argv(0));
|
||||||
|
if (!v)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// perform a variable print or set
|
||||||
|
if (Cmd_Argc() == 1)
|
||||||
|
{
|
||||||
|
Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cvar_Set (v->name, Cmd_Argv(1));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
Cvar_WriteVariables
|
||||||
|
|
||||||
|
Writes lines containing "set variable value" for all variables
|
||||||
|
with the archive flag set to true.
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void Cvar_WriteVariables (FILE *f)
|
||||||
|
{
|
||||||
|
cvar_t *var;
|
||||||
|
|
||||||
|
for (var = cvar_vars ; var ; var = var->next)
|
||||||
|
if (var->archive)
|
||||||
|
fprintf (f, "%s \"%s\"\n", var->name, var->string);
|
||||||
|
}
|
||||||
|
|
96
source/cvar.h
Normal file
96
source/cvar.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// cvar.h
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly
|
||||||
|
in C code.
|
||||||
|
|
||||||
|
it is sufficient to initialize a cvar_t with just the first two fields, or
|
||||||
|
you can add a ,true flag for variables that you want saved to the configuration
|
||||||
|
file when the game is quit:
|
||||||
|
|
||||||
|
cvar_t r_draworder = {"r_draworder","1"};
|
||||||
|
cvar_t scr_screensize = {"screensize","1",true};
|
||||||
|
|
||||||
|
Cvars must be registered before use, or they will have a 0 value instead of the float interpretation of the string. Generally, all cvar_t declarations should be registered in the apropriate init function before any console commands are executed:
|
||||||
|
Cvar_RegisterVariable (&host_framerate);
|
||||||
|
|
||||||
|
|
||||||
|
C code usually just references a cvar in place:
|
||||||
|
if ( r_draworder.value )
|
||||||
|
|
||||||
|
It could optionally ask for the value to be looked up for a string name:
|
||||||
|
if (Cvar_VariableValue ("r_draworder"))
|
||||||
|
|
||||||
|
Interpreted prog code can access cvars with the cvar(name) or
|
||||||
|
cvar_set (name, value) internal functions:
|
||||||
|
teamplay = cvar("teamplay");
|
||||||
|
|
||||||
|
The user can access cvars from the console in two ways:
|
||||||
|
r_draworder prints the current value
|
||||||
|
r_draworder 0 sets the current value to 0
|
||||||
|
Cvars are restricted from having the same names as commands to keep this
|
||||||
|
interface from being ambiguous.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct cvar_s
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *string;
|
||||||
|
qboolean archive; // set to true to cause it to be saved to vars.rc
|
||||||
|
qboolean server; // notifies players when changed
|
||||||
|
float value;
|
||||||
|
struct cvar_s *next;
|
||||||
|
} cvar_t;
|
||||||
|
|
||||||
|
void Cvar_RegisterVariable (cvar_t *variable);
|
||||||
|
// registers a cvar that allready has the name, string, and optionally the
|
||||||
|
// archive elements set.
|
||||||
|
|
||||||
|
void Cvar_Set (char *var_name, char *value);
|
||||||
|
// equivelant to "<name> <variable>" typed at the console
|
||||||
|
|
||||||
|
void Cvar_SetValue (char *var_name, float value);
|
||||||
|
// expands value to a string and calls Cvar_Set
|
||||||
|
|
||||||
|
float Cvar_VariableValue (char *var_name);
|
||||||
|
// returns 0 if not defined or non numeric
|
||||||
|
|
||||||
|
char *Cvar_VariableString (char *var_name);
|
||||||
|
// returns an empty string if not defined
|
||||||
|
|
||||||
|
char *Cvar_CompleteVariable (char *partial);
|
||||||
|
// attempts to match a partial variable name for command line completion
|
||||||
|
// returns NULL if nothing fits
|
||||||
|
|
||||||
|
qboolean Cvar_Command (void);
|
||||||
|
// called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known
|
||||||
|
// command. Returns true if the command was a variable reference that
|
||||||
|
// was handled. (print or change)
|
||||||
|
|
||||||
|
void Cvar_WriteVariables (FILE *f);
|
||||||
|
// Writes lines containing "set variable value" for all variables
|
||||||
|
// with the archive flag set to true.
|
||||||
|
|
||||||
|
cvar_t *Cvar_FindVar (char *var_name);
|
||||||
|
|
||||||
|
extern cvar_t *cvar_vars;
|
51
source/draw.h
Normal file
51
source/draw.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// draw.h -- these are the only functions outside the refresh allowed
|
||||||
|
// to touch the vid buffer
|
||||||
|
|
||||||
|
void Draw_Init (void);
|
||||||
|
void Draw_Character (int x, int y, int num);
|
||||||
|
void Draw_DebugChar (char num);
|
||||||
|
void Draw_Pic (int x, int y, qpic_t *pic);
|
||||||
|
void Draw_StretchPic (int x, int y, qpic_t *pic, int x_value, int y_value);
|
||||||
|
void Draw_ColorPic (int x, int y, qpic_t *pic, float r, float g , float b, float a);
|
||||||
|
void Draw_ColoredString (int x, int y, char *text, float r, float g, float b, float a, int scale);
|
||||||
|
void Draw_TransPic (int x, int y, qpic_t *pic);
|
||||||
|
void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation);
|
||||||
|
void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha);
|
||||||
|
void Draw_ConsoleBackground (int lines);
|
||||||
|
void Draw_LoadingFill(void);
|
||||||
|
void Draw_Fill (int x, int y, int w, int h, int c);
|
||||||
|
void Draw_FillByColor (int x, int y, int w, int h, unsigned int c);
|
||||||
|
void Draw_FadeScreen (void);
|
||||||
|
void Draw_String (int x, int y, char *str);
|
||||||
|
|
||||||
|
//other
|
||||||
|
void Clear_LoadingFill (void);
|
||||||
|
byte *StringToRGB (char *s);
|
||||||
|
|
||||||
|
extern float loading_cur_step;
|
||||||
|
extern char loading_name[32];
|
||||||
|
extern float loading_num_step;
|
||||||
|
|
||||||
|
qpic_t *Draw_PicFromWad (char *name);
|
||||||
|
qpic_t *Draw_CachePic (char *path);
|
||||||
|
qpic_t *Draw_CacheImg (char *path);
|
87
source/gnu.txt
Normal file
87
source/gnu.txt
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
Preamble
|
||||||
|
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
|
||||||
|
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
|
||||||
|
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
|
||||||
|
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
976
source/host.c
Normal file
976
source/host.c
Normal file
|
@ -0,0 +1,976 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// host.c -- coordinates spawning and killing of local servers
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "psp/module.h"
|
||||||
|
#include <pspge.h>
|
||||||
|
#include <pspsysevent.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
A server can allways be started, even if the system started out as a client
|
||||||
|
to a remote system.
|
||||||
|
A client can NOT be started if the system started as a dedicated server.
|
||||||
|
Memory is cleared / released when a server or client begins, not when they end.
|
||||||
|
*/
|
||||||
|
|
||||||
|
quakeparms_t host_parms;
|
||||||
|
|
||||||
|
qboolean host_initialized; // true if into command execution
|
||||||
|
|
||||||
|
double host_frametime;
|
||||||
|
double host_time;
|
||||||
|
double realtime; // without any filtering or bounding
|
||||||
|
double oldrealtime; // last frame run
|
||||||
|
int host_framecount;
|
||||||
|
|
||||||
|
int host_hunklevel;
|
||||||
|
|
||||||
|
int minimum_memory;
|
||||||
|
|
||||||
|
client_t *host_client; // current client
|
||||||
|
|
||||||
|
jmp_buf host_abortserver;
|
||||||
|
|
||||||
|
byte *host_basepal;
|
||||||
|
byte *host_colormap;
|
||||||
|
byte *host_q2pal;
|
||||||
|
byte *host_h2pal;
|
||||||
|
|
||||||
|
cvar_t host_framerate = {"host_framerate","0"}; // set for slow motion
|
||||||
|
cvar_t host_speeds = {"host_speeds","0"}; // set for running times
|
||||||
|
|
||||||
|
cvar_t sys_ticrate = {"sys_ticrate","0.05"};
|
||||||
|
cvar_t serverprofile = {"serverprofile","0"};
|
||||||
|
|
||||||
|
cvar_t fraglimit = {"fraglimit","0",false,true};
|
||||||
|
cvar_t timelimit = {"timelimit","0",false,true};
|
||||||
|
cvar_t teamplay = {"teamplay","0",false,true};
|
||||||
|
|
||||||
|
cvar_t samelevel = {"samelevel","0"};
|
||||||
|
|
||||||
|
cvar_t show_fps = {"show_fps","0", true}; // set for running times - muff
|
||||||
|
cvar_t cl_maxfps = {"cl_maxfps", "30", true}; // dr_mabuse1981: maxfps setting
|
||||||
|
cvar_t show_bat = {"show_bat","0"}; // test
|
||||||
|
int fps_count;
|
||||||
|
|
||||||
|
cvar_t developer = {"developer","0"};
|
||||||
|
|
||||||
|
cvar_t skill = {"skill","1"}; // 0 - 3
|
||||||
|
cvar_t deathmatch = {"deathmatch","0"}; // 0, 1, or 2
|
||||||
|
cvar_t coop = {"coop","0"}; // 0 or 1
|
||||||
|
|
||||||
|
cvar_t pausable = {"pausable","1"};
|
||||||
|
|
||||||
|
cvar_t temp1 = {"temp1","0"};
|
||||||
|
|
||||||
|
qboolean bmg_type_changed = false;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Host_EndGame
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Host_EndGame (char *message, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char string[1024];
|
||||||
|
|
||||||
|
va_start (argptr,message);
|
||||||
|
vsprintf (string,message,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
Con_DPrintf ("Host_EndGame: %s\n",string);
|
||||||
|
|
||||||
|
if (sv.active)
|
||||||
|
Host_ShutdownServer (false);
|
||||||
|
|
||||||
|
if (cls.state == ca_dedicated)
|
||||||
|
Sys_Error ("Host_EndGame: %s\n",string); // dedicated servers exit
|
||||||
|
|
||||||
|
if (cls.demonum != -1)
|
||||||
|
CL_NextDemo ();
|
||||||
|
else
|
||||||
|
CL_Disconnect ();
|
||||||
|
|
||||||
|
Clear_LoadingFill ();
|
||||||
|
|
||||||
|
longjmp (host_abortserver, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Host_Error
|
||||||
|
|
||||||
|
This shuts down both the client and server
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Host_Error (char *error, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char string[1024];
|
||||||
|
static qboolean inerror = false;
|
||||||
|
|
||||||
|
if (inerror)
|
||||||
|
Sys_Error ("Host_Error: recursively entered");
|
||||||
|
inerror = true;
|
||||||
|
|
||||||
|
SCR_EndLoadingPlaque (); // reenable screen updates
|
||||||
|
|
||||||
|
va_start (argptr,error);
|
||||||
|
vsprintf (string,error,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
Con_Printf ("Host_Error: %s\n",string);
|
||||||
|
|
||||||
|
if (sv.active)
|
||||||
|
Host_ShutdownServer (false);
|
||||||
|
|
||||||
|
if (cls.state == ca_dedicated)
|
||||||
|
Sys_Error ("Host_Error: %s\n",string); // dedicated servers exit
|
||||||
|
|
||||||
|
CL_Disconnect ();
|
||||||
|
cls.demonum = -1;
|
||||||
|
|
||||||
|
Clear_LoadingFill ();
|
||||||
|
|
||||||
|
inerror = false;
|
||||||
|
|
||||||
|
longjmp (host_abortserver, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Host_FindMaxClients
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Host_FindMaxClients (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
svs.maxclients = 1;
|
||||||
|
|
||||||
|
i = COM_CheckParm ("-dedicated");
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
cls.state = ca_dedicated;
|
||||||
|
if (i != (com_argc - 1))
|
||||||
|
{
|
||||||
|
svs.maxclients = Q_atoi (com_argv[i+1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
svs.maxclients = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cls.state = ca_disconnected;
|
||||||
|
|
||||||
|
i = COM_CheckParm ("-listen");
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (cls.state == ca_dedicated)
|
||||||
|
Sys_Error ("Only one of -dedicated or -listen can be specified");
|
||||||
|
if (i != (com_argc - 1))
|
||||||
|
svs.maxclients = Q_atoi (com_argv[i+1]);
|
||||||
|
else
|
||||||
|
svs.maxclients = 8;
|
||||||
|
}
|
||||||
|
if (svs.maxclients < 1)
|
||||||
|
svs.maxclients = 8;
|
||||||
|
else if (svs.maxclients > MAX_SCOREBOARD)
|
||||||
|
svs.maxclients = MAX_SCOREBOARD;
|
||||||
|
|
||||||
|
svs.maxclientslimit = svs.maxclients;
|
||||||
|
if (svs.maxclientslimit < 4)
|
||||||
|
svs.maxclientslimit = 4;
|
||||||
|
svs.clients = Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients");
|
||||||
|
|
||||||
|
if (svs.maxclients > 1)
|
||||||
|
Cvar_SetValue ("deathmatch", 1.0);
|
||||||
|
else
|
||||||
|
Cvar_SetValue ("deathmatch", 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=======================
|
||||||
|
Host_InitLocal
|
||||||
|
======================
|
||||||
|
*/
|
||||||
|
void Host_InitLocal (void)
|
||||||
|
{
|
||||||
|
Host_InitCommands ();
|
||||||
|
|
||||||
|
Cvar_RegisterVariable (&host_framerate);
|
||||||
|
Cvar_RegisterVariable (&host_speeds);
|
||||||
|
|
||||||
|
Cvar_RegisterVariable (&sys_ticrate);
|
||||||
|
Cvar_RegisterVariable (&serverprofile);
|
||||||
|
|
||||||
|
Cvar_RegisterVariable (&show_bat); // Crow_bar battery info
|
||||||
|
Cvar_RegisterVariable (&show_fps); // muff
|
||||||
|
Cvar_RegisterVariable (&cl_maxfps); // dr_mabuse1981: maxfps setting
|
||||||
|
Cvar_RegisterVariable (&fraglimit);
|
||||||
|
Cvar_RegisterVariable (&timelimit);
|
||||||
|
Cvar_RegisterVariable (&teamplay);
|
||||||
|
Cvar_RegisterVariable (&samelevel);
|
||||||
|
Cvar_RegisterVariable (&skill);
|
||||||
|
Cvar_RegisterVariable (&developer);
|
||||||
|
Cvar_RegisterVariable (&deathmatch);
|
||||||
|
Cvar_RegisterVariable (&coop);
|
||||||
|
|
||||||
|
Cvar_RegisterVariable (&pausable);
|
||||||
|
|
||||||
|
Cvar_RegisterVariable (&temp1);
|
||||||
|
|
||||||
|
Host_FindMaxClients ();
|
||||||
|
|
||||||
|
host_time = 1.0; // so a think at time 0 won't get called
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Host_WriteConfiguration
|
||||||
|
|
||||||
|
Writes key bindings and archived cvars to config.cfg
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Host_WriteConfiguration (void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
// dedicated servers initialize the host but don't parse and set the
|
||||||
|
// config.cfg cvars
|
||||||
|
if (host_initialized & !isDedicated)
|
||||||
|
{
|
||||||
|
f = fopen (va("%s/config.cfg",com_gamedir), "w");
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
Con_Printf ("Couldn't write config.cfg.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Key_WriteBindings (f);
|
||||||
|
Key_WriteDTBindings (f);
|
||||||
|
Cvar_WriteVariables (f);
|
||||||
|
|
||||||
|
fclose (f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
SV_ClientPrintf
|
||||||
|
|
||||||
|
Sends text across to be displayed
|
||||||
|
FIXME: make this just a stuffed echo?
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void SV_ClientPrintf (char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char string[1024];
|
||||||
|
|
||||||
|
va_start (argptr,fmt);
|
||||||
|
vsprintf (string, fmt,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
|
||||||
|
MSG_WriteByte (&host_client->message, svc_print);
|
||||||
|
MSG_WriteString (&host_client->message, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
SV_BroadcastPrintf
|
||||||
|
|
||||||
|
Sends text to all active clients
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void SV_BroadcastPrintf (char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char string[1024];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
va_start (argptr,fmt);
|
||||||
|
vsprintf (string, fmt,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
|
||||||
|
for (i=0 ; i<svs.maxclients ; i++)
|
||||||
|
if (svs.clients[i].active && svs.clients[i].spawned)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (&svs.clients[i].message, svc_print);
|
||||||
|
MSG_WriteString (&svs.clients[i].message, string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Host_ClientCommands
|
||||||
|
|
||||||
|
Send text over to the client to be executed
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void Host_ClientCommands (char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
char string[1024];
|
||||||
|
|
||||||
|
va_start (argptr,fmt);
|
||||||
|
vsprintf (string, fmt,argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
|
||||||
|
MSG_WriteByte (&host_client->message, svc_stufftext);
|
||||||
|
MSG_WriteString (&host_client->message, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=====================
|
||||||
|
SV_DropClient
|
||||||
|
|
||||||
|
Called when the player is getting totally kicked off the host
|
||||||
|
if (crash = true), don't bother sending signofs
|
||||||
|
=====================
|
||||||
|
*/
|
||||||
|
void SV_DropClient (qboolean crash)
|
||||||
|
{
|
||||||
|
int saveSelf;
|
||||||
|
int i;
|
||||||
|
client_t *client;
|
||||||
|
|
||||||
|
if (!crash)
|
||||||
|
{
|
||||||
|
// send any final messages (don't check for errors)
|
||||||
|
if (NET_CanSendMessage (host_client->netconnection))
|
||||||
|
{
|
||||||
|
MSG_WriteByte (&host_client->message, svc_disconnect);
|
||||||
|
NET_SendMessage (host_client->netconnection, &host_client->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host_client->edict && host_client->spawned)
|
||||||
|
{
|
||||||
|
// call the prog function for removing a client
|
||||||
|
// this will set the body to a dead frame, among other things
|
||||||
|
saveSelf = pr_global_struct->self;
|
||||||
|
pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
|
||||||
|
PR_ExecuteProgram (pr_global_struct->ClientDisconnect);
|
||||||
|
pr_global_struct->self = saveSelf;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_Printf ("Client %s removed\n",host_client->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// break the net connection
|
||||||
|
NET_Close (host_client->netconnection);
|
||||||
|
host_client->netconnection = NULL;
|
||||||
|
|
||||||
|
// free the client (the body stays around)
|
||||||
|
host_client->active = false;
|
||||||
|
host_client->name[0] = 0;
|
||||||
|
host_client->old_points = -999999;
|
||||||
|
host_client->old_kills = -999999;
|
||||||
|
net_activeconnections--;
|
||||||
|
|
||||||
|
// send notification to all clients
|
||||||
|
for (i=0, client = svs.clients ; i<svs.maxclients ; i++, client++)
|
||||||
|
{
|
||||||
|
if (!client->active)
|
||||||
|
continue;
|
||||||
|
MSG_WriteByte (&client->message, svc_updatename);
|
||||||
|
MSG_WriteByte (&client->message, host_client - svs.clients);
|
||||||
|
MSG_WriteString (&client->message, "");
|
||||||
|
MSG_WriteByte (&client->message, svc_updatepoints);
|
||||||
|
MSG_WriteByte (&client->message, host_client - svs.clients);
|
||||||
|
MSG_WriteLong (&client->message, 0);
|
||||||
|
MSG_WriteByte (&client->message, svc_updatekills);
|
||||||
|
MSG_WriteByte (&client->message, host_client - svs.clients);
|
||||||
|
MSG_WriteShort (&client->message, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Host_ShutdownServer
|
||||||
|
|
||||||
|
This only happens at the end of a game, not between levels
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Host_ShutdownServer(qboolean crash)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int count;
|
||||||
|
sizebuf_t buf;
|
||||||
|
char message[4];
|
||||||
|
double start;
|
||||||
|
|
||||||
|
if (!sv.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sv.active = false;
|
||||||
|
|
||||||
|
// stop all client sounds immediately
|
||||||
|
if (cls.state == ca_connected)
|
||||||
|
CL_Disconnect ();
|
||||||
|
|
||||||
|
// flush any pending messages - like the score!!!
|
||||||
|
start = Sys_FloatTime();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
|
||||||
|
{
|
||||||
|
if (host_client->active && host_client->message.cursize)
|
||||||
|
{
|
||||||
|
if (NET_CanSendMessage (host_client->netconnection))
|
||||||
|
{
|
||||||
|
NET_SendMessage(host_client->netconnection, &host_client->message);
|
||||||
|
SZ_Clear (&host_client->message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NET_GetMessage(host_client->netconnection);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Sys_FloatTime() - start) > 3.0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (count);
|
||||||
|
|
||||||
|
// make sure all the clients know we're disconnecting
|
||||||
|
buf.data = (byte *)message;
|
||||||
|
buf.maxsize = 4;
|
||||||
|
buf.cursize = 0;
|
||||||
|
MSG_WriteByte(&buf, svc_disconnect);
|
||||||
|
count = NET_SendToAll(&buf, 5);
|
||||||
|
if (count)
|
||||||
|
Con_Printf("Host_ShutdownServer: NET_SendToAll failed for %u clients\n", count);
|
||||||
|
|
||||||
|
for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
|
||||||
|
if (host_client->active)
|
||||||
|
SV_DropClient(crash);
|
||||||
|
|
||||||
|
//
|
||||||
|
// clear structures
|
||||||
|
//
|
||||||
|
memset (&sv, 0, sizeof(sv));
|
||||||
|
memset (svs.clients, 0, svs.maxclientslimit*sizeof(client_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Host_ClearMemory
|
||||||
|
|
||||||
|
This clears all the memory used by both the client and server, but does
|
||||||
|
not reinitialize anything.
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
extern int perk_order[8];
|
||||||
|
extern int current_perk_order;
|
||||||
|
extern double Hitmark_Time, crosshair_spread_time;
|
||||||
|
extern float cur_spread;
|
||||||
|
extern float crosshair_offset_step;
|
||||||
|
void Host_ClearMemory (void)
|
||||||
|
{
|
||||||
|
Con_DPrintf ("Clearing memory\n");
|
||||||
|
|
||||||
|
D_FlushCaches ();
|
||||||
|
|
||||||
|
Mod_ClearAll ();
|
||||||
|
|
||||||
|
if (host_hunklevel)
|
||||||
|
Hunk_FreeToLowMark (host_hunklevel);
|
||||||
|
|
||||||
|
cls.signon = 0;
|
||||||
|
memset (&sv, 0, sizeof(sv));
|
||||||
|
memset (&cl, 0, sizeof(cl));
|
||||||
|
perk_order[0] = 0;
|
||||||
|
perk_order[1] = 0;
|
||||||
|
perk_order[2] = 0;
|
||||||
|
perk_order[3] = 0;
|
||||||
|
perk_order[4] = 0;
|
||||||
|
perk_order[5] = 0;
|
||||||
|
perk_order[6] = 0;
|
||||||
|
perk_order[7] = 0;
|
||||||
|
cl.perks = 0;
|
||||||
|
current_perk_order = 0;
|
||||||
|
crosshair_spread_time = 0;
|
||||||
|
crosshair_offset_step = 0;
|
||||||
|
cur_spread = 0;
|
||||||
|
Hitmark_Time = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
Host_FilterTime
|
||||||
|
|
||||||
|
Returns false if the time is too short to run a frame
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
qboolean Host_FilterTime (float time)
|
||||||
|
{
|
||||||
|
realtime += time;
|
||||||
|
|
||||||
|
/* dr_mabuse1981: old dquake values commented out
|
||||||
|
if (!cls.timedemo && realtime - oldrealtime < 1.0/250.0)
|
||||||
|
return false; // framerate is too high
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (cl_maxfps.value < 1) Cvar_SetValue("cl_maxfps", 30);
|
||||||
|
if (!cls.timedemo && realtime - oldrealtime < 1.0/cl_maxfps.value)
|
||||||
|
return false; // framerate is too high
|
||||||
|
|
||||||
|
host_frametime = realtime - oldrealtime;
|
||||||
|
oldrealtime = realtime;
|
||||||
|
|
||||||
|
if (host_framerate.value > 0)
|
||||||
|
host_frametime = host_framerate.value;
|
||||||
|
else
|
||||||
|
{ // don't allow really long or short frames
|
||||||
|
if (host_frametime > 0.1)
|
||||||
|
host_frametime = 0.1;
|
||||||
|
if (host_frametime < 0.001)
|
||||||
|
host_frametime = 0.001;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
Host_GetConsoleCommands
|
||||||
|
|
||||||
|
Add them exactly as if they had been typed at the console
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
void Host_GetConsoleCommands (void)
|
||||||
|
{
|
||||||
|
char *cmd;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
cmd = Sys_ConsoleInput ();
|
||||||
|
if (!cmd)
|
||||||
|
break;
|
||||||
|
Cbuf_AddText (cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Host_ServerFrame
|
||||||
|
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Host_ServerFrame (void)
|
||||||
|
{
|
||||||
|
// run the world state
|
||||||
|
pr_global_struct->frametime = host_frametime;
|
||||||
|
|
||||||
|
// set the time and clear the general datagram
|
||||||
|
SV_ClearDatagram ();
|
||||||
|
|
||||||
|
// check for new clients
|
||||||
|
SV_CheckForNewClients ();
|
||||||
|
|
||||||
|
// read client messages
|
||||||
|
SV_RunClients ();
|
||||||
|
|
||||||
|
// move things around and think
|
||||||
|
// always pause in single player if in console or menus
|
||||||
|
if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
|
||||||
|
SV_Physics ();
|
||||||
|
|
||||||
|
// send all messages to the clients
|
||||||
|
SV_SendClientMessages ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Host_Frame
|
||||||
|
|
||||||
|
Runs all active servers
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void _Host_Frame (float time)
|
||||||
|
{
|
||||||
|
static double time1 = 0;
|
||||||
|
static double time2 = 0;
|
||||||
|
static double time3 = 0;
|
||||||
|
int pass1, pass2, pass3;
|
||||||
|
|
||||||
|
if (setjmp (host_abortserver) )
|
||||||
|
{
|
||||||
|
return; // something bad happened, or the server disconnected
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep the random time dependent
|
||||||
|
rand ();
|
||||||
|
|
||||||
|
// decide the simulation time
|
||||||
|
if (!Host_FilterTime (time))
|
||||||
|
{
|
||||||
|
return; // don't run too fast, or packets will flood out
|
||||||
|
}
|
||||||
|
|
||||||
|
// get new key events
|
||||||
|
Sys_SendKeyEvents ();
|
||||||
|
|
||||||
|
// allow mice or other external controllers to add commands
|
||||||
|
IN_Commands ();
|
||||||
|
|
||||||
|
// process console commands
|
||||||
|
Cbuf_Execute ();
|
||||||
|
|
||||||
|
NET_Poll();
|
||||||
|
|
||||||
|
// if running the server locally, make intentions now
|
||||||
|
if (sv.active)
|
||||||
|
CL_SendCmd ();
|
||||||
|
|
||||||
|
//-------------------
|
||||||
|
//
|
||||||
|
// server operations
|
||||||
|
//
|
||||||
|
//-------------------
|
||||||
|
|
||||||
|
// check for commands typed to the host
|
||||||
|
Host_GetConsoleCommands ();
|
||||||
|
if (sv.active)
|
||||||
|
Host_ServerFrame ();
|
||||||
|
//-------------------
|
||||||
|
//
|
||||||
|
// client operations
|
||||||
|
//
|
||||||
|
//-------------------
|
||||||
|
|
||||||
|
// if running the server remotely, send intentions now after
|
||||||
|
// the incoming messages have been read
|
||||||
|
if (!sv.active)
|
||||||
|
CL_SendCmd ();
|
||||||
|
|
||||||
|
host_time += host_frametime;
|
||||||
|
|
||||||
|
// fetch results from server
|
||||||
|
if (cls.state == ca_connected)
|
||||||
|
{
|
||||||
|
CL_ReadFromServer ();
|
||||||
|
}
|
||||||
|
// update video
|
||||||
|
if (host_speeds.value)
|
||||||
|
time1 = Sys_FloatTime ();
|
||||||
|
SCR_UpdateScreen ();
|
||||||
|
if (host_speeds.value)
|
||||||
|
time2 = Sys_FloatTime ();
|
||||||
|
// update audio
|
||||||
|
if (cls.signon == SIGNONS)
|
||||||
|
{
|
||||||
|
Thread_UpdateSound(r_origin, vpn, vright, vup);
|
||||||
|
//S_Update (r_origin, vpn, vright, vup);
|
||||||
|
CL_DecayLights ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Thread_UpdateSound(vec3_origin, vec3_origin, vec3_origin, vec3_origin);
|
||||||
|
//S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin);
|
||||||
|
|
||||||
|
//if (bmg_type_changed == true) {
|
||||||
|
CDAudio_Update();
|
||||||
|
// bmg_type_changed = false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (host_speeds.value)
|
||||||
|
{
|
||||||
|
pass1 = (time1 - time3)*1000;
|
||||||
|
time3 = Sys_FloatTime ();
|
||||||
|
pass2 = (time2 - time1)*1000;
|
||||||
|
pass3 = (time3 - time2)*1000;
|
||||||
|
Con_Printf ("%3i tot %3i server %3i gfx %3i snd\n",
|
||||||
|
pass1+pass2+pass3, pass1, pass2, pass3);
|
||||||
|
}
|
||||||
|
|
||||||
|
//frame speed counter
|
||||||
|
fps_count++;//muff
|
||||||
|
host_framecount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Host_Frame (float time)
|
||||||
|
{
|
||||||
|
double time1, time2;
|
||||||
|
static double timetotal;
|
||||||
|
static int timecount;
|
||||||
|
int i, c, m;
|
||||||
|
|
||||||
|
if (!serverprofile.value)
|
||||||
|
{
|
||||||
|
_Host_Frame (time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
time1 = Sys_FloatTime ();
|
||||||
|
_Host_Frame (time);
|
||||||
|
time2 = Sys_FloatTime ();
|
||||||
|
|
||||||
|
timetotal += time2 - time1;
|
||||||
|
timecount++;
|
||||||
|
|
||||||
|
if (timecount < 1000)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m = timetotal*1000/timecount;
|
||||||
|
timecount = 0;
|
||||||
|
timetotal = 0;
|
||||||
|
c = 0;
|
||||||
|
for (i=0 ; i<svs.maxclients ; i++)
|
||||||
|
{
|
||||||
|
if (svs.clients[i].active)
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
Con_Printf ("serverprofile: %2i clients %2i msec\n", c, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
extern int vcrFile;
|
||||||
|
#define VCR_SIGNATURE 0x56435231
|
||||||
|
// "VCR1"
|
||||||
|
|
||||||
|
void Host_InitVCR (quakeparms_t *parms)
|
||||||
|
{
|
||||||
|
int i, len, n;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (COM_CheckParm("-playback"))
|
||||||
|
{
|
||||||
|
if (com_argc != 2)
|
||||||
|
Sys_Error("No other parameters allowed with -playback\n");
|
||||||
|
|
||||||
|
Sys_FileOpenRead("quake.vcr", &vcrFile);
|
||||||
|
if (vcrFile == -1)
|
||||||
|
Sys_Error("playback file not found\n");
|
||||||
|
|
||||||
|
Sys_FileRead (vcrFile, &i, sizeof(int));
|
||||||
|
if (i != VCR_SIGNATURE)
|
||||||
|
Sys_Error("Invalid signature in vcr file\n");
|
||||||
|
|
||||||
|
Sys_FileRead (vcrFile, &com_argc, sizeof(int));
|
||||||
|
com_argv = malloc(com_argc * sizeof(char *));
|
||||||
|
com_argv[0] = parms->argv[0];
|
||||||
|
for (i = 0; i < com_argc; i++)
|
||||||
|
{
|
||||||
|
Sys_FileRead (vcrFile, &len, sizeof(int));
|
||||||
|
p = malloc(len);
|
||||||
|
Sys_FileRead (vcrFile, p, len);
|
||||||
|
com_argv[i+1] = p;
|
||||||
|
}
|
||||||
|
com_argc++; /* add one for arg[0] */
|
||||||
|
parms->argc = com_argc;
|
||||||
|
parms->argv = com_argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (n = COM_CheckParm("-record")) != 0)
|
||||||
|
{
|
||||||
|
vcrFile = Sys_FileOpenWrite("quake.vcr");
|
||||||
|
|
||||||
|
i = VCR_SIGNATURE;
|
||||||
|
Sys_FileWrite(vcrFile, &i, sizeof(int));
|
||||||
|
i = com_argc - 1;
|
||||||
|
Sys_FileWrite(vcrFile, &i, sizeof(int));
|
||||||
|
for (i = 1; i < com_argc; i++)
|
||||||
|
{
|
||||||
|
if (i == n)
|
||||||
|
{
|
||||||
|
len = 10;
|
||||||
|
Sys_FileWrite(vcrFile, &len, sizeof(int));
|
||||||
|
Sys_FileWrite(vcrFile, "-playback", len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len = Q_strlen(com_argv[i]) + 1;
|
||||||
|
Sys_FileWrite(vcrFile, &len, sizeof(int));
|
||||||
|
Sys_FileWrite(vcrFile, com_argv[i], len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preload (void)
|
||||||
|
{
|
||||||
|
Mod_ForName ("models/player.mdl", true);
|
||||||
|
|
||||||
|
Mod_ForName ("progs/ai/zb#.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zal(.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zar(.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zh^.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zbc#.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zalc(.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zarc(.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zhc^.mdl",true);
|
||||||
|
|
||||||
|
Mod_ForName ("progs/ai/zfull.mdl",true);
|
||||||
|
Mod_ForName ("progs/ai/zcfull.mdl",true);
|
||||||
|
|
||||||
|
Mod_ForName ("progs/VModels/v_knife.mdl", true);
|
||||||
|
Mod_ForName ("progs/VModels/v_colt.mdl", true);
|
||||||
|
Mod_ForName ("progs/Misc/instakill!.mdl", true);
|
||||||
|
Mod_ForName ("progs/Misc/maxammo!.mdl", true);
|
||||||
|
Mod_ForName ("progs/Misc/nuke!.mdl", true);
|
||||||
|
Mod_ForName ("progs/Misc/carpenter!.mdl", true);
|
||||||
|
Mod_ForName ("progs/Misc/x2!.mdl", true);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
Host_Init
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
#include "cl_slist.h"
|
||||||
|
|
||||||
|
void M_Start_Menu_f (void);
|
||||||
|
void Host_Init (quakeparms_t *parms)
|
||||||
|
{
|
||||||
|
|
||||||
|
minimum_memory = MINIMUM_MEMORY;
|
||||||
|
|
||||||
|
if (COM_CheckParm ("-minmemory"))
|
||||||
|
parms->memsize = minimum_memory;
|
||||||
|
|
||||||
|
host_parms = *parms;
|
||||||
|
|
||||||
|
if (parms->memsize < minimum_memory)
|
||||||
|
Sys_Error ("Only %4.1f megs of memory available, can't execute game", parms->memsize / (float)0x100000);
|
||||||
|
|
||||||
|
com_argc = parms->argc;
|
||||||
|
com_argv = parms->argv;
|
||||||
|
|
||||||
|
Memory_Init (parms->membase, parms->memsize);
|
||||||
|
Cbuf_Init ();
|
||||||
|
Cmd_Init ();
|
||||||
|
V_Init ();
|
||||||
|
Chase_Init ();
|
||||||
|
Host_InitVCR (parms);
|
||||||
|
COM_Init (parms->basedir);
|
||||||
|
Host_InitLocal ();
|
||||||
|
Key_Init ();
|
||||||
|
Con_Init ();
|
||||||
|
M_Init ();
|
||||||
|
PR_Init ();
|
||||||
|
Mod_Init ();
|
||||||
|
NET_Init ();
|
||||||
|
SV_Init ();
|
||||||
|
Con_Printf ("PSP NZP v%4.1f (PBP: "__TIME__" "__DATE__")\n", (float)(VERSION));
|
||||||
|
Con_Printf ("%4.1f megabyte heap \n",parms->memsize/ (1024*1024.0));
|
||||||
|
Con_Printf ("%4.1f megabyte PSP application heap \n",1.0f*PSP_HEAP_SIZE_MB);
|
||||||
|
Con_Printf ("PSP Model: %s\n", Sys_GetPSPModel());
|
||||||
|
Con_Printf ("VRAM Size: %i bytes\n", sceGeEdramGetSize());
|
||||||
|
|
||||||
|
R_InitTextures (); // needed even for dedicated servers
|
||||||
|
if (cls.state != ca_dedicated)
|
||||||
|
{
|
||||||
|
host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp");
|
||||||
|
if (!host_basepal)
|
||||||
|
Sys_Error ("Couldn't load gfx/palette.lmp");
|
||||||
|
|
||||||
|
host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp");
|
||||||
|
if (!host_colormap)
|
||||||
|
Sys_Error ("Couldn't load gfx/colormap.lmp");
|
||||||
|
|
||||||
|
host_q2pal = (byte *)COM_LoadHunkFile ("gfx/q2pal.lmp");
|
||||||
|
if (!host_q2pal)
|
||||||
|
Sys_Error ("Couldn't load gfx/q2pal.lmp");
|
||||||
|
|
||||||
|
host_h2pal = (byte *)COM_LoadHunkFile ("gfx/h2pal.lmp");
|
||||||
|
if (!host_h2pal)
|
||||||
|
Sys_Error ("Couldn't load gfx/h2pal.lmp");
|
||||||
|
|
||||||
|
IN_Init ();
|
||||||
|
VID_Init (host_basepal);
|
||||||
|
Draw_Init ();
|
||||||
|
SCR_Init ();
|
||||||
|
R_Init ();
|
||||||
|
S_Init ();
|
||||||
|
CDAudio_Init ();
|
||||||
|
HUD_Init ();
|
||||||
|
CL_Init ();
|
||||||
|
}
|
||||||
|
Preload();
|
||||||
|
Cbuf_InsertText ("exec nzp.rc\n");
|
||||||
|
|
||||||
|
Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
|
||||||
|
host_hunklevel = Hunk_LowMark ();
|
||||||
|
|
||||||
|
host_initialized = true;
|
||||||
|
M_Start_Menu_f();
|
||||||
|
Sys_Printf ("========Quake Initialized=========\n");
|
||||||
|
Con_Printf ("==========NZP Initialized=========\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Host_Shutdown
|
||||||
|
|
||||||
|
FIXME: this is a callback from Sys_Quit and Sys_Error. It would be better
|
||||||
|
to run quit through here before the final handoff to the sys code.
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Host_Shutdown(void)
|
||||||
|
{
|
||||||
|
static qboolean isdown = false;
|
||||||
|
|
||||||
|
if (isdown)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isdown = true;
|
||||||
|
|
||||||
|
// keep Con_Printf from trying to update the screen
|
||||||
|
scr_disabled_for_loading = true;
|
||||||
|
|
||||||
|
Clear_LoadingFill ();
|
||||||
|
|
||||||
|
SList_Shutdown();
|
||||||
|
|
||||||
|
Host_WriteConfiguration ();
|
||||||
|
|
||||||
|
if (con_initialized)
|
||||||
|
History_Shutdown ();
|
||||||
|
|
||||||
|
CDAudio_Shutdown ();
|
||||||
|
NET_Shutdown ();
|
||||||
|
S_Shutdown();
|
||||||
|
IN_Shutdown ();
|
||||||
|
|
||||||
|
if (cls.state != ca_dedicated)
|
||||||
|
{
|
||||||
|
VID_Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1454
source/host_cmd.c
Normal file
1454
source/host_cmd.c
Normal file
File diff suppressed because it is too large
Load diff
34
source/input.h
Normal file
34
source/input.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// input.h -- external (non-keyboard) input devices
|
||||||
|
|
||||||
|
void IN_Init (void);
|
||||||
|
|
||||||
|
void IN_Shutdown (void);
|
||||||
|
|
||||||
|
void IN_Commands (void);
|
||||||
|
// oportunity for devices to stick commands on the script buffer
|
||||||
|
|
||||||
|
void IN_Move (usercmd_t *cmd);
|
||||||
|
// add additional movement on top of the keyboard move cmd
|
||||||
|
|
||||||
|
void IN_ClearStates (void);
|
||||||
|
// restores all button and position states to defaults
|
||||||
|
|
1024
source/keys.c
Normal file
1024
source/keys.c
Normal file
File diff suppressed because it is too large
Load diff
140
source/keys.h
Normal file
140
source/keys.h
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// these are the key numbers that should be passed to Key_Event
|
||||||
|
//
|
||||||
|
#define K_TAB 9
|
||||||
|
#define K_ENTER 13
|
||||||
|
#define K_ESCAPE 27
|
||||||
|
#define K_SPACE 32
|
||||||
|
|
||||||
|
// normal keys should be passed as lowercased ascii
|
||||||
|
|
||||||
|
#define K_BACKSPACE 127
|
||||||
|
#define K_UPARROW 128
|
||||||
|
#define K_DOWNARROW 129
|
||||||
|
#define K_LEFTARROW 130
|
||||||
|
#define K_RIGHTARROW 131
|
||||||
|
|
||||||
|
#define K_ALT 132
|
||||||
|
#define K_CTRL 133
|
||||||
|
#define K_SHIFT 134
|
||||||
|
#define K_F1 135
|
||||||
|
#define K_F2 136
|
||||||
|
#define K_F3 137
|
||||||
|
#define K_F4 138
|
||||||
|
#define K_F5 139
|
||||||
|
#define K_F6 140
|
||||||
|
#define K_F7 141
|
||||||
|
#define K_F8 142
|
||||||
|
#define K_F9 143
|
||||||
|
#define K_F10 144
|
||||||
|
#define K_F11 145
|
||||||
|
#define K_F12 146
|
||||||
|
#define K_INS 147
|
||||||
|
#define K_DEL 148
|
||||||
|
#define K_PGDN 149
|
||||||
|
#define K_PGUP 150
|
||||||
|
#define K_HOME 151
|
||||||
|
#define K_END 152
|
||||||
|
#define K_SELECT 153
|
||||||
|
#define K_NOTE 154
|
||||||
|
#define K_SCREEN 155
|
||||||
|
|
||||||
|
#define K_PAUSE 255
|
||||||
|
|
||||||
|
//
|
||||||
|
// mouse buttons generate virtual keys
|
||||||
|
//
|
||||||
|
#define K_MOUSE1 200
|
||||||
|
#define K_MOUSE2 201
|
||||||
|
#define K_MOUSE3 202
|
||||||
|
|
||||||
|
//
|
||||||
|
// joystick buttons
|
||||||
|
//
|
||||||
|
#define K_JOY1 203
|
||||||
|
#define K_JOY2 204
|
||||||
|
#define K_JOY3 205
|
||||||
|
#define K_JOY4 206
|
||||||
|
|
||||||
|
//
|
||||||
|
// aux keys are for multi-buttoned joysticks to generate so they can use
|
||||||
|
// the normal binding process
|
||||||
|
//
|
||||||
|
#define K_AUX1 207
|
||||||
|
#define K_AUX2 208
|
||||||
|
#define K_AUX3 209
|
||||||
|
#define K_AUX4 210
|
||||||
|
#define K_AUX5 211
|
||||||
|
#define K_AUX6 212
|
||||||
|
#define K_AUX7 213
|
||||||
|
#define K_AUX8 214
|
||||||
|
#define K_AUX9 215
|
||||||
|
#define K_AUX10 216
|
||||||
|
#define K_AUX11 217
|
||||||
|
#define K_AUX12 218
|
||||||
|
#define K_AUX13 219
|
||||||
|
#define K_AUX14 220
|
||||||
|
#define K_AUX15 221
|
||||||
|
#define K_AUX16 222
|
||||||
|
#define K_AUX17 223
|
||||||
|
#define K_AUX18 224
|
||||||
|
#define K_AUX19 225
|
||||||
|
#define K_AUX20 226
|
||||||
|
#define K_AUX21 227
|
||||||
|
#define K_AUX22 228
|
||||||
|
#define K_AUX23 229
|
||||||
|
#define K_AUX24 230
|
||||||
|
#define K_AUX25 231
|
||||||
|
#define K_AUX26 232
|
||||||
|
#define K_AUX27 233
|
||||||
|
#define K_AUX28 234
|
||||||
|
#define K_AUX29 235
|
||||||
|
#define K_AUX30 236
|
||||||
|
#define K_AUX31 237
|
||||||
|
#define K_AUX32 238
|
||||||
|
|
||||||
|
// JACK: Intellimouse(c) Mouse Wheel Support
|
||||||
|
|
||||||
|
#define K_MWHEELUP 239
|
||||||
|
#define K_MWHEELDOWN 240
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {key_game, key_console, key_message, key_menu, key_menu_pause} keydest_t;
|
||||||
|
|
||||||
|
extern keydest_t key_dest;
|
||||||
|
extern char *keybindings[256];
|
||||||
|
extern char *dtbindings[256];
|
||||||
|
extern int key_repeats[256];
|
||||||
|
extern int key_count; // incremented every key event
|
||||||
|
extern int key_lastpress;
|
||||||
|
extern qboolean keydown[256];
|
||||||
|
void Key_Event (int key, qboolean down);
|
||||||
|
void Key_Init (void);
|
||||||
|
void Key_WriteBindings (FILE *f);
|
||||||
|
void Key_WriteDTBindings (FILE *f);
|
||||||
|
void Key_SetBinding (int keynum, char *binding);
|
||||||
|
void Key_ClearStates (void);
|
||||||
|
|
||||||
|
void History_Shutdown (void);
|
||||||
|
|
62
source/libpspmath/Makefile
Normal file
62
source/libpspmath/Makefile
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
TARGET_LIB = libpspmath.a
|
||||||
|
OBJS = \
|
||||||
|
printMatrixFloat.o \
|
||||||
|
vfpu_srand.o \
|
||||||
|
vfpu_randf.o \
|
||||||
|
vfpu_rand_8888.o \
|
||||||
|
vfpu_identity_matrix.o \
|
||||||
|
vfpu_translate_matrix.o \
|
||||||
|
vfpu_perspective_matrix.o \
|
||||||
|
vfpu_ortho_matrix.o \
|
||||||
|
vfpu_sinf.o \
|
||||||
|
vfpu_cosf.o \
|
||||||
|
vfpu_tanf.o \
|
||||||
|
vfpu_asinf.o \
|
||||||
|
vfpu_acosf.o \
|
||||||
|
vfpu_atanf.o \
|
||||||
|
vfpu_sinhf.o \
|
||||||
|
vfpu_coshf.o \
|
||||||
|
vfpu_tanhf.o \
|
||||||
|
vfpu_sincos.o \
|
||||||
|
vfpu_expf.o \
|
||||||
|
vfpu_logf.o \
|
||||||
|
vfpu_fabsf.o \
|
||||||
|
vfpu_sqrtf.o \
|
||||||
|
vfpu_powf.o \
|
||||||
|
vfpu_fmodf.o \
|
||||||
|
vfpu_fminf.o \
|
||||||
|
vfpu_fmaxf.o \
|
||||||
|
vfpu_ease_in_out.o \
|
||||||
|
vfpu_normalize_vector.o \
|
||||||
|
vfpu_zero_vector.o \
|
||||||
|
vfpu_scale_vector.o \
|
||||||
|
vfpu_add_vector.o \
|
||||||
|
vfpu_envmap_matrix.o \
|
||||||
|
vfpu_sphere_to_cartesian.o \
|
||||||
|
vfpu_quaternion_identity.o \
|
||||||
|
vfpu_quaternion_copy.o \
|
||||||
|
vfpu_quaternion_multiply.o \
|
||||||
|
vfpu_quaternion_normalize.o \
|
||||||
|
vfpu_quaternion_exp.o \
|
||||||
|
vfpu_quaternion_ln.o \
|
||||||
|
vfpu_quaternion_sample_linear.o \
|
||||||
|
vfpu_quaternion_from_euler.o \
|
||||||
|
vfpu_quaternion_to_matrix.o \
|
||||||
|
vfpu_quaternion_sample_hermite.o \
|
||||||
|
vfpu_quaternion_hermite_tangent.o
|
||||||
|
|
||||||
|
INCDIR =
|
||||||
|
CFLAGS = -O2 -G0 -Wall
|
||||||
|
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
ASFLAGS = $(CFLAGS)
|
||||||
|
|
||||||
|
LIBDIR =
|
||||||
|
LDFLAGS =
|
||||||
|
LIBS=
|
||||||
|
|
||||||
|
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||||
|
include $(PSPSDK)/lib/build.mak
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp $(TARGET_LIB) $(PSPSDK)/lib
|
||||||
|
cp pspmath.h $(PSPSDK)/include
|
5
source/libpspmath/README.txt
Normal file
5
source/libpspmath/README.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
this is a PSP VFPU accelerated math library required if the PSP_VFPU Dflag
|
||||||
|
is set. original library by mrmrice, made standalone by tufty
|
||||||
|
https://github.com/tufty/libpspmath
|
||||||
|
|
||||||
|
- motolegacy (2/3/2021)
|
BIN
source/libpspmath/libpspmath.a
Normal file
BIN
source/libpspmath/libpspmath.a
Normal file
Binary file not shown.
31
source/libpspmath/printMatrixFloat.c
Normal file
31
source/libpspmath/printMatrixFloat.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void printMatrixFloat(int matid) {
|
||||||
|
float m[16];
|
||||||
|
|
||||||
|
#define SV(N) \
|
||||||
|
asm("usv.q R"#N"00, 0 + %0\n" \
|
||||||
|
"usv.q R"#N"01, 16 + %0\n" \
|
||||||
|
"usv.q R"#N"02, 32 + %0\n" \
|
||||||
|
"usv.q R"#N"03, 48 + %0\n" \
|
||||||
|
: "=m"(m))
|
||||||
|
|
||||||
|
switch (matid) {
|
||||||
|
case 0: SV(0); break;
|
||||||
|
case 1: SV(1); break;
|
||||||
|
case 2: SV(2); break;
|
||||||
|
case 3: SV(3); break;
|
||||||
|
case 4: SV(4); break;
|
||||||
|
case 5: SV(5); break;
|
||||||
|
case 6: SV(6); break;
|
||||||
|
case 7: SV(7); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n\n");
|
||||||
|
printf(" C%d00 C%d10 C%d20 C%d30\n", matid, matid, matid, matid);
|
||||||
|
printf("R%d00: %0.6f %0.6f %0.6f %0.6f\n", matid, m[0], m[1], m[2], m[3]);
|
||||||
|
printf("R%d01: %0.6f %0.6f %0.6f %0.6f\n", matid, m[4], m[5], m[6], m[7]);
|
||||||
|
printf("R%d02: %0.6f %0.6f %0.6f %0.6f\n", matid, m[8], m[9], m[10], m[11]);
|
||||||
|
printf("R%d03: %0.6f %0.6f %0.6f %0.6f\n", matid, m[12], m[13], m[14], m[15]);
|
||||||
|
}
|
445
source/libpspmath/pspmath.h
Normal file
445
source/libpspmath/pspmath.h
Normal file
|
@ -0,0 +1,445 @@
|
||||||
|
/*
|
||||||
|
* PSP Software Development Kit - http://www.pspdev.org
|
||||||
|
* -----------------------------------------------------------------------
|
||||||
|
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 Steve Galatis
|
||||||
|
* Copyright (c) 2007 Christophe Avoinme
|
||||||
|
*
|
||||||
|
* General purpose math library using vfpu optimized instructions.
|
||||||
|
* Most of the routines here run at least 5 to 20 times faster than the equivalent
|
||||||
|
* routines in libm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _pspmath_h_
|
||||||
|
#define _pspmath_h_
|
||||||
|
|
||||||
|
#include <psptypes.h>
|
||||||
|
|
||||||
|
/** @defgroup VFPUMATH VFPU Math Library
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct quat {
|
||||||
|
float x, y, z, w;
|
||||||
|
} __attribute__((aligned(16))) ScePspQuatMatrix;
|
||||||
|
|
||||||
|
/** @addtogroup VFPUMATH */
|
||||||
|
/*@{*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print a formatted block of 16 vfpu registers
|
||||||
|
*
|
||||||
|
* @param blockid - register block id (0 to 7)
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void printVFPURegisters(int blockid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set vfpu random generator seed
|
||||||
|
*
|
||||||
|
* @param x - seed value
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_srand(unsigned int x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return random float value
|
||||||
|
*
|
||||||
|
* @param min - minimum value to return
|
||||||
|
* @param max - maximum value to return
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_randf(float min, float max);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return random color value in 8888 format
|
||||||
|
* This always sets the alpha channel value to 0xFF
|
||||||
|
*
|
||||||
|
* @param min - minimum value for each color channel (0..255)
|
||||||
|
* @param max - maximum value for each color channel (0..255)
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
unsigned int vfpu_rand_8888(int min, int max);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an identity matrix
|
||||||
|
*
|
||||||
|
* @param m - pointer to matrix to set
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_identity_matrix(ScePspFMatrix4 *m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a translation matrix
|
||||||
|
*
|
||||||
|
* @param m - pointer to matrix
|
||||||
|
* @param x - translation on x axis
|
||||||
|
* @param y - translation on y axis
|
||||||
|
* @param z - translation on z axis
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_translate_matrix(ScePspFMatrix4 *m, float x, float y, float z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a perspective projection matrix
|
||||||
|
*
|
||||||
|
* @param m - pointer to matrix
|
||||||
|
* @param fovy - vertical field of view
|
||||||
|
* @param aspect - aspect ratio of viewport
|
||||||
|
* @param near - near clipping plane
|
||||||
|
* @param far - far clipping plane
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_perspective_matrix(ScePspFMatrix4 *m, float fovy, float aspect, float near, float far);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an orthogonal projection matrix
|
||||||
|
*
|
||||||
|
* @param m - pointer to matrix
|
||||||
|
* @param left - coordinate for left edge of viewport
|
||||||
|
* @param right - coordinate for right edge of viewport
|
||||||
|
* @param bottom - coordinate for bottom edge of viewport
|
||||||
|
* @param top - coordinate for top edge of viewport
|
||||||
|
* @param near - near clipping plane
|
||||||
|
* @param far - far clipping plane
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_ortho_matrix(ScePspFMatrix4 *m, float left, float right, float bottom, float top, float near, float far);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate sine
|
||||||
|
*
|
||||||
|
* @param x - input in radians
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_sinf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate cosine
|
||||||
|
*
|
||||||
|
* @param x - input in radians
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_cosf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate tangent
|
||||||
|
*
|
||||||
|
* @param x - input in radians
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_tanf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate inverse sine (arcsin)
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_asinf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate inverse cosine (arccos)
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_acosf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate inverse tangent (arctan)
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_atanf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate inverse tangent, with proper quadrant fixup
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_atan2f(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate hyperbolic sine
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_sinhf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate hyperbolic cosine
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_coshf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate hyperbolic tangent
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_tanhf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate sine and cosine
|
||||||
|
*
|
||||||
|
* @param r - input in radians
|
||||||
|
* @param s - pointer to float for sin
|
||||||
|
* @param c - pointer to float for cos
|
||||||
|
**/
|
||||||
|
void vfpu_sincos(float r, float *s, float *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate exponent of x
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_expf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate logarithm of x
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_logf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate x raised to the power of y
|
||||||
|
*
|
||||||
|
* @param x - number to raise power of
|
||||||
|
* @param y - power to raise x by
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_powf(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate floating point remainder of x/y
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
* @param y - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_fmodf(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate absolute floating point of x
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_fabsf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate floating square root point of x
|
||||||
|
*
|
||||||
|
* @param x - input
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_sqrtf(float x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a smooth acceleration/deceleration curve based on the input time value
|
||||||
|
* returns 0 to 1
|
||||||
|
*
|
||||||
|
* @param t - input (0 to 1 float)
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
float vfpu_ease_in_out(float t);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a 3d vector, returning a unit vector of length = 1
|
||||||
|
*
|
||||||
|
* @param v - pointer to vector to normalize
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_normalize_vector(ScePspFVector4 *v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zero a 3d vector
|
||||||
|
*
|
||||||
|
* @param v - pointer to vector
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_zero_vector(ScePspFVector4 *v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale a 3d vector
|
||||||
|
*
|
||||||
|
* @param vout - pointer to result vector
|
||||||
|
* @param vin - pointer to vector to scale
|
||||||
|
* @param scale - float value to scale vector by
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_scale_vector(ScePspFVector4 *vout, ScePspFVector4 *vin, float scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add 2 3d vectors
|
||||||
|
*
|
||||||
|
* @param vout - pointer to result vector
|
||||||
|
* @param va - pointer to first vector to add
|
||||||
|
* @param vb - pointer to second vector to add
|
||||||
|
**/
|
||||||
|
void vfpu_add_vector(ScePspFVector4 *vout, ScePspFVector4 *va, ScePspFVector4 *vb);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate rotation matrix for environment map.
|
||||||
|
*
|
||||||
|
* @param envmat - pointer to array of 2 vectors to store envmap matrix
|
||||||
|
* @param r - angle to rotate in radians
|
||||||
|
**/
|
||||||
|
void vfpu_envmap_matrix(ScePspFVector4 *envmat, float r);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform 3d vector by 4x4 matrix
|
||||||
|
*
|
||||||
|
* @param m - pointer to transformation matrix
|
||||||
|
* @param vin - pointer to vector to transform
|
||||||
|
* @param vout - pointer to result vector
|
||||||
|
**/
|
||||||
|
void vfpu_transform_vector(ScePspFMatrix4 *m, ScePspFVector4 *vin, ScePspFVector4 *vout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert input sphere coordinates to cartesian coordinates
|
||||||
|
*
|
||||||
|
* @param az - azimuth angle (0 to PI*2)
|
||||||
|
* @param ze - zenith angle (0 to PI)
|
||||||
|
* @param rad - sphere radius
|
||||||
|
* @param x - pointer to float for x coordinate
|
||||||
|
* @param y - pointer to float for y coordinate
|
||||||
|
* @param z - pointer to float for z coordinate
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_sphere_to_cartesian(float az, float ze, float rad, float *x, float *y, float *z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an identity quaternion
|
||||||
|
*
|
||||||
|
* @param q - pointer to quaternion
|
||||||
|
*
|
||||||
|
* this will set the quaternion's components to 0,0,0,1
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_identity(ScePspQuatMatrix *q);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a quaternion
|
||||||
|
*
|
||||||
|
* @param dst - pointer to quaternion to copy to
|
||||||
|
* @param src - pointer to quaternion to copy from
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_copy(ScePspQuatMatrix *dst, ScePspQuatMatrix *src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a quaternion
|
||||||
|
*
|
||||||
|
* @param res - pointer to quaternion to normalize
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_normalize(ScePspQuatMatrix *res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiply 2 quaternions
|
||||||
|
*
|
||||||
|
* @param qout - pointer to result quaternion
|
||||||
|
* @param a - pointer to first quaternion to multiply
|
||||||
|
* @param b - pointer to second quaternion to multiply
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_multiply(ScePspQuatMatrix *qout, ScePspQuatMatrix *a, ScePspQuatMatrix *b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a quaternion from euler angles
|
||||||
|
*
|
||||||
|
* @param qout - pointer to output quaternion
|
||||||
|
* @param rx - rotation on x axis, in degrees
|
||||||
|
* @param ry - rotation on y axis, in degrees
|
||||||
|
* @param rz - rotation on z axis, in degrees
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_from_euler(ScePspQuatMatrix *qout, float rx, float ry, float rz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate exponent of a quaternion
|
||||||
|
*
|
||||||
|
* @param qout - pointer to output quaternion
|
||||||
|
* @param qin - pointer to input quaternion
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_exp(ScePspQuatMatrix *qout, ScePspQuatMatrix *qin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate logarithm of a quaternion
|
||||||
|
*
|
||||||
|
* @param qout - pointer to output quaternion
|
||||||
|
* @param qin - pointer to input quaternion
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_ln(ScePspQuatMatrix *qout, ScePspQuatMatrix *qin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a sample from a linear interpolation of 2 quaternions
|
||||||
|
*
|
||||||
|
* @param qout - pointer to output quaternion
|
||||||
|
* @param a - pointer to starting quaternion
|
||||||
|
* @param b - pointer to ending quaternion
|
||||||
|
* @param t - time value to sample, from 0 to 1
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_sample_linear(ScePspQuatMatrix *qout, ScePspQuatMatrix *a, ScePspQuatMatrix *b, float t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a sample from a hermite spline interpolation
|
||||||
|
*
|
||||||
|
* @param qout - pointer to output quaternion
|
||||||
|
* @param a - pointer to start quaternion
|
||||||
|
* @param b - pointer to end quaternion
|
||||||
|
* @param at - pointer to tangent point for quaternion a
|
||||||
|
* @param bt - pointer to tangent point for quaternion b
|
||||||
|
* @param t - time value to sample, from 0 to 1
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_sample_hermite(ScePspQuatMatrix *qout, ScePspQuatMatrix *a, ScePspQuatMatrix *b, ScePspQuatMatrix *at, ScePspQuatMatrix *bt, float t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a tangent point for hermite spline interpolation
|
||||||
|
*
|
||||||
|
* @param qout - pointer to output quaternion
|
||||||
|
* @param p1 - pointer to p-1 on spline curve for tangent
|
||||||
|
* @param p2 - pointer to p+1 on spline curve for tangent
|
||||||
|
* @param bias - value to scale difference between endpoints.
|
||||||
|
* for example, 0.5 results in a catmull-rom spline tangent
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
void vfpu_quaternion_hermite_tangent(ScePspQuatMatrix *qout, ScePspQuatMatrix *p1, ScePspQuatMatrix *p2, float bias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert quaternion to rotation matrix
|
||||||
|
*
|
||||||
|
* @param q - pointer to input quaternion
|
||||||
|
* @param m - pointer to output matrix
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void vfpu_quaternion_to_matrix(ScePspQuatMatrix *q, ScePspFMatrix4 *m);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
14
source/libpspmath/vfpu_acosf.c
Normal file
14
source/libpspmath/vfpu_acosf.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_acosf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_PI_2\n"
|
||||||
|
"vasin.s S000, S000\n"
|
||||||
|
"vocp.s S000, S000\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
10
source/libpspmath/vfpu_add_vector.c
Normal file
10
source/libpspmath/vfpu_add_vector.c
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_add_vector(ScePspFVector4 *vout, ScePspFVector4 *va, ScePspFVector4 *vb) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %1\n"
|
||||||
|
"lv.q C010, %2\n"
|
||||||
|
"vadd.t C020, C000, C010\n"
|
||||||
|
"sv.q C020, %0\n"
|
||||||
|
: "+m"(*vout): "m"(*va), "m"(*vb));
|
||||||
|
}
|
13
source/libpspmath/vfpu_asinf.c
Normal file
13
source/libpspmath/vfpu_asinf.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_asinf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_PI_2\n"
|
||||||
|
"vasin.s S000, S000\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
57
source/libpspmath/vfpu_atanf.c
Normal file
57
source/libpspmath/vfpu_atanf.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_atanf(float x) {
|
||||||
|
float result;
|
||||||
|
// result = asinf(x/sqrt(x*x+1))
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vmul.s S001, S000, S000\n"
|
||||||
|
"vadd.s S001, S001, S001[1]\n"
|
||||||
|
"vrsq.s S001, S001\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vasin.s S000, S000\n"
|
||||||
|
"vcst.s S001, VFPU_PI_2\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define PI 3.14159265358979f
|
||||||
|
#define PI_2 1.57079632679489f
|
||||||
|
|
||||||
|
inline static float fabsf(float x) {
|
||||||
|
float r;
|
||||||
|
__asm__ volatile( "abs.s %0, %1" : "=f"(r) :"f"(x):"memory");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* double a;
|
||||||
|
|
||||||
|
if (fabs(x) >= fabs(y)) {
|
||||||
|
a = atan(y/x) ;
|
||||||
|
if (x < 0.0) {
|
||||||
|
if (y >= 0.0) a += _pi ;
|
||||||
|
else a -= _pi ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a = -atan(x/y) ;
|
||||||
|
if (y < 0.0) a -= _halfpi ;
|
||||||
|
else a += _halfpi ;
|
||||||
|
}
|
||||||
|
return a ;*/
|
||||||
|
|
||||||
|
float vfpu_atan2f(float y, float x) {
|
||||||
|
float r;
|
||||||
|
|
||||||
|
if (fabsf(x) >= fabsf(y)) {
|
||||||
|
r = vfpu_atanf(y/x);
|
||||||
|
if (x < 0.0f) r += (y>=0.0f ? PI : -PI);
|
||||||
|
} else {
|
||||||
|
r = -vfpu_atanf(x/y);
|
||||||
|
r += (y < 0.0f ? -PI_2 : PI_2);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
13
source/libpspmath/vfpu_cosf.c
Normal file
13
source/libpspmath/vfpu_cosf.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_cosf(float rad) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_2_PI\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vcos.s S000, S000\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(rad));
|
||||||
|
return result;
|
||||||
|
}
|
18
source/libpspmath/vfpu_coshf.c
Normal file
18
source/libpspmath/vfpu_coshf.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_coshf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_LN2\n"
|
||||||
|
"vrcp.s S001, S001\n"
|
||||||
|
"vmov.s S002, S000[|x|]\n"
|
||||||
|
"vmul.s S002, S001, S002\n"
|
||||||
|
"vexp2.s S002, S002\n"
|
||||||
|
"vrcp.s S003, S002\n"
|
||||||
|
"vadd.s S002, S002, S003\n"
|
||||||
|
"vmul.s S002, S002, S002[1/2]\n"
|
||||||
|
"mfv %0, S002\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
19
source/libpspmath/vfpu_ease_in_out.c
Normal file
19
source/libpspmath/vfpu_ease_in_out.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
// simple ease in/out function
|
||||||
|
// input will be clamped to range of 0 < t < 1
|
||||||
|
|
||||||
|
float vfpu_ease_in_out(float t) {
|
||||||
|
float r;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vmov.q C000[0:1,,,], C000[x, 2, 1, 1/2]\n" // C000 = [0<t<1, 2, 1, 1/2]
|
||||||
|
"vmul.s S000, S000, S001\n" // raise S000 to 0..2 range
|
||||||
|
"vsub.s S000, S000, S002\n" // S000 now in -1 to 1 range
|
||||||
|
"vsin.s S000, S000\n" // S000 = sin(S000)
|
||||||
|
"vmul.s S000, S000, S003\n" // S000 = sin(t)/2
|
||||||
|
"vadd.s S000, S000, S003\n" // S000 = 0.5 + sin(t)/2
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(r) : "r"(t));
|
||||||
|
return r;
|
||||||
|
}
|
13
source/libpspmath/vfpu_envmap_matrix.c
Normal file
13
source/libpspmath/vfpu_envmap_matrix.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_envmap_matrix(ScePspFVector4 *envmat, float r) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_2_PI\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vrot.q C010, S000, [c, s, 0, 0]\n"
|
||||||
|
"vrot.q C020, S000, [-s, c, 0, 0]\n"
|
||||||
|
"sv.q C010, 0 + %0\n"
|
||||||
|
"sv.q C020, 16 + %0\n"
|
||||||
|
:"=m"(*envmat):"r"(r));
|
||||||
|
}
|
14
source/libpspmath/vfpu_expf.c
Normal file
14
source/libpspmath/vfpu_expf.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_expf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_LN2\n"
|
||||||
|
"vrcp.s S001, S001\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vexp2.s S000, S000\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
11
source/libpspmath/vfpu_fabsf.c
Normal file
11
source/libpspmath/vfpu_fabsf.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_fabsf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vmov.s S000, S000[|x|]\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
12
source/libpspmath/vfpu_fmaxf.c
Normal file
12
source/libpspmath/vfpu_fmaxf.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_fmaxf(float x, float y) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"mtv %2, S001\n"
|
||||||
|
"vmax.s S002, S000, S001\n"
|
||||||
|
"mfv %0, S002\n"
|
||||||
|
: "=r"(result) : "r"(x), "r"(y));
|
||||||
|
return result;
|
||||||
|
}
|
12
source/libpspmath/vfpu_fminf.c
Normal file
12
source/libpspmath/vfpu_fminf.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_fminf(float x, float y) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"mtv %2, S001\n"
|
||||||
|
"vmin.s S002, S000, S001\n"
|
||||||
|
"mfv %0, S002\n"
|
||||||
|
: "=r"(result) : "r"(x), "r"(y));
|
||||||
|
return result;
|
||||||
|
}
|
18
source/libpspmath/vfpu_fmodf.c
Normal file
18
source/libpspmath/vfpu_fmodf.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_fmodf(float x, float y) {
|
||||||
|
float result;
|
||||||
|
// return x-y*((int)(x/y));
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %2, S001\n"
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vrcp.s S002, S001\n"
|
||||||
|
"vmul.s S003, S000, S002\n"
|
||||||
|
"vf2iz.s S002, S003, 0\n"
|
||||||
|
"vi2f.s S003, S002, 0\n"
|
||||||
|
"vmul.s S003, S003, S001\n"
|
||||||
|
"vsub.s S000, S000, S003\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x), "r"(y));
|
||||||
|
return result;
|
||||||
|
}
|
11
source/libpspmath/vfpu_identity_matrix.c
Normal file
11
source/libpspmath/vfpu_identity_matrix.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_identity_matrix(ScePspFMatrix4 *m) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"vmidt.q M000\n"
|
||||||
|
"sv.q C000, 0 + %0\n"
|
||||||
|
"sv.q C010, 16 + %0\n"
|
||||||
|
"sv.q C020, 32 + %0\n"
|
||||||
|
"sv.q C030, 48 + %0\n"
|
||||||
|
:"=m"(*m));
|
||||||
|
}
|
14
source/libpspmath/vfpu_logf.c
Normal file
14
source/libpspmath/vfpu_logf.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_logf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_LOG2E\n"
|
||||||
|
"vrcp.s S001, S001\n"
|
||||||
|
"vlog2.s S000, S000\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
11
source/libpspmath/vfpu_normalize_vector.c
Normal file
11
source/libpspmath/vfpu_normalize_vector.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_normalize_vector(ScePspFVector4 *v) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %0\n"
|
||||||
|
"vdot.t S010, C000, C000\n"
|
||||||
|
"vrsq.s S010, S010\n"
|
||||||
|
"vscl.t C000, C000, S010\n"
|
||||||
|
"sv.q C000, %0\n"
|
||||||
|
: "+m"(*v));
|
||||||
|
}
|
38
source/libpspmath/vfpu_ortho_matrix.c
Normal file
38
source/libpspmath/vfpu_ortho_matrix.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_ortho_matrix(ScePspFMatrix4 *m, float left, float right, float bottom, float top, float near, float far) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"vmidt.q M100\n" // set M100 to identity
|
||||||
|
"mtv %2, S000\n" // C000 = [right, ?, ?, ]
|
||||||
|
"mtv %4, S001\n" // C000 = [right, top, ?, ]
|
||||||
|
"mtv %6, S002\n" // C000 = [right, top, far ]
|
||||||
|
"mtv %1, S010\n" // C010 = [left, ?, ?, ]
|
||||||
|
"mtv %3, S011\n" // C010 = [left, bottom, ?, ]
|
||||||
|
"mtv %5, S012\n" // C010 = [left, bottom, near]
|
||||||
|
"vsub.t C020, C000, C010\n" // C020 = [ dx, dy, dz]
|
||||||
|
"vrcp.t C020, C020\n" // C020 = [1/dx, 1/dy, 1/dz]
|
||||||
|
"vmul.s S100, S100[2], S020\n" // S100 = m->x.x = 2.0 / dx
|
||||||
|
"vmul.s S111, S111[2], S021\n" // S110 = m->y.y = 2.0 / dy
|
||||||
|
"vmul.s S122, S122[2], S022[-x]\n" // S122 = m->z.z = -2.0 / dz
|
||||||
|
"vsub.t C130, C000[-x,-y,-z], C010\n" // C130 = m->w[x, y, z] = [-(right+left), -(top+bottom), -(far+near)]
|
||||||
|
// we do vsub here since -(a+b) => (-1*a) + (-1*b) => -a - b
|
||||||
|
"vmul.t C130, C130, C020\n" // C130 = [-(right+left)/dx, -(top+bottom)/dy, -(far+near)/dz]
|
||||||
|
"sv.q C100, 0 + %0\n"
|
||||||
|
"sv.q C110, 16 + %0\n"
|
||||||
|
"sv.q C120, 32 + %0\n"
|
||||||
|
"sv.q C130, 48 + %0\n"
|
||||||
|
:"=m"(*m) : "r"(left), "r"(right), "r"(bottom), "r"(top), "r"(near), "r"(far));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vfpu_transform_vector(ScePspFMatrix4 *m, ScePspFVector4 *vin, ScePspFVector4 *vout) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, 0 + %1\n"
|
||||||
|
"lv.q C010, 16 + %1\n"
|
||||||
|
"lv.q C020, 32 + %1\n"
|
||||||
|
"lv.q C030, 48 + %1\n"
|
||||||
|
"lv.q C100, %2\n"
|
||||||
|
"vtfm4.q C110, M000, C100\n"
|
||||||
|
"sv.q C110, %0\n"
|
||||||
|
:"+m"(*vout): "m"(*m), "m"(*vin));
|
||||||
|
}
|
31
source/libpspmath/vfpu_perspective_matrix.c
Normal file
31
source/libpspmath/vfpu_perspective_matrix.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_perspective_matrix(ScePspFMatrix4 *m, float fovy, float aspect, float near, float far) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"vmzero.q M100\n" // set M100 to all zeros
|
||||||
|
"mtv %1, S000\n" // S000 = fovy
|
||||||
|
"viim.s S001, 90\n" // S002 = 90.0f
|
||||||
|
"vrcp.s S001, S001\n" // S002 = 1/90
|
||||||
|
"vmul.s S000, S000, S000[1/2]\n" // S000 = fovy * 0.5 = fovy/2
|
||||||
|
"vmul.s S000, S000, S001\n" // S000 = (fovy/2)/90
|
||||||
|
"vrot.p C002, S000, [c, s]\n" // S002 = cos(angle), S003 = sin(angle)
|
||||||
|
"vdiv.s S100, S002, S003\n" // S100 = m->x.x = cotangent = cos(angle)/sin(angle)
|
||||||
|
"mtv %3, S001\n" // S001 = near
|
||||||
|
"mtv %4, S002\n" // S002 = far
|
||||||
|
"vsub.s S003, S001, S002\n" // S003 = deltaz = near-far
|
||||||
|
"vrcp.s S003, S003\n" // S003 = 1/deltaz
|
||||||
|
"mtv %2, S000\n" // S000 = aspect
|
||||||
|
"vmov.s S111, S100\n" // S111 = m->y.y = cotangent
|
||||||
|
"vdiv.s S100, S100, S000\n" // S100 = m->x.x = cotangent / aspect
|
||||||
|
"vadd.s S122, S001, S002\n" // S122 = m->z.z = far + near
|
||||||
|
"vmul.s S122, S122, S003\n" // S122 = m->z.z = (far+near)/deltaz
|
||||||
|
"vmul.s S132, S001, S002\n" // S132 = m->w.z = far * near
|
||||||
|
"vmul.s S132, S132, S132[2]\n" // S132 = m->w.z = 2 * (far*near)
|
||||||
|
"vmul.s S132, S132, S003\n" // S132 = m->w.z = 2 * (far*near) / deltaz
|
||||||
|
"vsub.s S123, S123, S123[1]\n" // S123 = m->z.w = -1.0
|
||||||
|
"sv.q C100, 0 + %0\n"
|
||||||
|
"sv.q C110, 16 + %0\n"
|
||||||
|
"sv.q C120, 32 + %0\n"
|
||||||
|
"sv.q C130, 48 + %0\n"
|
||||||
|
:"=m"(*m): "r"(fovy),"r"(aspect),"r"(near),"r"(far));
|
||||||
|
}
|
15
source/libpspmath/vfpu_powf.c
Normal file
15
source/libpspmath/vfpu_powf.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_powf(float x, float y) {
|
||||||
|
float result;
|
||||||
|
// result = exp2f(y * log2f(x));
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"mtv %2, S001\n"
|
||||||
|
"vlog2.s S001, S001\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vexp2.s S000, S000\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x), "r"(y));
|
||||||
|
return result;
|
||||||
|
}
|
8
source/libpspmath/vfpu_quaternion_copy.c
Normal file
8
source/libpspmath/vfpu_quaternion_copy.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_copy(ScePspQuatMatrix *dst, ScePspQuatMatrix *src) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %1\n"
|
||||||
|
"sv.q C000, %0\n"
|
||||||
|
:"+m"(*dst) : "m"(*src));
|
||||||
|
}
|
24
source/libpspmath/vfpu_quaternion_exp.c
Normal file
24
source/libpspmath/vfpu_quaternion_exp.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_exp(ScePspQuatMatrix *qout, ScePspQuatMatrix *qin) {
|
||||||
|
//float r = sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
|
||||||
|
//float et = exp(a[3]);
|
||||||
|
//float s = r>=0.00001f? et*sin(r)/r: 0.f;
|
||||||
|
//return quat(s*a[0],s*a[1],s*a[2],et*cos(r));
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, 0 + %1\n" // C000 = [x, y, z, w]
|
||||||
|
"vdot.t S010, C000, C000\n" // S010 = x^2 + y^2 + z^2
|
||||||
|
"vsqrt.s S010, S010\n" // S010 = r = sqrt(x^2 + y^2 + z^2)
|
||||||
|
"vcst.s S011, VFPU_LN2\n" // S011 = ln(2)
|
||||||
|
"vrcp.s S011, S011\n" // S011 = 1/ln(2)
|
||||||
|
"vmul.s S011, S011, S003\n" // S011 = w*(1/ln(2))
|
||||||
|
"vexp2.s S011, S011\n" // S011 = et = exp(w)
|
||||||
|
"vcst.s S012, VFPU_2_PI\n" // S012 = 2/PI
|
||||||
|
"vmul.s S012, S012, S010\n" // S012 = r * 2/PI
|
||||||
|
"vrot.p R003, S012, [c,s]\n" // S003 = cos(r), S013 = sin(r)
|
||||||
|
"vdiv.s S013, S013, S010\n" // S013 = sin(r)/r
|
||||||
|
"vscl.p R003, R003, S011\n" // S003 = et * cos(r), S013 = et * sin(r)/r
|
||||||
|
"vscl.t C000, C000, S013\n" // C000 = [s*x, s*y, s*z, et*cos(r)]
|
||||||
|
"sv.q C000, 0 + %0\n"
|
||||||
|
: "=m"(*qout) : "m"(*qin));
|
||||||
|
}
|
34
source/libpspmath/vfpu_quaternion_from_euler.c
Normal file
34
source/libpspmath/vfpu_quaternion_from_euler.c
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
#define PI 3.14159265358979323846f
|
||||||
|
const float piover180 = PI/180.0f;
|
||||||
|
|
||||||
|
void vfpu_quaternion_from_euler(ScePspQuatMatrix *res, float x, float y, float z) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n\t" // S000 = x
|
||||||
|
"mtv %2, S001\n\t" // S001 = y
|
||||||
|
"mtv %3, S002\n\t" // S002 = z
|
||||||
|
"lv.s S010, 0(%4)\n"
|
||||||
|
"vscl.t C000, C000, S010\n\t" // x *= pi/180, y *= pi/180, z *= pi/180
|
||||||
|
|
||||||
|
"vfim.s S010, 0.5\n\t" // S010 = 0.5
|
||||||
|
"vscl.t C000, C000, S010\n\t" // x *= 0.5, y *= 0.5, z *= 0.5
|
||||||
|
"vcst.s S010, VFPU_2_PI\n\t" // load 2/PI into S010, S011 and S012
|
||||||
|
"vscl.t C000, C000, S010\n\t" // x *= 2/PI, y *= 2/pi, z *= pi/2
|
||||||
|
|
||||||
|
"vrot.p C010, S000, [s, c]\n\t" // S010 = sr, S011 = cr
|
||||||
|
"vrot.p C020, S001, [s, c]\n\t" // S020 = sp, S021 = cp
|
||||||
|
"vrot.p C030, S002, [s, c]\n\t" // S030 = sy, S031 = cy
|
||||||
|
|
||||||
|
// fear the madness of prefixes
|
||||||
|
"vmul.q R100, C010[x,y,y,x], C020[y,x,x,y]\n"
|
||||||
|
"vmul.q R100, R100, C030[y,x,y,x]\n"
|
||||||
|
"vmul.q R101, C010[y,x,y,x], C020[y,x,y,x]\n"
|
||||||
|
"vmul.q R101, R101, C030[x,y,y,x]\n"
|
||||||
|
"vadd.q C000, R100[x,z,0,0], R100[-y,w,0,0]\n"
|
||||||
|
"vadd.q C000, C000, R101[0,0,x,z]\n"
|
||||||
|
"vadd.q C000, C000, R101[0,0,-y,w]\n"
|
||||||
|
"usv.q C000, %0\n\t"
|
||||||
|
:"=m"(*res) : "r"(x), "r"(y), "r"(z), "r"(&piover180));
|
||||||
|
vfpu_quaternion_normalize(res);
|
||||||
|
}
|
21
source/libpspmath/vfpu_quaternion_hermite_tangent.c
Normal file
21
source/libpspmath/vfpu_quaternion_hermite_tangent.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_hermite_tangent(ScePspQuatMatrix *qout, ScePspQuatMatrix *p1, ScePspQuatMatrix *p2, float bias) {
|
||||||
|
__asm__ volatile (
|
||||||
|
// load p1 and p2
|
||||||
|
"lv.q C000, 0(%1)\n"
|
||||||
|
"lv.q C010, 0(%2)\n"
|
||||||
|
|
||||||
|
// load bias
|
||||||
|
"mtv %3, S100\n"
|
||||||
|
|
||||||
|
// C020 = C010 - C000
|
||||||
|
"vsub.q C020, C010, C000\n"
|
||||||
|
|
||||||
|
// scale C020 by bias
|
||||||
|
"vscl.q C020, C020, S100\n"
|
||||||
|
|
||||||
|
// store result
|
||||||
|
"sv.q C020, 0(%0)\n"
|
||||||
|
:"+r"(qout): "r"(p1), "r"(p2), "r"(bias));
|
||||||
|
}
|
8
source/libpspmath/vfpu_quaternion_identity.c
Normal file
8
source/libpspmath/vfpu_quaternion_identity.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_identity(ScePspQuatMatrix *q) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"vidt.q C030\n" // column is important here, we need the w component set to 1
|
||||||
|
"sv.q C030, %0\n"
|
||||||
|
: "+m"(*q));
|
||||||
|
}
|
26
source/libpspmath/vfpu_quaternion_ln.c
Normal file
26
source/libpspmath/vfpu_quaternion_ln.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_ln(ScePspQuatMatrix *qout, ScePspQuatMatrix *qin) {
|
||||||
|
//float r = sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
|
||||||
|
//float t = r>0.00001f? atan2(r,a[3])/r: 0.f;
|
||||||
|
//return quat(t*a[0],t*a[1],t*a[2],0.5*log(norm(a)));
|
||||||
|
float r;
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C010, 0 + %1\n"
|
||||||
|
"vdot.t S020, C010, C010\n" // r = x^2 + y^2 + z^2
|
||||||
|
"vsqrt.s S020, S020\n" // r = sqrt(x^2 + y^2 + z^2)
|
||||||
|
"mfv %0, S020\n"
|
||||||
|
:"=r"(r): "m"(*qin));
|
||||||
|
r = vfpu_atan2f(r, qin->w)/r;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S021\n" // t = atan2(r, w) / r
|
||||||
|
"vdot.q S022, C010, C010\n" // norm = x^2 + y^2 + z^2 + w^2
|
||||||
|
"vcst.s S023, VFPU_LOG2E\n"
|
||||||
|
"vrcp.s S023, S023\n"
|
||||||
|
"vlog2.s S013, S022\n"
|
||||||
|
"vmul.s S013, S013, S023\n"
|
||||||
|
"vmul.s S013, S013, S013[1/2]\n"
|
||||||
|
"vscl.t C010, C010, S021\n"
|
||||||
|
"sv.q C010, 0 + %0\n"
|
||||||
|
: "=m"(*qout) : "r"(r));
|
||||||
|
}
|
10
source/libpspmath/vfpu_quaternion_multiply.c
Normal file
10
source/libpspmath/vfpu_quaternion_multiply.c
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_multiply(ScePspQuatMatrix *qout, ScePspQuatMatrix *a, ScePspQuatMatrix *b) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %1\n" // load quaternion a
|
||||||
|
"lv.q C010, %2\n" // load quaternion b
|
||||||
|
"vqmul.q C020, C000, C010\n" // C000 = quat a * quat b (quaternion multiply)
|
||||||
|
"sv.q C020, %0\n" // store result
|
||||||
|
: "+m"(*qout) : "m"(*a), "m"(*b));
|
||||||
|
}
|
11
source/libpspmath/vfpu_quaternion_normalize.c
Normal file
11
source/libpspmath/vfpu_quaternion_normalize.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_normalize(ScePspQuatMatrix *res) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %0\n" // load quaternion into C000
|
||||||
|
"vdot.q S010, C000, C000\n" // S010 = x^2 + y^2 + z^2 + w^2
|
||||||
|
"vrsq.s S010, S010\n" // S020 = 1.0 / sqrt(S100)
|
||||||
|
"vscl.q C000, C000, S010\n" // C000 = C000 * S010 (normalized quaternion)
|
||||||
|
"sv.q C000, %0\n" // store into quaternion result
|
||||||
|
: "+m"(*res));
|
||||||
|
}
|
67
source/libpspmath/vfpu_quaternion_sample_hermite.c
Normal file
67
source/libpspmath/vfpu_quaternion_sample_hermite.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
// constants for the hermite curve functions
|
||||||
|
ScePspFMatrix4 hermite = {
|
||||||
|
{ 2, -3, 0, 1 },
|
||||||
|
{ -2, 3, 0, 0 },
|
||||||
|
{ 1, -2, 1, 0 },
|
||||||
|
{ 1, -1, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
void vfpu_quaternion_sample_hermite(ScePspQuatMatrix *qout, ScePspQuatMatrix *a, ScePspQuatMatrix *b, ScePspQuatMatrix *at, ScePspQuatMatrix *bt, float t) {
|
||||||
|
__asm__ volatile (
|
||||||
|
// load hermite transform matrix
|
||||||
|
"lv.q C000, 0(%6)\n"
|
||||||
|
"lv.q C010, 16(%6)\n"
|
||||||
|
"lv.q C020, 32(%6)\n"
|
||||||
|
"lv.q C030, 48(%6)\n"
|
||||||
|
|
||||||
|
// load a, b, at, bt
|
||||||
|
"lv.q C100, 0(%1)\n"
|
||||||
|
"lv.q C110, 0(%2)\n"
|
||||||
|
"lv.q C120, 0(%3)\n"
|
||||||
|
"lv.q C130, 0(%4)\n"
|
||||||
|
|
||||||
|
// C200 = [ t^3, t^2, t, 1]
|
||||||
|
"mtv %5, S202\n"
|
||||||
|
"vmul.s S201, S202, S202\n"
|
||||||
|
"vmul.s S200, S202, S201\n"
|
||||||
|
"vone.s S203\n"
|
||||||
|
|
||||||
|
// multiply M000 by C200
|
||||||
|
// C000 = [ 2*t^3, -3*t^2, 0, 1]
|
||||||
|
// C010 = [ -2*t^3, 3*t^2, 0, 0]
|
||||||
|
// C020 = [ t^3, -2*t^2, t, 0]
|
||||||
|
// C030 = [ t^3, -t^2, 0, 0]
|
||||||
|
|
||||||
|
"vmul.q C000, C000, C200\n"
|
||||||
|
"vmul.q C010, C010, C200\n"
|
||||||
|
"vmul.q C020, C020, C200\n"
|
||||||
|
"vmul.q C030, C030, C200\n"
|
||||||
|
|
||||||
|
// sum the terms
|
||||||
|
// S210 = 2*t^3 - 3*t^2 + 1
|
||||||
|
// S211 = -2*t^3 + 3*t^2
|
||||||
|
// S212 = t^3 - 2*t^2 + t
|
||||||
|
// S213 = t^3 - t^2
|
||||||
|
|
||||||
|
"vfad.q S210, C000\n"
|
||||||
|
"vfad.q S211, C010\n"
|
||||||
|
"vfad.q S212, C020\n"
|
||||||
|
"vfad.q S213, C030\n"
|
||||||
|
|
||||||
|
// scale the qaternions with terms
|
||||||
|
"vscl.q C100, C100, S210\n"
|
||||||
|
"vscl.q C110, C110, S211\n"
|
||||||
|
"vscl.q C120, C120, S212\n"
|
||||||
|
"vscl.q C130, C130, S213\n"
|
||||||
|
|
||||||
|
// sum the results
|
||||||
|
"vadd.q C100, C100, C110\n"
|
||||||
|
"vadd.q C100, C100, C120\n"
|
||||||
|
"vadd.q C100, C100, C130\n"
|
||||||
|
|
||||||
|
// and return results
|
||||||
|
"sv.q C100, 0(%0)\n"
|
||||||
|
:"+r"(qout): "r"(a), "r"(b), "r"(at), "r"(bt), "r"(t), "r"(&hermite));
|
||||||
|
}
|
14
source/libpspmath/vfpu_quaternion_sample_linear.c
Normal file
14
source/libpspmath/vfpu_quaternion_sample_linear.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_sample_linear(ScePspQuatMatrix *qout, ScePspQuatMatrix *a, ScePspQuatMatrix *b, float t) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, 0 + %1\n"
|
||||||
|
"lv.q C010, 0 + %2\n"
|
||||||
|
"mtv %3, S020\n"
|
||||||
|
"vocp.s S021, S020\n"
|
||||||
|
"vscl.q C000, C000, S021\n"
|
||||||
|
"vscl.q C010, C010, S020\n"
|
||||||
|
"vadd.q C000, C000, C010\n"
|
||||||
|
"sv.q C000, 0 + %0\n"
|
||||||
|
: "=m"(*qout) : "m"(*a), "m"(*b), "r"(t));
|
||||||
|
}
|
34
source/libpspmath/vfpu_quaternion_to_matrix.c
Normal file
34
source/libpspmath/vfpu_quaternion_to_matrix.c
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_quaternion_to_matrix(ScePspQuatMatrix *q, ScePspFMatrix4 *m) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %1\n" // C000 = [x, y, z, w ]
|
||||||
|
"vmul.q C010, C000, C000\n" // C010 = [x2, y2, z2, w2]
|
||||||
|
"vcrs.t C020, C000, C000\n" // C020 = [yz, xz, xy ]
|
||||||
|
"vmul.q C030, C000[x,y,z,1], C000[w,w,w,2]\n" // C030 = [wx, wy, wz ]
|
||||||
|
|
||||||
|
"vadd.q C100, C020[0,z,y,0], C030[0,z,-y,0]\n" // C100 = [0, xy+wz, xz-wy]
|
||||||
|
"vadd.s S100, S011, S012\n" // C100 = [y2+z2, xy+wz, xz-wy]
|
||||||
|
|
||||||
|
"vadd.q C110, C020[z,0,x,0], C030[-z,0,x,0]\n" // C110 = [xy-wz, 0, yz+wx]
|
||||||
|
"vadd.s S111, S010, S012\n" // C110 = [xy-wz, x2+z2, yz+wx]
|
||||||
|
|
||||||
|
"vadd.q C120, C020[y,x,0,0], C030[y,-x,0,0]\n" // C120 = [xz+wy, yz-wx, 0 ]
|
||||||
|
"vadd.s S122, S010, S011\n" // C120 = [xz+wy, yz-wx, x2+y2]
|
||||||
|
|
||||||
|
"vmscl.t M100, M100, S033\n" // C100 = [2*(y2+z2), 2*(xy+wz), 2*(xz-wy)]
|
||||||
|
// C110 = [2*(xy-wz), 2*(x2+z2), 2*(yz+wx)]
|
||||||
|
// C120 = [2*(xz+wy), 2*(yz-wx), 2*(x2+y2)]
|
||||||
|
|
||||||
|
"vocp.s S100, S100\n" // C100 = [1-2*(y2+z2), 2*(xy+wz), 2*(xz-wy) ]
|
||||||
|
"vocp.s S111, S111\n" // C110 = [2*(xy-wz), 1-2*(x2+z2), 2*(yz+wx) ]
|
||||||
|
"vocp.s S122, S122\n" // C120 = [2*(xz+wy), 2*(yz-wx), 1-2*(x2+y2)]
|
||||||
|
|
||||||
|
"vidt.q C130\n" // C130 = [0, 0, 0, 1]
|
||||||
|
|
||||||
|
"sv.q R100, 0 + %0\n"
|
||||||
|
"sv.q R101, 16 + %0\n"
|
||||||
|
"sv.q R102, 32 + %0\n"
|
||||||
|
"sv.q R103, 48 + %0\n"
|
||||||
|
: "=m"(*m) : "m"(*q));
|
||||||
|
}
|
24
source/libpspmath/vfpu_rand_8888.c
Normal file
24
source/libpspmath/vfpu_rand_8888.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
unsigned int vfpu_rand_8888(int min, int max) {
|
||||||
|
unsigned int result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S020\n"
|
||||||
|
"mtv %2, S021\n"
|
||||||
|
"vmov.t C000, C020[x, x, x]\n"
|
||||||
|
"vmov.t C010, C020[y, y, y]\n"
|
||||||
|
"vi2f.t C000, C000, 0\n"
|
||||||
|
"vi2f.t C010, C010, 0\n"
|
||||||
|
"vsub.t C010, C010, C000\n"
|
||||||
|
"vrndf1.t C020\n"
|
||||||
|
"vsub.t C020, C020, C020[1, 1, 1]\n"
|
||||||
|
"vmul.t C020, C020, C010\n"
|
||||||
|
"vadd.t C020, C020, C000\n"
|
||||||
|
"vf2iz.t C020, C020, 23\n"
|
||||||
|
"viim.s S023, 255\n"
|
||||||
|
"vf2iz.s S023, S023, 23\n"
|
||||||
|
"vi2uc.q S000, C020\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
:"=r"(result): "r"(min), "r"(max));
|
||||||
|
return result;
|
||||||
|
}
|
17
source/libpspmath/vfpu_randf.c
Normal file
17
source/libpspmath/vfpu_randf.c
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_randf(float min, float max) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"mtv %2, S001\n"
|
||||||
|
"vsub.s S001, S001, S000\n"
|
||||||
|
"vrndf1.s S002\n"
|
||||||
|
"vone.s S003\n"
|
||||||
|
"vsub.s S002, S002, S003\n"
|
||||||
|
"vmul.s S001, S002, S001\n"
|
||||||
|
"vadd.s S000, S000, S001\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(min), "r"(max));
|
||||||
|
return result;
|
||||||
|
}
|
10
source/libpspmath/vfpu_scale_vector.c
Normal file
10
source/libpspmath/vfpu_scale_vector.c
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_scale_vector(ScePspFVector4 *vout, ScePspFVector4 *vin, float scale) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"lv.q C000, %1\n"
|
||||||
|
"mtv %2, S010\n"
|
||||||
|
"vscl.t C000, C000, S010\n"
|
||||||
|
"sv.q C000, %0\n"
|
||||||
|
: "=m"(*vout) : "m"(*vin), "r"(scale));
|
||||||
|
}
|
12
source/libpspmath/vfpu_sincos.c
Normal file
12
source/libpspmath/vfpu_sincos.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_sincos(float r, float *s, float *c) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %2, S002\n"
|
||||||
|
"vcst.s S003, VFPU_2_PI\n"
|
||||||
|
"vmul.s S002, S002, S003\n"
|
||||||
|
"vrot.p C000, S002, [s, c]\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
"mfv %1, S001\n"
|
||||||
|
: "=r"(*s), "=r"(*c): "r"(r));
|
||||||
|
}
|
13
source/libpspmath/vfpu_sinf.c
Normal file
13
source/libpspmath/vfpu_sinf.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_sinf(float rad) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_2_PI\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vsin.s S000, S000\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(rad));
|
||||||
|
return result;
|
||||||
|
}
|
20
source/libpspmath/vfpu_sinhf.c
Normal file
20
source/libpspmath/vfpu_sinhf.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_sinhf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_LN2\n"
|
||||||
|
"vrcp.s S001, S001\n"
|
||||||
|
"vmov.s S002, S000[|x|]\n"
|
||||||
|
"vcmp.s NE, S000, S002\n"
|
||||||
|
"vmul.s S002, S001, S002\n"
|
||||||
|
"vexp2.s S002, S002\n"
|
||||||
|
"vrcp.s S003, S002\n"
|
||||||
|
"vsub.s S002, S002, S003\n"
|
||||||
|
"vmul.s S002, S002, S002[1/2]\n"
|
||||||
|
"vcmov.s S002, S002[-x], 0\n"
|
||||||
|
"mfv %0, S002\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
20
source/libpspmath/vfpu_sphere_to_cartesian.c
Normal file
20
source/libpspmath/vfpu_sphere_to_cartesian.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_sphere_to_cartesian(float az, float ze, float rad, float *x, float *y, float *z) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %3, S000\n"
|
||||||
|
"mtv %4, S001\n"
|
||||||
|
"mtv %5, S002\n"
|
||||||
|
"vcst.s S003, VFPU_2_PI\n" // C000 = [az, ze, rad, 2/pi]
|
||||||
|
"vscl.p C000, C000, S003\n" // C000 = [az*2/pi, ze*2/pi, rad, 2/pi]
|
||||||
|
"vrot.p C010, S000, [s, c]\n" // C010 = [sin(az), cos(az), ?, ?]
|
||||||
|
"vrot.p C012, S001, [s, c]\n" // C010 = [sin(az), cos(az), sin(ze), cos(ze)]
|
||||||
|
"vmul.q C020, C010[y, 1, x, 0], C010[z, w, z, 0]\n" // C020 = [0, cos(az)*sin(ez), cos(ze), sin(az)*sin(ze)]
|
||||||
|
"vscl.t C020, C020, S002\n" // C020 = [0, r*cos(az)*sin(ez), r*cos(ze), r*sin(az)*sin(ze)]
|
||||||
|
//"sv.q C020, 0 + %0\n"
|
||||||
|
"sv.s S020, %0\n"
|
||||||
|
"sv.s S021, %1\n"
|
||||||
|
"sv.s S022, %2\n"
|
||||||
|
:"+m"(*x), "+m"(*y), "+m"(*z)
|
||||||
|
:"r"(az), "r"(ze), "r"(rad));
|
||||||
|
}
|
11
source/libpspmath/vfpu_sqrtf.c
Normal file
11
source/libpspmath/vfpu_sqrtf.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_sqrtf(float x) {
|
||||||
|
float result;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vsqrt.s S000, S000\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
5
source/libpspmath/vfpu_srand.c
Normal file
5
source/libpspmath/vfpu_srand.c
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_srand(unsigned int x) {
|
||||||
|
__asm__ volatile ( "mtv %0, S000\n vrnds.s S000" : "=r"(x));
|
||||||
|
}
|
15
source/libpspmath/vfpu_tanf.c
Normal file
15
source/libpspmath/vfpu_tanf.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_tanf(float x) {
|
||||||
|
float result;
|
||||||
|
// result = sin(x)/cos(x);
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %1, S000\n"
|
||||||
|
"vcst.s S001, VFPU_2_PI\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vrot.p C002, S000, [s, c]\n"
|
||||||
|
"vdiv.s S000, S002, S003\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result) : "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
20
source/libpspmath/vfpu_tanhf.c
Normal file
20
source/libpspmath/vfpu_tanhf.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
float vfpu_tanhf(float x) {
|
||||||
|
float result;
|
||||||
|
//y = exp(x+x);
|
||||||
|
//return (y-1)/(y+1);
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %0, S000\n"
|
||||||
|
"vadd.s S000, S000, S000\n"
|
||||||
|
"vcst.s S001, VFPU_LN2\n"
|
||||||
|
"vrcp.s S001, S001\n"
|
||||||
|
"vmul.s S000, S000, S001\n"
|
||||||
|
"vexp2.s S000, S000\n"
|
||||||
|
"vone.s S001\n"
|
||||||
|
"vbfy1.p C002, C000\n"
|
||||||
|
"vdiv.s S000, S003, S002\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
: "=r"(result): "r"(x));
|
||||||
|
return result;
|
||||||
|
}
|
19
source/libpspmath/vfpu_translate_matrix.c
Normal file
19
source/libpspmath/vfpu_translate_matrix.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_translate_matrix(ScePspFMatrix4 *m, float x, float y, float z)
|
||||||
|
{
|
||||||
|
__asm__ volatile (
|
||||||
|
"vmidt.q M000\n"
|
||||||
|
"mtv %1, S030\n"
|
||||||
|
"mtv %2, S031\n"
|
||||||
|
"mtv %3, S032\n"
|
||||||
|
//"vmidt.q M100\n"
|
||||||
|
//"lv.q C200, %1\n"
|
||||||
|
//"vmov.t C130, C200\n"
|
||||||
|
//"vmmul.q M200, M100, M000\n"
|
||||||
|
"sv.q C000, 0 + %0\n"
|
||||||
|
"sv.q C010, 16 + %0\n"
|
||||||
|
"sv.q C020, 32 + %0\n"
|
||||||
|
"sv.q C030, 48 + %0\n"
|
||||||
|
: "=m"(*m) : "r"(x), "r"(y), "r"(z));
|
||||||
|
}
|
8
source/libpspmath/vfpu_zero_vector.c
Normal file
8
source/libpspmath/vfpu_zero_vector.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "pspmath.h"
|
||||||
|
|
||||||
|
void vfpu_zero_vector(ScePspFVector4 *v) {
|
||||||
|
__asm__ volatile (
|
||||||
|
"vzero.t C000\n"
|
||||||
|
"sv.q C000, %0\n"
|
||||||
|
: "+m"(*v));
|
||||||
|
}
|
953
source/mathlib.c
Normal file
953
source/mathlib.c
Normal file
|
@ -0,0 +1,953 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// mathlib.c -- math primitives
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
#include <pspmath.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Sys_Error (char *error, ...);
|
||||||
|
|
||||||
|
vec3_t vec3_origin = {0,0,0};
|
||||||
|
int nanmask = 255<<23;
|
||||||
|
|
||||||
|
int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3;
|
||||||
|
float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
|
||||||
|
vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
float rsqrt( float number )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
float d;
|
||||||
|
__asm__ ( //from official pspsdk by sony
|
||||||
|
".set push\n" // save assember option
|
||||||
|
".set noreorder\n" // suppress reordering
|
||||||
|
"lv.s s000, %1\n" // s000 = s
|
||||||
|
"vrsq.s s000, s000\n" // s000 = 1 / sqrt(s000)
|
||||||
|
"sv.s s000, %0\n" // d = s000
|
||||||
|
".set pop\n" // restore assember option
|
||||||
|
: "=m"(d)
|
||||||
|
: "m"(number)
|
||||||
|
);
|
||||||
|
return d;
|
||||||
|
#else
|
||||||
|
int i;
|
||||||
|
float x, y;
|
||||||
|
|
||||||
|
if( number == 0.0f )
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
x = number * 0.5f;
|
||||||
|
i = *(int *)&number; // evil floating point bit level hacking
|
||||||
|
i = 0x5f3759df - (i >> 1); // what the fuck?
|
||||||
|
y = *(float *)&i;
|
||||||
|
y = y * (1.5f - (x * y * y)); // first iteration
|
||||||
|
|
||||||
|
return y;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
SinCos
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void SinCos( float radians, float *sine, float *cosine )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
vfpu_sincos(radians,sine,cosine);
|
||||||
|
#else
|
||||||
|
__asm__ volatile (
|
||||||
|
"mtv %2, S002\n"
|
||||||
|
"vcst.s S003, VFPU_2_PI\n"
|
||||||
|
"vmul.s S002, S002, S003\n"
|
||||||
|
"vrot.p C000, S002, [s, c]\n"
|
||||||
|
"mfv %0, S000\n"
|
||||||
|
"mfv %1, S001\n"
|
||||||
|
: "=r"(*sine), "=r"(*cosine): "r"(radians));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
|
||||||
|
{
|
||||||
|
float d;
|
||||||
|
vec3_t n;
|
||||||
|
float inv_denom;
|
||||||
|
|
||||||
|
inv_denom = 1.0F / DotProduct( normal, normal );
|
||||||
|
|
||||||
|
d = DotProduct( normal, p ) * inv_denom;
|
||||||
|
|
||||||
|
n[0] = normal[0] * inv_denom;
|
||||||
|
n[1] = normal[1] * inv_denom;
|
||||||
|
n[2] = normal[2] * inv_denom;
|
||||||
|
|
||||||
|
dst[0] = p[0] - d * n[0];
|
||||||
|
dst[1] = p[1] - d * n[1];
|
||||||
|
dst[2] = p[2] - d * n[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** assumes "src" is normalized
|
||||||
|
*/
|
||||||
|
void PerpendicularVector( vec3_t dst, const vec3_t src )
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
int i;
|
||||||
|
float minelem = 1.0F;
|
||||||
|
vec3_t tempvec;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** find the smallest magnitude axially aligned vector
|
||||||
|
*/
|
||||||
|
for ( pos = 0, i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
if ( vfpu_fabsf( src[i] ) < minelem )
|
||||||
|
#else
|
||||||
|
if ( fabsf( src[i] ) < minelem )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
pos = i;
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
minelem = vfpu_fabsf( src[i] );
|
||||||
|
#else
|
||||||
|
minelem = fabsf( src[i] );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
|
||||||
|
tempvec[pos] = 1.0F;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** project the point onto the plane defined by src
|
||||||
|
*/
|
||||||
|
ProjectPointOnPlane( dst, tempvec, src );
|
||||||
|
|
||||||
|
/*
|
||||||
|
** normalize the result
|
||||||
|
*/
|
||||||
|
VectorNormalize( dst );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
|
||||||
|
{
|
||||||
|
float m[3][3];
|
||||||
|
float im[3][3];
|
||||||
|
float zrot[3][3];
|
||||||
|
float tmpmat[3][3];
|
||||||
|
float rot[3][3];
|
||||||
|
int i;
|
||||||
|
vec3_t vr, vup, vf;
|
||||||
|
|
||||||
|
vf[0] = dir[0];
|
||||||
|
vf[1] = dir[1];
|
||||||
|
vf[2] = dir[2];
|
||||||
|
|
||||||
|
PerpendicularVector( vr, dir );
|
||||||
|
CrossProduct( vr, vf, vup );
|
||||||
|
|
||||||
|
m[0][0] = vr[0];
|
||||||
|
m[1][0] = vr[1];
|
||||||
|
m[2][0] = vr[2];
|
||||||
|
|
||||||
|
m[0][1] = vup[0];
|
||||||
|
m[1][1] = vup[1];
|
||||||
|
m[2][1] = vup[2];
|
||||||
|
|
||||||
|
m[0][2] = vf[0];
|
||||||
|
m[1][2] = vf[1];
|
||||||
|
m[2][2] = vf[2];
|
||||||
|
|
||||||
|
memcpy( im, m, sizeof( im ) );
|
||||||
|
|
||||||
|
im[0][1] = m[1][0];
|
||||||
|
im[0][2] = m[2][0];
|
||||||
|
im[1][0] = m[0][1];
|
||||||
|
im[1][2] = m[2][1];
|
||||||
|
im[2][0] = m[0][2];
|
||||||
|
im[2][1] = m[1][2];
|
||||||
|
|
||||||
|
memset( zrot, 0, sizeof( zrot ) );
|
||||||
|
zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
|
||||||
|
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
zrot[0][0] = vfpu_cosf( DEG2RAD( degrees ) );
|
||||||
|
zrot[0][1] = vfpu_sinf( DEG2RAD( degrees ) );
|
||||||
|
zrot[1][0] = -vfpu_sinf( DEG2RAD( degrees ) );
|
||||||
|
zrot[1][1] = vfpu_cosf( DEG2RAD( degrees ) );
|
||||||
|
#else
|
||||||
|
zrot[0][0] = cosf( DEG2RAD( degrees ) );
|
||||||
|
zrot[0][1] = sinf( DEG2RAD( degrees ) );
|
||||||
|
zrot[1][0] = -sinf( DEG2RAD( degrees ) );
|
||||||
|
zrot[1][1] = cosf( DEG2RAD( degrees ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
R_ConcatRotations( m, zrot, tmpmat );
|
||||||
|
R_ConcatRotations( tmpmat, im, rot );
|
||||||
|
|
||||||
|
for ( i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
float anglemod(float a)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (a >= 0)
|
||||||
|
a -= 360*(int)(a/360);
|
||||||
|
else
|
||||||
|
a += 360*( 1 + (int)(-a/360) );
|
||||||
|
#endif
|
||||||
|
a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
BOPS_Error
|
||||||
|
|
||||||
|
Split out like this for ASM to call.
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void BOPS_Error (void)
|
||||||
|
{
|
||||||
|
Sys_Error ("BoxOnPlaneSide: Bad signbits");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
BoxOnPlaneSide
|
||||||
|
|
||||||
|
Returns 1, 2, or 1 + 2
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
// crow_bar's enhanced boxonplaneside
|
||||||
|
int BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, mplane_t *p)
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
int sides;
|
||||||
|
__asm__ (
|
||||||
|
".set push\n" // save assembler option
|
||||||
|
".set noreorder\n" // suppress reordering
|
||||||
|
"lv.s S000, 0 + %[normal]\n" // S000 = p->normal[0]
|
||||||
|
"lv.s S001, 4 + %[normal]\n" // S001 = p->normal[1]
|
||||||
|
"lv.s S002, 8 + %[normal]\n" // S002 = p->normal[2]
|
||||||
|
"vzero.p C030\n" // C030 = [0.0f, 0.0f]
|
||||||
|
"lv.s S032, %[dist]\n" // S032 = p->dist
|
||||||
|
"move $8, $0\n" // $8 = 0
|
||||||
|
"beq %[signbits], $8, 0f\n" // jump to 0
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 1f\n" // jump to 1
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 2f\n" // jump to 2
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 3f\n" // jump to 3
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 4f\n" // jump to 4
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 5f\n" // jump to 5
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 6f\n" // jump to 6
|
||||||
|
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
|
||||||
|
"beq %[signbits], $8, 7f\n" // jump to 7
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"0:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
|
||||||
|
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
|
||||||
|
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
|
||||||
|
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
|
||||||
|
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
|
||||||
|
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"1:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
|
||||||
|
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
|
||||||
|
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
|
||||||
|
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
|
||||||
|
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
|
||||||
|
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"2:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
|
||||||
|
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
|
||||||
|
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
|
||||||
|
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
|
||||||
|
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
|
||||||
|
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"3:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
|
||||||
|
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
|
||||||
|
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
|
||||||
|
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
|
||||||
|
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
|
||||||
|
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"4:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
|
||||||
|
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
|
||||||
|
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
|
||||||
|
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
|
||||||
|
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
|
||||||
|
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"5:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
|
||||||
|
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
|
||||||
|
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
|
||||||
|
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
|
||||||
|
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
|
||||||
|
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"6:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
|
||||||
|
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
|
||||||
|
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
|
||||||
|
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
|
||||||
|
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
|
||||||
|
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"j 8f\n" // jump to SetSides
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"7:\n"
|
||||||
|
/*
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
*/
|
||||||
|
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
|
||||||
|
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
|
||||||
|
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
|
||||||
|
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
|
||||||
|
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
|
||||||
|
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
|
||||||
|
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
|
||||||
|
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
|
||||||
|
"8:\n" // SetSides
|
||||||
|
/*
|
||||||
|
if( dist1 >= p->dist )
|
||||||
|
sides = 1;
|
||||||
|
if( dist2 < p->dist )
|
||||||
|
sides |= 2;
|
||||||
|
*/
|
||||||
|
"addiu %[sides], $0, 0\n" // sides = 0
|
||||||
|
"vcmp.s LT, S030, S032\n" // S030 < S032
|
||||||
|
"bvt 0, 9f\n" // if ( CC[0] == 1 ) jump to 9
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"addiu %[sides], %[sides], 1\n"// sides = 1
|
||||||
|
"9:\n"
|
||||||
|
"vcmp.s GE, S031, S032\n" // S031 >= S032
|
||||||
|
"bvt 0, 10f\n" // if ( CC[0] == 1 ) jump to 10
|
||||||
|
"nop\n" // ( delay slot )
|
||||||
|
"addiu %[sides], %[sides], 2\n"// sides = sides + 2
|
||||||
|
"10:\n"
|
||||||
|
".set pop\n" // restore assembler option
|
||||||
|
: [sides] "=r" ( sides )
|
||||||
|
: [normal] "m" (*(p->normal)),
|
||||||
|
[emaxs] "m" ( *emaxs ),
|
||||||
|
[emins] "m" ( *emins ),
|
||||||
|
[signbits] "r" ( p->signbits ),
|
||||||
|
[dist] "m" ( p->dist )
|
||||||
|
: "$8"
|
||||||
|
);
|
||||||
|
return sides;
|
||||||
|
#else
|
||||||
|
int sides = 0;
|
||||||
|
float dist1, dist2;
|
||||||
|
|
||||||
|
// general case
|
||||||
|
switch( p->signbits )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
|
||||||
|
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// shut up compiler
|
||||||
|
dist1 = dist2 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dist1 >= p->dist )
|
||||||
|
sides = 1;
|
||||||
|
if( dist2 < p->dist )
|
||||||
|
sides |= 2;
|
||||||
|
|
||||||
|
return sides;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vectoangles (vec3_t vec, vec3_t ang)
|
||||||
|
{
|
||||||
|
float forward, yaw, pitch;
|
||||||
|
|
||||||
|
if (!vec[1] && !vec[0])
|
||||||
|
{
|
||||||
|
yaw = 0;
|
||||||
|
pitch = (vec[2] > 0) ? 90 : 270;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
yaw = vec[0] ? (vfpu_atan2f(vec[1], vec[0]) * 180 / M_PI) : (vec[1] > 0) ? 90 : 270;
|
||||||
|
#else
|
||||||
|
yaw = vec[0] ? (atan2(vec[1], vec[0]) * 180 / M_PI) : (vec[1] > 0) ? 90 : 270;
|
||||||
|
#endif
|
||||||
|
if (yaw < 0)
|
||||||
|
yaw += 360;
|
||||||
|
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
forward = vfpu_sqrtf (vec[0] * vec[0] + vec[1] * vec[1]);
|
||||||
|
pitch = vfpu_atan2f (vec[2], forward) * 180 / M_PI;
|
||||||
|
#else
|
||||||
|
forward = sqrt (vec[0] * vec[0] + vec[1] * vec[1]);
|
||||||
|
pitch = atan2 (vec[2], forward) * 180 / M_PI;
|
||||||
|
#endif
|
||||||
|
if (pitch < 0)
|
||||||
|
pitch += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
ang[0] = pitch;
|
||||||
|
ang[1] = yaw;
|
||||||
|
ang[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
||||||
|
{
|
||||||
|
float angle;
|
||||||
|
float sr, sp, sy, cr, cp, cy;
|
||||||
|
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sy = vfpu_sinf(angle);
|
||||||
|
cy = vfpu_cosf(angle);
|
||||||
|
#else
|
||||||
|
sy = sinf(angle);
|
||||||
|
cy = cosf(angle);
|
||||||
|
#endif
|
||||||
|
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sp = vfpu_sinf(angle);
|
||||||
|
cp = vfpu_cosf(angle);
|
||||||
|
#else
|
||||||
|
sp = sinf(angle);
|
||||||
|
cp = cosf(angle);
|
||||||
|
#endif
|
||||||
|
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sr = vfpu_sinf(angle);
|
||||||
|
cr = vfpu_cosf(angle);
|
||||||
|
#else
|
||||||
|
sr = sinf(angle);
|
||||||
|
cr = cosf(angle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
forward[0] = cp*cy;
|
||||||
|
forward[1] = cp*sy;
|
||||||
|
forward[2] = -sp;
|
||||||
|
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
|
||||||
|
right[1] = (-1*sr*sp*sy+-1*cr*cy);
|
||||||
|
right[2] = -1*sr*cp;
|
||||||
|
up[0] = (cr*sp*cy+-sr*-sy);
|
||||||
|
up[1] = (cr*sp*sy+-sr*cy);
|
||||||
|
up[2] = cr*cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float VectorLength (vec3_t v)
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
return vfpu_sqrtf(DotProduct(v, v));
|
||||||
|
#else
|
||||||
|
return sqrtf(DotProduct(v, v));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int VectorCompare (vec3_t v1, vec3_t v2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
if (v1[i] != v2[i])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
|
||||||
|
{
|
||||||
|
vecc[0] = veca[0] + scale*vecb[0];
|
||||||
|
vecc[1] = veca[1] + scale*vecb[1];
|
||||||
|
vecc[2] = veca[2] + scale*vecb[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec_t _DotProduct (vec3_t v1, vec3_t v2)
|
||||||
|
{
|
||||||
|
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out)
|
||||||
|
{
|
||||||
|
out[0] = veca[0]-vecb[0];
|
||||||
|
out[1] = veca[1]-vecb[1];
|
||||||
|
out[2] = veca[2]-vecb[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out)
|
||||||
|
{
|
||||||
|
out[0] = veca[0]+vecb[0];
|
||||||
|
out[1] = veca[1]+vecb[1];
|
||||||
|
out[2] = veca[2]+vecb[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _VectorCopy (vec3_t in, vec3_t out)
|
||||||
|
{
|
||||||
|
out[0] = in[0];
|
||||||
|
out[1] = in[1];
|
||||||
|
out[2] = in[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
|
||||||
|
{
|
||||||
|
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||||
|
cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||||
|
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
vec_t Length(vec3_t v)
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
return vfpu_sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
#else
|
||||||
|
return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float VecLength2(vec3_t v1, vec3_t v2)
|
||||||
|
{
|
||||||
|
vec3_t k;
|
||||||
|
VectorSubtract(v1, v2, k);
|
||||||
|
return sqrt(k[0]*k[0] + k[1]*k[1] + k[2]*k[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
float VectorNormalize (vec3_t v)
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
float length = vfpu_sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
#else
|
||||||
|
float length = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
const float ilength = 1.0f / length;
|
||||||
|
v[0] *= ilength;
|
||||||
|
v[1] *= ilength;
|
||||||
|
v[2] *= ilength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VectorInverse (vec3_t v)
|
||||||
|
{
|
||||||
|
v[0] = -v[0];
|
||||||
|
v[1] = -v[1];
|
||||||
|
v[2] = -v[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void VectorScale (vec3_t in, vec_t scale, vec3_t out)
|
||||||
|
{
|
||||||
|
out[0] = in[0]*scale;
|
||||||
|
out[1] = in[1]*scale;
|
||||||
|
out[2] = in[2]*scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Q_log2(int val)
|
||||||
|
{
|
||||||
|
int answer=0;
|
||||||
|
while (val>>=1)
|
||||||
|
answer++;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
R_ConcatRotations
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3])
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
|
||||||
|
in1[0][2] * in2[2][0];
|
||||||
|
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
|
||||||
|
in1[0][2] * in2[2][1];
|
||||||
|
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
|
||||||
|
in1[0][2] * in2[2][2];
|
||||||
|
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
|
||||||
|
in1[1][2] * in2[2][0];
|
||||||
|
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
|
||||||
|
in1[1][2] * in2[2][1];
|
||||||
|
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
|
||||||
|
in1[1][2] * in2[2][2];
|
||||||
|
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
|
||||||
|
in1[2][2] * in2[2][0];
|
||||||
|
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
|
||||||
|
in1[2][2] * in2[2][1];
|
||||||
|
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
|
||||||
|
in1[2][2] * in2[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
R_ConcatTransforms
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4])
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
|
||||||
|
in1[0][2] * in2[2][0];
|
||||||
|
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
|
||||||
|
in1[0][2] * in2[2][1];
|
||||||
|
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
|
||||||
|
in1[0][2] * in2[2][2];
|
||||||
|
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] +
|
||||||
|
in1[0][2] * in2[2][3] + in1[0][3];
|
||||||
|
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
|
||||||
|
in1[1][2] * in2[2][0];
|
||||||
|
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
|
||||||
|
in1[1][2] * in2[2][1];
|
||||||
|
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
|
||||||
|
in1[1][2] * in2[2][2];
|
||||||
|
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] +
|
||||||
|
in1[1][2] * in2[2][3] + in1[1][3];
|
||||||
|
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
|
||||||
|
in1[2][2] * in2[2][0];
|
||||||
|
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
|
||||||
|
in1[2][2] * in2[2][1];
|
||||||
|
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
|
||||||
|
in1[2][2] * in2[2][2];
|
||||||
|
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
|
||||||
|
in1[2][2] * in2[2][3] + in1[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
FloorDivMod
|
||||||
|
|
||||||
|
Returns mathematically correct (floor-based) quotient and remainder for
|
||||||
|
numer and denom, both of which should contain no fractional part. The
|
||||||
|
quotient must fit in 32 bits.
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
|
||||||
|
void FloorDivMod (float numer, float denom, int *quotient,
|
||||||
|
int *rem)
|
||||||
|
{
|
||||||
|
int q, r;
|
||||||
|
float x;
|
||||||
|
|
||||||
|
if (denom <= 0.0)
|
||||||
|
Sys_Error ("FloorDivMod: bad denominator %d\n", denom);
|
||||||
|
|
||||||
|
if (numer >= 0.0)
|
||||||
|
{
|
||||||
|
|
||||||
|
x = floorf(numer / denom);
|
||||||
|
q = (int)x;
|
||||||
|
r = (int)floorf(numer - (x * denom));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// perform operations with positive values, and fix mod to make floor-based
|
||||||
|
//
|
||||||
|
x = floorf(-numer / denom);
|
||||||
|
q = -(int)x;
|
||||||
|
r = (int)floorf(-numer - (x * denom));
|
||||||
|
if (r != 0)
|
||||||
|
{
|
||||||
|
q--;
|
||||||
|
r = (int)denom - r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*quotient = q;
|
||||||
|
*rem = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
GreatestCommonDivisor
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
int GreatestCommonDivisor (int i1, int i2)
|
||||||
|
{
|
||||||
|
if (i1 > i2)
|
||||||
|
{
|
||||||
|
if (i2 == 0)
|
||||||
|
return (i1);
|
||||||
|
return GreatestCommonDivisor (i2, i1 % i2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i1 == 0)
|
||||||
|
return (i2);
|
||||||
|
return GreatestCommonDivisor (i1, i2 % i1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !id386
|
||||||
|
|
||||||
|
// TODO: move to nonintel.c
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
Invert24To16
|
||||||
|
|
||||||
|
Inverts an 8.24 value to a 16.16 value
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
|
||||||
|
fixed16_t Invert24To16(fixed16_t val)
|
||||||
|
{
|
||||||
|
if (val < 256)
|
||||||
|
return (0xFFFFFFFF);
|
||||||
|
|
||||||
|
return (fixed16_t)
|
||||||
|
(((float)0x10000 * (float)0x1000000 / (float)val) + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out)
|
||||||
|
{
|
||||||
|
out[0] = DotProduct(in1, in2[0]) + in2[0][3];
|
||||||
|
out[1] = DotProduct(in1, in2[1]) + in2[1][3];
|
||||||
|
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AngleQuaternion( const vec3_t angles, vec4_t quaternion )
|
||||||
|
{
|
||||||
|
float angle;
|
||||||
|
float sr, sp, sy, cr, cp, cy;
|
||||||
|
|
||||||
|
// FIXME: rescale the inputs to 1/2 angle
|
||||||
|
angle = angles[2] * 0.5;
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sy = vfpu_sinf(angle);
|
||||||
|
cy = vfpu_cosf(angle);
|
||||||
|
#else
|
||||||
|
sy = sin(angle);
|
||||||
|
cy = cos(angle);
|
||||||
|
#endif
|
||||||
|
angle = angles[1] * 0.5;
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sp = vfpu_sinf(angle);
|
||||||
|
cp = vfpu_cosf(angle);
|
||||||
|
#else
|
||||||
|
sp = sin(angle);
|
||||||
|
cp = cos(angle);
|
||||||
|
#endif
|
||||||
|
angle = angles[0] * 0.5;
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sr = vfpu_sinf(angle);
|
||||||
|
cr = vfpu_cosf(angle);
|
||||||
|
#else
|
||||||
|
sr = sin(angle);
|
||||||
|
cr = cos(angle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
quaternion[0] = sr*cp*cy-cr*sp*sy; // X
|
||||||
|
quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
|
||||||
|
quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
|
||||||
|
quaternion[3] = cr*cp*cy+sr*sp*sy; // W
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] )
|
||||||
|
{
|
||||||
|
|
||||||
|
matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2];
|
||||||
|
matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2];
|
||||||
|
matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1];
|
||||||
|
|
||||||
|
matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2];
|
||||||
|
matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2];
|
||||||
|
matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0];
|
||||||
|
|
||||||
|
matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1];
|
||||||
|
matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0];
|
||||||
|
matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float omega, cosom, sinom, sclp, sclq;
|
||||||
|
|
||||||
|
// decide if one of the quaternions is backwards
|
||||||
|
float a = 0;
|
||||||
|
float b = 0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
a += (p[i]-q[i])*(p[i]-q[i]);
|
||||||
|
b += (p[i]+q[i])*(p[i]+q[i]);
|
||||||
|
}
|
||||||
|
if (a > b) {
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
q[i] = -q[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
|
||||||
|
|
||||||
|
if ((1.0 + cosom) > 0.00000001) {
|
||||||
|
if ((1.0 - cosom) > 0.00000001) {
|
||||||
|
omega = acos( cosom );
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sinom = vfpu_sinf( omega );
|
||||||
|
sclp = vfpu_sinf( (1.0 - t)*omega) / sinom;
|
||||||
|
sclq = vfpu_sinf( t*omega ) / sinom;
|
||||||
|
#else
|
||||||
|
sinom = sin( omega );
|
||||||
|
sclp = sin( (1.0 - t)*omega) / sinom;
|
||||||
|
sclq = sin( t*omega ) / sinom;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sclp = 1.0 - t;
|
||||||
|
sclq = t;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
qt[i] = sclp * p[i] + sclq * q[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qt[0] = -p[1];
|
||||||
|
qt[1] = p[0];
|
||||||
|
qt[2] = -p[3];
|
||||||
|
qt[3] = p[2];
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
sclp = vfpu_sinf( (1.0 - t) * 0.5 * M_PI);
|
||||||
|
sclq = vfpu_sinf( t * 0.5 * M_PI);
|
||||||
|
#else
|
||||||
|
sclp = sin( (1.0 - t) * 0.5 * M_PI);
|
||||||
|
sclq = sin( t * 0.5 * M_PI);
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
qt[i] = sclp * p[i] + sclq * qt[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
201
source/mathlib.h
Normal file
201
source/mathlib.h
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// mathlib.h
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
#include <pspmath.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef float vec_t;
|
||||||
|
typedef vec_t vec2_t[2];
|
||||||
|
typedef vec_t vec3_t[3];
|
||||||
|
typedef vec_t vec4_t[4];
|
||||||
|
typedef vec_t vec5_t[5];
|
||||||
|
|
||||||
|
typedef byte byte_vec4_t[4];
|
||||||
|
|
||||||
|
typedef int fixed4_t;
|
||||||
|
typedef int fixed8_t;
|
||||||
|
typedef int fixed16_t;
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mplane_s;
|
||||||
|
|
||||||
|
extern vec3_t vec3_origin;
|
||||||
|
extern int nanmask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define M_PI_DIV_180 (M_PI / 180.0) //johnfitz
|
||||||
|
//#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
|
||||||
|
#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz
|
||||||
|
|
||||||
|
//#else
|
||||||
|
*/
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI = GU_PI // matches value in gcc v2 math.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define M_PI_DIV_180 (M_PI / 180.0) //johnfitz
|
||||||
|
//#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
|
||||||
|
#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#define CLAMP(min, x, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x)) //johnfitz
|
||||||
|
|
||||||
|
#define lhrandom(MIN,MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN))
|
||||||
|
|
||||||
|
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
|
||||||
|
|
||||||
|
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
|
||||||
|
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
||||||
|
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
|
||||||
|
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
|
||||||
|
#define VectorClear(a) ((a)[0] = (a)[1] = (a)[2] = 0)
|
||||||
|
#define VectorNegate(a, b) ((b)[0] = -(a)[0], (b)[1] = -(a)[1], (b)[2] = -(a)[2])
|
||||||
|
#define VectorSet(v, x, y, z) ((v)[0] = (x), (v)[1] = (y), (v)[2] = (z))
|
||||||
|
#define VectorRandom(v) {do{(v)[0] = lhrandom(-1, 1);(v)[1] = lhrandom(-1, 1);(v)[2] = lhrandom(-1, 1);}while(DotProduct(v, v) > 1);}
|
||||||
|
|
||||||
|
#define VSM(a,b,c) {c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;}
|
||||||
|
|
||||||
|
// MDave -- courtesy of johnfitz, lordhavoc
|
||||||
|
#define VectorNormalizeFast(_v)\
|
||||||
|
{\
|
||||||
|
float _y, _number;\
|
||||||
|
_number = DotProduct(_v, _v);\
|
||||||
|
if (_number != 0.0)\
|
||||||
|
{\
|
||||||
|
*((long *)&_y) = 0x5f3759df - ((* (long *) &_number) >> 1);\
|
||||||
|
_y = _y * (1.5f - (_number * 0.5f * _y * _y));\
|
||||||
|
VectorScale(_v, _y, _v);\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef float matrix3x4[3][4];
|
||||||
|
typedef float matrix3x3[3][3];
|
||||||
|
|
||||||
|
void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
|
||||||
|
|
||||||
|
vec_t _DotProduct (vec3_t v1, vec3_t v2);
|
||||||
|
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
|
||||||
|
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
|
||||||
|
void _VectorCopy (vec3_t in, vec3_t out);
|
||||||
|
|
||||||
|
void vectoangles (vec3_t vec, vec3_t ang);
|
||||||
|
|
||||||
|
int VectorCompare (vec3_t v1, vec3_t v2);
|
||||||
|
vec_t Length (vec3_t v);
|
||||||
|
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
|
||||||
|
float VectorLength (vec3_t v);
|
||||||
|
float VecLength2(vec3_t v1, vec3_t v2);
|
||||||
|
float VectorNormalize (vec3_t v); // returns vector length
|
||||||
|
void VectorInverse (vec3_t v);
|
||||||
|
void VectorScale (vec3_t in, vec_t scale, vec3_t out);
|
||||||
|
int Q_log2(int val);
|
||||||
|
|
||||||
|
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
|
||||||
|
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
|
||||||
|
|
||||||
|
void FloorDivMod (float numer, float denom, int *quotient,
|
||||||
|
int *rem);
|
||||||
|
fixed16_t Invert24To16(fixed16_t val);
|
||||||
|
int GreatestCommonDivisor (int i1, int i2);
|
||||||
|
|
||||||
|
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||||
|
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
|
||||||
|
float anglemod(float a);
|
||||||
|
|
||||||
|
#define VectorL2Compare(v, w, m) \
|
||||||
|
(_mathlib_temp_float1 = (m) * (m), \
|
||||||
|
_mathlib_temp_vec1[0] = (v)[0] - (w)[0], _mathlib_temp_vec1[1] = (v)[1] - (w)[1], _mathlib_temp_vec1[2] = (v)[2] - (w)[2],\
|
||||||
|
_mathlib_temp_vec1[0] * _mathlib_temp_vec1[0] + \
|
||||||
|
_mathlib_temp_vec1[1] * _mathlib_temp_vec1[1] + \
|
||||||
|
_mathlib_temp_vec1[2] * _mathlib_temp_vec1[2] < _mathlib_temp_float1)
|
||||||
|
|
||||||
|
|
||||||
|
#define VectorSupCompare(v, w, m) \
|
||||||
|
(_mathlib_temp_float1 = m, \
|
||||||
|
(v)[0] - (w)[0] > -_mathlib_temp_float1 && (v)[0] - (w)[0] < _mathlib_temp_float1 && \
|
||||||
|
(v)[1] - (w)[1] > -_mathlib_temp_float1 && (v)[1] - (w)[1] < _mathlib_temp_float1 && \
|
||||||
|
(v)[2] - (w)[2] > -_mathlib_temp_float1 && (v)[2] - (w)[2] < _mathlib_temp_float1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define VectorNormalizeFast(_v) \
|
||||||
|
do { \
|
||||||
|
_mathlib_temp_float1 = DotProduct((_v), (_v)); \
|
||||||
|
if (_mathlib_temp_float1) { \
|
||||||
|
_mathlib_temp_float2 = 0.5f * _mathlib_temp_float1; \
|
||||||
|
_mathlib_temp_int1 = *((int *) &_mathlib_temp_float1); \
|
||||||
|
_mathlib_temp_int1 = 0x5f375a86 - (_mathlib_temp_int1 >> 1); \
|
||||||
|
_mathlib_temp_float1 = *((float *) &_mathlib_temp_int1); \
|
||||||
|
_mathlib_temp_float1 = _mathlib_temp_float1 * (1.5f - _mathlib_temp_float2 * _mathlib_temp_float1 * _mathlib_temp_float1); \
|
||||||
|
VectorScale((_v), _mathlib_temp_float1, (_v)) \
|
||||||
|
} \
|
||||||
|
} while (0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
||||||
|
(((p)->type < 3)? \
|
||||||
|
( \
|
||||||
|
((p)->dist <= (emins)[(p)->type])? \
|
||||||
|
1 \
|
||||||
|
: \
|
||||||
|
( \
|
||||||
|
((p)->dist >= (emaxs)[(p)->type])?\
|
||||||
|
2 \
|
||||||
|
: \
|
||||||
|
3 \
|
||||||
|
) \
|
||||||
|
) \
|
||||||
|
: \
|
||||||
|
BoxOnPlaneSide( (emins), (emaxs), (p)))
|
||||||
|
|
||||||
|
#define VectorInterpolate(v1, _frac, v2, v) \
|
||||||
|
do { \
|
||||||
|
_mathlib_temp_float1 = _frac; \
|
||||||
|
\
|
||||||
|
(v)[0] = (v1)[0] + _mathlib_temp_float1 * ((v2)[0] - (v1)[0]);\
|
||||||
|
(v)[1] = (v1)[1] + _mathlib_temp_float1 * ((v2)[1] - (v1)[1]);\
|
||||||
|
(v)[2] = (v1)[2] + _mathlib_temp_float1 * ((v2)[2] - (v1)[2]);\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define FloatInterpolate(f1, _frac, f2) \
|
||||||
|
(_mathlib_temp_float1 = _frac, \
|
||||||
|
(f1) + _mathlib_temp_float1 * ((f2) - (f1)))
|
||||||
|
|
||||||
|
#define PlaneDist(point, plane) ( \
|
||||||
|
(plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define PlaneDiff(point, plane) ( \
|
||||||
|
(((plane)->type < 3) ? (point)[(plane)->type] - (plane)->dist : DotProduct((point), (plane)->normal) - (plane)->dist) \
|
||||||
|
)
|
||||||
|
|
||||||
|
// Prototypes added by PM.
|
||||||
|
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
|
||||||
|
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out);
|
||||||
|
extern int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3;
|
||||||
|
extern float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
|
||||||
|
extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
|
532
source/matrixlib.c
Normal file
532
source/matrixlib.c
Normal file
|
@ -0,0 +1,532 @@
|
||||||
|
/*
|
||||||
|
matrixlib.c - internal matrixlib
|
||||||
|
Copyright (C) 2010 Uncle Mike
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
|
||||||
|
const matrix3x4 matrix3x4_identity =
|
||||||
|
{
|
||||||
|
{ 1, 0, 0, 0 }, // PITCH [forward], org[0]
|
||||||
|
{ 0, 1, 0, 0 }, // YAW [right] , org[1]
|
||||||
|
{ 0, 0, 1, 0 }, // ROLL [up] , org[2]
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
Matrix3x4 operations
|
||||||
|
|
||||||
|
========================================================================
|
||||||
|
*/
|
||||||
|
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
vec3_t dir;
|
||||||
|
|
||||||
|
dir[0] = v[0] - in[0][3];
|
||||||
|
dir[1] = v[1] - in[1][3];
|
||||||
|
dir[2] = v[2] - in[2][3];
|
||||||
|
|
||||||
|
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
|
||||||
|
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
|
||||||
|
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
|
||||||
|
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
|
||||||
|
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 )
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
|
||||||
|
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
|
||||||
|
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
|
||||||
|
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
|
||||||
|
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
|
||||||
|
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
|
||||||
|
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
|
||||||
|
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
|
||||||
|
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
|
||||||
|
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
|
||||||
|
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
|
||||||
|
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z )
|
||||||
|
{
|
||||||
|
out[0][3] = x;
|
||||||
|
out[1][3] = y;
|
||||||
|
out[2][3] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out )
|
||||||
|
{
|
||||||
|
out[0] = in[0][3];
|
||||||
|
out[1] = in[1][3];
|
||||||
|
out[2] = in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin )
|
||||||
|
{
|
||||||
|
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
|
||||||
|
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
|
||||||
|
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||||
|
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale )
|
||||||
|
{
|
||||||
|
float angle, sr, sp, sy, cr, cp, cy;
|
||||||
|
|
||||||
|
if( angles[ROLL] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sr, &cr );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
|
||||||
|
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (sr*sp*sy+cr*cy) * scale;
|
||||||
|
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = (sr*cp) * scale;
|
||||||
|
out[2][2] = (cr*cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
else if( angles[PITCH] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = (sp*cy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = (sp*sy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = 0;
|
||||||
|
out[2][2] = (cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
else if( angles[YAW] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
|
||||||
|
out[0][0] = (cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = 0;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = 0;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0;
|
||||||
|
out[2][1] = 0;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[0][0] = scale;
|
||||||
|
out[0][1] = 0;
|
||||||
|
out[0][2] = 0;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = 0;
|
||||||
|
out[1][1] = scale;
|
||||||
|
out[1][2] = 0;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0;
|
||||||
|
out[2][1] = 0;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_TransformPositivePlane( const matrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
float scale = vfpu_sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||||
|
#else
|
||||||
|
float scale = sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||||
|
#endif
|
||||||
|
float iscale = 1.0f / scale;
|
||||||
|
|
||||||
|
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
|
||||||
|
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
|
||||||
|
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
|
||||||
|
*dist = d * scale + ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_Invert_Simple( matrix3x4 out, const matrix3x4 in1 )
|
||||||
|
{
|
||||||
|
// we only support uniform scaling, so assume the first row is enough
|
||||||
|
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||||
|
// this means multiplying by the inverse scale twice - squaring it, which
|
||||||
|
// makes the sqrt a waste of time)
|
||||||
|
float scale = 1.0 / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
|
||||||
|
|
||||||
|
// invert the rotation by transposing and multiplying by the squared
|
||||||
|
// recipricol of the input matrix scale as described above
|
||||||
|
out[0][0] = in1[0][0] * scale;
|
||||||
|
out[0][1] = in1[1][0] * scale;
|
||||||
|
out[0][2] = in1[2][0] * scale;
|
||||||
|
out[1][0] = in1[0][1] * scale;
|
||||||
|
out[1][1] = in1[1][1] * scale;
|
||||||
|
out[1][2] = in1[2][1] * scale;
|
||||||
|
out[2][0] = in1[0][2] * scale;
|
||||||
|
out[2][1] = in1[1][2] * scale;
|
||||||
|
out[2][2] = in1[2][2] * scale;
|
||||||
|
|
||||||
|
// invert the translate
|
||||||
|
out[0][3] = -(in1[0][3] * out[0][0] + in1[1][3] * out[0][1] + in1[2][3] * out[0][2]);
|
||||||
|
out[1][3] = -(in1[0][3] * out[1][0] + in1[1][3] * out[1][1] + in1[2][3] * out[1][2]);
|
||||||
|
out[2][3] = -(in1[0][3] * out[2][0] + in1[1][3] * out[2][1] + in1[2][3] * out[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const matrix4x4 matrix4x4_identity =
|
||||||
|
{
|
||||||
|
{ 1, 0, 0, 0 }, // PITCH
|
||||||
|
{ 0, 1, 0, 0 }, // YAW
|
||||||
|
{ 0, 0, 1, 0 }, // ROLL
|
||||||
|
{ 0, 0, 0, 1 }, // ORIGIN
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
Matrix4x4 operations
|
||||||
|
|
||||||
|
========================================================================
|
||||||
|
*/
|
||||||
|
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
vec3_t dir;
|
||||||
|
|
||||||
|
dir[0] = v[0] - in[0][3];
|
||||||
|
dir[1] = v[1] - in[1][3];
|
||||||
|
dir[2] = v[2] - in[2][3];
|
||||||
|
|
||||||
|
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
|
||||||
|
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
|
||||||
|
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
|
||||||
|
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
|
||||||
|
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 )
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
|
||||||
|
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
|
||||||
|
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
|
||||||
|
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
|
||||||
|
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
|
||||||
|
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
|
||||||
|
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
|
||||||
|
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
|
||||||
|
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
|
||||||
|
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
|
||||||
|
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
|
||||||
|
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z )
|
||||||
|
{
|
||||||
|
out[0][3] = x;
|
||||||
|
out[1][3] = y;
|
||||||
|
out[2][3] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_OriginFromMatrix( const matrix4x4 in, float *out )
|
||||||
|
{
|
||||||
|
out[0] = in[0][3];
|
||||||
|
out[1] = in[1][3];
|
||||||
|
out[2] = in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_FromOriginQuat( matrix4x4 out, const vec4_t quaternion, const vec3_t origin )
|
||||||
|
{
|
||||||
|
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0;
|
||||||
|
out[3][1] = 0;
|
||||||
|
out[3][2] = 0;
|
||||||
|
out[3][3] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale )
|
||||||
|
{
|
||||||
|
float angle, sr, sp, sy, cr, cp, cy;
|
||||||
|
|
||||||
|
if( angles[ROLL] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sr, &cr );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
|
||||||
|
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (sr*sp*sy+cr*cy) * scale;
|
||||||
|
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = (sr*cp) * scale;
|
||||||
|
out[2][2] = (cr*cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0;
|
||||||
|
out[3][1] = 0;
|
||||||
|
out[3][2] = 0;
|
||||||
|
out[3][3] = 1;
|
||||||
|
}
|
||||||
|
else if( angles[PITCH] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = (sp*cy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = (sp*sy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = 0;
|
||||||
|
out[2][2] = (cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0;
|
||||||
|
out[3][1] = 0;
|
||||||
|
out[3][2] = 0;
|
||||||
|
out[3][3] = 1;
|
||||||
|
}
|
||||||
|
else if( angles[YAW] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI*2 / 360);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
|
||||||
|
out[0][0] = (cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = 0;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = 0;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0;
|
||||||
|
out[2][1] = 0;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0;
|
||||||
|
out[3][1] = 0;
|
||||||
|
out[3][2] = 0;
|
||||||
|
out[3][3] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[0][0] = scale;
|
||||||
|
out[0][1] = 0;
|
||||||
|
out[0][2] = 0;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = 0;
|
||||||
|
out[1][1] = scale;
|
||||||
|
out[1][2] = 0;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0;
|
||||||
|
out[2][1] = 0;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0;
|
||||||
|
out[3][1] = 0;
|
||||||
|
out[3][2] = 0;
|
||||||
|
out[3][3] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
float xyDist = vfpu_sqrtf( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
|
||||||
|
#else
|
||||||
|
float xyDist = sqrtf( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// enough here to get angles?
|
||||||
|
if( xyDist > 0.001f )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
angles[0] = RAD2DEG( vfpu_atan2f( -in[2][0], xyDist ) );
|
||||||
|
angles[1] = RAD2DEG( vfpu_atan2f( in[1][0], in[0][0] ) );
|
||||||
|
angles[2] = RAD2DEG( vfpu_atan2f( in[2][1], in[2][2] ) );
|
||||||
|
#else
|
||||||
|
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ) );
|
||||||
|
angles[1] = RAD2DEG( atan2( in[1][0], in[0][0] ) );
|
||||||
|
angles[2] = RAD2DEG( atan2( in[2][1], in[2][2] ) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else // forward is mostly Z, gimbal lock
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
angles[0] = RAD2DEG( vfpu_atan2f( -in[2][0], xyDist ) );
|
||||||
|
angles[1] = RAD2DEG( vfpu_atan2f( -in[0][1], in[1][1] ) );
|
||||||
|
#else
|
||||||
|
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ) );
|
||||||
|
angles[1] = RAD2DEG( atan2( -in[0][1], in[1][1] ) );
|
||||||
|
#endif
|
||||||
|
angles[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
origin[0] = in[0][3];
|
||||||
|
origin[1] = in[1][3];
|
||||||
|
origin[2] = in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
float scale = vfpu_sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||||
|
#else
|
||||||
|
float scale = sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||||
|
#endif
|
||||||
|
float iscale = 1.0f / scale;
|
||||||
|
|
||||||
|
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
|
||||||
|
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
|
||||||
|
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
|
||||||
|
*dist = d * scale + ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_TransformStandardPlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||||
|
{
|
||||||
|
#ifdef PSP_VFPU
|
||||||
|
float scale = vfpu_sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||||
|
#else
|
||||||
|
float scale = sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||||
|
#endif
|
||||||
|
float iscale = 1.0f / scale;
|
||||||
|
|
||||||
|
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
|
||||||
|
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
|
||||||
|
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
|
||||||
|
*dist = d * scale - ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 )
|
||||||
|
{
|
||||||
|
// we only support uniform scaling, so assume the first row is enough
|
||||||
|
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||||
|
// this means multiplying by the inverse scale twice - squaring it, which
|
||||||
|
// makes the sqrt a waste of time)
|
||||||
|
float scale = 1.0f / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
|
||||||
|
|
||||||
|
// invert the rotation by transposing and multiplying by the squared
|
||||||
|
// recipricol of the input matrix scale as described above
|
||||||
|
out[0][0] = in1[0][0] * scale;
|
||||||
|
out[0][1] = in1[1][0] * scale;
|
||||||
|
out[0][2] = in1[2][0] * scale;
|
||||||
|
out[1][0] = in1[0][1] * scale;
|
||||||
|
out[1][1] = in1[1][1] * scale;
|
||||||
|
out[1][2] = in1[2][1] * scale;
|
||||||
|
out[2][0] = in1[0][2] * scale;
|
||||||
|
out[2][1] = in1[1][2] * scale;
|
||||||
|
out[2][2] = in1[2][2] * scale;
|
||||||
|
|
||||||
|
// invert the translate
|
||||||
|
out[0][3] = -(in1[0][3] * out[0][0] + in1[1][3] * out[0][1] + in1[2][3] * out[0][2]);
|
||||||
|
out[1][3] = -(in1[0][3] * out[1][0] + in1[1][3] * out[1][1] + in1[2][3] * out[1][2]);
|
||||||
|
out[2][3] = -(in1[0][3] * out[2][0] + in1[1][3] * out[2][1] + in1[2][3] * out[2][2]);
|
||||||
|
|
||||||
|
// don't know if there's anything worth doing here
|
||||||
|
out[3][0] = 0;
|
||||||
|
out[3][1] = 0;
|
||||||
|
out[3][2] = 0;
|
||||||
|
out[3][3] = 1;
|
||||||
|
}
|
5697
source/menu.c
Normal file
5697
source/menu.c
Normal file
File diff suppressed because it is too large
Load diff
40
source/menu.h
Normal file
40
source/menu.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// the net drivers should just set the apropriate bits in m_activenet,
|
||||||
|
// instead of having the menu code look through their internal tables
|
||||||
|
//
|
||||||
|
#define MNET_IPX 1
|
||||||
|
#define MNET_TCP 2
|
||||||
|
|
||||||
|
extern int m_activenet;
|
||||||
|
|
||||||
|
//
|
||||||
|
// menus
|
||||||
|
//
|
||||||
|
void M_Init (void);
|
||||||
|
void M_Keydown (int key);
|
||||||
|
void M_Draw (void);
|
||||||
|
void M_ToggleMenu_f (void);
|
||||||
|
|
||||||
|
|
||||||
|
void Save_Achivements(void);
|
||||||
|
void Load_Achivements(void);
|
161
source/modelgen.h
Normal file
161
source/modelgen.h
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// modelgen.h: header file for model generation program
|
||||||
|
//
|
||||||
|
|
||||||
|
// *********************************************************
|
||||||
|
// * This file must be identical in the modelgen directory *
|
||||||
|
// * and in the Quake directory, because it's used to *
|
||||||
|
// * pass data from one to the other via model files. *
|
||||||
|
// *********************************************************
|
||||||
|
|
||||||
|
#ifdef INCLUDELIBS
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "scriplib.h"
|
||||||
|
#include "trilib.h"
|
||||||
|
#include "lbmlib.h"
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ALIAS_VERSION 6
|
||||||
|
#define ALIAS_NEWVERSION 50
|
||||||
|
|
||||||
|
#define ALIAS_ONSEAM 0x0020
|
||||||
|
|
||||||
|
// must match definition in spritegn.h
|
||||||
|
#ifndef SYNCTYPE_T
|
||||||
|
#define SYNCTYPE_T
|
||||||
|
typedef enum {ST_SYNC=0, ST_RAND } synctype_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum { ALIAS_SINGLE=0, ALIAS_GROUP } aliasframetype_t;
|
||||||
|
|
||||||
|
typedef enum { ALIAS_SKIN_SINGLE=0, ALIAS_SKIN_GROUP } aliasskintype_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int ident;
|
||||||
|
int version;
|
||||||
|
vec3_t scale;
|
||||||
|
vec3_t scale_origin;
|
||||||
|
float boundingradius;
|
||||||
|
vec3_t eyeposition;
|
||||||
|
int numskins;
|
||||||
|
int skinwidth;
|
||||||
|
int skinheight;
|
||||||
|
int numverts;
|
||||||
|
int numtris;
|
||||||
|
int numframes;
|
||||||
|
synctype_t synctype;
|
||||||
|
int flags;
|
||||||
|
float size;
|
||||||
|
} mdl_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int ident;
|
||||||
|
int version;
|
||||||
|
vec3_t scale;
|
||||||
|
vec3_t scale_origin;
|
||||||
|
float boundingradius;
|
||||||
|
vec3_t eyeposition;
|
||||||
|
int numskins;
|
||||||
|
int skinwidth;
|
||||||
|
int skinheight;
|
||||||
|
int numverts;
|
||||||
|
int numtris;
|
||||||
|
int numframes;
|
||||||
|
synctype_t synctype;
|
||||||
|
int flags;
|
||||||
|
float size;
|
||||||
|
int num_st_verts;
|
||||||
|
} newmdl_t;
|
||||||
|
|
||||||
|
// TODO: could be shorts
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int onseam;
|
||||||
|
int s;
|
||||||
|
int t;
|
||||||
|
} stvert_t;
|
||||||
|
|
||||||
|
typedef struct dtriangle_s {
|
||||||
|
int facesfront;
|
||||||
|
int vertindex[3];
|
||||||
|
} dtriangle_t;
|
||||||
|
|
||||||
|
typedef struct dnewtriangle_s
|
||||||
|
{
|
||||||
|
int facesfront;
|
||||||
|
unsigned short vertindex[3];
|
||||||
|
unsigned short stindex[3];
|
||||||
|
} dnewtriangle_t;
|
||||||
|
|
||||||
|
#define DT_FACES_FRONT 0x0010
|
||||||
|
|
||||||
|
// This mirrors trivert_t in trilib.h, is present so Quake knows how to
|
||||||
|
// load this data
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte v[3];
|
||||||
|
byte lightnormalindex;
|
||||||
|
} trivertx_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
trivertx_t bboxmin; // lightnormal isn't used
|
||||||
|
trivertx_t bboxmax; // lightnormal isn't used
|
||||||
|
char name[16]; // frame name from grabbing
|
||||||
|
} daliasframe_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int numframes;
|
||||||
|
trivertx_t bboxmin; // lightnormal isn't used
|
||||||
|
trivertx_t bboxmax; // lightnormal isn't used
|
||||||
|
} daliasgroup_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int numskins;
|
||||||
|
} daliasskingroup_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float interval;
|
||||||
|
} daliasinterval_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float interval;
|
||||||
|
} daliasskininterval_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
aliasframetype_t type;
|
||||||
|
} daliasframetype_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
aliasskintype_t type;
|
||||||
|
} daliasskintype_t;
|
||||||
|
|
||||||
|
#define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') // little-endian "IDPO"
|
||||||
|
#define RAPOLYHEADER (('O'<<24)+('P'<<16)+('A'<<8)+'R') // little-endian "RAPO"
|
336
source/net.h
Normal file
336
source/net.h
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// net.h -- quake's interface to the networking layer
|
||||||
|
|
||||||
|
struct qsockaddr
|
||||||
|
{
|
||||||
|
unsigned char sa_len;
|
||||||
|
unsigned char sa_family;
|
||||||
|
unsigned char sa_data[14];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define NET_NAMELEN 64
|
||||||
|
|
||||||
|
// HACK HACK HACK - certain maps will hit this limit.. no clue why.. so let's just
|
||||||
|
// double it lol
|
||||||
|
#define NET_MAXMESSAGE /*8192*/16384
|
||||||
|
#define NET_HEADERSIZE (2 * sizeof(unsigned int))
|
||||||
|
#define NET_DATAGRAMSIZE (MAX_DATAGRAM + NET_HEADERSIZE)
|
||||||
|
|
||||||
|
// NetHeader flags
|
||||||
|
#define NETFLAG_LENGTH_MASK 0x0000ffff
|
||||||
|
#define NETFLAG_DATA 0x00010000
|
||||||
|
#define NETFLAG_ACK 0x00020000
|
||||||
|
#define NETFLAG_NAK 0x00040000
|
||||||
|
#define NETFLAG_EOM 0x00080000
|
||||||
|
#define NETFLAG_UNRELIABLE 0x00100000
|
||||||
|
#define NETFLAG_CTL 0x80000000
|
||||||
|
|
||||||
|
|
||||||
|
#define NET_PROTOCOL_VERSION 3
|
||||||
|
|
||||||
|
// This is the network info/connection protocol. It is used to find Quake
|
||||||
|
// servers, get info about them, and connect to them. Once connected, the
|
||||||
|
// Quake game protocol (documented elsewhere) is used.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// General notes:
|
||||||
|
// game_name is currently always "QUAKE", but is there so this same protocol
|
||||||
|
// can be used for future games as well; can you say Quake2?
|
||||||
|
//
|
||||||
|
// CCREQ_CONNECT
|
||||||
|
// string game_name "QUAKE"
|
||||||
|
// byte net_protocol_version NET_PROTOCOL_VERSION
|
||||||
|
//
|
||||||
|
// CCREQ_SERVER_INFO
|
||||||
|
// string game_name "QUAKE"
|
||||||
|
// byte net_protocol_version NET_PROTOCOL_VERSION
|
||||||
|
//
|
||||||
|
// CCREQ_PLAYER_INFO
|
||||||
|
// byte player_number
|
||||||
|
//
|
||||||
|
// CCREQ_RULE_INFO
|
||||||
|
// string rule
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// CCREP_ACCEPT
|
||||||
|
// long port
|
||||||
|
//
|
||||||
|
// CCREP_REJECT
|
||||||
|
// string reason
|
||||||
|
//
|
||||||
|
// CCREP_SERVER_INFO
|
||||||
|
// string server_address
|
||||||
|
// string host_name
|
||||||
|
// string level_name
|
||||||
|
// byte current_players
|
||||||
|
// byte max_players
|
||||||
|
// byte protocol_version NET_PROTOCOL_VERSION
|
||||||
|
//
|
||||||
|
// CCREP_PLAYER_INFO
|
||||||
|
// byte player_number
|
||||||
|
// string name
|
||||||
|
// long colors
|
||||||
|
// long frags
|
||||||
|
// long connect_time
|
||||||
|
// string address
|
||||||
|
//
|
||||||
|
// CCREP_RULE_INFO
|
||||||
|
// string rule
|
||||||
|
// string value
|
||||||
|
|
||||||
|
// note:
|
||||||
|
// There are two address forms used above. The short form is just a
|
||||||
|
// port number. The address that goes along with the port is defined as
|
||||||
|
// "whatever address you receive this reponse from". This lets us use
|
||||||
|
// the host OS to solve the problem of multiple host addresses (possibly
|
||||||
|
// with no routing between them); the host will use the right address
|
||||||
|
// when we reply to the inbound connection request. The long from is
|
||||||
|
// a full address and port in a string. It is used for returning the
|
||||||
|
// address of a server that is not running locally.
|
||||||
|
|
||||||
|
#define CCREQ_CONNECT 0x01
|
||||||
|
#define CCREQ_SERVER_INFO 0x02
|
||||||
|
#define CCREQ_PLAYER_INFO 0x03
|
||||||
|
#define CCREQ_RULE_INFO 0x04
|
||||||
|
|
||||||
|
#define CCREP_ACCEPT 0x81
|
||||||
|
#define CCREP_REJECT 0x82
|
||||||
|
#define CCREP_SERVER_INFO 0x83
|
||||||
|
#define CCREP_PLAYER_INFO 0x84
|
||||||
|
#define CCREP_RULE_INFO 0x85
|
||||||
|
|
||||||
|
typedef struct qsocket_s
|
||||||
|
{
|
||||||
|
struct qsocket_s *next;
|
||||||
|
double connecttime;
|
||||||
|
double lastMessageTime;
|
||||||
|
double lastSendTime;
|
||||||
|
|
||||||
|
qboolean disconnected;
|
||||||
|
qboolean canSend;
|
||||||
|
qboolean sendNext;
|
||||||
|
|
||||||
|
int driver;
|
||||||
|
int landriver;
|
||||||
|
int socket;
|
||||||
|
void *driverdata;
|
||||||
|
|
||||||
|
unsigned int ackSequence;
|
||||||
|
unsigned int sendSequence;
|
||||||
|
unsigned int unreliableSendSequence;
|
||||||
|
int sendMessageLength;
|
||||||
|
byte sendMessage [NET_MAXMESSAGE];
|
||||||
|
|
||||||
|
unsigned int receiveSequence;
|
||||||
|
unsigned int unreliableReceiveSequence;
|
||||||
|
int receiveMessageLength;
|
||||||
|
byte receiveMessage [NET_MAXMESSAGE];
|
||||||
|
|
||||||
|
struct qsockaddr addr;
|
||||||
|
char address[NET_NAMELEN];
|
||||||
|
|
||||||
|
} qsocket_t;
|
||||||
|
|
||||||
|
extern qsocket_t *net_activeSockets;
|
||||||
|
extern qsocket_t *net_freeSockets;
|
||||||
|
extern int net_numsockets;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
qboolean initialized;
|
||||||
|
int controlSock;
|
||||||
|
int (*Init) (void);
|
||||||
|
void (*Shutdown) (void);
|
||||||
|
void (*Listen) (qboolean state);
|
||||||
|
int (*OpenSocket) (int port);
|
||||||
|
int (*CloseSocket) (int socket);
|
||||||
|
int (*Connect) (int socket, struct qsockaddr *addr);
|
||||||
|
int (*CheckNewConnections) (void);
|
||||||
|
int (*Read) (int socket, byte *buf, int len, struct qsockaddr *addr);
|
||||||
|
int (*Write) (int socket, byte *buf, int len, struct qsockaddr *addr);
|
||||||
|
int (*Broadcast) (int socket, byte *buf, int len);
|
||||||
|
char * (*AddrToString) (struct qsockaddr *addr);
|
||||||
|
int (*StringToAddr) (char *string, struct qsockaddr *addr);
|
||||||
|
int (*GetSocketAddr) (int socket, struct qsockaddr *addr);
|
||||||
|
int (*GetNameFromAddr) (struct qsockaddr *addr, char *name);
|
||||||
|
int (*GetAddrFromName) (char *name, struct qsockaddr *addr);
|
||||||
|
int (*AddrCompare) (struct qsockaddr *addr1, struct qsockaddr *addr2);
|
||||||
|
int (*GetSocketPort) (struct qsockaddr *addr);
|
||||||
|
int (*SetSocketPort) (struct qsockaddr *addr, int port);
|
||||||
|
} net_landriver_t;
|
||||||
|
|
||||||
|
#define MAX_NET_DRIVERS 8
|
||||||
|
extern int net_numlandrivers;
|
||||||
|
extern net_landriver_t net_landrivers[MAX_NET_DRIVERS];
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
qboolean initialized;
|
||||||
|
int (*Init) (void);
|
||||||
|
void (*Listen) (qboolean state);
|
||||||
|
void (*SearchForHosts) (qboolean xmit);
|
||||||
|
qsocket_t *(*Connect) (char *host);
|
||||||
|
qsocket_t *(*CheckNewConnections) (void);
|
||||||
|
int (*QGetMessage) (qsocket_t *sock);
|
||||||
|
int (*QSendMessage) (qsocket_t *sock, sizebuf_t *data);
|
||||||
|
int (*SendUnreliableMessage) (qsocket_t *sock, sizebuf_t *data);
|
||||||
|
qboolean (*CanSendMessage) (qsocket_t *sock);
|
||||||
|
qboolean (*CanSendUnreliableMessage) (qsocket_t *sock);
|
||||||
|
void (*Close) (qsocket_t *sock);
|
||||||
|
void (*Shutdown) (void);
|
||||||
|
int controlSock;
|
||||||
|
} net_driver_t;
|
||||||
|
|
||||||
|
extern int net_numdrivers;
|
||||||
|
extern net_driver_t net_drivers[MAX_NET_DRIVERS];
|
||||||
|
|
||||||
|
extern int DEFAULTnet_hostport;
|
||||||
|
extern int net_hostport;
|
||||||
|
|
||||||
|
extern int net_driverlevel;
|
||||||
|
extern cvar_t hostname;
|
||||||
|
extern char playername[];
|
||||||
|
extern int playercolor;
|
||||||
|
|
||||||
|
extern int messagesSent;
|
||||||
|
extern int messagesReceived;
|
||||||
|
extern int unreliableMessagesSent;
|
||||||
|
extern int unreliableMessagesReceived;
|
||||||
|
|
||||||
|
qsocket_t *NET_NewQSocket (void);
|
||||||
|
void NET_FreeQSocket(qsocket_t *);
|
||||||
|
double SetNetTime(void);
|
||||||
|
|
||||||
|
|
||||||
|
#define HOSTCACHESIZE 8
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[16];
|
||||||
|
char map[16];
|
||||||
|
char cname[32];
|
||||||
|
int users;
|
||||||
|
int maxusers;
|
||||||
|
int driver;
|
||||||
|
int ldriver;
|
||||||
|
struct qsockaddr addr;
|
||||||
|
} hostcache_t;
|
||||||
|
|
||||||
|
extern int hostCacheCount;
|
||||||
|
extern hostcache_t hostcache[HOSTCACHESIZE];
|
||||||
|
|
||||||
|
#ifndef htonl
|
||||||
|
extern unsigned long htonl (unsigned long hostlong);
|
||||||
|
#endif
|
||||||
|
#ifndef htons
|
||||||
|
extern unsigned short htons (unsigned short hostshort);
|
||||||
|
#endif
|
||||||
|
#ifndef ntohl
|
||||||
|
extern unsigned long ntohl (unsigned long netlong);
|
||||||
|
#endif
|
||||||
|
#ifndef ntohs
|
||||||
|
extern unsigned short ntohs (unsigned short netshort);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// public network functions
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
extern double net_time;
|
||||||
|
extern sizebuf_t net_message;
|
||||||
|
extern int net_activeconnections;
|
||||||
|
|
||||||
|
void NET_Init (void);
|
||||||
|
void NET_Shutdown (void);
|
||||||
|
|
||||||
|
struct qsocket_s *NET_CheckNewConnections (void);
|
||||||
|
// returns a new connection number if there is one pending, else -1
|
||||||
|
|
||||||
|
struct qsocket_s *NET_Connect (char *host);
|
||||||
|
// called by client to connect to a host. Returns -1 if not able to
|
||||||
|
|
||||||
|
qboolean NET_CanSendMessage (qsocket_t *sock);
|
||||||
|
// Returns true or false if the given qsocket can currently accept a
|
||||||
|
// message to be transmitted.
|
||||||
|
|
||||||
|
int NET_GetMessage (struct qsocket_s *sock);
|
||||||
|
// returns data in net_message sizebuf
|
||||||
|
// returns 0 if no data is waiting
|
||||||
|
// returns 1 if a message was received
|
||||||
|
// returns 2 if an unreliable message was received
|
||||||
|
// returns -1 if the connection died
|
||||||
|
|
||||||
|
int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data);
|
||||||
|
int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data);
|
||||||
|
// returns 0 if the message connot be delivered reliably, but the connection
|
||||||
|
// is still considered valid
|
||||||
|
// returns 1 if the message was sent properly
|
||||||
|
// returns -1 if the connection died
|
||||||
|
|
||||||
|
int NET_SendToAll(sizebuf_t *data, int blocktime);
|
||||||
|
// This is a reliable *blocking* send to all attached clients.
|
||||||
|
|
||||||
|
|
||||||
|
void NET_Close (struct qsocket_s *sock);
|
||||||
|
// if a dead connection is returned by a get or send function, this function
|
||||||
|
// should be called when it is convenient
|
||||||
|
|
||||||
|
// Server calls when a client is kicked off for a game related misbehavior
|
||||||
|
// like an illegal protocal conversation. Client calls when disconnecting
|
||||||
|
// from a server.
|
||||||
|
// A netcon_t number will not be reused until this function is called for it
|
||||||
|
|
||||||
|
void NET_Poll(void);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _PollProcedure
|
||||||
|
{
|
||||||
|
struct _PollProcedure *next;
|
||||||
|
double nextTime;
|
||||||
|
void (*procedure)();
|
||||||
|
void *arg;
|
||||||
|
} PollProcedure;
|
||||||
|
|
||||||
|
void SchedulePollProcedure(PollProcedure *pp, double timeOffset);
|
||||||
|
|
||||||
|
extern qboolean serialAvailable;
|
||||||
|
extern qboolean ipxAvailable;
|
||||||
|
extern qboolean tcpipAvailable;
|
||||||
|
extern qboolean tcpipAdhoc;
|
||||||
|
|
||||||
|
extern char my_ipx_address[NET_NAMELEN];
|
||||||
|
extern char my_tcpip_address[NET_NAMELEN];
|
||||||
|
extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem);
|
||||||
|
extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem);
|
||||||
|
extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
|
||||||
|
extern void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
|
||||||
|
|
||||||
|
extern qboolean slistInProgress;
|
||||||
|
extern qboolean slistSilent;
|
||||||
|
extern qboolean slistLocal;
|
||||||
|
|
||||||
|
void NET_Slist_f (void);
|
1286
source/net_dgrm.c
Normal file
1286
source/net_dgrm.c
Normal file
File diff suppressed because it is too large
Load diff
35
source/net_dgrm.h
Normal file
35
source/net_dgrm.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// net_dgrm.h
|
||||||
|
|
||||||
|
int net_driver_to_use;
|
||||||
|
|
||||||
|
int Datagram_Init (void);
|
||||||
|
void Datagram_Listen (qboolean state);
|
||||||
|
void Datagram_SearchForHosts (qboolean xmit);
|
||||||
|
qsocket_t *Datagram_Connect (char *host);
|
||||||
|
qsocket_t *Datagram_CheckNewConnections (void);
|
||||||
|
int Datagram_GetMessage (qsocket_t *sock);
|
||||||
|
int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data);
|
||||||
|
int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data);
|
||||||
|
qboolean Datagram_CanSendMessage (qsocket_t *sock);
|
||||||
|
qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock);
|
||||||
|
void Datagram_Close (qsocket_t *sock);
|
||||||
|
void Datagram_Shutdown (void);
|
245
source/net_loop.c
Normal file
245
source/net_loop.c
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// net_loop.c
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
#include "net_loop.h"
|
||||||
|
|
||||||
|
qboolean localconnectpending = false;
|
||||||
|
qsocket_t *loop_client = NULL;
|
||||||
|
qsocket_t *loop_server = NULL;
|
||||||
|
|
||||||
|
int Loop_Init (void)
|
||||||
|
{
|
||||||
|
if (cls.state == ca_dedicated)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Loop_Shutdown (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Loop_Listen (qboolean state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Loop_SearchForHosts (qboolean xmit)
|
||||||
|
{
|
||||||
|
if (!sv.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hostCacheCount = 1;
|
||||||
|
if (Q_strcmp(hostname.string, "UNNAMED") == 0)
|
||||||
|
Q_strcpy(hostcache[0].name, "local");
|
||||||
|
else
|
||||||
|
Q_strcpy(hostcache[0].name, hostname.string);
|
||||||
|
Q_strcpy(hostcache[0].map, sv.name);
|
||||||
|
hostcache[0].users = net_activeconnections;
|
||||||
|
hostcache[0].maxusers = svs.maxclients;
|
||||||
|
hostcache[0].driver = net_driverlevel;
|
||||||
|
Q_strcpy(hostcache[0].cname, "local");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qsocket_t *Loop_Connect (char *host)
|
||||||
|
{
|
||||||
|
if (Q_strcmp(host,"local") != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
localconnectpending = true;
|
||||||
|
|
||||||
|
if (!loop_client)
|
||||||
|
{
|
||||||
|
if ((loop_client = NET_NewQSocket ()) == NULL)
|
||||||
|
{
|
||||||
|
Con_Printf("Loop_Connect: no qsocket available\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Q_strcpy (loop_client->address, "localhost");
|
||||||
|
}
|
||||||
|
loop_client->receiveMessageLength = 0;
|
||||||
|
loop_client->sendMessageLength = 0;
|
||||||
|
loop_client->canSend = true;
|
||||||
|
|
||||||
|
if (!loop_server)
|
||||||
|
{
|
||||||
|
if ((loop_server = NET_NewQSocket ()) == NULL)
|
||||||
|
{
|
||||||
|
Con_Printf("Loop_Connect: no qsocket available\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Q_strcpy (loop_server->address, "LOCAL");
|
||||||
|
}
|
||||||
|
loop_server->receiveMessageLength = 0;
|
||||||
|
loop_server->sendMessageLength = 0;
|
||||||
|
loop_server->canSend = true;
|
||||||
|
|
||||||
|
loop_client->driverdata = (void *)loop_server;
|
||||||
|
loop_server->driverdata = (void *)loop_client;
|
||||||
|
|
||||||
|
return loop_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qsocket_t *Loop_CheckNewConnections (void)
|
||||||
|
{
|
||||||
|
if (!localconnectpending)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
localconnectpending = false;
|
||||||
|
loop_server->sendMessageLength = 0;
|
||||||
|
loop_server->receiveMessageLength = 0;
|
||||||
|
loop_server->canSend = true;
|
||||||
|
loop_client->sendMessageLength = 0;
|
||||||
|
loop_client->receiveMessageLength = 0;
|
||||||
|
loop_client->canSend = true;
|
||||||
|
return loop_server;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int IntAlign(int value)
|
||||||
|
{
|
||||||
|
return (value + (sizeof(int) - 1)) & (~(sizeof(int) - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Loop_GetMessage (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
if (sock->receiveMessageLength == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = sock->receiveMessage[0];
|
||||||
|
length = sock->receiveMessage[1] + (sock->receiveMessage[2] << 8);
|
||||||
|
// alignment byte skipped here
|
||||||
|
SZ_Clear (&net_message);
|
||||||
|
SZ_Write (&net_message, &sock->receiveMessage[4], length);
|
||||||
|
|
||||||
|
length = IntAlign(length + 4);
|
||||||
|
sock->receiveMessageLength -= length;
|
||||||
|
|
||||||
|
if (sock->receiveMessageLength)
|
||||||
|
Q_memcpy(sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength);
|
||||||
|
|
||||||
|
if (sock->driverdata && ret == 1)
|
||||||
|
((qsocket_t *)sock->driverdata)->canSend = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data)
|
||||||
|
{
|
||||||
|
byte *buffer;
|
||||||
|
int *bufferLength;
|
||||||
|
|
||||||
|
if (!sock->driverdata)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength;
|
||||||
|
|
||||||
|
if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE)
|
||||||
|
Sys_Error("Loop_SendMessage: overflow\n");
|
||||||
|
|
||||||
|
buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength;
|
||||||
|
|
||||||
|
// message type
|
||||||
|
*buffer++ = 1;
|
||||||
|
|
||||||
|
// length
|
||||||
|
*buffer++ = data->cursize & 0xff;
|
||||||
|
*buffer++ = data->cursize >> 8;
|
||||||
|
|
||||||
|
// align
|
||||||
|
buffer++;
|
||||||
|
|
||||||
|
// message
|
||||||
|
Q_memcpy(buffer, data->data, data->cursize);
|
||||||
|
*bufferLength = IntAlign(*bufferLength + data->cursize + 4);
|
||||||
|
|
||||||
|
sock->canSend = false;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
|
||||||
|
{
|
||||||
|
byte *buffer;
|
||||||
|
int *bufferLength;
|
||||||
|
|
||||||
|
if (!sock->driverdata)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength;
|
||||||
|
|
||||||
|
if ((*bufferLength + data->cursize + sizeof(byte) + sizeof(short)) > NET_MAXMESSAGE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength;
|
||||||
|
|
||||||
|
// message type
|
||||||
|
*buffer++ = 2;
|
||||||
|
|
||||||
|
// length
|
||||||
|
*buffer++ = data->cursize & 0xff;
|
||||||
|
*buffer++ = data->cursize >> 8;
|
||||||
|
|
||||||
|
// align
|
||||||
|
buffer++;
|
||||||
|
|
||||||
|
// message
|
||||||
|
Q_memcpy(buffer, data->data, data->cursize);
|
||||||
|
*bufferLength = IntAlign(*bufferLength + data->cursize + 4);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qboolean Loop_CanSendMessage (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
if (!sock->driverdata)
|
||||||
|
return false;
|
||||||
|
return sock->canSend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Loop_Close (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
if (sock->driverdata)
|
||||||
|
((qsocket_t *)sock->driverdata)->driverdata = NULL;
|
||||||
|
sock->receiveMessageLength = 0;
|
||||||
|
sock->sendMessageLength = 0;
|
||||||
|
sock->canSend = true;
|
||||||
|
if (sock == loop_client)
|
||||||
|
loop_client = NULL;
|
||||||
|
else
|
||||||
|
loop_server = NULL;
|
||||||
|
}
|
33
source/net_loop.h
Normal file
33
source/net_loop.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// net_loop.h
|
||||||
|
|
||||||
|
int Loop_Init (void);
|
||||||
|
void Loop_Listen (qboolean state);
|
||||||
|
void Loop_SearchForHosts (qboolean xmit);
|
||||||
|
qsocket_t *Loop_Connect (char *host);
|
||||||
|
qsocket_t *Loop_CheckNewConnections (void);
|
||||||
|
int Loop_GetMessage (qsocket_t *sock);
|
||||||
|
int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data);
|
||||||
|
int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data);
|
||||||
|
qboolean Loop_CanSendMessage (qsocket_t *sock);
|
||||||
|
qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock);
|
||||||
|
void Loop_Close (qsocket_t *sock);
|
||||||
|
void Loop_Shutdown (void);
|
987
source/net_main.c
Normal file
987
source/net_main.c
Normal file
|
@ -0,0 +1,987 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// net_main.c
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
#include "net_vcr.h"
|
||||||
|
|
||||||
|
qsocket_t *net_activeSockets = NULL;
|
||||||
|
qsocket_t *net_freeSockets = NULL;
|
||||||
|
int net_numsockets = 0;
|
||||||
|
|
||||||
|
qboolean serialAvailable = false;
|
||||||
|
qboolean ipxAvailable = false;
|
||||||
|
qboolean tcpipAvailable = false;
|
||||||
|
qboolean tcpipAdhoc = false;
|
||||||
|
|
||||||
|
int net_hostport;
|
||||||
|
int DEFAULTnet_hostport = 26000;
|
||||||
|
|
||||||
|
char my_ipx_address[NET_NAMELEN];
|
||||||
|
char my_tcpip_address[NET_NAMELEN];
|
||||||
|
|
||||||
|
void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem);
|
||||||
|
void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem);
|
||||||
|
void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
|
||||||
|
void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup);
|
||||||
|
|
||||||
|
static qboolean listening = false;
|
||||||
|
|
||||||
|
qboolean slistInProgress = false;
|
||||||
|
qboolean slistSilent = false;
|
||||||
|
qboolean slistLocal = true;
|
||||||
|
static double slistStartTime;
|
||||||
|
static int slistLastShown;
|
||||||
|
|
||||||
|
static void Slist_Send(void);
|
||||||
|
static void Slist_Poll(void);
|
||||||
|
PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send};
|
||||||
|
PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll};
|
||||||
|
|
||||||
|
|
||||||
|
sizebuf_t net_message;
|
||||||
|
int net_activeconnections = 0;
|
||||||
|
|
||||||
|
int messagesSent = 0;
|
||||||
|
int messagesReceived = 0;
|
||||||
|
int unreliableMessagesSent = 0;
|
||||||
|
int unreliableMessagesReceived = 0;
|
||||||
|
|
||||||
|
cvar_t net_messagetimeout = {"net_messagetimeout","300"};
|
||||||
|
cvar_t hostname = {"hostname", "Unnamed Server"};
|
||||||
|
|
||||||
|
qboolean configRestored = false;
|
||||||
|
cvar_t config_com_port = {"_config_com_port", "0x3f8", true};
|
||||||
|
cvar_t config_com_irq = {"_config_com_irq", "4", true};
|
||||||
|
cvar_t config_com_baud = {"_config_com_baud", "57600", true};
|
||||||
|
cvar_t config_com_modem = {"_config_com_modem", "1", true};
|
||||||
|
cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", true};
|
||||||
|
cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", true};
|
||||||
|
cvar_t config_modem_init = {"_config_modem_init", "", true};
|
||||||
|
cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", true};
|
||||||
|
|
||||||
|
int vcrFile = -1;
|
||||||
|
qboolean recording = false;
|
||||||
|
|
||||||
|
// these two macros are to make the code more readable
|
||||||
|
#define sfunc net_drivers[sock->driver]
|
||||||
|
#define dfunc net_drivers[net_driverlevel]
|
||||||
|
|
||||||
|
int net_driverlevel;
|
||||||
|
|
||||||
|
|
||||||
|
double net_time;
|
||||||
|
|
||||||
|
double SetNetTime(void)
|
||||||
|
{
|
||||||
|
net_time = Sys_FloatTime();
|
||||||
|
return net_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
NET_NewQSocket
|
||||||
|
|
||||||
|
Called by drivers when a new communications endpoint is required
|
||||||
|
The sequence and buffer fields will be filled in properly
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
qsocket_t *NET_NewQSocket (void)
|
||||||
|
{
|
||||||
|
qsocket_t *sock;
|
||||||
|
|
||||||
|
if (net_freeSockets == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (net_activeconnections >= svs.maxclients)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// get one from free list
|
||||||
|
sock = net_freeSockets;
|
||||||
|
net_freeSockets = sock->next;
|
||||||
|
|
||||||
|
// add it to active list
|
||||||
|
sock->next = net_activeSockets;
|
||||||
|
net_activeSockets = sock;
|
||||||
|
|
||||||
|
sock->disconnected = false;
|
||||||
|
sock->connecttime = net_time;
|
||||||
|
Q_strcpy (sock->address,"UNSET ADDRESS");
|
||||||
|
sock->driver = net_driverlevel;
|
||||||
|
sock->socket = 0;
|
||||||
|
sock->driverdata = NULL;
|
||||||
|
sock->canSend = true;
|
||||||
|
sock->sendNext = false;
|
||||||
|
sock->lastMessageTime = net_time;
|
||||||
|
sock->ackSequence = 0;
|
||||||
|
sock->sendSequence = 0;
|
||||||
|
sock->unreliableSendSequence = 0;
|
||||||
|
sock->sendMessageLength = 0;
|
||||||
|
sock->receiveSequence = 0;
|
||||||
|
sock->unreliableReceiveSequence = 0;
|
||||||
|
sock->receiveMessageLength = 0;
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NET_FreeQSocket(qsocket_t *sock)
|
||||||
|
{
|
||||||
|
qsocket_t *s;
|
||||||
|
|
||||||
|
// remove it from active list
|
||||||
|
if (sock == net_activeSockets)
|
||||||
|
net_activeSockets = net_activeSockets->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (s = net_activeSockets; s; s = s->next)
|
||||||
|
if (s->next == sock)
|
||||||
|
{
|
||||||
|
s->next = sock->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!s)
|
||||||
|
Sys_Error ("NET_FreeQSocket: not active\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// add it to free list
|
||||||
|
sock->next = net_freeSockets;
|
||||||
|
net_freeSockets = sock;
|
||||||
|
sock->disconnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void NET_Listen_f (void)
|
||||||
|
{
|
||||||
|
if (Cmd_Argc () != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listening = Q_atoi(Cmd_Argv(1)) ? true : false;
|
||||||
|
|
||||||
|
for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
|
||||||
|
{
|
||||||
|
if (net_drivers[net_driverlevel].initialized == false)
|
||||||
|
continue;
|
||||||
|
dfunc.Listen (listening);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void MaxPlayers_f (void)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (Cmd_Argc () != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("\"maxplayers\" is \"%u\"\n", svs.maxclients);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sv.active)
|
||||||
|
{
|
||||||
|
Con_Printf ("maxplayers can not be changed while a server is running.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = Q_atoi(Cmd_Argv(1));
|
||||||
|
if (n < 1)
|
||||||
|
n = 1;
|
||||||
|
if (n > svs.maxclientslimit)
|
||||||
|
{
|
||||||
|
n = svs.maxclientslimit;
|
||||||
|
Con_Printf ("\"maxplayers\" set to \"%u\"\n", n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((n == 1) && listening)
|
||||||
|
Cbuf_AddText ("listen 0\n");
|
||||||
|
|
||||||
|
if ((n > 1) && (!listening))
|
||||||
|
Cbuf_AddText ("listen 1\n");
|
||||||
|
|
||||||
|
svs.maxclients = n;
|
||||||
|
if (n == 1)
|
||||||
|
{
|
||||||
|
Cvar_Set ("deathmatch", "0");
|
||||||
|
Cvar_Set ("coop", "0");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (coop.value)
|
||||||
|
Cvar_Set ("deathmatch", "0");
|
||||||
|
else
|
||||||
|
Cvar_Set ("deathmatch", "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void NET_Port_f (void)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (Cmd_Argc () != 2)
|
||||||
|
{
|
||||||
|
Con_Printf ("\"port\" is \"%u\"\n", net_hostport);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = Q_atoi(Cmd_Argv(1));
|
||||||
|
if (n < 1 || n > 65534)
|
||||||
|
{
|
||||||
|
Con_Printf ("Bad value, must be between 1 and 65534\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULTnet_hostport = n;
|
||||||
|
net_hostport = n;
|
||||||
|
|
||||||
|
if (listening)
|
||||||
|
{
|
||||||
|
// force a change to the new port
|
||||||
|
Cbuf_AddText ("listen 0\n");
|
||||||
|
Cbuf_AddText ("listen 1\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintSlistHeader(void)
|
||||||
|
{
|
||||||
|
Con_Printf("Server Map Users\n");
|
||||||
|
Con_Printf("--------------- --------------- -----\n");
|
||||||
|
slistLastShown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintSlist(void)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (n = slistLastShown; n < hostCacheCount; n++)
|
||||||
|
{
|
||||||
|
if (hostcache[n].maxusers)
|
||||||
|
Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers);
|
||||||
|
else
|
||||||
|
Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map);
|
||||||
|
}
|
||||||
|
slistLastShown = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintSlistTrailer(void)
|
||||||
|
{
|
||||||
|
if (hostCacheCount)
|
||||||
|
Con_Printf("== end list ==\n\n");
|
||||||
|
else
|
||||||
|
Con_Printf("No Quake servers found.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NET_Slist_f (void)
|
||||||
|
{
|
||||||
|
if (slistInProgress)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (! slistSilent)
|
||||||
|
{
|
||||||
|
Con_Printf("Looking for Quake servers...\n");
|
||||||
|
PrintSlistHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
slistInProgress = true;
|
||||||
|
slistStartTime = Sys_FloatTime();
|
||||||
|
|
||||||
|
SchedulePollProcedure(&slistSendProcedure, 0.0);
|
||||||
|
SchedulePollProcedure(&slistPollProcedure, 0.1);
|
||||||
|
|
||||||
|
hostCacheCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Slist_Send(void)
|
||||||
|
{
|
||||||
|
for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
|
||||||
|
{
|
||||||
|
if (!slistLocal && net_driverlevel == 0)
|
||||||
|
continue;
|
||||||
|
if (net_drivers[net_driverlevel].initialized == false)
|
||||||
|
continue;
|
||||||
|
dfunc.SearchForHosts (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Sys_FloatTime() - slistStartTime) < 0.5)
|
||||||
|
SchedulePollProcedure(&slistSendProcedure, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Slist_Poll(void)
|
||||||
|
{
|
||||||
|
for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
|
||||||
|
{
|
||||||
|
if (!slistLocal && net_driverlevel == 0)
|
||||||
|
continue;
|
||||||
|
if (net_drivers[net_driverlevel].initialized == false)
|
||||||
|
continue;
|
||||||
|
dfunc.SearchForHosts (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! slistSilent)
|
||||||
|
PrintSlist();
|
||||||
|
|
||||||
|
if ((Sys_FloatTime() - slistStartTime) < 1.5)
|
||||||
|
{
|
||||||
|
SchedulePollProcedure(&slistPollProcedure, 0.1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! slistSilent)
|
||||||
|
PrintSlistTrailer();
|
||||||
|
slistInProgress = false;
|
||||||
|
slistSilent = false;
|
||||||
|
slistLocal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
NET_Connect
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
|
||||||
|
int hostCacheCount = 0;
|
||||||
|
hostcache_t hostcache[HOSTCACHESIZE];
|
||||||
|
|
||||||
|
qsocket_t *NET_Connect (char *host)
|
||||||
|
{
|
||||||
|
qsocket_t *ret;
|
||||||
|
int n;
|
||||||
|
int numdrivers = net_numdrivers;
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
if (host && *host == 0)
|
||||||
|
host = NULL;
|
||||||
|
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
if (Q_strcasecmp (host, "local") == 0)
|
||||||
|
{
|
||||||
|
numdrivers = 1;
|
||||||
|
goto JustDoIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostCacheCount)
|
||||||
|
{
|
||||||
|
for (n = 0; n < hostCacheCount; n++)
|
||||||
|
if (Q_strcasecmp (host, hostcache[n].name) == 0)
|
||||||
|
{
|
||||||
|
host = hostcache[n].cname;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (n < hostCacheCount)
|
||||||
|
goto JustDoIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slistSilent = host ? true : false;
|
||||||
|
NET_Slist_f ();
|
||||||
|
|
||||||
|
while(slistInProgress)
|
||||||
|
NET_Poll();
|
||||||
|
|
||||||
|
if (host == NULL)
|
||||||
|
{
|
||||||
|
if (hostCacheCount != 1)
|
||||||
|
return NULL;
|
||||||
|
host = hostcache[0].cname;
|
||||||
|
Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostCacheCount)
|
||||||
|
for (n = 0; n < hostCacheCount; n++)
|
||||||
|
if (Q_strcasecmp (host, hostcache[n].name) == 0)
|
||||||
|
{
|
||||||
|
host = hostcache[n].cname;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
JustDoIt:
|
||||||
|
for (net_driverlevel=0 ; net_driverlevel<numdrivers; net_driverlevel++)
|
||||||
|
{
|
||||||
|
if (net_drivers[net_driverlevel].initialized == false)
|
||||||
|
continue;
|
||||||
|
ret = dfunc.Connect (host);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
Con_Printf("\n");
|
||||||
|
PrintSlistHeader();
|
||||||
|
PrintSlist();
|
||||||
|
PrintSlistTrailer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
NET_CheckNewConnections
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
double time;
|
||||||
|
int op;
|
||||||
|
long session;
|
||||||
|
} vcrConnect;
|
||||||
|
|
||||||
|
qsocket_t *NET_CheckNewConnections (void)
|
||||||
|
{
|
||||||
|
qsocket_t *ret;
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
|
||||||
|
{
|
||||||
|
if (net_drivers[net_driverlevel].initialized == false)
|
||||||
|
continue;
|
||||||
|
if (net_driverlevel && listening == false)
|
||||||
|
continue;
|
||||||
|
ret = dfunc.CheckNewConnections ();
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrConnect.time = host_time;
|
||||||
|
vcrConnect.op = VCR_OP_CONNECT;
|
||||||
|
vcrConnect.session = (long)ret;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect));
|
||||||
|
Sys_FileWrite (vcrFile, ret->address, NET_NAMELEN);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrConnect.time = host_time;
|
||||||
|
vcrConnect.op = VCR_OP_CONNECT;
|
||||||
|
vcrConnect.session = 0;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrConnect, sizeof(vcrConnect));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===================
|
||||||
|
NET_Close
|
||||||
|
===================
|
||||||
|
*/
|
||||||
|
void NET_Close (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
if (!sock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sock->disconnected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
// call the driver_Close function
|
||||||
|
sfunc.Close (sock);
|
||||||
|
|
||||||
|
NET_FreeQSocket(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
NET_GetMessage
|
||||||
|
|
||||||
|
If there is a complete message, return it in net_message
|
||||||
|
|
||||||
|
returns 0 if no data is waiting
|
||||||
|
returns 1 if a message was received
|
||||||
|
returns -1 if connection is invalid
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
double time;
|
||||||
|
int op;
|
||||||
|
long session;
|
||||||
|
int ret;
|
||||||
|
int len;
|
||||||
|
} vcrGetMessage;
|
||||||
|
|
||||||
|
extern void PrintStats(qsocket_t *s);
|
||||||
|
|
||||||
|
int NET_GetMessage (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sock->disconnected)
|
||||||
|
{
|
||||||
|
Con_Printf("NET_GetMessage: disconnected socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
ret = sfunc.QGetMessage(sock);
|
||||||
|
|
||||||
|
// see if this connection has timed out
|
||||||
|
if (ret == 0 && sock->driver)
|
||||||
|
{
|
||||||
|
if (net_time - sock->lastMessageTime > net_messagetimeout.value)
|
||||||
|
{
|
||||||
|
NET_Close(sock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
if (sock->driver)
|
||||||
|
{
|
||||||
|
sock->lastMessageTime = net_time;
|
||||||
|
if (ret == 1)
|
||||||
|
messagesReceived++;
|
||||||
|
else if (ret == 2)
|
||||||
|
unreliableMessagesReceived++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrGetMessage.time = host_time;
|
||||||
|
vcrGetMessage.op = VCR_OP_GETMESSAGE;
|
||||||
|
vcrGetMessage.session = (long)sock;
|
||||||
|
vcrGetMessage.ret = ret;
|
||||||
|
vcrGetMessage.len = net_message.cursize;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrGetMessage, 24);
|
||||||
|
Sys_FileWrite (vcrFile, net_message.data, net_message.cursize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrGetMessage.time = host_time;
|
||||||
|
vcrGetMessage.op = VCR_OP_GETMESSAGE;
|
||||||
|
vcrGetMessage.session = (long)sock;
|
||||||
|
vcrGetMessage.ret = ret;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrGetMessage, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
NET_SendMessage
|
||||||
|
|
||||||
|
Try to send a complete length+message unit over the reliable stream.
|
||||||
|
returns 0 if the message cannot be delivered reliably, but the connection
|
||||||
|
is still considered valid
|
||||||
|
returns 1 if the message was sent properly
|
||||||
|
returns -1 if the connection died
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
double time;
|
||||||
|
int op;
|
||||||
|
long session;
|
||||||
|
int r;
|
||||||
|
} vcrSendMessage;
|
||||||
|
|
||||||
|
int NET_SendMessage (qsocket_t *sock, sizebuf_t *data)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sock->disconnected)
|
||||||
|
{
|
||||||
|
Con_Printf("NET_SendMessage: disconnected socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
r = sfunc.QSendMessage(sock, data);
|
||||||
|
if (r == 1 && sock->driver)
|
||||||
|
messagesSent++;
|
||||||
|
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrSendMessage.time = host_time;
|
||||||
|
vcrSendMessage.op = VCR_OP_SENDMESSAGE;
|
||||||
|
vcrSendMessage.session = (long)sock;
|
||||||
|
vcrSendMessage.r = r;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sock->disconnected)
|
||||||
|
{
|
||||||
|
Con_Printf("NET_SendMessage: disconnected socket\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
r = sfunc.SendUnreliableMessage(sock, data);
|
||||||
|
if (r == 1 && sock->driver)
|
||||||
|
unreliableMessagesSent++;
|
||||||
|
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrSendMessage.time = host_time;
|
||||||
|
vcrSendMessage.op = VCR_OP_SENDMESSAGE;
|
||||||
|
vcrSendMessage.session = (long)sock;
|
||||||
|
vcrSendMessage.r = r;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
NET_CanSendMessage
|
||||||
|
|
||||||
|
Returns true or false if the given qsocket can currently accept a
|
||||||
|
message to be transmitted.
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
qboolean NET_CanSendMessage (qsocket_t *sock)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!sock)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (sock->disconnected)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
r = sfunc.CanSendMessage(sock);
|
||||||
|
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
vcrSendMessage.time = host_time;
|
||||||
|
vcrSendMessage.op = VCR_OP_CANSENDMESSAGE;
|
||||||
|
vcrSendMessage.session = (long)sock;
|
||||||
|
vcrSendMessage.r = r;
|
||||||
|
Sys_FileWrite (vcrFile, &vcrSendMessage, 20);
|
||||||
|
}
|
||||||
|
//Con_Printf("Cansend = %i \n",r);//blubs : this is why it doesn't send the next signonreply
|
||||||
|
//return r; //blubs, not sure if this will fuck us up later
|
||||||
|
//if(r != 1)
|
||||||
|
// Con_Printf("Error, couldn't send msg, r:%i\n",r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int NET_SendToAll(sizebuf_t *data, int blocktime)
|
||||||
|
{
|
||||||
|
double start;
|
||||||
|
int i;
|
||||||
|
int count = 0;
|
||||||
|
qboolean state1 [MAX_SCOREBOARD];
|
||||||
|
qboolean state2 [MAX_SCOREBOARD];
|
||||||
|
|
||||||
|
for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
|
||||||
|
{
|
||||||
|
if (!host_client->netconnection)
|
||||||
|
continue;
|
||||||
|
if (host_client->active)
|
||||||
|
{
|
||||||
|
if (host_client->netconnection->driver == 0)
|
||||||
|
{
|
||||||
|
NET_SendMessage(host_client->netconnection, data);
|
||||||
|
state1[i] = true;
|
||||||
|
state2[i] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
state1[i] = false;
|
||||||
|
state2[i] = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state1[i] = true;
|
||||||
|
state2[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = Sys_FloatTime();
|
||||||
|
while (count)
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
|
||||||
|
{
|
||||||
|
if (! state1[i])
|
||||||
|
{
|
||||||
|
if (NET_CanSendMessage (host_client->netconnection))
|
||||||
|
{
|
||||||
|
state1[i] = true;
|
||||||
|
NET_SendMessage(host_client->netconnection, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NET_GetMessage (host_client->netconnection);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! state2[i])
|
||||||
|
{
|
||||||
|
if (NET_CanSendMessage (host_client->netconnection))
|
||||||
|
{
|
||||||
|
state2[i] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NET_GetMessage (host_client->netconnection);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Sys_FloatTime() - start) > blocktime)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
NET_Init
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
|
||||||
|
void NET_Init (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int controlSocket;
|
||||||
|
qsocket_t *s;
|
||||||
|
|
||||||
|
if (COM_CheckParm("-playback"))
|
||||||
|
{
|
||||||
|
net_numdrivers = 1;
|
||||||
|
net_drivers[0].Init = VCR_Init;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COM_CheckParm("-record"))
|
||||||
|
recording = true;
|
||||||
|
|
||||||
|
i = COM_CheckParm ("-port");
|
||||||
|
if (!i)
|
||||||
|
i = COM_CheckParm ("-udpport");
|
||||||
|
if (!i)
|
||||||
|
i = COM_CheckParm ("-ipxport");
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (i < com_argc-1)
|
||||||
|
DEFAULTnet_hostport = Q_atoi (com_argv[i+1]);
|
||||||
|
else
|
||||||
|
Sys_Error ("NET_Init: you must specify a number after -port");
|
||||||
|
}
|
||||||
|
net_hostport = DEFAULTnet_hostport;
|
||||||
|
|
||||||
|
if (COM_CheckParm("-listen") || cls.state == ca_dedicated)
|
||||||
|
listening = true;
|
||||||
|
net_numsockets = svs.maxclientslimit;
|
||||||
|
if (cls.state != ca_dedicated)
|
||||||
|
net_numsockets++;
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
for (i = 0; i < net_numsockets; i++)
|
||||||
|
{
|
||||||
|
s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket");
|
||||||
|
s->next = net_freeSockets;
|
||||||
|
net_freeSockets = s;
|
||||||
|
s->disconnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate space for network message buffer
|
||||||
|
SZ_Alloc (&net_message, NET_MAXMESSAGE);
|
||||||
|
|
||||||
|
Cvar_RegisterVariable (&net_messagetimeout);
|
||||||
|
Cvar_RegisterVariable (&hostname);
|
||||||
|
Cvar_RegisterVariable (&config_com_port);
|
||||||
|
Cvar_RegisterVariable (&config_com_irq);
|
||||||
|
Cvar_RegisterVariable (&config_com_baud);
|
||||||
|
Cvar_RegisterVariable (&config_com_modem);
|
||||||
|
Cvar_RegisterVariable (&config_modem_dialtype);
|
||||||
|
Cvar_RegisterVariable (&config_modem_clear);
|
||||||
|
Cvar_RegisterVariable (&config_modem_init);
|
||||||
|
Cvar_RegisterVariable (&config_modem_hangup);
|
||||||
|
|
||||||
|
if(!host_initialized)
|
||||||
|
{
|
||||||
|
Cmd_AddCommand ("slist", NET_Slist_f);
|
||||||
|
Cmd_AddCommand ("listen", NET_Listen_f);
|
||||||
|
Cmd_AddCommand ("maxplayers", MaxPlayers_f);
|
||||||
|
Cmd_AddCommand ("port", NET_Port_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize all the drivers
|
||||||
|
for (net_driverlevel=0 ; net_driverlevel<net_numdrivers ; net_driverlevel++)
|
||||||
|
{
|
||||||
|
controlSocket = net_drivers[net_driverlevel].Init();
|
||||||
|
if (controlSocket == -1)
|
||||||
|
continue;
|
||||||
|
net_drivers[net_driverlevel].initialized = true;
|
||||||
|
net_drivers[net_driverlevel].controlSock = controlSocket;
|
||||||
|
if (listening)
|
||||||
|
net_drivers[net_driverlevel].Listen (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*my_ipx_address)
|
||||||
|
Con_DPrintf("IPX address %s\n", my_ipx_address);
|
||||||
|
if (*my_tcpip_address)
|
||||||
|
Con_DPrintf("TCP/IP address %s\n", my_tcpip_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
NET_Shutdown
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
|
||||||
|
void NET_Shutdown (void)
|
||||||
|
{
|
||||||
|
qsocket_t *sock;
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
for (sock = net_activeSockets; sock; sock = sock->next)
|
||||||
|
NET_Close(sock);
|
||||||
|
|
||||||
|
//
|
||||||
|
// shutdown the drivers
|
||||||
|
//
|
||||||
|
for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++)
|
||||||
|
{
|
||||||
|
if (net_drivers[net_driverlevel].initialized == true)
|
||||||
|
{
|
||||||
|
net_drivers[net_driverlevel].Shutdown ();
|
||||||
|
net_drivers[net_driverlevel].initialized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vcrFile != -1)
|
||||||
|
{
|
||||||
|
Con_Printf ("Closing vcrfile.\n");
|
||||||
|
Sys_FileClose(vcrFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PollProcedure *pollProcedureList = NULL;
|
||||||
|
|
||||||
|
void NET_Poll(void)
|
||||||
|
{
|
||||||
|
PollProcedure *pp;
|
||||||
|
qboolean useModem;
|
||||||
|
|
||||||
|
if (!configRestored)
|
||||||
|
{
|
||||||
|
if (serialAvailable)
|
||||||
|
{
|
||||||
|
if (config_com_modem.value == 1.0)
|
||||||
|
useModem = true;
|
||||||
|
else
|
||||||
|
useModem = false;
|
||||||
|
SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem);
|
||||||
|
SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string);
|
||||||
|
}
|
||||||
|
configRestored = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetNetTime();
|
||||||
|
|
||||||
|
for (pp = pollProcedureList; pp; pp = pp->next)
|
||||||
|
{
|
||||||
|
if (pp->nextTime > net_time)
|
||||||
|
break;
|
||||||
|
pollProcedureList = pp->next;
|
||||||
|
pp->procedure(pp->arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SchedulePollProcedure(PollProcedure *proc, double timeOffset)
|
||||||
|
{
|
||||||
|
PollProcedure *pp, *prev;
|
||||||
|
|
||||||
|
proc->nextTime = Sys_FloatTime() + timeOffset;
|
||||||
|
for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next)
|
||||||
|
{
|
||||||
|
if (pp->nextTime >= proc->nextTime)
|
||||||
|
break;
|
||||||
|
prev = pp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev == NULL)
|
||||||
|
{
|
||||||
|
proc->next = pollProcedureList;
|
||||||
|
pollProcedureList = proc;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc->next = pp;
|
||||||
|
prev->next = proc;
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue