mirror of
https://github.com/DrBeef/QVR.git
synced 2024-11-21 19:41:01 +00:00
Initial Commit of Source
This commit is contained in:
parent
d5460eaba0
commit
90d0c76d59
242 changed files with 208887 additions and 0 deletions
17
.gitattributes
vendored
Normal file
17
.gitattributes
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
61
.gitignore
vendored
Normal file
61
.gitignore
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
||||
# OSX
|
||||
# =========================
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
# build files
|
||||
*.o
|
||||
*.d
|
||||
|
||||
#binaries
|
||||
*.so
|
||||
|
||||
#files created by build
|
||||
*.apk
|
||||
*.ap_
|
||||
*.class
|
||||
*.log
|
||||
bin/*
|
||||
gen/*
|
||||
.idea/*
|
||||
.gradle/*
|
19
QVR.iml
Normal file
19
QVR.iml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="QVR" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
92
app/app.iml
Normal file
92
app/app.iml
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="QVR" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateDebugAndroidTestSources</task>
|
||||
<task>generateDebugSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 16 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="cardboard" level="project" />
|
||||
</component>
|
||||
</module>
|
25
app/build.gradle
Normal file
25
app/build.gradle
Normal file
|
@ -0,0 +1,25 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 16
|
||||
buildToolsVersion '19.1.0'
|
||||
defaultConfig {
|
||||
applicationId "com.drbeef.qvr"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 19
|
||||
versionCode 1
|
||||
versionName '1.0.0'
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
}
|
117
app/jni/Android.mk
Normal file
117
app/jni/Android.mk
Normal file
|
@ -0,0 +1,117 @@
|
|||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
#--------------------------------------------------------
|
||||
# libquakecardboard.so
|
||||
#--------------------------------------------------------
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := qvr
|
||||
LOCAL_CFLAGS := -std=c99
|
||||
LOCAL_SRC_FILES := QVR.c
|
||||
LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lEGL # include default libraries
|
||||
|
||||
# CD objects
|
||||
SRC_NOCD=cd_null.c
|
||||
|
||||
SRC_SND_COMMON=snd_main.c snd_mem.c snd_mix.c snd_ogg.c snd_wav.c snd_modplug.c
|
||||
|
||||
|
||||
|
||||
###### Common objects and flags #####
|
||||
|
||||
# Common objects
|
||||
SRC_COMMON= \
|
||||
bih.c \
|
||||
cap_avi.c \
|
||||
cap_ogg.c \
|
||||
cd_shared.c \
|
||||
crypto.c \
|
||||
cl_collision.c \
|
||||
cl_demo.c \
|
||||
cl_dyntexture.c \
|
||||
cl_input.c \
|
||||
cl_main.c \
|
||||
cl_parse.c \
|
||||
cl_particles.c \
|
||||
cl_screen.c \
|
||||
cl_video.c \
|
||||
clvm_cmds.c \
|
||||
cmd.c \
|
||||
collision.c \
|
||||
common.c \
|
||||
console.c \
|
||||
csprogs.c \
|
||||
curves.c \
|
||||
cvar.c \
|
||||
dpsoftrast.c \
|
||||
dpvsimpledecode.c \
|
||||
filematch.c \
|
||||
fractalnoise.c \
|
||||
fs.c \
|
||||
ft2.c \
|
||||
utf8lib.c \
|
||||
gl_backend.c \
|
||||
gl_draw.c \
|
||||
gl_rmain.c \
|
||||
gl_rsurf.c \
|
||||
gl_textures.c \
|
||||
hmac.c \
|
||||
host.c \
|
||||
host_cmd.c \
|
||||
image.c \
|
||||
image_png.c \
|
||||
jpeg.c \
|
||||
keys.c \
|
||||
lhnet.c \
|
||||
libcurl.c \
|
||||
mathlib.c \
|
||||
matrixlib.c \
|
||||
mdfour.c \
|
||||
menu.c \
|
||||
meshqueue.c \
|
||||
mod_skeletal_animatevertices_sse.c \
|
||||
mod_skeletal_animatevertices_generic.c \
|
||||
model_alias.c \
|
||||
model_brush.c \
|
||||
model_shared.c \
|
||||
model_sprite.c \
|
||||
mvm_cmds.c \
|
||||
netconn.c \
|
||||
palette.c \
|
||||
polygon.c \
|
||||
portals.c \
|
||||
protocol.c \
|
||||
prvm_cmds.c \
|
||||
prvm_edict.c \
|
||||
prvm_exec.c \
|
||||
r_explosion.c \
|
||||
r_lerpanim.c \
|
||||
r_lightning.c \
|
||||
r_modules.c \
|
||||
r_shadow.c \
|
||||
r_sky.c \
|
||||
r_sprites.c \
|
||||
sbar.c \
|
||||
snprintf.c \
|
||||
sv_demo.c \
|
||||
sv_main.c \
|
||||
sv_move.c \
|
||||
sv_phys.c \
|
||||
sv_user.c \
|
||||
svbsp.c \
|
||||
svvm_cmds.c \
|
||||
sys_shared.c \
|
||||
vid_shared.c \
|
||||
view.c \
|
||||
wad.c \
|
||||
world.c \
|
||||
zone.c
|
||||
|
||||
|
||||
SRC_ANDROID= builddate.c sys_linux.c vid_android.c thread_pthread.c snd_android.c $(SRC_SND_COMMON) $(SRC_NOCD) $(SRC_COMMON)
|
||||
|
||||
LOCAL_SRC_FILES += $(SRC_ANDROID)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
22
app/jni/Application.mk
Normal file
22
app/jni/Application.mk
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Common build settings for all VR apps
|
||||
|
||||
# This needs to be defined to get the right header directories for egl / etc
|
||||
APP_PLATFORM := android-16
|
||||
|
||||
APP_ABI := armeabi-v7a
|
||||
|
||||
# Statically link the GNU STL. This may not be safe for multi-so libraries but
|
||||
# we don't know of any problems yet.
|
||||
APP_STL := gnustl_static
|
||||
|
||||
# Make sure every shared lib includes a .note.gnu.build-id header, for crash reporting
|
||||
APP_LDFLAGS := -Wl,--build-id
|
||||
|
||||
# Explicitly use GCC 4.8 as our toolchain. This is the 32-bit default as of
|
||||
# r10d but versions as far back as r9d have 4.8. The previous default, 4.6, is
|
||||
# deprecated as of r10c.
|
||||
NDK_TOOLCHAIN_VERSION := 4.8
|
||||
|
||||
# Define the directories for $(import-module, ...) to look in
|
||||
ROOT_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||
NDK_MODULE_PATH :=
|
340
app/jni/COPYING
Normal file
340
app/jni/COPYING
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
449
app/jni/QVR.c
Normal file
449
app/jni/QVR.c
Normal file
|
@ -0,0 +1,449 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <android/log.h>
|
||||
#include <android/native_window_jni.h> // for native window JNI
|
||||
#include <android/input.h>
|
||||
|
||||
#include <qtypes.h>
|
||||
#include <quakedef.h>
|
||||
#include <menu.h>
|
||||
#include <cvar.h>
|
||||
|
||||
//All the functionality we link to in the DarkPlaces Engine implementation
|
||||
extern void QC_BeginFrame();
|
||||
extern void QC_DrawFrame(int eye, int x, int y);
|
||||
extern void QC_EndFrame();
|
||||
extern void QC_GetAudio();
|
||||
extern void QC_KeyEvent(int state,int key,int character);
|
||||
extern void QC_MoveEvent(float yaw, float pitch, float roll);
|
||||
extern void QC_SetCallbacks(void *init_audio, void *write_audio);
|
||||
extern void QC_SetResolution(int width, int height);
|
||||
extern void QC_Analog(int enable,float x,float y);
|
||||
extern void QC_MotionEvent(float delta, float dx, float dy);
|
||||
extern int main (int argc, char **argv);
|
||||
|
||||
extern qboolean vrMode;
|
||||
extern int bigScreen;
|
||||
extern int gameAssetsDownloadStatus;
|
||||
|
||||
extern cvar_t cl_autocentreoffset;
|
||||
extern cvar_t v_eyebufferresolution;
|
||||
|
||||
static JavaVM *jVM;
|
||||
static jobject audioBuffer=0;
|
||||
static jobject audioCallbackObj=0;
|
||||
|
||||
jmethodID android_initAudio;
|
||||
jmethodID android_writeAudio;
|
||||
jmethodID android_pauseAudio;
|
||||
jmethodID android_resumeAudio;
|
||||
jmethodID android_terminateAudio;
|
||||
|
||||
static jobject quakeCallbackObj=0;
|
||||
jmethodID android_BigScreenMode;
|
||||
jmethodID android_SwitchVRMode;
|
||||
jmethodID android_SwitchStereoMode;
|
||||
jmethodID android_Exit;
|
||||
|
||||
void jni_initAudio(void *buffer, int size)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
(*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4);
|
||||
tmp = (*env)->NewDirectByteBuffer(env, buffer, size);
|
||||
audioBuffer = (jobject)(*env)->NewGlobalRef(env, tmp);
|
||||
return (*env)->CallVoidMethod(env, audioCallbackObj, android_initAudio, size);
|
||||
}
|
||||
|
||||
void jni_writeAudio(int offset, int length)
|
||||
{
|
||||
if (audioBuffer==0) return;
|
||||
JNIEnv *env;
|
||||
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
|
||||
}
|
||||
(*env)->CallVoidMethod(env, audioCallbackObj, android_writeAudio, audioBuffer, offset, length);
|
||||
}
|
||||
|
||||
void jni_pauseAudio()
|
||||
{
|
||||
if (audioBuffer==0) return;
|
||||
JNIEnv *env;
|
||||
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
|
||||
}
|
||||
(*env)->CallVoidMethod(env, audioCallbackObj, android_pauseAudio);
|
||||
}
|
||||
|
||||
void jni_resumeAudio()
|
||||
{
|
||||
if (audioBuffer==0) return;
|
||||
JNIEnv *env;
|
||||
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
|
||||
}
|
||||
(*env)->CallVoidMethod(env, audioCallbackObj, android_resumeAudio);
|
||||
}
|
||||
|
||||
void jni_terminateAudio()
|
||||
{
|
||||
if (audioBuffer==0) return;
|
||||
JNIEnv *env;
|
||||
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
|
||||
}
|
||||
(*env)->CallVoidMethod(env, audioCallbackObj, android_terminateAudio);
|
||||
}
|
||||
|
||||
|
||||
void jni_BigScreenMode(int mode)
|
||||
{
|
||||
JNIEnv *env;
|
||||
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
|
||||
}
|
||||
(*env)->CallVoidMethod(env, quakeCallbackObj, android_BigScreenMode, mode);
|
||||
}
|
||||
|
||||
|
||||
void jni_SwitchStereoMode(int mode)
|
||||
{
|
||||
JNIEnv *env;
|
||||
if (((*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
(*jVM)->AttachCurrentThread(jVM,&env, NULL);
|
||||
}
|
||||
(*env)->CallVoidMethod(env, quakeCallbackObj, android_SwitchStereoMode, mode);
|
||||
}
|
||||
|
||||
void jni_SwitchVRMode(int mode)
|
||||
{
|
||||
//Force headtracking on / off depending on whether we are using VR mode
|
||||
//user must then change to their preference
|
||||
headtracking = vrMode > 0;
|
||||
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
(*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4);
|
||||
(*env)->CallVoidMethod(env, quakeCallbackObj, android_SwitchVRMode, mode);
|
||||
}
|
||||
|
||||
void jni_Exit()
|
||||
{
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
(*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4);
|
||||
(*env)->CallVoidMethod(env, quakeCallbackObj, android_Exit);
|
||||
}
|
||||
|
||||
//Retain the folder we are using
|
||||
char *strGameFolder = NULL;
|
||||
|
||||
//Timing stuff for joypad control
|
||||
static long oldtime=0;
|
||||
long delta=0;
|
||||
float last_joystick_x=0;
|
||||
float last_joystick_y=0;
|
||||
|
||||
int curtime;
|
||||
int Sys_Milliseconds (void)
|
||||
{
|
||||
struct timeval tp;
|
||||
struct timezone tzp;
|
||||
static int secbase;
|
||||
|
||||
gettimeofday(&tp, &tzp);
|
||||
|
||||
if (!secbase)
|
||||
{
|
||||
secbase = tp.tv_sec;
|
||||
return tp.tv_usec/1000;
|
||||
}
|
||||
|
||||
curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
int returnvalue = -1;
|
||||
void QC_exit(int exitCode)
|
||||
{
|
||||
returnvalue = exitCode;
|
||||
Host_Shutdown();
|
||||
jni_Exit();
|
||||
}
|
||||
|
||||
vec3_t hmdorientation;
|
||||
|
||||
int JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jVM = vm;
|
||||
if((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
static void UnEscapeQuotes( char *arg )
|
||||
{
|
||||
char *last = NULL;
|
||||
while( *arg ) {
|
||||
if( *arg == '"' && *last == '\\' ) {
|
||||
char *c_curr = arg;
|
||||
char *c_last = last;
|
||||
while( *c_curr ) {
|
||||
*c_last = *c_curr;
|
||||
c_last = c_curr;
|
||||
c_curr++;
|
||||
}
|
||||
*c_last = '\0';
|
||||
}
|
||||
last = arg;
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
|
||||
static int ParseCommandLine(char *cmdline, char **argv)
|
||||
{
|
||||
char *bufp;
|
||||
char *lastp = NULL;
|
||||
int argc, last_argc;
|
||||
argc = last_argc = 0;
|
||||
for ( bufp = cmdline; *bufp; ) {
|
||||
while ( isspace(*bufp) ) {
|
||||
++bufp;
|
||||
}
|
||||
if ( *bufp == '"' ) {
|
||||
++bufp;
|
||||
if ( *bufp ) {
|
||||
if ( argv ) {
|
||||
argv[argc] = bufp;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
while ( *bufp && ( *bufp != '"' || *lastp == '\\' ) ) {
|
||||
lastp = bufp;
|
||||
++bufp;
|
||||
}
|
||||
} else {
|
||||
if ( *bufp ) {
|
||||
if ( argv ) {
|
||||
argv[argc] = bufp;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
while ( *bufp && ! isspace(*bufp) ) {
|
||||
++bufp;
|
||||
}
|
||||
}
|
||||
if ( *bufp ) {
|
||||
if ( argv ) {
|
||||
*bufp = '\0';
|
||||
}
|
||||
++bufp;
|
||||
}
|
||||
if( argv && last_argc != argc ) {
|
||||
UnEscapeQuotes( argv[last_argc] );
|
||||
}
|
||||
last_argc = argc;
|
||||
}
|
||||
if ( argv ) {
|
||||
argv[argc] = NULL;
|
||||
}
|
||||
return(argc);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_setResolution( JNIEnv * env, jobject obj, int width, int height )
|
||||
{
|
||||
QC_SetResolution(width, height);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_initialise( JNIEnv * env, jobject obj, jstring gameFolder, jstring commandLineParams )
|
||||
{
|
||||
static qboolean quake_initialised = false;
|
||||
if (!quake_initialised)
|
||||
{
|
||||
jboolean iscopy;
|
||||
const char * folder = (*env)->GetStringUTFChars(env, gameFolder, &iscopy);
|
||||
chdir(folder);
|
||||
strGameFolder = strdup(folder);
|
||||
(*env)->ReleaseStringUTFChars(env, gameFolder, folder);
|
||||
|
||||
const char *arg = (*env)->GetStringUTFChars(env, commandLineParams, &iscopy);
|
||||
|
||||
char *cmdLine = NULL;
|
||||
if (arg && strlen(arg))
|
||||
{
|
||||
cmdLine = strdup(arg);
|
||||
}
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, commandLineParams, arg);
|
||||
|
||||
if (cmdLine)
|
||||
{
|
||||
char **argv;
|
||||
int argc=0;
|
||||
argv = malloc(sizeof(char*) * 255);
|
||||
argc = ParseCommandLine(strdup(cmdLine), argv);
|
||||
main(argc, argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
int argc =1; char *argv[] = { "quake" };
|
||||
main(argc, argv);
|
||||
}
|
||||
|
||||
//Start game with credits active
|
||||
MR_ToggleMenu(1);
|
||||
quake_initialised = true;
|
||||
}
|
||||
}
|
||||
|
||||
#define YAW 1
|
||||
#define PITCH 0
|
||||
#define ROLL 2
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onNewFrame( JNIEnv * env, jobject obj, float pitch, float yaw, float roll )
|
||||
{
|
||||
long t=Sys_Milliseconds();
|
||||
delta=t-oldtime;
|
||||
oldtime=t;
|
||||
if (delta>1000)
|
||||
delta=1000;
|
||||
|
||||
QC_MotionEvent(delta, last_joystick_x, last_joystick_y);
|
||||
|
||||
//Save orientation
|
||||
if (headtracking)
|
||||
{
|
||||
hmdorientation[YAW] = yaw;
|
||||
hmdorientation[PITCH] = pitch;
|
||||
hmdorientation[ROLL] = roll;
|
||||
}
|
||||
else
|
||||
{
|
||||
hmdorientation[YAW] = 0;
|
||||
hmdorientation[PITCH] = 0;
|
||||
hmdorientation[ROLL] = 0;
|
||||
|
||||
}
|
||||
|
||||
//Set move information
|
||||
QC_MoveEvent(hmdorientation[YAW], hmdorientation[PITCH], hmdorientation[ROLL]);
|
||||
|
||||
//Set everything up
|
||||
QC_BeginFrame();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onDrawEye( JNIEnv * env, jobject obj, int eye, int x, int y )
|
||||
{
|
||||
QC_DrawFrame(eye, x, y);
|
||||
|
||||
//const GLenum depthAttachment[1] = { GL_DEPTH_ATTACHMENT };
|
||||
//glInvalidateFramebuffer( GL_FRAMEBUFFER, 1, depthAttachment );
|
||||
//glFlush();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onFinishFrame( JNIEnv * env, jobject obj )
|
||||
{
|
||||
QC_EndFrame();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onSwitchVRMode( JNIEnv * env, jobject obj, int mode )
|
||||
{
|
||||
vrMode = mode;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onBigScreenMode( JNIEnv * env, jobject obj, int mode )
|
||||
{
|
||||
bigScreen = mode;
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL Java_com_drbeef_qvr_QVRJNILib_getCentreOffset( JNIEnv * env, jobject obj )
|
||||
{
|
||||
return cl_autocentreoffset.integer;
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL Java_com_drbeef_qvr_QVRJNILib_getEyeBufferResolution( JNIEnv * env, jobject obj )
|
||||
{
|
||||
return v_eyebufferresolution.integer;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_setCentreOffset( JNIEnv * env, jobject obj, int offset )
|
||||
{
|
||||
//This is called only by the calculator, so only set it if it is not already set (i.e. by user or a previous run)
|
||||
if (cl_autocentreoffset.integer == 0)
|
||||
Cvar_SetValueQuick (&cl_autocentreoffset, offset);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onKeyEvent( JNIEnv * env, jobject obj, int keyCode, int action, int character )
|
||||
{
|
||||
//Dispatch to quake
|
||||
QC_KeyEvent(action == AKEY_EVENT_ACTION_DOWN ? 1 : 0, keyCode, character);
|
||||
}
|
||||
|
||||
#define SOURCE_GAMEPAD 0x00000401
|
||||
#define SOURCE_JOYSTICK 0x01000010
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onTouchEvent( JNIEnv * env, jobject obj, int source, int action, float x, float y )
|
||||
{
|
||||
if (source == SOURCE_JOYSTICK || source == SOURCE_GAMEPAD)
|
||||
QC_Analog(true, x, y);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_onMotionEvent( JNIEnv * env, jobject obj, int source, int action, float x, float y )
|
||||
{
|
||||
if (source == SOURCE_JOYSTICK || source == SOURCE_GAMEPAD)
|
||||
{
|
||||
last_joystick_x=x;
|
||||
last_joystick_y=y;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_setCallbackObjects(JNIEnv *env, jclass c, jobject obj1, jobject obj2)
|
||||
{
|
||||
jclass audioCallbackClass;
|
||||
|
||||
(*jVM)->GetEnv(jVM, (void**) &env, JNI_VERSION_1_4);
|
||||
|
||||
audioCallbackObj = (jobject)(*env)->NewGlobalRef(env, obj1);
|
||||
audioCallbackClass = (*env)->GetObjectClass(env, audioCallbackObj);
|
||||
|
||||
android_initAudio = (*env)->GetMethodID(env,audioCallbackClass,"initAudio","(I)V");
|
||||
android_writeAudio = (*env)->GetMethodID(env,audioCallbackClass,"writeAudio","(Ljava/nio/ByteBuffer;II)V");
|
||||
android_pauseAudio = (*env)->GetMethodID(env,audioCallbackClass,"pauseAudio","()V");
|
||||
android_resumeAudio = (*env)->GetMethodID(env,audioCallbackClass,"resumeAudio","()V");
|
||||
android_terminateAudio = (*env)->GetMethodID(env,audioCallbackClass,"terminateAudio","()V");
|
||||
|
||||
|
||||
jclass quakeCallbackClass;
|
||||
|
||||
quakeCallbackObj = (jobject)(*env)->NewGlobalRef(env, obj2);
|
||||
quakeCallbackClass = (*env)->GetObjectClass(env, quakeCallbackObj);
|
||||
|
||||
android_BigScreenMode = (*env)->GetMethodID(env,quakeCallbackClass,"BigScreenMode","(I)V");
|
||||
android_SwitchVRMode = (*env)->GetMethodID(env,quakeCallbackClass,"SwitchVRMode","(I)V");
|
||||
android_SwitchStereoMode = (*env)->GetMethodID(env,quakeCallbackClass,"SwitchStereoMode","(I)V");
|
||||
android_Exit = (*env)->GetMethodID(env,quakeCallbackClass,"Exit","()V");
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_requestAudioData(JNIEnv *env, jclass c, jlong handle)
|
||||
{
|
||||
QC_GetAudio();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_qvr_QVRJNILib_setDownloadStatus( JNIEnv * env, jobject obj, int status )
|
||||
{
|
||||
gameAssetsDownloadStatus = status;
|
||||
}
|
11
app/jni/SDLMain.h
Normal file
11
app/jni/SDLMain.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
|
||||
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
|
||||
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
|
||||
|
||||
Feel free to customize this file to suit your needs
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface SDLMain : NSObject
|
||||
@end
|
216
app/jni/bih.c
Normal file
216
app/jni/bih.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
|
||||
// This code written in 2010 by Forest Hale (lordhavoc ghdigital com), and placed into public domain.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bih.h"
|
||||
|
||||
static int BIH_BuildNode(bih_t *bih, int numchildren, int *leaflist, float *totalmins, float *totalmaxs)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int longestaxis;
|
||||
int axis = 0;
|
||||
int nodenum;
|
||||
int front = 0;
|
||||
int back = 0;
|
||||
bih_node_t *node;
|
||||
bih_leaf_t *child;
|
||||
float splitdist;
|
||||
float d;
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
float size[3];
|
||||
float frontmins[3];
|
||||
float frontmaxs[3];
|
||||
float backmins[3];
|
||||
float backmaxs[3];
|
||||
// calculate bounds of children
|
||||
child = bih->leafs + leaflist[0];
|
||||
mins[0] = child->mins[0];
|
||||
mins[1] = child->mins[1];
|
||||
mins[2] = child->mins[2];
|
||||
maxs[0] = child->maxs[0];
|
||||
maxs[1] = child->maxs[1];
|
||||
maxs[2] = child->maxs[2];
|
||||
for (i = 1;i < numchildren;i++)
|
||||
{
|
||||
child = bih->leafs + leaflist[i];
|
||||
if (mins[0] > child->mins[0]) mins[0] = child->mins[0];
|
||||
if (mins[1] > child->mins[1]) mins[1] = child->mins[1];
|
||||
if (mins[2] > child->mins[2]) mins[2] = child->mins[2];
|
||||
if (maxs[0] < child->maxs[0]) maxs[0] = child->maxs[0];
|
||||
if (maxs[1] < child->maxs[1]) maxs[1] = child->maxs[1];
|
||||
if (maxs[2] < child->maxs[2]) maxs[2] = child->maxs[2];
|
||||
}
|
||||
size[0] = maxs[0] - mins[0];
|
||||
size[1] = maxs[1] - mins[1];
|
||||
size[2] = maxs[2] - mins[2];
|
||||
// provide bounds to caller
|
||||
totalmins[0] = mins[0];
|
||||
totalmins[1] = mins[1];
|
||||
totalmins[2] = mins[2];
|
||||
totalmaxs[0] = maxs[0];
|
||||
totalmaxs[1] = maxs[1];
|
||||
totalmaxs[2] = maxs[2];
|
||||
// if we run out of nodes it's the caller's fault, but don't crash
|
||||
if (bih->numnodes == bih->maxnodes)
|
||||
{
|
||||
if (!bih->error)
|
||||
bih->error = BIHERROR_OUT_OF_NODES;
|
||||
return 0;
|
||||
}
|
||||
nodenum = bih->numnodes++;
|
||||
node = bih->nodes + nodenum;
|
||||
// store bounds for node
|
||||
node->mins[0] = mins[0];
|
||||
node->mins[1] = mins[1];
|
||||
node->mins[2] = mins[2];
|
||||
node->maxs[0] = maxs[0];
|
||||
node->maxs[1] = maxs[1];
|
||||
node->maxs[2] = maxs[2];
|
||||
node->front = 0;
|
||||
node->back = 0;
|
||||
node->frontmin = 0;
|
||||
node->backmax = 0;
|
||||
memset(node->children, -1, sizeof(node->children));
|
||||
// check if there are few enough children to store an unordered node
|
||||
if (numchildren <= BIH_MAXUNORDEREDCHILDREN)
|
||||
{
|
||||
node->type = BIH_UNORDERED;
|
||||
for (j = 0;j < numchildren;j++)
|
||||
node->children[j] = leaflist[j];
|
||||
return nodenum;
|
||||
}
|
||||
// pick longest axis
|
||||
longestaxis = 0;
|
||||
if (size[0] < size[1]) longestaxis = 1;
|
||||
if (size[longestaxis] < size[2]) longestaxis = 2;
|
||||
// iterate possible split axis choices, starting with the longest axis, if
|
||||
// all fail it means all children have the same bounds and we simply split
|
||||
// the list in half because each node can only have two children.
|
||||
for (j = 0;j < 3;j++)
|
||||
{
|
||||
// pick an axis
|
||||
axis = (longestaxis + j) % 3;
|
||||
// sort children into front and back lists
|
||||
splitdist = (node->mins[axis] + node->maxs[axis]) * 0.5f;
|
||||
front = 0;
|
||||
back = 0;
|
||||
for (i = 0;i < numchildren;i++)
|
||||
{
|
||||
child = bih->leafs + leaflist[i];
|
||||
d = (child->mins[axis] + child->maxs[axis]) * 0.5f;
|
||||
if (d < splitdist)
|
||||
bih->leafsortscratch[back++] = leaflist[i];
|
||||
else
|
||||
leaflist[front++] = leaflist[i];
|
||||
}
|
||||
// now copy the back ones into the space made in the leaflist for them
|
||||
if (back)
|
||||
memcpy(leaflist + front, bih->leafsortscratch, back*sizeof(leaflist[0]));
|
||||
// if both sides have some children, it's good enough for us.
|
||||
if (front && back)
|
||||
break;
|
||||
}
|
||||
if (j == 3)
|
||||
{
|
||||
// somewhat common case: no good choice, divide children arbitrarily
|
||||
axis = 0;
|
||||
back = numchildren >> 1;
|
||||
front = numchildren - back;
|
||||
}
|
||||
|
||||
// we now have front and back children divided in leaflist...
|
||||
node->type = (bih_nodetype_t)((int)BIH_SPLITX + axis);
|
||||
node->front = BIH_BuildNode(bih, front, leaflist, frontmins, frontmaxs);
|
||||
node->frontmin = frontmins[axis];
|
||||
node->back = BIH_BuildNode(bih, back, leaflist + front, backmins, backmaxs);
|
||||
node->backmax = backmaxs[axis];
|
||||
return nodenum;
|
||||
}
|
||||
|
||||
int BIH_Build(bih_t *bih, int numleafs, bih_leaf_t *leafs, int maxnodes, bih_node_t *nodes, int *temp_leafsort, int *temp_leafsortscratch)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(bih, 0, sizeof(*bih));
|
||||
bih->numleafs = numleafs;
|
||||
bih->leafs = leafs;
|
||||
bih->leafsort = temp_leafsort;
|
||||
bih->leafsortscratch = temp_leafsortscratch;
|
||||
bih->numnodes = 0;
|
||||
bih->maxnodes = maxnodes;
|
||||
bih->nodes = nodes;
|
||||
|
||||
// clear things we intend to rebuild
|
||||
memset(bih->nodes, 0, sizeof(bih->nodes[0]) * bih->maxnodes);
|
||||
for (i = 0;i < bih->numleafs;i++)
|
||||
bih->leafsort[i] = i;
|
||||
|
||||
bih->rootnode = BIH_BuildNode(bih, bih->numleafs, bih->leafsort, bih->mins, bih->maxs);
|
||||
return bih->error;
|
||||
}
|
||||
|
||||
static void BIH_GetTriangleListForBox_Node(const bih_t *bih, int nodenum, int maxtriangles, int *trianglelist_idx, int *trianglelist_surf, int *numtrianglespointer, const float *mins, const float *maxs)
|
||||
{
|
||||
int axis;
|
||||
bih_node_t *node;
|
||||
bih_leaf_t *leaf;
|
||||
for(;;)
|
||||
{
|
||||
node = bih->nodes + nodenum;
|
||||
// check if this is an unordered node (which holds an array of leaf numbers)
|
||||
if (node->type == BIH_UNORDERED)
|
||||
{
|
||||
for (axis = 0;axis < BIH_MAXUNORDEREDCHILDREN && node->children[axis] >= 0;axis++)
|
||||
{
|
||||
leaf = bih->leafs + node->children[axis];
|
||||
if (mins[0] > leaf->maxs[0] || maxs[0] < leaf->mins[0]
|
||||
|| mins[1] > leaf->maxs[1] || maxs[1] < leaf->mins[1]
|
||||
|| mins[2] > leaf->maxs[2] || maxs[2] < leaf->mins[2])
|
||||
continue;
|
||||
switch(leaf->type)
|
||||
{
|
||||
case BIH_RENDERTRIANGLE:
|
||||
if (*numtrianglespointer >= maxtriangles)
|
||||
{
|
||||
++*numtrianglespointer; // so the caller can detect overflow
|
||||
break;
|
||||
}
|
||||
if(trianglelist_surf)
|
||||
trianglelist_surf[*numtrianglespointer] = leaf->surfaceindex;
|
||||
trianglelist_idx[*numtrianglespointer] = leaf->itemindex;
|
||||
++*numtrianglespointer;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// splitting node
|
||||
axis = node->type - BIH_SPLITX;
|
||||
if (mins[axis] < node->backmax)
|
||||
{
|
||||
if (maxs[axis] > node->frontmin)
|
||||
BIH_GetTriangleListForBox_Node(bih, node->front, maxtriangles, trianglelist_idx, trianglelist_surf, numtrianglespointer, mins, maxs);
|
||||
nodenum = node->back;
|
||||
continue;
|
||||
}
|
||||
if (maxs[axis] > node->frontmin)
|
||||
{
|
||||
nodenum = node->front;
|
||||
continue;
|
||||
}
|
||||
// fell between the child groups, nothing here
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int BIH_GetTriangleListForBox(const bih_t *bih, int maxtriangles, int *trianglelist_idx, int *trianglelist_surf, const float *mins, const float *maxs)
|
||||
{
|
||||
int numtriangles = 0;
|
||||
BIH_GetTriangleListForBox_Node(bih, bih->rootnode, maxtriangles, trianglelist_idx, trianglelist_surf, &numtriangles, mins, maxs);
|
||||
return numtriangles;
|
||||
}
|
91
app/jni/bih.h
Normal file
91
app/jni/bih.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
|
||||
// This code written in 2010 by Forest Hale (lordhavoc ghdigital com), and placed into public domain.
|
||||
|
||||
// Based on information in http://zach.in.tu-clausthal.de/papers/vrst02.html (in particular vrst02_boxtree.pdf)
|
||||
|
||||
#ifndef BIH_H
|
||||
#define BIH_H
|
||||
|
||||
#define BIH_MAXUNORDEREDCHILDREN 8
|
||||
|
||||
typedef enum biherror_e
|
||||
{
|
||||
BIHERROR_OK, // no error, be happy
|
||||
BIHERROR_OUT_OF_NODES // could not produce complete hierarchy, maxnodes too low (should be roughly half of numleafs)
|
||||
}
|
||||
biherror_t;
|
||||
|
||||
typedef enum bih_nodetype_e
|
||||
{
|
||||
BIH_SPLITX = 0,
|
||||
BIH_SPLITY = 1,
|
||||
BIH_SPLITZ = 2,
|
||||
BIH_UNORDERED = 3,
|
||||
}
|
||||
bih_nodetype_t;
|
||||
|
||||
typedef enum bih_leaftype_e
|
||||
{
|
||||
BIH_BRUSH = 4,
|
||||
BIH_COLLISIONTRIANGLE = 5,
|
||||
BIH_RENDERTRIANGLE = 6
|
||||
}
|
||||
bih_leaftype_t;
|
||||
|
||||
typedef struct bih_node_s
|
||||
{
|
||||
bih_nodetype_t type; // = BIH_SPLITX and similar values
|
||||
// TODO: store just one float for distance, and have BIH_SPLITMINX and BIH_SPLITMAXX distinctions, to reduce memory footprint and traversal time, as described in the paper (vrst02_boxtree.pdf)
|
||||
// TODO: move bounds data to parent node and remove it from leafs?
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
// node indexes of children (always > this node's index)
|
||||
int front;
|
||||
int back;
|
||||
// interval of children
|
||||
float frontmin; // children[0]
|
||||
float backmax; // children[1]
|
||||
// BIH_UNORDERED uses this for a list of leafindex (all >= 0), -1 = end of list
|
||||
int children[BIH_MAXUNORDEREDCHILDREN];
|
||||
}
|
||||
bih_node_t;
|
||||
|
||||
typedef struct bih_leaf_s
|
||||
{
|
||||
bih_leaftype_t type; // = BIH_BRUSH And similar values
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
// data past this point is generic and entirely up to the caller...
|
||||
int textureindex;
|
||||
int surfaceindex;
|
||||
int itemindex; // triangle or brush index
|
||||
}
|
||||
bih_leaf_t;
|
||||
|
||||
typedef struct bih_s
|
||||
{
|
||||
// permanent fields
|
||||
// leafs are constructed by caller before calling BIH_Build
|
||||
int numleafs;
|
||||
bih_leaf_t *leafs;
|
||||
// nodes are constructed by BIH_Build
|
||||
int numnodes;
|
||||
bih_node_t *nodes;
|
||||
int rootnode; // 0 if numnodes > 0, -1 otherwise
|
||||
// bounds calculated by BIH_Build
|
||||
float mins[3];
|
||||
float maxs[3];
|
||||
|
||||
// fields used only during BIH_Build:
|
||||
int maxnodes;
|
||||
int error; // set to a value if an error occurs in building (such as numnodes == maxnodes)
|
||||
int *leafsort;
|
||||
int *leafsortscratch;
|
||||
}
|
||||
bih_t;
|
||||
|
||||
int BIH_Build(bih_t *bih, int numleafs, bih_leaf_t *leafs, int maxnodes, bih_node_t *nodes, int *temp_leafsort, int *temp_leafsortscratch);
|
||||
|
||||
int BIH_GetTriangleListForBox(const bih_t *bih, int maxtriangles, int *trianglelist_idx, int *trianglelist_surf, const float *mins, const float *maxs);
|
||||
|
||||
#endif
|
321
app/jni/bspfile.h
Normal file
321
app/jni/bspfile.h
Normal file
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#define MAX_MAP_HULLS 16 // Q1BSP has 4, Hexen2 Q1BSP has 8, MCBSP has 16
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#define BSPVERSION 29
|
||||
|
||||
typedef struct lump_s
|
||||
{
|
||||
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 hullinfo_s
|
||||
{
|
||||
int filehulls;
|
||||
float hullsizes[MAX_MAP_HULLS][2][3];
|
||||
} hullinfo_t;
|
||||
|
||||
typedef struct mmodel_s
|
||||
{
|
||||
float mins[3], maxs[3];
|
||||
float origin[3];
|
||||
int headnode[MAX_MAP_HULLS];
|
||||
int visleafs; // not including the solid leaf 0
|
||||
int firstface, numfaces;
|
||||
} mmodel_t;
|
||||
|
||||
/*
|
||||
// WARNING: this struct does NOT match q1bsp's disk format because MAX_MAP_HULLS has been changed by Sajt's MCBSP code, this struct is only being used in memory as a result
|
||||
typedef struct dmodel_s
|
||||
{
|
||||
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 dheader_s
|
||||
{
|
||||
int version;
|
||||
lump_t lumps[HEADER_LUMPS];
|
||||
} dheader_t;
|
||||
|
||||
typedef struct dmiptexlump_s
|
||||
{
|
||||
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 dvertex_s
|
||||
{
|
||||
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 dplane_s
|
||||
{
|
||||
float normal[3];
|
||||
float dist;
|
||||
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
|
||||
} dplane_t;
|
||||
*/
|
||||
|
||||
|
||||
// contents values in Q1 maps
|
||||
#define CONTENTS_EMPTY -1
|
||||
#define CONTENTS_SOLID -2
|
||||
#define CONTENTS_WATER -3
|
||||
#define CONTENTS_SLIME -4
|
||||
#define CONTENTS_LAVA -5
|
||||
#define CONTENTS_SKY -6
|
||||
// these were #ifdef QUAKE2 in the quake source
|
||||
#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
|
||||
|
||||
//contents flags in Q2 maps
|
||||
#define CONTENTSQ2_SOLID 0x00000001 // an eye is never valid in a solid
|
||||
#define CONTENTSQ2_WINDOW 0x00000002 // translucent, but not watery
|
||||
#define CONTENTSQ2_AUX 0x00000004
|
||||
#define CONTENTSQ2_LAVA 0x00000008
|
||||
#define CONTENTSQ2_SLIME 0x00000010
|
||||
#define CONTENTSQ2_WATER 0x00000020
|
||||
#define CONTENTSQ2_MIST 0x00000040
|
||||
#define CONTENTSQ2_AREAPORTAL 0x00008000
|
||||
#define CONTENTSQ2_PLAYERCLIP 0x00010000
|
||||
#define CONTENTSQ2_MONSTERCLIP 0x00020000
|
||||
#define CONTENTSQ2_CURRENT_0 0x00040000
|
||||
#define CONTENTSQ2_CURRENT_90 0x00080000
|
||||
#define CONTENTSQ2_CURRENT_180 0x00100000
|
||||
#define CONTENTSQ2_CURRENT_270 0x00200000
|
||||
#define CONTENTSQ2_CURRENT_UP 0x00400000
|
||||
#define CONTENTSQ2_CURRENT_DOWN 0x00800000
|
||||
#define CONTENTSQ2_ORIGIN 0x01000000 // removed before bsping an entity
|
||||
#define CONTENTSQ2_MONSTER 0x02000000 // should never be on a brush, only in game
|
||||
#define CONTENTSQ2_DEADMONSTER 0x04000000
|
||||
#define CONTENTSQ2_DETAIL 0x08000000 // brushes to be added after vis leafs
|
||||
#define CONTENTSQ2_TRANSLUCENT 0x10000000 // auto set if any surface has trans
|
||||
#define CONTENTSQ2_LADDER 0x20000000
|
||||
|
||||
//contents flags in Q3 maps
|
||||
#define CONTENTSQ3_SOLID 0x00000001 // solid (opaque and transparent)
|
||||
#define CONTENTSQ3_LAVA 0x00000008 // lava
|
||||
#define CONTENTSQ3_SLIME 0x00000010 // slime
|
||||
#define CONTENTSQ3_WATER 0x00000020 // water
|
||||
#define CONTENTSQ3_FOG 0x00000040 // unused?
|
||||
#define CONTENTSQ3_AREAPORTAL 0x00008000 // areaportal (separates areas)
|
||||
#define CONTENTSQ3_PLAYERCLIP 0x00010000 // block players
|
||||
#define CONTENTSQ3_MONSTERCLIP 0x00020000 // block monsters
|
||||
#define CONTENTSQ3_TELEPORTER 0x00040000 // hint for Q3's bots
|
||||
#define CONTENTSQ3_JUMPPAD 0x00080000 // hint for Q3's bots
|
||||
#define CONTENTSQ3_CLUSTERPORTAL 0x00100000 // hint for Q3's bots
|
||||
#define CONTENTSQ3_DONOTENTER 0x00200000 // hint for Q3's bots
|
||||
#define CONTENTSQ3_BOTCLIP 0x00400000 // hint for Q3's bots
|
||||
#define CONTENTSQ3_ORIGIN 0x01000000 // used by origin brushes to indicate origin of bmodel (removed by map compiler)
|
||||
#define CONTENTSQ3_BODY 0x02000000 // used by bbox entities (should never be on a brush)
|
||||
#define CONTENTSQ3_CORPSE 0x04000000 // used by dead bodies (SOLID_CORPSE in darkplaces)
|
||||
#define CONTENTSQ3_DETAIL 0x08000000 // brushes that do not split the bsp tree (decorations)
|
||||
#define CONTENTSQ3_STRUCTURAL 0x10000000 // brushes that split the bsp tree
|
||||
#define CONTENTSQ3_TRANSLUCENT 0x20000000 // leaves surfaces that are inside for rendering
|
||||
#define CONTENTSQ3_TRIGGER 0x40000000 // used by trigger entities
|
||||
#define CONTENTSQ3_NODROP 0x80000000 // remove items that fall into this brush
|
||||
|
||||
#define SUPERCONTENTS_SOLID 0x00000001
|
||||
#define SUPERCONTENTS_WATER 0x00000002
|
||||
#define SUPERCONTENTS_SLIME 0x00000004
|
||||
#define SUPERCONTENTS_LAVA 0x00000008
|
||||
#define SUPERCONTENTS_SKY 0x00000010
|
||||
#define SUPERCONTENTS_BODY 0x00000020
|
||||
#define SUPERCONTENTS_CORPSE 0x00000040
|
||||
#define SUPERCONTENTS_NODROP 0x00000080
|
||||
#define SUPERCONTENTS_PLAYERCLIP 0x00000100
|
||||
#define SUPERCONTENTS_MONSTERCLIP 0x00000200
|
||||
#define SUPERCONTENTS_DONOTENTER 0x00000400
|
||||
#define SUPERCONTENTS_BOTCLIP 0x00000800
|
||||
#define SUPERCONTENTS_OPAQUE 0x00001000
|
||||
// TODO: is there any reason to define:
|
||||
// fog?
|
||||
// areaportal?
|
||||
// teleporter?
|
||||
// jumppad?
|
||||
// clusterportal?
|
||||
// detail? (div0) no, game code should not be allowed to differentiate between structural and detail
|
||||
// structural? (div0) no, game code should not be allowed to differentiate between structural and detail
|
||||
// trigger? (div0) no, as these are always solid anyway, and that's all that matters for trigger brushes
|
||||
#define SUPERCONTENTS_LIQUIDSMASK (SUPERCONTENTS_LAVA | SUPERCONTENTS_SLIME | SUPERCONTENTS_WATER)
|
||||
#define SUPERCONTENTS_VISBLOCKERMASK SUPERCONTENTS_OPAQUE
|
||||
|
||||
/*
|
||||
#define SUPERCONTENTS_DEADMONSTER 0x00000000
|
||||
#define SUPERCONTENTS_CURRENT_0 0x00000000
|
||||
#define SUPERCONTENTS_CURRENT_90 0x00000000
|
||||
#define SUPERCONTENTS_CURRENT_180 0x00000000
|
||||
#define SUPERCONTENTS_CURRENT_270 0x00000000
|
||||
#define SUPERCONTENTS_CURRENT_DOWN 0x00000000
|
||||
#define SUPERCONTENTS_CURRENT_UP 0x00000000
|
||||
#define SUPERCONTENTS_AREAPORTAL 0x00000000
|
||||
#define SUPERCONTENTS_AUX 0x00000000
|
||||
#define SUPERCONTENTS_CLUSTERPORTAL 0x00000000
|
||||
#define SUPERCONTENTS_DETAIL 0x00000000
|
||||
#define SUPERCONTENTS_STRUCTURAL 0x00000000
|
||||
#define SUPERCONTENTS_DONOTENTER 0x00000000
|
||||
#define SUPERCONTENTS_JUMPPAD 0x00000000
|
||||
#define SUPERCONTENTS_LADDER 0x00000000
|
||||
#define SUPERCONTENTS_MONSTER 0x00000000
|
||||
#define SUPERCONTENTS_MONSTERCLIP 0x00000000
|
||||
#define SUPERCONTENTS_PLAYERCLIP 0x00000000
|
||||
#define SUPERCONTENTS_TELEPORTER 0x00000000
|
||||
#define SUPERCONTENTS_TRANSLUCENT 0x00000000
|
||||
#define SUPERCONTENTS_TRIGGER 0x00000000
|
||||
#define SUPERCONTENTS_WINDOW 0x00000000
|
||||
*/
|
||||
|
||||
/*
|
||||
typedef struct dnode_s
|
||||
{
|
||||
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 dclipnode_s
|
||||
{
|
||||
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 dedge_s
|
||||
{
|
||||
unsigned short v[2]; // vertex numbers
|
||||
} dedge_t;
|
||||
*/
|
||||
|
||||
#define MAXLIGHTMAPS 4
|
||||
/*
|
||||
typedef struct dface_s
|
||||
{
|
||||
// LordHavoc: changed from short to unsigned short for q2 support
|
||||
unsigned short planenum;
|
||||
short side;
|
||||
|
||||
int firstedge; // we must support > 64k edges
|
||||
short numedges;
|
||||
short texinfo;
|
||||
|
||||
// lighting info
|
||||
unsigned char 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 dleaf_s
|
||||
{
|
||||
int contents;
|
||||
int visofs; // -1 = no visibility info
|
||||
|
||||
short mins[3]; // for frustum culling
|
||||
short maxs[3];
|
||||
|
||||
unsigned short firstmarksurface;
|
||||
unsigned short nummarksurfaces;
|
||||
|
||||
unsigned char ambient_level[NUM_AMBIENTS];
|
||||
} dleaf_t;
|
||||
*/
|
||||
|
19
app/jni/build.bat
Normal file
19
app/jni/build.bat
Normal file
|
@ -0,0 +1,19 @@
|
|||
call ndk-build V=0 -j10 NDK_DEBUG=0 %1
|
||||
|
||||
cd ..\libs
|
||||
|
||||
del libs.jar
|
||||
mkdir lib
|
||||
mkdir lib\armeabi-v7a
|
||||
copy .\armeabi-v7a\ lib\armeabi-v7a\*
|
||||
7z a -x!*.jar libs.zip .\lib*
|
||||
rename libs.zip libs.jar
|
||||
|
||||
REM Create an archive of the source
|
||||
cd ..\src\main\assets\source
|
||||
del QVRSource.zip
|
||||
REM exclude unnecessary files from build
|
||||
7z a -r -x!.git* -x!*.o -x!*.d -x!obj -x!*.bin -x!app\build -x!app\libs -x!*.jar -x!*.so -x!*.log -x!*.jks -x!*.apk QVRSource.zip ..\..\..\..\..\*
|
||||
|
||||
|
||||
cd ..\..\..\..\jni
|
12
app/jni/builddate.c
Normal file
12
app/jni/builddate.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
#define STRINGIFY2(arg) #arg
|
||||
#define STRINGIFY(arg) STRINGIFY2(arg)
|
||||
|
||||
extern const char *buildstring;
|
||||
const char *buildstring = __TIME__ " " __DATE__
|
||||
#ifdef SVNREVISION
|
||||
" " STRINGIFY(SVNREVISION)
|
||||
#endif
|
||||
#ifdef BUILDTYPE
|
||||
" " STRINGIFY(BUILDTYPE)
|
||||
#endif
|
||||
;
|
720
app/jni/cap_avi.c
Normal file
720
app/jni/cap_avi.c
Normal file
|
@ -0,0 +1,720 @@
|
|||
#include "quakedef.h"
|
||||
#include "cap_avi.h"
|
||||
|
||||
#define AVI_MASTER_INDEX_SIZE 640 // GB ought to be enough for anyone
|
||||
|
||||
typedef struct capturevideostate_avi_formatspecific_s
|
||||
{
|
||||
// AVI stuff
|
||||
fs_offset_t videofile_firstchunkframes_offset;
|
||||
fs_offset_t videofile_totalframes_offset1;
|
||||
fs_offset_t videofile_totalframes_offset2;
|
||||
fs_offset_t videofile_totalsampleframes_offset;
|
||||
int videofile_ix_master_audio_inuse;
|
||||
fs_offset_t videofile_ix_master_audio_inuse_offset;
|
||||
fs_offset_t videofile_ix_master_audio_start_offset;
|
||||
int videofile_ix_master_video_inuse;
|
||||
fs_offset_t videofile_ix_master_video_inuse_offset;
|
||||
fs_offset_t videofile_ix_master_video_start_offset;
|
||||
fs_offset_t videofile_ix_movistart;
|
||||
fs_offset_t position;
|
||||
qboolean canseek;
|
||||
sizebuf_t riffbuffer;
|
||||
unsigned char riffbufferdata[128];
|
||||
sizebuf_t riffindexbuffer;
|
||||
int riffstacklevel;
|
||||
fs_offset_t riffstackstartoffset[4];
|
||||
fs_offset_t riffstacksizehint[4];
|
||||
const char *riffstackfourcc[4];
|
||||
}
|
||||
capturevideostate_avi_formatspecific_t;
|
||||
#define LOAD_FORMATSPECIFIC_AVI() capturevideostate_avi_formatspecific_t *format = (capturevideostate_avi_formatspecific_t *) cls.capturevideo.formatspecific
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Start(void)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
memset(&format->riffbuffer, 0, sizeof(sizebuf_t));
|
||||
format->riffbuffer.maxsize = sizeof(format->riffbufferdata);
|
||||
format->riffbuffer.data = format->riffbufferdata;
|
||||
format->position = 0;
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Flush(void)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (format->riffbuffer.cursize > 0)
|
||||
{
|
||||
if (!FS_Write(cls.capturevideo.videofile, format->riffbuffer.data, format->riffbuffer.cursize))
|
||||
cls.capturevideo.error = true;
|
||||
format->position += format->riffbuffer.cursize;
|
||||
format->riffbuffer.cursize = 0;
|
||||
format->riffbuffer.overflowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_FlushNoIncrease(void)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (format->riffbuffer.cursize > 0)
|
||||
{
|
||||
if (!FS_Write(cls.capturevideo.videofile, format->riffbuffer.data, format->riffbuffer.cursize))
|
||||
cls.capturevideo.error = true;
|
||||
format->riffbuffer.cursize = 0;
|
||||
format->riffbuffer.overflowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_WriteBytes(const unsigned char *data, size_t size)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
if (!FS_Write(cls.capturevideo.videofile, data, size))
|
||||
cls.capturevideo.error = true;
|
||||
format->position += size;
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Write32(int n)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (format->riffbuffer.cursize + 4 > format->riffbuffer.maxsize)
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
MSG_WriteLong(&format->riffbuffer, n);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Write16(int n)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (format->riffbuffer.cursize + 2 > format->riffbuffer.maxsize)
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
MSG_WriteShort(&format->riffbuffer, n);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_WriteFourCC(const char *chunkfourcc)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (format->riffbuffer.cursize + (int)strlen(chunkfourcc) > format->riffbuffer.maxsize)
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
MSG_WriteUnterminatedString(&format->riffbuffer, chunkfourcc);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_WriteTerminatedString(const char *string)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (format->riffbuffer.cursize + (int)strlen(string) > format->riffbuffer.maxsize)
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
MSG_WriteString(&format->riffbuffer, string);
|
||||
}
|
||||
|
||||
static fs_offset_t SCR_CaptureVideo_RIFF_GetPosition(void)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
//return FS_Tell(cls.capturevideo.videofile);
|
||||
return format->position;
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Push(const char *chunkfourcc, const char *listtypefourcc, fs_offset_t sizeHint)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if (listtypefourcc && sizeHint >= 0)
|
||||
sizeHint += 4; // size hint is for INNER size
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC(chunkfourcc);
|
||||
SCR_CaptureVideo_RIFF_Write32(sizeHint);
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
format->riffstacksizehint[format->riffstacklevel] = sizeHint;
|
||||
format->riffstackstartoffset[format->riffstacklevel] = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
format->riffstackfourcc[format->riffstacklevel] = chunkfourcc;
|
||||
++format->riffstacklevel;
|
||||
if (listtypefourcc)
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC(listtypefourcc);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Pop(void)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
fs_offset_t offset, sizehint;
|
||||
int x;
|
||||
unsigned char sizebytes[4];
|
||||
// write out the chunk size and then return to the current file position
|
||||
format->riffstacklevel--;
|
||||
offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
|
||||
sizehint = format->riffstacksizehint[format->riffstacklevel];
|
||||
x = (int)(offset - (format->riffstackstartoffset[format->riffstacklevel]));
|
||||
|
||||
if(x != sizehint)
|
||||
{
|
||||
if(sizehint != -1)
|
||||
{
|
||||
int i;
|
||||
Con_Printf("WARNING: invalid size hint %d when writing video data (actual size: %d)\n", (int) sizehint, x);
|
||||
for(i = 0; i <= format->riffstacklevel; ++i)
|
||||
{
|
||||
Con_Printf(" RIFF level %d = %s\n", i, format->riffstackfourcc[i]);
|
||||
}
|
||||
}
|
||||
sizebytes[0] = (x) & 0xff;sizebytes[1] = (x >> 8) & 0xff;sizebytes[2] = (x >> 16) & 0xff;sizebytes[3] = (x >> 24) & 0xff;
|
||||
if(FS_Seek(cls.capturevideo.videofile, -(x + 4), SEEK_END) >= 0)
|
||||
{
|
||||
FS_Write(cls.capturevideo.videofile, sizebytes, 4);
|
||||
}
|
||||
FS_Seek(cls.capturevideo.videofile, 0, SEEK_END);
|
||||
}
|
||||
|
||||
if (offset & 1)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_WriteBytes((unsigned char *) "\0", 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void GrowBuf(sizebuf_t *buf, int extralen)
|
||||
{
|
||||
if(buf->cursize + extralen > buf->maxsize)
|
||||
{
|
||||
int oldsize = buf->maxsize;
|
||||
unsigned char *olddata;
|
||||
olddata = buf->data;
|
||||
buf->maxsize = max(buf->maxsize * 2, 4096);
|
||||
buf->data = (unsigned char *) Mem_Alloc(tempmempool, buf->maxsize);
|
||||
if(olddata)
|
||||
{
|
||||
memcpy(buf->data, olddata, oldsize);
|
||||
Mem_Free(olddata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_IndexEntry(const char *chunkfourcc, int chunksize, int flags)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
if(!format->canseek)
|
||||
Sys_Error("SCR_CaptureVideo_RIFF_IndexEntry called on non-seekable AVI");
|
||||
|
||||
if (format->riffstacklevel != 2)
|
||||
Sys_Error("SCR_Capturevideo_RIFF_IndexEntry: RIFF stack level is %i (should be 2)\n", format->riffstacklevel);
|
||||
GrowBuf(&format->riffindexbuffer, 16);
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
MSG_WriteUnterminatedString(&format->riffindexbuffer, chunkfourcc);
|
||||
MSG_WriteLong(&format->riffindexbuffer, flags);
|
||||
MSG_WriteLong(&format->riffindexbuffer, (int)FS_Tell(cls.capturevideo.videofile) - format->riffstackstartoffset[1]);
|
||||
MSG_WriteLong(&format->riffindexbuffer, chunksize);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_MakeIxChunk(const char *fcc, const char *dwChunkId, fs_offset_t masteridx_counter, int *masteridx_count, fs_offset_t masteridx_start)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
int nMatching;
|
||||
int i;
|
||||
fs_offset_t ix = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
fs_offset_t pos, sz;
|
||||
|
||||
if(!format->canseek)
|
||||
Sys_Error("SCR_CaptureVideo_RIFF_MakeIxChunk called on non-seekable AVI");
|
||||
|
||||
if(*masteridx_count >= AVI_MASTER_INDEX_SIZE)
|
||||
return;
|
||||
|
||||
nMatching = 0; // go through index and enumerate them
|
||||
for(i = 0; i < format->riffindexbuffer.cursize; i += 16)
|
||||
if(!memcmp(format->riffindexbuffer.data + i, dwChunkId, 4))
|
||||
++nMatching;
|
||||
|
||||
sz = 2+2+4+4+4+4+4;
|
||||
for(i = 0; i < format->riffindexbuffer.cursize; i += 16)
|
||||
if(!memcmp(format->riffindexbuffer.data + i, dwChunkId, 4))
|
||||
sz += 8;
|
||||
|
||||
SCR_CaptureVideo_RIFF_Push(fcc, NULL, sz);
|
||||
SCR_CaptureVideo_RIFF_Write16(2); // wLongsPerEntry
|
||||
SCR_CaptureVideo_RIFF_Write16(0x0100); // bIndexType=1, bIndexSubType=0
|
||||
SCR_CaptureVideo_RIFF_Write32(nMatching); // nEntriesInUse
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC(dwChunkId); // dwChunkId
|
||||
SCR_CaptureVideo_RIFF_Write32(format->videofile_ix_movistart & (fs_offset_t) 0xFFFFFFFFu);
|
||||
SCR_CaptureVideo_RIFF_Write32(((fs_offset_t) format->videofile_ix_movistart) >> 32);
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved
|
||||
|
||||
for(i = 0; i < format->riffindexbuffer.cursize; i += 16)
|
||||
if(!memcmp(format->riffindexbuffer.data + i, dwChunkId, 4))
|
||||
{
|
||||
unsigned int *p = (unsigned int *) (format->riffindexbuffer.data + i);
|
||||
unsigned int flags = p[1];
|
||||
unsigned int rpos = p[2];
|
||||
unsigned int size = p[3];
|
||||
size &= ~0x80000000;
|
||||
if(!(flags & 0x10)) // no keyframe?
|
||||
size |= 0x80000000;
|
||||
SCR_CaptureVideo_RIFF_Write32(rpos + 8);
|
||||
SCR_CaptureVideo_RIFF_Write32(size);
|
||||
}
|
||||
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
pos = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
|
||||
if(FS_Seek(cls.capturevideo.videofile, masteridx_start + 16 * *masteridx_count, SEEK_SET) >= 0)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Write32(ix & (fs_offset_t) 0xFFFFFFFFu);
|
||||
SCR_CaptureVideo_RIFF_Write32(((fs_offset_t) ix) >> 32);
|
||||
SCR_CaptureVideo_RIFF_Write32(pos - ix);
|
||||
SCR_CaptureVideo_RIFF_Write32(nMatching);
|
||||
SCR_CaptureVideo_RIFF_FlushNoIncrease();
|
||||
}
|
||||
|
||||
if(FS_Seek(cls.capturevideo.videofile, masteridx_counter, SEEK_SET) >= 0)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Write32(++*masteridx_count);
|
||||
SCR_CaptureVideo_RIFF_FlushNoIncrease();
|
||||
}
|
||||
|
||||
FS_Seek(cls.capturevideo.videofile, 0, SEEK_END); // return value doesn't matter here
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_Finish(qboolean final)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
// close the "movi" list
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
if(format->videofile_ix_master_video_inuse_offset)
|
||||
SCR_CaptureVideo_RIFF_MakeIxChunk("ix00", "00dc", format->videofile_ix_master_video_inuse_offset, &format->videofile_ix_master_video_inuse, format->videofile_ix_master_video_start_offset);
|
||||
if(format->videofile_ix_master_audio_inuse_offset)
|
||||
SCR_CaptureVideo_RIFF_MakeIxChunk("ix01", "01wb", format->videofile_ix_master_audio_inuse_offset, &format->videofile_ix_master_audio_inuse, format->videofile_ix_master_audio_start_offset);
|
||||
// write the idx1 chunk that we've been building while saving the frames (for old style players)
|
||||
if(final && format->videofile_firstchunkframes_offset)
|
||||
// TODO replace index creating by OpenDML ix##/##ix/indx chunk so it works for more than one AVI part too
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Push("idx1", NULL, format->riffindexbuffer.cursize);
|
||||
SCR_CaptureVideo_RIFF_WriteBytes(format->riffindexbuffer.data, format->riffindexbuffer.cursize);
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
format->riffindexbuffer.cursize = 0;
|
||||
// pop the RIFF chunk itself
|
||||
while (format->riffstacklevel > 0)
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
if(format->videofile_firstchunkframes_offset)
|
||||
{
|
||||
Con_DPrintf("Finishing first chunk (%d frames)\n", cls.capturevideo.frame);
|
||||
if(FS_Seek(cls.capturevideo.videofile, format->videofile_firstchunkframes_offset, SEEK_SET) >= 0)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.frame);
|
||||
SCR_CaptureVideo_RIFF_FlushNoIncrease();
|
||||
}
|
||||
FS_Seek(cls.capturevideo.videofile, 0, SEEK_END);
|
||||
format->videofile_firstchunkframes_offset = 0;
|
||||
}
|
||||
else
|
||||
Con_DPrintf("Finishing another chunk (%d frames)\n", cls.capturevideo.frame);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_RIFF_OverflowCheck(int framesize)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
fs_offset_t cursize;
|
||||
//fs_offset_t curfilesize;
|
||||
if (format->riffstacklevel != 2)
|
||||
Sys_Error("SCR_CaptureVideo_RIFF_OverflowCheck: chunk stack leakage!\n");
|
||||
|
||||
if(!format->canseek)
|
||||
return;
|
||||
|
||||
// check where we are in the file
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
cursize = SCR_CaptureVideo_RIFF_GetPosition() - format->riffstackstartoffset[0];
|
||||
//curfilesize = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
|
||||
// if this would overflow the windows limit of 1GB per RIFF chunk, we need
|
||||
// to close the current RIFF chunk and open another for future frames
|
||||
if (8 + cursize + framesize + format->riffindexbuffer.cursize + 8 + format->riffindexbuffer.cursize + 64 > 1<<30) // note that the Ix buffer takes less space... I just don't dare to / 2 here now... sorry, maybe later
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Finish(false);
|
||||
// begin a new 1GB extended section of the AVI
|
||||
SCR_CaptureVideo_RIFF_Push("RIFF", "AVIX", -1);
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "movi", -1);
|
||||
format->videofile_ix_movistart = format->riffstackstartoffset[1];
|
||||
}
|
||||
}
|
||||
|
||||
// converts from BGRA32 to I420 colorspace (identical to YV12 except chroma plane order is reversed), this colorspace is handled by the Intel(r) 4:2:0 codec on Windows
|
||||
static void SCR_CaptureVideo_ConvertFrame_BGRA_to_I420_flip(int width, int height, unsigned char *instart, unsigned char *outstart)
|
||||
{
|
||||
int x, y;
|
||||
int blockr, blockg, blockb;
|
||||
int outoffset = (width/2)*(height/2);
|
||||
unsigned char *b, *out;
|
||||
// process one line at a time, and CbCr every other line at 2 pixel intervals
|
||||
for (y = 0;y < height;y++)
|
||||
{
|
||||
// 1x1 Y
|
||||
for (b = instart + (height-1-y)*width*4, out = outstart + y*width, x = 0;x < width;x++, b += 4, out++)
|
||||
{
|
||||
blockr = b[2];
|
||||
blockg = b[1];
|
||||
blockb = b[0];
|
||||
*out = cls.capturevideo.yuvnormalizetable[0][cls.capturevideo.rgbtoyuvscaletable[0][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[0][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[0][2][blockb]];
|
||||
}
|
||||
if ((y & 1) == 0 && y/2 < height/2) // if h is odd, this skips the last row
|
||||
{
|
||||
// 2x2 Cr and Cb planes
|
||||
int inpitch = width*4;
|
||||
for (b = instart + (height-2-y)*width*4, out = outstart + width*height + (y/2)*(width/2), x = 0;x < width/2;x++, b += 8, out++)
|
||||
{
|
||||
blockr = (b[2] + b[6] + b[inpitch+2] + b[inpitch+6]) >> 2;
|
||||
blockg = (b[1] + b[5] + b[inpitch+1] + b[inpitch+5]) >> 2;
|
||||
blockb = (b[0] + b[4] + b[inpitch+0] + b[inpitch+4]) >> 2;
|
||||
// Cr
|
||||
out[0 ] = cls.capturevideo.yuvnormalizetable[1][cls.capturevideo.rgbtoyuvscaletable[1][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[1][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[1][2][blockb] + 128];
|
||||
// Cb
|
||||
out[outoffset] = cls.capturevideo.yuvnormalizetable[2][cls.capturevideo.rgbtoyuvscaletable[2][0][blockr] + cls.capturevideo.rgbtoyuvscaletable[2][1][blockg] + cls.capturevideo.rgbtoyuvscaletable[2][2][blockb] + 128];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_Avi_VideoFrames(int num)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
int x = 0, width = cls.capturevideo.width, height = cls.capturevideo.height;
|
||||
unsigned char *in, *out;
|
||||
// FIXME: width/height must be multiple of 2, enforce this?
|
||||
in = cls.capturevideo.outbuffer;
|
||||
out = cls.capturevideo.outbuffer + width*height*4;
|
||||
SCR_CaptureVideo_ConvertFrame_BGRA_to_I420_flip(width, height, in, out);
|
||||
x = width*height+(width/2)*(height/2)*2;
|
||||
while(num-- > 0)
|
||||
{
|
||||
if(format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_OverflowCheck(8 + x);
|
||||
SCR_CaptureVideo_RIFF_IndexEntry("00dc", x, 0x10); // AVIIF_KEYFRAME
|
||||
}
|
||||
|
||||
if(!format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Push("RIFF", "AVIX", 12+8+x);
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "movi", 8+x);
|
||||
}
|
||||
SCR_CaptureVideo_RIFF_Push("00dc", NULL, x);
|
||||
SCR_CaptureVideo_RIFF_WriteBytes(out, x);
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
if(!format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_Avi_EndVideo(void)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
|
||||
if(format->canseek)
|
||||
{
|
||||
// close any open chunks
|
||||
SCR_CaptureVideo_RIFF_Finish(true);
|
||||
|
||||
// go back and fix the video frames and audio samples fields
|
||||
if(format->videofile_totalframes_offset1)
|
||||
if(FS_Seek(cls.capturevideo.videofile, format->videofile_totalframes_offset1, SEEK_SET) >= 0)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.frame);
|
||||
SCR_CaptureVideo_RIFF_FlushNoIncrease();
|
||||
}
|
||||
if(format->videofile_totalframes_offset2)
|
||||
if(FS_Seek(cls.capturevideo.videofile, format->videofile_totalframes_offset2, SEEK_SET) >= 0)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.frame);
|
||||
SCR_CaptureVideo_RIFF_FlushNoIncrease();
|
||||
}
|
||||
if (cls.capturevideo.soundrate)
|
||||
{
|
||||
if(format->videofile_totalsampleframes_offset)
|
||||
if(FS_Seek(cls.capturevideo.videofile, format->videofile_totalsampleframes_offset, SEEK_SET) >= 0)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.soundsampleframe);
|
||||
SCR_CaptureVideo_RIFF_FlushNoIncrease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (format->riffindexbuffer.data)
|
||||
{
|
||||
Mem_Free(format->riffindexbuffer.data);
|
||||
format->riffindexbuffer.data = NULL;
|
||||
}
|
||||
|
||||
FS_Close(cls.capturevideo.videofile);
|
||||
cls.capturevideo.videofile = NULL;
|
||||
|
||||
Mem_Free(format);
|
||||
}
|
||||
|
||||
static void SCR_CaptureVideo_Avi_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length)
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
int x;
|
||||
unsigned char bufstereo16le[PAINTBUFFER_SIZE * 4];
|
||||
unsigned char* out_ptr;
|
||||
size_t i;
|
||||
|
||||
// write the sound buffer as little endian 16bit interleaved stereo
|
||||
for(i = 0, out_ptr = bufstereo16le; i < length; i++, out_ptr += 4)
|
||||
{
|
||||
int n0, n1;
|
||||
|
||||
n0 = paintbuffer[i].sample[0] * 32768.0f;
|
||||
n0 = bound(-32768, n0, 32767);
|
||||
out_ptr[0] = (unsigned char)n0;
|
||||
out_ptr[1] = (unsigned char)(n0 >> 8);
|
||||
|
||||
n1 = paintbuffer[i].sample[1] * 32768.0f;
|
||||
n1 = bound(-32768, n1, 32767);
|
||||
out_ptr[2] = (unsigned char)n1;
|
||||
out_ptr[3] = (unsigned char)(n1 >> 8);
|
||||
}
|
||||
|
||||
x = length*4;
|
||||
if(format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_OverflowCheck(8 + x);
|
||||
SCR_CaptureVideo_RIFF_IndexEntry("01wb", x, 0x10); // AVIIF_KEYFRAME
|
||||
}
|
||||
|
||||
if(!format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Push("RIFF", "AVIX", 12+8+x);
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "movi", 8+x);
|
||||
}
|
||||
SCR_CaptureVideo_RIFF_Push("01wb", NULL, x);
|
||||
SCR_CaptureVideo_RIFF_WriteBytes(bufstereo16le, x);
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
if(!format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
}
|
||||
|
||||
void SCR_CaptureVideo_Avi_BeginVideo(void)
|
||||
{
|
||||
int width = cls.capturevideo.width;
|
||||
int height = cls.capturevideo.height;
|
||||
int n, d;
|
||||
unsigned int i;
|
||||
double aspect;
|
||||
char vabuf[1024];
|
||||
|
||||
aspect = vid.width / (vid.height * vid_pixelheight.value);
|
||||
|
||||
cls.capturevideo.format = CAPTUREVIDEOFORMAT_AVI_I420;
|
||||
cls.capturevideo.formatextension = "avi";
|
||||
cls.capturevideo.videofile = FS_OpenRealFile(va(vabuf, sizeof(vabuf), "%s.%s", cls.capturevideo.basename, cls.capturevideo.formatextension), "wb", false);
|
||||
cls.capturevideo.endvideo = SCR_CaptureVideo_Avi_EndVideo;
|
||||
cls.capturevideo.videoframes = SCR_CaptureVideo_Avi_VideoFrames;
|
||||
cls.capturevideo.soundframe = SCR_CaptureVideo_Avi_SoundFrame;
|
||||
cls.capturevideo.formatspecific = Mem_Alloc(tempmempool, sizeof(capturevideostate_avi_formatspecific_t));
|
||||
{
|
||||
LOAD_FORMATSPECIFIC_AVI();
|
||||
format->canseek = (FS_Seek(cls.capturevideo.videofile, 0, SEEK_SET) == 0);
|
||||
SCR_CaptureVideo_RIFF_Start();
|
||||
// enclosing RIFF chunk (there can be multiple of these in >1GB files, the later ones are "AVIX" instead of "AVI " and have no header/stream info)
|
||||
SCR_CaptureVideo_RIFF_Push("RIFF", "AVI ", format->canseek ? -1 : 12+(8+56+12+(12+52+8+40+8+68)+(cls.capturevideo.soundrate?(12+12+52+8+18):0)+12+(8+4))+12+(8+(((int) strlen(engineversion) | 1) + 1))+12);
|
||||
// AVI main header
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "hdrl", format->canseek ? -1 : 8+56+12+(12+52+8+40+8+68)+(cls.capturevideo.soundrate?(12+12+52+8+18):0)+12+(8+4));
|
||||
SCR_CaptureVideo_RIFF_Push("avih", NULL, 56);
|
||||
SCR_CaptureVideo_RIFF_Write32((int)(1000000.0 / (cls.capturevideo.framerate / cls.capturevideo.framestep))); // microseconds per frame
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // max bytes per second
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // padding granularity
|
||||
SCR_CaptureVideo_RIFF_Write32(0x910); // flags (AVIF_HASINDEX | AVIF_ISINTERLEAVED | AVIF_TRUSTCKTYPE)
|
||||
format->videofile_firstchunkframes_offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // total frames
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // initial frames
|
||||
if (cls.capturevideo.soundrate)
|
||||
SCR_CaptureVideo_RIFF_Write32(2); // number of streams
|
||||
else
|
||||
SCR_CaptureVideo_RIFF_Write32(1); // number of streams
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // suggested buffer size
|
||||
SCR_CaptureVideo_RIFF_Write32(width); // width
|
||||
SCR_CaptureVideo_RIFF_Write32(height); // height
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // reserved[0]
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // reserved[1]
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // reserved[2]
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // reserved[3]
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// video stream info
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "strl", format->canseek ? -1 : 12+52+8+40+8+68);
|
||||
SCR_CaptureVideo_RIFF_Push("strh", "vids", 52);
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC("I420"); // stream fourcc (I420 colorspace, uncompressed)
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // flags
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // priority
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // language
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // initial frames
|
||||
// find an ideal divisor for the framerate
|
||||
FindFraction(cls.capturevideo.framerate / cls.capturevideo.framestep, &n, &d, 1000);
|
||||
SCR_CaptureVideo_RIFF_Write32(d); // samples/second divisor
|
||||
SCR_CaptureVideo_RIFF_Write32(n); // samples/second multiplied by divisor
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // start
|
||||
format->videofile_totalframes_offset1 = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
SCR_CaptureVideo_RIFF_Write32(0xFFFFFFFF); // length
|
||||
SCR_CaptureVideo_RIFF_Write32(width*height+(width/2)*(height/2)*2); // suggested buffer size
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // quality
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // sample size
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // frame left
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // frame top
|
||||
SCR_CaptureVideo_RIFF_Write16(width); // frame right
|
||||
SCR_CaptureVideo_RIFF_Write16(height); // frame bottom
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// video stream format
|
||||
SCR_CaptureVideo_RIFF_Push("strf", NULL, 40);
|
||||
SCR_CaptureVideo_RIFF_Write32(40); // BITMAPINFO struct size
|
||||
SCR_CaptureVideo_RIFF_Write32(width); // width
|
||||
SCR_CaptureVideo_RIFF_Write32(height); // height
|
||||
SCR_CaptureVideo_RIFF_Write16(3); // planes
|
||||
SCR_CaptureVideo_RIFF_Write16(12); // bitcount
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC("I420"); // compression
|
||||
SCR_CaptureVideo_RIFF_Write32(width*height+(width/2)*(height/2)*2); // size of image
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // x pixels per meter
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // y pixels per meter
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // color used
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // color important
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// master index
|
||||
if(format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Push("indx", NULL, -1);
|
||||
SCR_CaptureVideo_RIFF_Write16(4); // wLongsPerEntry
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // bIndexSubType=0, bIndexType=0
|
||||
format->videofile_ix_master_video_inuse_offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // nEntriesInUse
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC("00dc"); // dwChunkId
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved1
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved2
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved3
|
||||
format->videofile_ix_master_video_start_offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
for(i = 0; i < AVI_MASTER_INDEX_SIZE * 4; ++i)
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // fill up later
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
// extended format (aspect!)
|
||||
SCR_CaptureVideo_RIFF_Push("vprp", NULL, 68);
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // VideoFormatToken
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // VideoStandard
|
||||
SCR_CaptureVideo_RIFF_Write32((int)(cls.capturevideo.framerate / cls.capturevideo.framestep)); // dwVerticalRefreshRate (bogus)
|
||||
SCR_CaptureVideo_RIFF_Write32(width); // dwHTotalInT
|
||||
SCR_CaptureVideo_RIFF_Write32(height); // dwVTotalInLines
|
||||
FindFraction(aspect, &n, &d, 1000);
|
||||
SCR_CaptureVideo_RIFF_Write32((n << 16) | d); // dwFrameAspectRatio // TODO a word
|
||||
SCR_CaptureVideo_RIFF_Write32(width); // dwFrameWidthInPixels
|
||||
SCR_CaptureVideo_RIFF_Write32(height); // dwFrameHeightInLines
|
||||
SCR_CaptureVideo_RIFF_Write32(1); // nFieldPerFrame
|
||||
SCR_CaptureVideo_RIFF_Write32(width); // CompressedBMWidth
|
||||
SCR_CaptureVideo_RIFF_Write32(height); // CompressedBMHeight
|
||||
SCR_CaptureVideo_RIFF_Write32(width); // ValidBMHeight
|
||||
SCR_CaptureVideo_RIFF_Write32(height); // ValidBMWidth
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // ValidBMXOffset
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // ValidBMYOffset
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // ValidBMXOffsetInT
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // ValidBMYValidStartLine
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
if (cls.capturevideo.soundrate)
|
||||
{
|
||||
// audio stream info
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "strl", format->canseek ? -1 : 12+52+8+18);
|
||||
SCR_CaptureVideo_RIFF_Push("strh", "auds", 52);
|
||||
SCR_CaptureVideo_RIFF_Write32(1); // stream fourcc (PCM audio, uncompressed)
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // flags
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // priority
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // language
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // initial frames
|
||||
SCR_CaptureVideo_RIFF_Write32(1); // samples/second divisor
|
||||
SCR_CaptureVideo_RIFF_Write32((int)(cls.capturevideo.soundrate)); // samples/second multiplied by divisor
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // start
|
||||
format->videofile_totalsampleframes_offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
SCR_CaptureVideo_RIFF_Write32(0xFFFFFFFF); // length
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.soundrate * 2); // suggested buffer size (this is a half second)
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // quality
|
||||
SCR_CaptureVideo_RIFF_Write32(4); // sample size
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // frame left
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // frame top
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // frame right
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // frame bottom
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// audio stream format
|
||||
SCR_CaptureVideo_RIFF_Push("strf", NULL, 18);
|
||||
SCR_CaptureVideo_RIFF_Write16(1); // format (uncompressed PCM?)
|
||||
SCR_CaptureVideo_RIFF_Write16(2); // channels (stereo)
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.soundrate); // sampleframes per second
|
||||
SCR_CaptureVideo_RIFF_Write32(cls.capturevideo.soundrate * 4); // average bytes per second
|
||||
SCR_CaptureVideo_RIFF_Write16(4); // block align
|
||||
SCR_CaptureVideo_RIFF_Write16(16); // bits per sample
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // size
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// master index
|
||||
if(format->canseek)
|
||||
{
|
||||
SCR_CaptureVideo_RIFF_Push("indx", NULL, -1);
|
||||
SCR_CaptureVideo_RIFF_Write16(4); // wLongsPerEntry
|
||||
SCR_CaptureVideo_RIFF_Write16(0); // bIndexSubType=0, bIndexType=0
|
||||
format->videofile_ix_master_audio_inuse_offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // nEntriesInUse
|
||||
SCR_CaptureVideo_RIFF_WriteFourCC("01wb"); // dwChunkId
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved1
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved2
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // dwReserved3
|
||||
format->videofile_ix_master_audio_start_offset = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
for(i = 0; i < AVI_MASTER_INDEX_SIZE * 4; ++i)
|
||||
SCR_CaptureVideo_RIFF_Write32(0); // fill up later
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
|
||||
format->videofile_ix_master_audio_inuse = format->videofile_ix_master_video_inuse = 0;
|
||||
|
||||
// extended header (for total #frames)
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "odml", 8+4);
|
||||
SCR_CaptureVideo_RIFF_Push("dmlh", NULL, 4);
|
||||
format->videofile_totalframes_offset2 = SCR_CaptureVideo_RIFF_GetPosition();
|
||||
SCR_CaptureVideo_RIFF_Write32(0xFFFFFFFF);
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
|
||||
// close the AVI header list
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// software that produced this AVI video file
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "INFO", 8+((strlen(engineversion) | 1) + 1));
|
||||
SCR_CaptureVideo_RIFF_Push("ISFT", NULL, strlen(engineversion) + 1);
|
||||
SCR_CaptureVideo_RIFF_WriteTerminatedString(engineversion);
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// enable this junk filler if you like the LIST movi to always begin at 4KB in the file (why?)
|
||||
#if 0
|
||||
SCR_CaptureVideo_RIFF_Push("JUNK", NULL);
|
||||
x = 4096 - SCR_CaptureVideo_RIFF_GetPosition();
|
||||
while (x > 0)
|
||||
{
|
||||
const char *junkfiller = "[ DarkPlaces junk data ]";
|
||||
int i = min(x, (int)strlen(junkfiller));
|
||||
SCR_CaptureVideo_RIFF_WriteBytes((const unsigned char *)junkfiller, i);
|
||||
x -= i;
|
||||
}
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
#endif
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// begin the actual video section now
|
||||
SCR_CaptureVideo_RIFF_Push("LIST", "movi", format->canseek ? -1 : 0);
|
||||
format->videofile_ix_movistart = format->riffstackstartoffset[1];
|
||||
// we're done with the headers now...
|
||||
SCR_CaptureVideo_RIFF_Flush();
|
||||
if (format->riffstacklevel != 2)
|
||||
Sys_Error("SCR_CaptureVideo_BeginVideo: broken AVI writing code (stack level is %i (should be 2) at end of headers)\n", format->riffstacklevel);
|
||||
|
||||
if(!format->canseek)
|
||||
{
|
||||
// close the movi immediately
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
// close the AVI immediately (we'll put all frames into AVIX)
|
||||
SCR_CaptureVideo_RIFF_Pop();
|
||||
}
|
||||
}
|
||||
}
|
1
app/jni/cap_avi.h
Normal file
1
app/jni/cap_avi.h
Normal file
|
@ -0,0 +1 @@
|
|||
void SCR_CaptureVideo_Avi_BeginVideo(void);
|
1121
app/jni/cap_ogg.c
Normal file
1121
app/jni/cap_ogg.c
Normal file
File diff suppressed because it is too large
Load diff
4
app/jni/cap_ogg.h
Normal file
4
app/jni/cap_ogg.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
void SCR_CaptureVideo_Ogg_Init(void);
|
||||
qboolean SCR_CaptureVideo_Ogg_Available(void);
|
||||
void SCR_CaptureVideo_Ogg_BeginVideo(void);
|
||||
void SCR_CaptureVideo_Ogg_CloseDLL(void);
|
91
app/jni/cd_null.c
Normal file
91
app/jni/cd_null.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
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"
|
||||
#include "cdaudio.h"
|
||||
|
||||
|
||||
void CDAudio_SysEject (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_SysCloseDoor (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int CDAudio_SysGetAudioDiskInfo (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
float CDAudio_SysGetVolume (void)
|
||||
{
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_SysSetVolume (float volume)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int CDAudio_SysPlay (int track)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int CDAudio_SysStop (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int CDAudio_SysPause (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CDAudio_SysResume (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CDAudio_SysUpdate (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_SysInit (void)
|
||||
{
|
||||
}
|
||||
|
||||
int CDAudio_SysStartup (void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CDAudio_SysShutdown (void)
|
||||
{
|
||||
}
|
783
app/jni/cd_shared.c
Normal file
783
app/jni/cd_shared.c
Normal file
|
@ -0,0 +1,783 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
|
||||
// rights reserved.
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "cdaudio.h"
|
||||
#include "sound.h"
|
||||
|
||||
// used by menu to ghost CD audio slider
|
||||
cvar_t cdaudioinitialized = {CVAR_READONLY,"cdaudioinitialized","0","indicates if CD Audio system is active"};
|
||||
cvar_t cdaudio = {CVAR_SAVE,"cdaudio","1","CD playing mode (0 = never access CD drive, 1 = play CD tracks if no replacement available, 2 = play fake tracks if no CD track available, 3 = play only real CD tracks, 4 = play real CD tracks even instead of named fake tracks)"};
|
||||
|
||||
#define MAX_PLAYLISTS 10
|
||||
int music_playlist_active = -1;
|
||||
int music_playlist_playing = 0; // 0 = not playing, 1 = playing, -1 = tried and failed
|
||||
|
||||
cvar_t music_playlist_index = {0, "music_playlist_index", "-1", "selects which of the music_playlist_ variables is the active one, -1 disables playlists"};
|
||||
cvar_t music_playlist_list[MAX_PLAYLISTS] =
|
||||
{
|
||||
{0, "music_playlist_list0", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list1", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list2", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list3", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list4", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list5", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list6", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list7", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list8", "", "list of tracks to play"},
|
||||
{0, "music_playlist_list9", "", "list of tracks to play"}
|
||||
};
|
||||
cvar_t music_playlist_current[MAX_PLAYLISTS] =
|
||||
{
|
||||
{0, "music_playlist_current0", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current1", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current2", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current3", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current4", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current5", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current6", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current7", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current8", "0", "current track index to play in list"},
|
||||
{0, "music_playlist_current9", "0", "current track index to play in list"},
|
||||
};
|
||||
cvar_t music_playlist_random[MAX_PLAYLISTS] =
|
||||
{
|
||||
{0, "music_playlist_random0", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random1", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random2", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random3", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random4", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random5", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random6", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random7", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random8", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
{0, "music_playlist_random9", "0", "enables random play order if 1, 0 is sequential play"},
|
||||
};
|
||||
cvar_t music_playlist_sampleposition[MAX_PLAYLISTS] =
|
||||
{
|
||||
{0, "music_playlist_sampleposition0", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition1", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition2", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition3", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition4", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition5", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition6", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition7", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition8", "-1", "resume position for track, -1 restarts every time"},
|
||||
{0, "music_playlist_sampleposition9", "-1", "resume position for track, -1 restarts every time"},
|
||||
};
|
||||
|
||||
static qboolean wasPlaying = false;
|
||||
static qboolean initialized = false;
|
||||
static qboolean enabled = false;
|
||||
static float cdvolume;
|
||||
typedef char filename_t[MAX_QPATH];
|
||||
#ifdef MAXTRACKS
|
||||
static filename_t remap[MAXTRACKS];
|
||||
#endif
|
||||
static unsigned char maxTrack;
|
||||
static int faketrack = -1;
|
||||
|
||||
static float saved_vol = 1.0f;
|
||||
|
||||
// exported variables
|
||||
qboolean cdValid = false;
|
||||
qboolean cdPlaying = false;
|
||||
qboolean cdPlayLooping = false;
|
||||
unsigned char cdPlayTrack;
|
||||
|
||||
cl_cdstate_t cd;
|
||||
|
||||
static void CDAudio_Eject (void)
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if(cdaudio.integer == 0)
|
||||
return;
|
||||
|
||||
CDAudio_SysEject();
|
||||
}
|
||||
|
||||
|
||||
static void CDAudio_CloseDoor (void)
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if(cdaudio.integer == 0)
|
||||
return;
|
||||
|
||||
CDAudio_SysCloseDoor();
|
||||
}
|
||||
|
||||
static int CDAudio_GetAudioDiskInfo (void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cdValid = false;
|
||||
|
||||
if(cdaudio.integer == 0)
|
||||
return -1;
|
||||
|
||||
ret = CDAudio_SysGetAudioDiskInfo();
|
||||
if (ret < 1)
|
||||
return -1;
|
||||
|
||||
cdValid = true;
|
||||
maxTrack = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qboolean CDAudio_Play_real (int track, qboolean looping, qboolean complain)
|
||||
{
|
||||
if(track < 1)
|
||||
{
|
||||
if(complain)
|
||||
Con_Print("Could not load BGM track.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cdValid)
|
||||
{
|
||||
CDAudio_GetAudioDiskInfo();
|
||||
if (!cdValid)
|
||||
{
|
||||
if(complain)
|
||||
Con_DPrint ("No CD in player.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (track > maxTrack)
|
||||
{
|
||||
if(complain)
|
||||
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CDAudio_SysPlay(track) == -1)
|
||||
return false;
|
||||
|
||||
if(cdaudio.integer != 3)
|
||||
Con_DPrintf ("CD track %u playing...\n", track);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDAudio_Play_byName (const char *trackname, qboolean looping, qboolean tryreal, float startposition)
|
||||
{
|
||||
unsigned int track;
|
||||
sfx_t* sfx;
|
||||
char filename[MAX_QPATH];
|
||||
|
||||
Host_StartVideo();
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if(tryreal && strspn(trackname, "0123456789") == strlen(trackname))
|
||||
{
|
||||
track = (unsigned char) atoi(trackname);
|
||||
#ifdef MAXTRACKS
|
||||
if(track > 0 && track < MAXTRACKS)
|
||||
if(*remap[track])
|
||||
{
|
||||
if(strspn(remap[track], "0123456789") == strlen(remap[track]))
|
||||
{
|
||||
trackname = remap[track];
|
||||
}
|
||||
else
|
||||
{
|
||||
// ignore remappings to fake tracks if we're going to play a real track
|
||||
switch(cdaudio.integer)
|
||||
{
|
||||
case 0: // we never access CD
|
||||
case 1: // we have a replacement
|
||||
trackname = remap[track];
|
||||
break;
|
||||
case 2: // we only use fake track replacement if CD track is invalid
|
||||
CDAudio_GetAudioDiskInfo();
|
||||
if(!cdValid || track > maxTrack)
|
||||
trackname = remap[track];
|
||||
break;
|
||||
case 3: // we always play from CD - ignore this remapping then
|
||||
case 4: // we randomize anyway
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(tryreal && strspn(trackname, "0123456789") == strlen(trackname))
|
||||
{
|
||||
track = (unsigned char) atoi(trackname);
|
||||
if (track < 1)
|
||||
{
|
||||
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
track = 0;
|
||||
|
||||
// div0: I assume this code was intentionally there. Maybe turn it into a cvar?
|
||||
if (cdPlaying && cdPlayTrack == track && faketrack == -1)
|
||||
return;
|
||||
CDAudio_Stop ();
|
||||
|
||||
if(track >= 1)
|
||||
{
|
||||
if(cdaudio.integer == 3) // only play real CD tracks at all
|
||||
{
|
||||
if(CDAudio_Play_real(track, looping, true))
|
||||
goto success;
|
||||
return;
|
||||
}
|
||||
|
||||
if(cdaudio.integer == 2) // prefer real CD track over fake
|
||||
{
|
||||
if(CDAudio_Play_real(track, looping, false))
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
|
||||
if(cdaudio.integer == 4) // only play real CD tracks, EVEN instead of fake tracks!
|
||||
{
|
||||
if(CDAudio_Play_real(track, looping, false))
|
||||
goto success;
|
||||
|
||||
if(cdValid && maxTrack > 0)
|
||||
{
|
||||
track = 1 + (rand() % maxTrack);
|
||||
if(CDAudio_Play_real(track, looping, true))
|
||||
goto success;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrint ("No CD in player.\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Try playing a fake track (sound file) first
|
||||
if(track >= 1)
|
||||
{
|
||||
dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%03u.wav", track);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%03u.ogg", track);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/track%03u.ogg", track);// added by motorsep
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/cdtracks/track%03u.ogg", track);// added by motorsep
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%02u.wav", track);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%02u.ogg", track);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/track%02u.ogg", track);// added by motorsep
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/cdtracks/track%02u.ogg", track);// added by motorsep
|
||||
}
|
||||
else
|
||||
{
|
||||
dpsnprintf(filename, sizeof(filename), "%s", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "%s.wav", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "%s.ogg", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/%s", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/%s.wav", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/%s.ogg", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/%s", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/%s.wav", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/%s.ogg", trackname);
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/%s.ogg", trackname); // added by motorsep
|
||||
if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/cdtracks/%s.ogg", trackname); // added by motorsep
|
||||
}
|
||||
if (FS_FileExists(filename) && (sfx = S_PrecacheSound (filename, false, false)))
|
||||
{
|
||||
faketrack = S_StartSound_StartPosition_Flags (-1, 0, sfx, vec3_origin, cdvolume, 0, startposition, (looping ? CHANNELFLAG_FORCELOOP : 0) | CHANNELFLAG_FULLVOLUME | CHANNELFLAG_LOCALSOUND, 1.0f);
|
||||
if (faketrack != -1)
|
||||
{
|
||||
if(track >= 1)
|
||||
{
|
||||
if(cdaudio.integer != 0) // we don't need these messages if only fake tracks can be played anyway
|
||||
Con_DPrintf ("Fake CD track %u playing...\n", track);
|
||||
}
|
||||
else
|
||||
Con_DPrintf ("BGM track %s playing...\n", trackname);
|
||||
}
|
||||
}
|
||||
|
||||
// If we can't play a fake CD track, try the real one
|
||||
if (faketrack == -1)
|
||||
{
|
||||
if(cdaudio.integer == 0 || track < 1)
|
||||
{
|
||||
Con_Print("Could not load BGM track.\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!CDAudio_Play_real(track, looping, true))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
success:
|
||||
cdPlayLooping = looping;
|
||||
cdPlayTrack = track;
|
||||
cdPlaying = true;
|
||||
|
||||
if (cdvolume == 0.0 || bgmvolume.value == 0)
|
||||
CDAudio_Pause ();
|
||||
}
|
||||
|
||||
void CDAudio_Play (int track, qboolean looping)
|
||||
{
|
||||
char buf[20];
|
||||
if (music_playlist_index.integer >= 0)
|
||||
return;
|
||||
dpsnprintf(buf, sizeof(buf), "%d", (int) track);
|
||||
CDAudio_Play_byName(buf, looping, true, 0);
|
||||
}
|
||||
|
||||
float CDAudio_GetPosition (void)
|
||||
{
|
||||
if(faketrack != -1)
|
||||
return S_GetChannelPosition(faketrack);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void CDAudio_StopPlaylistTrack(void);
|
||||
|
||||
void CDAudio_Stop (void)
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
// save the playlist position
|
||||
CDAudio_StopPlaylistTrack();
|
||||
|
||||
if (faketrack != -1)
|
||||
{
|
||||
S_StopChannel (faketrack, true, true);
|
||||
faketrack = -1;
|
||||
}
|
||||
else if (cdPlaying && (CDAudio_SysStop() == -1))
|
||||
return;
|
||||
else if(wasPlaying)
|
||||
{
|
||||
CDAudio_Resume(); // needed by SDL - can't stop while paused there (causing pause/stop to fail after play, pause, stop, play otherwise)
|
||||
if (cdPlaying && (CDAudio_SysStop() == -1))
|
||||
return;
|
||||
}
|
||||
|
||||
wasPlaying = false;
|
||||
cdPlaying = false;
|
||||
}
|
||||
|
||||
void CDAudio_Pause (void)
|
||||
{
|
||||
if (!enabled || !cdPlaying)
|
||||
return;
|
||||
|
||||
if (faketrack != -1)
|
||||
S_SetChannelFlag (faketrack, CHANNELFLAG_PAUSED, true);
|
||||
else if (CDAudio_SysPause() == -1)
|
||||
return;
|
||||
|
||||
wasPlaying = cdPlaying;
|
||||
cdPlaying = false;
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_Resume (void)
|
||||
{
|
||||
if (!enabled || cdPlaying || !wasPlaying)
|
||||
return;
|
||||
|
||||
if (faketrack != -1)
|
||||
S_SetChannelFlag (faketrack, CHANNELFLAG_PAUSED, false);
|
||||
else if (CDAudio_SysResume() == -1)
|
||||
return;
|
||||
cdPlaying = true;
|
||||
}
|
||||
|
||||
static void CD_f (void)
|
||||
{
|
||||
const char *command;
|
||||
#ifdef MAXTRACKS
|
||||
int ret;
|
||||
int n;
|
||||
#endif
|
||||
|
||||
command = Cmd_Argv (1);
|
||||
|
||||
if (strcasecmp(command, "remap") != 0)
|
||||
Host_StartVideo();
|
||||
|
||||
if (strcasecmp(command, "on") == 0)
|
||||
{
|
||||
enabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "off") == 0)
|
||||
{
|
||||
CDAudio_Stop();
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "reset") == 0)
|
||||
{
|
||||
enabled = true;
|
||||
CDAudio_Stop();
|
||||
#ifdef MAXTRACKS
|
||||
for (n = 0; n < MAXTRACKS; n++)
|
||||
*remap[n] = 0; // empty string, that is, unremapped
|
||||
#endif
|
||||
CDAudio_GetAudioDiskInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "rescan") == 0)
|
||||
{
|
||||
CDAudio_Shutdown();
|
||||
CDAudio_Startup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "remap") == 0)
|
||||
{
|
||||
#ifdef MAXTRACKS
|
||||
ret = Cmd_Argc() - 2;
|
||||
if (ret <= 0)
|
||||
{
|
||||
for (n = 1; n < MAXTRACKS; n++)
|
||||
if (*remap[n])
|
||||
Con_Printf(" %u -> %s\n", n, remap[n]);
|
||||
return;
|
||||
}
|
||||
for (n = 1; n <= ret; n++)
|
||||
strlcpy(remap[n], Cmd_Argv (n+1), sizeof(*remap));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "close") == 0)
|
||||
{
|
||||
CDAudio_CloseDoor();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "play") == 0)
|
||||
{
|
||||
if (music_playlist_index.integer >= 0)
|
||||
return;
|
||||
CDAudio_Play_byName(Cmd_Argv (2), false, true, (Cmd_Argc() > 3) ? atof( Cmd_Argv(3) ) : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "loop") == 0)
|
||||
{
|
||||
if (music_playlist_index.integer >= 0)
|
||||
return;
|
||||
CDAudio_Play_byName(Cmd_Argv (2), true, true, (Cmd_Argc() > 3) ? atof( Cmd_Argv(3) ) : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "stop") == 0)
|
||||
{
|
||||
if (music_playlist_index.integer >= 0)
|
||||
return;
|
||||
CDAudio_Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "pause") == 0)
|
||||
{
|
||||
if (music_playlist_index.integer >= 0)
|
||||
return;
|
||||
CDAudio_Pause();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "resume") == 0)
|
||||
{
|
||||
if (music_playlist_index.integer >= 0)
|
||||
return;
|
||||
CDAudio_Resume();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "eject") == 0)
|
||||
{
|
||||
if (faketrack == -1)
|
||||
CDAudio_Stop();
|
||||
CDAudio_Eject();
|
||||
cdValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(command, "info") == 0)
|
||||
{
|
||||
CDAudio_GetAudioDiskInfo ();
|
||||
if (cdValid)
|
||||
Con_Printf("%u tracks on CD.\n", maxTrack);
|
||||
else
|
||||
Con_Print ("No CD in player.\n");
|
||||
if (cdPlaying)
|
||||
Con_Printf("Currently %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
|
||||
else if (wasPlaying)
|
||||
Con_Printf("Paused %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
|
||||
if (cdvolume >= 0)
|
||||
Con_Printf("Volume is %f\n", cdvolume);
|
||||
else
|
||||
Con_Printf("Can't get CD volume\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf("CD commands:\n");
|
||||
Con_Printf("cd on - enables CD audio system\n");
|
||||
Con_Printf("cd off - stops and disables CD audio system\n");
|
||||
Con_Printf("cd reset - resets CD audio system (clears track remapping and re-reads disc information)\n");
|
||||
Con_Printf("cd rescan - rescans disks in drives (to use another disc)\n");
|
||||
Con_Printf("cd remap <remap1> [remap2] [remap3] [...] - chooses (possibly emulated) CD tracks to play when a map asks for a particular track, this has many uses\n");
|
||||
Con_Printf("cd close - closes CD tray\n");
|
||||
Con_Printf("cd eject - stops playing music and opens CD tray to allow you to change disc\n");
|
||||
Con_Printf("cd play <tracknumber> <startposition> - plays selected track in remapping table\n");
|
||||
Con_Printf("cd loop <tracknumber> <startposition> - plays and repeats selected track in remapping table\n");
|
||||
Con_Printf("cd stop - stops playing current CD track\n");
|
||||
Con_Printf("cd pause - pauses CD playback\n");
|
||||
Con_Printf("cd resume - unpauses CD playback\n");
|
||||
Con_Printf("cd info - prints basic disc information (number of tracks, currently playing track, volume level)\n");
|
||||
}
|
||||
|
||||
static void CDAudio_SetVolume (float newvol)
|
||||
{
|
||||
// If the volume hasn't changed
|
||||
if (newvol == cdvolume)
|
||||
return;
|
||||
|
||||
// If the CD has been muted
|
||||
if (newvol == 0.0f)
|
||||
CDAudio_Pause ();
|
||||
else
|
||||
{
|
||||
// If the CD has been unmuted
|
||||
if (cdvolume == 0.0f)
|
||||
CDAudio_Resume ();
|
||||
|
||||
if (faketrack != -1)
|
||||
S_SetChannelVolume (faketrack, newvol);
|
||||
else
|
||||
CDAudio_SysSetVolume (newvol * mastervolume.value);
|
||||
}
|
||||
|
||||
cdvolume = newvol;
|
||||
}
|
||||
|
||||
static void CDAudio_StopPlaylistTrack(void)
|
||||
{
|
||||
if (music_playlist_active >= 0 && music_playlist_active < MAX_PLAYLISTS && music_playlist_sampleposition[music_playlist_active].value >= 0)
|
||||
{
|
||||
// save position for resume
|
||||
float position = CDAudio_GetPosition();
|
||||
Cvar_SetValueQuick(&music_playlist_sampleposition[music_playlist_active], position >= 0 ? position : 0);
|
||||
}
|
||||
music_playlist_active = -1;
|
||||
music_playlist_playing = 0; // not playing
|
||||
}
|
||||
|
||||
void CDAudio_StartPlaylist(qboolean resume)
|
||||
{
|
||||
const char *list;
|
||||
const char *t;
|
||||
int index;
|
||||
int current;
|
||||
int randomplay;
|
||||
int count;
|
||||
int listindex;
|
||||
float position;
|
||||
char trackname[MAX_QPATH];
|
||||
CDAudio_Stop();
|
||||
index = music_playlist_index.integer;
|
||||
if (index >= 0 && index < MAX_PLAYLISTS && bgmvolume.value > 0)
|
||||
{
|
||||
list = music_playlist_list[index].string;
|
||||
current = music_playlist_current[index].integer;
|
||||
randomplay = music_playlist_random[index].integer;
|
||||
position = music_playlist_sampleposition[index].value;
|
||||
count = 0;
|
||||
trackname[0] = 0;
|
||||
if (list && list[0])
|
||||
{
|
||||
for (t = list;;count++)
|
||||
{
|
||||
if (!COM_ParseToken_Console(&t))
|
||||
break;
|
||||
// if we don't find the desired track, use the first one
|
||||
if (count == 0)
|
||||
strlcpy(trackname, com_token, sizeof(trackname));
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
{
|
||||
// position < 0 means never resume track
|
||||
if (position < 0)
|
||||
position = 0;
|
||||
// advance to next track in playlist if the last one ended
|
||||
if (!resume)
|
||||
{
|
||||
position = 0;
|
||||
current++;
|
||||
if (randomplay)
|
||||
current = (int)lhrandom(0, count);
|
||||
}
|
||||
// wrap playlist position if needed
|
||||
if (current >= count)
|
||||
current = 0;
|
||||
// set current
|
||||
Cvar_SetValueQuick(&music_playlist_current[index], current);
|
||||
// get the Nth trackname
|
||||
if (current >= 0 && current < count)
|
||||
{
|
||||
for (listindex = 0, t = list;;listindex++)
|
||||
{
|
||||
if (!COM_ParseToken_Console(&t))
|
||||
break;
|
||||
if (listindex == current)
|
||||
{
|
||||
strlcpy(trackname, com_token, sizeof(trackname));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (trackname[0])
|
||||
{
|
||||
CDAudio_Play_byName(trackname, false, false, position);
|
||||
if (faketrack != -1)
|
||||
music_playlist_active = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
music_playlist_playing = music_playlist_active >= 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
void CDAudio_Update (void)
|
||||
{
|
||||
static int lastplaylist = -1;
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
CDAudio_SetVolume (bgmvolume.value);
|
||||
if (music_playlist_playing > 0 && CDAudio_GetPosition() < 0)
|
||||
{
|
||||
// this track ended, start a new track from the beginning
|
||||
CDAudio_StartPlaylist(false);
|
||||
lastplaylist = music_playlist_index.integer;
|
||||
}
|
||||
else if (lastplaylist != music_playlist_index.integer
|
||||
|| (bgmvolume.value > 0 && !music_playlist_playing && music_playlist_index.integer >= 0))
|
||||
{
|
||||
// active playlist changed, save position and switch track
|
||||
CDAudio_StartPlaylist(true);
|
||||
lastplaylist = music_playlist_index.integer;
|
||||
}
|
||||
|
||||
if (faketrack == -1 && cdaudio.integer != 0 && bgmvolume.value != 0)
|
||||
CDAudio_SysUpdate();
|
||||
}
|
||||
|
||||
int CDAudio_Init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cls.state == ca_dedicated)
|
||||
return -1;
|
||||
|
||||
// COMMANDLINEOPTION: Sound: -nocdaudio disables CD audio support
|
||||
if (COM_CheckParm("-nocdaudio"))
|
||||
return -1;
|
||||
|
||||
CDAudio_SysInit();
|
||||
|
||||
#ifdef MAXTRACKS
|
||||
for (i = 0; i < MAXTRACKS; i++)
|
||||
*remap[i] = 0;
|
||||
#endif
|
||||
|
||||
Cvar_RegisterVariable(&cdaudio);
|
||||
Cvar_RegisterVariable(&cdaudioinitialized);
|
||||
Cvar_SetValueQuick(&cdaudioinitialized, true);
|
||||
enabled = true;
|
||||
|
||||
Cvar_RegisterVariable(&music_playlist_index);
|
||||
for (i = 0;i < MAX_PLAYLISTS;i++)
|
||||
{
|
||||
Cvar_RegisterVariable(&music_playlist_list[i]);
|
||||
Cvar_RegisterVariable(&music_playlist_current[i]);
|
||||
Cvar_RegisterVariable(&music_playlist_random[i]);
|
||||
Cvar_RegisterVariable(&music_playlist_sampleposition[i]);
|
||||
}
|
||||
|
||||
Cmd_AddCommand("cd", CD_f, "execute a CD drive command (cd on/off/reset/remap/close/play/loop/stop/pause/resume/eject/info) - use cd by itself for usage");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CDAudio_Startup (void)
|
||||
{
|
||||
if (COM_CheckParm("-nocdaudio"))
|
||||
return -1;
|
||||
|
||||
CDAudio_SysStartup ();
|
||||
|
||||
if (CDAudio_GetAudioDiskInfo())
|
||||
{
|
||||
Con_Print("CDAudio_Init: No CD in player.\n");
|
||||
cdValid = false;
|
||||
}
|
||||
|
||||
saved_vol = CDAudio_SysGetVolume ();
|
||||
if (saved_vol < 0.0f)
|
||||
{
|
||||
Con_Print ("Can't get initial CD volume\n");
|
||||
saved_vol = 1.0f;
|
||||
}
|
||||
else
|
||||
Con_Printf ("Initial CD volume: %g\n", saved_vol);
|
||||
|
||||
initialized = true;
|
||||
|
||||
Con_Print("CD Audio Initialized\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDAudio_Shutdown (void)
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
|
||||
CDAudio_SysSetVolume (saved_vol);
|
||||
|
||||
CDAudio_Stop();
|
||||
CDAudio_SysShutdown();
|
||||
initialized = false;
|
||||
}
|
66
app/jni/cdaudio.h
Normal file
66
app/jni/cdaudio.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
typedef struct cl_cdstate_s
|
||||
{
|
||||
qboolean Valid;
|
||||
qboolean Playing;
|
||||
qboolean PlayLooping;
|
||||
unsigned char PlayTrack;
|
||||
}
|
||||
cl_cdstate_t;
|
||||
|
||||
//extern cl_cdstate_t cd;
|
||||
|
||||
extern qboolean cdValid;
|
||||
extern qboolean cdPlaying;
|
||||
extern qboolean cdPlayLooping;
|
||||
extern unsigned char cdPlayTrack;
|
||||
|
||||
extern cvar_t cdaudioinitialized;
|
||||
|
||||
int CDAudio_Init(void);
|
||||
void CDAudio_Open(void);
|
||||
void CDAudio_Close(void);
|
||||
void CDAudio_Play(int track, qboolean looping);
|
||||
void CDAudio_Play_byName (const char *trackname, qboolean looping, qboolean tryreal, float startposition);
|
||||
void CDAudio_Stop(void);
|
||||
void CDAudio_Pause(void);
|
||||
void CDAudio_Resume(void);
|
||||
int CDAudio_Startup(void);
|
||||
void CDAudio_Shutdown(void);
|
||||
void CDAudio_Update(void);
|
||||
float CDAudio_GetPosition(void);
|
||||
void CDAudio_StartPlaylist(qboolean resume);
|
||||
|
||||
// Prototypes of the system dependent functions
|
||||
void CDAudio_SysEject (void);
|
||||
void CDAudio_SysCloseDoor (void);
|
||||
int CDAudio_SysGetAudioDiskInfo (void);
|
||||
float CDAudio_SysGetVolume (void);
|
||||
void CDAudio_SysSetVolume (float volume);
|
||||
int CDAudio_SysPlay (int track);
|
||||
int CDAudio_SysStop (void);
|
||||
int CDAudio_SysPause (void);
|
||||
int CDAudio_SysResume (void);
|
||||
int CDAudio_SysUpdate (void);
|
||||
void CDAudio_SysInit (void);
|
||||
int CDAudio_SysStartup (void);
|
||||
void CDAudio_SysShutdown (void);
|
30
app/jni/cflags.mk
Normal file
30
app/jni/cflags.mk
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This file is included in all .mk files to ensure their compilation flags are in sync
|
||||
# across debug and release builds.
|
||||
|
||||
# NOTE: this is not part of import_vrlib.mk because VRLib itself needs to have these flags
|
||||
# set, but VRLib's make file cannot include import_vrlib.mk or it would be importing itself.
|
||||
|
||||
LOCAL_CFLAGS := -DANDROID_NDK
|
||||
LOCAL_CFLAGS += -Werror # error on warnings
|
||||
LOCAL_CFLAGS += -Wall
|
||||
LOCAL_CFLAGS += -Wextra
|
||||
#LOCAL_CFLAGS += -Wlogical-op # not part of -Wall or -Wextra
|
||||
#LOCAL_CFLAGS += -Weffc++ # too many issues to fix for now
|
||||
LOCAL_CFLAGS += -Wno-strict-aliasing # TODO: need to rewrite some code
|
||||
LOCAL_CFLAGS += -Wno-unused-parameter
|
||||
LOCAL_CFLAGS += -Wno-missing-field-initializers # warns on this: SwipeAction ret = {}
|
||||
LOCAL_CFLAGS += -Wno-multichar # used in internal Android headers: DISPLAY_EVENT_VSYNC = 'vsyn',
|
||||
LOCAL_CPPFLAGS := -Wno-type-limits
|
||||
LOCAL_CPPFLAGS += -Wno-invalid-offsetof
|
||||
|
||||
# disable deprecation errors, but keep the warnings
|
||||
LOCAL_CFLAGS += -Wno-error=deprecated-declarations
|
||||
|
||||
ifeq ($(OVR_DEBUG),1)
|
||||
LOCAL_CFLAGS += -DOVR_BUILD_DEBUG=1 -O0 -g
|
||||
else
|
||||
LOCAL_CFLAGS += -O3
|
||||
endif
|
||||
|
||||
# Explicitly compile for the ARM and not the Thumb instruction set.
|
||||
LOCAL_ARM_MODE := arm
|
1079
app/jni/cl_collision.c
Normal file
1079
app/jni/cl_collision.c
Normal file
File diff suppressed because it is too large
Load diff
19
app/jni/cl_collision.h
Normal file
19
app/jni/cl_collision.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef CL_COLLISION_H
|
||||
#define CL_COLLISION_H
|
||||
|
||||
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent);
|
||||
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
|
||||
|
||||
dp_model_t *CL_GetModelByIndex(int modelindex);
|
||||
dp_model_t *CL_GetModelFromEdict(prvm_edict_t *ed);
|
||||
|
||||
void CL_LinkEdict(prvm_edict_t *ent);
|
||||
int CL_GenericHitSuperContentsMask(const prvm_edict_t *edict);
|
||||
trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
|
||||
trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces);
|
||||
trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
|
||||
trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask);
|
||||
#define CL_PointSuperContents(point) (CL_TracePoint((point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0, true, false, NULL, false).startsupercontents)
|
||||
|
||||
#endif
|
617
app/jni/cl_demo.c
Normal file
617
app/jni/cl_demo.c
Normal file
|
@ -0,0 +1,617 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
extern cvar_t cl_capturevideo;
|
||||
extern cvar_t cl_capturevideo_demo_stop;
|
||||
int old_vsync = 0;
|
||||
|
||||
static void CL_FinishTimeDemo (void);
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
DEMO CODE
|
||||
|
||||
When a demo is playing back, all outgoing network messages are skipped, and
|
||||
incoming messages are read from the demo file.
|
||||
|
||||
Whenever cl.time gets past the last received message, another message is
|
||||
read from the demo file.
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_NextDemo
|
||||
|
||||
Called to play the next demo in the demo loop
|
||||
=====================
|
||||
*/
|
||||
void CL_NextDemo (void)
|
||||
{
|
||||
char str[MAX_INPUTLINE];
|
||||
|
||||
if (cls.demonum == -1)
|
||||
return; // don't play demos
|
||||
|
||||
if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS)
|
||||
{
|
||||
cls.demonum = 0;
|
||||
if (!cls.demos[cls.demonum][0])
|
||||
{
|
||||
Con_Print("No demos listed with startdemos\n");
|
||||
cls.demonum = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dpsnprintf (str, sizeof(str), "playdemo %s\n", cls.demos[cls.demonum]);
|
||||
Cbuf_InsertText (str);
|
||||
cls.demonum++;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CL_StopPlayback
|
||||
|
||||
Called when a demo file runs out, or the user starts a game
|
||||
==============
|
||||
*/
|
||||
// LordHavoc: now called only by CL_Disconnect
|
||||
void CL_StopPlayback (void)
|
||||
{
|
||||
if (cl_capturevideo_demo_stop.integer)
|
||||
Cvar_Set("cl_capturevideo", "0");
|
||||
|
||||
if (!cls.demoplayback)
|
||||
return;
|
||||
|
||||
FS_Close (cls.demofile);
|
||||
cls.demoplayback = false;
|
||||
cls.demofile = NULL;
|
||||
|
||||
if (cls.timedemo)
|
||||
CL_FinishTimeDemo ();
|
||||
|
||||
if (!cls.demostarting) // only quit if not starting another demo
|
||||
if (COM_CheckParm("-demo") || COM_CheckParm("-capturedemo"))
|
||||
Host_Quit_f();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_WriteDemoMessage
|
||||
|
||||
Dumps the current net message, prefixed by the length and view angles
|
||||
#====================
|
||||
*/
|
||||
void CL_WriteDemoMessage (sizebuf_t *message)
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
float f;
|
||||
|
||||
if (cls.demopaused) // LordHavoc: pausedemo
|
||||
return;
|
||||
|
||||
len = LittleLong (message->cursize);
|
||||
FS_Write (cls.demofile, &len, 4);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
f = LittleFloat (cl.viewangles[i]);
|
||||
FS_Write (cls.demofile, &f, 4);
|
||||
}
|
||||
FS_Write (cls.demofile, message->data, message->cursize);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_CutDemo
|
||||
|
||||
Dumps the current demo to a buffer, and resets the demo to its starting point.
|
||||
Used to insert csprogs.dat files as a download to the beginning of a demo file.
|
||||
====================
|
||||
*/
|
||||
void CL_CutDemo (unsigned char **buf, fs_offset_t *filesize)
|
||||
{
|
||||
*buf = NULL;
|
||||
*filesize = 0;
|
||||
|
||||
FS_Close(cls.demofile);
|
||||
*buf = FS_LoadFile(cls.demoname, tempmempool, false, filesize);
|
||||
|
||||
// restart the demo recording
|
||||
cls.demofile = FS_OpenRealFile(cls.demoname, "wb", false);
|
||||
if(!cls.demofile)
|
||||
Sys_Error("failed to reopen the demo file");
|
||||
FS_Printf(cls.demofile, "%i\n", cls.forcetrack);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_PasteDemo
|
||||
|
||||
Adds the cut stuff back to the demo. Also frees the buffer.
|
||||
Used to insert csprogs.dat files as a download to the beginning of a demo file.
|
||||
====================
|
||||
*/
|
||||
void CL_PasteDemo (unsigned char **buf, fs_offset_t *filesize)
|
||||
{
|
||||
fs_offset_t startoffset = 0;
|
||||
|
||||
if(!*buf)
|
||||
return;
|
||||
|
||||
// skip cdtrack
|
||||
while(startoffset < *filesize && ((char *)(*buf))[startoffset] != '\n')
|
||||
++startoffset;
|
||||
if(startoffset < *filesize)
|
||||
++startoffset;
|
||||
|
||||
FS_Write(cls.demofile, *buf + startoffset, *filesize - startoffset);
|
||||
|
||||
Mem_Free(*buf);
|
||||
*buf = NULL;
|
||||
*filesize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_ReadDemoMessage
|
||||
|
||||
Handles playback of demos
|
||||
====================
|
||||
*/
|
||||
void CL_ReadDemoMessage(void)
|
||||
{
|
||||
int i;
|
||||
float f;
|
||||
|
||||
if (!cls.demoplayback)
|
||||
return;
|
||||
|
||||
// LordHavoc: pausedemo
|
||||
if (cls.demopaused)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// decide if it is time to grab the next message
|
||||
// always grab until fully connected
|
||||
if (cls.signon == SIGNONS)
|
||||
{
|
||||
if (cls.timedemo)
|
||||
{
|
||||
cls.td_frames++;
|
||||
cls.td_onesecondframes++;
|
||||
// if this is the first official frame we can now grab the real
|
||||
// td_starttime so the bogus time on the first frame doesn't
|
||||
// count against the final report
|
||||
if (cls.td_frames == 0)
|
||||
{
|
||||
cls.td_starttime = realtime;
|
||||
cls.td_onesecondnexttime = cl.time + 1;
|
||||
cls.td_onesecondrealtime = realtime;
|
||||
cls.td_onesecondframes = 0;
|
||||
cls.td_onesecondminfps = 0;
|
||||
cls.td_onesecondmaxfps = 0;
|
||||
cls.td_onesecondavgfps = 0;
|
||||
cls.td_onesecondavgcount = 0;
|
||||
}
|
||||
if (cl.time >= cls.td_onesecondnexttime)
|
||||
{
|
||||
double fps = cls.td_onesecondframes / (realtime - cls.td_onesecondrealtime);
|
||||
if (cls.td_onesecondavgcount == 0)
|
||||
{
|
||||
cls.td_onesecondminfps = fps;
|
||||
cls.td_onesecondmaxfps = fps;
|
||||
}
|
||||
cls.td_onesecondrealtime = realtime;
|
||||
cls.td_onesecondminfps = min(cls.td_onesecondminfps, fps);
|
||||
cls.td_onesecondmaxfps = max(cls.td_onesecondmaxfps, fps);
|
||||
cls.td_onesecondavgfps += fps;
|
||||
cls.td_onesecondavgcount++;
|
||||
cls.td_onesecondframes = 0;
|
||||
cls.td_onesecondnexttime++;
|
||||
}
|
||||
}
|
||||
else if (cl.time <= cl.mtime[0])
|
||||
{
|
||||
// don't need another message yet
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// get the next message
|
||||
FS_Read(cls.demofile, &cl_message.cursize, 4);
|
||||
cl_message.cursize = LittleLong(cl_message.cursize);
|
||||
if(cl_message.cursize & DEMOMSG_CLIENT_TO_SERVER) // This is a client->server message! Ignore for now!
|
||||
{
|
||||
// skip over demo packet
|
||||
FS_Seek(cls.demofile, 12 + (cl_message.cursize & (~DEMOMSG_CLIENT_TO_SERVER)), SEEK_CUR);
|
||||
continue;
|
||||
}
|
||||
if (cl_message.cursize > cl_message.maxsize)
|
||||
{
|
||||
Con_Printf("Demo message (%i) > cl_message.maxsize (%i)", cl_message.cursize, cl_message.maxsize);
|
||||
cl_message.cursize = 0;
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
VectorCopy(cl.mviewangles[0], cl.mviewangles[1]);
|
||||
for (i = 0;i < 3;i++)
|
||||
{
|
||||
FS_Read(cls.demofile, &f, 4);
|
||||
cl.mviewangles[0][i] = LittleFloat(f);
|
||||
}
|
||||
|
||||
if (FS_Read(cls.demofile, cl_message.data, cl_message.cursize) == cl_message.cursize)
|
||||
{
|
||||
MSG_BeginReading(&cl_message);
|
||||
CL_ParseServerMessage();
|
||||
|
||||
if (cls.signon != SIGNONS)
|
||||
Cbuf_Execute(); // immediately execute svc_stufftext if in the demo before connect!
|
||||
|
||||
// In case the demo contains a "svc_disconnect" message
|
||||
if (!cls.demoplayback)
|
||||
return;
|
||||
|
||||
if (cls.timedemo)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_Stop_f
|
||||
|
||||
stop recording a demo
|
||||
====================
|
||||
*/
|
||||
void CL_Stop_f (void)
|
||||
{
|
||||
sizebuf_t buf;
|
||||
unsigned char bufdata[64];
|
||||
|
||||
if (!cls.demorecording)
|
||||
{
|
||||
Con_Print("Not recording a demo.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// write a disconnect message to the demo file
|
||||
// LordHavoc: don't replace the cl_message when doing this
|
||||
buf.data = bufdata;
|
||||
buf.maxsize = sizeof(bufdata);
|
||||
SZ_Clear(&buf);
|
||||
MSG_WriteByte(&buf, svc_disconnect);
|
||||
CL_WriteDemoMessage(&buf);
|
||||
|
||||
// finish up
|
||||
if(cl_autodemo.integer && (cl_autodemo_delete.integer & 1))
|
||||
{
|
||||
FS_RemoveOnClose(cls.demofile);
|
||||
Con_Print("Completed and deleted demo\n");
|
||||
}
|
||||
else
|
||||
Con_Print("Completed demo\n");
|
||||
FS_Close (cls.demofile);
|
||||
cls.demofile = NULL;
|
||||
cls.demorecording = false;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_Record_f
|
||||
|
||||
record <demoname> <map> [cd track]
|
||||
====================
|
||||
*/
|
||||
void CL_Record_f (void)
|
||||
{
|
||||
int c, track;
|
||||
char name[MAX_OSPATH];
|
||||
char vabuf[1024];
|
||||
|
||||
c = Cmd_Argc();
|
||||
if (c != 2 && c != 3 && c != 4)
|
||||
{
|
||||
Con_Print("record <demoname> [<map> [cd track]]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strstr(Cmd_Argv(1), ".."))
|
||||
{
|
||||
Con_Print("Relative pathnames are not allowed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == 2 && cls.state == ca_connected)
|
||||
{
|
||||
Con_Print("Can not record - already connected to server\nClient demo recording must be started before connecting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cls.state == ca_connected)
|
||||
CL_Disconnect();
|
||||
|
||||
// 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;
|
||||
|
||||
// get the demo name
|
||||
strlcpy (name, Cmd_Argv(1), sizeof (name));
|
||||
FS_DefaultExtension (name, ".dem", sizeof (name));
|
||||
|
||||
// start the map up
|
||||
if (c > 2)
|
||||
Cmd_ExecuteString ( va(vabuf, sizeof(vabuf), "map %s", Cmd_Argv(2)), src_command, false);
|
||||
|
||||
// open the demo file
|
||||
Con_Printf("recording to %s.\n", name);
|
||||
cls.demofile = FS_OpenRealFile(name, "wb", false);
|
||||
if (!cls.demofile)
|
||||
{
|
||||
Con_Print("ERROR: couldn't open.\n");
|
||||
return;
|
||||
}
|
||||
strlcpy(cls.demoname, name, sizeof(cls.demoname));
|
||||
|
||||
cls.forcetrack = track;
|
||||
FS_Printf(cls.demofile, "%i\n", cls.forcetrack);
|
||||
|
||||
cls.demorecording = true;
|
||||
cls.demo_lastcsprogssize = -1;
|
||||
cls.demo_lastcsprogscrc = -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_PlayDemo_f
|
||||
|
||||
play [demoname]
|
||||
====================
|
||||
*/
|
||||
void CL_PlayDemo_f (void)
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
int c;
|
||||
qboolean neg = false;
|
||||
qfile_t *f;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Con_Print("play <demoname> : plays a demo\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// open the demo file
|
||||
strlcpy (name, Cmd_Argv(1), sizeof (name));
|
||||
FS_DefaultExtension (name, ".dem", sizeof (name));
|
||||
f = FS_OpenVirtualFile(name, false);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf("ERROR: couldn't open %s.\n", name);
|
||||
cls.demonum = -1; // stop demo loop
|
||||
return;
|
||||
}
|
||||
|
||||
cls.demostarting = true;
|
||||
|
||||
// disconnect from server
|
||||
CL_Disconnect ();
|
||||
Host_ShutdownServer ();
|
||||
|
||||
// update networking ports (this is mainly just needed at startup)
|
||||
NetConn_UpdateSockets();
|
||||
|
||||
cls.protocol = PROTOCOL_QUAKE;
|
||||
|
||||
Con_Printf("Playing demo %s.\n", name);
|
||||
cls.demofile = f;
|
||||
strlcpy(cls.demoname, name, sizeof(cls.demoname));
|
||||
|
||||
cls.demoplayback = true;
|
||||
cls.state = ca_connected;
|
||||
cls.forcetrack = 0;
|
||||
|
||||
while ((c = FS_Getc (cls.demofile)) != '\n')
|
||||
if (c == '-')
|
||||
neg = true;
|
||||
else
|
||||
cls.forcetrack = cls.forcetrack * 10 + (c - '0');
|
||||
|
||||
if (neg)
|
||||
cls.forcetrack = -cls.forcetrack;
|
||||
|
||||
cls.demostarting = false;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int frames;
|
||||
double time, totalfpsavg;
|
||||
double fpsmin, fpsavg, fpsmax;
|
||||
}
|
||||
benchmarkhistory_t;
|
||||
static size_t doublecmp_offset;
|
||||
static int doublecmp_withoffset(const void *a_, const void *b_)
|
||||
{
|
||||
const double *a = (const double *) ((const char *) a_ + doublecmp_offset);
|
||||
const double *b = (const double *) ((const char *) b_ + doublecmp_offset);
|
||||
if(*a > *b)
|
||||
return +1;
|
||||
if(*a < *b)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_FinishTimeDemo
|
||||
|
||||
====================
|
||||
*/
|
||||
static void CL_FinishTimeDemo (void)
|
||||
{
|
||||
int frames;
|
||||
int i;
|
||||
double time, totalfpsavg;
|
||||
double fpsmin, fpsavg, fpsmax; // report min/avg/max fps
|
||||
static int benchmark_runs = 0;
|
||||
char vabuf[1024];
|
||||
|
||||
cls.timedemo = false;
|
||||
|
||||
frames = cls.td_frames;
|
||||
time = realtime - cls.td_starttime;
|
||||
totalfpsavg = time > 0 ? frames / time : 0;
|
||||
fpsmin = cls.td_onesecondminfps;
|
||||
fpsavg = cls.td_onesecondavgcount ? cls.td_onesecondavgfps / cls.td_onesecondavgcount : 0;
|
||||
fpsmax = cls.td_onesecondmaxfps;
|
||||
// LordHavoc: timedemo now prints out 7 digits of fraction, and min/avg/max
|
||||
Con_Printf("%i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount);
|
||||
Log_Printf("benchmark.log", "date %s | enginedate %s | demo %s | commandline %s | run %d | result %i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", Sys_TimeString("%Y-%m-%d %H:%M:%S"), buildstring, cls.demoname, cmdline.string, benchmark_runs + 1, frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount);
|
||||
if (COM_CheckParm("-benchmark"))
|
||||
{
|
||||
++benchmark_runs;
|
||||
i = COM_CheckParm("-benchmarkruns");
|
||||
if(i && i + 1 < com_argc)
|
||||
{
|
||||
static benchmarkhistory_t *history = NULL;
|
||||
if(!history)
|
||||
history = (benchmarkhistory_t *)Z_Malloc(sizeof(*history) * atoi(com_argv[i + 1]));
|
||||
|
||||
history[benchmark_runs - 1].frames = frames;
|
||||
history[benchmark_runs - 1].time = time;
|
||||
history[benchmark_runs - 1].totalfpsavg = totalfpsavg;
|
||||
history[benchmark_runs - 1].fpsmin = fpsmin;
|
||||
history[benchmark_runs - 1].fpsavg = fpsavg;
|
||||
history[benchmark_runs - 1].fpsmax = fpsmax;
|
||||
|
||||
if(atoi(com_argv[i + 1]) > benchmark_runs)
|
||||
{
|
||||
// restart the benchmark
|
||||
Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", cls.demoname));
|
||||
// cannot execute here
|
||||
}
|
||||
else
|
||||
{
|
||||
// print statistics
|
||||
int first = COM_CheckParm("-benchmarkruns_skipfirst") ? 1 : 0;
|
||||
if(benchmark_runs > first)
|
||||
{
|
||||
#define DO_MIN(f) \
|
||||
for(i = first; i < benchmark_runs; ++i) if((i == first) || (history[i].f < f)) f = history[i].f
|
||||
|
||||
#define DO_MAX(f) \
|
||||
for(i = first; i < benchmark_runs; ++i) if((i == first) || (history[i].f > f)) f = history[i].f
|
||||
|
||||
#define DO_MED(f) \
|
||||
doublecmp_offset = (char *)&history->f - (char *)history; \
|
||||
qsort(history + first, benchmark_runs - first, sizeof(*history), doublecmp_withoffset); \
|
||||
if((first + benchmark_runs) & 1) \
|
||||
f = history[(first + benchmark_runs - 1) / 2].f; \
|
||||
else \
|
||||
f = (history[(first + benchmark_runs - 2) / 2].f + history[(first + benchmark_runs) / 2].f) / 2
|
||||
|
||||
DO_MIN(frames);
|
||||
DO_MAX(time);
|
||||
DO_MIN(totalfpsavg);
|
||||
DO_MIN(fpsmin);
|
||||
DO_MIN(fpsavg);
|
||||
DO_MIN(fpsmax);
|
||||
Con_Printf("MIN: %i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount);
|
||||
|
||||
DO_MED(frames);
|
||||
DO_MED(time);
|
||||
DO_MED(totalfpsavg);
|
||||
DO_MED(fpsmin);
|
||||
DO_MED(fpsavg);
|
||||
DO_MED(fpsmax);
|
||||
Con_Printf("MED: %i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount);
|
||||
|
||||
DO_MAX(frames);
|
||||
DO_MIN(time);
|
||||
DO_MAX(totalfpsavg);
|
||||
DO_MAX(fpsmin);
|
||||
DO_MAX(fpsavg);
|
||||
DO_MAX(fpsmax);
|
||||
Con_Printf("MAX: %i frames %5.7f seconds %5.7f fps, one-second fps min/avg/max: %.0f %.0f %.0f (%i seconds)\n", frames, time, totalfpsavg, fpsmin, fpsavg, fpsmax, cls.td_onesecondavgcount);
|
||||
}
|
||||
Z_Free(history);
|
||||
history = NULL;
|
||||
Host_Quit_f();
|
||||
}
|
||||
}
|
||||
else
|
||||
Host_Quit_f();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_TimeDemo_f
|
||||
|
||||
timedemo [demoname]
|
||||
====================
|
||||
*/
|
||||
void CL_TimeDemo_f (void)
|
||||
{
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Con_Print("timedemo <demoname> : gets demo speeds\n");
|
||||
return;
|
||||
}
|
||||
|
||||
srand(0); // predictable random sequence for benchmarking
|
||||
|
||||
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
|
||||
|
||||
// instantly hide console and deactivate it
|
||||
key_dest = key_game;
|
||||
key_consoleactive = 0;
|
||||
scr_con_current = 0;
|
||||
|
||||
cls.timedemo = true;
|
||||
cls.td_frames = -2; // skip the first frame
|
||||
cls.demonum = -1; // stop demo loop
|
||||
}
|
||||
|
93
app/jni/cl_dyntexture.c
Normal file
93
app/jni/cl_dyntexture.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Andreas Kirsch 07
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "cl_dyntexture.h"
|
||||
|
||||
typedef struct dyntexture_s {
|
||||
// everything after DYNAMIC_TEXTURE_PATH_PREFIX
|
||||
char name[ MAX_QPATH + 32 ];
|
||||
// texture pointer (points to r_texture_white at first)
|
||||
rtexture_t *texture;
|
||||
} dyntexture_t;
|
||||
|
||||
static dyntexture_t dyntextures[ MAX_DYNAMIC_TEXTURE_COUNT ];
|
||||
static unsigned dyntexturecount;
|
||||
|
||||
#define DEFAULT_DYNTEXTURE r_texture_grey128
|
||||
|
||||
static dyntexture_t * cl_finddyntexture( const char *name, qboolean warnonfailure ) {
|
||||
unsigned i;
|
||||
dyntexture_t *dyntexture = NULL;
|
||||
|
||||
// sanity checks - make sure its actually a dynamic texture path
|
||||
if( !name || !*name || strncmp( name, CLDYNTEXTUREPREFIX, sizeof( CLDYNTEXTUREPREFIX ) - 1 ) != 0 ) {
|
||||
// TODO: print a warning or something
|
||||
if (warnonfailure)
|
||||
Con_Printf( "cl_finddyntexture: Bad dynamic texture name '%s'\n", name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for( i = 0 ; i < dyntexturecount ; i++ ) {
|
||||
dyntexture = &dyntextures[ i ];
|
||||
if( dyntexture->name && strcmp( dyntexture->name, name ) == 0 ) {
|
||||
return dyntexture;
|
||||
}
|
||||
}
|
||||
|
||||
if( dyntexturecount == MAX_DYNAMIC_TEXTURE_COUNT ) {
|
||||
// TODO: warn or expand the array, etc.
|
||||
return NULL;
|
||||
}
|
||||
dyntexture = &dyntextures[ dyntexturecount++ ];
|
||||
strlcpy( dyntexture->name, name, sizeof( dyntexture->name ) );
|
||||
dyntexture->texture = DEFAULT_DYNTEXTURE;
|
||||
return dyntexture;
|
||||
}
|
||||
|
||||
rtexture_t * CL_GetDynTexture( const char *name ) {
|
||||
dyntexture_t *dyntexture = cl_finddyntexture( name, false );
|
||||
if( dyntexture ) {
|
||||
return dyntexture->texture;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CL_LinkDynTexture( const char *name, rtexture_t *texture ) {
|
||||
dyntexture_t *dyntexture;
|
||||
cachepic_t *cachepic;
|
||||
skinframe_t *skinframe;
|
||||
|
||||
dyntexture = cl_finddyntexture( name, true );
|
||||
if( !dyntexture ) {
|
||||
Con_Printf( "CL_LinkDynTexture: internal error in cl_finddyntexture!\n" );
|
||||
return;
|
||||
}
|
||||
// TODO: assert dyntexture != NULL!
|
||||
if( dyntexture->texture != texture ) {
|
||||
dyntexture->texture = texture;
|
||||
|
||||
cachepic = Draw_CachePic_Flags( name, CACHEPICFLAG_NOTPERSISTENT );
|
||||
// TODO: assert cachepic and skinframe should be valid pointers...
|
||||
// TODO: assert cachepic->tex = dyntexture->texture
|
||||
cachepic->tex = texture;
|
||||
// update cachepic's size, too
|
||||
cachepic->width = R_TextureWidth( texture );
|
||||
cachepic->height = R_TextureHeight( texture );
|
||||
|
||||
// update skinframes
|
||||
skinframe = NULL;
|
||||
while( (skinframe = R_SkinFrame_FindNextByName( skinframe, name )) != NULL ) {
|
||||
skinframe->base = texture;
|
||||
// simply reset the compare* attributes of skinframe
|
||||
skinframe->comparecrc = 0;
|
||||
skinframe->comparewidth = skinframe->compareheight = 0;
|
||||
// this is kind of hacky
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_UnlinkDynTexture( const char *name ) {
|
||||
CL_LinkDynTexture( name, DEFAULT_DYNTEXTURE );
|
||||
}
|
||||
|
20
app/jni/cl_dyntexture.h
Normal file
20
app/jni/cl_dyntexture.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Andreas 'Black' Kirsch 07
|
||||
#ifndef CL_DYNTEXTURE_H
|
||||
#define CL_DYNTEXTURE_H
|
||||
|
||||
#define CLDYNTEXTUREPREFIX "_dynamic/"
|
||||
|
||||
// always path fully specified names to the dynamic texture functions! (ie. with the _dynamic/ prefix, etc.!)
|
||||
|
||||
// return a valid texture handle for a dynamic texture (might be filler texture if it hasnt been initialized yet)
|
||||
// or NULL if its not a valid dynamic texture name
|
||||
rtexture_t * CL_GetDynTexture( const char *name );
|
||||
|
||||
// link a texture handle as dynamic texture and update texture handles in the renderer and draw_* accordingly
|
||||
void CL_LinkDynTexture( const char *name, rtexture_t *texture );
|
||||
|
||||
// unlink a texture handle from its name
|
||||
void CL_UnlinkDynTexture( const char *name );
|
||||
|
||||
#endif
|
||||
|
2297
app/jni/cl_input.c
Normal file
2297
app/jni/cl_input.c
Normal file
File diff suppressed because it is too large
Load diff
2499
app/jni/cl_main.c
Normal file
2499
app/jni/cl_main.c
Normal file
File diff suppressed because it is too large
Load diff
4278
app/jni/cl_parse.c
Normal file
4278
app/jni/cl_parse.c
Normal file
File diff suppressed because it is too large
Load diff
3101
app/jni/cl_particles.c
Normal file
3101
app/jni/cl_particles.c
Normal file
File diff suppressed because it is too large
Load diff
2788
app/jni/cl_screen.c
Normal file
2788
app/jni/cl_screen.c
Normal file
File diff suppressed because it is too large
Load diff
30
app/jni/cl_screen.h
Normal file
30
app/jni/cl_screen.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
#ifndef CL_SCREEN_H
|
||||
#define CL_SCREEN_H
|
||||
|
||||
void SHOWLMP_decodehide(void);
|
||||
void SHOWLMP_decodeshow(void);
|
||||
void SHOWLMP_drawall(void);
|
||||
|
||||
extern cvar_t vid_conwidth;
|
||||
extern cvar_t vid_conheight;
|
||||
extern cvar_t vid_pixelheight;
|
||||
extern cvar_t scr_screenshot_jpeg;
|
||||
extern cvar_t scr_screenshot_jpeg_quality;
|
||||
extern cvar_t scr_screenshot_png;
|
||||
extern cvar_t scr_screenshot_gammaboost;
|
||||
extern cvar_t scr_screenshot_name;
|
||||
|
||||
void CL_Screen_NewMap(void);
|
||||
void CL_Screen_Init(void);
|
||||
void CL_Screen_Shutdown(void);
|
||||
void CL_BeginUpdateScreen();
|
||||
void CL_EndUpdateScreen();
|
||||
|
||||
void SCR_DrawScreen ();
|
||||
|
||||
qboolean R_Stereo_Active(void);
|
||||
qboolean R_Stereo_ColorMasking(void);
|
||||
|
||||
#endif
|
||||
|
743
app/jni/cl_video.c
Normal file
743
app/jni/cl_video.c
Normal file
|
@ -0,0 +1,743 @@
|
|||
|
||||
#include "quakedef.h"
|
||||
#include "cl_dyntexture.h"
|
||||
#include "cl_video.h"
|
||||
|
||||
// cvars
|
||||
cvar_t cl_video_subtitles = {CVAR_SAVE, "cl_video_subtitles", "0", "show subtitles for videos (if they are present)"};
|
||||
cvar_t cl_video_subtitles_lines = {CVAR_SAVE, "cl_video_subtitles_lines", "4", "how many lines to occupy for subtitles"};
|
||||
cvar_t cl_video_subtitles_textsize = {CVAR_SAVE, "cl_video_subtitles_textsize", "16", "textsize for subtitles"};
|
||||
cvar_t cl_video_scale = {CVAR_SAVE, "cl_video_scale", "1", "scale of video, 1 = fullscreen, 0.75 - 3/4 of screen etc."};
|
||||
cvar_t cl_video_scale_vpos = {CVAR_SAVE, "cl_video_scale_vpos", "0", "vertical align of scaled video, -1 is top, 1 is bottom"};
|
||||
cvar_t cl_video_stipple = {CVAR_SAVE, "cl_video_stipple", "0", "draw interlacing-like effect on videos, similar to scr_stipple but static and used only with video playing."};
|
||||
cvar_t cl_video_brightness = {CVAR_SAVE, "cl_video_brightness", "1", "brightness of video, 1 = fullbright, 0.75 - 3/4 etc."};
|
||||
cvar_t cl_video_keepaspectratio = {CVAR_SAVE, "cl_video_keepaspectratio", "0", "keeps aspect ratio of fullscreen videos, leaving black color on unfilled areas, a value of 2 let video to be stretched horizontally with top & bottom being sliced out"};
|
||||
cvar_t cl_video_fadein = {CVAR_SAVE, "cl_video_fadein", "0", "fading-from-black effect once video is started, in seconds"};
|
||||
cvar_t cl_video_fadeout = {CVAR_SAVE, "cl_video_fadeout", "0", "fading-to-black effect once video is ended, in seconds"};
|
||||
|
||||
cvar_t v_glslgamma_video = {CVAR_SAVE, "v_glslgamma_video", "1", "applies GLSL gamma to played video, could be a fraction, requires r_glslgamma_2d 1."};
|
||||
|
||||
// DPV stream decoder
|
||||
#include "dpvsimpledecode.h"
|
||||
|
||||
// VorteX: libavcodec implementation
|
||||
#include "cl_video_libavw.c"
|
||||
|
||||
// JAM video decoder used by Blood Omnicide
|
||||
#ifdef JAMVIDEO
|
||||
#include "cl_video_jamdecode.c"
|
||||
#endif
|
||||
|
||||
// constants (and semi-constants)
|
||||
static int cl_videormask;
|
||||
static int cl_videobmask;
|
||||
static int cl_videogmask;
|
||||
static int cl_videobytesperpixel;
|
||||
|
||||
static int cl_num_videos;
|
||||
static clvideo_t cl_videos[ MAXCLVIDEOS ];
|
||||
static rtexturepool_t *cl_videotexturepool;
|
||||
|
||||
static clvideo_t *FindUnusedVid( void )
|
||||
{
|
||||
int i;
|
||||
for( i = 1 ; i < MAXCLVIDEOS ; i++ )
|
||||
if( cl_videos[ i ].state == CLVIDEO_UNUSED )
|
||||
return &cl_videos[ i ];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static qboolean OpenStream( clvideo_t * video )
|
||||
{
|
||||
const char *errorstring;
|
||||
|
||||
video->stream = dpvsimpledecode_open( video, video->filename, &errorstring);
|
||||
if (video->stream)
|
||||
return true;
|
||||
|
||||
#ifdef JAMVIDEO
|
||||
video->stream = jam_open( video, video->filename, &errorstring);
|
||||
if (video->stream)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
video->stream = LibAvW_OpenVideo( video, video->filename, &errorstring);
|
||||
if (video->stream)
|
||||
return true;
|
||||
|
||||
Con_Printf("unable to open \"%s\", error: %s\n", video->filename, errorstring);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void VideoUpdateCallback(rtexture_t *rt, void *data)
|
||||
{
|
||||
clvideo_t *video = (clvideo_t *) data;
|
||||
R_UpdateTexture( video->cpif.tex, (unsigned char *)video->imagedata, 0, 0, 0, video->cpif.width, video->cpif.height, 1 );
|
||||
}
|
||||
|
||||
static void LinkVideoTexture( clvideo_t *video )
|
||||
{
|
||||
video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name, video->cpif.width, video->cpif.height, NULL, TEXTYPE_BGRA, TEXF_PERSISTENT | TEXF_CLAMP, -1, NULL );
|
||||
R_MakeTextureDynamic( video->cpif.tex, VideoUpdateCallback, video );
|
||||
CL_LinkDynTexture( video->cpif.name, video->cpif.tex );
|
||||
}
|
||||
|
||||
static void UnlinkVideoTexture( clvideo_t *video )
|
||||
{
|
||||
CL_UnlinkDynTexture( video->cpif.name );
|
||||
// free the texture
|
||||
R_FreeTexture( video->cpif.tex );
|
||||
video->cpif.tex = NULL;
|
||||
// free the image data
|
||||
Mem_Free( video->imagedata );
|
||||
}
|
||||
|
||||
static void SuspendVideo( clvideo_t * video )
|
||||
{
|
||||
if (video->suspended)
|
||||
return;
|
||||
video->suspended = true;
|
||||
UnlinkVideoTexture(video);
|
||||
// if we are in firstframe mode, also close the stream
|
||||
if (video->state == CLVIDEO_FIRSTFRAME)
|
||||
{
|
||||
if (video->stream)
|
||||
video->close(video->stream);
|
||||
video->stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean WakeVideo( clvideo_t * video )
|
||||
{
|
||||
if( !video->suspended )
|
||||
return true;
|
||||
video->suspended = false;
|
||||
|
||||
if( video->state == CLVIDEO_FIRSTFRAME )
|
||||
if( !OpenStream( video ) ) {
|
||||
video->state = CLVIDEO_UNUSED;
|
||||
return false;
|
||||
}
|
||||
|
||||
video->imagedata = Mem_Alloc( cls.permanentmempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
|
||||
LinkVideoTexture( video );
|
||||
|
||||
// update starttime
|
||||
video->starttime += realtime - video->lasttime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void LoadSubtitles( clvideo_t *video, const char *subtitlesfile )
|
||||
{
|
||||
char *subtitle_text;
|
||||
const char *data;
|
||||
float subtime, sublen;
|
||||
int numsubs = 0;
|
||||
|
||||
if (gamemode == GAME_BLOODOMNICIDE)
|
||||
{
|
||||
char overridename[MAX_QPATH];
|
||||
cvar_t *langcvar;
|
||||
|
||||
langcvar = Cvar_FindVar("language");
|
||||
subtitle_text = NULL;
|
||||
if (langcvar)
|
||||
{
|
||||
dpsnprintf(overridename, sizeof(overridename), "locale/%s/%s", langcvar->string, subtitlesfile);
|
||||
subtitle_text = (char *)FS_LoadFile(overridename, cls.permanentmempool, false, NULL);
|
||||
}
|
||||
if (!subtitle_text)
|
||||
subtitle_text = (char *)FS_LoadFile(subtitlesfile, cls.permanentmempool, false, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
subtitle_text = (char *)FS_LoadFile(subtitlesfile, cls.permanentmempool, false, NULL);
|
||||
}
|
||||
if (!subtitle_text)
|
||||
{
|
||||
Con_DPrintf( "LoadSubtitles: can't open subtitle file '%s'!\n", subtitlesfile );
|
||||
return;
|
||||
}
|
||||
|
||||
// parse subtitle_text
|
||||
// line is: x y "text" where
|
||||
// x - start time
|
||||
// y - seconds last (if 0 - last thru next sub, if negative - last to next sub - this amount of seconds)
|
||||
|
||||
data = subtitle_text;
|
||||
for (;;)
|
||||
{
|
||||
if (!COM_ParseToken_QuakeC(&data, false))
|
||||
break;
|
||||
subtime = atof( com_token );
|
||||
if (!COM_ParseToken_QuakeC(&data, false))
|
||||
break;
|
||||
sublen = atof( com_token );
|
||||
if (!COM_ParseToken_QuakeC(&data, false))
|
||||
break;
|
||||
if (!com_token[0])
|
||||
continue;
|
||||
// check limits
|
||||
if (video->subtitles == CLVIDEO_MAX_SUBTITLES)
|
||||
{
|
||||
Con_Printf("WARNING: CLVIDEO_MAX_SUBTITLES = %i reached when reading subtitles from '%s'\n", CLVIDEO_MAX_SUBTITLES, subtitlesfile);
|
||||
break;
|
||||
}
|
||||
// add a sub
|
||||
video->subtitle_text[numsubs] = (char *) Mem_Alloc(cls.permanentmempool, strlen(com_token) + 1);
|
||||
memcpy(video->subtitle_text[numsubs], com_token, strlen(com_token) + 1);
|
||||
video->subtitle_start[numsubs] = subtime;
|
||||
video->subtitle_end[numsubs] = sublen;
|
||||
if (numsubs > 0) // make true len for prev sub, autofix overlapping subtitles
|
||||
{
|
||||
if (video->subtitle_end[numsubs-1] <= 0)
|
||||
video->subtitle_end[numsubs-1] = max(video->subtitle_start[numsubs-1], video->subtitle_start[numsubs] + video->subtitle_end[numsubs-1]);
|
||||
else
|
||||
video->subtitle_end[numsubs-1] = min(video->subtitle_start[numsubs-1] + video->subtitle_end[numsubs-1], video->subtitle_start[numsubs]);
|
||||
}
|
||||
numsubs++;
|
||||
// todo: check timing for consistency?
|
||||
}
|
||||
if (numsubs > 0) // make true len for prev sub, autofix overlapping subtitles
|
||||
{
|
||||
if (video->subtitle_end[numsubs-1] <= 0)
|
||||
video->subtitle_end[numsubs-1] = 99999999; // fixme: make it end when video ends?
|
||||
else
|
||||
video->subtitle_end[numsubs-1] = video->subtitle_start[numsubs-1] + video->subtitle_end[numsubs-1];
|
||||
}
|
||||
Z_Free( subtitle_text );
|
||||
video->subtitles = numsubs;
|
||||
/*
|
||||
Con_Printf( "video->subtitles: %i\n", video->subtitles );
|
||||
for (numsubs = 0; numsubs < video->subtitles; numsubs++)
|
||||
Con_Printf( " %03.2f %03.2f : %s\n", video->subtitle_start[numsubs], video->subtitle_end[numsubs], video->subtitle_text[numsubs] );
|
||||
*/
|
||||
}
|
||||
|
||||
static clvideo_t* OpenVideo( clvideo_t *video, const char *filename, const char *name, int owner, const char *subtitlesfile )
|
||||
{
|
||||
strlcpy( video->filename, filename, sizeof(video->filename) );
|
||||
video->ownertag = owner;
|
||||
if( strncmp( name, CLVIDEOPREFIX, sizeof( CLVIDEOPREFIX ) - 1 ) )
|
||||
return NULL;
|
||||
strlcpy( video->cpif.name, name, sizeof(video->cpif.name) );
|
||||
|
||||
if( !OpenStream( video ) )
|
||||
return NULL;
|
||||
|
||||
video->state = CLVIDEO_FIRSTFRAME;
|
||||
video->framenum = -1;
|
||||
video->framerate = video->getframerate( video->stream );
|
||||
video->lasttime = realtime;
|
||||
video->subtitles = 0;
|
||||
|
||||
video->cpif.width = video->getwidth( video->stream );
|
||||
video->cpif.height = video->getheight( video->stream );
|
||||
video->imagedata = Mem_Alloc( cls.permanentmempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
|
||||
LinkVideoTexture( video );
|
||||
|
||||
// VorteX: load simple subtitle_text file
|
||||
if (subtitlesfile[0])
|
||||
LoadSubtitles( video, subtitlesfile );
|
||||
|
||||
return video;
|
||||
}
|
||||
|
||||
clvideo_t* CL_OpenVideo( const char *filename, const char *name, int owner, const char *subtitlesfile )
|
||||
{
|
||||
clvideo_t *video;
|
||||
// sanity check
|
||||
if( !name || !*name || strncmp( name, CLVIDEOPREFIX, sizeof( CLVIDEOPREFIX ) - 1 ) != 0 ) {
|
||||
Con_DPrintf( "CL_OpenVideo: Bad video texture name '%s'!\n", name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
video = FindUnusedVid();
|
||||
if( !video ) {
|
||||
Con_Printf( "CL_OpenVideo: unable to open video \"%s\" - video limit reached\n", filename );
|
||||
return NULL;
|
||||
}
|
||||
video = OpenVideo( video, filename, name, owner, subtitlesfile );
|
||||
// expand the active range to include the new entry
|
||||
if (video) {
|
||||
cl_num_videos = max(cl_num_videos, (int)(video - cl_videos) + 1);
|
||||
}
|
||||
return video;
|
||||
}
|
||||
|
||||
static clvideo_t* CL_GetVideoBySlot( int slot )
|
||||
{
|
||||
clvideo_t *video = &cl_videos[ slot ];
|
||||
|
||||
if( video->suspended )
|
||||
{
|
||||
if( !WakeVideo( video ) )
|
||||
return NULL;
|
||||
else if( video->state == CLVIDEO_RESETONWAKEUP )
|
||||
video->framenum = -1;
|
||||
}
|
||||
|
||||
video->lasttime = realtime;
|
||||
|
||||
return video;
|
||||
}
|
||||
|
||||
clvideo_t *CL_GetVideoByName( const char *name )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0 ; i < cl_num_videos ; i++ )
|
||||
if( cl_videos[ i ].state != CLVIDEO_UNUSED
|
||||
&& !strcmp( cl_videos[ i ].cpif.name , name ) )
|
||||
break;
|
||||
if( i != cl_num_videos )
|
||||
return CL_GetVideoBySlot( i );
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CL_SetVideoState(clvideo_t *video, clvideostate_t state)
|
||||
{
|
||||
if (!video)
|
||||
return;
|
||||
|
||||
video->lasttime = realtime;
|
||||
video->state = state;
|
||||
if (state == CLVIDEO_FIRSTFRAME)
|
||||
CL_RestartVideo(video);
|
||||
}
|
||||
|
||||
void CL_RestartVideo(clvideo_t *video)
|
||||
{
|
||||
if (!video)
|
||||
return;
|
||||
|
||||
// reset time
|
||||
video->starttime = video->lasttime = realtime;
|
||||
video->framenum = -1;
|
||||
|
||||
// reopen stream
|
||||
if (video->stream)
|
||||
video->close(video->stream);
|
||||
video->stream = NULL;
|
||||
if (!OpenStream(video))
|
||||
video->state = CLVIDEO_UNUSED;
|
||||
}
|
||||
|
||||
// close video
|
||||
void CL_CloseVideo(clvideo_t * video)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!video || video->state == CLVIDEO_UNUSED)
|
||||
return;
|
||||
|
||||
// close stream
|
||||
if (!video->suspended || video->state != CLVIDEO_FIRSTFRAME)
|
||||
{
|
||||
if (video->stream)
|
||||
video->close(video->stream);
|
||||
video->stream = NULL;
|
||||
}
|
||||
// unlink texture
|
||||
if (!video->suspended)
|
||||
UnlinkVideoTexture(video);
|
||||
// purge subtitles
|
||||
if (video->subtitles)
|
||||
{
|
||||
for (i = 0; i < video->subtitles; i++)
|
||||
Z_Free( video->subtitle_text[i] );
|
||||
video->subtitles = 0;
|
||||
}
|
||||
video->state = CLVIDEO_UNUSED;
|
||||
}
|
||||
|
||||
// update all videos
|
||||
void CL_Video_Frame(void)
|
||||
{
|
||||
clvideo_t *video;
|
||||
int destframe;
|
||||
int i;
|
||||
|
||||
if (!cl_num_videos)
|
||||
return;
|
||||
for (video = cl_videos, i = 0 ; i < cl_num_videos ; video++, i++)
|
||||
{
|
||||
if (video->state != CLVIDEO_UNUSED && !video->suspended)
|
||||
{
|
||||
if (realtime - video->lasttime > CLTHRESHOLD)
|
||||
{
|
||||
SuspendVideo(video);
|
||||
continue;
|
||||
}
|
||||
if (video->state == CLVIDEO_PAUSE)
|
||||
{
|
||||
video->starttime = realtime - video->framenum * video->framerate;
|
||||
continue;
|
||||
}
|
||||
// read video frame from stream if time has come
|
||||
if (video->state == CLVIDEO_FIRSTFRAME )
|
||||
destframe = 0;
|
||||
else
|
||||
destframe = (int)((realtime - video->starttime) * video->framerate);
|
||||
if (destframe < 0)
|
||||
destframe = 0;
|
||||
if (video->framenum < destframe)
|
||||
{
|
||||
do {
|
||||
video->framenum++;
|
||||
if (video->decodeframe(video->stream, video->imagedata, cl_videormask, cl_videogmask, cl_videobmask, cl_videobytesperpixel, cl_videobytesperpixel * video->cpif.width))
|
||||
{
|
||||
// finished?
|
||||
CL_RestartVideo(video);
|
||||
if (video->state == CLVIDEO_PLAY)
|
||||
video->state = CLVIDEO_FIRSTFRAME;
|
||||
return;
|
||||
}
|
||||
} while(video->framenum < destframe);
|
||||
R_MarkDirtyTexture(video->cpif.tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stop main video
|
||||
if (cl_videos->state == CLVIDEO_FIRSTFRAME)
|
||||
CL_VideoStop();
|
||||
|
||||
// reduce range to exclude unnecessary entries
|
||||
while(cl_num_videos > 0 && cl_videos[cl_num_videos-1].state == CLVIDEO_UNUSED)
|
||||
cl_num_videos--;
|
||||
}
|
||||
|
||||
void CL_PurgeOwner( int owner )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < cl_num_videos ; i++)
|
||||
if (cl_videos[i].ownertag == owner)
|
||||
CL_CloseVideo(&cl_videos[i]);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dp_font_t *font;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
float alignment; // 0 = left, 0.5 = center, 1 = right
|
||||
float fontsize;
|
||||
float textalpha;
|
||||
}
|
||||
cl_video_subtitle_info_t;
|
||||
|
||||
static float CL_DrawVideo_WordWidthFunc(void *passthrough, const char *w, size_t *length, float maxWidth)
|
||||
{
|
||||
cl_video_subtitle_info_t *si = (cl_video_subtitle_info_t *) passthrough;
|
||||
|
||||
if(w == NULL)
|
||||
return si->fontsize * si->font->maxwidth;
|
||||
if(maxWidth >= 0)
|
||||
return DrawQ_TextWidth_UntilWidth(w, length, si->fontsize, si->fontsize, false, si->font, -maxWidth); // -maxWidth: we want at least one char
|
||||
else if(maxWidth == -1)
|
||||
return DrawQ_TextWidth(w, *length, si->fontsize, si->fontsize, false, si->font);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CL_DrawVideo_DisplaySubtitleLine(void *passthrough, const char *line, size_t length, float width, qboolean isContinuation)
|
||||
{
|
||||
cl_video_subtitle_info_t *si = (cl_video_subtitle_info_t *) passthrough;
|
||||
|
||||
int x = (int) (si->x + (si->width - width) * si->alignment);
|
||||
if (length > 0)
|
||||
DrawQ_String(x, si->y, line, length, si->fontsize, si->fontsize, 1.0, 1.0, 1.0, si->textalpha, 0, NULL, false, si->font);
|
||||
si->y += si->fontsize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cl_videoplaying = false; // old, but still supported
|
||||
|
||||
void CL_DrawVideo(void)
|
||||
{
|
||||
clvideo_t *video;
|
||||
float videotime, px, py, sx, sy, st[8], b;
|
||||
cl_video_subtitle_info_t si;
|
||||
int i;
|
||||
|
||||
if (!cl_videoplaying)
|
||||
return;
|
||||
|
||||
video = CL_GetVideoBySlot( 0 );
|
||||
|
||||
// fix cvars
|
||||
if (cl_video_scale.value <= 0 || cl_video_scale.value > 1)
|
||||
Cvar_SetValueQuick( &cl_video_scale, 1);
|
||||
if (cl_video_brightness.value <= 0 || cl_video_brightness.value > 10)
|
||||
Cvar_SetValueQuick( &cl_video_brightness, 1);
|
||||
|
||||
// calc video proportions
|
||||
px = 0;
|
||||
py = 0;
|
||||
sx = vid_conwidth.integer;
|
||||
sy = vid_conheight.integer;
|
||||
st[0] = 0.0; st[1] = 0.0;
|
||||
st[2] = 1.0; st[3] = 0.0;
|
||||
st[4] = 0.0; st[5] = 1.0;
|
||||
st[6] = 1.0; st[7] = 1.0;
|
||||
if (cl_video_keepaspectratio.integer)
|
||||
{
|
||||
float a = video->getaspectratio(video->stream) / ((float)vid.width / (float)vid.height);
|
||||
if (cl_video_keepaspectratio.integer >= 2)
|
||||
{
|
||||
// clip instead of scale
|
||||
if (a < 1.0) // clip horizontally
|
||||
{
|
||||
st[1] = st[3] = (1 - a)*0.5;
|
||||
st[5] = st[7] = 1 - (1 - a)*0.5;
|
||||
}
|
||||
else if (a > 1.0) // clip vertically
|
||||
{
|
||||
st[0] = st[4] = (1 - 1/a)*0.5;
|
||||
st[2] = st[6] = (1/a)*0.5;
|
||||
}
|
||||
}
|
||||
else if (a < 1.0) // scale horizontally
|
||||
{
|
||||
px += sx * (1 - a) * 0.5;
|
||||
sx *= a;
|
||||
}
|
||||
else if (a > 1.0) // scale vertically
|
||||
{
|
||||
a = 1 / a;
|
||||
py += sy * (1 - a);
|
||||
sy *= a;
|
||||
}
|
||||
}
|
||||
|
||||
if (cl_video_scale.value != 1)
|
||||
{
|
||||
px += sx * (1 - cl_video_scale.value) * 0.5;
|
||||
py += sy * (1 - cl_video_scale.value) * ((bound(-1, cl_video_scale_vpos.value, 1) + 1) / 2);
|
||||
sx *= cl_video_scale.value;
|
||||
sy *= cl_video_scale.value;
|
||||
}
|
||||
|
||||
// calc brightness for fadein and fadeout effects
|
||||
b = cl_video_brightness.value;
|
||||
if (cl_video_fadein.value && (realtime - video->starttime) < cl_video_fadein.value)
|
||||
b = pow((realtime - video->starttime)/cl_video_fadein.value, 2);
|
||||
else if (cl_video_fadeout.value && ((video->starttime + video->framenum * video->framerate) - realtime) < cl_video_fadeout.value)
|
||||
b = pow(((video->starttime + video->framenum * video->framerate) - realtime)/cl_video_fadeout.value, 2);
|
||||
|
||||
// draw black bg in case stipple is active or video is scaled
|
||||
if (cl_video_stipple.integer || px != 0 || py != 0 || sx != vid_conwidth.integer || sy != vid_conheight.integer)
|
||||
DrawQ_Fill(0, 0, vid_conwidth.integer, vid_conheight.integer, 0, 0, 0, 1, 0);
|
||||
|
||||
#ifndef USE_GLES2
|
||||
// enable video-only polygon stipple (of global stipple is not active)
|
||||
if (qglPolygonStipple && !scr_stipple.integer && cl_video_stipple.integer)
|
||||
{
|
||||
GLubyte stipple[128];
|
||||
int i, s, width, parts;
|
||||
|
||||
s = cl_video_stipple.integer;
|
||||
parts = (s & 007);
|
||||
width = (s & 070) >> 3;
|
||||
qglEnable(GL_POLYGON_STIPPLE);CHECKGLERROR // 0x0B42
|
||||
for(i = 0; i < 128; ++i)
|
||||
{
|
||||
int line = i/4;
|
||||
stipple[i] = ((line >> width) & ((1 << parts) - 1)) ? 0x00 : 0xFF;
|
||||
}
|
||||
qglPolygonStipple(stipple);CHECKGLERROR
|
||||
}
|
||||
#endif
|
||||
|
||||
// draw video
|
||||
if (v_glslgamma_video.value >= 1)
|
||||
DrawQ_SuperPic(px, py, &video->cpif, sx, sy, st[0], st[1], b, b, b, 1, st[2], st[3], b, b, b, 1, st[4], st[5], b, b, b, 1, st[6], st[7], b, b, b, 1, 0);
|
||||
else
|
||||
{
|
||||
DrawQ_SuperPic(px, py, &video->cpif, sx, sy, st[0], st[1], b, b, b, 1, st[2], st[3], b, b, b, 1, st[4], st[5], b, b, b, 1, st[6], st[7], b, b, b, 1, DRAWFLAG_NOGAMMA);
|
||||
if (v_glslgamma_video.value > 0.0)
|
||||
DrawQ_SuperPic(px, py, &video->cpif, sx, sy, st[0], st[1], b, b, b, v_glslgamma_video.value, st[2], st[3], b, b, b, v_glslgamma_video.value, st[4], st[5], b, b, b, v_glslgamma_video.value, st[6], st[7], b, b, b, v_glslgamma_video.value, 0);
|
||||
}
|
||||
|
||||
#ifndef USE_GLES2
|
||||
// disable video-only stipple
|
||||
if (qglPolygonStipple && !scr_stipple.integer && cl_video_stipple.integer)
|
||||
qglDisable(GL_POLYGON_STIPPLE);CHECKGLERROR
|
||||
#endif
|
||||
|
||||
// VorteX: draw subtitle_text
|
||||
if (!video->subtitles || !cl_video_subtitles.integer)
|
||||
return;
|
||||
|
||||
// find current subtitle
|
||||
videotime = realtime - video->starttime;
|
||||
for (i = 0; i < video->subtitles; i++)
|
||||
{
|
||||
if (videotime >= video->subtitle_start[i] && videotime <= video->subtitle_end[i])
|
||||
{
|
||||
// found, draw it
|
||||
si.font = FONT_NOTIFY;
|
||||
si.x = vid_conwidth.integer * 0.1;
|
||||
si.y = vid_conheight.integer - (max(1, cl_video_subtitles_lines.value) * cl_video_subtitles_textsize.value);
|
||||
si.width = vid_conwidth.integer * 0.8;
|
||||
si.height = max(1, cl_video_subtitles_lines.integer) * cl_video_subtitles_textsize.value;
|
||||
si.alignment = 0.5;
|
||||
si.fontsize = cl_video_subtitles_textsize.value;
|
||||
si.textalpha = min(1, (videotime - video->subtitle_start[i])/0.5) * min(1, ((video->subtitle_end[i] - videotime)/0.3)); // fade in and fade out
|
||||
COM_Wordwrap(video->subtitle_text[i], strlen(video->subtitle_text[i]), 0, si.width, CL_DrawVideo_WordWidthFunc, &si, CL_DrawVideo_DisplaySubtitleLine, &si);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_VideoStart(char *filename, const char *subtitlesfile)
|
||||
{
|
||||
char vabuf[1024];
|
||||
Host_StartVideo();
|
||||
|
||||
if( cl_videos->state != CLVIDEO_UNUSED )
|
||||
CL_CloseVideo( cl_videos );
|
||||
// already contains video/
|
||||
if( !OpenVideo( cl_videos, filename, va(vabuf, sizeof(vabuf), CLDYNTEXTUREPREFIX "%s", filename ), 0, subtitlesfile ) )
|
||||
return;
|
||||
// expand the active range to include the new entry
|
||||
cl_num_videos = max(cl_num_videos, 1);
|
||||
|
||||
cl_videoplaying = true;
|
||||
|
||||
CL_SetVideoState( cl_videos, CLVIDEO_PLAY );
|
||||
CL_RestartVideo( cl_videos );
|
||||
}
|
||||
|
||||
void CL_Video_KeyEvent( int key, int ascii, qboolean down )
|
||||
{
|
||||
// only react to up events, to allow the user to delay the abortion point if it suddenly becomes interesting..
|
||||
if( !down ) {
|
||||
if( key == K_ESCAPE || key == K_ENTER || key == K_MOUSE1 || key == K_SPACE ) {
|
||||
CL_VideoStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_VideoStop(void)
|
||||
{
|
||||
cl_videoplaying = false;
|
||||
|
||||
CL_CloseVideo( cl_videos );
|
||||
}
|
||||
|
||||
static void CL_PlayVideo_f(void)
|
||||
{
|
||||
char name[MAX_QPATH], subtitlesfile[MAX_QPATH];
|
||||
const char *extension;
|
||||
|
||||
Host_StartVideo();
|
||||
|
||||
if (COM_CheckParm("-benchmark"))
|
||||
return;
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
Con_Print("usage: playvideo <videoname> [custom_subtitles_file]\nplays video named video/<videoname>.dpv\nif custom subtitles file is not presented\nit tries video/<videoname>.sub");
|
||||
return;
|
||||
}
|
||||
|
||||
extension = FS_FileExtension(Cmd_Argv(1));
|
||||
if (extension[0])
|
||||
dpsnprintf(name, sizeof(name), "video/%s", Cmd_Argv(1));
|
||||
else
|
||||
dpsnprintf(name, sizeof(name), "video/%s.dpv", Cmd_Argv(1));
|
||||
if ( Cmd_Argc() > 2)
|
||||
CL_VideoStart(name, Cmd_Argv(2));
|
||||
else
|
||||
{
|
||||
dpsnprintf(subtitlesfile, sizeof(subtitlesfile), "video/%s.dpsubs", Cmd_Argv(1));
|
||||
CL_VideoStart(name, subtitlesfile);
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_StopVideo_f(void)
|
||||
{
|
||||
CL_VideoStop();
|
||||
}
|
||||
|
||||
static void cl_video_start( void )
|
||||
{
|
||||
int i;
|
||||
clvideo_t *video;
|
||||
|
||||
cl_videotexturepool = R_AllocTexturePool();
|
||||
|
||||
for( video = cl_videos, i = 0 ; i < cl_num_videos ; i++, video++ )
|
||||
if( video->state != CLVIDEO_UNUSED && !video->suspended )
|
||||
LinkVideoTexture( video );
|
||||
}
|
||||
|
||||
static void cl_video_shutdown( void )
|
||||
{
|
||||
int i;
|
||||
clvideo_t *video;
|
||||
|
||||
for( video = cl_videos, i = 0 ; i < cl_num_videos ; i++, video++ )
|
||||
if( video->state != CLVIDEO_UNUSED && !video->suspended )
|
||||
SuspendVideo( video );
|
||||
R_FreeTexturePool( &cl_videotexturepool );
|
||||
}
|
||||
|
||||
static void cl_video_newmap( void )
|
||||
{
|
||||
}
|
||||
|
||||
void CL_Video_Init( void )
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char b[4];
|
||||
unsigned int i;
|
||||
}
|
||||
bgra;
|
||||
|
||||
cl_num_videos = 0;
|
||||
cl_videobytesperpixel = 4;
|
||||
|
||||
// set masks in an endian-independent way (as they really represent bytes)
|
||||
bgra.i = 0;bgra.b[0] = 0xFF;cl_videobmask = bgra.i;
|
||||
bgra.i = 0;bgra.b[1] = 0xFF;cl_videogmask = bgra.i;
|
||||
bgra.i = 0;bgra.b[2] = 0xFF;cl_videormask = bgra.i;
|
||||
|
||||
Cmd_AddCommand( "playvideo", CL_PlayVideo_f, "play a .dpv video file" );
|
||||
Cmd_AddCommand( "stopvideo", CL_StopVideo_f, "stop playing a .dpv video file" );
|
||||
|
||||
Cvar_RegisterVariable(&cl_video_subtitles);
|
||||
Cvar_RegisterVariable(&cl_video_subtitles_lines);
|
||||
Cvar_RegisterVariable(&cl_video_subtitles_textsize);
|
||||
Cvar_RegisterVariable(&cl_video_scale);
|
||||
Cvar_RegisterVariable(&cl_video_scale_vpos);
|
||||
Cvar_RegisterVariable(&cl_video_brightness);
|
||||
Cvar_RegisterVariable(&cl_video_stipple);
|
||||
Cvar_RegisterVariable(&cl_video_keepaspectratio);
|
||||
Cvar_RegisterVariable(&cl_video_fadein);
|
||||
Cvar_RegisterVariable(&cl_video_fadeout);
|
||||
|
||||
Cvar_RegisterVariable(&v_glslgamma_video);
|
||||
|
||||
R_RegisterModule( "CL_Video", cl_video_start, cl_video_shutdown, cl_video_newmap, NULL, NULL );
|
||||
|
||||
LibAvW_OpenLibrary();
|
||||
}
|
||||
|
||||
void CL_Video_Shutdown( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < cl_num_videos ; i++)
|
||||
CL_CloseVideo(&cl_videos[ i ]);
|
||||
|
||||
LibAvW_CloseLibrary();
|
||||
}
|
97
app/jni/cl_video.h
Normal file
97
app/jni/cl_video.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
|
||||
#ifndef CL_VIDEO_H
|
||||
#define CL_VIDEO_H
|
||||
|
||||
#include "cl_dyntexture.h"
|
||||
|
||||
// yields DYNAMIC_TEXTURE_PATH_PREFIX CLVIDEOPREFIX video name for a path
|
||||
#define CLVIDEOPREFIX CLDYNTEXTUREPREFIX "video/"
|
||||
#define CLTHRESHOLD 2.0
|
||||
|
||||
#define MENUOWNER 1
|
||||
|
||||
typedef enum clvideostate_e
|
||||
{
|
||||
CLVIDEO_UNUSED,
|
||||
CLVIDEO_PLAY,
|
||||
CLVIDEO_LOOP,
|
||||
CLVIDEO_PAUSE,
|
||||
CLVIDEO_FIRSTFRAME,
|
||||
CLVIDEO_RESETONWAKEUP,
|
||||
CLVIDEO_STATECOUNT
|
||||
} clvideostate_t;
|
||||
|
||||
#define CLVIDEO_MAX_SUBTITLES 512
|
||||
|
||||
extern cvar_t cl_video_subtitles;
|
||||
extern cvar_t cl_video_subtitles_lines;
|
||||
extern cvar_t cl_video_subtitles_textsize;
|
||||
extern cvar_t cl_video_scale;
|
||||
extern cvar_t cl_video_scale_vpos;
|
||||
extern cvar_t cl_video_stipple;
|
||||
extern cvar_t cl_video_brightness;
|
||||
extern cvar_t cl_video_keepaspectratio;
|
||||
|
||||
typedef struct clvideo_s
|
||||
{
|
||||
int ownertag;
|
||||
clvideostate_t state;
|
||||
|
||||
// private stuff
|
||||
void *stream;
|
||||
|
||||
double starttime;
|
||||
int framenum;
|
||||
double framerate;
|
||||
|
||||
void *imagedata;
|
||||
|
||||
cachepic_t cpif;
|
||||
|
||||
// VorteX: subtitles array
|
||||
int subtitles;
|
||||
char *subtitle_text[CLVIDEO_MAX_SUBTITLES];
|
||||
float subtitle_start[CLVIDEO_MAX_SUBTITLES];
|
||||
float subtitle_end[CLVIDEO_MAX_SUBTITLES];
|
||||
|
||||
// this functions gets filled by video format module
|
||||
void (*close) (void *stream);
|
||||
unsigned int (*getwidth) (void *stream);
|
||||
unsigned int (*getheight) (void *stream);
|
||||
double (*getframerate) (void *stream);
|
||||
double (*getaspectratio) (void *stream);
|
||||
int (*decodeframe) (void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow);
|
||||
|
||||
// if a video is suspended, it is automatically paused (else we'd still have to process the frames)
|
||||
// used to determine whether the video's resources should be freed or not
|
||||
double lasttime;
|
||||
// when lasttime - realtime > THRESHOLD, all but the stream is freed
|
||||
qboolean suspended;
|
||||
|
||||
char filename[MAX_QPATH];
|
||||
} clvideo_t;
|
||||
|
||||
clvideo_t* CL_OpenVideo( const char *filename, const char *name, int owner, const char *subtitlesfile );
|
||||
clvideo_t* CL_GetVideoByName( const char *name );
|
||||
void CL_SetVideoState( clvideo_t *video, clvideostate_t state );
|
||||
void CL_RestartVideo( clvideo_t *video );
|
||||
|
||||
void CL_CloseVideo( clvideo_t * video );
|
||||
void CL_PurgeOwner( int owner );
|
||||
|
||||
void CL_Video_Frame( void ); // update all videos
|
||||
void CL_Video_Init( void );
|
||||
void CL_Video_Shutdown( void );
|
||||
|
||||
// old interface
|
||||
extern int cl_videoplaying;
|
||||
|
||||
void CL_DrawVideo( void );
|
||||
void CL_VideoStart( char *filename, const char *subtitlesfile );
|
||||
void CL_VideoStop( void );
|
||||
|
||||
// new function used for fullscreen videos
|
||||
// TODO: Andreas Kirsch: move this subsystem somewhere else (preferably host) since the cl_video system shouldnt do such work like managing key events..
|
||||
void CL_Video_KeyEvent( int key, int ascii, qboolean down );
|
||||
|
||||
#endif
|
386
app/jni/cl_video_libavw.c
Normal file
386
app/jni/cl_video_libavw.c
Normal file
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
Libavcodec integration for Darkplaces by Timofeyev Pavel
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
// LordHavoc: for some reason this is being #include'd rather than treated as its own file...
|
||||
// LordHavoc: adapted to not require stdint.h as this is not available on MSVC++, using unsigned char instead of uint8_t and fs_offset_t instead of int64_t.
|
||||
|
||||
// scaler type
|
||||
#define LIBAVW_SCALER_BILINEAR 0
|
||||
#define LIBAVW_SCALER_BICUBIC 1
|
||||
#define LIBAVW_SCALER_X 2
|
||||
#define LIBAVW_SCALER_POINT 3
|
||||
#define LIBAVW_SCALER_AREA 4
|
||||
#define LIBAVW_SCALER_BICUBLIN 5
|
||||
#define LIBAVW_SCALER_GAUSS 6
|
||||
#define LIBAVW_SCALER_SINC 7
|
||||
#define LIBAVW_SCALER_LANCZOS 8
|
||||
#define LIBAVW_SCALER_SPLINE 9
|
||||
// output format
|
||||
#define LIBAVW_PIXEL_FORMAT_BGR 0
|
||||
#define LIBAVW_PIXEL_FORMAT_BGRA 1
|
||||
// print levels
|
||||
#define LIBAVW_PRINT_WARNING 1
|
||||
#define LIBAVW_PRINT_ERROR 2
|
||||
#define LIBAVW_PRINT_FATAL 3
|
||||
#define LIBAVW_PRINT_PANIC 4
|
||||
// exported callback functions:
|
||||
typedef void avwCallbackPrint(int, const char *);
|
||||
typedef int avwCallbackIoRead(void *, unsigned char *, int);
|
||||
typedef fs_offset_t avwCallbackIoSeek(void *, fs_offset_t, int);
|
||||
typedef fs_offset_t avwCallbackIoSeekSize(void *);
|
||||
// exported functions:
|
||||
int (*qLibAvW_Init)(avwCallbackPrint *printfunction); // init library, returns error code
|
||||
const char *(*qLibAvW_ErrorString)(int errorcode); // get string for error code
|
||||
const char *(*qLibAvW_AvcVersion)(void); // get a string containing libavcodec version wrapper was built for
|
||||
float (*qLibAvW_Version)(void); // get wrapper version
|
||||
int (*qLibAvW_CreateStream)(void **stream); // create stream, returns error code
|
||||
void (*qLibAvW_RemoveStream)(void *stream); // flush and remove stream
|
||||
int (*qLibAvW_StreamGetVideoWidth)(void *stream); // get video parameters of stream
|
||||
int (*qLibAvW_StreamGetVideoHeight)(void *stream);
|
||||
double (*qLibAvW_StreamGetFramerate)(void *stream);
|
||||
int (*qLibAvW_StreamGetError)(void *stream); // get last function errorcode from stream
|
||||
// simple API to play video
|
||||
int (*qLibAvW_PlayVideo)(void *stream, void *file, avwCallbackIoRead *IoRead, avwCallbackIoSeek *IoSeek, avwCallbackIoSeekSize *IoSeekSize);
|
||||
int (*qLibAvW_PlaySeekNextFrame)(void *stream);
|
||||
int (*qLibAvW_PlayGetFrameImage)(void *stream, int pixel_format, void *imagedata, int imagewidth, int imageheight, int scaler);
|
||||
|
||||
static dllfunction_t libavwfuncs[] =
|
||||
{
|
||||
{"LibAvW_Init", (void **) &qLibAvW_Init },
|
||||
{"LibAvW_ErrorString", (void **) &qLibAvW_ErrorString },
|
||||
{"LibAvW_AvcVersion", (void **) &qLibAvW_AvcVersion },
|
||||
{"LibAvW_Version", (void **) &qLibAvW_Version },
|
||||
{"LibAvW_CreateStream", (void **) &qLibAvW_CreateStream },
|
||||
{"LibAvW_RemoveStream", (void **) &qLibAvW_RemoveStream },
|
||||
{"LibAvW_StreamGetVideoWidth", (void **) &qLibAvW_StreamGetVideoWidth },
|
||||
{"LibAvW_StreamGetVideoHeight",(void **) &qLibAvW_StreamGetVideoHeight },
|
||||
{"LibAvW_StreamGetFramerate", (void **) &qLibAvW_StreamGetFramerate },
|
||||
{"LibAvW_StreamGetError", (void **) &qLibAvW_StreamGetError },
|
||||
{"LibAvW_PlayVideo", (void **) &qLibAvW_PlayVideo },
|
||||
{"LibAvW_PlaySeekNextFrame", (void **) &qLibAvW_PlaySeekNextFrame },
|
||||
{"LibAvW_PlayGetFrameImage", (void **) &qLibAvW_PlayGetFrameImage },
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
const char* dllnames_libavw[] =
|
||||
{
|
||||
#if defined(WIN32)
|
||||
"libavw.dll",
|
||||
#elif defined(MACOSX)
|
||||
"libavw.dylib",
|
||||
#else
|
||||
"libavw.so.1",
|
||||
"libavw.so",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static dllhandle_t libavw_dll = NULL;
|
||||
|
||||
// DP videostream
|
||||
typedef struct libavwstream_s
|
||||
{
|
||||
qfile_t *file;
|
||||
double info_framerate;
|
||||
unsigned int info_imagewidth;
|
||||
unsigned int info_imageheight;
|
||||
double info_aspectratio;
|
||||
void *stream;
|
||||
|
||||
// channel the sound file is being played on
|
||||
sfx_t *sfx;
|
||||
int sndchan;
|
||||
int sndstarted;
|
||||
}
|
||||
libavwstream_t;
|
||||
|
||||
cvar_t cl_video_libavw_minwidth = {CVAR_SAVE, "cl_video_libavw_minwidth", "0", "if videos width is lesser than minimal, thay will be upscaled"};
|
||||
cvar_t cl_video_libavw_minheight = {CVAR_SAVE, "cl_video_libavw_minheight", "0", "if videos height is lesser than minimal, thay will be upscaled"};
|
||||
cvar_t cl_video_libavw_scaler = {CVAR_SAVE, "cl_video_libavw_scaler", "1", "selects a scaler for libavcode played videos. Scalers are: 0 - bilinear, 1 - bicubic, 2 - x, 3 - point, 4 - area, 5 - bicublin, 6 - gauss, 7 - sinc, 8 - lanczos, 9 - spline."};
|
||||
|
||||
// video extensions
|
||||
const char* libavw_extensions[] =
|
||||
{
|
||||
"ogv",
|
||||
"avi",
|
||||
"mpg",
|
||||
"mp4",
|
||||
"mkv",
|
||||
"webm",
|
||||
"bik",
|
||||
"roq",
|
||||
"flv",
|
||||
"wmv",
|
||||
"mpeg",
|
||||
"mjpeg",
|
||||
"mpeg4",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
Video decoding
|
||||
a features that is not supported yet and likely to be done
|
||||
- streaming audio from videofiles
|
||||
- streaming subtitles
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
unsigned int libavw_getwidth(void *stream);
|
||||
unsigned int libavw_getheight(void *stream);
|
||||
double libavw_getframerate(void *stream);
|
||||
double libavw_getaspectratio(void *stream);
|
||||
void libavw_close(void *stream);
|
||||
|
||||
static int libavw_decodeframe(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
|
||||
{
|
||||
int pixel_format = LIBAVW_PIXEL_FORMAT_BGR;
|
||||
int errorcode;
|
||||
|
||||
libavwstream_t *s = (libavwstream_t *)stream;
|
||||
|
||||
// start sound
|
||||
if (!s->sndstarted)
|
||||
{
|
||||
if (s->sfx != NULL)
|
||||
s->sndchan = S_StartSound(-1, 0, s->sfx, vec3_origin, 1.0f, 0);
|
||||
s->sndstarted = 1;
|
||||
}
|
||||
|
||||
// read frame
|
||||
if (!qLibAvW_PlaySeekNextFrame(s->stream))
|
||||
{
|
||||
// got error or file end
|
||||
errorcode = qLibAvW_StreamGetError(s->stream);
|
||||
if (errorcode)
|
||||
Con_Printf("LibAvW: %s\n", qLibAvW_ErrorString(errorcode));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// decode into bgr texture
|
||||
if (bytesperpixel == 4)
|
||||
pixel_format = LIBAVW_PIXEL_FORMAT_BGRA;
|
||||
else if (bytesperpixel == 3)
|
||||
pixel_format = LIBAVW_PIXEL_FORMAT_BGR;
|
||||
else
|
||||
{
|
||||
Con_Printf("LibAvW: cannot determine pixel format for bpp %i\n", bytesperpixel);
|
||||
return 1;
|
||||
}
|
||||
if (!qLibAvW_PlayGetFrameImage(s->stream, pixel_format, imagedata, s->info_imagewidth, s->info_imageheight, min(9, max(0, cl_video_libavw_scaler.integer))))
|
||||
Con_Printf("LibAvW: %s\n", qLibAvW_ErrorString(qLibAvW_StreamGetError(s->stream)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get stream info
|
||||
unsigned int libavw_getwidth(void *stream)
|
||||
{
|
||||
return ((libavwstream_t *)stream)->info_imagewidth;
|
||||
}
|
||||
|
||||
unsigned int libavw_getheight(void *stream)
|
||||
{
|
||||
return ((libavwstream_t *)stream)->info_imageheight;
|
||||
}
|
||||
|
||||
double libavw_getframerate(void *stream)
|
||||
{
|
||||
return ((libavwstream_t *)stream)->info_framerate;
|
||||
}
|
||||
|
||||
double libavw_getaspectratio(void *stream)
|
||||
{
|
||||
return ((libavwstream_t *)stream)->info_aspectratio;
|
||||
}
|
||||
|
||||
// close stream
|
||||
void libavw_close(void *stream)
|
||||
{
|
||||
libavwstream_t *s = (libavwstream_t *)stream;
|
||||
|
||||
if (s->stream)
|
||||
qLibAvW_RemoveStream(s->stream);
|
||||
s->stream = NULL;
|
||||
if (s->file)
|
||||
FS_Close(s->file);
|
||||
s->file = NULL;
|
||||
if (s->sndchan >= 0)
|
||||
S_StopChannel(s->sndchan, true, true);
|
||||
s->sndchan = -1;
|
||||
}
|
||||
|
||||
// IO wrapper
|
||||
static int LibAvW_FS_Read(void *opaque, unsigned char *buf, int buf_size)
|
||||
{
|
||||
return FS_Read((qfile_t *)opaque, buf, buf_size);
|
||||
}
|
||||
static fs_offset_t LibAvW_FS_Seek(void *opaque, fs_offset_t pos, int whence)
|
||||
{
|
||||
return (fs_offset_t)FS_Seek((qfile_t *)opaque, pos, whence);
|
||||
}
|
||||
static fs_offset_t LibAvW_FS_SeekSize(void *opaque)
|
||||
{
|
||||
return (fs_offset_t)FS_FileSize((qfile_t *)opaque);
|
||||
}
|
||||
|
||||
// open as DP video stream
|
||||
static void *LibAvW_OpenVideo(clvideo_t *video, char *filename, const char **errorstring)
|
||||
{
|
||||
libavwstream_t *s;
|
||||
char filebase[MAX_OSPATH], check[MAX_OSPATH];
|
||||
unsigned int i;
|
||||
int errorcode;
|
||||
char *wavename;
|
||||
size_t len;
|
||||
|
||||
if (!libavw_dll)
|
||||
return NULL;
|
||||
|
||||
// allocate stream
|
||||
s = (libavwstream_t *)Z_Malloc(sizeof(libavwstream_t));
|
||||
if (s == NULL)
|
||||
{
|
||||
*errorstring = "unable to allocate memory for stream info structure";
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(libavwstream_t));
|
||||
s->sndchan = -1;
|
||||
|
||||
// open file
|
||||
s->file = FS_OpenVirtualFile(filename, true);
|
||||
if (!s->file)
|
||||
{
|
||||
FS_StripExtension(filename, filebase, sizeof(filebase));
|
||||
// we tried .dpv, try another extensions
|
||||
for (i = 0; libavw_extensions[i] != NULL; i++)
|
||||
{
|
||||
dpsnprintf(check, sizeof(check), "%s.%s", filebase, libavw_extensions[i]);
|
||||
s->file = FS_OpenVirtualFile(check, true);
|
||||
if (s->file)
|
||||
break;
|
||||
}
|
||||
if (!s->file)
|
||||
{
|
||||
*errorstring = "unable to open videofile";
|
||||
libavw_close(s);
|
||||
Z_Free(s);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate libavw stream
|
||||
if ((errorcode = qLibAvW_CreateStream(&s->stream)))
|
||||
{
|
||||
*errorstring = qLibAvW_ErrorString(errorcode);
|
||||
libavw_close(s);
|
||||
Z_Free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// open video for playing
|
||||
if (!qLibAvW_PlayVideo(s->stream, s->file, &LibAvW_FS_Read, &LibAvW_FS_Seek, &LibAvW_FS_SeekSize))
|
||||
{
|
||||
*errorstring = qLibAvW_ErrorString(qLibAvW_StreamGetError(s->stream));
|
||||
libavw_close(s);
|
||||
Z_Free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// all right, start codec
|
||||
s->info_imagewidth = qLibAvW_StreamGetVideoWidth(s->stream);
|
||||
s->info_imageheight = qLibAvW_StreamGetVideoHeight(s->stream);
|
||||
s->info_framerate = qLibAvW_StreamGetFramerate(s->stream);
|
||||
s->info_aspectratio = (double)s->info_imagewidth / (double)s->info_imageheight;
|
||||
video->close = libavw_close;
|
||||
video->getwidth = libavw_getwidth;
|
||||
video->getheight = libavw_getheight;
|
||||
video->getframerate = libavw_getframerate;
|
||||
video->decodeframe = libavw_decodeframe;
|
||||
video->getaspectratio = libavw_getaspectratio;
|
||||
|
||||
// apply min-width, min-height, keep aspect rate
|
||||
if (cl_video_libavw_minwidth.integer > 0)
|
||||
s->info_imagewidth = max(s->info_imagewidth, (unsigned int)cl_video_libavw_minwidth.integer);
|
||||
if (cl_video_libavw_minheight.integer > 0)
|
||||
s->info_imageheight = max(s->info_imageheight, (unsigned int)cl_video_libavw_minheight.integer);
|
||||
|
||||
// provide sound in separate .wav
|
||||
len = strlen(filename) + 10;
|
||||
wavename = (char *)Z_Malloc(len);
|
||||
if (wavename)
|
||||
{
|
||||
FS_StripExtension(filename, wavename, len-1);
|
||||
strlcat(wavename, ".wav", len);
|
||||
s->sfx = S_PrecacheSound(wavename, false, false);
|
||||
s->sndchan = -1;
|
||||
Z_Free(wavename);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static void libavw_message(int level, const char *message)
|
||||
{
|
||||
if (level == LIBAVW_PRINT_WARNING)
|
||||
Con_Printf("LibAvcodec warning: %s\n", message);
|
||||
else if (level == LIBAVW_PRINT_ERROR)
|
||||
Con_Printf("LibAvcodec error: %s\n", message);
|
||||
else if (level == LIBAVW_PRINT_FATAL)
|
||||
Con_Printf("LibAvcodec fatal error: %s\n", message);
|
||||
else
|
||||
Con_Printf("LibAvcodec panic: %s\n", message);
|
||||
}
|
||||
|
||||
static qboolean LibAvW_OpenLibrary(void)
|
||||
{
|
||||
int errorcode;
|
||||
|
||||
// COMMANDLINEOPTION: Video: -nolibavw disables libavcodec wrapper support
|
||||
if (COM_CheckParm("-nolibavw"))
|
||||
return false;
|
||||
|
||||
// load DLL's
|
||||
Sys_LoadLibrary(dllnames_libavw, &libavw_dll, libavwfuncs);
|
||||
if (!libavw_dll)
|
||||
return false;
|
||||
|
||||
// initialize libav wrapper
|
||||
if ((errorcode = qLibAvW_Init(&libavw_message)))
|
||||
{
|
||||
Con_Printf("LibAvW failed to initialize: %s\n", qLibAvW_ErrorString(errorcode));
|
||||
Sys_UnloadLibrary(&libavw_dll);
|
||||
}
|
||||
|
||||
Cvar_RegisterVariable(&cl_video_libavw_minwidth);
|
||||
Cvar_RegisterVariable(&cl_video_libavw_minheight);
|
||||
Cvar_RegisterVariable(&cl_video_libavw_scaler);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void LibAvW_CloseLibrary(void)
|
||||
{
|
||||
Sys_UnloadLibrary(&libavw_dll);
|
||||
}
|
||||
|
2052
app/jni/client.h
Normal file
2052
app/jni/client.h
Normal file
File diff suppressed because it is too large
Load diff
98
app/jni/clprogdefs.h
Normal file
98
app/jni/clprogdefs.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* file generated by qcc, do not modify */
|
||||
|
||||
|
||||
#ifndef CLPROGDEFS_H
|
||||
#define CLPROGDEFS_H
|
||||
|
||||
/*
|
||||
typedef struct cl_globalvars_s
|
||||
{
|
||||
int pad[28];
|
||||
int self;
|
||||
int other;
|
||||
int world;
|
||||
float time;
|
||||
float frametime;
|
||||
float player_localentnum;
|
||||
float player_localnum;
|
||||
float maxclients;
|
||||
float clientcommandframe;
|
||||
float servercommandframe;
|
||||
string_t mapname;
|
||||
vec3_t v_forward;
|
||||
vec3_t v_up;
|
||||
vec3_t v_right;
|
||||
float trace_allsolid;
|
||||
float trace_startsolid;
|
||||
float trace_fraction;
|
||||
vec3_t trace_endpos;
|
||||
vec3_t trace_plane_normal;
|
||||
float trace_plane_dist;
|
||||
int trace_ent;
|
||||
float trace_inopen;
|
||||
float trace_inwater;
|
||||
func_t CSQC_Init;
|
||||
func_t CSQC_Shutdown;
|
||||
func_t CSQC_InputEvent;
|
||||
func_t CSQC_UpdateView;
|
||||
func_t CSQC_ConsoleCommand;
|
||||
vec3_t pmove_org;
|
||||
vec3_t pmove_vel;
|
||||
vec3_t pmove_mins;
|
||||
vec3_t pmove_maxs;
|
||||
float input_timelength;
|
||||
vec3_t input_angles;
|
||||
vec3_t input_movevalues;
|
||||
float input_buttons;
|
||||
float movevar_gravity;
|
||||
float movevar_stopspeed;
|
||||
float movevar_maxspeed;
|
||||
float movevar_spectatormaxspeed;
|
||||
float movevar_accelerate;
|
||||
float movevar_airaccelerate;
|
||||
float movevar_wateraccelerate;
|
||||
float movevar_friction;
|
||||
float movevar_waterfriction;
|
||||
float movevar_entgravity;
|
||||
} cl_globalvars_t;
|
||||
|
||||
typedef struct cl_entvars_s
|
||||
{
|
||||
float modelindex;
|
||||
vec3_t absmin;
|
||||
vec3_t absmax;
|
||||
float entnum;
|
||||
float drawmask;
|
||||
func_t predraw;
|
||||
float movetype;
|
||||
float solid;
|
||||
vec3_t origin;
|
||||
vec3_t oldorigin;
|
||||
vec3_t velocity;
|
||||
vec3_t angles;
|
||||
vec3_t avelocity;
|
||||
string_t classname;
|
||||
string_t model;
|
||||
float frame;
|
||||
float skin;
|
||||
float effects;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t size;
|
||||
func_t touch;
|
||||
func_t use;
|
||||
func_t think;
|
||||
func_t blocked;
|
||||
float nextthink;
|
||||
int chain;
|
||||
string_t netname;
|
||||
int enemy;
|
||||
float flags;
|
||||
float colormap;
|
||||
int owner;
|
||||
} cl_entvars_t;
|
||||
|
||||
#define CL_PROGHEADER_CRC 52195
|
||||
*/
|
||||
|
||||
#endif
|
5007
app/jni/clvm_cmds.c
Normal file
5007
app/jni/clvm_cmds.c
Normal file
File diff suppressed because it is too large
Load diff
27
app/jni/clvm_cmds.h
Normal file
27
app/jni/clvm_cmds.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef __CLVM_CMDS_H__
|
||||
#define __CLVM_CMDS_H__
|
||||
|
||||
/* These are VM built-ins that originate in the client-side programs support
|
||||
but are reused by the other programs (usually the menu). */
|
||||
|
||||
void VM_CL_setmodel (void);
|
||||
void VM_CL_precache_model (void);
|
||||
void VM_CL_setorigin (void);
|
||||
|
||||
void VM_CL_R_AddDynamicLight (void);
|
||||
void VM_CL_R_ClearScene (void);
|
||||
void VM_CL_R_AddEntities (void);
|
||||
void VM_CL_R_AddEntity (void);
|
||||
void VM_CL_R_SetView (void);
|
||||
void VM_CL_R_RenderScene (void);
|
||||
void VM_CL_R_LoadWorldModel (void);
|
||||
|
||||
void VM_CL_R_PolygonBegin (void);
|
||||
void VM_CL_R_PolygonVertex (void);
|
||||
void VM_CL_R_PolygonEnd (void);
|
||||
|
||||
void VM_CL_setattachment(void);
|
||||
void VM_CL_gettagindex(void);
|
||||
void VM_CL_gettaginfo(void);
|
||||
|
||||
#endif /* __CLVM_CMDS_H__ */
|
2233
app/jni/cmd.c
Normal file
2233
app/jni/cmd.c
Normal file
File diff suppressed because it is too large
Load diff
173
app/jni/cmd.h
Normal file
173
app/jni/cmd.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
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 quake.rc\n"); Cbuf_Execute ();
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CMD_H
|
||||
#define CMD_H
|
||||
|
||||
/// allocates an initial text buffer that will grow as needed
|
||||
void Cbuf_Init (void);
|
||||
|
||||
void Cmd_Init_Commands (void);
|
||||
|
||||
void Cbuf_Shutdown (void);
|
||||
|
||||
/*! as new commands are generated from the console or keybindings,
|
||||
* the text is added to the end of the command buffer.
|
||||
*/
|
||||
void Cbuf_AddText (const 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_InsertText (const char *text);
|
||||
|
||||
/*! Pulls off 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.
|
||||
* \note Do not call inside a command function!
|
||||
*/
|
||||
void Cbuf_Execute (void);
|
||||
/*! Performs deferred commands and runs Cbuf_Execute, called by Host_Main */
|
||||
void Cbuf_Frame (void);
|
||||
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
|
||||
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;
|
||||
|
||||
void Cmd_Init (void);
|
||||
void Cmd_Shutdown (void);
|
||||
|
||||
// called by Host_Init, this marks cvars, commands and aliases with their init values
|
||||
void Cmd_SaveInitState (void);
|
||||
// called by FS_GameDir_f, this restores cvars, commands and aliases to init values
|
||||
void Cmd_RestoreInitState (void);
|
||||
|
||||
void Cmd_AddCommand_WithClientCommand (const char *cmd_name, xcommand_t consolefunction, xcommand_t clientfunction, const char *description);
|
||||
void Cmd_AddCommand (const char *cmd_name, xcommand_t function, const char *description);
|
||||
// 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
|
||||
|
||||
/// used by the cvar code to check for cvar / command name overlap
|
||||
qboolean Cmd_Exists (const char *cmd_name);
|
||||
|
||||
/// attempts to match a partial command for automatic command line completion
|
||||
/// returns NULL if nothing fits
|
||||
const char *Cmd_CompleteCommand (const char *partial);
|
||||
|
||||
int Cmd_CompleteAliasCountPossible (const char *partial);
|
||||
|
||||
const char **Cmd_CompleteAliasBuildList (const char *partial);
|
||||
|
||||
int Cmd_CompleteCountPossible (const char *partial);
|
||||
|
||||
const char **Cmd_CompleteBuildList (const char *partial);
|
||||
|
||||
void Cmd_CompleteCommandPrint (const char *partial);
|
||||
|
||||
const char *Cmd_CompleteAlias (const char *partial);
|
||||
|
||||
void Cmd_CompleteAliasPrint (const char *partial);
|
||||
|
||||
// Enhanced console completion by Fett erich@heintz.com
|
||||
|
||||
// Added by EvilTypeGuy eviltypeguy@qeradiant.com
|
||||
|
||||
int Cmd_Argc (void);
|
||||
const char *Cmd_Argv (int arg);
|
||||
const 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 always safe.
|
||||
|
||||
/// 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 (const char *parm);
|
||||
|
||||
//void Cmd_TokenizeString (char *text);
|
||||
// Takes a null terminated string. Does not need to be /n terminated.
|
||||
// breaks the string up into arg tokens.
|
||||
|
||||
/// 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_ExecuteString (const char *text, cmd_source_t src, qboolean lockmutex);
|
||||
|
||||
/// adds the string as a clc_stringcmd to the client message.
|
||||
/// (used when there is no reason to generate a local command to do it)
|
||||
void Cmd_ForwardStringToServer (const char *s);
|
||||
|
||||
/// 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_ForwardToServer (void);
|
||||
|
||||
/// used by command functions to send output to either the graphics console or
|
||||
/// passed as a print message to the client
|
||||
void Cmd_Print(const char *text);
|
||||
|
||||
/// quotes a string so that it can be used as a command argument again;
|
||||
/// quoteset is a string that contains one or more of ", \, $ and specifies
|
||||
/// the characters to be quoted (you usually want to either pass "\"\\" or
|
||||
/// "\"\\$"). Returns true on success, and false on overrun (in which case out
|
||||
/// will contain a part of the quoted string). If putquotes is set, the
|
||||
/// enclosing quote marks are also put.
|
||||
qboolean Cmd_QuoteString(char *out, size_t outlen, const char *in, const char *quoteset, qboolean putquotes);
|
||||
|
||||
void Cmd_ClearCsqcFuncs (void);
|
||||
|
||||
#endif
|
||||
|
1988
app/jni/collision.c
Normal file
1988
app/jni/collision.c
Normal file
File diff suppressed because it is too large
Load diff
191
app/jni/collision.h
Normal file
191
app/jni/collision.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
|
||||
#ifndef COLLISION_H
|
||||
#define COLLISION_H
|
||||
|
||||
typedef struct plane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
}
|
||||
plane_t;
|
||||
|
||||
struct texture_s;
|
||||
typedef struct trace_s
|
||||
{
|
||||
// if true, the entire trace was in solid (see hitsupercontentsmask)
|
||||
int allsolid;
|
||||
// if true, the initial point was in solid (see hitsupercontentsmask)
|
||||
int startsolid;
|
||||
// this is set to true in world.c if startsolid was set in a trace against world
|
||||
int worldstartsolid;
|
||||
// this is set to true in world.c if startsolid was set in a trace against a SOLID_BSP entity, in other words this is true if the entity is stuck in a door or wall, but not if stuck in another normal entity
|
||||
int bmodelstartsolid;
|
||||
// if true, the trace passed through empty somewhere
|
||||
// (set only by Q1BSP tracing)
|
||||
int inopen;
|
||||
// if true, the trace passed through water/slime/lava somewhere
|
||||
// (set only by Q1BSP tracing)
|
||||
int inwater;
|
||||
// fraction of the total distance that was traveled before impact
|
||||
// (1.0 = did not hit anything)
|
||||
double fraction;
|
||||
// like fraction but is not nudged away from the surface (better for
|
||||
// comparisons between two trace structs, as only one nudge for the final
|
||||
// result is ever needed)
|
||||
double realfraction;
|
||||
// final position of the trace (simply a point between start and end)
|
||||
double endpos[3];
|
||||
// surface normal at impact (not really correct for edge collisions)
|
||||
plane_t plane;
|
||||
// entity the surface is on
|
||||
// (not set by trace functions, only by physics)
|
||||
void *ent;
|
||||
// which SUPERCONTENTS bits to collide with, I.E. to consider solid
|
||||
// (this also affects startsolid/allsolid)
|
||||
int hitsupercontentsmask;
|
||||
// the supercontents mask at the start point
|
||||
int startsupercontents;
|
||||
// the supercontents of the impacted surface
|
||||
int hitsupercontents;
|
||||
// the q3 surfaceflags of the impacted surface
|
||||
int hitq3surfaceflags;
|
||||
// the texture of the impacted surface
|
||||
const struct texture_s *hittexture;
|
||||
// initially false, set when the start leaf is found
|
||||
// (set only by Q1BSP tracing and entity box tracing)
|
||||
int startfound;
|
||||
// if startsolid, contains the minimum penetration depth found in the
|
||||
// trace, and the normal needed to push it out of that solid
|
||||
double startdepth;
|
||||
double startdepthnormal[3];
|
||||
}
|
||||
trace_t;
|
||||
|
||||
void Collision_Init(void);
|
||||
void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture);
|
||||
void Collision_ClipTrace_Point(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, int hitsupercontentsmask, int boxsupercontents, int boxq3surfaceflags, const texture_t *boxtexture);
|
||||
|
||||
void Collision_Cache_Reset(qboolean resetlimits);
|
||||
void Collision_Cache_Init(mempool_t *mempool);
|
||||
void Collision_Cache_NewFrame(void);
|
||||
|
||||
typedef struct colpointf_s
|
||||
{
|
||||
vec3_t v;
|
||||
}
|
||||
colpointf_t;
|
||||
|
||||
typedef struct colplanef_s
|
||||
{
|
||||
const struct texture_s *texture;
|
||||
int q3surfaceflags;
|
||||
vec3_t normal;
|
||||
vec_t dist;
|
||||
}
|
||||
colplanef_t;
|
||||
|
||||
typedef struct colbrushf_s
|
||||
{
|
||||
// culling box
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
// used to avoid tracing against the same brush more than once per sweep
|
||||
int markframe;
|
||||
// the content flags of this brush
|
||||
int supercontents;
|
||||
// bounding planes (face planes) of this brush
|
||||
int numplanes;
|
||||
colplanef_t *planes;
|
||||
// edge directions (normals) of this brush
|
||||
int numedgedirs;
|
||||
colpointf_t *edgedirs;
|
||||
// points (corners) of this brush
|
||||
int numpoints;
|
||||
colpointf_t *points;
|
||||
// renderable triangles representing this brush, using the points
|
||||
int numtriangles;
|
||||
int *elements;
|
||||
// texture data for cases where an edgedir is used
|
||||
const struct texture_s *texture;
|
||||
int q3surfaceflags;
|
||||
// optimized collisions for common cases
|
||||
int isaabb; // indicates this is an axis aligned box
|
||||
int hasaabbplanes; // indicates this has precomputed planes for AABB collisions
|
||||
}
|
||||
colbrushf_t;
|
||||
|
||||
typedef struct colboxbrushf_s
|
||||
{
|
||||
colpointf_t points[8];
|
||||
colpointf_t edgedirs[6];
|
||||
colplanef_t planes[6];
|
||||
colbrushf_t brush;
|
||||
}
|
||||
colboxbrushf_t;
|
||||
|
||||
void Collision_CalcPlanesForTriangleBrushFloat(colbrushf_t *brush);
|
||||
colbrushf_t *Collision_AllocBrushFromPermanentPolygonFloat(mempool_t *mempool, int numpoints, float *points, int supercontents, int q3surfaceflags, const texture_t *texture);
|
||||
colbrushf_t *Collision_NewBrushFromPlanes(mempool_t *mempool, int numoriginalplanes, const colplanef_t *originalplanes, int supercontents, int q3surfaceflags, const texture_t *texture, int hasaabbplanes);
|
||||
void Collision_TraceBrushBrushFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, const colbrushf_t *thatbrush_start, const colbrushf_t *thatbrush_end);
|
||||
void Collision_TraceBrushTriangleMeshFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, const texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs);
|
||||
void Collision_TraceLineBrushFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, const colbrushf_t *thatbrush_start, const colbrushf_t *thatbrush_end);
|
||||
void Collision_TraceLineTriangleMeshFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, int numtriangles, const int *element3i, const float *vertex3f, int stride, float *bbox6f, int supercontents, int q3surfaceflags, const texture_t *texture, const vec3_t segmentmins, const vec3_t segmentmaxs);
|
||||
void Collision_TracePointBrushFloat(trace_t *trace, const vec3_t point, const colbrushf_t *thatbrush);
|
||||
qboolean Collision_PointInsideBrushFloat(const vec3_t point, const colbrushf_t *brush);
|
||||
|
||||
void Collision_BrushForBox(colboxbrushf_t *boxbrush, const vec3_t mins, const vec3_t maxs, int supercontents, int q3surfaceflags, const texture_t *texture);
|
||||
|
||||
void Collision_BoundingBoxOfBrushTraceSegment(const colbrushf_t *start, const colbrushf_t *end, vec3_t mins, vec3_t maxs, float startfrac, float endfrac);
|
||||
|
||||
float Collision_ClipTrace_Line_Sphere(double *linestart, double *lineend, double *sphereorigin, double sphereradius, double *impactpoint, double *impactnormal);
|
||||
void Collision_TraceLineTriangleFloat(trace_t *trace, const vec3_t linestart, const vec3_t lineend, const float *point0, const float *point1, const float *point2, int supercontents, int q3surfaceflags, const texture_t *texture);
|
||||
void Collision_TraceBrushTriangleFloat(trace_t *trace, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, const float *v0, const float *v1, const float *v2, int supercontents, int q3surfaceflags, const texture_t *texture);
|
||||
|
||||
// traces a box move against a single entity
|
||||
// mins and maxs are relative
|
||||
//
|
||||
// if the entire move stays in a single solid brush, trace.allsolid will be set
|
||||
//
|
||||
// if the starting point is in a solid, it will be allowed to move out to an
|
||||
// open area, and trace.startsolid will be set
|
||||
//
|
||||
// type is one of the MOVE_ values such as MOVE_NOMONSTERS which skips box
|
||||
// entities, only colliding with SOLID_BSP entities (doors, lifts)
|
||||
//
|
||||
// passedict is excluded from clipping checks
|
||||
struct frameblend_s;
|
||||
struct skeleton_s;
|
||||
void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask);
|
||||
void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, qboolean hitsurfaces);
|
||||
void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask);
|
||||
// like above but does not do a transform and does nothing if model is NULL
|
||||
void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontents);
|
||||
void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents, qboolean hitsurfaces);
|
||||
void Collision_ClipPointToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, int hitsupercontents);
|
||||
// caching surface trace for renderer (NOT THREAD SAFE)
|
||||
void Collision_Cache_ClipLineToGenericEntitySurfaces(trace_t *trace, dp_model_t *model, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
|
||||
void Collision_Cache_ClipLineToWorldSurfaces(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents);
|
||||
// combines data from two traces:
|
||||
// merges contents flags, startsolid, allsolid, inwater
|
||||
// updates fraction, endpos, plane and surface info if new fraction is shorter
|
||||
void Collision_CombineTraces(trace_t *cliptrace, const trace_t *trace, void *touch, qboolean isbmodel);
|
||||
|
||||
// shorten a trace by the given factor
|
||||
void Collision_ShortenTrace(trace_t *trace, float shorten_factor, const vec3_t end);
|
||||
|
||||
// this enables rather large debugging spew!
|
||||
// settings:
|
||||
// 0 = no spew
|
||||
// 1 = spew trace calls if something odd is happening
|
||||
// 2 = spew trace calls always
|
||||
// 3 = spew detailed trace flow (bsp tree recursion info)
|
||||
#define COLLISIONPARANOID 0
|
||||
|
||||
// make every trace <collision_endposnudge>qu longer, and shorten the result, to work around a stupid bug somewhere
|
||||
#define COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
|
||||
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
|
||||
extern cvar_t collision_endposnudge;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
2276
app/jni/common.c
Normal file
2276
app/jni/common.c
Normal file
File diff suppressed because it is too large
Load diff
380
app/jni/common.h
Normal file
380
app/jni/common.h
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
|
||||
/// MSVC has a different name for several standard functions
|
||||
#ifdef WIN32
|
||||
# define strcasecmp _stricmp
|
||||
# define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
// Create our own define for Mac OS X
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# define MACOSX
|
||||
#endif
|
||||
|
||||
#ifdef SUNOS
|
||||
#include <sys/file.h> ///< Needed for FNDELAY
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef struct sizebuf_s
|
||||
{
|
||||
qboolean allowoverflow; ///< if false, do a Sys_Error
|
||||
qboolean overflowed; ///< set to true if the buffer size failed
|
||||
unsigned char *data;
|
||||
int maxsize;
|
||||
int cursize;
|
||||
int readcount;
|
||||
qboolean badread; // set if a read goes beyond end of message
|
||||
} sizebuf_t;
|
||||
|
||||
void SZ_Clear (sizebuf_t *buf);
|
||||
unsigned char *SZ_GetSpace (sizebuf_t *buf, int length);
|
||||
void SZ_Write (sizebuf_t *buf, const unsigned char *data, int length);
|
||||
void SZ_HexDumpToConsole(const sizebuf_t *buf);
|
||||
|
||||
void Com_HexDumpToConsole(const unsigned char *data, int size);
|
||||
|
||||
unsigned short CRC_Block(const unsigned char *data, size_t size);
|
||||
unsigned short CRC_Block_CaseInsensitive(const unsigned char *data, size_t size); // for hash lookup functions that use strcasecmp for comparison
|
||||
|
||||
unsigned char COM_BlockSequenceCRCByteQW(unsigned char *base, int length, int sequence);
|
||||
|
||||
// these are actually md4sum (mdfour.c)
|
||||
unsigned Com_BlockChecksum (void *buffer, int length);
|
||||
void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
|
||||
|
||||
void COM_Init_Commands(void);
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Endianess handling
|
||||
//============================================================================
|
||||
|
||||
// check mem_bigendian if you need to know the system byte order
|
||||
|
||||
/*! \name Byte order functions.
|
||||
* @{
|
||||
*/
|
||||
|
||||
// unaligned memory access crashes on some platform, so always read bytes...
|
||||
#define BigShort(l) BuffBigShort((unsigned char *)&(l))
|
||||
#define LittleShort(l) BuffLittleShort((unsigned char *)&(l))
|
||||
#define BigLong(l) BuffBigLong((unsigned char *)&(l))
|
||||
#define LittleLong(l) BuffLittleLong((unsigned char *)&(l))
|
||||
#define BigFloat(l) BuffBigFloat((unsigned char *)&(l))
|
||||
#define LittleFloat(l) BuffLittleFloat((unsigned char *)&(l))
|
||||
|
||||
/// Extract a big endian 32bit float from the given \p buffer.
|
||||
float BuffBigFloat (const unsigned char *buffer);
|
||||
|
||||
/// Extract a big endian 32bit int from the given \p buffer.
|
||||
int BuffBigLong (const unsigned char *buffer);
|
||||
|
||||
/// Extract a big endian 16bit short from the given \p buffer.
|
||||
short BuffBigShort (const unsigned char *buffer);
|
||||
|
||||
/// Extract a little endian 32bit float from the given \p buffer.
|
||||
float BuffLittleFloat (const unsigned char *buffer);
|
||||
|
||||
/// Extract a little endian 32bit int from the given \p buffer.
|
||||
int BuffLittleLong (const unsigned char *buffer);
|
||||
|
||||
/// Extract a little endian 16bit short from the given \p buffer.
|
||||
short BuffLittleShort (const unsigned char *buffer);
|
||||
|
||||
/// Encode a big endian 32bit int to the given \p buffer
|
||||
void StoreBigLong (unsigned char *buffer, unsigned int i);
|
||||
|
||||
/// Encode a big endian 16bit int to the given \p buffer
|
||||
void StoreBigShort (unsigned char *buffer, unsigned short i);
|
||||
|
||||
/// Encode a little endian 32bit int to the given \p buffer
|
||||
void StoreLittleLong (unsigned char *buffer, unsigned int i);
|
||||
|
||||
/// Encode a little endian 16bit int to the given \p buffer
|
||||
void StoreLittleShort (unsigned char *buffer, unsigned short i);
|
||||
//@}
|
||||
|
||||
//============================================================================
|
||||
|
||||
// these versions are purely for internal use, never sent in network protocol
|
||||
// (use Protocol_EnumForNumber and Protocol_NumberToEnum to convert)
|
||||
typedef enum protocolversion_e
|
||||
{
|
||||
PROTOCOL_UNKNOWN,
|
||||
PROTOCOL_DARKPLACES7, ///< added QuakeWorld-style movement protocol to allow more consistent prediction
|
||||
PROTOCOL_DARKPLACES6, ///< various changes
|
||||
PROTOCOL_DARKPLACES5, ///< uses EntityFrame5 entity snapshot encoder/decoder which is based on a Tribes networking article at http://www.garagegames.com/articles/networking1/
|
||||
PROTOCOL_DARKPLACES4, ///< various changes
|
||||
PROTOCOL_DARKPLACES3, ///< uses EntityFrame4 entity snapshot encoder/decoder which is broken, this attempted to do partial snapshot updates on a QuakeWorld-like protocol, but it is broken and impossible to fix
|
||||
PROTOCOL_DARKPLACES2, ///< various changes
|
||||
PROTOCOL_DARKPLACES1, ///< uses EntityFrame entity snapshot encoder/decoder which is a QuakeWorld-like entity snapshot delta compression method
|
||||
PROTOCOL_QUAKEDP, ///< darkplaces extended quake protocol (used by TomazQuake and others), backwards compatible as long as no extended features are used
|
||||
PROTOCOL_NEHAHRAMOVIE, ///< Nehahra movie protocol, a big nasty hack dating back to early days of the Quake Standards Group (but only ever used by neh_gl.exe), this is potentially backwards compatible with quake protocol as long as no extended features are used (but in actuality the neh_gl.exe which wrote this protocol ALWAYS wrote the extended information)
|
||||
PROTOCOL_QUAKE, ///< quake (aka netquake/normalquake/nq) protocol
|
||||
PROTOCOL_QUAKEWORLD, ///< quakeworld protocol
|
||||
PROTOCOL_NEHAHRABJP, ///< same as QUAKEDP but with 16bit modelindex
|
||||
PROTOCOL_NEHAHRABJP2, ///< same as NEHAHRABJP but with 16bit soundindex
|
||||
PROTOCOL_NEHAHRABJP3 ///< same as NEHAHRABJP2 but with some changes
|
||||
}
|
||||
protocolversion_t;
|
||||
|
||||
/*! \name Message IO functions.
|
||||
* Handles byte ordering and avoids alignment errors
|
||||
* @{
|
||||
*/
|
||||
|
||||
void MSG_InitReadBuffer (sizebuf_t *buf, unsigned char *data, int size);
|
||||
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, vec_t f);
|
||||
void MSG_WriteString (sizebuf_t *sb, const char *s);
|
||||
void MSG_WriteUnterminatedString (sizebuf_t *sb, const char *s);
|
||||
void MSG_WriteAngle8i (sizebuf_t *sb, vec_t f);
|
||||
void MSG_WriteAngle16i (sizebuf_t *sb, vec_t f);
|
||||
void MSG_WriteAngle32f (sizebuf_t *sb, vec_t f);
|
||||
void MSG_WriteCoord13i (sizebuf_t *sb, vec_t f);
|
||||
void MSG_WriteCoord16i (sizebuf_t *sb, vec_t f);
|
||||
void MSG_WriteCoord32f (sizebuf_t *sb, vec_t f);
|
||||
void MSG_WriteCoord (sizebuf_t *sb, vec_t f, protocolversion_t protocol);
|
||||
void MSG_WriteVector (sizebuf_t *sb, const vec3_t v, protocolversion_t protocol);
|
||||
void MSG_WriteAngle (sizebuf_t *sb, vec_t f, protocolversion_t protocol);
|
||||
|
||||
void MSG_BeginReading (sizebuf_t *sb);
|
||||
int MSG_ReadLittleShort (sizebuf_t *sb);
|
||||
int MSG_ReadBigShort (sizebuf_t *sb);
|
||||
int MSG_ReadLittleLong (sizebuf_t *sb);
|
||||
int MSG_ReadBigLong (sizebuf_t *sb);
|
||||
float MSG_ReadLittleFloat (sizebuf_t *sb);
|
||||
float MSG_ReadBigFloat (sizebuf_t *sb);
|
||||
char *MSG_ReadString (sizebuf_t *sb, char *string, size_t maxstring);
|
||||
int MSG_ReadBytes (sizebuf_t *sb, int numbytes, unsigned char *out);
|
||||
|
||||
#define MSG_ReadChar(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (signed char)(sb)->data[(sb)->readcount++])
|
||||
#define MSG_ReadByte(sb) ((sb)->readcount >= (sb)->cursize ? ((sb)->badread = true, -1) : (unsigned char)(sb)->data[(sb)->readcount++])
|
||||
#define MSG_ReadShort MSG_ReadLittleShort
|
||||
#define MSG_ReadLong MSG_ReadLittleLong
|
||||
#define MSG_ReadFloat MSG_ReadLittleFloat
|
||||
|
||||
float MSG_ReadAngle8i (sizebuf_t *sb);
|
||||
float MSG_ReadAngle16i (sizebuf_t *sb);
|
||||
float MSG_ReadAngle32f (sizebuf_t *sb);
|
||||
float MSG_ReadCoord13i (sizebuf_t *sb);
|
||||
float MSG_ReadCoord16i (sizebuf_t *sb);
|
||||
float MSG_ReadCoord32f (sizebuf_t *sb);
|
||||
float MSG_ReadCoord (sizebuf_t *sb, protocolversion_t protocol);
|
||||
void MSG_ReadVector (sizebuf_t *sb, vec3_t v, protocolversion_t protocol);
|
||||
float MSG_ReadAngle (sizebuf_t *sb, protocolversion_t protocol);
|
||||
//@}
|
||||
//============================================================================
|
||||
|
||||
typedef float (*COM_WordWidthFunc_t) (void *passthrough, const char *w, size_t *length, float maxWidth); // length is updated to the longest fitting string into maxWidth; if maxWidth < 0, all characters are used and length is used as is
|
||||
typedef int (*COM_LineProcessorFunc) (void *passthrough, const char *line, size_t length, float width, qboolean isContination);
|
||||
int COM_Wordwrap(const char *string, size_t length, float continuationSize, float maxWidth, COM_WordWidthFunc_t wordWidth, void *passthroughCW, COM_LineProcessorFunc processLine, void *passthroughPL);
|
||||
|
||||
extern char com_token[MAX_INPUTLINE];
|
||||
|
||||
int COM_ParseToken_Simple(const char **datapointer, qboolean returnnewline, qboolean parsebackslash, qboolean parsecomments);
|
||||
int COM_ParseToken_QuakeC(const char **datapointer, qboolean returnnewline);
|
||||
int COM_ParseToken_VM_Tokenize(const char **datapointer, qboolean returnnewline);
|
||||
int COM_ParseToken_Console(const char **datapointer);
|
||||
|
||||
extern int com_argc;
|
||||
extern const char **com_argv;
|
||||
extern int com_selffd;
|
||||
|
||||
int COM_CheckParm (const char *parm);
|
||||
void COM_Init (void);
|
||||
void COM_Shutdown (void);
|
||||
void COM_InitGameType (void);
|
||||
|
||||
char *va(char *buf, size_t buflen, const char *format, ...) DP_FUNC_PRINTF(3);
|
||||
char *portable_va(char *buf, size_t buflen, const char *format, ...) DP_FUNC_PRINTF(3);
|
||||
// does a varargs printf into provided buffer, returns buffer (so it can be called in-line unlike dpsnprintf)
|
||||
|
||||
|
||||
// snprintf and vsnprintf are NOT portable. Use their DP counterparts instead
|
||||
#ifdef snprintf
|
||||
# undef snprintf
|
||||
#endif
|
||||
#define snprintf DO_NOT_USE_SNPRINTF__USE_DPSNPRINTF
|
||||
#ifdef vsnprintf
|
||||
# undef vsnprintf
|
||||
#endif
|
||||
//#define vsnprintf DO_NOT_USE_VSNPRINTF__USE_DPVSNPRINTF
|
||||
|
||||
// dpsnprintf and dpvsnprintf
|
||||
// return the number of printed characters, excluding the final '\0'
|
||||
// or return -1 if the buffer isn't big enough to contain the entire string.
|
||||
// buffer is ALWAYS null-terminated
|
||||
extern int dpsnprintf (char *buffer, size_t buffersize, const char *format, ...) DP_FUNC_PRINTF(3);
|
||||
extern int dpvsnprintf (char *buffer, size_t buffersize, const char *format, va_list args);
|
||||
|
||||
// A bunch of functions are forbidden for security reasons (and also to please MSVS 2005, for some of them)
|
||||
// LordHavoc: added #undef lines here to avoid warnings in Linux
|
||||
#undef strcat
|
||||
#define strcat DO_NOT_USE_STRCAT__USE_STRLCAT_OR_MEMCPY
|
||||
#undef strncat
|
||||
#define strncat DO_NOT_USE_STRNCAT__USE_STRLCAT_OR_MEMCPY
|
||||
#undef strcpy
|
||||
#define strcpy DO_NOT_USE_STRCPY__USE_STRLCPY_OR_MEMCPY
|
||||
#undef strncpy
|
||||
#define strncpy DO_NOT_USE_STRNCPY__USE_STRLCPY_OR_MEMCPY
|
||||
//#undef sprintf
|
||||
//#define sprintf DO_NOT_USE_SPRINTF__USE_DPSNPRINTF
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
extern struct cvar_s registered;
|
||||
extern struct cvar_s cmdline;
|
||||
|
||||
typedef enum userdirmode_e
|
||||
{
|
||||
USERDIRMODE_NOHOME, // basedir only
|
||||
USERDIRMODE_HOME, // Windows basedir, general POSIX (~/.)
|
||||
USERDIRMODE_MYGAMES, // pre-Vista (My Documents/My Games/), general POSIX (~/.)
|
||||
USERDIRMODE_SAVEDGAMES, // Vista (%USERPROFILE%/Saved Games/), OSX (~/Library/Application Support/), Linux (~/.config)
|
||||
USERDIRMODE_COUNT
|
||||
}
|
||||
userdirmode_t;
|
||||
|
||||
typedef enum gamemode_e
|
||||
{
|
||||
GAME_NORMAL,
|
||||
GAME_HIPNOTIC,
|
||||
GAME_ROGUE,
|
||||
GAME_QUOTH,
|
||||
GAME_NEHAHRA,
|
||||
GAME_NEXUIZ,
|
||||
GAME_XONOTIC,
|
||||
GAME_TRANSFUSION,
|
||||
GAME_GOODVSBAD2,
|
||||
GAME_TEU,
|
||||
GAME_BATTLEMECH,
|
||||
GAME_ZYMOTIC,
|
||||
GAME_SETHERAL,
|
||||
GAME_TENEBRAE, // full of evil hackery
|
||||
GAME_NEOTERIC,
|
||||
GAME_OPENQUARTZ, //this game sucks
|
||||
GAME_PRYDON,
|
||||
GAME_DELUXEQUAKE,
|
||||
GAME_THEHUNTED,
|
||||
GAME_DEFEATINDETAIL2,
|
||||
GAME_DARSANA,
|
||||
GAME_CONTAGIONTHEORY,
|
||||
GAME_EDU2P,
|
||||
GAME_PROPHECY,
|
||||
GAME_BLOODOMNICIDE,
|
||||
GAME_STEELSTORM, // added by motorsep
|
||||
GAME_STEELSTORM2, // added by motorsep
|
||||
GAME_TOMESOFMEPHISTOPHELES, // added by motorsep
|
||||
GAME_STRAPBOMB, // added by motorsep for Urre
|
||||
GAME_MOONHELM,
|
||||
GAME_COUNT
|
||||
}
|
||||
gamemode_t;
|
||||
|
||||
extern gamemode_t gamemode;
|
||||
extern const char *gamename;
|
||||
extern const char *gamedirname1;
|
||||
extern const char *gamedirname2;
|
||||
extern const char *gamescreenshotname;
|
||||
extern const char *gameuserdirname;
|
||||
extern char com_modname[MAX_OSPATH];
|
||||
|
||||
void COM_ChangeGameTypeForGameDirs(void);
|
||||
|
||||
void COM_ToLowerString (const char *in, char *out, size_t size_out);
|
||||
void COM_ToUpperString (const char *in, char *out, size_t size_out);
|
||||
int COM_StringBeginsWith(const char *s, const char *match);
|
||||
|
||||
int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *tokenbuf, int tokenbufsize, const char *commentprefix);
|
||||
|
||||
size_t COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid);
|
||||
qboolean COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qboolean escape_carets);
|
||||
void COM_ToLowerString (const char *in, char *out, size_t size_out);
|
||||
void COM_ToUpperString (const char *in, char *out, size_t size_out);
|
||||
|
||||
typedef struct stringlist_s
|
||||
{
|
||||
/// maxstrings changes as needed, causing reallocation of strings[] array
|
||||
int maxstrings;
|
||||
int numstrings;
|
||||
char **strings;
|
||||
} stringlist_t;
|
||||
|
||||
int matchpattern(const char *in, const char *pattern, int caseinsensitive);
|
||||
int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, qboolean wildcard_least_one);
|
||||
void stringlistinit(stringlist_t *list);
|
||||
void stringlistfreecontents(stringlist_t *list);
|
||||
void stringlistappend(stringlist_t *list, const char *text);
|
||||
void stringlistsort(stringlist_t *list, qboolean uniq);
|
||||
void listdirectory(stringlist_t *list, const char *basepath, const char *path);
|
||||
|
||||
char *InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength);
|
||||
void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value);
|
||||
void InfoString_Print(char *buffer);
|
||||
|
||||
// strlcat and strlcpy, from OpenBSD
|
||||
// Most (all?) BSDs already have them
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(MACOSX)
|
||||
# define HAVE_STRLCAT 1
|
||||
# define HAVE_STRLCPY 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/*!
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||
#endif // #ifndef HAVE_STRLCAT
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/*!
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
|
||||
#endif // #ifndef HAVE_STRLCPY
|
||||
|
||||
void FindFraction(double val, int *num, int *denom, int denomMax);
|
||||
|
||||
// decodes XPM file to XPM array (as if #include'd)
|
||||
char **XPM_DecodeString(const char *in);
|
||||
|
||||
size_t base64_encode(unsigned char *buf, size_t buflen, size_t outbuflen);
|
||||
|
||||
#endif
|
||||
|
365
app/jni/conproc.c
Normal file
365
app/jni/conproc.c
Normal file
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// conproc.c
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#include "conproc.h"
|
||||
|
||||
HANDLE heventDone;
|
||||
HANDLE hfileBuffer;
|
||||
HANDLE heventChildSend;
|
||||
HANDLE heventParentSend;
|
||||
HANDLE hStdout;
|
||||
HANDLE hStdin;
|
||||
|
||||
DWORD RequestProc (DWORD dwNichts);
|
||||
LPVOID GetMappedBuffer (HANDLE hfileBuffer);
|
||||
void ReleaseMappedBuffer (LPVOID pBuffer);
|
||||
BOOL GetScreenBufferLines (int *piLines);
|
||||
BOOL SetScreenBufferLines (int iLines);
|
||||
BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine);
|
||||
BOOL WriteText (LPCTSTR szText);
|
||||
int CharToCode (int c);
|
||||
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
|
||||
|
||||
|
||||
void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild)
|
||||
{
|
||||
DWORD dwID;
|
||||
|
||||
// ignore if we don't have all the events.
|
||||
if (!hFile || !heventParent || !heventChild)
|
||||
return;
|
||||
|
||||
hfileBuffer = hFile;
|
||||
heventParentSend = heventParent;
|
||||
heventChildSend = heventChild;
|
||||
|
||||
// so we'll know when to go away.
|
||||
heventDone = CreateEvent (NULL, false, false, NULL);
|
||||
|
||||
if (!heventDone)
|
||||
{
|
||||
Con_Print("Couldn't create heventDone\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CreateThread (NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE) RequestProc,
|
||||
0,
|
||||
0,
|
||||
&dwID))
|
||||
{
|
||||
CloseHandle (heventDone);
|
||||
Con_Print("Couldn't create QHOST thread\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// save off the input/output handles.
|
||||
hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
hStdin = GetStdHandle (STD_INPUT_HANDLE);
|
||||
|
||||
// force 80 character width, at least 25 character height
|
||||
SetConsoleCXCY (hStdout, 80, 25);
|
||||
}
|
||||
|
||||
|
||||
void DeinitConProc (void)
|
||||
{
|
||||
if (heventDone)
|
||||
SetEvent (heventDone);
|
||||
}
|
||||
|
||||
|
||||
DWORD RequestProc (DWORD dwNichts)
|
||||
{
|
||||
int *pBuffer;
|
||||
DWORD dwRet;
|
||||
HANDLE heventWait[2];
|
||||
int iBeginLine, iEndLine;
|
||||
|
||||
heventWait[0] = heventParentSend;
|
||||
heventWait[1] = heventDone;
|
||||
|
||||
while (1)
|
||||
{
|
||||
dwRet = WaitForMultipleObjects (2, heventWait, false, INFINITE);
|
||||
|
||||
// heventDone fired, so we're exiting.
|
||||
if (dwRet == WAIT_OBJECT_0 + 1)
|
||||
break;
|
||||
|
||||
pBuffer = (int *) GetMappedBuffer (hfileBuffer);
|
||||
|
||||
// hfileBuffer is invalid. Just leave.
|
||||
if (!pBuffer)
|
||||
{
|
||||
Con_Print("Invalid hfileBuffer\n");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pBuffer[0])
|
||||
{
|
||||
case CCOM_WRITE_TEXT:
|
||||
// Param1 : Text
|
||||
pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1));
|
||||
break;
|
||||
|
||||
case CCOM_GET_TEXT:
|
||||
// Param1 : Begin line
|
||||
// Param2 : End line
|
||||
iBeginLine = pBuffer[1];
|
||||
iEndLine = pBuffer[2];
|
||||
pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine,
|
||||
iEndLine);
|
||||
break;
|
||||
|
||||
case CCOM_GET_SCR_LINES:
|
||||
// No params
|
||||
pBuffer[0] = GetScreenBufferLines (&pBuffer[1]);
|
||||
break;
|
||||
|
||||
case CCOM_SET_SCR_LINES:
|
||||
// Param1 : Number of lines
|
||||
pBuffer[0] = SetScreenBufferLines (pBuffer[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
ReleaseMappedBuffer (pBuffer);
|
||||
SetEvent (heventChildSend);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
LPVOID GetMappedBuffer (HANDLE hfileBuffer)
|
||||
{
|
||||
LPVOID pBuffer;
|
||||
|
||||
pBuffer = MapViewOfFile (hfileBuffer,
|
||||
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
|
||||
void ReleaseMappedBuffer (LPVOID pBuffer)
|
||||
{
|
||||
UnmapViewOfFile (pBuffer);
|
||||
}
|
||||
|
||||
|
||||
BOOL GetScreenBufferLines (int *piLines)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
BOOL bRet;
|
||||
|
||||
bRet = GetConsoleScreenBufferInfo (hStdout, &info);
|
||||
|
||||
if (bRet)
|
||||
*piLines = info.dwSize.Y;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
BOOL SetScreenBufferLines (int iLines)
|
||||
{
|
||||
|
||||
return SetConsoleCXCY (hStdout, 80, iLines);
|
||||
}
|
||||
|
||||
|
||||
BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine)
|
||||
{
|
||||
COORD coord;
|
||||
DWORD dwRead;
|
||||
BOOL bRet;
|
||||
|
||||
coord.X = 0;
|
||||
coord.Y = iBeginLine;
|
||||
|
||||
bRet = ReadConsoleOutputCharacter(
|
||||
hStdout,
|
||||
pszText,
|
||||
80 * (iEndLine - iBeginLine + 1),
|
||||
coord,
|
||||
&dwRead);
|
||||
|
||||
// Make sure it's null terminated.
|
||||
if (bRet)
|
||||
pszText[dwRead] = '\0';
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
BOOL WriteText (LPCTSTR szText)
|
||||
{
|
||||
DWORD dwWritten;
|
||||
INPUT_RECORD rec;
|
||||
char upper, *sz;
|
||||
|
||||
sz = (LPTSTR) szText;
|
||||
|
||||
while (*sz)
|
||||
{
|
||||
// 13 is the code for a carriage return (\n) instead of 10.
|
||||
if (*sz == 10)
|
||||
*sz = 13;
|
||||
|
||||
upper = toupper(*sz);
|
||||
|
||||
rec.EventType = KEY_EVENT;
|
||||
rec.Event.KeyEvent.bKeyDown = true;
|
||||
rec.Event.KeyEvent.wRepeatCount = 1;
|
||||
rec.Event.KeyEvent.wVirtualKeyCode = upper;
|
||||
rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz);
|
||||
rec.Event.KeyEvent.uChar.AsciiChar = *sz;
|
||||
rec.Event.KeyEvent.uChar.UnicodeChar = *sz;
|
||||
rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0;
|
||||
|
||||
WriteConsoleInput(
|
||||
hStdin,
|
||||
&rec,
|
||||
1,
|
||||
&dwWritten);
|
||||
|
||||
rec.Event.KeyEvent.bKeyDown = false;
|
||||
|
||||
WriteConsoleInput(
|
||||
hStdin,
|
||||
&rec,
|
||||
1,
|
||||
&dwWritten);
|
||||
|
||||
sz++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int CharToCode (int c)
|
||||
{
|
||||
char upper;
|
||||
|
||||
upper = toupper(c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 13:
|
||||
return 28;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isalpha(c))
|
||||
return (30 + upper - 65);
|
||||
|
||||
if (isdigit(c))
|
||||
return (1 + upper - 47);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
COORD coordMax;
|
||||
|
||||
coordMax = GetLargestConsoleWindowSize(hStdout);
|
||||
|
||||
if (cy > coordMax.Y)
|
||||
cy = coordMax.Y;
|
||||
|
||||
if (cx > coordMax.X)
|
||||
cx = coordMax.X;
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(hStdout, &info))
|
||||
return false;
|
||||
|
||||
// height
|
||||
info.srWindow.Left = 0;
|
||||
info.srWindow.Right = info.dwSize.X - 1;
|
||||
info.srWindow.Top = 0;
|
||||
info.srWindow.Bottom = cy - 1;
|
||||
|
||||
if (cy < info.dwSize.Y)
|
||||
{
|
||||
if (!SetConsoleWindowInfo(hStdout, true, &info.srWindow))
|
||||
return false;
|
||||
|
||||
info.dwSize.Y = cy;
|
||||
|
||||
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
|
||||
return false;
|
||||
}
|
||||
else if (cy > info.dwSize.Y)
|
||||
{
|
||||
info.dwSize.Y = cy;
|
||||
|
||||
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
|
||||
return false;
|
||||
|
||||
if (!SetConsoleWindowInfo(hStdout, true, &info.srWindow))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(hStdout, &info))
|
||||
return false;
|
||||
|
||||
// width
|
||||
info.srWindow.Left = 0;
|
||||
info.srWindow.Right = cx - 1;
|
||||
info.srWindow.Top = 0;
|
||||
info.srWindow.Bottom = info.dwSize.Y - 1;
|
||||
|
||||
if (cx < info.dwSize.X)
|
||||
{
|
||||
if (!SetConsoleWindowInfo(hStdout, true, &info.srWindow))
|
||||
return false;
|
||||
|
||||
info.dwSize.X = cx;
|
||||
|
||||
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
|
||||
return false;
|
||||
}
|
||||
else if (cx > info.dwSize.X)
|
||||
{
|
||||
info.dwSize.X = cx;
|
||||
|
||||
if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
|
||||
return false;
|
||||
|
||||
if (!SetConsoleWindowInfo(hStdout, true, &info.srWindow))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
42
app/jni/conproc.h
Normal file
42
app/jni/conproc.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
// conproc.h
|
||||
|
||||
#ifndef CONPROC_H
|
||||
#define CONPROC_H
|
||||
|
||||
#define CCOM_WRITE_TEXT 0x2
|
||||
// Param1 : Text
|
||||
|
||||
#define CCOM_GET_TEXT 0x3
|
||||
// Param1 : Begin line
|
||||
// Param2 : End line
|
||||
|
||||
#define CCOM_GET_SCR_LINES 0x4
|
||||
// No params
|
||||
|
||||
#define CCOM_SET_SCR_LINES 0x5
|
||||
// Param1 : Number of lines
|
||||
|
||||
void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild);
|
||||
void DeinitConProc (void);
|
||||
|
||||
#endif
|
||||
|
3014
app/jni/console.c
Normal file
3014
app/jni/console.c
Normal file
File diff suppressed because it is too large
Load diff
151
app/jni/console.h
Normal file
151
app/jni/console.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
//
|
||||
// console
|
||||
//
|
||||
extern int con_totallines;
|
||||
extern int con_backscroll;
|
||||
extern qboolean con_initialized;
|
||||
|
||||
void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest, qboolean proquakeprotocol);
|
||||
void Con_Rcon_Redirect_End(void);
|
||||
void Con_Rcon_Redirect_Abort(void);
|
||||
|
||||
/// If the line width has changed, reformat the buffer.
|
||||
void Con_CheckResize (void);
|
||||
void Con_Init (void);
|
||||
void Con_Init_Commands (void);
|
||||
void Con_Shutdown (void);
|
||||
void Con_DrawConsole (int lines);
|
||||
|
||||
/// Prints to a chosen console target
|
||||
void Con_MaskPrint(int mask, const char *msg);
|
||||
|
||||
// Prints to a chosen console target
|
||||
void Con_MaskPrintf(int mask, const char *fmt, ...) DP_FUNC_PRINTF(2);
|
||||
|
||||
/// Prints to all appropriate console targets, and adds timestamps
|
||||
void Con_Print(const char *txt);
|
||||
|
||||
/// Prints to all appropriate console targets.
|
||||
void Con_Printf(const char *fmt, ...) DP_FUNC_PRINTF(1);
|
||||
|
||||
/// A Con_Print that only shows up if the "developer" cvar is set.
|
||||
void Con_DPrint(const char *msg);
|
||||
|
||||
/// A Con_Printf that only shows up if the "developer" cvar is set
|
||||
void Con_DPrintf(const char *fmt, ...) DP_FUNC_PRINTF(1);
|
||||
void Con_Clear_f (void);
|
||||
void Con_DrawNotify (void);
|
||||
|
||||
/// Clear all notify lines.
|
||||
void Con_ClearNotify (void);
|
||||
void Con_ToggleConsole_f (void);
|
||||
|
||||
int Nicks_CompleteChatLine(char *buffer, size_t size, unsigned int pos);
|
||||
|
||||
qboolean GetMapList (const char *s, char *completedname, int completednamebufferlength);
|
||||
|
||||
/// wrapper function to attempt to either complete the command line
|
||||
/// or to list possible matches grouped by type
|
||||
/// (i.e. will display possible variables, aliases, commands
|
||||
/// that match what they've typed so far)
|
||||
void Con_CompleteCommandLine(void);
|
||||
|
||||
/// Generic libs/util/console.c function to display a list
|
||||
/// formatted in columns on the console
|
||||
void Con_DisplayList(const char **list);
|
||||
|
||||
|
||||
/*! \name log
|
||||
* @{
|
||||
*/
|
||||
void Log_Init (void);
|
||||
void Log_Close (void);
|
||||
void Log_Start (void);
|
||||
void Log_DestBuffer_Flush (void); ///< call this once per frame to send out replies to rcon streaming clients
|
||||
|
||||
void Log_Printf(const char *logfilename, const char *fmt, ...) DP_FUNC_PRINTF(2);
|
||||
//@}
|
||||
|
||||
// CON_MASK_PRINT is the default (Con_Print/Con_Printf)
|
||||
// CON_MASK_DEVELOPER is used by Con_DPrint/Con_DPrintf
|
||||
#define CON_MASK_HIDENOTIFY 128
|
||||
#define CON_MASK_CHAT 1
|
||||
#define CON_MASK_INPUT 2
|
||||
#define CON_MASK_DEVELOPER 4
|
||||
#define CON_MASK_PRINT 8
|
||||
|
||||
typedef struct con_lineinfo_s
|
||||
{
|
||||
char *start;
|
||||
size_t len;
|
||||
int mask;
|
||||
|
||||
/// used only by console.c
|
||||
double addtime;
|
||||
int height; ///< recalculated line height when needed (-1 to unset)
|
||||
}
|
||||
con_lineinfo_t;
|
||||
|
||||
typedef struct conbuffer_s
|
||||
{
|
||||
qboolean active;
|
||||
int textsize;
|
||||
char *text;
|
||||
int maxlines;
|
||||
con_lineinfo_t *lines;
|
||||
int lines_first;
|
||||
int lines_count; ///< cyclic buffer
|
||||
}
|
||||
conbuffer_t;
|
||||
|
||||
#define CONBUFFER_LINES(buf, i) (buf)->lines[((buf)->lines_first + (i)) % (buf)->maxlines]
|
||||
#define CONBUFFER_LINES_COUNT(buf) ((buf)->lines_count)
|
||||
#define CONBUFFER_LINES_LAST(buf) CONBUFFER_LINES(buf, CONBUFFER_LINES_COUNT(buf) - 1)
|
||||
|
||||
void ConBuffer_Init(conbuffer_t *buf, int textsize, int maxlines, mempool_t *mempool);
|
||||
void ConBuffer_Clear (conbuffer_t *buf);
|
||||
void ConBuffer_Shutdown(conbuffer_t *buf);
|
||||
|
||||
/*! Notifies the console code about the current time
|
||||
* (and shifts back times of other entries when the time
|
||||
* went backwards)
|
||||
*/
|
||||
void ConBuffer_FixTimes(conbuffer_t *buf);
|
||||
|
||||
/// Deletes the first line from the console history.
|
||||
void ConBuffer_DeleteLine(conbuffer_t *buf);
|
||||
|
||||
/// Deletes the last line from the console history.
|
||||
void ConBuffer_DeleteLastLine(conbuffer_t *buf);
|
||||
|
||||
/// Appends a given string as a new line to the console.
|
||||
void ConBuffer_AddLine(conbuffer_t *buf, const char *line, int len, int mask);
|
||||
int ConBuffer_FindPrevLine(conbuffer_t *buf, int mask_must, int mask_mustnot, int start);
|
||||
int ConBuffer_FindNextLine(conbuffer_t *buf, int mask_must, int mask_mustnot, int start);
|
||||
const char *ConBuffer_GetLine(conbuffer_t *buf, int i);
|
||||
|
||||
#endif
|
||||
|
2588
app/jni/crypto.c
Normal file
2588
app/jni/crypto.c
Normal file
File diff suppressed because it is too large
Load diff
158
app/jni/crypto.h
Normal file
158
app/jni/crypto.h
Normal file
|
@ -0,0 +1,158 @@
|
|||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
extern cvar_t crypto_developer;
|
||||
extern cvar_t crypto_aeslevel;
|
||||
#define ENCRYPTION_REQUIRED (crypto_aeslevel.integer >= 3)
|
||||
|
||||
extern int crypto_keyfp_recommended_length; // applies to LOCAL IDs, and to ALL keys
|
||||
|
||||
#define CRYPTO_HEADERSIZE 31
|
||||
// AES case causes 16 to 31 bytes overhead
|
||||
// SHA256 case causes 16 bytes overhead as we truncate to 128bit
|
||||
|
||||
#include "lhnet.h"
|
||||
|
||||
#define FP64_SIZE 44
|
||||
#define DHKEY_SIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char dhkey[DHKEY_SIZE]; // shared key, not NUL terminated
|
||||
char client_idfp[FP64_SIZE+1];
|
||||
char client_keyfp[FP64_SIZE+1]; // NULL if signature fail
|
||||
char server_idfp[FP64_SIZE+1];
|
||||
char server_keyfp[FP64_SIZE+1]; // NULL if signature fail
|
||||
qboolean authenticated;
|
||||
qboolean use_aes;
|
||||
void *data;
|
||||
}
|
||||
crypto_t;
|
||||
|
||||
void Crypto_Init(void);
|
||||
void Crypto_Init_Commands(void);
|
||||
void Crypto_LoadKeys(void); // NOTE: when this is called, the SV_LockThreadMutex MUST be active
|
||||
void Crypto_Shutdown(void);
|
||||
qboolean Crypto_Available(void);
|
||||
void sha256(unsigned char *out, const unsigned char *in, int n); // may ONLY be called if Crypto_Available()
|
||||
const void *Crypto_EncryptPacket(crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len);
|
||||
const void *Crypto_DecryptPacket(crypto_t *crypto, const void *data_src, size_t len_src, void *data_dst, size_t *len_dst, size_t len);
|
||||
#define CRYPTO_NOMATCH 0 // process as usual (packet was not used)
|
||||
#define CRYPTO_MATCH 1 // process as usual (packet was used)
|
||||
#define CRYPTO_DISCARD 2 // discard this packet
|
||||
#define CRYPTO_REPLACE 3 // make the buffer the current packet
|
||||
int Crypto_ClientParsePacket(const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress);
|
||||
int Crypto_ServerParsePacket(const char *data_in, size_t len_in, char *data_out, size_t *len_out, lhnetaddress_t *peeraddress);
|
||||
|
||||
// if len_out is nonzero, the packet is to be sent to the client
|
||||
|
||||
qboolean Crypto_ServerAppendToChallenge(const char *data_in, size_t len_in, char *data_out, size_t *len_out, size_t maxlen);
|
||||
crypto_t *Crypto_ServerGetInstance(lhnetaddress_t *peeraddress);
|
||||
qboolean Crypto_ServerFinishInstance(crypto_t *out, crypto_t *in); // also clears allocated memory
|
||||
const char *Crypto_GetInfoResponseDataString(void);
|
||||
|
||||
// retrieves a host key for an address (can be exposed to menuqc, or used by the engine to look up stored keys e.g. for server bookmarking)
|
||||
// pointers may be NULL
|
||||
qboolean Crypto_RetrieveHostKey(lhnetaddress_t *peeraddress, int *keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, int *aeslevel);
|
||||
int Crypto_RetrieveLocalKey(int keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen, qboolean *issigned); // return value: -1 if more to come, +1 if valid, 0 if end of list
|
||||
|
||||
size_t Crypto_SignData(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size);
|
||||
size_t Crypto_SignDataDetached(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size);
|
||||
|
||||
// netconn protocol:
|
||||
// non-crypto:
|
||||
// getchallenge >
|
||||
// < challenge
|
||||
// connect >
|
||||
// < accept (or: reject)
|
||||
// crypto:
|
||||
// getchallenge >
|
||||
// < challenge SP <challenge> NUL vlen <size> d0pk <fingerprints I can auth to> NUL NUL <other fingerprints I accept>
|
||||
//
|
||||
// IF serverfp:
|
||||
// d0pk\cnt\0\challenge\<challenge>\aeslevel\<level> NUL <serverfp> NUL <clientfp>
|
||||
// >
|
||||
// check if client would get accepted; if not, do "reject" now
|
||||
// require non-control packets to be encrypted require non-control packets to be encrypted
|
||||
// do not send anything yet do not send anything yet
|
||||
// RESET to serverfp RESET to serverfp
|
||||
// d0_blind_id_authenticate_with_private_id_start() = 1
|
||||
// < d0pk\cnt\1\aes\<aesenabled> NUL *startdata*
|
||||
// d0_blind_id_authenticate_with_private_id_challenge() = 1
|
||||
// d0pk\cnt\2 NUL *challengedata* >
|
||||
// d0_blind_id_authenticate_with_private_id_response() = 0
|
||||
// < d0pk\cnt\3 NUL *responsedata*
|
||||
// d0_blind_id_authenticate_with_private_id_verify() = 1
|
||||
// store server's fingerprint NOW
|
||||
// d0_blind_id_sessionkey_public_id() = 1 d0_blind_id_sessionkey_public_id() = 1
|
||||
//
|
||||
// IF clientfp AND NOT serverfp:
|
||||
// RESET to clientfp RESET to clientfp
|
||||
// d0_blind_id_authenticate_with_private_id_start() = 1
|
||||
// d0pk\cnt\0\challenge\<challenge>\aeslevel\<level> NUL NUL <clientfp> NUL *startdata*
|
||||
// >
|
||||
// check if client would get accepted; if not, do "reject" now
|
||||
// require non-control packets to be encrypted require non-control packets to be encrypted
|
||||
// d0_blind_id_authenticate_with_private_id_challenge() = 1
|
||||
// < d0pk\cnt\5\aes\<aesenabled> NUL *challengedata*
|
||||
//
|
||||
// IF clientfp AND serverfp:
|
||||
// RESET to clientfp RESET to clientfp
|
||||
// d0_blind_id_authenticate_with_private_id_start() = 1
|
||||
// d0pk\cnt\4 NUL *startdata* >
|
||||
// d0_blind_id_authenticate_with_private_id_challenge() = 1
|
||||
// < d0pk\cnt\5 NUL *challengedata*
|
||||
//
|
||||
// IF clientfp:
|
||||
// d0_blind_id_authenticate_with_private_id_response() = 0
|
||||
// d0pk\cnt\6 NUL *responsedata* >
|
||||
// d0_blind_id_authenticate_with_private_id_verify() = 1
|
||||
// store client's fingerprint NOW
|
||||
// d0_blind_id_sessionkey_public_id() = 1 d0_blind_id_sessionkey_public_id() = 1
|
||||
// note: the ... is the "connect" message, except without the challenge. Reinterpret as regular connect message on server side
|
||||
//
|
||||
// enforce encrypted transmission (key is XOR of the two DH keys)
|
||||
//
|
||||
// IF clientfp:
|
||||
// < challenge (mere sync message)
|
||||
//
|
||||
// connect\... >
|
||||
// < accept (ALWAYS accept if connection is encrypted, ignore challenge as it had been checked before)
|
||||
//
|
||||
// commence with ingame protocol
|
||||
|
||||
// in short:
|
||||
// server:
|
||||
// getchallenge NUL d0_blind_id: reply with challenge with added fingerprints
|
||||
// cnt=0: IF server will auth, cnt=1, ELSE cnt=5
|
||||
// cnt=2: cnt=3
|
||||
// cnt=4: cnt=5
|
||||
// cnt=6: send "challenge"
|
||||
// client:
|
||||
// challenge with added fingerprints: cnt=0; if client will auth but not server, append client auth start
|
||||
// cnt=1: cnt=2
|
||||
// cnt=3: IF client will auth, cnt=4, ELSE rewrite as "challenge"
|
||||
// cnt=5: cnt=6, server will continue by sending "challenge" (let's avoid sending two packets as response to one)
|
||||
// other change:
|
||||
// accept empty "challenge", and challenge-less connect in case crypto protocol has executed and finished
|
||||
// statusResponse and infoResponse get an added d0_blind_id key that lists
|
||||
// the keys the server can auth with and to in key@ca SPACE key@ca notation
|
||||
// any d0pk\ message has an appended "id" parameter; messages with an unexpected "id" are ignored to prevent errors from multiple concurrent auth runs
|
||||
|
||||
|
||||
// comparison to OTR:
|
||||
// - encryption: yes
|
||||
// - authentication: yes
|
||||
// - deniability: no (attacker requires the temporary session key to prove you
|
||||
// have sent a specific message, the private key itself does not suffice), no
|
||||
// measures are taken to provide forgeability to even provide deniability
|
||||
// against an attacker who knows the temporary session key, as using CTR mode
|
||||
// for the encryption - which, together with deriving the MAC key from the
|
||||
// encryption key, and MACing the ciphertexts instead of the plaintexts,
|
||||
// would provide forgeability and thus deniability - requires longer
|
||||
// encrypted packets and deniability was not a goal of this, as we may e.g.
|
||||
// reserve the right to capture packet dumps + extra state info to prove a
|
||||
// client/server has sent specific packets to prove cheating)
|
||||
// - perfect forward secrecy: yes (session key is derived via DH key exchange)
|
||||
|
||||
#endif
|
1252
app/jni/csprogs.c
Normal file
1252
app/jni/csprogs.c
Normal file
File diff suppressed because it is too large
Load diff
121
app/jni/csprogs.h
Normal file
121
app/jni/csprogs.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
#ifndef CSPROGS_H
|
||||
#define CSPROGS_H
|
||||
|
||||
// LordHavoc: changed to match MAX_EDICTS
|
||||
#define CL_MAX_EDICTS MAX_EDICTS
|
||||
|
||||
#define ENTMASK_ENGINE 1
|
||||
#define ENTMASK_ENGINEVIEWMODELS 2
|
||||
#define ENTMASK_NORMAL 4
|
||||
|
||||
#define VF_MIN 1 //(vector)
|
||||
#define VF_MIN_X 2 //(float)
|
||||
#define VF_MIN_Y 3 //(float)
|
||||
#define VF_SIZE 4 //(vector) (viewport size)
|
||||
#define VF_SIZE_X 5 //(float)
|
||||
#define VF_SIZE_Y 6 //(float)
|
||||
#define VF_VIEWPORT 7 //(vector, vector)
|
||||
#define VF_FOV 8 //(vector)
|
||||
#define VF_FOVX 9 //(float)
|
||||
#define VF_FOVY 10 //(float)
|
||||
#define VF_ORIGIN 11 //(vector)
|
||||
#define VF_ORIGIN_X 12 //(float)
|
||||
#define VF_ORIGIN_Y 13 //(float)
|
||||
#define VF_ORIGIN_Z 14 //(float)
|
||||
#define VF_ANGLES 15 //(vector)
|
||||
#define VF_ANGLES_X 16 //(float)
|
||||
#define VF_ANGLES_Y 17 //(float)
|
||||
#define VF_ANGLES_Z 18 //(float)
|
||||
|
||||
#define VF_DRAWWORLD 19 //(float) //actually world model and sky
|
||||
#define VF_DRAWENGINESBAR 20 //(float)
|
||||
#define VF_DRAWCROSSHAIR 21 //(float)
|
||||
|
||||
#define VF_CL_VIEWANGLES 33 //(vector) //sweet thing for RPGs/...
|
||||
#define VF_CL_VIEWANGLES_X 34 //(float)
|
||||
#define VF_CL_VIEWANGLES_Y 35 //(float)
|
||||
#define VF_CL_VIEWANGLES_Z 36 //(float)
|
||||
|
||||
// FTEQW's extension range
|
||||
#define VF_PERSPECTIVE 200 //(float)
|
||||
|
||||
// what is this doing here? This is a DP extension introduced by Black, should be in 4xx range
|
||||
#define VF_CLEARSCREEN 201 //(float)
|
||||
|
||||
// what is this doing here? This is a DP extension introduced by VorteX, should be in 4xx range
|
||||
#define VF_FOG_DENSITY 202 //(float)
|
||||
#define VF_FOG_COLOR 203 //(vector)
|
||||
#define VF_FOG_COLOR_R 204 //(float)
|
||||
#define VF_FOG_COLOR_G 205 //(float)
|
||||
#define VF_FOG_COLOR_B 206 //(float)
|
||||
#define VF_FOG_ALPHA 207 //(float)
|
||||
#define VF_FOG_START 208 //(float)
|
||||
#define VF_FOG_END 209 //(float)
|
||||
#define VF_FOG_HEIGHT 210 //(float)
|
||||
#define VF_FOG_FADEDEPTH 211 //(float)
|
||||
|
||||
// DP's extension range
|
||||
#define VF_MAINVIEW 400 //(float)
|
||||
#define VF_MINFPS_QUALITY 401 //(float)
|
||||
|
||||
#define RF_VIEWMODEL 1 // The entity is never drawn in mirrors. In engines with realtime lighting, it casts no shadows.
|
||||
#define RF_EXTERNALMODEL 2 // The entity is appears in mirrors but not in the normal view. It does still cast shadows in engines with realtime lighting.
|
||||
#define RF_DEPTHHACK 4 // The entity appears closer to the view than normal, either by scaling it wierdly or by just using a depthrange. This will usually be found in conjunction with RF_VIEWMODEL
|
||||
#define RF_ADDITIVE 8 // Add the entity acording to it's alpha values instead of the normal blend
|
||||
#define RF_USEAXIS 16 // When set, the entity will use the v_forward, v_right and v_up globals instead of it's angles field for orientation. Angles will be ignored compleatly.
|
||||
// Note that to use this properly, you'll NEED to use the predraw function to set the globals.
|
||||
//#define RF_DOUBLESIDED 32
|
||||
#define RF_USETRANSPARENTOFFSET 64 // Allows QC to customize origin used for transparent sorting via transparent_origin global, helps to fix transparent sorting bugs on a very large entities
|
||||
#define RF_WORLDOBJECT 128 // for large outdoor entities that should not be culled
|
||||
#define RF_MODELLIGHT 4096 // CSQC-set model light
|
||||
#define RF_DYNAMICMODELLIGHT 8192 // origin-dependent model light
|
||||
|
||||
#define RF_FULLBRIGHT 256
|
||||
#define RF_NOSHADOW 512
|
||||
|
||||
extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat
|
||||
extern cvar_t csqc_progcrc;
|
||||
extern cvar_t csqc_progsize;
|
||||
|
||||
void CL_VM_PreventInformationLeaks(void);
|
||||
|
||||
qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t len, int crc, int cnt, sizebuf_t *buf, int protocol);
|
||||
|
||||
qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out);
|
||||
|
||||
qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clipplane, vec3_t visorigin);
|
||||
|
||||
void CL_VM_Init(void);
|
||||
void CL_VM_ShutDown(void);
|
||||
void CL_VM_UpdateIntermissionState(int intermission);
|
||||
void CL_VM_UpdateShowingScoresState(int showingscores);
|
||||
qboolean CL_VM_InputEvent(int eventtype, int x, int y);
|
||||
qboolean CL_VM_ConsoleCommand(const char *cmd);
|
||||
void CL_VM_UpdateDmgGlobals(int dmg_take, int dmg_save, vec3_t dmg_origin);
|
||||
void CL_VM_UpdateIntermissionState(int intermission);
|
||||
qboolean CL_VM_Event_Sound(int sound_num, float volume, int channel, float attenuation, int ent, vec3_t pos, int flags, float speed);
|
||||
qboolean CL_VM_Parse_TempEntity(void);
|
||||
void CL_VM_Parse_StuffCmd(const char *msg);
|
||||
void CL_VM_Parse_CenterPrint(const char *msg);
|
||||
int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent);
|
||||
int CL_GetTagMatrix(prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex);
|
||||
void CL_GetEntityMatrix(prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix);
|
||||
/* VMs exposing the polygon calls must call this on Init/Reset */
|
||||
void VM_Polygons_Reset(prvm_prog_t *prog);
|
||||
void QW_CL_StartUpload(unsigned char *data, int size);
|
||||
|
||||
void CSQC_UpdateNetworkTimes(double newtime, double oldtime);
|
||||
void CSQC_AddPrintText(const char *msg);
|
||||
void CSQC_ReadEntities(void);
|
||||
void CSQC_RelinkAllEntities(int drawmask);
|
||||
void CSQC_RelinkCSQCEntities(void);
|
||||
void CSQC_Predraw(prvm_edict_t *ed);
|
||||
void CSQC_Think(prvm_edict_t *ed);
|
||||
qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum);//csprogs.c
|
||||
void CSQC_R_RecalcView(void);
|
||||
|
||||
dp_model_t *CL_GetModelByIndex(int modelindex);
|
||||
|
||||
int CL_VM_GetViewEntity(void);
|
||||
|
||||
#endif
|
440
app/jni/curves.c
Normal file
440
app/jni/curves.c
Normal file
|
@ -0,0 +1,440 @@
|
|||
|
||||
/*
|
||||
this code written by Forest Hale, on 2004-10-17, and placed into public domain
|
||||
this implements Quadratic BSpline surfaces as seen in Quake3 by id Software
|
||||
|
||||
a small rant on misuse of the name 'bezier': many people seem to think that
|
||||
bezier is a generic term for splines, but it is not, it is a term for a
|
||||
specific type of bspline (4 control points, cubic bspline), bsplines are the
|
||||
generalization of the bezier spline to support dimensions other than cubic.
|
||||
|
||||
example equations for 1-5 control point bsplines being sampled as t=0...1
|
||||
1: flat (0th dimension)
|
||||
o = a
|
||||
2: linear (1st dimension)
|
||||
o = a * (1 - t) + b * t
|
||||
3: quadratic bspline (2nd dimension)
|
||||
o = a * (1 - t) * (1 - t) + 2 * b * (1 - t) * t + c * t * t
|
||||
4: cubic (bezier) bspline (3rd dimension)
|
||||
o = a * (1 - t) * (1 - t) * (1 - t) + 3 * b * (1 - t) * (1 - t) * t + 3 * c * (1 - t) * t * t + d * t * t * t
|
||||
5: quartic bspline (4th dimension)
|
||||
o = a * (1 - t) * (1 - t) * (1 - t) * (1 - t) + 4 * b * (1 - t) * (1 - t) * (1 - t) * t + 6 * c * (1 - t) * (1 - t) * t * t + 4 * d * (1 - t) * t * t * t + e * t * t * t * t
|
||||
|
||||
arbitrary dimension bspline
|
||||
double factorial(int n)
|
||||
{
|
||||
int i;
|
||||
double f;
|
||||
f = 1;
|
||||
for (i = 1;i < n;i++)
|
||||
f = f * i;
|
||||
return f;
|
||||
}
|
||||
double bsplinesample(int dimensions, double t, double *param)
|
||||
{
|
||||
double o = 0;
|
||||
for (i = 0;i < dimensions + 1;i++)
|
||||
o += param[i] * factorial(dimensions)/(factorial(i)*factorial(dimensions-i)) * pow(t, i) * pow(1 - t, dimensions - i);
|
||||
return o;
|
||||
}
|
||||
*/
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "curves.h"
|
||||
|
||||
// Calculate number of resulting vertex rows/columns by given patch size and tesselation factor
|
||||
// tess=0 means that we reduce detalization of base 3x3 patches by removing middle row and column of vertices
|
||||
// "DimForTess" is "DIMension FOR TESSelation factor"
|
||||
// NB: tess=0 actually means that tess must be 0.5, but obviously it can't because it is of int type. (so "a*tess"-like code is replaced by "a/2" if tess=0)
|
||||
int Q3PatchDimForTess(int size, int tess)
|
||||
{
|
||||
if (tess > 0)
|
||||
return (size - 1) * tess + 1;
|
||||
else if (tess == 0)
|
||||
return (size - 1) / 2 + 1;
|
||||
else
|
||||
return 0; // Maybe warn about wrong tess here?
|
||||
}
|
||||
|
||||
// usage:
|
||||
// to expand a 5x5 patch to 21x21 vertices (4x4 tesselation), one might use this call:
|
||||
// Q3PatchSubdivideFloat(3, sizeof(float[3]), outvertices, 5, 5, sizeof(float[3]), patchvertices, 4, 4);
|
||||
void Q3PatchTesselateFloat(int numcomponents, int outputstride, float *outputvertices, int patchwidth, int patchheight, int inputstride, float *patchvertices, int tesselationwidth, int tesselationheight)
|
||||
{
|
||||
int k, l, x, y, component, outputwidth = Q3PatchDimForTess(patchwidth, tesselationwidth);
|
||||
float px, py, *v, a, b, c, *cp[3][3], temp[3][64];
|
||||
int xmax = max(1, 2*tesselationwidth);
|
||||
int ymax = max(1, 2*tesselationheight);
|
||||
|
||||
// iterate over the individual 3x3 quadratic spline surfaces one at a time
|
||||
// expanding them to fill the output array (with some overlap to ensure
|
||||
// the edges are filled)
|
||||
for (k = 0;k < patchheight-1;k += 2)
|
||||
{
|
||||
for (l = 0;l < patchwidth-1;l += 2)
|
||||
{
|
||||
// set up control point pointers for quicker lookup later
|
||||
for (y = 0;y < 3;y++)
|
||||
for (x = 0;x < 3;x++)
|
||||
cp[y][x] = (float *)((unsigned char *)patchvertices + ((k+y)*patchwidth+(l+x)) * inputstride);
|
||||
// for each row...
|
||||
for (y = 0;y <= ymax;y++)
|
||||
{
|
||||
// calculate control points for this row by collapsing the 3
|
||||
// rows of control points to one row using py
|
||||
py = (float)y / (float)ymax;
|
||||
// calculate quadratic spline weights for py
|
||||
a = ((1.0f - py) * (1.0f - py));
|
||||
b = ((1.0f - py) * (2.0f * py));
|
||||
c = (( py) * ( py));
|
||||
for (component = 0;component < numcomponents;component++)
|
||||
{
|
||||
temp[0][component] = cp[0][0][component] * a + cp[1][0][component] * b + cp[2][0][component] * c;
|
||||
temp[1][component] = cp[0][1][component] * a + cp[1][1][component] * b + cp[2][1][component] * c;
|
||||
temp[2][component] = cp[0][2][component] * a + cp[1][2][component] * b + cp[2][2][component] * c;
|
||||
}
|
||||
// fetch a pointer to the beginning of the output vertex row
|
||||
v = (float *)((unsigned char *)outputvertices + ((k * ymax / 2 + y) * outputwidth + l * xmax / 2) * outputstride);
|
||||
// for each column of the row...
|
||||
for (x = 0;x <= xmax;x++)
|
||||
{
|
||||
// calculate point based on the row control points
|
||||
px = (float)x / (float)xmax;
|
||||
// calculate quadratic spline weights for px
|
||||
// (could be precalculated)
|
||||
a = ((1.0f - px) * (1.0f - px));
|
||||
b = ((1.0f - px) * (2.0f * px));
|
||||
c = (( px) * ( px));
|
||||
for (component = 0;component < numcomponents;component++)
|
||||
v[component] = temp[0][component] * a + temp[1][component] * b + temp[2][component] * c;
|
||||
// advance to next output vertex using outputstride
|
||||
// (the next vertex may not be directly following this
|
||||
// one, as this may be part of a larger structure)
|
||||
v = (float *)((unsigned char *)v + outputstride);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// enable this if you want results printed out
|
||||
printf("vertices[%i][%i] =\n{\n", (patchheight-1)*tesselationheight+1, (patchwidth-1)*tesselationwidth+1);
|
||||
for (y = 0;y < (patchheight-1)*tesselationheight+1;y++)
|
||||
{
|
||||
for (x = 0;x < (patchwidth-1)*tesselationwidth+1;x++)
|
||||
{
|
||||
printf("(");
|
||||
for (component = 0;component < numcomponents;component++)
|
||||
printf("%f ", outputvertices[(y*((patchwidth-1)*tesselationwidth+1)+x)*numcomponents+component]);
|
||||
printf(") ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("}\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int Q3PatchTesselation(float largestsquared3xcurvearea, float tolerance)
|
||||
{
|
||||
float f;
|
||||
// f is actually a squared 2x curve area... so the formula had to be adjusted to give roughly the same subdivisions
|
||||
f = pow(largestsquared3xcurvearea / 64.0f, 0.25f) / tolerance;
|
||||
//if(f < 0.25) // VERY flat patches
|
||||
if(f < 0.0001) // TOTALLY flat patches
|
||||
return 0;
|
||||
else if(f < 2)
|
||||
return 1;
|
||||
else
|
||||
return (int) floor(log(f) / log(2.0f)) + 1;
|
||||
// this is always at least 2
|
||||
// maps [0.25..0.5[ to -1 (actually, 1 is returned)
|
||||
// maps [0.5..1[ to 0 (actually, 1 is returned)
|
||||
// maps [1..2[ to 1
|
||||
// maps [2..4[ to 2
|
||||
// maps [4..8[ to 4
|
||||
}
|
||||
|
||||
static float Squared3xCurveArea(const float *a, const float *control, const float *b, int components)
|
||||
{
|
||||
#if 0
|
||||
// mimicing the old behaviour with the new code...
|
||||
|
||||
float deviation;
|
||||
float quartercurvearea = 0;
|
||||
int c;
|
||||
for (c = 0;c < components;c++)
|
||||
{
|
||||
deviation = control[c] * 0.5f - a[c] * 0.25f - b[c] * 0.25f;
|
||||
quartercurvearea += deviation*deviation;
|
||||
}
|
||||
|
||||
// But as the new code now works on the squared 2x curve area, let's scale the value
|
||||
return quartercurvearea * quartercurvearea * 64.0;
|
||||
|
||||
#else
|
||||
// ideally, we'd like the area between the spline a->control->b and the line a->b.
|
||||
// but as this is hard to calculate, let's calculate an upper bound of it:
|
||||
// the area of the triangle a->control->b->a.
|
||||
//
|
||||
// one can prove that the area of a quadratic spline = 2/3 * the area of
|
||||
// the triangle of its control points!
|
||||
// to do it, first prove it for the spline through (0,0), (1,1), (2,0)
|
||||
// (which is a parabola) and then note that moving the control point
|
||||
// left/right is just shearing and keeps the area of both the spline and
|
||||
// the triangle invariant.
|
||||
//
|
||||
// why are we going for the spline area anyway?
|
||||
// we know that:
|
||||
//
|
||||
// the area between the spline and the line a->b is a measure of the
|
||||
// error of approximation of the spline by the line.
|
||||
//
|
||||
// also, on circle-like or parabola-like curves, you easily get that the
|
||||
// double amount of line approximation segments reduces the error to its quarter
|
||||
// (also, easy to prove for splines by doing it for one specific one, and using
|
||||
// affine transforms to get all other splines)
|
||||
//
|
||||
// so...
|
||||
//
|
||||
// let's calculate the area! but we have to avoid the cross product, as
|
||||
// components is not necessarily 3
|
||||
//
|
||||
// the area of a triangle spanned by vectors a and b is
|
||||
//
|
||||
// 0.5 * |a| |b| sin gamma
|
||||
//
|
||||
// now, cos gamma is
|
||||
//
|
||||
// a.b / (|a| |b|)
|
||||
//
|
||||
// so the area is
|
||||
//
|
||||
// 0.5 * sqrt(|a|^2 |b|^2 - (a.b)^2)
|
||||
int c;
|
||||
float aa = 0, bb = 0, ab = 0;
|
||||
for (c = 0;c < components;c++)
|
||||
{
|
||||
float xa = a[c] - control[c];
|
||||
float xb = b[c] - control[c];
|
||||
aa += xa * xa;
|
||||
ab += xa * xb;
|
||||
bb += xb * xb;
|
||||
}
|
||||
// area is 0.5 * sqrt(aa*bb - ab*ab)
|
||||
// 2x TRIANGLE area is sqrt(aa*bb - ab*ab)
|
||||
// 3x CURVE area is sqrt(aa*bb - ab*ab)
|
||||
return aa * bb - ab * ab;
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns how much tesselation of each segment is needed to remain under tolerance
|
||||
int Q3PatchTesselationOnX(int patchwidth, int patchheight, int components, const float *in, float tolerance)
|
||||
{
|
||||
int x, y;
|
||||
const float *patch;
|
||||
float squared3xcurvearea, largestsquared3xcurvearea;
|
||||
largestsquared3xcurvearea = 0;
|
||||
for (y = 0;y < patchheight;y++)
|
||||
{
|
||||
for (x = 0;x < patchwidth-1;x += 2)
|
||||
{
|
||||
patch = in + ((y * patchwidth) + x) * components;
|
||||
squared3xcurvearea = Squared3xCurveArea(&patch[0], &patch[components], &patch[2*components], components);
|
||||
if (largestsquared3xcurvearea < squared3xcurvearea)
|
||||
largestsquared3xcurvearea = squared3xcurvearea;
|
||||
}
|
||||
}
|
||||
return Q3PatchTesselation(largestsquared3xcurvearea, tolerance);
|
||||
}
|
||||
|
||||
// returns how much tesselation of each segment is needed to remain under tolerance
|
||||
int Q3PatchTesselationOnY(int patchwidth, int patchheight, int components, const float *in, float tolerance)
|
||||
{
|
||||
int x, y;
|
||||
const float *patch;
|
||||
float squared3xcurvearea, largestsquared3xcurvearea;
|
||||
largestsquared3xcurvearea = 0;
|
||||
for (y = 0;y < patchheight-1;y += 2)
|
||||
{
|
||||
for (x = 0;x < patchwidth;x++)
|
||||
{
|
||||
patch = in + ((y * patchwidth) + x) * components;
|
||||
squared3xcurvearea = Squared3xCurveArea(&patch[0], &patch[patchwidth*components], &patch[2*patchwidth*components], components);
|
||||
if (largestsquared3xcurvearea < squared3xcurvearea)
|
||||
largestsquared3xcurvearea = squared3xcurvearea;
|
||||
}
|
||||
}
|
||||
return Q3PatchTesselation(largestsquared3xcurvearea, tolerance);
|
||||
}
|
||||
|
||||
// Find an equal vertex in array. Check only vertices with odd X and Y
|
||||
static int FindEqualOddVertexInArray(int numcomponents, float *vertex, float *vertices, int width, int height)
|
||||
{
|
||||
int x, y, j;
|
||||
for (y=0; y<height; y+=2)
|
||||
{
|
||||
for (x=0; x<width; x+=2)
|
||||
{
|
||||
qboolean found = true;
|
||||
for (j=0; j<numcomponents; j++)
|
||||
if (fabs(*(vertex+j) - *(vertices+j)) > 0.05)
|
||||
// div0: this is notably smaller than the smallest radiant grid
|
||||
// but large enough so we don't need to get scared of roundoff
|
||||
// errors
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
return y*width+x;
|
||||
vertices += numcomponents*2;
|
||||
}
|
||||
vertices += numcomponents*(width-1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define SIDE_INVALID -1
|
||||
#define SIDE_X 0
|
||||
#define SIDE_Y 1
|
||||
|
||||
static int GetSide(int p1, int p2, int width, int height, int *pointdist)
|
||||
{
|
||||
int x1 = p1 % width, y1 = p1 / width;
|
||||
int x2 = p2 % width, y2 = p2 / width;
|
||||
if (p1 < 0 || p2 < 0)
|
||||
return SIDE_INVALID;
|
||||
if (x1 == x2)
|
||||
{
|
||||
if (y1 != y2)
|
||||
{
|
||||
*pointdist = abs(y2 - y1);
|
||||
return SIDE_Y;
|
||||
}
|
||||
else
|
||||
return SIDE_INVALID;
|
||||
}
|
||||
else if (y1 == y2)
|
||||
{
|
||||
*pointdist = abs(x2 - x1);
|
||||
return SIDE_X;
|
||||
}
|
||||
else
|
||||
return SIDE_INVALID;
|
||||
}
|
||||
|
||||
// Increase tesselation of one of two touching patches to make a seamless connection between them
|
||||
// Returns 0 in case if patches were not modified, otherwise 1
|
||||
int Q3PatchAdjustTesselation(int numcomponents, patchinfo_t *patch1, float *patchvertices1, patchinfo_t *patch2, float *patchvertices2)
|
||||
{
|
||||
// what we are doing here is:
|
||||
// we take for each corner of one patch
|
||||
// and check if the other patch contains that corner
|
||||
// once we have a pair of such matches
|
||||
|
||||
struct {int id1,id2;} commonverts[8];
|
||||
int i, j, k, side1, side2, *tess1, *tess2;
|
||||
int dist1 = 0, dist2 = 0;
|
||||
qboolean modified = false;
|
||||
|
||||
// Potential paired vertices (corners of the first patch)
|
||||
commonverts[0].id1 = 0;
|
||||
commonverts[1].id1 = patch1->xsize-1;
|
||||
commonverts[2].id1 = patch1->xsize*(patch1->ysize-1);
|
||||
commonverts[3].id1 = patch1->xsize*patch1->ysize-1;
|
||||
for (i=0;i<4;++i)
|
||||
commonverts[i].id2 = FindEqualOddVertexInArray(numcomponents, patchvertices1+numcomponents*commonverts[i].id1, patchvertices2, patch2->xsize, patch2->ysize);
|
||||
|
||||
// Corners of the second patch
|
||||
commonverts[4].id2 = 0;
|
||||
commonverts[5].id2 = patch2->xsize-1;
|
||||
commonverts[6].id2 = patch2->xsize*(patch2->ysize-1);
|
||||
commonverts[7].id2 = patch2->xsize*patch2->ysize-1;
|
||||
for (i=4;i<8;++i)
|
||||
commonverts[i].id1 = FindEqualOddVertexInArray(numcomponents, patchvertices2+numcomponents*commonverts[i].id2, patchvertices1, patch1->xsize, patch1->ysize);
|
||||
|
||||
for (i=0;i<8;++i)
|
||||
for (j=i+1;j<8;++j)
|
||||
{
|
||||
side1 = GetSide(commonverts[i].id1,commonverts[j].id1,patch1->xsize,patch1->ysize,&dist1);
|
||||
side2 = GetSide(commonverts[i].id2,commonverts[j].id2,patch2->xsize,patch2->ysize,&dist2);
|
||||
|
||||
if (side1 == SIDE_INVALID || side2 == SIDE_INVALID)
|
||||
continue;
|
||||
|
||||
if(dist1 != dist2)
|
||||
{
|
||||
// no patch welding if the resolutions mismatch
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update every lod level
|
||||
for (k=0;k<PATCH_LODS_NUM;++k)
|
||||
{
|
||||
tess1 = side1 == SIDE_X ? &patch1->lods[k].xtess : &patch1->lods[k].ytess;
|
||||
tess2 = side2 == SIDE_X ? &patch2->lods[k].xtess : &patch2->lods[k].ytess;
|
||||
if (*tess1 != *tess2)
|
||||
{
|
||||
if (*tess1 < *tess2)
|
||||
*tess1 = *tess2;
|
||||
else
|
||||
*tess2 = *tess1;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
#undef SIDE_INVALID
|
||||
#undef SIDE_X
|
||||
#undef SIDE_Y
|
||||
|
||||
// calculates elements for a grid of vertices
|
||||
// (such as those produced by Q3PatchTesselate)
|
||||
// (note: width and height are the actual vertex size, this produces
|
||||
// (width-1)*(height-1)*2 triangles, 3 elements each)
|
||||
void Q3PatchTriangleElements(int *elements, int width, int height, int firstvertex)
|
||||
{
|
||||
int x, y, row0, row1;
|
||||
for (y = 0;y < height - 1;y++)
|
||||
{
|
||||
if(y % 2)
|
||||
{
|
||||
// swap the triangle order in odd rows as optimization for collision stride
|
||||
row0 = firstvertex + (y + 0) * width + width - 2;
|
||||
row1 = firstvertex + (y + 1) * width + width - 2;
|
||||
for (x = 0;x < width - 1;x++)
|
||||
{
|
||||
*elements++ = row1;
|
||||
*elements++ = row1 + 1;
|
||||
*elements++ = row0 + 1;
|
||||
*elements++ = row0;
|
||||
*elements++ = row1;
|
||||
*elements++ = row0 + 1;
|
||||
row0--;
|
||||
row1--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
row0 = firstvertex + (y + 0) * width;
|
||||
row1 = firstvertex + (y + 1) * width;
|
||||
for (x = 0;x < width - 1;x++)
|
||||
{
|
||||
*elements++ = row0;
|
||||
*elements++ = row1;
|
||||
*elements++ = row0 + 1;
|
||||
*elements++ = row1;
|
||||
*elements++ = row1 + 1;
|
||||
*elements++ = row0 + 1;
|
||||
row0++;
|
||||
row1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
39
app/jni/curves.h
Normal file
39
app/jni/curves.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#ifndef CURVES_H
|
||||
#define CURVES_H
|
||||
|
||||
#define PATCH_LODS_NUM 2
|
||||
#define PATCH_LOD_COLLISION 0
|
||||
#define PATCH_LOD_VISUAL 1
|
||||
|
||||
typedef struct patchinfo_s
|
||||
{
|
||||
int xsize, ysize;
|
||||
struct {
|
||||
int xtess, ytess;
|
||||
} lods[PATCH_LODS_NUM];
|
||||
} patchinfo_t;
|
||||
|
||||
// Calculate number of resulting vertex rows/columns by given patch size and tesselation factor
|
||||
// When tess=0 it means that we reduce detalization of base 3x3 patches by removing middle row and column
|
||||
// "DimForTess" is "DIMension FOR TESSelation factor"
|
||||
int Q3PatchDimForTess(int size, int tess);
|
||||
|
||||
// usage:
|
||||
// to expand a 5x5 patch to 21x21 vertices (4x4 tesselation), one might use this call:
|
||||
// Q3PatchSubdivideFloat(3, sizeof(float[3]), outvertices, 5, 5, sizeof(float[3]), patchvertices, 4, 4);
|
||||
void Q3PatchTesselateFloat(int numcomponents, int outputstride, float *outputvertices, int patchwidth, int patchheight, int inputstride, float *patchvertices, int tesselationwidth, int tesselationheight);
|
||||
// returns how much tesselation of each segment is needed to remain under tolerance
|
||||
int Q3PatchTesselationOnX(int patchwidth, int patchheight, int components, const float *in, float tolerance);
|
||||
// returns how much tesselation of each segment is needed to remain under tolerance
|
||||
int Q3PatchTesselationOnY(int patchwidth, int patchheight, int components, const float *in, float tolerance);
|
||||
// calculates elements for a grid of vertices
|
||||
// (such as those produced by Q3PatchTesselate)
|
||||
// (note: width and height are the actual vertex size, this produces
|
||||
// (width-1)*(height-1)*2 triangles, 3 elements each)
|
||||
void Q3PatchTriangleElements(int *elements, int width, int height, int firstvertex);
|
||||
|
||||
int Q3PatchAdjustTesselation(int numcomponents, patchinfo_t *patch1, float *patchvertices1, patchinfo_t *patch2, float *patchvertices2);
|
||||
|
||||
#endif
|
||||
|
1027
app/jni/cvar.c
Normal file
1027
app/jni/cvar.c
Normal file
File diff suppressed because it is too large
Load diff
245
app/jni/cvar.h
Normal file
245
app/jni/cvar.h
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.
|
||||
|
||||
*/
|
||||
// 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");
|
||||
cvar_set ("registered", "1");
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef CVAR_H
|
||||
#define CVAR_H
|
||||
|
||||
// cvar flags
|
||||
|
||||
#define CVAR_SAVE 1
|
||||
#define CVAR_NOTIFY 2
|
||||
#define CVAR_READONLY 4
|
||||
#define CVAR_SERVERINFO 8
|
||||
#define CVAR_USERINFO 16
|
||||
// CVAR_PRIVATE means do not $ expand or sendcvar this cvar under any circumstances (rcon_password uses this)
|
||||
#define CVAR_PRIVATE 32
|
||||
// this means that this cvar should update a userinfo key but the name does not correspond directly to the userinfo key to update, and may require additional conversion ("_cl_color" for example should update "topcolor" and "bottomcolor")
|
||||
#define CVAR_NQUSERINFOHACK 64
|
||||
// used to determine if flags is valid
|
||||
#define CVAR_NORESETTODEFAULTS 128
|
||||
// for engine-owned cvars that must not be reset on gametype switch (e.g. scr_screenshot_name, which otherwise isn't set to the mod name properly)
|
||||
#define CVAR_MAXFLAGSVAL 255
|
||||
// for internal use only!
|
||||
#define CVAR_DEFAULTSET (1<<30)
|
||||
#define CVAR_ALLOCATED (1<<31)
|
||||
|
||||
/*
|
||||
// type of a cvar for menu purposes
|
||||
#define CVARMENUTYPE_FLOAT 1
|
||||
#define CVARMENUTYPE_INTEGER 2
|
||||
#define CVARMENUTYPE_SLIDER 3
|
||||
#define CVARMENUTYPE_BOOL 4
|
||||
#define CVARMENUTYPE_STRING 5
|
||||
#define CVARMENUTYPE_OPTION 6
|
||||
|
||||
// which menu to put a cvar in
|
||||
#define CVARMENU_GRAPHICS 1
|
||||
#define CVARMENU_SOUND 2
|
||||
#define CVARMENU_INPUT 3
|
||||
#define CVARMENU_NETWORK 4
|
||||
#define CVARMENU_SERVER 5
|
||||
|
||||
#define MAX_CVAROPTIONS 16
|
||||
|
||||
typedef struct cvaroption_s
|
||||
{
|
||||
int value;
|
||||
const char *name;
|
||||
}
|
||||
cvaroption_t;
|
||||
|
||||
typedef struct menucvar_s
|
||||
{
|
||||
int type;
|
||||
float valuemin, valuemax, valuestep;
|
||||
int numoptions;
|
||||
cvaroption_t optionlist[MAX_CVAROPTIONS];
|
||||
}
|
||||
menucvar_t;
|
||||
*/
|
||||
|
||||
typedef struct cvar_s
|
||||
{
|
||||
int flags;
|
||||
|
||||
const char *name;
|
||||
|
||||
const char *string;
|
||||
const char *description;
|
||||
int integer;
|
||||
float value;
|
||||
float vector[3];
|
||||
|
||||
const char *defstring;
|
||||
|
||||
// values at init (for Cvar_RestoreInitState)
|
||||
qboolean initstate; // indicates this existed at init
|
||||
int initflags;
|
||||
const char *initstring;
|
||||
const char *initdescription;
|
||||
int initinteger;
|
||||
float initvalue;
|
||||
float initvector[3];
|
||||
const char *initdefstring;
|
||||
|
||||
unsigned int globaldefindex_progid[3];
|
||||
int globaldefindex[3];
|
||||
int globaldefindex_stringno[3];
|
||||
|
||||
//menucvar_t menuinfo;
|
||||
struct cvar_s *next;
|
||||
struct cvar_s *nextonhashchain;
|
||||
} cvar_t;
|
||||
|
||||
/*
|
||||
void Cvar_MenuSlider(cvar_t *variable, int menu, float slider_min, float slider_max, float slider_step);
|
||||
void Cvar_MenuBool(cvar_t *variable, int menu, const char *name_false, const char *name_true);
|
||||
void Cvar_MenuFloat(cvar_t *variable, int menu, float range_min, float range_max);
|
||||
void Cvar_MenuInteger(cvar_t *variable, int menu, int range_min, int range_max);
|
||||
void Cvar_MenuString(cvar_t *variable, int menu);
|
||||
void Cvar_MenuOption(cvar_t *variable, int menu, int value[16], const char *name[16]);
|
||||
*/
|
||||
|
||||
/// registers a cvar that already has the name, string, and optionally the
|
||||
/// archive elements set.
|
||||
void Cvar_RegisterVariable (cvar_t *variable);
|
||||
|
||||
/// equivelant to "<name> <variable>" typed at the console
|
||||
void Cvar_Set (const char *var_name, const char *value);
|
||||
|
||||
/// expands value to a string and calls Cvar_Set
|
||||
void Cvar_SetValue (const char *var_name, float value);
|
||||
|
||||
void Cvar_SetQuick (cvar_t *var, const char *value);
|
||||
void Cvar_SetValueQuick (cvar_t *var, float value);
|
||||
|
||||
float Cvar_VariableValueOr (const char *var_name, float def);
|
||||
// returns def if not defined
|
||||
|
||||
float Cvar_VariableValue (const char *var_name);
|
||||
// returns 0 if not defined or non numeric
|
||||
|
||||
const char *Cvar_VariableStringOr (const char *var_name, const char *def);
|
||||
// returns def if not defined
|
||||
|
||||
const char *Cvar_VariableString (const char *var_name);
|
||||
// returns an empty string if not defined
|
||||
|
||||
const char *Cvar_VariableDefString (const char *var_name);
|
||||
// returns an empty string if not defined
|
||||
|
||||
const char *Cvar_VariableDescription (const char *var_name);
|
||||
// returns an empty string if not defined
|
||||
|
||||
const char *Cvar_CompleteVariable (const char *partial);
|
||||
// attempts to match a partial variable name for command line completion
|
||||
// returns NULL if nothing fits
|
||||
|
||||
void Cvar_CompleteCvarPrint (const char *partial);
|
||||
|
||||
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_SaveInitState(void);
|
||||
void Cvar_RestoreInitState(void);
|
||||
|
||||
void Cvar_UnlockDefaults (void);
|
||||
void Cvar_LockDefaults_f (void);
|
||||
void Cvar_ResetToDefaults_All_f (void);
|
||||
void Cvar_ResetToDefaults_NoSaveOnly_f (void);
|
||||
void Cvar_ResetToDefaults_SaveOnly_f (void);
|
||||
|
||||
void Cvar_WriteVariables (qfile_t *f);
|
||||
// Writes lines containing "set variable value" for all variables
|
||||
// with the archive flag set to true.
|
||||
|
||||
cvar_t *Cvar_FindVar (const char *var_name);
|
||||
cvar_t *Cvar_FindVarAfter (const char *prev_var_name, int neededflags);
|
||||
|
||||
int Cvar_CompleteCountPossible (const char *partial);
|
||||
const char **Cvar_CompleteBuildList (const char *partial);
|
||||
// Added by EvilTypeGuy - functions for tab completion system
|
||||
// Thanks to Fett erich@heintz.com
|
||||
// Thanks to taniwha
|
||||
|
||||
/// Prints a list of Cvars including a count of them to the user console
|
||||
/// Referenced in cmd.c in Cmd_Init hence it's inclusion here.
|
||||
/// Added by EvilTypeGuy eviltypeguy@qeradiant.com
|
||||
/// Thanks to Matthias "Maddes" Buecher, http://www.inside3d.com/qip/
|
||||
void Cvar_List_f (void);
|
||||
|
||||
void Cvar_Set_f (void);
|
||||
void Cvar_SetA_f (void);
|
||||
void Cvar_Del_f (void);
|
||||
// commands to create new cvars (or set existing ones)
|
||||
// seta creates an archived cvar (saved to config)
|
||||
|
||||
/// allocates a cvar by name and returns its address,
|
||||
/// or merely sets its value if it already exists.
|
||||
cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *newdescription);
|
||||
|
||||
extern const char *cvar_dummy_description; // ALWAYS the same pointer
|
||||
extern cvar_t *cvar_vars; // used to list all cvars
|
||||
|
||||
void Cvar_UpdateAllAutoCvars(void); // updates ALL autocvars of the active prog to the cvar values (savegame loading)
|
||||
|
||||
#ifdef FILLALLCVARSWITHRUBBISH
|
||||
void Cvar_FillAll_f();
|
||||
#endif /* FILLALLCVARSWITHRUBBISH */
|
||||
|
||||
#endif
|
||||
|
5690
app/jni/dpsoftrast.c
Normal file
5690
app/jni/dpsoftrast.c
Normal file
File diff suppressed because it is too large
Load diff
327
app/jni/dpsoftrast.h
Normal file
327
app/jni/dpsoftrast.h
Normal file
|
@ -0,0 +1,327 @@
|
|||
|
||||
#ifndef DPSOFTRAST_H
|
||||
#define DPSOFTRAST_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DPSOFTRAST_MAXMIPMAPS 16
|
||||
#define DPSOFTRAST_TEXTURE_MAXSIZE (1<<(DPSOFTRAST_MAXMIPMAPS - 1))
|
||||
#define DPSOFTRAST_MAXTEXTUREUNITS 16
|
||||
#define DPSOFTRAST_MAXTEXCOORDARRAYS 8
|
||||
|
||||
// type of pixels in texture (some of these are converted to BGRA8 on update)
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_BGRA8 0
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_DEPTH 1
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_RGBA8 2
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_ALPHA8 3
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_RGBA16F 4
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_RGBA32F 5
|
||||
#define DPSOFTRAST_TEXTURE_FORMAT_COMPAREMASK 0x0F
|
||||
|
||||
// modifier flags for texture (can not be changed after creation)
|
||||
#define DPSOFTRAST_TEXTURE_FLAG_MIPMAP 0x10
|
||||
#define DPSOFTRAST_TEXTURE_FLAG_CUBEMAP 0x20
|
||||
#define DPSOFTRAST_TEXTURE_FLAG_USEALPHA 0x40
|
||||
#define DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE 0x80
|
||||
|
||||
typedef enum DPSOFTRAST_TEXTURE_FILTER_e
|
||||
{
|
||||
DPSOFTRAST_TEXTURE_FILTER_NEAREST = 0,
|
||||
DPSOFTRAST_TEXTURE_FILTER_LINEAR = 1,
|
||||
DPSOFTRAST_TEXTURE_FILTER_NEAREST_MIPMAP_TRIANGLE = 2,
|
||||
DPSOFTRAST_TEXTURE_FILTER_LINEAR_MIPMAP_TRIANGLE = 3,
|
||||
}
|
||||
DPSOFTRAST_TEXTURE_FILTER;
|
||||
|
||||
int DPSOFTRAST_Init(int width, int height, int numthreads, int interlace, unsigned int *colorpixels, unsigned int *depthpixels);
|
||||
void DPSOFTRAST_Shutdown(void);
|
||||
void DPSOFTRAST_Flush(void);
|
||||
void DPSOFTRAST_Finish(void);
|
||||
|
||||
int DPSOFTRAST_Texture_New(int flags, int width, int height, int depth);
|
||||
void DPSOFTRAST_Texture_Free(int index);
|
||||
void DPSOFTRAST_Texture_UpdatePartial(int index, int mip, const unsigned char *pixels, int blockx, int blocky, int blockwidth, int blockheight);
|
||||
void DPSOFTRAST_Texture_UpdateFull(int index, const unsigned char *pixels);
|
||||
int DPSOFTRAST_Texture_GetWidth(int index, int mip);
|
||||
int DPSOFTRAST_Texture_GetHeight(int index, int mip);
|
||||
int DPSOFTRAST_Texture_GetDepth(int index, int mip);
|
||||
unsigned char *DPSOFTRAST_Texture_GetPixelPointer(int index, int mip);
|
||||
void DPSOFTRAST_Texture_Filter(int index, DPSOFTRAST_TEXTURE_FILTER filter);
|
||||
|
||||
void DPSOFTRAST_SetRenderTargets(int width, int height, unsigned int *depthpixels, unsigned int *colorpixels0, unsigned int *colorpixels1, unsigned int *colorpixels2, unsigned int *colorpixels3);
|
||||
void DPSOFTRAST_Viewport(int x, int y, int width, int height);
|
||||
void DPSOFTRAST_ClearColor(float r, float g, float b, float a);
|
||||
void DPSOFTRAST_ClearDepth(float d);
|
||||
void DPSOFTRAST_ColorMask(int r, int g, int b, int a);
|
||||
void DPSOFTRAST_DepthTest(int enable);
|
||||
void DPSOFTRAST_ScissorTest(int enable);
|
||||
void DPSOFTRAST_Scissor(float x, float y, float width, float height);
|
||||
void DPSOFTRAST_ClipPlane(float x, float y, float z, float w);
|
||||
|
||||
void DPSOFTRAST_BlendFunc(int smodulate, int dmodulate);
|
||||
void DPSOFTRAST_BlendSubtract(int enable);
|
||||
void DPSOFTRAST_DepthMask(int enable);
|
||||
void DPSOFTRAST_DepthFunc(int comparemode);
|
||||
void DPSOFTRAST_DepthRange(float range0, float range1);
|
||||
void DPSOFTRAST_PolygonOffset(float alongnormal, float intoview);
|
||||
void DPSOFTRAST_CullFace(int mode);
|
||||
void DPSOFTRAST_Color4f(float r, float g, float b, float a);
|
||||
void DPSOFTRAST_GetPixelsBGRA(int blockx, int blocky, int blockwidth, int blockheight, unsigned char *outpixels);
|
||||
void DPSOFTRAST_CopyRectangleToTexture(int index, int mip, int tx, int ty, int sx, int sy, int width, int height);
|
||||
void DPSOFTRAST_SetTexture(int unitnum, int index);
|
||||
|
||||
void DPSOFTRAST_SetVertexPointer(const float *vertex3f, size_t stride);
|
||||
void DPSOFTRAST_SetColorPointer(const float *color4f, size_t stride);
|
||||
void DPSOFTRAST_SetColorPointer4ub(const unsigned char *color4ub, size_t stride);
|
||||
void DPSOFTRAST_SetTexCoordPointer(int unitnum, int numcomponents, size_t stride, const float *texcoordf);
|
||||
|
||||
typedef enum gl20_texunit_e
|
||||
{
|
||||
// postprocess shaders, and generic shaders:
|
||||
GL20TU_FIRST = 0,
|
||||
GL20TU_SECOND = 1,
|
||||
GL20TU_GAMMARAMPS = 2,
|
||||
// standard material properties
|
||||
GL20TU_NORMAL = 0,
|
||||
GL20TU_COLOR = 1,
|
||||
GL20TU_GLOSS = 2,
|
||||
GL20TU_GLOW = 3,
|
||||
// material properties for a second material
|
||||
GL20TU_SECONDARY_NORMAL = 4,
|
||||
GL20TU_SECONDARY_COLOR = 5,
|
||||
GL20TU_SECONDARY_GLOSS = 6,
|
||||
GL20TU_SECONDARY_GLOW = 7,
|
||||
// material properties for a colormapped material
|
||||
// conflicts with secondary material
|
||||
GL20TU_PANTS = 4,
|
||||
GL20TU_SHIRT = 7,
|
||||
// fog fade in the distance
|
||||
GL20TU_FOGMASK = 8,
|
||||
// compiled ambient lightmap and deluxemap
|
||||
GL20TU_LIGHTMAP = 9,
|
||||
GL20TU_DELUXEMAP = 10,
|
||||
// refraction, used by water shaders
|
||||
GL20TU_REFRACTION = 3,
|
||||
// reflection, used by water shaders, also with normal material rendering
|
||||
// conflicts with secondary material
|
||||
GL20TU_REFLECTION = 7,
|
||||
// rtlight attenuation (distance fade) and cubemap filter (projection texturing)
|
||||
// conflicts with lightmap/deluxemap
|
||||
GL20TU_ATTENUATION = 9,
|
||||
GL20TU_CUBE = 10,
|
||||
GL20TU_SHADOWMAP2D = 15,
|
||||
GL20TU_CUBEPROJECTION = 12,
|
||||
// rtlight prepass data (screenspace depth and normalmap)
|
||||
// GL20TU_UNUSED1 = 13,
|
||||
GL20TU_SCREENNORMALMAP = 14,
|
||||
// lightmap prepass data (screenspace diffuse and specular from lights)
|
||||
GL20TU_SCREENDIFFUSE = 11,
|
||||
GL20TU_SCREENSPECULAR = 12,
|
||||
// fake reflections
|
||||
GL20TU_REFLECTMASK = 5,
|
||||
GL20TU_REFLECTCUBE = 6,
|
||||
GL20TU_FOGHEIGHTTEXTURE = 14
|
||||
}
|
||||
gl20_texunit;
|
||||
|
||||
typedef enum glsl_attrib_e
|
||||
{
|
||||
GLSLATTRIB_POSITION = 0,
|
||||
GLSLATTRIB_COLOR = 1,
|
||||
GLSLATTRIB_TEXCOORD0 = 2,
|
||||
GLSLATTRIB_TEXCOORD1 = 3,
|
||||
GLSLATTRIB_TEXCOORD2 = 4,
|
||||
GLSLATTRIB_TEXCOORD3 = 5,
|
||||
GLSLATTRIB_TEXCOORD4 = 6,
|
||||
GLSLATTRIB_TEXCOORD5 = 7,
|
||||
GLSLATTRIB_TEXCOORD6 = 8,
|
||||
GLSLATTRIB_TEXCOORD7 = 9,
|
||||
}
|
||||
glsl_attrib;
|
||||
|
||||
// this enum selects which of the glslshadermodeinfo entries should be used
|
||||
typedef enum shadermode_e
|
||||
{
|
||||
SHADERMODE_GENERIC, ///< (particles/HUD/etc) vertex color, optionally multiplied by one texture
|
||||
SHADERMODE_POSTPROCESS, ///< postprocessing shader (r_glsl_postprocess)
|
||||
SHADERMODE_DEPTH_OR_SHADOW, ///< (depthfirst/shadows) vertex shader only
|
||||
SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp)
|
||||
SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp)
|
||||
SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
|
||||
SHADERMODE_FAKELIGHT, ///< (fakelight) modulate texture by "fake" lighting (no lightmaps, no nothing)
|
||||
SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap)
|
||||
SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap)
|
||||
SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP, // forced deluxemapping for lightmapped surfaces
|
||||
SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR, // forced deluxemapping for vertexlit surfaces
|
||||
SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp)
|
||||
SHADERMODE_LIGHTSOURCE, ///< (lightsource) use directional pixel shading from light source (rtlight)
|
||||
SHADERMODE_REFRACTION, ///< refract background (the material is rendered normally after this pass)
|
||||
SHADERMODE_WATER, ///< refract background and reflection (the material is rendered normally after this pass)
|
||||
SHADERMODE_DEFERREDGEOMETRY, ///< (deferred) render material properties to screenspace geometry buffers
|
||||
SHADERMODE_DEFERREDLIGHTSOURCE, ///< (deferred) use directional pixel shading from light source (rtlight) on screenspace geometry buffers
|
||||
SHADERMODE_COUNT
|
||||
}
|
||||
shadermode_t;
|
||||
|
||||
typedef enum shaderpermutation_e
|
||||
{
|
||||
SHADERPERMUTATION_DIFFUSE = 1<<0, ///< (lightsource) whether to use directional shading
|
||||
SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, ///< indicates this is a two-layer material blend based on vertex alpha (q3bsp)
|
||||
SHADERPERMUTATION_VIEWTINT = 1<<2, ///< view tint (postprocessing only), use vertex colors (generic only)
|
||||
SHADERPERMUTATION_COLORMAPPING = 1<<3, ///< indicates this is a colormapped skin
|
||||
SHADERPERMUTATION_SATURATION = 1<<4, ///< saturation (postprocessing only)
|
||||
SHADERPERMUTATION_FOGINSIDE = 1<<5, ///< tint the color by fog color or black if using additive blend mode
|
||||
SHADERPERMUTATION_FOGOUTSIDE = 1<<6, ///< tint the color by fog color or black if using additive blend mode
|
||||
SHADERPERMUTATION_FOGHEIGHTTEXTURE = 1<<7, ///< fog color and density determined by texture mapped on vertical axis
|
||||
SHADERPERMUTATION_FOGALPHAHACK = 1<<8, ///< fog color and density determined by texture mapped on vertical axis
|
||||
SHADERPERMUTATION_GAMMARAMPS = 1<<9, ///< gamma (postprocessing only)
|
||||
SHADERPERMUTATION_CUBEFILTER = 1<<10, ///< (lightsource) use cubemap light filter
|
||||
SHADERPERMUTATION_GLOW = 1<<11, ///< (lightmap) blend in an additive glow texture
|
||||
SHADERPERMUTATION_BLOOM = 1<<12, ///< bloom (postprocessing only)
|
||||
SHADERPERMUTATION_SPECULAR = 1<<13, ///< (lightsource or deluxemapping) render specular effects
|
||||
SHADERPERMUTATION_POSTPROCESSING = 1<<14, ///< user defined postprocessing (postprocessing only)
|
||||
SHADERPERMUTATION_REFLECTION = 1<<15, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
|
||||
SHADERPERMUTATION_OFFSETMAPPING = 1<<16, ///< adjust texcoords to roughly simulate a displacement mapped surface
|
||||
SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<17, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
|
||||
SHADERPERMUTATION_SHADOWMAP2D = 1<<18, ///< (lightsource) use shadowmap texture as light filter
|
||||
SHADERPERMUTATION_SHADOWMAPVSDCT = 1<<19, ///< (lightsource) use virtual shadow depth cube texture for shadowmap indexing
|
||||
SHADERPERMUTATION_SHADOWMAPORTHO = 1<<20, ///< (lightsource) use orthographic shadowmap projection
|
||||
SHADERPERMUTATION_DEFERREDLIGHTMAP = 1<<21, ///< (lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
|
||||
SHADERPERMUTATION_ALPHAKILL = 1<<22, ///< (deferredgeometry) discard pixel if diffuse texture alpha below 0.5, (generic) apply global alpha
|
||||
SHADERPERMUTATION_REFLECTCUBE = 1<<23, ///< fake reflections using global cubemap (not HDRI light probe)
|
||||
SHADERPERMUTATION_NORMALMAPSCROLLBLEND = 1<<24, ///< (water) counter-direction normalmaps scrolling
|
||||
SHADERPERMUTATION_BOUNCEGRID = 1<<25, ///< (lightmap) use Texture_BounceGrid as an additional source of ambient light
|
||||
SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL = 1<<26, ///< (lightmap) use 16-component pixels in bouncegrid texture for directional lighting rather than standard 4-component
|
||||
SHADERPERMUTATION_TRIPPY = 1<<27, ///< use trippy vertex shader effect
|
||||
SHADERPERMUTATION_DEPTHRGB = 1<<28, ///< read/write depth values in RGB color coded format for older hardware without depth samplers
|
||||
SHADERPERMUTATION_ALPHAGEN_VERTEX = 1<<29, ///< alphaGen vertex
|
||||
SHADERPERMUTATION_SKELETAL = 1<<30, ///< (skeletal models) use skeletal matrices to deform vertices (gpu-skinning)
|
||||
SHADERPERMUTATION_COUNT = 31 ///< size of shaderpermutationinfo array
|
||||
}
|
||||
shaderpermutation_t;
|
||||
|
||||
typedef enum DPSOFTRAST_UNIFORM_e
|
||||
{
|
||||
DPSOFTRAST_UNIFORM_Texture_First,
|
||||
DPSOFTRAST_UNIFORM_Texture_Second,
|
||||
DPSOFTRAST_UNIFORM_Texture_GammaRamps,
|
||||
DPSOFTRAST_UNIFORM_Texture_Normal,
|
||||
DPSOFTRAST_UNIFORM_Texture_Color,
|
||||
DPSOFTRAST_UNIFORM_Texture_Gloss,
|
||||
DPSOFTRAST_UNIFORM_Texture_Glow,
|
||||
DPSOFTRAST_UNIFORM_Texture_SecondaryNormal,
|
||||
DPSOFTRAST_UNIFORM_Texture_SecondaryColor,
|
||||
DPSOFTRAST_UNIFORM_Texture_SecondaryGloss,
|
||||
DPSOFTRAST_UNIFORM_Texture_SecondaryGlow,
|
||||
DPSOFTRAST_UNIFORM_Texture_Pants,
|
||||
DPSOFTRAST_UNIFORM_Texture_Shirt,
|
||||
DPSOFTRAST_UNIFORM_Texture_FogHeightTexture,
|
||||
DPSOFTRAST_UNIFORM_Texture_FogMask,
|
||||
DPSOFTRAST_UNIFORM_Texture_Lightmap,
|
||||
DPSOFTRAST_UNIFORM_Texture_Deluxemap,
|
||||
DPSOFTRAST_UNIFORM_Texture_Attenuation,
|
||||
DPSOFTRAST_UNIFORM_Texture_Cube,
|
||||
DPSOFTRAST_UNIFORM_Texture_Refraction,
|
||||
DPSOFTRAST_UNIFORM_Texture_Reflection,
|
||||
DPSOFTRAST_UNIFORM_Texture_ShadowMap2D,
|
||||
DPSOFTRAST_UNIFORM_Texture_CubeProjection,
|
||||
DPSOFTRAST_UNIFORM_Texture_ScreenNormalMap,
|
||||
DPSOFTRAST_UNIFORM_Texture_ScreenDiffuse,
|
||||
DPSOFTRAST_UNIFORM_Texture_ScreenSpecular,
|
||||
DPSOFTRAST_UNIFORM_Texture_ReflectMask,
|
||||
DPSOFTRAST_UNIFORM_Texture_ReflectCube,
|
||||
DPSOFTRAST_UNIFORM_Alpha,
|
||||
DPSOFTRAST_UNIFORM_BloomBlur_Parameters,
|
||||
DPSOFTRAST_UNIFORM_ClientTime,
|
||||
DPSOFTRAST_UNIFORM_Color_Ambient,
|
||||
DPSOFTRAST_UNIFORM_Color_Diffuse,
|
||||
DPSOFTRAST_UNIFORM_Color_Specular,
|
||||
DPSOFTRAST_UNIFORM_Color_Glow,
|
||||
DPSOFTRAST_UNIFORM_Color_Pants,
|
||||
DPSOFTRAST_UNIFORM_Color_Shirt,
|
||||
DPSOFTRAST_UNIFORM_DeferredColor_Ambient,
|
||||
DPSOFTRAST_UNIFORM_DeferredColor_Diffuse,
|
||||
DPSOFTRAST_UNIFORM_DeferredColor_Specular,
|
||||
DPSOFTRAST_UNIFORM_DeferredMod_Diffuse,
|
||||
DPSOFTRAST_UNIFORM_DeferredMod_Specular,
|
||||
DPSOFTRAST_UNIFORM_DistortScaleRefractReflect,
|
||||
DPSOFTRAST_UNIFORM_EyePosition,
|
||||
DPSOFTRAST_UNIFORM_FogColor,
|
||||
DPSOFTRAST_UNIFORM_FogHeightFade,
|
||||
DPSOFTRAST_UNIFORM_FogPlane,
|
||||
DPSOFTRAST_UNIFORM_FogPlaneViewDist,
|
||||
DPSOFTRAST_UNIFORM_FogRangeRecip,
|
||||
DPSOFTRAST_UNIFORM_LightColor,
|
||||
DPSOFTRAST_UNIFORM_LightDir,
|
||||
DPSOFTRAST_UNIFORM_LightPosition,
|
||||
DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps,
|
||||
DPSOFTRAST_UNIFORM_PixelSize,
|
||||
DPSOFTRAST_UNIFORM_ReflectColor,
|
||||
DPSOFTRAST_UNIFORM_ReflectFactor,
|
||||
DPSOFTRAST_UNIFORM_ReflectOffset,
|
||||
DPSOFTRAST_UNIFORM_RefractColor,
|
||||
DPSOFTRAST_UNIFORM_Saturation,
|
||||
DPSOFTRAST_UNIFORM_ScreenCenterRefractReflect,
|
||||
DPSOFTRAST_UNIFORM_ScreenScaleRefractReflect,
|
||||
DPSOFTRAST_UNIFORM_ScreenToDepth,
|
||||
DPSOFTRAST_UNIFORM_ShadowMap_Parameters,
|
||||
DPSOFTRAST_UNIFORM_ShadowMap_TextureScale,
|
||||
DPSOFTRAST_UNIFORM_SpecularPower,
|
||||
DPSOFTRAST_UNIFORM_UserVec1,
|
||||
DPSOFTRAST_UNIFORM_UserVec2,
|
||||
DPSOFTRAST_UNIFORM_UserVec3,
|
||||
DPSOFTRAST_UNIFORM_UserVec4,
|
||||
DPSOFTRAST_UNIFORM_ViewTintColor,
|
||||
DPSOFTRAST_UNIFORM_ViewToLightM1,
|
||||
DPSOFTRAST_UNIFORM_ViewToLightM2,
|
||||
DPSOFTRAST_UNIFORM_ViewToLightM3,
|
||||
DPSOFTRAST_UNIFORM_ViewToLightM4,
|
||||
DPSOFTRAST_UNIFORM_ModelToLightM1,
|
||||
DPSOFTRAST_UNIFORM_ModelToLightM2,
|
||||
DPSOFTRAST_UNIFORM_ModelToLightM3,
|
||||
DPSOFTRAST_UNIFORM_ModelToLightM4,
|
||||
DPSOFTRAST_UNIFORM_TexMatrixM1,
|
||||
DPSOFTRAST_UNIFORM_TexMatrixM2,
|
||||
DPSOFTRAST_UNIFORM_TexMatrixM3,
|
||||
DPSOFTRAST_UNIFORM_TexMatrixM4,
|
||||
DPSOFTRAST_UNIFORM_BackgroundTexMatrixM1,
|
||||
DPSOFTRAST_UNIFORM_BackgroundTexMatrixM2,
|
||||
DPSOFTRAST_UNIFORM_BackgroundTexMatrixM3,
|
||||
DPSOFTRAST_UNIFORM_BackgroundTexMatrixM4,
|
||||
DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1,
|
||||
DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM2,
|
||||
DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM3,
|
||||
DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM4,
|
||||
DPSOFTRAST_UNIFORM_ModelViewMatrixM1,
|
||||
DPSOFTRAST_UNIFORM_ModelViewMatrixM2,
|
||||
DPSOFTRAST_UNIFORM_ModelViewMatrixM3,
|
||||
DPSOFTRAST_UNIFORM_ModelViewMatrixM4,
|
||||
DPSOFTRAST_UNIFORM_PixelToScreenTexCoord,
|
||||
DPSOFTRAST_UNIFORM_ModelToReflectCubeM1,
|
||||
DPSOFTRAST_UNIFORM_ModelToReflectCubeM2,
|
||||
DPSOFTRAST_UNIFORM_ModelToReflectCubeM3,
|
||||
DPSOFTRAST_UNIFORM_ModelToReflectCubeM4,
|
||||
DPSOFTRAST_UNIFORM_ShadowMapMatrixM1,
|
||||
DPSOFTRAST_UNIFORM_ShadowMapMatrixM2,
|
||||
DPSOFTRAST_UNIFORM_ShadowMapMatrixM3,
|
||||
DPSOFTRAST_UNIFORM_ShadowMapMatrixM4,
|
||||
DPSOFTRAST_UNIFORM_BloomColorSubtract,
|
||||
DPSOFTRAST_UNIFORM_NormalmapScrollBlend,
|
||||
DPSOFTRAST_UNIFORM_OffsetMapping_LodDistance,
|
||||
DPSOFTRAST_UNIFORM_OffsetMapping_Bias,
|
||||
DPSOFTRAST_UNIFORM_TOTAL
|
||||
}
|
||||
DPSOFTRAST_UNIFORM;
|
||||
|
||||
void DPSOFTRAST_SetShader(int mode, int permutation, int exactspecularmath);
|
||||
#define DPSOFTRAST_Uniform1f(index, v0) DPSOFTRAST_Uniform4f(index, v0, 0, 0, 0)
|
||||
#define DPSOFTRAST_Uniform2f(index, v0, v1) DPSOFTRAST_Uniform4f(index, v0, v1, 0, 0)
|
||||
#define DPSOFTRAST_Uniform3f(index, v0, v1, v2) DPSOFTRAST_Uniform4f(index, v0, v1, v2, 0)
|
||||
void DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM index, float v0, float v1, float v2, float v3);
|
||||
void DPSOFTRAST_Uniform4fv(DPSOFTRAST_UNIFORM index, const float *v);
|
||||
void DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM index, int arraysize, int transpose, const float *v);
|
||||
void DPSOFTRAST_Uniform1i(DPSOFTRAST_UNIFORM index, int i0);
|
||||
|
||||
void DPSOFTRAST_DrawTriangles(int firstvertex, int numvertices, int numtriangles, const int *element3i, const unsigned short *element3s);
|
||||
|
||||
#endif // DPSOFTRAST_H
|
656
app/jni/dpvsimpledecode.c
Normal file
656
app/jni/dpvsimpledecode.c
Normal file
|
@ -0,0 +1,656 @@
|
|||
#include "quakedef.h"
|
||||
#include "dpvsimpledecode.h"
|
||||
|
||||
#define HZREADERROR_OK 0
|
||||
#define HZREADERROR_EOF 1
|
||||
#define HZREADERROR_MALLOCFAILED 2
|
||||
|
||||
//#define HZREADBLOCKSIZE 16000
|
||||
#define HZREADBLOCKSIZE 1048576
|
||||
|
||||
typedef struct hz_bitstream_read_s
|
||||
{
|
||||
qfile_t *file;
|
||||
int endoffile;
|
||||
}
|
||||
hz_bitstream_read_t;
|
||||
|
||||
typedef struct hz_bitstream_readblock_s
|
||||
{
|
||||
struct hz_bitstream_readblock_s *next;
|
||||
unsigned int size;
|
||||
unsigned char data[HZREADBLOCKSIZE];
|
||||
}
|
||||
hz_bitstream_readblock_t;
|
||||
|
||||
typedef struct hz_bitstream_readblocks_s
|
||||
{
|
||||
hz_bitstream_readblock_t *blocks;
|
||||
hz_bitstream_readblock_t *current;
|
||||
unsigned int position;
|
||||
unsigned int store;
|
||||
int count;
|
||||
}
|
||||
hz_bitstream_readblocks_t;
|
||||
|
||||
static hz_bitstream_read_t *hz_bitstream_read_open(char *filename)
|
||||
{
|
||||
qfile_t *file;
|
||||
hz_bitstream_read_t *stream;
|
||||
if ((file = FS_OpenVirtualFile(filename, false)))
|
||||
{
|
||||
stream = (hz_bitstream_read_t *)Z_Malloc(sizeof(hz_bitstream_read_t));
|
||||
memset(stream, 0, sizeof(*stream));
|
||||
stream->file = file;
|
||||
return stream;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void hz_bitstream_read_close(hz_bitstream_read_t *stream)
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
FS_Close(stream->file);
|
||||
Z_Free(stream);
|
||||
}
|
||||
}
|
||||
|
||||
static hz_bitstream_readblocks_t *hz_bitstream_read_blocks_new(void)
|
||||
{
|
||||
hz_bitstream_readblocks_t *blocks;
|
||||
blocks = (hz_bitstream_readblocks_t *)Z_Malloc(sizeof(hz_bitstream_readblocks_t));
|
||||
if (blocks == NULL)
|
||||
return NULL;
|
||||
memset(blocks, 0, sizeof(hz_bitstream_readblocks_t));
|
||||
return blocks;
|
||||
}
|
||||
|
||||
static void hz_bitstream_read_blocks_free(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
hz_bitstream_readblock_t *b, *n;
|
||||
if (blocks == NULL)
|
||||
return;
|
||||
for (b = blocks->blocks;b;b = n)
|
||||
{
|
||||
n = b->next;
|
||||
Z_Free(b);
|
||||
}
|
||||
Z_Free(blocks);
|
||||
}
|
||||
|
||||
static void hz_bitstream_read_flushbits(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
blocks->store = 0;
|
||||
blocks->count = 0;
|
||||
}
|
||||
|
||||
static int hz_bitstream_read_blocks_read(hz_bitstream_readblocks_t *blocks, hz_bitstream_read_t *stream, unsigned int size)
|
||||
{
|
||||
int s;
|
||||
hz_bitstream_readblock_t *b, *p;
|
||||
s = size;
|
||||
p = NULL;
|
||||
b = blocks->blocks;
|
||||
while (s > 0)
|
||||
{
|
||||
if (b == NULL)
|
||||
{
|
||||
b = (hz_bitstream_readblock_t *)Z_Malloc(sizeof(hz_bitstream_readblock_t));
|
||||
if (b == NULL)
|
||||
return HZREADERROR_MALLOCFAILED;
|
||||
b->next = NULL;
|
||||
b->size = 0;
|
||||
if (p != NULL)
|
||||
p->next = b;
|
||||
else
|
||||
blocks->blocks = b;
|
||||
}
|
||||
if (s > HZREADBLOCKSIZE)
|
||||
b->size = HZREADBLOCKSIZE;
|
||||
else
|
||||
b->size = s;
|
||||
s -= b->size;
|
||||
if (FS_Read(stream->file, b->data, b->size) != (fs_offset_t)b->size)
|
||||
{
|
||||
stream->endoffile = 1;
|
||||
break;
|
||||
}
|
||||
p = b;
|
||||
b = b->next;
|
||||
}
|
||||
while (b)
|
||||
{
|
||||
b->size = 0;
|
||||
b = b->next;
|
||||
}
|
||||
blocks->current = blocks->blocks;
|
||||
blocks->position = 0;
|
||||
hz_bitstream_read_flushbits(blocks);
|
||||
if (stream->endoffile)
|
||||
return HZREADERROR_EOF;
|
||||
return HZREADERROR_OK;
|
||||
}
|
||||
|
||||
static unsigned int hz_bitstream_read_blocks_getbyte(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
while (blocks->current != NULL && blocks->position >= blocks->current->size)
|
||||
{
|
||||
blocks->position = 0;
|
||||
blocks->current = blocks->current->next;
|
||||
}
|
||||
if (blocks->current == NULL)
|
||||
return 0;
|
||||
return blocks->current->data[blocks->position++];
|
||||
}
|
||||
|
||||
static int hz_bitstream_read_bit(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
if (!blocks->count)
|
||||
{
|
||||
blocks->count += 8;
|
||||
blocks->store <<= 8;
|
||||
blocks->store |= hz_bitstream_read_blocks_getbyte(blocks) & 0xFF;
|
||||
}
|
||||
blocks->count--;
|
||||
return (blocks->store >> blocks->count) & 1;
|
||||
}
|
||||
|
||||
static unsigned int hz_bitstream_read_bits(hz_bitstream_readblocks_t *blocks, int size)
|
||||
{
|
||||
unsigned int num = 0;
|
||||
// we can only handle about 24 bits at a time safely
|
||||
// (there might be up to 7 bits more than we need in the bit store)
|
||||
if (size > 24)
|
||||
{
|
||||
size -= 8;
|
||||
num |= hz_bitstream_read_bits(blocks, 8) << size;
|
||||
}
|
||||
while (blocks->count < size)
|
||||
{
|
||||
blocks->count += 8;
|
||||
blocks->store <<= 8;
|
||||
blocks->store |= hz_bitstream_read_blocks_getbyte(blocks) & 0xFF;
|
||||
}
|
||||
blocks->count -= size;
|
||||
num |= (blocks->store >> blocks->count) & ((1 << size) - 1);
|
||||
return num;
|
||||
}
|
||||
|
||||
static unsigned int hz_bitstream_read_byte(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
return hz_bitstream_read_blocks_getbyte(blocks);
|
||||
}
|
||||
|
||||
static unsigned int hz_bitstream_read_short(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
return (hz_bitstream_read_byte(blocks) << 8)
|
||||
| (hz_bitstream_read_byte(blocks));
|
||||
}
|
||||
|
||||
static unsigned int hz_bitstream_read_int(hz_bitstream_readblocks_t *blocks)
|
||||
{
|
||||
return (hz_bitstream_read_byte(blocks) << 24)
|
||||
| (hz_bitstream_read_byte(blocks) << 16)
|
||||
| (hz_bitstream_read_byte(blocks) << 8)
|
||||
| (hz_bitstream_read_byte(blocks));
|
||||
}
|
||||
|
||||
static void hz_bitstream_read_bytes(hz_bitstream_readblocks_t *blocks, void *outdata, unsigned int size)
|
||||
{
|
||||
unsigned char *out;
|
||||
out = (unsigned char *)outdata;
|
||||
while (size--)
|
||||
*out++ = hz_bitstream_read_byte(blocks);
|
||||
}
|
||||
|
||||
#define BLOCKSIZE 8
|
||||
|
||||
typedef struct dpvsimpledecodestream_s
|
||||
{
|
||||
hz_bitstream_read_t *bitstream;
|
||||
hz_bitstream_readblocks_t *framedatablocks;
|
||||
|
||||
int error;
|
||||
|
||||
double info_framerate;
|
||||
unsigned int info_frames;
|
||||
|
||||
unsigned int info_imagewidth;
|
||||
unsigned int info_imageheight;
|
||||
unsigned int info_imagebpp;
|
||||
unsigned int info_imageRloss;
|
||||
unsigned int info_imageRmask;
|
||||
unsigned int info_imageRshift;
|
||||
unsigned int info_imageGloss;
|
||||
unsigned int info_imageGmask;
|
||||
unsigned int info_imageGshift;
|
||||
unsigned int info_imageBloss;
|
||||
unsigned int info_imageBmask;
|
||||
unsigned int info_imageBshift;
|
||||
unsigned int info_imagesize;
|
||||
double info_aspectratio;
|
||||
|
||||
// current video frame (needed because of delta compression)
|
||||
int videoframenum;
|
||||
// current video frame data (needed because of delta compression)
|
||||
unsigned int *videopixels;
|
||||
|
||||
// channel the sound file is being played on
|
||||
int sndchan;
|
||||
}
|
||||
dpvsimpledecodestream_t;
|
||||
|
||||
static int dpvsimpledecode_setpixelformat(dpvsimpledecodestream_t *s, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel)
|
||||
{
|
||||
int Rshift, Rbits, Gshift, Gbits, Bshift, Bbits;
|
||||
if (!Rmask)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_INVALIDRMASK;
|
||||
return s->error;
|
||||
}
|
||||
if (!Gmask)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_INVALIDGMASK;
|
||||
return s->error;
|
||||
}
|
||||
if (!Bmask)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_INVALIDBMASK;
|
||||
return s->error;
|
||||
}
|
||||
if (Rmask & Gmask || Rmask & Bmask || Gmask & Bmask)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_COLORMASKSOVERLAP;
|
||||
return s->error;
|
||||
}
|
||||
switch (bytesperpixel)
|
||||
{
|
||||
case 2:
|
||||
if ((Rmask | Gmask | Bmask) > 65536)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_COLORMASKSEXCEEDBPP;
|
||||
return s->error;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
s->error = DPVSIMPLEDECODEERROR_UNSUPPORTEDBPP;
|
||||
return s->error;
|
||||
}
|
||||
for (Rshift = 0;!(Rmask & 1);Rshift++, Rmask >>= 1);
|
||||
for (Gshift = 0;!(Gmask & 1);Gshift++, Gmask >>= 1);
|
||||
for (Bshift = 0;!(Bmask & 1);Bshift++, Bmask >>= 1);
|
||||
if (((Rmask + 1) & Rmask) != 0)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_INVALIDRMASK;
|
||||
return s->error;
|
||||
}
|
||||
if (((Gmask + 1) & Gmask) != 0)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_INVALIDGMASK;
|
||||
return s->error;
|
||||
}
|
||||
if (((Bmask + 1) & Bmask) != 0)
|
||||
{
|
||||
s->error = DPVSIMPLEDECODEERROR_INVALIDBMASK;
|
||||
return s->error;
|
||||
}
|
||||
for (Rbits = 0;Rmask & 1;Rbits++, Rmask >>= 1);
|
||||
for (Gbits = 0;Gmask & 1;Gbits++, Gmask >>= 1);
|
||||
for (Bbits = 0;Bmask & 1;Bbits++, Bmask >>= 1);
|
||||
if (Rbits > 8)
|
||||
{
|
||||
Rshift += (Rbits - 8);
|
||||
Rbits = 8;
|
||||
}
|
||||
if (Gbits > 8)
|
||||
{
|
||||
Gshift += (Gbits - 8);
|
||||
Gbits = 8;
|
||||
}
|
||||
if (Bbits > 8)
|
||||
{
|
||||
Bshift += (Bbits - 8);
|
||||
Bbits = 8;
|
||||
}
|
||||
s->info_imagebpp = bytesperpixel;
|
||||
s->info_imageRloss = 16 + (8 - Rbits);
|
||||
s->info_imageGloss = 8 + (8 - Gbits);
|
||||
s->info_imageBloss = 0 + (8 - Bbits);
|
||||
s->info_imageRmask = (1 << Rbits) - 1;
|
||||
s->info_imageGmask = (1 << Gbits) - 1;
|
||||
s->info_imageBmask = (1 << Bbits) - 1;
|
||||
s->info_imageRshift = Rshift;
|
||||
s->info_imageGshift = Gshift;
|
||||
s->info_imageBshift = Bshift;
|
||||
s->info_imagesize = s->info_imagewidth * s->info_imageheight * s->info_imagebpp;
|
||||
return s->error;
|
||||
}
|
||||
|
||||
// opening and closing streams
|
||||
|
||||
// opens a stream
|
||||
void *dpvsimpledecode_open(clvideo_t *video, char *filename, const char **errorstring)
|
||||
{
|
||||
dpvsimpledecodestream_t *s;
|
||||
char t[8], *wavename;
|
||||
if (errorstring != NULL)
|
||||
*errorstring = NULL;
|
||||
s = (dpvsimpledecodestream_t *)Z_Malloc(sizeof(dpvsimpledecodestream_t));
|
||||
if (s != NULL)
|
||||
{
|
||||
s->bitstream = hz_bitstream_read_open(filename);
|
||||
if (s->bitstream != NULL)
|
||||
{
|
||||
// check file identification
|
||||
s->framedatablocks = hz_bitstream_read_blocks_new();
|
||||
if (s->framedatablocks != NULL)
|
||||
{
|
||||
hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 8);
|
||||
hz_bitstream_read_bytes(s->framedatablocks, t, 8);
|
||||
if (!memcmp(t, "DPVideo", 8))
|
||||
{
|
||||
// check version number
|
||||
hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 2);
|
||||
if (hz_bitstream_read_short(s->framedatablocks) == 1)
|
||||
{
|
||||
hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 12);
|
||||
s->info_imagewidth = hz_bitstream_read_short(s->framedatablocks);
|
||||
s->info_imageheight = hz_bitstream_read_short(s->framedatablocks);
|
||||
s->info_framerate = (double) hz_bitstream_read_int(s->framedatablocks) * (1.0 / 65536.0);
|
||||
s->info_aspectratio = (double)s->info_imagewidth / (double)s->info_imageheight;
|
||||
|
||||
if (s->info_framerate > 0.0)
|
||||
{
|
||||
s->videopixels = (unsigned int *)Z_Malloc(s->info_imagewidth * s->info_imageheight * sizeof(*s->videopixels));
|
||||
if (s->videopixels != NULL)
|
||||
{
|
||||
size_t namelen;
|
||||
|
||||
namelen = strlen(filename) + 10;
|
||||
wavename = (char *)Z_Malloc(namelen);
|
||||
if (wavename)
|
||||
{
|
||||
sfx_t* sfx;
|
||||
|
||||
FS_StripExtension(filename, wavename, namelen);
|
||||
strlcat(wavename, ".wav", namelen);
|
||||
sfx = S_PrecacheSound (wavename, false, false);
|
||||
if (sfx != NULL)
|
||||
s->sndchan = S_StartSound (-1, 0, sfx, vec3_origin, 1.0f, 0);
|
||||
else
|
||||
s->sndchan = -1;
|
||||
Z_Free(wavename);
|
||||
}
|
||||
// all is well...
|
||||
// set the module functions
|
||||
s->videoframenum = -10000;
|
||||
video->close = dpvsimpledecode_close;
|
||||
video->getwidth = dpvsimpledecode_getwidth;
|
||||
video->getheight = dpvsimpledecode_getheight;
|
||||
video->getframerate = dpvsimpledecode_getframerate;
|
||||
video->decodeframe = dpvsimpledecode_video;
|
||||
video->getaspectratio = dpvsimpledecode_getaspectratio;
|
||||
|
||||
return s;
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "unable to allocate video image buffer";
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "error in video info chunk";
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "read error";
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "not a dpvideo file";
|
||||
hz_bitstream_read_blocks_free(s->framedatablocks);
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "unable to allocate memory for reading buffer";
|
||||
hz_bitstream_read_close(s->bitstream);
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "unable to open file";
|
||||
Z_Free(s);
|
||||
}
|
||||
else if (errorstring != NULL)
|
||||
*errorstring = "unable to allocate memory for stream info structure";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// closes a stream
|
||||
void dpvsimpledecode_close(void *stream)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
if (s == NULL)
|
||||
return;
|
||||
if (s->videopixels)
|
||||
Z_Free(s->videopixels);
|
||||
if (s->sndchan != -1)
|
||||
S_StopChannel (s->sndchan, true, true);
|
||||
if (s->framedatablocks)
|
||||
hz_bitstream_read_blocks_free(s->framedatablocks);
|
||||
if (s->bitstream)
|
||||
hz_bitstream_read_close(s->bitstream);
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
// utilitarian functions
|
||||
|
||||
// returns the current error number for the stream, and resets the error
|
||||
// number to DPVSIMPLEDECODEERROR_NONE
|
||||
// if the supplied string pointer variable is not NULL, it will be set to the
|
||||
// error message
|
||||
int dpvsimpledecode_error(void *stream, const char **errorstring)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
int e;
|
||||
e = s->error;
|
||||
s->error = 0;
|
||||
if (errorstring)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case DPVSIMPLEDECODEERROR_NONE:
|
||||
*errorstring = "no error";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_EOF:
|
||||
*errorstring = "end of file reached (this is not an error)";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_READERROR:
|
||||
*errorstring = "read error (corrupt or incomplete file)";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_SOUNDBUFFERTOOSMALL:
|
||||
*errorstring = "sound buffer is too small for decoding frame (please allocate it as large as dpvsimpledecode_getneededsoundbufferlength suggests)";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_INVALIDRMASK:
|
||||
*errorstring = "invalid red bits mask";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_INVALIDGMASK:
|
||||
*errorstring = "invalid green bits mask";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_INVALIDBMASK:
|
||||
*errorstring = "invalid blue bits mask";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_COLORMASKSOVERLAP:
|
||||
*errorstring = "color bit masks overlap";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_COLORMASKSEXCEEDBPP:
|
||||
*errorstring = "color masks too big for specified bytes per pixel";
|
||||
break;
|
||||
case DPVSIMPLEDECODEERROR_UNSUPPORTEDBPP:
|
||||
*errorstring = "unsupported bytes per pixel (must be 2 for 16bit, or 4 for 32bit)";
|
||||
break;
|
||||
default:
|
||||
*errorstring = "unknown error";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
// returns the width of the image data
|
||||
unsigned int dpvsimpledecode_getwidth(void *stream)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
return s->info_imagewidth;
|
||||
}
|
||||
|
||||
// returns the height of the image data
|
||||
unsigned int dpvsimpledecode_getheight(void *stream)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
return s->info_imageheight;
|
||||
}
|
||||
|
||||
// returns the framerate of the stream
|
||||
double dpvsimpledecode_getframerate(void *stream)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
return s->info_framerate;
|
||||
}
|
||||
|
||||
// return aspect ratio of the stream
|
||||
double dpvsimpledecode_getaspectratio(void *stream)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
return s->info_aspectratio;
|
||||
}
|
||||
|
||||
static int dpvsimpledecode_convertpixels(dpvsimpledecodestream_t *s, void *imagedata, int imagebytesperrow)
|
||||
{
|
||||
unsigned int a, x, y, width, height;
|
||||
unsigned int Rloss, Rmask, Rshift, Gloss, Gmask, Gshift, Bloss, Bmask, Bshift;
|
||||
unsigned int *in;
|
||||
|
||||
width = s->info_imagewidth;
|
||||
height = s->info_imageheight;
|
||||
|
||||
Rloss = s->info_imageRloss;
|
||||
Rmask = s->info_imageRmask;
|
||||
Rshift = s->info_imageRshift;
|
||||
Gloss = s->info_imageGloss;
|
||||
Gmask = s->info_imageGmask;
|
||||
Gshift = s->info_imageGshift;
|
||||
Bloss = s->info_imageBloss;
|
||||
Bmask = s->info_imageBmask;
|
||||
Bshift = s->info_imageBshift;
|
||||
|
||||
in = s->videopixels;
|
||||
if (s->info_imagebpp == 4)
|
||||
{
|
||||
unsigned int *outrow;
|
||||
for (y = 0;y < height;y++)
|
||||
{
|
||||
outrow = (unsigned int *)((unsigned char *)imagedata + y * imagebytesperrow);
|
||||
for (x = 0;x < width;x++)
|
||||
{
|
||||
a = *in++;
|
||||
outrow[x] = (((a >> Rloss) & Rmask) << Rshift) | (((a >> Gloss) & Gmask) << Gshift) | (((a >> Bloss) & Bmask) << Bshift);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short *outrow;
|
||||
for (y = 0;y < height;y++)
|
||||
{
|
||||
outrow = (unsigned short *)((unsigned char *)imagedata + y * imagebytesperrow);
|
||||
if (Rloss == 19 && Gloss == 10 && Bloss == 3 && Rshift == 11 && Gshift == 5 && Bshift == 0)
|
||||
{
|
||||
// optimized
|
||||
for (x = 0;x < width;x++)
|
||||
{
|
||||
a = *in++;
|
||||
outrow[x] = ((a >> 8) & 0xF800) | ((a >> 5) & 0x07E0) | ((a >> 3) & 0x001F);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0;x < width;x++)
|
||||
{
|
||||
a = *in++;
|
||||
outrow[x] = (((a >> Rloss) & Rmask) << Rshift) | (((a >> Gloss) & Gmask) << Gshift) | (((a >> Bloss) & Bmask) << Bshift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return s->error;
|
||||
}
|
||||
|
||||
static int dpvsimpledecode_decompressimage(dpvsimpledecodestream_t *s)
|
||||
{
|
||||
int i, a, b, colors, g, x1, y1, bw, bh, width, height, palettebits;
|
||||
unsigned int palette[256], *outrow, *out;
|
||||
g = BLOCKSIZE;
|
||||
width = s->info_imagewidth;
|
||||
height = s->info_imageheight;
|
||||
for (y1 = 0;y1 < height;y1 += g)
|
||||
{
|
||||
outrow = s->videopixels + y1 * width;
|
||||
bh = g;
|
||||
if (y1 + bh > height)
|
||||
bh = height - y1;
|
||||
for (x1 = 0;x1 < width;x1 += g)
|
||||
{
|
||||
out = outrow + x1;
|
||||
bw = g;
|
||||
if (x1 + bw > width)
|
||||
bw = width - x1;
|
||||
if (hz_bitstream_read_bit(s->framedatablocks))
|
||||
{
|
||||
// updated block
|
||||
palettebits = hz_bitstream_read_bits(s->framedatablocks, 3);
|
||||
colors = 1 << palettebits;
|
||||
for (i = 0;i < colors;i++)
|
||||
palette[i] = hz_bitstream_read_bits(s->framedatablocks, 24);
|
||||
if (palettebits)
|
||||
{
|
||||
for (b = 0;b < bh;b++, out += width)
|
||||
for (a = 0;a < bw;a++)
|
||||
out[a] = palette[hz_bitstream_read_bits(s->framedatablocks, palettebits)];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (b = 0;b < bh;b++, out += width)
|
||||
for (a = 0;a < bw;a++)
|
||||
out[a] = palette[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return s->error;
|
||||
}
|
||||
|
||||
// decodes a video frame to the supplied output pixels
|
||||
int dpvsimpledecode_video(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow)
|
||||
{
|
||||
dpvsimpledecodestream_t *s = (dpvsimpledecodestream_t *)stream;
|
||||
unsigned int framedatasize;
|
||||
char t[4];
|
||||
s->error = DPVSIMPLEDECODEERROR_NONE;
|
||||
if (dpvsimpledecode_setpixelformat(s, Rmask, Gmask, Bmask, bytesperpixel))
|
||||
return s->error;
|
||||
|
||||
hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, 8);
|
||||
hz_bitstream_read_bytes(s->framedatablocks, t, 4);
|
||||
if (memcmp(t, "VID0", 4))
|
||||
{
|
||||
if (t[0] == 0)
|
||||
return (s->error = DPVSIMPLEDECODEERROR_EOF);
|
||||
else
|
||||
return (s->error = DPVSIMPLEDECODEERROR_READERROR);
|
||||
}
|
||||
framedatasize = hz_bitstream_read_int(s->framedatablocks);
|
||||
hz_bitstream_read_blocks_read(s->framedatablocks, s->bitstream, framedatasize);
|
||||
if (dpvsimpledecode_decompressimage(s))
|
||||
return s->error;
|
||||
|
||||
dpvsimpledecode_convertpixels(s, imagedata, imagebytesperrow);
|
||||
return s->error;
|
||||
}
|
49
app/jni/dpvsimpledecode.h
Normal file
49
app/jni/dpvsimpledecode.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
|
||||
#ifndef DPVSIMPLEDECODE_H
|
||||
#define DPVSIMPLEDECODE_H
|
||||
|
||||
#include "cl_video.h"
|
||||
|
||||
#define DPVSIMPLEDECODEERROR_NONE 0
|
||||
#define DPVSIMPLEDECODEERROR_EOF 1
|
||||
#define DPVSIMPLEDECODEERROR_READERROR 2
|
||||
#define DPVSIMPLEDECODEERROR_SOUNDBUFFERTOOSMALL 3
|
||||
#define DPVSIMPLEDECODEERROR_INVALIDRMASK 4
|
||||
#define DPVSIMPLEDECODEERROR_INVALIDGMASK 5
|
||||
#define DPVSIMPLEDECODEERROR_INVALIDBMASK 6
|
||||
#define DPVSIMPLEDECODEERROR_COLORMASKSOVERLAP 7
|
||||
#define DPVSIMPLEDECODEERROR_COLORMASKSEXCEEDBPP 8
|
||||
#define DPVSIMPLEDECODEERROR_UNSUPPORTEDBPP 9
|
||||
|
||||
// opening and closing streams
|
||||
|
||||
// opens a stream
|
||||
void *dpvsimpledecode_open(clvideo_t *video, char *filename, const char **errorstring);
|
||||
|
||||
// closes a stream
|
||||
void dpvsimpledecode_close(void *stream);
|
||||
|
||||
// utilitarian functions
|
||||
|
||||
// returns the current error number for the stream, and resets the error
|
||||
// number to DPVDECODEERROR_NONE
|
||||
// if the supplied string pointer variable is not NULL, it will be set to the
|
||||
// error message
|
||||
int dpvsimpledecode_error(void *stream, const char **errorstring);
|
||||
|
||||
// returns the width of the image data
|
||||
unsigned int dpvsimpledecode_getwidth(void *stream);
|
||||
|
||||
// returns the height of the image data
|
||||
unsigned int dpvsimpledecode_getheight(void *stream);
|
||||
|
||||
// returns the framerate of the stream
|
||||
double dpvsimpledecode_getframerate(void *stream);
|
||||
|
||||
// returns aspect ratio of the stream
|
||||
double dpvsimpledecode_getaspectratio(void *stream);
|
||||
|
||||
// decodes a video frame to the supplied output pixels
|
||||
int dpvsimpledecode_video(void *stream, void *imagedata, unsigned int Rmask, unsigned int Gmask, unsigned int Bmask, unsigned int bytesperpixel, int imagebytesperrow);
|
||||
|
||||
#endif
|
207
app/jni/draw.h
Normal file
207
app/jni/draw.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
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
|
||||
|
||||
#ifndef DRAW_H
|
||||
#define DRAW_H
|
||||
|
||||
// FIXME: move this stuff to cl_screen
|
||||
typedef struct cachepic_s
|
||||
{
|
||||
// size of pic
|
||||
int width, height;
|
||||
// this flag indicates that it should be loaded and unloaded on demand
|
||||
int autoload;
|
||||
// texture flags to upload with
|
||||
int texflags;
|
||||
// texture may be freed after a while
|
||||
int lastusedframe;
|
||||
// renderer texture to use
|
||||
rtexture_t *tex;
|
||||
// used for hash lookups
|
||||
struct cachepic_s *chain;
|
||||
// flags - CACHEPICFLAG_NEWPIC for example
|
||||
unsigned int flags;
|
||||
// has alpha?
|
||||
qboolean hasalpha;
|
||||
// name of pic
|
||||
char name[MAX_QPATH];
|
||||
// allow to override/free the texture
|
||||
qboolean allow_free_tex;
|
||||
}
|
||||
cachepic_t;
|
||||
|
||||
typedef enum cachepicflags_e
|
||||
{
|
||||
CACHEPICFLAG_NOTPERSISTENT = 1,
|
||||
CACHEPICFLAG_QUIET = 2,
|
||||
CACHEPICFLAG_NOCOMPRESSION = 4,
|
||||
CACHEPICFLAG_NOCLAMP = 8,
|
||||
CACHEPICFLAG_NEWPIC = 16, // disables matching texflags check, because a pic created with Draw_NewPic should not be subject to that
|
||||
CACHEPICFLAG_MIPMAP = 32,
|
||||
CACHEPICFLAG_NEAREST = 64 // force nearest filtering instead of linear
|
||||
}
|
||||
cachepicflags_t;
|
||||
|
||||
void Draw_Init (void);
|
||||
void Draw_Frame (void);
|
||||
cachepic_t *Draw_CachePic_Flags (const char *path, unsigned int cachepicflags);
|
||||
cachepic_t *Draw_CachePic (const char *path); // standard function with no options, used throughout engine
|
||||
// create or update a pic's image
|
||||
cachepic_t *Draw_NewPic(const char *picname, int width, int height, int alpha, unsigned char *pixels);
|
||||
// free the texture memory used by a pic
|
||||
void Draw_FreePic(const char *picname);
|
||||
|
||||
// a triangle mesh..
|
||||
// each vertex is 3 floats
|
||||
// each texcoord is 2 floats
|
||||
// each color is 4 floats
|
||||
typedef struct drawqueuemesh_s
|
||||
{
|
||||
rtexture_t *texture;
|
||||
int num_triangles;
|
||||
int num_vertices;
|
||||
int *data_element3i;
|
||||
unsigned short *data_element3s;
|
||||
float *data_vertex3f;
|
||||
float *data_texcoord2f;
|
||||
float *data_color4f;
|
||||
}
|
||||
drawqueuemesh_t;
|
||||
|
||||
enum drawqueue_drawflag_e {
|
||||
DRAWFLAG_NORMAL,
|
||||
DRAWFLAG_ADDITIVE,
|
||||
DRAWFLAG_MODULATE,
|
||||
DRAWFLAG_2XMODULATE,
|
||||
DRAWFLAG_SCREEN,
|
||||
DRAWFLAG_NUMFLAGS,
|
||||
DRAWFLAG_MASK = 0xFF, // ONLY R_BeginPolygon()
|
||||
DRAWFLAG_MIPMAP = 0x100, // ONLY R_BeginPolygon()
|
||||
DRAWFLAG_NOGAMMA = 0x200 // ONLY R_DrawQSuperPic()
|
||||
};
|
||||
#define DRAWFLAGS_BLEND 0xFF /* this matches all blending flags */
|
||||
|
||||
typedef struct ft2_settings_s
|
||||
{
|
||||
float scale, voffset;
|
||||
// cvar parameters (only read on loadfont command)
|
||||
int antialias, hinting;
|
||||
float outline, blur, shadowx, shadowy, shadowz;
|
||||
} ft2_settings_t;
|
||||
|
||||
#define MAX_FONT_SIZES 16
|
||||
#define MAX_FONT_FALLBACKS 3
|
||||
typedef struct dp_font_s
|
||||
{
|
||||
rtexture_t *tex;
|
||||
float width_of[256]; // width_of[0] == max width of any char; 1.0f is base width (1/16 of texture width); therefore, all widths have to be <= 1 (does not include scale)
|
||||
float maxwidth; // precalculated max width of the font (includes scale)
|
||||
char texpath[MAX_QPATH];
|
||||
char title[MAX_QPATH];
|
||||
|
||||
int req_face; // requested face index, usually 0
|
||||
float req_sizes[MAX_FONT_SIZES]; // sizes to render the font with, 0 still defaults to 16 (backward compatibility when loadfont doesn't get a size parameter) and -1 = disabled
|
||||
char fallbacks[MAX_FONT_FALLBACKS][MAX_QPATH];
|
||||
int fallback_faces[MAX_FONT_FALLBACKS];
|
||||
struct ft2_font_s *ft2;
|
||||
|
||||
ft2_settings_t settings;
|
||||
}
|
||||
dp_font_t;
|
||||
|
||||
typedef struct dp_fonts_s
|
||||
{
|
||||
dp_font_t *f;
|
||||
int maxsize;
|
||||
}
|
||||
dp_fonts_t;
|
||||
extern dp_fonts_t dp_fonts;
|
||||
|
||||
#define MAX_FONTS 16 // fonts at the start
|
||||
#define FONTS_EXPAND 8 // fonts grow when no free slots
|
||||
#define FONT_DEFAULT (&dp_fonts.f[0]) // should be fixed width
|
||||
#define FONT_CONSOLE (&dp_fonts.f[1]) // REALLY should be fixed width (ls!)
|
||||
#define FONT_SBAR (&dp_fonts.f[2]) // must be fixed width
|
||||
#define FONT_NOTIFY (&dp_fonts.f[3]) // free
|
||||
#define FONT_CHAT (&dp_fonts.f[4]) // free
|
||||
#define FONT_CENTERPRINT (&dp_fonts.f[5]) // free
|
||||
#define FONT_INFOBAR (&dp_fonts.f[6]) // free
|
||||
#define FONT_MENU (&dp_fonts.f[7]) // should be fixed width
|
||||
#define FONT_USER(i) (&dp_fonts.f[8+i]) // userdefined fonts
|
||||
#define MAX_USERFONTS (dp_fonts.maxsize - 8)
|
||||
|
||||
// shared color tag printing constants
|
||||
#define STRING_COLOR_TAG '^'
|
||||
#define STRING_COLOR_DEFAULT 7
|
||||
#define STRING_COLOR_DEFAULT_STR "^7"
|
||||
#define STRING_COLOR_RGB_TAG_CHAR 'x'
|
||||
#define STRING_COLOR_RGB_TAG "^x"
|
||||
|
||||
// all of these functions will set r_defdef.draw2dstage if not in 2D rendering mode (and of course prepare for 2D rendering in that case)
|
||||
|
||||
// draw an image (or a filled rectangle if pic == NULL)
|
||||
void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags);
|
||||
// draw a rotated image
|
||||
void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, float org_x, float org_y, float angle, float red, float green, float blue, float alpha, int flags);
|
||||
// draw a filled rectangle (slightly faster than DrawQ_Pic with pic = NULL)
|
||||
void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags);
|
||||
// draw a text string,
|
||||
// with optional color tag support,
|
||||
// returns final unclipped x coordinate
|
||||
// if outcolor is provided the initial color is read from it, and it is updated at the end with the new value at the end of the text (not at the end of the clipped part)
|
||||
// the color is tinted by the provided base color
|
||||
// if r_textshadow is not zero, an additional instance of the text is drawn first at an offset with an inverted shade of gray (black text produces a white shadow, brightly colored text produces a black shadow)
|
||||
extern float DrawQ_Color[4];
|
||||
float DrawQ_String(float x, float y, const char *text, size_t maxlen, float scalex, float scaley, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt);
|
||||
float DrawQ_String_Scale(float x, float y, const char *text, size_t maxlen, float sizex, float sizey, float scalex, float scaley, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt);
|
||||
float DrawQ_TextWidth(const char *text, size_t maxlen, float w, float h, qboolean ignorecolorcodes, const dp_font_t *fnt);
|
||||
float DrawQ_TextWidth_UntilWidth(const char *text, size_t *maxlen, float w, float h, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxWidth);
|
||||
float DrawQ_TextWidth_UntilWidth_TrackColors(const char *text, size_t *maxlen, float w, float h, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth);
|
||||
float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *maxlen, float w, float h, float sw, float sh, int *outcolor, qboolean ignorecolorcodes, const dp_font_t *fnt, float maxwidth);
|
||||
// draw a very fancy pic (per corner texcoord/color control), the order is tl, tr, bl, br
|
||||
void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags);
|
||||
// draw a triangle mesh
|
||||
void DrawQ_Mesh(drawqueuemesh_t *mesh, int flags, qboolean hasalpha);
|
||||
// set the clipping area
|
||||
void DrawQ_SetClipArea(float x, float y, float width, float height);
|
||||
// reset the clipping area
|
||||
void DrawQ_ResetClipArea(void);
|
||||
// draw a line
|
||||
void DrawQ_Line(float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags);
|
||||
// draw a lot of lines (call R_Mesh_PrepareVertices_Generic first)
|
||||
void DrawQ_Lines(float width, int numlines, int flags, qboolean hasalpha);
|
||||
// draw a line loop
|
||||
void DrawQ_LineLoop(drawqueuemesh_t *mesh, int flags);
|
||||
// resets r_refdef.draw2dstage
|
||||
void DrawQ_Finish(void);
|
||||
void DrawQ_ProcessDrawFlag(int flags, qboolean alpha); // sets GL_DepthMask and GL_BlendFunc
|
||||
void DrawQ_RecalcView(void); // use this when changing r_refdef.view.* from e.g. csqc
|
||||
|
||||
rtexture_t *Draw_GetPicTexture(cachepic_t *pic);
|
||||
|
||||
void R_DrawGamma(void);
|
||||
|
||||
extern rtexturepool_t *drawtexturepool; // used by ft2.c
|
||||
|
||||
#endif
|
||||
|
204
app/jni/filematch.c
Normal file
204
app/jni/filematch.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
// LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...
|
||||
|
||||
int matchpattern(const char *in, const char *pattern, int caseinsensitive)
|
||||
{
|
||||
return matchpattern_with_separator(in, pattern, caseinsensitive, "/\\:", false);
|
||||
}
|
||||
|
||||
// wildcard_least_one: if true * matches 1 or more characters
|
||||
// if false * matches 0 or more characters
|
||||
int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, qboolean wildcard_least_one)
|
||||
{
|
||||
int c1, c2;
|
||||
while (*pattern)
|
||||
{
|
||||
switch (*pattern)
|
||||
{
|
||||
case 0:
|
||||
return 1; // end of pattern
|
||||
case '?': // match any single character
|
||||
if (*in == 0 || strchr(separators, *in))
|
||||
return 0; // no match
|
||||
in++;
|
||||
pattern++;
|
||||
break;
|
||||
case '*': // match anything until following string
|
||||
if(wildcard_least_one)
|
||||
{
|
||||
if (*in == 0 || strchr(separators, *in))
|
||||
return 0; // no match
|
||||
in++;
|
||||
}
|
||||
pattern++;
|
||||
while (*in)
|
||||
{
|
||||
if (strchr(separators, *in))
|
||||
break;
|
||||
// see if pattern matches at this offset
|
||||
if (matchpattern_with_separator(in, pattern, caseinsensitive, separators, wildcard_least_one))
|
||||
return 1;
|
||||
// nope, advance to next offset
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (*in != *pattern)
|
||||
{
|
||||
if (!caseinsensitive)
|
||||
return 0; // no match
|
||||
c1 = *in;
|
||||
if (c1 >= 'A' && c1 <= 'Z')
|
||||
c1 += 'a' - 'A';
|
||||
c2 = *pattern;
|
||||
if (c2 >= 'A' && c2 <= 'Z')
|
||||
c2 += 'a' - 'A';
|
||||
if (c1 != c2)
|
||||
return 0; // no match
|
||||
}
|
||||
in++;
|
||||
pattern++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*in)
|
||||
return 0; // reached end of pattern but not end of input
|
||||
return 1; // success
|
||||
}
|
||||
|
||||
// a little strings system
|
||||
void stringlistinit(stringlist_t *list)
|
||||
{
|
||||
memset(list, 0, sizeof(*list));
|
||||
}
|
||||
|
||||
void stringlistfreecontents(stringlist_t *list)
|
||||
{
|
||||
int i;
|
||||
for (i = 0;i < list->numstrings;i++)
|
||||
{
|
||||
if (list->strings[i])
|
||||
Z_Free(list->strings[i]);
|
||||
list->strings[i] = NULL;
|
||||
}
|
||||
list->numstrings = 0;
|
||||
list->maxstrings = 0;
|
||||
if (list->strings)
|
||||
Z_Free(list->strings);
|
||||
list->strings = NULL;
|
||||
}
|
||||
|
||||
void stringlistappend(stringlist_t *list, const char *text)
|
||||
{
|
||||
size_t textlen;
|
||||
char **oldstrings;
|
||||
|
||||
if (list->numstrings >= list->maxstrings)
|
||||
{
|
||||
oldstrings = list->strings;
|
||||
list->maxstrings += 4096;
|
||||
list->strings = (char **) Z_Malloc(list->maxstrings * sizeof(*list->strings));
|
||||
if (list->numstrings)
|
||||
memcpy(list->strings, oldstrings, list->numstrings * sizeof(*list->strings));
|
||||
if (oldstrings)
|
||||
Z_Free(oldstrings);
|
||||
}
|
||||
textlen = strlen(text) + 1;
|
||||
list->strings[list->numstrings] = (char *) Z_Malloc(textlen);
|
||||
memcpy(list->strings[list->numstrings], text, textlen);
|
||||
list->numstrings++;
|
||||
}
|
||||
|
||||
static int stringlistsort_cmp(const void *a, const void *b)
|
||||
{
|
||||
return strcasecmp(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
void stringlistsort(stringlist_t *list, qboolean uniq)
|
||||
{
|
||||
int i, j;
|
||||
if(list->numstrings < 1)
|
||||
return;
|
||||
qsort(&list->strings[0], list->numstrings, sizeof(list->strings[0]), stringlistsort_cmp);
|
||||
if(uniq)
|
||||
{
|
||||
// i: the item to read
|
||||
// j: the item last written
|
||||
for (i = 1, j = 0; i < list->numstrings; ++i)
|
||||
{
|
||||
char *save;
|
||||
if(!strcasecmp(list->strings[i], list->strings[j]))
|
||||
continue;
|
||||
++j;
|
||||
save = list->strings[j];
|
||||
list->strings[j] = list->strings[i];
|
||||
list->strings[i] = save;
|
||||
}
|
||||
for(i = j+1; i < list->numstrings; ++i)
|
||||
{
|
||||
if (list->strings[i])
|
||||
Z_Free(list->strings[i]);
|
||||
}
|
||||
list->numstrings = j+1;
|
||||
}
|
||||
}
|
||||
|
||||
// operating system specific code
|
||||
static void adddirentry(stringlist_t *list, const char *path, const char *name)
|
||||
{
|
||||
if (strcmp(name, ".") && strcmp(name, ".."))
|
||||
{
|
||||
char temp[MAX_OSPATH];
|
||||
dpsnprintf( temp, sizeof( temp ), "%s%s", path, name );
|
||||
stringlistappend(list, temp);
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
void listdirectory(stringlist_t *list, const char *basepath, const char *path)
|
||||
{
|
||||
int i;
|
||||
char pattern[4096], *c;
|
||||
WIN32_FIND_DATA n_file;
|
||||
HANDLE hFile;
|
||||
strlcpy (pattern, basepath, sizeof(pattern));
|
||||
strlcat (pattern, path, sizeof (pattern));
|
||||
strlcat (pattern, "*", sizeof (pattern));
|
||||
// ask for the directory listing handle
|
||||
hFile = FindFirstFile(pattern, &n_file);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
do {
|
||||
adddirentry(list, path, n_file.cFileName);
|
||||
} while (FindNextFile(hFile, &n_file) != 0);
|
||||
FindClose(hFile);
|
||||
|
||||
// convert names to lowercase because windows does not care, but pattern matching code often does
|
||||
for (i = 0;i < list->numstrings;i++)
|
||||
for (c = list->strings[i];*c;c++)
|
||||
if (*c >= 'A' && *c <= 'Z')
|
||||
*c += 'a' - 'A';
|
||||
}
|
||||
#else
|
||||
void listdirectory(stringlist_t *list, const char *basepath, const char *path)
|
||||
{
|
||||
char fullpath[MAX_OSPATH];
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
dpsnprintf(fullpath, sizeof(fullpath), "%s%s", basepath, *path ? path : "./");
|
||||
dir = opendir(fullpath);
|
||||
if (!dir)
|
||||
return;
|
||||
while ((ent = readdir(dir)))
|
||||
adddirentry(list, path, ent->d_name);
|
||||
closedir(dir);
|
||||
}
|
||||
#endif
|
||||
|
226
app/jni/fractalnoise.c
Normal file
226
app/jni/fractalnoise.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
|
||||
#include "quakedef.h"
|
||||
|
||||
void fractalnoise(unsigned char *noise, int size, int startgrid)
|
||||
{
|
||||
int x, y, g, g2, amplitude, min, max, size1 = size - 1, sizepower, gridpower;
|
||||
int *noisebuf;
|
||||
#define n(x,y) noisebuf[((y)&size1)*size+((x)&size1)]
|
||||
|
||||
for (sizepower = 0;(1 << sizepower) < size;sizepower++);
|
||||
if (size != (1 << sizepower))
|
||||
{
|
||||
Con_Printf("fractalnoise: size must be power of 2\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++);
|
||||
if (startgrid != (1 << gridpower))
|
||||
{
|
||||
Con_Printf("fractalnoise: grid must be power of 2\n");
|
||||
return;
|
||||
}
|
||||
|
||||
startgrid = bound(0, startgrid, size);
|
||||
|
||||
amplitude = 0xFFFF; // this gets halved before use
|
||||
noisebuf = (int *)Mem_Alloc(tempmempool, size*size*sizeof(int));
|
||||
memset(noisebuf, 0, size*size*sizeof(int));
|
||||
|
||||
for (g2 = startgrid;g2;g2 >>= 1)
|
||||
{
|
||||
// brownian motion (at every smaller level there is random behavior)
|
||||
amplitude >>= 1;
|
||||
for (y = 0;y < size;y += g2)
|
||||
for (x = 0;x < size;x += g2)
|
||||
n(x,y) += (rand()&litude);
|
||||
|
||||
g = g2 >> 1;
|
||||
if (g)
|
||||
{
|
||||
// subdivide, diamond-square algorithm (really this has little to do with squares)
|
||||
// diamond
|
||||
for (y = 0;y < size;y += g2)
|
||||
for (x = 0;x < size;x += g2)
|
||||
n(x+g,y+g) = (n(x,y) + n(x+g2,y) + n(x,y+g2) + n(x+g2,y+g2)) >> 2;
|
||||
// square
|
||||
for (y = 0;y < size;y += g2)
|
||||
for (x = 0;x < size;x += g2)
|
||||
{
|
||||
n(x+g,y) = (n(x,y) + n(x+g2,y) + n(x+g,y-g) + n(x+g,y+g)) >> 2;
|
||||
n(x,y+g) = (n(x,y) + n(x,y+g2) + n(x-g,y+g) + n(x+g,y+g)) >> 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// find range of noise values
|
||||
min = max = 0;
|
||||
for (y = 0;y < size;y++)
|
||||
for (x = 0;x < size;x++)
|
||||
{
|
||||
if (n(x,y) < min) min = n(x,y);
|
||||
if (n(x,y) > max) max = n(x,y);
|
||||
}
|
||||
max -= min;
|
||||
max++;
|
||||
// normalize noise and copy to output
|
||||
for (y = 0;y < size;y++)
|
||||
for (x = 0;x < size;x++)
|
||||
*noise++ = (unsigned char) (((n(x,y) - min) * 256) / max);
|
||||
Mem_Free(noisebuf);
|
||||
#undef n
|
||||
}
|
||||
|
||||
// unnormalized, used for explosions mainly, does not allocate/free memory (hence the name quick)
|
||||
void fractalnoisequick(unsigned char *noise, int size, int startgrid)
|
||||
{
|
||||
int x, y, g, g2, amplitude, size1 = size - 1, sizepower, gridpower;
|
||||
#define n(x,y) noise[((y)&size1)*size+((x)&size1)]
|
||||
|
||||
for (sizepower = 0;(1 << sizepower) < size;sizepower++);
|
||||
if (size != (1 << sizepower))
|
||||
{
|
||||
Con_Printf("fractalnoise: size must be power of 2\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (gridpower = 0;(1 << gridpower) < startgrid;gridpower++);
|
||||
if (startgrid != (1 << gridpower))
|
||||
{
|
||||
Con_Printf("fractalnoise: grid must be power of 2\n");
|
||||
return;
|
||||
}
|
||||
|
||||
startgrid = bound(0, startgrid, size);
|
||||
|
||||
amplitude = 255; // this gets halved before use
|
||||
memset(noise, 0, size*size);
|
||||
|
||||
for (g2 = startgrid;g2;g2 >>= 1)
|
||||
{
|
||||
// brownian motion (at every smaller level there is random behavior)
|
||||
amplitude >>= 1;
|
||||
for (y = 0;y < size;y += g2)
|
||||
for (x = 0;x < size;x += g2)
|
||||
n(x,y) += (rand()&litude);
|
||||
|
||||
g = g2 >> 1;
|
||||
if (g)
|
||||
{
|
||||
// subdivide, diamond-square algorithm (really this has little to do with squares)
|
||||
// diamond
|
||||
for (y = 0;y < size;y += g2)
|
||||
for (x = 0;x < size;x += g2)
|
||||
n(x+g,y+g) = (unsigned char) (((int) n(x,y) + (int) n(x+g2,y) + (int) n(x,y+g2) + (int) n(x+g2,y+g2)) >> 2);
|
||||
// square
|
||||
for (y = 0;y < size;y += g2)
|
||||
for (x = 0;x < size;x += g2)
|
||||
{
|
||||
n(x+g,y) = (unsigned char) (((int) n(x,y) + (int) n(x+g2,y) + (int) n(x+g,y-g) + (int) n(x+g,y+g)) >> 2);
|
||||
n(x,y+g) = (unsigned char) (((int) n(x,y) + (int) n(x,y+g2) + (int) n(x-g,y+g) + (int) n(x+g,y+g)) >> 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef n
|
||||
}
|
||||
|
||||
#define NOISE_SIZE 256
|
||||
#define NOISE_MASK 255
|
||||
float noise4f(float x, float y, float z, float w)
|
||||
{
|
||||
int i;
|
||||
int index[4][2];
|
||||
float frac[4][2];
|
||||
float v[4];
|
||||
static float noisetable[NOISE_SIZE];
|
||||
static int r[NOISE_SIZE];
|
||||
// LordHavoc: this is inspired by code I saw in Quake3, however I think my
|
||||
// version is much cleaner and substantially faster as well
|
||||
//
|
||||
// the following changes were made:
|
||||
// 1. for the permutation indexing (r[] array in this code) I substituted
|
||||
// the ^ operator (which never overflows) for the original addition and
|
||||
// masking code, this should not have any effect on quality.
|
||||
// 2. removed the outermost randomization array lookup.
|
||||
// (it really wasn't necessary, it's fine if X indexes the array
|
||||
// directly without permutation indexing)
|
||||
// 3. reimplemented the blending using frac[] arrays rather than a macro.
|
||||
// (the original macro read one parameter twice - not good)
|
||||
// 4. cleaned up the code by using 4 nested loops to make it read nicer
|
||||
// (but then I unrolled it completely for speed, it still looks nicer).
|
||||
if (!noisetable[0])
|
||||
{
|
||||
// noisetable is a random-ish series of float values in +/- 1 range
|
||||
for (i = 0;i < NOISE_SIZE;i++)
|
||||
noisetable[i] = (rand() / (double)RAND_MAX) * 2 - 1;
|
||||
// r is a remapping table to make each dimension of the index have different indexing behavior
|
||||
for (i = 0;i < NOISE_SIZE;i++)
|
||||
r[i] = (int)(rand() * (double)NOISE_SIZE / ((double)RAND_MAX + 1)) & NOISE_MASK;
|
||||
// that & is only needed if RAND_MAX is > the range of double, which isn't the case on most platforms
|
||||
}
|
||||
frac[0][1] = x - floor(x);index[0][0] = ((int)floor(x)) & NOISE_MASK;
|
||||
frac[1][1] = y - floor(y);index[1][0] = ((int)floor(y)) & NOISE_MASK;
|
||||
frac[2][1] = z - floor(z);index[2][0] = ((int)floor(z)) & NOISE_MASK;
|
||||
frac[3][1] = w - floor(w);index[3][0] = ((int)floor(w)) & NOISE_MASK;
|
||||
for (i = 0;i < 4;i++)
|
||||
frac[i][0] = 1 - frac[i][1];
|
||||
for (i = 0;i < 4;i++)
|
||||
index[i][1] = (index[i][0] < NOISE_SIZE - 1) ? (index[i][0] + 1) : 0;
|
||||
#if 1
|
||||
// short version
|
||||
v[0] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]]);
|
||||
v[1] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]]);
|
||||
v[2] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]]);
|
||||
v[3] = frac[1][0] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]]) + frac[1][1] * (frac[0][0] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]] + frac[0][1] * noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]]);
|
||||
return frac[3][0] * (frac[2][0] * v[0] + frac[2][1] * v[1]) + frac[3][1] * (frac[2][0] * v[2] + frac[2][1] * v[3]);
|
||||
#elif 1
|
||||
// longer version
|
||||
v[ 0] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]];
|
||||
v[ 1] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]];
|
||||
v[ 2] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]];
|
||||
v[ 3] = noisetable[r[r[r[index[3][0]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]];
|
||||
v[ 4] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]];
|
||||
v[ 5] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]];
|
||||
v[ 6] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]];
|
||||
v[ 7] = noisetable[r[r[r[index[3][0]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]];
|
||||
v[ 8] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][0]];
|
||||
v[ 9] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][0]] ^ index[0][1]];
|
||||
v[10] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][0]];
|
||||
v[11] = noisetable[r[r[r[index[3][1]] ^ index[2][0]] ^ index[1][1]] ^ index[0][1]];
|
||||
v[12] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][0]];
|
||||
v[13] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][0]] ^ index[0][1]];
|
||||
v[14] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][0]];
|
||||
v[15] = noisetable[r[r[r[index[3][1]] ^ index[2][1]] ^ index[1][1]] ^ index[0][1]];
|
||||
v[16] = frac[0][0] * v[ 0] + frac[0][1] * v[ 1];
|
||||
v[17] = frac[0][0] * v[ 2] + frac[0][1] * v[ 3];
|
||||
v[18] = frac[0][0] * v[ 4] + frac[0][1] * v[ 5];
|
||||
v[19] = frac[0][0] * v[ 6] + frac[0][1] * v[ 7];
|
||||
v[20] = frac[0][0] * v[ 8] + frac[0][1] * v[ 9];
|
||||
v[21] = frac[0][0] * v[10] + frac[0][1] * v[11];
|
||||
v[22] = frac[0][0] * v[12] + frac[0][1] * v[13];
|
||||
v[23] = frac[0][0] * v[14] + frac[0][1] * v[15];
|
||||
v[24] = frac[1][0] * v[16] + frac[1][1] * v[17];
|
||||
v[25] = frac[1][0] * v[18] + frac[1][1] * v[19];
|
||||
v[26] = frac[1][0] * v[20] + frac[1][1] * v[21];
|
||||
v[27] = frac[1][0] * v[22] + frac[1][1] * v[23];
|
||||
v[28] = frac[2][0] * v[24] + frac[2][1] * v[25];
|
||||
v[29] = frac[2][0] * v[26] + frac[2][1] * v[27];
|
||||
return frac[3][0] * v[28] + frac[3][1] * v[29];
|
||||
#else
|
||||
// the algorithm...
|
||||
for (l = 0;l < 2;l++)
|
||||
{
|
||||
for (k = 0;k < 2;k++)
|
||||
{
|
||||
for (j = 0;j < 2;j++)
|
||||
{
|
||||
for (i = 0;i < 2;i++)
|
||||
v[l][k][j][i] = noisetable[r[r[r[index[l][3]] ^ index[k][2]] ^ index[j][1]] ^ index[i][0]];
|
||||
v[l][k][j][2] = frac[0][0] * v[l][k][j][0] + frac[0][1] * v[l][k][j][1];
|
||||
}
|
||||
v[l][k][2][2] = frac[1][0] * v[l][k][0][2] + frac[1][1] * v[l][k][1][2];
|
||||
}
|
||||
v[l][2][2][2] = frac[2][0] * v[l][0][2][2] + frac[2][1] * v[l][1][2][2];
|
||||
}
|
||||
v[2][2][2][2] = frac[3][0] * v[0][2][2][2] + frac[3][1] * v[1][2][2][2];
|
||||
#endif
|
||||
}
|
3995
app/jni/fs.c
Normal file
3995
app/jni/fs.c
Normal file
File diff suppressed because it is too large
Load diff
144
app/jni/fs.h
Normal file
144
app/jni/fs.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
DarkPlaces file system
|
||||
|
||||
Copyright (C) 2003-2005 Mathieu Olivier
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef FS_H
|
||||
#define FS_H
|
||||
|
||||
|
||||
// ------ Types ------ //
|
||||
|
||||
typedef struct qfile_s qfile_t;
|
||||
|
||||
#ifdef WIN32
|
||||
//typedef long fs_offset_t; // 32bit
|
||||
typedef __int64 fs_offset_t; ///< 64bit (lots of warnings, and read/write still don't take 64bit on win64)
|
||||
#else
|
||||
typedef long long fs_offset_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ------ Variables ------ //
|
||||
|
||||
extern char fs_gamedir [MAX_OSPATH];
|
||||
extern char fs_basedir [MAX_OSPATH];
|
||||
extern char fs_userdir [MAX_OSPATH];
|
||||
|
||||
// list of active game directories (empty if not running a mod)
|
||||
#define MAX_GAMEDIRS 16
|
||||
extern int fs_numgamedirs;
|
||||
extern char fs_gamedirs[MAX_GAMEDIRS][MAX_QPATH];
|
||||
|
||||
|
||||
// ------ Main functions ------ //
|
||||
|
||||
// IMPORTANT: the file path is automatically prefixed by the current game directory for
|
||||
// each file created by FS_WriteFile, or opened in "write" or "append" mode by FS_OpenRealFile
|
||||
|
||||
qboolean FS_AddPack(const char *pakfile, qboolean *already_loaded, qboolean keep_plain_dirs); // already_loaded may be NULL if caller does not care
|
||||
const char *FS_WhichPack(const char *filename);
|
||||
void FS_CreatePath (char *path);
|
||||
int FS_SysOpenFD(const char *filepath, const char *mode, qboolean nonblocking); // uses absolute path
|
||||
qfile_t* FS_SysOpen (const char* filepath, const char* mode, qboolean nonblocking); // uses absolute path
|
||||
qfile_t* FS_OpenRealFile (const char* filepath, const char* mode, qboolean quiet);
|
||||
qfile_t* FS_OpenVirtualFile (const char* filepath, qboolean quiet);
|
||||
qfile_t* FS_FileFromData (const unsigned char *data, const size_t size, qboolean quiet);
|
||||
int FS_Close (qfile_t* file);
|
||||
void FS_RemoveOnClose(qfile_t* file);
|
||||
fs_offset_t FS_Write (qfile_t* file, const void* data, size_t datasize);
|
||||
fs_offset_t FS_Read (qfile_t* file, void* buffer, size_t buffersize);
|
||||
int FS_Print(qfile_t* file, const char *msg);
|
||||
int FS_Printf(qfile_t* file, const char* format, ...) DP_FUNC_PRINTF(2);
|
||||
int FS_VPrintf(qfile_t* file, const char* format, va_list ap);
|
||||
int FS_Getc (qfile_t* file);
|
||||
int FS_UnGetc (qfile_t* file, unsigned char c);
|
||||
int FS_Seek (qfile_t* file, fs_offset_t offset, int whence);
|
||||
fs_offset_t FS_Tell (qfile_t* file);
|
||||
fs_offset_t FS_FileSize (qfile_t* file);
|
||||
void FS_Purge (qfile_t* file);
|
||||
const char *FS_FileWithoutPath (const char *in);
|
||||
const char *FS_FileExtension (const char *in);
|
||||
int FS_CheckNastyPath (const char *path, qboolean isgamedir);
|
||||
|
||||
extern const char *const fs_checkgamedir_missing; // "(missing)"
|
||||
const char *FS_CheckGameDir(const char *gamedir); // returns NULL if nasty, fs_checkgamedir_missing (exact pointer) if missing
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[MAX_OSPATH];
|
||||
char description[8192];
|
||||
}
|
||||
gamedir_t;
|
||||
extern gamedir_t *fs_all_gamedirs; // terminated by entry with empty name
|
||||
extern int fs_all_gamedirs_count;
|
||||
|
||||
qboolean FS_ChangeGameDirs(int numgamedirs, char gamedirs[][MAX_QPATH], qboolean complain, qboolean failmissing);
|
||||
qboolean FS_IsRegisteredQuakePack(const char *name);
|
||||
int FS_CRCFile(const char *filename, size_t *filesizepointer);
|
||||
void FS_Rescan(void);
|
||||
|
||||
typedef struct fssearch_s
|
||||
{
|
||||
int numfilenames;
|
||||
char **filenames;
|
||||
// array of filenames
|
||||
char *filenamesbuffer;
|
||||
}
|
||||
fssearch_t;
|
||||
|
||||
fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet);
|
||||
void FS_FreeSearch(fssearch_t *search);
|
||||
|
||||
unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer);
|
||||
qboolean FS_WriteFileInBlocks (const char *filename, const void *const *data, const fs_offset_t *len, size_t count);
|
||||
qboolean FS_WriteFile (const char *filename, const void *data, fs_offset_t len);
|
||||
|
||||
|
||||
// ------ Other functions ------ //
|
||||
|
||||
void FS_StripExtension (const char *in, char *out, size_t size_out);
|
||||
void FS_DefaultExtension (char *path, const char *extension, size_t size_path);
|
||||
|
||||
#define FS_FILETYPE_NONE 0
|
||||
#define FS_FILETYPE_FILE 1
|
||||
#define FS_FILETYPE_DIRECTORY 2
|
||||
int FS_FileType (const char *filename); // the file can be into a package
|
||||
int FS_SysFileType (const char *filename); // only look for files outside of packages
|
||||
|
||||
qboolean FS_FileExists (const char *filename); // the file can be into a package
|
||||
qboolean FS_SysFileExists (const char *filename); // only look for files outside of packages
|
||||
|
||||
void FS_mkdir (const char *path);
|
||||
|
||||
unsigned char *FS_Deflate(const unsigned char *data, size_t size, size_t *deflated_size, int level, mempool_t *mempool);
|
||||
unsigned char *FS_Inflate(const unsigned char *data, size_t size, size_t *inflated_size, mempool_t *mempool);
|
||||
|
||||
qboolean FS_HasZlib(void);
|
||||
|
||||
void FS_Init_SelfPack(void);
|
||||
void FS_Init(void);
|
||||
void FS_Shutdown(void);
|
||||
void FS_Init_Commands(void);
|
||||
|
||||
#endif
|
1593
app/jni/ft2.c
Normal file
1593
app/jni/ft2.c
Normal file
File diff suppressed because it is too large
Load diff
81
app/jni/ft2.h
Normal file
81
app/jni/ft2.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* Header for FreeType 2 and UTF-8 encoding support for
|
||||
* DarkPlaces
|
||||
*/
|
||||
|
||||
#ifndef DP_FREETYPE2_H__
|
||||
#define DP_FREETYPE2_H__
|
||||
|
||||
//#include <sys/types.h>
|
||||
|
||||
#include "utf8lib.h"
|
||||
|
||||
/*
|
||||
* From http://www.unicode.org/Public/UNIDATA/Blocks.txt
|
||||
*
|
||||
* E000..F8FF; Private Use Area
|
||||
* F0000..FFFFF; Supplementary Private Use Area-A
|
||||
*
|
||||
* We use:
|
||||
* Range E000 - E0FF
|
||||
* Contains the non-FreeType2 version of characters.
|
||||
*/
|
||||
|
||||
typedef struct ft2_font_map_s ft2_font_map_t;
|
||||
typedef struct ft2_attachment_s ft2_attachment_t;
|
||||
#define ft2_oldstyle_map ((ft2_font_map_t*)-1)
|
||||
|
||||
typedef float ft2_kernvec[2];
|
||||
typedef struct ft2_kerning_s
|
||||
{
|
||||
ft2_kernvec kerning[256][256]; /* kerning[left char][right char] */
|
||||
} ft2_kerning_t;
|
||||
|
||||
typedef struct ft2_font_s
|
||||
{
|
||||
char name[64];
|
||||
qboolean has_kerning;
|
||||
// last requested size loaded using Font_SetSize
|
||||
float currentw;
|
||||
float currenth;
|
||||
float ascend;
|
||||
float descend;
|
||||
qboolean image_font; // only fallbacks are freetype fonts
|
||||
|
||||
// TODO: clean this up and do not expose everything.
|
||||
|
||||
const unsigned char *data; // FT2 needs it to stay
|
||||
//fs_offset_t datasize;
|
||||
void *face;
|
||||
|
||||
// an unordered array of ordered linked lists of glyph maps for a specific size
|
||||
ft2_font_map_t *font_maps[MAX_FONT_SIZES];
|
||||
int num_sizes;
|
||||
|
||||
// attachments
|
||||
size_t attachmentcount;
|
||||
ft2_attachment_t *attachments;
|
||||
|
||||
ft2_settings_t *settings;
|
||||
|
||||
// fallback mechanism
|
||||
struct ft2_font_s *next;
|
||||
} ft2_font_t;
|
||||
|
||||
void Font_CloseLibrary(void);
|
||||
void Font_Init(void);
|
||||
qboolean Font_OpenLibrary(void);
|
||||
ft2_font_t* Font_Alloc(void);
|
||||
void Font_UnloadFont(ft2_font_t *font);
|
||||
// IndexForSize suggests to change the width and height if a font size is in a reasonable range
|
||||
// for example, you render at a size of 12.4, and a font of size 12 has been loaded
|
||||
// in such a case, *outw and *outh are set to 12, which is often a good alternative size
|
||||
int Font_IndexForSize(ft2_font_t *font, float size, float *outw, float *outh);
|
||||
ft2_font_map_t *Font_MapForIndex(ft2_font_t *font, int index);
|
||||
qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt);
|
||||
qboolean Font_GetKerningForSize(ft2_font_t *font, float w, float h, Uchar left, Uchar right, float *outx, float *outy);
|
||||
qboolean Font_GetKerningForMap(ft2_font_t *font, int map_index, float w, float h, Uchar left, Uchar right, float *outx, float *outy);
|
||||
float Font_VirtualToRealSize(float sz);
|
||||
float Font_SnapTo(float val, float snapwidth);
|
||||
// since this is used on a font_map_t, let's name it FontMap_*
|
||||
ft2_font_map_t *FontMap_FindForChar(ft2_font_map_t *start, Uchar ch);
|
||||
#endif // DP_FREETYPE2_H__
|
500
app/jni/ft2_defs.h
Normal file
500
app/jni/ft2_defs.h
Normal file
|
@ -0,0 +1,500 @@
|
|||
/* FreeType 2 definitions from the freetype header mostly.
|
||||
*/
|
||||
|
||||
#ifndef FT2_DEFS_H_H__
|
||||
#define FT2_DEFS_H_H__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef __int32 FT_Int32;
|
||||
typedef unsigned __int32 FT_UInt32;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
typedef int32_t FT_Int32;
|
||||
typedef uint32_t FT_UInt32;
|
||||
#endif
|
||||
|
||||
typedef int FT_Error;
|
||||
|
||||
typedef signed char FT_Char;
|
||||
typedef unsigned char FT_Byte;
|
||||
typedef const FT_Byte *FT_Bytes;
|
||||
typedef char FT_String;
|
||||
typedef signed short FT_Short;
|
||||
typedef unsigned short FT_UShort;
|
||||
typedef signed int FT_Int;
|
||||
typedef unsigned int FT_UInt;
|
||||
typedef signed long FT_Long;
|
||||
typedef signed long FT_Fixed;
|
||||
typedef unsigned long FT_ULong;
|
||||
typedef void *FT_Pointer;
|
||||
typedef size_t FT_Offset;
|
||||
typedef signed long FT_F26Dot6;
|
||||
|
||||
typedef void *FT_Stream;
|
||||
typedef void *FT_Module;
|
||||
typedef void *FT_Library;
|
||||
typedef struct FT_FaceRec_ *FT_Face;
|
||||
typedef struct FT_CharMapRec_* FT_CharMap;
|
||||
typedef struct FT_SizeRec_* FT_Size;
|
||||
typedef struct FT_Size_InternalRec_* FT_Size_Internal;
|
||||
typedef struct FT_GlyphSlotRec_* FT_GlyphSlot;
|
||||
typedef struct FT_SubGlyphRec_* FT_SubGlyph;
|
||||
typedef struct FT_Slot_InternalRec_* FT_Slot_Internal;
|
||||
|
||||
// Taken from the freetype headers:
|
||||
typedef signed long FT_Pos;
|
||||
typedef struct FT_Vector_
|
||||
{
|
||||
FT_Pos x;
|
||||
FT_Pos y;
|
||||
} FT_Vector;
|
||||
|
||||
typedef struct FT_BBox_
|
||||
{
|
||||
FT_Pos xMin, yMin;
|
||||
FT_Pos xMax, yMax;
|
||||
} FT_BBox;
|
||||
|
||||
typedef enum FT_Pixel_Mode_
|
||||
{
|
||||
FT_PIXEL_MODE_NONE = 0,
|
||||
FT_PIXEL_MODE_MONO,
|
||||
FT_PIXEL_MODE_GRAY,
|
||||
FT_PIXEL_MODE_GRAY2,
|
||||
FT_PIXEL_MODE_GRAY4,
|
||||
FT_PIXEL_MODE_LCD,
|
||||
FT_PIXEL_MODE_LCD_V,
|
||||
FT_PIXEL_MODE_MAX /* do not remove */
|
||||
} FT_Pixel_Mode;
|
||||
typedef enum FT_Render_Mode_
|
||||
{
|
||||
FT_RENDER_MODE_NORMAL = 0,
|
||||
FT_RENDER_MODE_LIGHT,
|
||||
FT_RENDER_MODE_MONO,
|
||||
FT_RENDER_MODE_LCD,
|
||||
FT_RENDER_MODE_LCD_V,
|
||||
|
||||
FT_RENDER_MODE_MAX
|
||||
} FT_Render_Mode;
|
||||
|
||||
#define ft_pixel_mode_none FT_PIXEL_MODE_NONE
|
||||
#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO
|
||||
#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY
|
||||
#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2
|
||||
#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4
|
||||
|
||||
typedef struct FT_Bitmap_
|
||||
{
|
||||
int rows;
|
||||
int width;
|
||||
int pitch;
|
||||
unsigned char* buffer;
|
||||
short num_grays;
|
||||
char pixel_mode;
|
||||
char palette_mode;
|
||||
void* palette;
|
||||
} FT_Bitmap;
|
||||
|
||||
typedef struct FT_Outline_
|
||||
{
|
||||
short n_contours; /* number of contours in glyph */
|
||||
short n_points; /* number of points in the glyph */
|
||||
|
||||
FT_Vector* points; /* the outline's points */
|
||||
char* tags; /* the points flags */
|
||||
short* contours; /* the contour end points */
|
||||
|
||||
int flags; /* outline masks */
|
||||
} FT_Outline;
|
||||
|
||||
#define FT_OUTLINE_NONE 0x0
|
||||
#define FT_OUTLINE_OWNER 0x1
|
||||
#define FT_OUTLINE_EVEN_ODD_FILL 0x2
|
||||
#define FT_OUTLINE_REVERSE_FILL 0x4
|
||||
#define FT_OUTLINE_IGNORE_DROPOUTS 0x8
|
||||
#define FT_OUTLINE_SMART_DROPOUTS 0x10
|
||||
#define FT_OUTLINE_INCLUDE_STUBS 0x20
|
||||
|
||||
#define FT_OUTLINE_HIGH_PRECISION 0x100
|
||||
#define FT_OUTLINE_SINGLE_PASS 0x200
|
||||
|
||||
#define ft_outline_none FT_OUTLINE_NONE
|
||||
#define ft_outline_owner FT_OUTLINE_OWNER
|
||||
#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL
|
||||
#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL
|
||||
#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS
|
||||
#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION
|
||||
#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS
|
||||
|
||||
#define FT_CURVE_TAG( flag ) ( flag & 3 )
|
||||
|
||||
#define FT_CURVE_TAG_ON 1
|
||||
#define FT_CURVE_TAG_CONIC 0
|
||||
#define FT_CURVE_TAG_CUBIC 2
|
||||
|
||||
#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */
|
||||
#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */
|
||||
|
||||
#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \
|
||||
FT_CURVE_TAG_TOUCH_Y )
|
||||
|
||||
#define FT_Curve_Tag_On FT_CURVE_TAG_ON
|
||||
#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC
|
||||
#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC
|
||||
#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X
|
||||
#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y
|
||||
|
||||
typedef int
|
||||
(*FT_Outline_MoveToFunc)( const FT_Vector* to,
|
||||
void* user );
|
||||
#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc
|
||||
|
||||
typedef int
|
||||
(*FT_Outline_LineToFunc)( const FT_Vector* to,
|
||||
void* user );
|
||||
#define FT_Outline_LineTo_Func FT_Outline_LineToFunc
|
||||
|
||||
typedef int
|
||||
(*FT_Outline_ConicToFunc)( const FT_Vector* control,
|
||||
const FT_Vector* to,
|
||||
void* user );
|
||||
#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc
|
||||
|
||||
typedef int
|
||||
(*FT_Outline_CubicToFunc)( const FT_Vector* control1,
|
||||
const FT_Vector* control2,
|
||||
const FT_Vector* to,
|
||||
void* user );
|
||||
#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc
|
||||
|
||||
typedef struct FT_Outline_Funcs_
|
||||
{
|
||||
FT_Outline_MoveToFunc move_to;
|
||||
FT_Outline_LineToFunc line_to;
|
||||
FT_Outline_ConicToFunc conic_to;
|
||||
FT_Outline_CubicToFunc cubic_to;
|
||||
|
||||
int shift;
|
||||
FT_Pos delta;
|
||||
} FT_Outline_Funcs;
|
||||
|
||||
#ifndef FT_IMAGE_TAG
|
||||
#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \
|
||||
value = ( ( (unsigned long)_x1 << 24 ) | \
|
||||
( (unsigned long)_x2 << 16 ) | \
|
||||
( (unsigned long)_x3 << 8 ) | \
|
||||
(unsigned long)_x4 )
|
||||
#endif /* FT_IMAGE_TAG */
|
||||
|
||||
typedef enum FT_Glyph_Format_
|
||||
{
|
||||
FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ),
|
||||
|
||||
FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ),
|
||||
FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ),
|
||||
FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ),
|
||||
FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' )
|
||||
} FT_Glyph_Format;
|
||||
#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE
|
||||
#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE
|
||||
#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP
|
||||
#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE
|
||||
#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER
|
||||
|
||||
typedef struct FT_Glyph_Metrics_
|
||||
{
|
||||
FT_Pos width;
|
||||
FT_Pos height;
|
||||
|
||||
FT_Pos horiBearingX;
|
||||
FT_Pos horiBearingY;
|
||||
FT_Pos horiAdvance;
|
||||
|
||||
FT_Pos vertBearingX;
|
||||
FT_Pos vertBearingY;
|
||||
FT_Pos vertAdvance;
|
||||
} FT_Glyph_Metrics;
|
||||
|
||||
#define FT_EXPORT( x ) x
|
||||
|
||||
#define FT_OPEN_MEMORY 0x1
|
||||
#define FT_OPEN_STREAM 0x2
|
||||
#define FT_OPEN_PATHNAME 0x4
|
||||
#define FT_OPEN_DRIVER 0x8
|
||||
#define FT_OPEN_PARAMS 0x10
|
||||
|
||||
typedef struct FT_Parameter_
|
||||
{
|
||||
FT_ULong tag;
|
||||
FT_Pointer data;
|
||||
} FT_Parameter;
|
||||
|
||||
typedef struct FT_Open_Args_
|
||||
{
|
||||
FT_UInt flags;
|
||||
const FT_Byte* memory_base;
|
||||
FT_Long memory_size;
|
||||
FT_String* pathname;
|
||||
FT_Stream stream;
|
||||
FT_Module driver;
|
||||
FT_Int num_params;
|
||||
FT_Parameter* params;
|
||||
} FT_Open_Args;
|
||||
typedef enum FT_Size_Request_Type_
|
||||
{
|
||||
FT_SIZE_REQUEST_TYPE_NOMINAL,
|
||||
FT_SIZE_REQUEST_TYPE_REAL_DIM,
|
||||
FT_SIZE_REQUEST_TYPE_BBOX,
|
||||
FT_SIZE_REQUEST_TYPE_CELL,
|
||||
FT_SIZE_REQUEST_TYPE_SCALES,
|
||||
|
||||
FT_SIZE_REQUEST_TYPE_MAX
|
||||
|
||||
} FT_Size_Request_Type;
|
||||
typedef struct FT_Size_RequestRec_
|
||||
{
|
||||
FT_Size_Request_Type type;
|
||||
FT_Long width;
|
||||
FT_Long height;
|
||||
FT_UInt horiResolution;
|
||||
FT_UInt vertResolution;
|
||||
} FT_Size_RequestRec;
|
||||
typedef struct FT_Size_RequestRec_ *FT_Size_Request;
|
||||
|
||||
#define FT_LOAD_DEFAULT 0x0
|
||||
#define FT_LOAD_NO_SCALE 0x1
|
||||
#define FT_LOAD_NO_HINTING 0x2
|
||||
#define FT_LOAD_RENDER 0x4
|
||||
#define FT_LOAD_NO_BITMAP 0x8
|
||||
#define FT_LOAD_VERTICAL_LAYOUT 0x10
|
||||
#define FT_LOAD_FORCE_AUTOHINT 0x20
|
||||
#define FT_LOAD_CROP_BITMAP 0x40
|
||||
#define FT_LOAD_PEDANTIC 0x80
|
||||
#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 0x200
|
||||
#define FT_LOAD_NO_RECURSE 0x400
|
||||
#define FT_LOAD_IGNORE_TRANSFORM 0x800
|
||||
#define FT_LOAD_MONOCHROME 0x1000
|
||||
#define FT_LOAD_LINEAR_DESIGN 0x2000
|
||||
#define FT_LOAD_NO_AUTOHINT 0x8000U
|
||||
|
||||
#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 )
|
||||
|
||||
#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL )
|
||||
#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT )
|
||||
#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO )
|
||||
#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD )
|
||||
#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V )
|
||||
|
||||
#define FT_ENC_TAG( value, a, b, c, d ) \
|
||||
value = ( ( (FT_UInt32)(a) << 24 ) | \
|
||||
( (FT_UInt32)(b) << 16 ) | \
|
||||
( (FT_UInt32)(c) << 8 ) | \
|
||||
(FT_UInt32)(d) )
|
||||
|
||||
typedef enum FT_Encoding_
|
||||
{
|
||||
FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ),
|
||||
|
||||
FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ),
|
||||
FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ),
|
||||
|
||||
FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ),
|
||||
FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ),
|
||||
FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ),
|
||||
FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ),
|
||||
FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ),
|
||||
|
||||
/* for backwards compatibility */
|
||||
FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS,
|
||||
FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312,
|
||||
FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5,
|
||||
FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG,
|
||||
FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB,
|
||||
|
||||
FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ),
|
||||
FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ),
|
||||
FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ),
|
||||
FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ),
|
||||
|
||||
FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ),
|
||||
|
||||
FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' )
|
||||
} FT_Encoding;
|
||||
|
||||
#define ft_encoding_none FT_ENCODING_NONE
|
||||
#define ft_encoding_unicode FT_ENCODING_UNICODE
|
||||
#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL
|
||||
#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1
|
||||
#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2
|
||||
#define ft_encoding_sjis FT_ENCODING_SJIS
|
||||
#define ft_encoding_gb2312 FT_ENCODING_GB2312
|
||||
#define ft_encoding_big5 FT_ENCODING_BIG5
|
||||
#define ft_encoding_wansung FT_ENCODING_WANSUNG
|
||||
#define ft_encoding_johab FT_ENCODING_JOHAB
|
||||
|
||||
#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD
|
||||
#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT
|
||||
#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM
|
||||
#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN
|
||||
|
||||
typedef struct FT_Bitmap_Size_
|
||||
{
|
||||
FT_Short height;
|
||||
FT_Short width;
|
||||
|
||||
FT_Pos size;
|
||||
|
||||
FT_Pos x_ppem;
|
||||
FT_Pos y_ppem;
|
||||
} FT_Bitmap_Size;
|
||||
|
||||
typedef struct FT_CharMapRec_
|
||||
{
|
||||
FT_Face face;
|
||||
FT_Encoding encoding;
|
||||
FT_UShort platform_id;
|
||||
FT_UShort encoding_id;
|
||||
} FT_CharMapRec;
|
||||
|
||||
typedef void (*FT_Generic_Finalizer)(void* object);
|
||||
typedef struct FT_Generic_
|
||||
{
|
||||
void* data;
|
||||
FT_Generic_Finalizer finalizer;
|
||||
} FT_Generic;
|
||||
|
||||
typedef struct FT_Size_Metrics_
|
||||
{
|
||||
FT_UShort x_ppem; /* horizontal pixels per EM */
|
||||
FT_UShort y_ppem; /* vertical pixels per EM */
|
||||
|
||||
FT_Fixed x_scale; /* scaling values used to convert font */
|
||||
FT_Fixed y_scale; /* units to 26.6 fractional pixels */
|
||||
|
||||
FT_Pos ascender; /* ascender in 26.6 frac. pixels */
|
||||
FT_Pos descender; /* descender in 26.6 frac. pixels */
|
||||
FT_Pos height; /* text height in 26.6 frac. pixels */
|
||||
FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */
|
||||
} FT_Size_Metrics;
|
||||
|
||||
typedef struct FT_SizeRec_
|
||||
{
|
||||
FT_Face face; /* parent face object */
|
||||
FT_Generic generic; /* generic pointer for client uses */
|
||||
FT_Size_Metrics metrics; /* size metrics */
|
||||
FT_Size_Internal internal;
|
||||
} FT_SizeRec;
|
||||
|
||||
typedef struct FT_FaceRec_
|
||||
{
|
||||
FT_Long num_faces;
|
||||
FT_Long face_index;
|
||||
|
||||
FT_Long face_flags;
|
||||
FT_Long style_flags;
|
||||
|
||||
FT_Long num_glyphs;
|
||||
|
||||
FT_String* family_name;
|
||||
FT_String* style_name;
|
||||
|
||||
FT_Int num_fixed_sizes;
|
||||
FT_Bitmap_Size* available_sizes;
|
||||
|
||||
FT_Int num_charmaps;
|
||||
FT_CharMap* charmaps;
|
||||
|
||||
FT_Generic generic;
|
||||
|
||||
/*# The following member variables (down to `underline_thickness') */
|
||||
/*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */
|
||||
/*# for bitmap fonts. */
|
||||
FT_BBox bbox;
|
||||
|
||||
FT_UShort units_per_EM;
|
||||
FT_Short ascender;
|
||||
FT_Short descender;
|
||||
FT_Short height;
|
||||
|
||||
FT_Short max_advance_width;
|
||||
FT_Short max_advance_height;
|
||||
|
||||
FT_Short underline_position;
|
||||
FT_Short underline_thickness;
|
||||
|
||||
FT_GlyphSlot glyph;
|
||||
FT_Size size;
|
||||
FT_CharMap charmap;
|
||||
|
||||
/* ft2 private
|
||||
FT_Driver driver;
|
||||
FT_Memory memory;
|
||||
FT_Stream stream;
|
||||
|
||||
FT_ListRec sizes_list;
|
||||
|
||||
FT_Generic autohint;
|
||||
void* extensions;
|
||||
|
||||
FT_Face_Internal internal;
|
||||
*/
|
||||
} FT_FaceRec;
|
||||
|
||||
typedef struct FT_GlyphSlotRec_
|
||||
{
|
||||
FT_Library library;
|
||||
FT_Face face;
|
||||
FT_GlyphSlot next;
|
||||
FT_UInt reserved; /* retained for binary compatibility */
|
||||
FT_Generic generic;
|
||||
|
||||
FT_Glyph_Metrics metrics;
|
||||
FT_Fixed linearHoriAdvance;
|
||||
FT_Fixed linearVertAdvance;
|
||||
FT_Vector advance;
|
||||
|
||||
FT_Glyph_Format format;
|
||||
|
||||
FT_Bitmap bitmap;
|
||||
FT_Int bitmap_left;
|
||||
FT_Int bitmap_top;
|
||||
|
||||
FT_Outline outline;
|
||||
|
||||
FT_UInt num_subglyphs;
|
||||
FT_SubGlyph subglyphs;
|
||||
|
||||
void* control_data;
|
||||
long control_len;
|
||||
|
||||
FT_Pos lsb_delta;
|
||||
FT_Pos rsb_delta;
|
||||
|
||||
void* other;
|
||||
|
||||
FT_Slot_Internal internal;
|
||||
} FT_GlyphSlotRec;
|
||||
|
||||
#define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
|
||||
#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
|
||||
#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 )
|
||||
#define FT_FACE_FLAG_SFNT ( 1L << 3 )
|
||||
#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 )
|
||||
#define FT_FACE_FLAG_VERTICAL ( 1L << 5 )
|
||||
#define FT_FACE_FLAG_KERNING ( 1L << 6 )
|
||||
#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 )
|
||||
#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 )
|
||||
#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 )
|
||||
#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 )
|
||||
#define FT_FACE_FLAG_HINTER ( 1L << 11 )
|
||||
#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 )
|
||||
#define FT_FACE_FLAG_TRICKY ( 1L << 13 )
|
||||
|
||||
typedef enum FT_Kerning_Mode_
|
||||
{
|
||||
FT_KERNING_DEFAULT = 0,
|
||||
FT_KERNING_UNFITTED,
|
||||
FT_KERNING_UNSCALED
|
||||
} FT_Kerning_Mode;
|
||||
|
||||
#endif // FT2_DEFS_H_H__
|
64
app/jni/ft2_fontdefs.h
Normal file
64
app/jni/ft2_fontdefs.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef FT2_PRIVATE_H__
|
||||
#define FT2_PRIVATE_H__
|
||||
|
||||
// anything should work, but I recommend multiples of 8
|
||||
// since the texture size should be a power of 2
|
||||
#define FONT_CHARS_PER_LINE 16
|
||||
#define FONT_CHAR_LINES 16
|
||||
#define FONT_CHARS_PER_MAP (FONT_CHARS_PER_LINE * FONT_CHAR_LINES)
|
||||
|
||||
typedef struct glyph_slot_s
|
||||
{
|
||||
qboolean image;
|
||||
// we keep the quad coords here only currently
|
||||
// if you need other info, make Font_LoadMapForIndex fill it into this slot
|
||||
float txmin; // texture coordinate in [0,1]
|
||||
float txmax;
|
||||
float tymin;
|
||||
float tymax;
|
||||
float vxmin;
|
||||
float vxmax;
|
||||
float vymin;
|
||||
float vymax;
|
||||
float advance_x;
|
||||
float advance_y;
|
||||
} glyph_slot_t;
|
||||
|
||||
struct ft2_font_map_s
|
||||
{
|
||||
Uchar start;
|
||||
struct ft2_font_map_s *next;
|
||||
float size;
|
||||
// the actual size used in the freetype code
|
||||
// by convention, the requested size is the height of the font's bounding box.
|
||||
float intSize;
|
||||
int glyphSize;
|
||||
|
||||
cachepic_t *pic;
|
||||
qboolean static_tex;
|
||||
glyph_slot_t glyphs[FONT_CHARS_PER_MAP];
|
||||
|
||||
// contains the kerning information for the first 256 characters
|
||||
// for the other characters, we will lookup the kerning information
|
||||
ft2_kerning_t kerning;
|
||||
// safes us the trouble of calculating these over and over again
|
||||
double sfx, sfy;
|
||||
|
||||
// the width_of for the image-font, pixel-snapped for this size
|
||||
float width_of[256];
|
||||
};
|
||||
|
||||
struct ft2_attachment_s
|
||||
{
|
||||
const unsigned char *data;
|
||||
fs_offset_t size;
|
||||
};
|
||||
|
||||
//qboolean Font_LoadMapForIndex(ft2_font_t *font, Uchar _ch, ft2_font_map_t **outmap);
|
||||
qboolean Font_LoadMapForIndex(ft2_font_t *font, int map_index, Uchar _ch, ft2_font_map_t **outmap);
|
||||
|
||||
void font_start(void);
|
||||
void font_shutdown(void);
|
||||
void font_newmap(void);
|
||||
|
||||
#endif // FT2_PRIVATE_H__
|
4867
app/jni/gl_backend.c
Normal file
4867
app/jni/gl_backend.c
Normal file
File diff suppressed because it is too large
Load diff
127
app/jni/gl_backend.h
Normal file
127
app/jni/gl_backend.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
|
||||
#ifndef GL_BACKEND_H
|
||||
#define GL_BACKEND_H
|
||||
|
||||
extern r_viewport_t gl_viewport;
|
||||
extern matrix4x4_t gl_modelmatrix;
|
||||
extern matrix4x4_t gl_viewmatrix;
|
||||
extern matrix4x4_t gl_modelviewmatrix;
|
||||
extern matrix4x4_t gl_projectionmatrix;
|
||||
extern matrix4x4_t gl_modelviewprojectionmatrix;
|
||||
extern float gl_modelview16f[16];
|
||||
extern float gl_modelviewprojection16f[16];
|
||||
extern qboolean gl_modelmatrixchanged;
|
||||
|
||||
extern cvar_t gl_vbo_dynamicvertex;
|
||||
extern cvar_t gl_vbo_dynamicindex;
|
||||
|
||||
#define POLYGONELEMENTS_MAXPOINTS 258
|
||||
extern int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2)*3];
|
||||
extern unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2)*3];
|
||||
#define QUADELEMENTS_MAXQUADS 128
|
||||
extern int quadelement3i[QUADELEMENTS_MAXQUADS*6];
|
||||
extern unsigned short quadelement3s[QUADELEMENTS_MAXQUADS*6];
|
||||
|
||||
void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out);
|
||||
qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor);
|
||||
void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float x1, float y1, float x2, float y2, float zNear, float zFar, const float *nearplane);
|
||||
void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float zNear, float zFar, const float *nearplane);
|
||||
void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float zNear, const float *nearplane);
|
||||
void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane);
|
||||
void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, int border, float nearclip, float farclip, const float *nearplane);
|
||||
void R_SetViewport(const r_viewport_t *v);
|
||||
void R_GetViewport(r_viewport_t *v);
|
||||
void GL_Finish(void);
|
||||
|
||||
void GL_BlendFunc(int blendfunc1, int blendfunc2);
|
||||
void GL_BlendEquationSubtract(qboolean negated);
|
||||
void GL_DepthMask(int state);
|
||||
void GL_DepthTest(int state);
|
||||
void GL_DepthFunc(int state);
|
||||
void GL_DepthRange(float nearfrac, float farfrac);
|
||||
void R_SetStencilSeparate(qboolean enable, int writemask, int frontfail, int frontzfail, int frontzpass, int backfail, int backzfail, int backzpass, int frontcompare, int backcompare, int comparereference, int comparemask);
|
||||
void R_SetStencil(qboolean enable, int writemask, int fail, int zfail, int zpass, int compare, int comparereference, int comparemask);
|
||||
void GL_PolygonOffset(float planeoffset, float depthoffset);
|
||||
void GL_CullFace(int state);
|
||||
void GL_AlphaTest(int state);
|
||||
void GL_AlphaToCoverage(qboolean state);
|
||||
void GL_ColorMask(int r, int g, int b, int a);
|
||||
void GL_Color(float cr, float cg, float cb, float ca);
|
||||
void GL_ActiveTexture(unsigned int num);
|
||||
void GL_ClientActiveTexture(unsigned int num);
|
||||
void GL_Scissor(int x, int y, int width, int height);
|
||||
void GL_ScissorTest(int state);
|
||||
void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue);
|
||||
void GL_ReadPixelsBGRA(int x, int y, int width, int height, unsigned char *outpixels);
|
||||
int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4);
|
||||
void R_Mesh_DestroyFramebufferObject(int fbo);
|
||||
void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4);
|
||||
|
||||
unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **vertexstrings_list, int geometrystrings_count, const char **geometrystrings_list, int fragmentstrings_count, const char **fragmentstrings_list);
|
||||
void GL_Backend_FreeProgram(unsigned int prog);
|
||||
|
||||
extern cvar_t gl_paranoid;
|
||||
extern cvar_t gl_printcheckerror;
|
||||
|
||||
// adds console variables and registers the render module (only call from GL_Init)
|
||||
void gl_backend_init(void);
|
||||
|
||||
// starts mesh rendering for the frame
|
||||
void R_Mesh_Start(void);
|
||||
|
||||
// ends mesh rendering for the frame
|
||||
// (only valid after R_Mesh_Start)
|
||||
void R_Mesh_Finish(void);
|
||||
|
||||
|
||||
// vertex buffer and index buffer creation/updating/freeing
|
||||
r_meshbuffer_t *R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qboolean isindexbuffer, qboolean isuniformbuffer, qboolean isdynamic, qboolean isindex16);
|
||||
void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size, qboolean subdata, size_t offset);
|
||||
void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer);
|
||||
void GL_Mesh_ListVBOs(qboolean printeach);
|
||||
|
||||
void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *buffer, int bufferoffset);
|
||||
|
||||
r_vertexgeneric_t *R_Mesh_PrepareVertices_Generic_Lock(int numvertices);
|
||||
qboolean R_Mesh_PrepareVertices_Generic_Unlock(void);
|
||||
void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f);
|
||||
void R_Mesh_PrepareVertices_Generic(int numvertices, const r_vertexgeneric_t *vertex, const r_meshbuffer_t *vertexbuffer, int bufferoffset);
|
||||
|
||||
r_vertexmesh_t *R_Mesh_PrepareVertices_Mesh_Lock(int numvertices);
|
||||
qboolean R_Mesh_PrepareVertices_Mesh_Unlock(void); // if this returns false, you need to prepare the mesh again!
|
||||
void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *color4f, const float *texcoordtexture2f, const float *texcoordlightmap2f);
|
||||
void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, const r_meshbuffer_t *buffer, int bufferoffset);
|
||||
|
||||
// sets up the requested vertex transform matrix
|
||||
void R_EntityMatrix(const matrix4x4_t *matrix);
|
||||
// sets the vertex array pointer
|
||||
void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset);
|
||||
// sets the color array pointer (GL_Color only works when this is NULL)
|
||||
void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset);
|
||||
// sets the texcoord array pointer for an array unit, if GL_UNSIGNED_BYTE | 0x80000000 is specified it will be an unnormalized type (integer values)
|
||||
void R_Mesh_TexCoordPointer(unsigned int unitnum, int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset);
|
||||
// returns current texture bound to this identifier
|
||||
int R_Mesh_TexBound(unsigned int unitnum, int id);
|
||||
// copies a section of the framebuffer to a 2D texture
|
||||
void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height);
|
||||
// bind a given texture to a given image unit
|
||||
void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex);
|
||||
// sets the texcoord matrix for a texenv unit, can be NULL or blank (will use identity)
|
||||
void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix);
|
||||
// sets the combine state for a texenv unit
|
||||
void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale);
|
||||
// set up a blank texture state (unbinds all textures, texcoord pointers, and resets combine settings)
|
||||
void R_Mesh_ResetTextureState(void);
|
||||
// before a texture is freed, make sure there are no references to it
|
||||
void R_Mesh_ClearBindingsForTexture(int texnum);
|
||||
|
||||
// renders a mesh
|
||||
void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, int element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, int element3s_bufferoffset);
|
||||
|
||||
// saves a section of the rendered frame to a .tga or .jpg file
|
||||
qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean png, qboolean gammacorrect, qboolean keep_alpha);
|
||||
// used by R_Envmap_f and internally in backend, clears the frame
|
||||
void R_ClearScreen(qboolean fogcolor);
|
||||
|
||||
#endif
|
||||
|
2268
app/jni/gl_draw.c
Normal file
2268
app/jni/gl_draw.c
Normal file
File diff suppressed because it is too large
Load diff
12691
app/jni/gl_rmain.c
Normal file
12691
app/jni/gl_rmain.c
Normal file
File diff suppressed because it is too large
Load diff
1645
app/jni/gl_rsurf.c
Normal file
1645
app/jni/gl_rsurf.c
Normal file
File diff suppressed because it is too large
Load diff
2983
app/jni/gl_textures.c
Normal file
2983
app/jni/gl_textures.c
Normal file
File diff suppressed because it is too large
Load diff
1347
app/jni/glquake.h
Normal file
1347
app/jni/glquake.h
Normal file
File diff suppressed because it is too large
Load diff
61
app/jni/hmac.c
Normal file
61
app/jni/hmac.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "quakedef.h"
|
||||
#include "hmac.h"
|
||||
|
||||
qboolean hmac(
|
||||
hashfunc_t hfunc, int hlen, int hblock,
|
||||
unsigned char *out,
|
||||
const unsigned char *in, int n,
|
||||
const unsigned char *key, int k
|
||||
)
|
||||
{
|
||||
unsigned char hashbuf[32];
|
||||
unsigned char k_xor_ipad[128];
|
||||
unsigned char k_xor_opad[128];
|
||||
unsigned char *catbuf;
|
||||
int i;
|
||||
|
||||
if(sizeof(hashbuf) < (size_t) hlen)
|
||||
return false;
|
||||
if(sizeof(k_xor_ipad) < (size_t) hblock)
|
||||
return false;
|
||||
if(sizeof(k_xor_ipad) < (size_t) hlen)
|
||||
return false;
|
||||
|
||||
catbuf = (unsigned char *)Mem_Alloc(tempmempool, (size_t) hblock + max((size_t) hlen, (size_t) n));
|
||||
|
||||
if(k > hblock)
|
||||
{
|
||||
// hash the key if it is too long
|
||||
hfunc(k_xor_opad, key, k);
|
||||
key = k_xor_opad;
|
||||
k = hlen;
|
||||
}
|
||||
|
||||
if(k < hblock)
|
||||
{
|
||||
// zero pad the key if it is too short
|
||||
if(key != k_xor_opad)
|
||||
memcpy(k_xor_opad, key, k);
|
||||
for(i = k; i < hblock; ++i)
|
||||
k_xor_opad[i] = 0;
|
||||
key = k_xor_opad;
|
||||
k = hblock;
|
||||
}
|
||||
|
||||
for(i = 0; i < hblock; ++i)
|
||||
{
|
||||
k_xor_ipad[i] = key[i] ^ 0x36;
|
||||
k_xor_opad[i] = key[i] ^ 0x5c;
|
||||
}
|
||||
|
||||
memcpy(catbuf, k_xor_ipad, hblock);
|
||||
memcpy(catbuf + hblock, in, n);
|
||||
hfunc(hashbuf, catbuf, hblock + n);
|
||||
memcpy(catbuf, k_xor_opad, hblock);
|
||||
memcpy(catbuf + hblock, hashbuf, hlen);
|
||||
hfunc(out, catbuf, hblock + hlen);
|
||||
|
||||
Mem_Free(catbuf);
|
||||
|
||||
return true;
|
||||
}
|
15
app/jni/hmac.h
Normal file
15
app/jni/hmac.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef HMAC_H
|
||||
#define HMAC_H
|
||||
|
||||
typedef void (*hashfunc_t) (unsigned char *out, const unsigned char *in, int n);
|
||||
qboolean hmac(
|
||||
hashfunc_t hfunc, int hlen, int hblock,
|
||||
unsigned char *out,
|
||||
const unsigned char *in, int n,
|
||||
const unsigned char *key, int k
|
||||
);
|
||||
|
||||
#define HMAC_MDFOUR_16BYTES(out, in, n, key, k) hmac(mdfour, 16, 64, out, in, n, key, k)
|
||||
#define HMAC_SHA256_32BYTES(out, in, n, key, k) hmac(sha256, 32, 64, out, in, n, key, k)
|
||||
|
||||
#endif
|
1460
app/jni/host.c
Normal file
1460
app/jni/host.c
Normal file
File diff suppressed because it is too large
Load diff
3051
app/jni/host_cmd.c
Normal file
3051
app/jni/host_cmd.c
Normal file
File diff suppressed because it is too large
Load diff
1588
app/jni/image.c
Normal file
1588
app/jni/image.c
Normal file
File diff suppressed because it is too large
Load diff
62
app/jni/image.h
Normal file
62
app/jni/image.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
|
||||
#ifndef IMAGE_H
|
||||
#define IMAGE_H
|
||||
|
||||
extern int image_width, image_height;
|
||||
|
||||
|
||||
// swizzle components (even converting number of components) and flip images
|
||||
// (warning: input must be different than output due to non-linear read/write)
|
||||
// (tip: component indices can contain values | 0x80000000 to tell it to
|
||||
// store them directly into output, so 255 | 0x80000000 would write 255)
|
||||
void Image_CopyMux(unsigned char *outpixels, const unsigned char *inpixels, int inputwidth, int inputheight, qboolean inputflipx, qboolean inputflipy, qboolean inputflipdiagonal, int numoutputcomponents, int numinputcomponents, int *outputinputcomponentindices);
|
||||
|
||||
// applies gamma correction to RGB pixels, in can be the same as out
|
||||
void Image_GammaRemapRGB(const unsigned char *in, unsigned char *out, int pixels, const unsigned char *gammar, const unsigned char *gammag, const unsigned char *gammab);
|
||||
|
||||
// converts 8bit image data to BGRA, in can not be the same as out
|
||||
void Image_Copy8bitBGRA(const unsigned char *in, unsigned char *out, int pixels, const unsigned int *pal);
|
||||
|
||||
void Image_StripImageExtension (const char *in, char *out, size_t size_out);
|
||||
|
||||
// called by conchars.tga loader in gl_draw.c, otherwise private
|
||||
unsigned char *LoadTGA_BGRA (const unsigned char *f, int filesize, int *miplevel);
|
||||
|
||||
// loads a texture, as pixel data
|
||||
unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qboolean allowFixtrans, qboolean convertsRGB, int *miplevel);
|
||||
|
||||
// loads an 8bit pcx image into a 296x194x8bit buffer, with cropping as needed
|
||||
qboolean LoadPCX_QWSkin(const unsigned char *f, int filesize, unsigned char *pixels, int outwidth, int outheight);
|
||||
|
||||
// loads a texture, as a texture
|
||||
rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, qboolean complain, int flags, qboolean allowFixtrans, qboolean sRGB);
|
||||
|
||||
// writes an upside down BGR image into a TGA
|
||||
qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data);
|
||||
|
||||
// writes a BGRA image into a TGA file
|
||||
qboolean Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data);
|
||||
|
||||
// resizes the image (in can not be the same as out)
|
||||
void Image_Resample32(const void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int quality);
|
||||
|
||||
// scales the image down by a power of 2 (in can be the same as out)
|
||||
void Image_MipReduce32(const unsigned char *in, unsigned char *out, int *width, int *height, int *depth, int destwidth, int destheight, int destdepth);
|
||||
|
||||
void Image_HeightmapToNormalmap_BGRA(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale);
|
||||
|
||||
// console command to fix the colors of transparent pixels (to prevent weird borders)
|
||||
void Image_FixTransparentPixels_f(void);
|
||||
extern cvar_t r_fixtrans_auto;
|
||||
|
||||
#define Image_LinearFloatFromsRGBFloat(c) (((c) <= 0.04045f) ? (c) * (1.0f / 12.92f) : (float)pow(((c) + 0.055f)*(1.0f/1.055f), 2.4f))
|
||||
#define Image_sRGBFloatFromLinearFloat(c) (((c) < 0.0031308f) ? (c) * 12.92f : 1.055f * (float)pow((c), 1.0f/2.4f) - 0.055f)
|
||||
#define Image_LinearFloatFromsRGB(c) Image_LinearFloatFromsRGBFloat((c) * (1.0f / 255.0f))
|
||||
#define Image_sRGBFloatFromLinear(c) Image_sRGBFloatFromLinearFloat((c) * (1.0f / 255.0f))
|
||||
#define Image_sRGBFloatFromLinear_Lightmap(c) Image_sRGBFloatFromLinearFloat((c) * (2.0f / 255.0f)) * 0.5f
|
||||
|
||||
void Image_MakeLinearColorsFromsRGB(unsigned char *pout, const unsigned char *pin, int numpixels);
|
||||
void Image_MakesRGBColorsFromLinear_Lightmap(unsigned char *pout, const unsigned char *pin, int numpixels);
|
||||
|
||||
#endif
|
||||
|
559
app/jni/image_png.c
Normal file
559
app/jni/image_png.c
Normal file
|
@ -0,0 +1,559 @@
|
|||
/*
|
||||
Copyright (C) 2006 Serge "(515)" Ziryukin, Forest "LordHavoc" Hale
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
//[515]: png implemented into DP ONLY FOR TESTING 2d stuff with csqc
|
||||
// so delete this bullshit :D
|
||||
//
|
||||
//LordHavoc: rewrote most of this.
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "image.h"
|
||||
#include "image_png.h"
|
||||
|
||||
|
||||
static void (*qpng_set_sig_bytes) (void*, int);
|
||||
static int (*qpng_sig_cmp) (const unsigned char*, size_t, size_t);
|
||||
static void* (*qpng_create_read_struct) (const char*, void*, void(*)(void *png, const char *message), void(*)(void *png, const char *message));
|
||||
static void* (*qpng_create_write_struct) (const char*, void*, void(*)(void *png, const char *message), void(*)(void *png, const char *message));
|
||||
static void* (*qpng_create_info_struct) (void*);
|
||||
static void (*qpng_read_info) (void*, void*);
|
||||
static void (*qpng_set_compression_level) (void*, int);
|
||||
static void (*qpng_set_filter) (void*, int, int);
|
||||
static void (*qpng_set_expand) (void*);
|
||||
static void (*qpng_set_palette_to_rgb) (void*);
|
||||
static void (*qpng_set_tRNS_to_alpha) (void*);
|
||||
static void (*qpng_set_gray_to_rgb) (void*);
|
||||
static void (*qpng_set_filler) (void*, unsigned int, int);
|
||||
static void (*qpng_set_IHDR) (void*, void*, unsigned long, unsigned long, int, int, int, int, int);
|
||||
static void (*qpng_set_packing) (void*);
|
||||
static void (*qpng_set_bgr) (void*);
|
||||
static int (*qpng_set_interlace_handling) (void*);
|
||||
static void (*qpng_read_update_info) (void*, void*);
|
||||
static void (*qpng_read_image) (void*, unsigned char**);
|
||||
static void (*qpng_read_end) (void*, void*);
|
||||
static void (*qpng_destroy_read_struct) (void**, void**, void**);
|
||||
static void (*qpng_destroy_write_struct) (void**, void**);
|
||||
static void (*qpng_set_read_fn) (void*, void*, void(*)(void *png, unsigned char *data, size_t length));
|
||||
static void (*qpng_set_write_fn) (void*, void*, void(*)(void *png, unsigned char *data, size_t length), void(*)(void *png));
|
||||
static unsigned int (*qpng_get_valid) (void*, void*, unsigned int);
|
||||
static unsigned int (*qpng_get_rowbytes) (void*, void*);
|
||||
static unsigned char (*qpng_get_channels) (void*, void*);
|
||||
static unsigned char (*qpng_get_bit_depth) (void*, void*);
|
||||
static unsigned int (*qpng_get_IHDR) (void*, void*, unsigned long*, unsigned long*, int *, int *, int *, int *, int *);
|
||||
static unsigned int (*qpng_access_version_number) (void); // FIXME is this return type right? It is a png_uint_32 in libpng
|
||||
static void (*qpng_write_info) (void*, void*);
|
||||
static void (*qpng_write_row) (void*, unsigned char*);
|
||||
static void (*qpng_write_end) (void*, void*);
|
||||
|
||||
// libpng 1.4+ longjmp hack
|
||||
typedef void (*qpng_longjmp_ptr) (jmp_buf, int);
|
||||
static jmp_buf* (*qpng_set_longjmp_fn) (void *, qpng_longjmp_ptr, size_t);
|
||||
#define qpng_jmpbuf_14(png_ptr) (*qpng_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf)))
|
||||
|
||||
// libpng 1.2 longjmp hack
|
||||
#define qpng_jmpbuf_12(png_ptr) (*((jmp_buf *) png_ptr))
|
||||
|
||||
// all version support
|
||||
#define qpng_jmpbuf(png_ptr) \
|
||||
(qpng_set_longjmp_fn ? qpng_jmpbuf_14(png_ptr) : qpng_jmpbuf_12(png_ptr))
|
||||
|
||||
static dllfunction_t pngfuncs[] =
|
||||
{
|
||||
{"png_set_sig_bytes", (void **) &qpng_set_sig_bytes},
|
||||
{"png_sig_cmp", (void **) &qpng_sig_cmp},
|
||||
{"png_create_read_struct", (void **) &qpng_create_read_struct},
|
||||
{"png_create_write_struct", (void **) &qpng_create_write_struct},
|
||||
{"png_create_info_struct", (void **) &qpng_create_info_struct},
|
||||
{"png_read_info", (void **) &qpng_read_info},
|
||||
{"png_set_compression_level", (void **) &qpng_set_compression_level},
|
||||
{"png_set_filter", (void **) &qpng_set_filter},
|
||||
{"png_set_expand", (void **) &qpng_set_expand},
|
||||
{"png_set_palette_to_rgb", (void **) &qpng_set_palette_to_rgb},
|
||||
{"png_set_tRNS_to_alpha", (void **) &qpng_set_tRNS_to_alpha},
|
||||
{"png_set_gray_to_rgb", (void **) &qpng_set_gray_to_rgb},
|
||||
{"png_set_filler", (void **) &qpng_set_filler},
|
||||
{"png_set_IHDR", (void **) &qpng_set_IHDR},
|
||||
{"png_set_packing", (void **) &qpng_set_packing},
|
||||
{"png_set_bgr", (void **) &qpng_set_bgr},
|
||||
{"png_set_interlace_handling", (void **) &qpng_set_interlace_handling},
|
||||
{"png_read_update_info", (void **) &qpng_read_update_info},
|
||||
{"png_read_image", (void **) &qpng_read_image},
|
||||
{"png_read_end", (void **) &qpng_read_end},
|
||||
{"png_destroy_read_struct", (void **) &qpng_destroy_read_struct},
|
||||
{"png_destroy_write_struct", (void **) &qpng_destroy_write_struct},
|
||||
{"png_set_read_fn", (void **) &qpng_set_read_fn},
|
||||
{"png_set_write_fn", (void **) &qpng_set_write_fn},
|
||||
{"png_get_valid", (void **) &qpng_get_valid},
|
||||
{"png_get_rowbytes", (void **) &qpng_get_rowbytes},
|
||||
{"png_get_channels", (void **) &qpng_get_channels},
|
||||
{"png_get_bit_depth", (void **) &qpng_get_bit_depth},
|
||||
{"png_get_IHDR", (void **) &qpng_get_IHDR},
|
||||
{"png_access_version_number", (void **) &qpng_access_version_number},
|
||||
{"png_write_info", (void **) &qpng_write_info},
|
||||
{"png_write_row", (void **) &qpng_write_row},
|
||||
{"png_write_end", (void **) &qpng_write_end},
|
||||
{NULL, NULL}
|
||||
};
|
||||
static dllfunction_t png14funcs[] =
|
||||
{
|
||||
{"png_set_longjmp_fn", (void **) &qpng_set_longjmp_fn},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
// Handle for PNG DLL
|
||||
dllhandle_t png_dll = NULL;
|
||||
dllhandle_t png14_dll = NULL;
|
||||
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
DLL load & unload
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
====================
|
||||
PNG_OpenLibrary
|
||||
|
||||
Try to load the PNG DLL
|
||||
====================
|
||||
*/
|
||||
qboolean PNG_OpenLibrary (void)
|
||||
{
|
||||
const char* dllnames [] =
|
||||
{
|
||||
#if WIN32
|
||||
"libpng16.dll",
|
||||
"libpng16-16.dll",
|
||||
"libpng15-15.dll",
|
||||
"libpng15.dll",
|
||||
"libpng14-14.dll",
|
||||
"libpng14.dll",
|
||||
"libpng12.dll",
|
||||
#elif defined(MACOSX)
|
||||
"libpng16.16.dylib",
|
||||
"libpng15.15.dylib",
|
||||
"libpng14.14.dylib",
|
||||
"libpng12.0.dylib",
|
||||
#else
|
||||
"libpng16.so.16",
|
||||
"libpng15.so.15", // WTF libtool guidelines anyone?
|
||||
"libpng14.so.14", // WTF libtool guidelines anyone?
|
||||
"libpng12.so.0",
|
||||
"libpng.so", // FreeBSD
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
// Already loaded?
|
||||
if (png_dll)
|
||||
return true;
|
||||
|
||||
// Load the DLL
|
||||
if(!Sys_LoadLibrary (dllnames, &png_dll, pngfuncs))
|
||||
return false;
|
||||
if(qpng_access_version_number() / 100 >= 104)
|
||||
if(!Sys_LoadLibrary (dllnames, &png14_dll, png14funcs))
|
||||
{
|
||||
Sys_UnloadLibrary (&png_dll);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
PNG_CloseLibrary
|
||||
|
||||
Unload the PNG DLL
|
||||
====================
|
||||
*/
|
||||
void PNG_CloseLibrary (void)
|
||||
{
|
||||
Sys_UnloadLibrary (&png14_dll);
|
||||
Sys_UnloadLibrary (&png_dll);
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PNG decompression
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
#define PNG_LIBPNG_VER_STRING_12 "1.2.4"
|
||||
#define PNG_LIBPNG_VER_STRING_14 "1.4.0"
|
||||
#define PNG_LIBPNG_VER_STRING_15 "1.5.0"
|
||||
#define PNG_LIBPNG_VER_STRING_16 "1.6.0"
|
||||
|
||||
#define PNG_COLOR_MASK_PALETTE 1
|
||||
#define PNG_COLOR_MASK_COLOR 2
|
||||
#define PNG_COLOR_MASK_ALPHA 4
|
||||
|
||||
#define PNG_COLOR_TYPE_GRAY 0
|
||||
#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
|
||||
#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
|
||||
#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
|
||||
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
|
||||
|
||||
#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
|
||||
#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
|
||||
|
||||
#define PNG_INFO_tRNS 0x0010
|
||||
|
||||
// this struct is only used for status information during loading
|
||||
static struct
|
||||
{
|
||||
const unsigned char *tmpBuf;
|
||||
int tmpBuflength;
|
||||
int tmpi;
|
||||
//int FBgColor;
|
||||
//int FTransparent;
|
||||
unsigned int FRowBytes;
|
||||
//double FGamma;
|
||||
//double FScreenGamma;
|
||||
unsigned char **FRowPtrs;
|
||||
unsigned char *Data;
|
||||
//char *Title;
|
||||
//char *Author;
|
||||
//char *Description;
|
||||
int BitDepth;
|
||||
int BytesPerPixel;
|
||||
int ColorType;
|
||||
unsigned long Height; // retarded libpng 1.2 pngconf.h uses long (64bit/32bit depending on arch)
|
||||
unsigned long Width; // retarded libpng 1.2 pngconf.h uses long (64bit/32bit depending on arch)
|
||||
int Interlace;
|
||||
int Compression;
|
||||
int Filter;
|
||||
//double LastModified;
|
||||
//int Transparent;
|
||||
qfile_t *outfile;
|
||||
} my_png;
|
||||
|
||||
//LordHavoc: removed __cdecl prefix, added overrun protection, and rewrote this to be more efficient
|
||||
static void PNG_fReadData(void *png, unsigned char *data, size_t length)
|
||||
{
|
||||
size_t l;
|
||||
l = my_png.tmpBuflength - my_png.tmpi;
|
||||
if (l < length)
|
||||
{
|
||||
Con_Printf("PNG_fReadData: overrun by %i bytes\n", (int)(length - l));
|
||||
// a read going past the end of the file, fill in the remaining bytes
|
||||
// with 0 just to be consistent
|
||||
memset(data + l, 0, length - l);
|
||||
length = l;
|
||||
}
|
||||
memcpy(data, my_png.tmpBuf + my_png.tmpi, length);
|
||||
my_png.tmpi += (int)length;
|
||||
//Com_HexDumpToConsole(data, (int)length);
|
||||
}
|
||||
|
||||
static void PNG_fWriteData(void *png, unsigned char *data, size_t length)
|
||||
{
|
||||
FS_Write(my_png.outfile, data, length);
|
||||
}
|
||||
|
||||
static void PNG_fFlushData(void *png)
|
||||
{
|
||||
}
|
||||
|
||||
static void PNG_error_fn(void *png, const char *message)
|
||||
{
|
||||
Con_Printf("PNG_LoadImage: error: %s\n", message);
|
||||
}
|
||||
|
||||
static void PNG_warning_fn(void *png, const char *message)
|
||||
{
|
||||
Con_Printf("PNG_LoadImage: warning: %s\n", message);
|
||||
}
|
||||
|
||||
unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize, int *miplevel)
|
||||
{
|
||||
unsigned int c;
|
||||
unsigned int y;
|
||||
void *png, *pnginfo;
|
||||
unsigned char *imagedata = NULL;
|
||||
unsigned char ioBuffer[8192];
|
||||
|
||||
// FIXME: register an error handler so that abort() won't be called on error
|
||||
|
||||
// No DLL = no PNGs
|
||||
if (!png_dll)
|
||||
return NULL;
|
||||
|
||||
if(qpng_sig_cmp(raw, 0, filesize))
|
||||
return NULL;
|
||||
png = (void *)qpng_create_read_struct(
|
||||
(qpng_access_version_number() / 100 == 102) ? PNG_LIBPNG_VER_STRING_12 :
|
||||
(qpng_access_version_number() / 100 == 104) ? PNG_LIBPNG_VER_STRING_14 :
|
||||
(qpng_access_version_number() / 100 == 105) ? PNG_LIBPNG_VER_STRING_15 :
|
||||
PNG_LIBPNG_VER_STRING_16, // nasty hack... whatever
|
||||
0, PNG_error_fn, PNG_warning_fn
|
||||
);
|
||||
if(!png)
|
||||
return NULL;
|
||||
|
||||
// this must be memset before the setjmp error handler, because it relies
|
||||
// on the fields in this struct for cleanup
|
||||
memset(&my_png, 0, sizeof(my_png));
|
||||
|
||||
// NOTE: this relies on jmp_buf being the first thing in the png structure
|
||||
// created by libpng! (this is correct for libpng 1.2.x)
|
||||
if (setjmp(qpng_jmpbuf(png)))
|
||||
{
|
||||
if (my_png.Data)
|
||||
Mem_Free(my_png.Data);
|
||||
my_png.Data = NULL;
|
||||
if (my_png.FRowPtrs)
|
||||
Mem_Free(my_png.FRowPtrs);
|
||||
my_png.FRowPtrs = NULL;
|
||||
qpng_destroy_read_struct(&png, &pnginfo, 0);
|
||||
return NULL;
|
||||
}
|
||||
//
|
||||
|
||||
pnginfo = qpng_create_info_struct(png);
|
||||
if(!pnginfo)
|
||||
{
|
||||
qpng_destroy_read_struct(&png, &pnginfo, 0);
|
||||
return NULL;
|
||||
}
|
||||
qpng_set_sig_bytes(png, 0);
|
||||
|
||||
my_png.tmpBuf = raw;
|
||||
my_png.tmpBuflength = filesize;
|
||||
my_png.tmpi = 0;
|
||||
//my_png.Data = NULL;
|
||||
//my_png.FRowPtrs = NULL;
|
||||
//my_png.Height = 0;
|
||||
//my_png.Width = 0;
|
||||
my_png.ColorType = PNG_COLOR_TYPE_RGB;
|
||||
//my_png.Interlace = 0;
|
||||
//my_png.Compression = 0;
|
||||
//my_png.Filter = 0;
|
||||
qpng_set_read_fn(png, ioBuffer, PNG_fReadData);
|
||||
qpng_read_info(png, pnginfo);
|
||||
qpng_get_IHDR(png, pnginfo, &my_png.Width, &my_png.Height,&my_png.BitDepth, &my_png.ColorType, &my_png.Interlace, &my_png.Compression, &my_png.Filter);
|
||||
|
||||
// this check guards against pngconf.h with unsigned int *width/height parameters on big endian systems by detecting the strange values and shifting them down 32bits
|
||||
// (if it's little endian the unwritten bytes are the most significant
|
||||
// ones and we don't worry about that)
|
||||
//
|
||||
// this is only necessary because of retarded 64bit png_uint_32 types in libpng 1.2, which can (conceivably) vary by platform
|
||||
#if LONG_MAX > 4000000000
|
||||
if (my_png.Width > LONG_MAX || my_png.Height > LONG_MAX)
|
||||
{
|
||||
my_png.Width >>= 32;
|
||||
my_png.Height >>= 32;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (my_png.ColorType == PNG_COLOR_TYPE_PALETTE)
|
||||
qpng_set_palette_to_rgb(png);
|
||||
if (my_png.ColorType == PNG_COLOR_TYPE_GRAY || my_png.ColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
qpng_set_gray_to_rgb(png);
|
||||
if (qpng_get_valid(png, pnginfo, PNG_INFO_tRNS))
|
||||
qpng_set_tRNS_to_alpha(png);
|
||||
if (my_png.BitDepth == 8 && !(my_png.ColorType & PNG_COLOR_MASK_ALPHA))
|
||||
qpng_set_filler(png, 255, 1);
|
||||
if (( my_png.ColorType == PNG_COLOR_TYPE_GRAY) || (my_png.ColorType == PNG_COLOR_TYPE_GRAY_ALPHA ))
|
||||
qpng_set_gray_to_rgb(png);
|
||||
if (my_png.BitDepth < 8)
|
||||
qpng_set_expand(png);
|
||||
|
||||
qpng_read_update_info(png, pnginfo);
|
||||
|
||||
my_png.FRowBytes = qpng_get_rowbytes(png, pnginfo);
|
||||
my_png.BytesPerPixel = qpng_get_channels(png, pnginfo);
|
||||
|
||||
my_png.FRowPtrs = (unsigned char **)Mem_Alloc(tempmempool, my_png.Height * sizeof(*my_png.FRowPtrs));
|
||||
if (my_png.FRowPtrs)
|
||||
{
|
||||
imagedata = (unsigned char *)Mem_Alloc(tempmempool, my_png.Height * my_png.FRowBytes);
|
||||
if(imagedata)
|
||||
{
|
||||
my_png.Data = imagedata;
|
||||
for(y = 0;y < my_png.Height;y++)
|
||||
my_png.FRowPtrs[y] = my_png.Data + y * my_png.FRowBytes;
|
||||
qpng_read_image(png, my_png.FRowPtrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("PNG_LoadImage : not enough memory\n");
|
||||
qpng_destroy_read_struct(&png, &pnginfo, 0);
|
||||
Mem_Free(my_png.FRowPtrs);
|
||||
return NULL;
|
||||
}
|
||||
Mem_Free(my_png.FRowPtrs);
|
||||
my_png.FRowPtrs = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("PNG_LoadImage : not enough memory\n");
|
||||
qpng_destroy_read_struct(&png, &pnginfo, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qpng_read_end(png, pnginfo);
|
||||
qpng_destroy_read_struct(&png, &pnginfo, 0);
|
||||
|
||||
image_width = (int)my_png.Width;
|
||||
image_height = (int)my_png.Height;
|
||||
|
||||
if (my_png.BitDepth != 8)
|
||||
{
|
||||
Con_Printf ("PNG_LoadImage : bad color depth\n");
|
||||
Mem_Free(imagedata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// swizzle RGBA to BGRA
|
||||
for (y = 0;y < (unsigned int)(image_width*image_height*4);y += 4)
|
||||
{
|
||||
c = imagedata[y+0];
|
||||
imagedata[y+0] = imagedata[y+2];
|
||||
imagedata[y+2] = c;
|
||||
}
|
||||
|
||||
return imagedata;
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PNG compression
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define PNG_INTERLACE_NONE 0
|
||||
#define PNG_INTERLACE_ADAM7 1
|
||||
#define PNG_FILTER_TYPE_BASE 0
|
||||
#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
|
||||
#define PNG_COMPRESSION_TYPE_BASE 0
|
||||
#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
|
||||
#define PNG_NO_FILTERS 0x00
|
||||
#define PNG_FILTER_NONE 0x08
|
||||
#define PNG_FILTER_SUB 0x10
|
||||
#define PNG_FILTER_UP 0x20
|
||||
#define PNG_FILTER_AVG 0x40
|
||||
#define PNG_FILTER_PAETH 0x80
|
||||
#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
|
||||
PNG_FILTER_AVG | PNG_FILTER_PAETH)
|
||||
|
||||
/*
|
||||
====================
|
||||
PNG_SaveImage_preflipped
|
||||
|
||||
Save a preflipped PNG image to a file
|
||||
====================
|
||||
*/
|
||||
qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data)
|
||||
{
|
||||
unsigned int offset, linesize;
|
||||
qfile_t* file = NULL;
|
||||
void *png, *pnginfo;
|
||||
unsigned char ioBuffer[8192];
|
||||
int passes, i, j;
|
||||
|
||||
// No DLL = no JPEGs
|
||||
if (!png_dll)
|
||||
{
|
||||
Con_Print("You need the libpng library to save PNG images\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
png = (void *)qpng_create_write_struct(
|
||||
(qpng_access_version_number() / 100 == 102) ? PNG_LIBPNG_VER_STRING_12 :
|
||||
(qpng_access_version_number() / 100 == 104) ? PNG_LIBPNG_VER_STRING_14 :
|
||||
(qpng_access_version_number() / 100 == 105) ? PNG_LIBPNG_VER_STRING_15 :
|
||||
PNG_LIBPNG_VER_STRING_16, // nasty hack... whatever
|
||||
0, PNG_error_fn, PNG_warning_fn
|
||||
);
|
||||
if(!png)
|
||||
return false;
|
||||
pnginfo = (void *)qpng_create_info_struct(png);
|
||||
if(!pnginfo)
|
||||
{
|
||||
qpng_destroy_write_struct(&png, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// this must be memset before the setjmp error handler, because it relies
|
||||
// on the fields in this struct for cleanup
|
||||
memset(&my_png, 0, sizeof(my_png));
|
||||
|
||||
// NOTE: this relies on jmp_buf being the first thing in the png structure
|
||||
// created by libpng! (this is correct for libpng 1.2.x)
|
||||
#ifdef __cplusplus
|
||||
#ifdef WIN64
|
||||
if (setjmp((_JBTYPE *)png))
|
||||
#elif defined(MACOSX) || defined(WIN32)
|
||||
if (setjmp((int *)png))
|
||||
#else
|
||||
if (setjmp((__jmp_buf_tag *)png))
|
||||
#endif
|
||||
#else
|
||||
if (setjmp(png))
|
||||
#endif
|
||||
{
|
||||
qpng_destroy_write_struct(&png, &pnginfo);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open the file
|
||||
file = FS_OpenRealFile(filename, "wb", true);
|
||||
if (!file)
|
||||
return false;
|
||||
my_png.outfile = file;
|
||||
qpng_set_write_fn(png, ioBuffer, PNG_fWriteData, PNG_fFlushData);
|
||||
|
||||
//qpng_set_compression_level(png, Z_BEST_COMPRESSION);
|
||||
qpng_set_compression_level(png, Z_BEST_SPEED);
|
||||
qpng_set_IHDR(png, pnginfo, width, height, 8, has_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
qpng_set_filter(png, 0, PNG_NO_FILTERS);
|
||||
qpng_write_info(png, pnginfo);
|
||||
qpng_set_packing(png);
|
||||
qpng_set_bgr(png);
|
||||
|
||||
passes = qpng_set_interlace_handling(png);
|
||||
|
||||
linesize = width * (has_alpha ? 4 : 3);
|
||||
offset = linesize * (height - 1);
|
||||
for(i = 0; i < passes; ++i)
|
||||
for(j = 0; j < height; ++j)
|
||||
qpng_write_row(png, &data[offset - j * linesize]);
|
||||
|
||||
qpng_write_end(png, NULL);
|
||||
qpng_destroy_write_struct(&png, &pnginfo);
|
||||
|
||||
FS_Close (file);
|
||||
|
||||
return true;
|
||||
}
|
33
app/jni/image_png.h
Normal file
33
app/jni/image_png.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright (C) 2006 Serge "(515)" Ziryukin
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PNG_H
|
||||
#define PNG_H
|
||||
|
||||
qboolean PNG_OpenLibrary (void);
|
||||
void PNG_CloseLibrary (void);
|
||||
unsigned char* PNG_LoadImage_BGRA (const unsigned char *f, int filesize, int *miplevel);
|
||||
qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data);
|
||||
|
||||
#endif
|
||||
|
53
app/jni/input.h
Normal file
53
app/jni/input.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.
|
||||
|
||||
*/
|
||||
/// \file input.h -- external (non-keyboard) input devices
|
||||
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
extern cvar_t in_pitch_min;
|
||||
extern cvar_t in_pitch_max;
|
||||
|
||||
extern qboolean in_client_mouse;
|
||||
extern float in_windowmouse_x, in_windowmouse_y;
|
||||
extern float in_mouse_x, in_mouse_y;
|
||||
|
||||
//enum input_dest_e {input_game,input_message,input_menu} input_dest;
|
||||
|
||||
void IN_Move (void);
|
||||
// add additional movement on top of the keyboard move cmd
|
||||
|
||||
#define IN_BESTWEAPON_MAX 32
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
int impulse;
|
||||
int activeweaponcode;
|
||||
int weaponbit;
|
||||
int ammostat;
|
||||
int ammomin;
|
||||
/// \TODO add a parameter for the picture to be used by the sbar, and use it there
|
||||
}
|
||||
in_bestweapon_info_t;
|
||||
extern in_bestweapon_info_t in_bestweapon_info[IN_BESTWEAPON_MAX];
|
||||
void IN_BestWeapon_ResetData(void); ///< call before each map so QC can start from a clean state
|
||||
|
||||
#endif
|
||||
|
22
app/jni/intoverflow.h
Normal file
22
app/jni/intoverflow.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef INTOVERFLOW_H
|
||||
#define INTOVERFLOW_H
|
||||
|
||||
// simple safe library to handle integer overflows when doing buffer size calculations
|
||||
// Usage:
|
||||
// - calculate data size using INTOVERFLOW_??? macros
|
||||
// - compare: calculated-size <= INTOVERFLOW_NORMALIZE(buffersize)
|
||||
// Functionality:
|
||||
// - all overflows (values > INTOVERFLOW_MAX) and errors are mapped to INTOVERFLOW_MAX
|
||||
// - if any input of an operation is INTOVERFLOW_MAX, INTOVERFLOW_MAX will be returned
|
||||
// - otherwise, regular arithmetics apply
|
||||
|
||||
#define INTOVERFLOW_MAX 2147483647
|
||||
|
||||
#define INTOVERFLOW_ADD(a,b) (((a) < INTOVERFLOW_MAX && (b) < INTOVERFLOW_MAX && (a) < INTOVERFLOW_MAX - (b)) ? ((a) + (b)) : INTOVERFLOW_MAX)
|
||||
#define INTOVERFLOW_SUB(a,b) (((a) < INTOVERFLOW_MAX && (b) < INTOVERFLOW_MAX && (b) <= (a)) ? ((a) - (b)) : INTOVERFLOW_MAX)
|
||||
#define INTOVERFLOW_MUL(a,b) (((a) < INTOVERFLOW_MAX && (b) < INTOVERFLOW_MAX && (a) < INTOVERFLOW_MAX / (b)) ? ((a) * (b)) : INTOVERFLOW_MAX)
|
||||
#define INTOVERFLOW_DIV(a,b) (((a) < INTOVERFLOW_MAX && (b) < INTOVERFLOW_MAX && (b) > 0) ? ((a) / (b)) : INTOVERFLOW_MAX)
|
||||
|
||||
#define INTOVERFLOW_NORMALIZE(a) (((a) < INTOVERFLOW_MAX) ? (a) : (INTOVERFLOW_MAX - 1))
|
||||
|
||||
#endif
|
1108
app/jni/jpeg.c
Normal file
1108
app/jni/jpeg.c
Normal file
File diff suppressed because it is too large
Load diff
39
app/jni/jpeg.h
Normal file
39
app/jni/jpeg.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright (C) 2002 Mathieu Olivier
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef JPEG_H
|
||||
#define JPEG_H
|
||||
|
||||
|
||||
qboolean JPEG_OpenLibrary (void);
|
||||
void JPEG_CloseLibrary (void);
|
||||
unsigned char* JPEG_LoadImage_BGRA (const unsigned char *f, int filesize, int *miplevel);
|
||||
qboolean JPEG_SaveImage_preflipped (const char *filename, int width, int height, unsigned char *data);
|
||||
|
||||
/*! \returns 0 if failed, or the size actually used.
|
||||
*/
|
||||
size_t JPEG_SaveImage_to_Buffer (char *jpegbuf, size_t jpegsize, int width, int height, unsigned char *data);
|
||||
qboolean Image_Compress(const char *imagename, size_t maxsize, void **buf, size_t *size);
|
||||
|
||||
|
||||
#endif
|
2003
app/jni/keys.c
Normal file
2003
app/jni/keys.c
Normal file
File diff suppressed because it is too large
Load diff
392
app/jni/keys.h
Normal file
392
app/jni/keys.h
Normal file
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
$RCSfile$
|
||||
|
||||
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:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id: keys.h 11463 2011-10-22 23:52:58Z havoc $
|
||||
*/
|
||||
|
||||
#ifndef __KEYS_H
|
||||
#define __KEYS_H
|
||||
|
||||
#include "qtypes.h"
|
||||
|
||||
//
|
||||
// these are the key numbers that should be passed to Key_Event
|
||||
//
|
||||
typedef enum keynum_e
|
||||
{
|
||||
K_TEXT = 1, // used only for unicode character input
|
||||
K_TAB = 9,
|
||||
K_ENTER = 13,
|
||||
K_ESCAPE = 27,
|
||||
K_SPACE = 32,
|
||||
|
||||
// normal keys should be passed as lowercased ascii
|
||||
|
||||
K_BACKSPACE = 127,
|
||||
K_UPARROW,
|
||||
K_DOWNARROW,
|
||||
K_LEFTARROW,
|
||||
K_RIGHTARROW,
|
||||
|
||||
K_ALT,
|
||||
K_CTRL,
|
||||
K_SHIFT,
|
||||
|
||||
K_F1,
|
||||
K_F2,
|
||||
K_F3,
|
||||
K_F4,
|
||||
K_F5,
|
||||
K_F6,
|
||||
K_F7,
|
||||
K_F8,
|
||||
K_F9,
|
||||
K_F10,
|
||||
K_F11,
|
||||
K_F12,
|
||||
|
||||
K_INS,
|
||||
K_DEL,
|
||||
K_PGDN,
|
||||
K_PGUP,
|
||||
K_HOME,
|
||||
K_END,
|
||||
|
||||
K_PAUSE,
|
||||
|
||||
K_NUMLOCK,
|
||||
K_CAPSLOCK,
|
||||
K_SCROLLOCK,
|
||||
|
||||
K_KP_0,
|
||||
K_KP_INS = K_KP_0,
|
||||
K_KP_1,
|
||||
K_KP_END = K_KP_1,
|
||||
K_KP_2,
|
||||
K_KP_DOWNARROW = K_KP_2,
|
||||
K_KP_3,
|
||||
K_KP_PGDN = K_KP_3,
|
||||
K_KP_4,
|
||||
K_KP_LEFTARROW = K_KP_4,
|
||||
K_KP_5,
|
||||
K_KP_6,
|
||||
K_KP_RIGHTARROW = K_KP_6,
|
||||
K_KP_7,
|
||||
K_KP_HOME = K_KP_7,
|
||||
K_KP_8,
|
||||
K_KP_UPARROW = K_KP_8,
|
||||
K_KP_9,
|
||||
K_KP_PGUP = K_KP_9,
|
||||
K_KP_PERIOD,
|
||||
K_KP_DEL = K_KP_PERIOD,
|
||||
K_KP_DIVIDE,
|
||||
K_KP_SLASH = K_KP_DIVIDE,
|
||||
K_KP_MULTIPLY,
|
||||
K_KP_MINUS,
|
||||
K_KP_PLUS,
|
||||
K_KP_ENTER,
|
||||
K_KP_EQUALS,
|
||||
|
||||
K_PRINTSCREEN,
|
||||
|
||||
// mouse buttons generate virtual keys
|
||||
|
||||
K_MOUSE1 = 512,
|
||||
K_OTHERDEVICESBEGIN = K_MOUSE1,
|
||||
K_MOUSE2,
|
||||
K_MOUSE3,
|
||||
K_MWHEELUP,
|
||||
K_MWHEELDOWN,
|
||||
K_MOUSE4,
|
||||
K_MOUSE5,
|
||||
K_MOUSE6,
|
||||
K_MOUSE7,
|
||||
K_MOUSE8,
|
||||
K_MOUSE9,
|
||||
K_MOUSE10,
|
||||
K_MOUSE11,
|
||||
K_MOUSE12,
|
||||
K_MOUSE13,
|
||||
K_MOUSE14,
|
||||
K_MOUSE15,
|
||||
K_MOUSE16,
|
||||
|
||||
//
|
||||
// joystick buttons
|
||||
//
|
||||
K_JOY1 = 768,
|
||||
K_JOY2,
|
||||
K_JOY3,
|
||||
K_JOY4,
|
||||
K_JOY5,
|
||||
K_JOY6,
|
||||
K_JOY7,
|
||||
K_JOY8,
|
||||
K_JOY9,
|
||||
K_JOY10,
|
||||
K_JOY11,
|
||||
K_JOY12,
|
||||
K_JOY13,
|
||||
K_JOY14,
|
||||
K_JOY15,
|
||||
K_JOY16,
|
||||
|
||||
//
|
||||
// aux keys are for multi-buttoned joysticks to generate so they can use
|
||||
// the normal binding process
|
||||
//
|
||||
K_AUX1,
|
||||
K_AUX2,
|
||||
K_AUX3,
|
||||
K_AUX4,
|
||||
K_AUX5,
|
||||
K_AUX6,
|
||||
K_AUX7,
|
||||
K_AUX8,
|
||||
K_AUX9,
|
||||
K_AUX10,
|
||||
K_AUX11,
|
||||
K_AUX12,
|
||||
K_AUX13,
|
||||
K_AUX14,
|
||||
K_AUX15,
|
||||
K_AUX16,
|
||||
K_AUX17,
|
||||
K_AUX18,
|
||||
K_AUX19,
|
||||
K_AUX20,
|
||||
K_AUX21,
|
||||
K_AUX22,
|
||||
K_AUX23,
|
||||
K_AUX24,
|
||||
K_AUX25,
|
||||
K_AUX26,
|
||||
K_AUX27,
|
||||
K_AUX28,
|
||||
K_AUX29,
|
||||
K_AUX30,
|
||||
K_AUX31,
|
||||
K_AUX32,
|
||||
|
||||
// Microsoft Xbox 360 Controller For Windows
|
||||
K_X360_DPAD_UP,
|
||||
K_X360_DPAD_DOWN,
|
||||
K_X360_DPAD_LEFT,
|
||||
K_X360_DPAD_RIGHT,
|
||||
K_X360_START,
|
||||
K_X360_BACK,
|
||||
K_X360_LEFT_THUMB,
|
||||
K_X360_RIGHT_THUMB,
|
||||
K_X360_LEFT_SHOULDER,
|
||||
K_X360_RIGHT_SHOULDER,
|
||||
K_X360_A,
|
||||
K_X360_B,
|
||||
K_X360_X,
|
||||
K_X360_Y,
|
||||
K_X360_LEFT_TRIGGER,
|
||||
K_X360_RIGHT_TRIGGER,
|
||||
K_X360_LEFT_THUMB_UP,
|
||||
K_X360_LEFT_THUMB_DOWN,
|
||||
K_X360_LEFT_THUMB_LEFT,
|
||||
K_X360_LEFT_THUMB_RIGHT,
|
||||
K_X360_RIGHT_THUMB_UP,
|
||||
K_X360_RIGHT_THUMB_DOWN,
|
||||
K_X360_RIGHT_THUMB_LEFT,
|
||||
K_X360_RIGHT_THUMB_RIGHT,
|
||||
|
||||
// generic joystick emulation for menu
|
||||
K_JOY_UP,
|
||||
K_JOY_DOWN,
|
||||
K_JOY_LEFT,
|
||||
K_JOY_RIGHT,
|
||||
|
||||
K_MIDINOTE0 = 896, // to this, the note number is added
|
||||
K_MIDINOTE1,
|
||||
K_MIDINOTE2,
|
||||
K_MIDINOTE3,
|
||||
K_MIDINOTE4,
|
||||
K_MIDINOTE5,
|
||||
K_MIDINOTE6,
|
||||
K_MIDINOTE7,
|
||||
K_MIDINOTE8,
|
||||
K_MIDINOTE9,
|
||||
K_MIDINOTE10,
|
||||
K_MIDINOTE11,
|
||||
K_MIDINOTE12,
|
||||
K_MIDINOTE13,
|
||||
K_MIDINOTE14,
|
||||
K_MIDINOTE15,
|
||||
K_MIDINOTE16,
|
||||
K_MIDINOTE17,
|
||||
K_MIDINOTE18,
|
||||
K_MIDINOTE19,
|
||||
K_MIDINOTE20,
|
||||
K_MIDINOTE21,
|
||||
K_MIDINOTE22,
|
||||
K_MIDINOTE23,
|
||||
K_MIDINOTE24,
|
||||
K_MIDINOTE25,
|
||||
K_MIDINOTE26,
|
||||
K_MIDINOTE27,
|
||||
K_MIDINOTE28,
|
||||
K_MIDINOTE29,
|
||||
K_MIDINOTE30,
|
||||
K_MIDINOTE31,
|
||||
K_MIDINOTE32,
|
||||
K_MIDINOTE33,
|
||||
K_MIDINOTE34,
|
||||
K_MIDINOTE35,
|
||||
K_MIDINOTE36,
|
||||
K_MIDINOTE37,
|
||||
K_MIDINOTE38,
|
||||
K_MIDINOTE39,
|
||||
K_MIDINOTE40,
|
||||
K_MIDINOTE41,
|
||||
K_MIDINOTE42,
|
||||
K_MIDINOTE43,
|
||||
K_MIDINOTE44,
|
||||
K_MIDINOTE45,
|
||||
K_MIDINOTE46,
|
||||
K_MIDINOTE47,
|
||||
K_MIDINOTE48,
|
||||
K_MIDINOTE49,
|
||||
K_MIDINOTE50,
|
||||
K_MIDINOTE51,
|
||||
K_MIDINOTE52,
|
||||
K_MIDINOTE53,
|
||||
K_MIDINOTE54,
|
||||
K_MIDINOTE55,
|
||||
K_MIDINOTE56,
|
||||
K_MIDINOTE57,
|
||||
K_MIDINOTE58,
|
||||
K_MIDINOTE59,
|
||||
K_MIDINOTE60,
|
||||
K_MIDINOTE61,
|
||||
K_MIDINOTE62,
|
||||
K_MIDINOTE63,
|
||||
K_MIDINOTE64,
|
||||
K_MIDINOTE65,
|
||||
K_MIDINOTE66,
|
||||
K_MIDINOTE67,
|
||||
K_MIDINOTE68,
|
||||
K_MIDINOTE69,
|
||||
K_MIDINOTE70,
|
||||
K_MIDINOTE71,
|
||||
K_MIDINOTE72,
|
||||
K_MIDINOTE73,
|
||||
K_MIDINOTE74,
|
||||
K_MIDINOTE75,
|
||||
K_MIDINOTE76,
|
||||
K_MIDINOTE77,
|
||||
K_MIDINOTE78,
|
||||
K_MIDINOTE79,
|
||||
K_MIDINOTE80,
|
||||
K_MIDINOTE81,
|
||||
K_MIDINOTE82,
|
||||
K_MIDINOTE83,
|
||||
K_MIDINOTE84,
|
||||
K_MIDINOTE85,
|
||||
K_MIDINOTE86,
|
||||
K_MIDINOTE87,
|
||||
K_MIDINOTE88,
|
||||
K_MIDINOTE89,
|
||||
K_MIDINOTE90,
|
||||
K_MIDINOTE91,
|
||||
K_MIDINOTE92,
|
||||
K_MIDINOTE93,
|
||||
K_MIDINOTE94,
|
||||
K_MIDINOTE95,
|
||||
K_MIDINOTE96,
|
||||
K_MIDINOTE97,
|
||||
K_MIDINOTE98,
|
||||
K_MIDINOTE99,
|
||||
K_MIDINOTE100,
|
||||
K_MIDINOTE101,
|
||||
K_MIDINOTE102,
|
||||
K_MIDINOTE103,
|
||||
K_MIDINOTE104,
|
||||
K_MIDINOTE105,
|
||||
K_MIDINOTE106,
|
||||
K_MIDINOTE107,
|
||||
K_MIDINOTE108,
|
||||
K_MIDINOTE109,
|
||||
K_MIDINOTE110,
|
||||
K_MIDINOTE111,
|
||||
K_MIDINOTE112,
|
||||
K_MIDINOTE113,
|
||||
K_MIDINOTE114,
|
||||
K_MIDINOTE115,
|
||||
K_MIDINOTE116,
|
||||
K_MIDINOTE117,
|
||||
K_MIDINOTE118,
|
||||
K_MIDINOTE119,
|
||||
K_MIDINOTE120,
|
||||
K_MIDINOTE121,
|
||||
K_MIDINOTE122,
|
||||
K_MIDINOTE123,
|
||||
K_MIDINOTE124,
|
||||
K_MIDINOTE125,
|
||||
K_MIDINOTE126,
|
||||
K_MIDINOTE127,
|
||||
|
||||
MAX_KEYS
|
||||
}
|
||||
keynum_t;
|
||||
|
||||
typedef enum keydest_e { key_game, key_message, key_menu, key_menu_grabbed, key_console, key_void } keydest_t;
|
||||
|
||||
extern char key_line[MAX_INPUTLINE];
|
||||
extern int key_linepos;
|
||||
extern qboolean key_insert; // insert key toggle (for editing)
|
||||
extern keydest_t key_dest;
|
||||
// key_consoleactive bits
|
||||
// user wants console (halfscreen)
|
||||
#define KEY_CONSOLEACTIVE_USER 1
|
||||
// console forced because there's nothing else active (fullscreen)
|
||||
#define KEY_CONSOLEACTIVE_FORCED 4
|
||||
extern int key_consoleactive;
|
||||
extern char *keybindings[MAX_BINDMAPS][MAX_KEYS];
|
||||
|
||||
extern int chat_mode; // 0 for say, 1 for say_team, -1 for command
|
||||
extern char chat_buffer[MAX_INPUTLINE];
|
||||
extern unsigned int chat_bufferlen;
|
||||
|
||||
void Key_ClearEditLine(int edit_line);
|
||||
void Key_WriteBindings(qfile_t *f);
|
||||
void Key_Init(void);
|
||||
void Key_Shutdown(void);
|
||||
void Key_Init_Cvars(void);
|
||||
void Key_Event(int key, int ascii, qboolean down);
|
||||
void Key_ReleaseAll (void);
|
||||
void Key_ClearStates (void); // FIXME: should this function still exist? Or should Key_ReleaseAll be used instead when shutting down a vid driver?
|
||||
void Key_EventQueue_Block(void);
|
||||
void Key_EventQueue_Unblock(void);
|
||||
|
||||
qboolean Key_SetBinding (int keynum, int bindmap, const char *binding);
|
||||
const char *Key_GetBind (int key, int bindmap);
|
||||
void Key_FindKeysForCommand (const char *command, int *keys, int numkeys, int bindmap);
|
||||
qboolean Key_SetBindMap(int fg, int bg);
|
||||
void Key_GetBindMap(int *fg, int *bg);
|
||||
|
||||
#endif // __KEYS_H
|
||||
|
106
app/jni/lhfont.h
Normal file
106
app/jni/lhfont.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x08,0x08,0x99,0x00,0x83,0xFF,0xFF,0x00,0xE1,0x00,0x99,0x00,0x83,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x89,0xFF,0x8B,0x00,0x85,0xFF,0x85,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x8B,0xFF,0x89,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x85,0xFF,0x9D,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x8A,0xFF,0x89,0x00,0x86,0xFF,0x84,0x00,0x89,0xFF,
|
||||
0x87,0x00,0x85,0xFF,0x86,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x85,0x00,0x84,0xFF,0x88,0x00,0x8B,0xFF,0x88,0x00,0x86,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x86,0xFF,0x9B,0x00,0x84,0xFF,0x85,0x00,0x81,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x84,0xFF,0x8D,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x99,0x00,0x83,0xFF,0x87,0x00,0x81,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x93,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x83,0x00,0x8B,0xFF,0x84,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x8B,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,0x87,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8D,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x87,0xFF,0x8A,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x8A,0x00,0x82,0xFF,0x8D,0x00,
|
||||
0x83,0xFF,0x8D,0x00,0x82,0xFF,0x96,0x00,0x8B,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x88,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x87,0xFF,0x89,0x00,0x85,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x84,0xFF,0x9F,0x00,0x84,0xFF,0x94,0x00,0x8B,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8D,0x00,0x89,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x8A,0x00,0x84,0xFF,0x86,0x00,0x84,0xFF,0x9F,0x00,0x84,0xFF,0x95,0x00,0x84,0xFF,0x87,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x8D,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x85,0x00,0x89,0xFF,0x8A,0x00,0x84,0xFF,
|
||||
0x87,0x00,0x82,0xFF,0x8D,0x00,0x83,0xFF,0x8D,0x00,0x82,0xFF,0x98,0x00,0x83,0xFF,0x87,0x00,0x81,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x86,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x99,0x00,0x84,0xFF,0x85,0x00,0x81,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x9B,0x00,0x83,0xFF,0x85,0x00,0xFF,0x00,0xB6,0x00,0x86,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x86,0xFF,0x86,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x93,0x00,0xFF,0x00,0xB7,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x86,0xFF,0x92,0x00,0xFF,0x00,0xE0,0x00,0x86,0xFF,0x81,0x00,0x83,0xFF,0x91,0x00,0xFF,0x00,0xE1,0x00,0x85,0xFF,
|
||||
0x81,0x00,0x83,0xFF,0x91,0x00,0xF3,0x00,0x85,0xFF,0xFF,0x00,0x85,0x00,0xF3,0x00,0x86,0xFF,0xFF,0x00,0x84,0x00,0x93,0x00,0x89,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x85,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x83,0x00,0x92,0x00,0x8A,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,
|
||||
0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x86,0x00,0x87,0xFF,0x88,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x83,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x82,0x00,0x91,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x84,0xFF,0x86,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x91,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8A,0x00,0x8A,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x00,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x81,0x00,0x92,0x00,0x8A,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x93,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x00,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x8D,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0x00,0x84,0xFF,0x90,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x87,0x00,0x8D,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x81,0x00,0x84,0x00,0x84,0xFF,0x89,0x00,0x88,0xFF,0x84,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x89,0xFF,0x84,0x00,0x83,0xFF,0x8A,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0xA4,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x88,0x00,0x8B,0xFF,0x84,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x82,0x00,0x85,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0xA5,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,
|
||||
0x87,0x00,0x87,0xFF,0x83,0x00,0x85,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0xA3,0x00,0x83,0xFF,0x94,0x00,0x86,0xFF,0x97,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x97,0x00,0x85,0xFF,0xB7,0x00,0x85,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0xA3,0x00,0x83,0xFF,0x95,0x00,0x85,0xFF,0x97,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x97,0x00,0x85,0xFF,0xB7,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x97,0x00,0x85,0xFF,0xFF,0x00,0xE1,0x00,0x96,0x00,0x86,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x83,0xFF,0x8D,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x89,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x8F,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x93,0x00,0x8D,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x8C,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8A,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x87,0x00,0x85,0xFF,0x86,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x8E,0x00,0x84,0xFF,0x83,0x00,0x87,0xFF,0x93,0x00,0x8D,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x82,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x91,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x82,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x83,0x00,0x8B,0xFF,0x84,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x84,0xFF,0x8C,0x00,0x83,0xFF,0x90,0x00,0x84,0xFF,
|
||||
0x89,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x82,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0x8F,0x00,0x84,0xFF,0x8A,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x8A,0x00,0x83,0xFF,0x8E,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x88,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x85,0xFF,0x8A,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x89,0x00,0x83,0xFF,0x8D,0x00,0x84,0xFF,0x8C,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x91,0x00,
|
||||
0x81,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x85,0xFF,0x89,0x00,0x85,0xFF,0x8A,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x8D,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x91,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x8E,0x00,0x83,0xFF,0x84,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x92,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x8A,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,
|
||||
0x8A,0x00,0x84,0xFF,0x8F,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x93,0x00,0x81,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x83,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x84,0xFF,0x8C,0x00,0x87,0xFF,0x86,0x00,0x87,0xFF,0x94,0x00,0x81,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8D,0x00,0x87,0xFF,0x87,0x00,0x85,0xFF,0x95,0x00,0xFF,0x00,0xE4,0x00,0x83,0xFF,0x96,0x00,0xFF,0x00,0xE5,0x00,0x81,0xFF,0x97,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x83,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x87,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x8B,0xFF,0x83,0x00,0x85,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x83,0x00,0x82,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x8A,0x00,0x89,0xFF,0x86,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x82,0x00,0x87,0xFF,0x88,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x82,0x00,0x81,0x00,
|
||||
0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,
|
||||
0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,
|
||||
0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x00,0x00,0x86,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x84,0x00,0x82,0xFF,0x83,0x00,0x82,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8D,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x8D,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,
|
||||
0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x85,0x00,0x81,0xFF,0x83,0x00,0x81,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8D,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x8D,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x8D,0xFF,0x83,0x00,0x86,0xFF,0x00,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x85,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x85,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x82,0x00,0x89,0xFF,0x87,0x00,0x85,0xFF,0x86,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x82,0x00,0x89,0xFF,0x86,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x82,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x82,0x00,0x83,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x89,0xFF,
|
||||
0x87,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x87,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x83,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xB3,0x00,0x83,0xFF,0xC7,0x00,0xFF,0x00,0xB3,0x00,0x84,0xFF,0xC6,0x00,0x83,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x89,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,
|
||||
0x87,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x8D,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x85,0x00,0x82,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x8A,0xFF,0x8A,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,0x8C,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x86,0x00,0x8B,0xFF,0x86,0x00,0x84,0xFF,0x95,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x8B,0xFF,0x87,0x00,0x84,0xFF,0x94,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x88,0x00,0x88,0xFF,0x89,0x00,
|
||||
0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0xA5,0x00,0x84,0xFF,0x9D,0x00,0x84,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x89,0x00,0x88,0xFF,0x88,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x84,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x8A,0xFF,0xA5,0x00,0x83,0xFF,0x9F,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x84,0x00,
|
||||
0x88,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x90,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0xA5,0x00,0x83,0xFF,0x9F,0x00,0x83,0xFF,0x89,0x00,0x85,0xFF,0x83,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0xA5,0x00,0x84,0xFF,0x9D,0x00,0x84,0xFF,0x89,0x00,0x86,0xFF,0x82,0x00,0x82,0x00,0x89,0xFF,0x86,0x00,0x85,0xFF,0x87,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x87,0x00,
|
||||
0x86,0xFF,0x85,0x00,0x8B,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x8B,0xFF,0x87,0x00,0x84,0xFF,0x8E,0x00,0x83,0xFF,0x81,0x00,0x83,0x00,0x87,0xFF,0x87,0x00,0x85,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x85,0xFF,0x85,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x86,0x00,0x8B,0xFF,0x86,0x00,0x84,0xFF,0x8F,0x00,0x83,0xFF,0x81,0x00,0xFF,0x00,0xA5,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,
|
||||
0x97,0x00,0x84,0xFF,0x88,0x00,0x8A,0xFF,0x82,0x00,0xFF,0x00,0xA5,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0x89,0x00,0x89,0xFF,0x83,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xC5,0x00,0x83,0xFF,0xB5,0x00,0xFF,0x00,0xC5,0x00,0x84,0xFF,0xB4,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x89,0x00,0x81,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x85,0xFF,0x81,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x95,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x95,0x00,0x83,0xFF,
|
||||
0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x88,0xFF,0x84,0x00,0x84,0xFF,0x84,0x00,0x83,0xFF,0x82,0x00,0x8C,0xFF,0x97,0x00,0x84,0xFF,0x87,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x95,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x8A,0x00,0xB0,0x00,0x8D,0xFF,0x83,0x00,0x89,0xFF,0x84,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,0x89,0x00,0x84,0xFF,0x89,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x95,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x89,0x00,0xB0,0x00,0x8D,0xFF,0x87,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x85,0x00,0x84,0xFF,
|
||||
0x82,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x97,0x00,0x84,0xFF,0x8B,0x00,0x84,0xFF,0x88,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x95,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x88,0x00,0x95,0x00,0x83,0xFF,0x96,0x00,0x8D,0xFF,0x87,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x86,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x96,0x00,0x84,0xFF,0x8D,0x00,0x84,0xFF,0x83,0x00,0x8F,0xFF,0x81,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x94,0x00,0x84,0xFF,0x87,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x88,0xFF,0x87,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x81,0x00,0x86,0xFF,0x95,0x00,0x83,0xFF,
|
||||
0x8F,0x00,0x83,0xFF,0x83,0x00,0x8F,0xFF,0x81,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x95,0x00,0x84,0xFF,0x86,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x88,0xFF,0x89,0x00,0x84,0xFF,0x86,0x00,0x88,0xFF,0x00,0x00,0x82,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0xBA,0x00,0x84,0xFF,0x85,0x00,0x95,0x00,0x83,0xFF,0x96,0x00,0x8D,0xFF,0x83,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x8D,0x00,0x84,0xFF,0x86,0x00,0x86,0xFF,0x82,0x00,0x81,0xFF,0x88,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0xBB,0x00,0x84,0xFF,
|
||||
0x84,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x8D,0xFF,0x83,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x87,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x86,0x00,0x86,0xFF,0x8D,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0xBC,0x00,0x84,0xFF,0x83,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x8D,0xFF,0x83,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x85,0x00,0x87,0xFF,0x8D,0x00,0x83,0xFF,0x85,0x00,0x84,0xFF,0x8D,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0xBD,0x00,0x84,0xFF,
|
||||
0x82,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x88,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x8C,0x00,0x83,0xFF,0x86,0x00,0x84,0xFF,0x8B,0x00,0x84,0xFF,0xDD,0x00,0x84,0xFF,0x81,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x89,0x00,0x81,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x8C,0x00,0x83,0xFF,0x87,0x00,0x84,0xFF,0x89,0x00,0x84,0xFF,0xDF,0x00,0x83,0xFF,0x81,0x00,0xA2,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0xB6,0x00,
|
||||
0x87,0xFF,0x9A,0x00,0x84,0xFF,0x87,0x00,0x84,0xFF,0xE6,0x00,0xA2,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0xB7,0x00,0x85,0xFF,0x9C,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0xE7,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x85,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x89,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0xC3,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x84,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,
|
||||
0x83,0x00,0x8A,0xFF,0x8A,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x88,0xFF,0x99,0x00,0xA1,0xFF,0x86,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x96,0x00,0xA5,0xFF,0x84,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x94,0x00,0xA9,0xFF,0x82,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x88,0x00,0x88,0xFF,0x89,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x89,0x00,0x88,0xFF,
|
||||
0x88,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x84,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x8A,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x90,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x84,0x00,0x89,0xFF,0x86,0x00,0x85,0xFF,0x87,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x87,0x00,0x86,0xFF,0x85,0x00,0x8B,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x95,0x00,0xA9,0xFF,0x82,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x85,0x00,0x87,0xFF,0x87,0x00,0x85,0xFF,0x87,0x00,0x89,0xFF,
|
||||
0x85,0x00,0x89,0xFF,0x89,0x00,0x85,0xFF,0x85,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x98,0x00,0xA5,0xFF,0x84,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xB8,0x00,0xA1,0xFF,0x86,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xE1,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xB2,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x97,0x00,0x85,0xFF,0xFF,0x00,0x94,0x00,0xB1,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x95,0x00,0x87,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x81,0xFF,0xAB,0x00,0x81,0x00,0xAB,0xFF,
|
||||
0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x83,0xFF,0xA9,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x85,0xFF,0xA7,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x87,0xFF,0xA5,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,
|
||||
0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,
|
||||
0x83,0xFF,0x85,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x87,0xFF,0xA5,0x00,0x82,0x00,0xA9,0xFF,0x83,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x85,0xFF,
|
||||
0xA7,0x00,0x83,0x00,0xA7,0xFF,0x84,0x00,0x8D,0xFF,0x81,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x83,0xFF,0xA9,0x00,0xB1,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x95,0x00,0x87,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x81,0xFF,0xAB,0x00,0xB2,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x97,0x00,0x85,0xFF,0xFF,0x00,0x94,0x00,0xFF,0x00,0xFF,0x00,0x99,0x00,0x83,0xFF,0xFF,0x00,0xE1,0x00,0x99,0x00,0x83,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x89,0xFF,0x8B,0x00,
|
||||
0x85,0xFF,0x85,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x8B,0xFF,0x89,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x85,0xFF,0x9D,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x8A,0xFF,0x89,0x00,0x86,0xFF,0x84,0x00,0x89,0xFF,0x87,0x00,0x85,0xFF,0x86,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x85,0x00,0x84,0xFF,0x88,0x00,0x8B,0xFF,0x88,0x00,0x86,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x86,0xFF,0x9B,0x00,0x84,0xFF,0x85,0x00,0x81,0x00,0x89,0xFF,0x87,0x00,
|
||||
0x89,0xFF,0x83,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x84,0xFF,0x8D,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x99,0x00,0x83,0xFF,0x87,0x00,0x81,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x83,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x83,0x00,0x8B,0xFF,0x84,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x8B,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,
|
||||
0x87,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8D,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x87,0xFF,0x8A,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x8A,0x00,0x82,0xFF,0x8D,0x00,0x83,0xFF,0x8D,0x00,0x82,0xFF,0x96,0x00,0x8B,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x88,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x87,0xFF,0x89,0x00,0x85,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x84,0xFF,0x9F,0x00,0x84,0xFF,0x94,0x00,0x8B,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8D,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x8A,0x00,0x84,0xFF,0x86,0x00,0x84,0xFF,0x9F,0x00,0x84,0xFF,0x95,0x00,0x84,0xFF,0x87,0x00,
|
||||
0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x8D,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x85,0x00,0x89,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x82,0xFF,0x8D,0x00,0x83,0xFF,0x8D,0x00,0x82,0xFF,0x98,0x00,0x83,0xFF,0x87,0x00,0x81,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x86,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x99,0x00,0x84,0xFF,0x85,0x00,0x81,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,
|
||||
0x8B,0x00,0x83,0xFF,0x9B,0x00,0x83,0xFF,0x85,0x00,0xFF,0x00,0xB6,0x00,0x86,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x86,0xFF,0x86,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x93,0x00,0xFF,0x00,0xB7,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x86,0xFF,0x92,0x00,0xFF,0x00,0xE0,0x00,0x86,0xFF,0x81,0x00,0x83,0xFF,0x91,0x00,0xFF,0x00,0xE1,0x00,0x85,0xFF,0x81,0x00,0x83,0xFF,0x91,0x00,0xF3,0x00,0x85,0xFF,0xFF,0x00,0x85,0x00,0xF3,0x00,0x86,0xFF,0xFF,0x00,0x84,0x00,0x93,0x00,0x89,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x85,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x83,0x00,0x92,0x00,0x8A,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x86,0x00,0x87,0xFF,0x88,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x83,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x84,0x00,0x89,0xFF,0x82,0x00,0x91,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x91,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8A,0x00,0x8A,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x00,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x92,0x00,0x8A,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x93,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x00,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x8D,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0x00,0x84,0xFF,0x90,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x85,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x87,0x00,0x8D,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x84,0x00,0x84,0xFF,0x89,0x00,0x88,0xFF,0x84,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x89,0xFF,0x84,0x00,0x83,0xFF,0x8A,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0xA4,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x85,0x00,
|
||||
0x83,0xFF,0x88,0x00,0x8B,0xFF,0x84,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x82,0x00,0x85,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0xA5,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x83,0x00,0x85,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0xA3,0x00,0x83,0xFF,0x94,0x00,0x86,0xFF,0x97,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x97,0x00,0x85,0xFF,0xB7,0x00,0x85,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0xA3,0x00,0x83,0xFF,
|
||||
0x95,0x00,0x85,0xFF,0x97,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x97,0x00,0x85,0xFF,0xB7,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x97,0x00,0x85,0xFF,0xFF,0x00,0xE1,0x00,0x96,0x00,0x86,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x83,0xFF,0x8D,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x8F,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x93,0x00,0x8D,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x8C,0x00,0x88,0xFF,
|
||||
0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8A,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x87,0x00,0x85,0xFF,0x86,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x8E,0x00,0x84,0xFF,0x83,0x00,0x87,0xFF,0x93,0x00,0x8D,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x82,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x91,0x00,
|
||||
0x84,0xFF,0x88,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x82,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x83,0x00,0x8B,0xFF,0x84,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x84,0xFF,0x8C,0x00,0x83,0xFF,0x90,0x00,0x84,0xFF,0x89,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8C,0x00,0x82,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x81,0x00,
|
||||
0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0x8F,0x00,0x84,0xFF,0x8A,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x8A,0x00,0x83,0xFF,0x8E,0x00,0x84,0xFF,0x8B,0x00,0x83,0xFF,0xA3,0x00,0x81,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x8A,0xFF,0x85,0x00,0x88,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x85,0xFF,0x8A,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x89,0x00,0x83,0xFF,0x8D,0x00,0x84,0xFF,0x8C,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x91,0x00,0x81,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,
|
||||
0x86,0x00,0x85,0xFF,0x89,0x00,0x85,0xFF,0x8A,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x8D,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x91,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x8E,0x00,0x83,0xFF,0x84,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x92,0x00,
|
||||
0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x8A,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x8F,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x93,0x00,0x81,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x8A,0xFF,0x85,0x00,0x8A,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,
|
||||
0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x81,0x00,0x84,0xFF,0x83,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x84,0xFF,0x8C,0x00,0x87,0xFF,0x86,0x00,0x87,0xFF,0x94,0x00,0x81,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x89,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8D,0x00,0x87,0xFF,
|
||||
0x87,0x00,0x85,0xFF,0x95,0x00,0xFF,0x00,0xE4,0x00,0x83,0xFF,0x96,0x00,0xFF,0x00,0xE5,0x00,0x81,0xFF,0x97,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0x83,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x87,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x85,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x83,0x00,0x82,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x83,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x8A,0x00,0x89,0xFF,0x86,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x82,0x00,0x87,0xFF,0x88,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x82,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,
|
||||
0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x81,0x00,0x81,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x00,0x00,0x86,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,
|
||||
0x85,0xFF,0x84,0x00,0x82,0xFF,0x83,0x00,0x82,0xFF,0x84,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8D,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x8D,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x85,0x00,0x81,0xFF,0x83,0x00,0x81,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8D,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,
|
||||
0x8B,0x00,0x83,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x83,0xFF,0x89,0x00,0x8D,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x8D,0xFF,0x83,0x00,0x86,0xFF,0x00,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x81,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x85,0xFF,0x81,0x00,0x85,0xFF,0x83,0x00,0x85,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x82,0x00,0x89,0xFF,0x87,0x00,0x85,0xFF,0x86,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x84,0x00,
|
||||
0x8A,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x82,0x00,0x89,0xFF,0x86,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x83,0x00,0x84,0xFF,0x82,0x00,0x83,0xFF,0x84,0x00,0x89,0xFF,0x82,0x00,0x83,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x87,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,
|
||||
0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x83,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xB3,0x00,0x83,0xFF,0xC7,0x00,0xFF,0x00,0xB3,0x00,0x84,0xFF,0xC6,0x00,0x83,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x89,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x8D,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x85,0x00,0x82,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x8A,0xFF,0x8A,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,
|
||||
0x85,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x88,0xFF,0x88,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,0x8C,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x86,0x00,0x8B,0xFF,0x86,0x00,0x84,0xFF,0x95,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,
|
||||
0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x8B,0xFF,0x87,0x00,0x84,0xFF,0x94,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x88,0x00,0x88,0xFF,0x89,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0xA5,0x00,0x84,0xFF,0x9D,0x00,0x84,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x87,0x00,0x83,0xFF,0x89,0x00,0x88,0xFF,0x88,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x84,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x8A,0xFF,0xA5,0x00,0x83,0xFF,0x9F,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x85,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x90,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0xA5,0x00,0x83,0xFF,0x9F,0x00,0x83,0xFF,0x89,0x00,0x85,0xFF,0x83,0x00,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,
|
||||
0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0xA5,0x00,0x84,0xFF,0x9D,0x00,0x84,0xFF,0x89,0x00,0x86,0xFF,0x82,0x00,0x82,0x00,0x89,0xFF,0x86,0x00,0x85,0xFF,0x87,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x87,0x00,0x86,0xFF,0x85,0x00,0x8B,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x87,0x00,0x8B,0xFF,0x87,0x00,0x84,0xFF,0x8E,0x00,0x83,0xFF,0x81,0x00,0x83,0x00,0x87,0xFF,
|
||||
0x87,0x00,0x85,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x85,0xFF,0x85,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x86,0x00,0x8B,0xFF,0x86,0x00,0x84,0xFF,0x8F,0x00,0x83,0xFF,0x81,0x00,0xFF,0x00,0xA5,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,0x88,0x00,0x8A,0xFF,0x82,0x00,0xFF,0x00,0xA5,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x97,0x00,0x83,0xFF,0x89,0x00,0x89,0xFF,0x83,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xC5,0x00,0x83,0xFF,0xB5,0x00,0xFF,0x00,
|
||||
0xC5,0x00,0x84,0xFF,0xB4,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x89,0x00,0x81,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x85,0xFF,0x81,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8C,0x00,0x84,0xFF,0x95,0x00,0x83,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x88,0xFF,0x84,0x00,0x84,0xFF,0x84,0x00,0x83,0xFF,0x82,0x00,0x8C,0xFF,0x97,0x00,0x84,0xFF,0x87,0x00,0x84,0xFF,0x88,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x95,0x00,0x83,0xFF,
|
||||
0x89,0x00,0x84,0xFF,0x8A,0x00,0xB0,0x00,0x8D,0xFF,0x83,0x00,0x89,0xFF,0x84,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x97,0x00,0x84,0xFF,0x89,0x00,0x84,0xFF,0x89,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x95,0x00,0x83,0xFF,0x8A,0x00,0x84,0xFF,0x89,0x00,0xB0,0x00,0x8D,0xFF,0x87,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x85,0x00,0x84,0xFF,0x82,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x97,0x00,0x84,0xFF,0x8B,0x00,0x84,0xFF,0x88,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x8D,0x00,0x83,0xFF,0x95,0x00,0x83,0xFF,0x8B,0x00,0x84,0xFF,0x88,0x00,0x95,0x00,0x83,0xFF,0x96,0x00,0x8D,0xFF,0x87,0x00,
|
||||
0x81,0xFF,0x81,0x00,0x81,0xFF,0x86,0x00,0x84,0xFF,0x87,0x00,0x83,0xFF,0x81,0x00,0x85,0xFF,0x96,0x00,0x84,0xFF,0x8D,0x00,0x84,0xFF,0x83,0x00,0x8F,0xFF,0x81,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x94,0x00,0x84,0xFF,0x87,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x88,0xFF,0x87,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x81,0x00,0x86,0xFF,0x95,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x83,0x00,0x8F,0xFF,0x81,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x95,0x00,0x84,0xFF,0x86,0x00,0x95,0x00,0x83,0xFF,0x98,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x88,0xFF,0x89,0x00,0x84,0xFF,0x86,0x00,0x88,0xFF,0x00,0x00,0x82,0xFF,0x88,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0xBA,0x00,0x84,0xFF,0x85,0x00,0x95,0x00,0x83,0xFF,0x96,0x00,0x8D,0xFF,0x83,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x8D,0x00,0x84,0xFF,0x86,0x00,0x86,0xFF,0x82,0x00,0x81,0xFF,0x88,0x00,0x84,0xFF,0x86,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0xBB,0x00,0x84,0xFF,0x84,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x8D,0xFF,0x83,0x00,0x81,0xFF,0x81,0x00,0x81,0xFF,0x87,0x00,0x83,0xFF,0x82,0x00,0x84,0xFF,0x86,0x00,0x86,0xFF,0x8D,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x85,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0xBC,0x00,0x84,0xFF,0x83,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x83,0x00,0x8D,0xFF,0x83,0x00,0x89,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x84,0xFF,0x85,0x00,0x87,0xFF,0x8D,0x00,0x83,0xFF,0x85,0x00,0x84,0xFF,0x8D,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0xBD,0x00,0x84,0xFF,0x82,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x86,0x00,0x88,0xFF,0x83,0x00,0x83,0xFF,0x84,0x00,0x84,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x8C,0x00,0x83,0xFF,0x86,0x00,0x84,0xFF,0x8B,0x00,
|
||||
0x84,0xFF,0xDD,0x00,0x84,0xFF,0x81,0x00,0x95,0x00,0x83,0xFF,0x88,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x89,0x00,0x81,0xFF,0x87,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x8C,0x00,0x83,0xFF,0x87,0x00,0x84,0xFF,0x89,0x00,0x84,0xFF,0xDF,0x00,0x83,0xFF,0x81,0x00,0xA2,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0xB6,0x00,0x87,0xFF,0x9A,0x00,0x84,0xFF,0x87,0x00,0x84,0xFF,0xE6,0x00,0xA2,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0xB7,0x00,0x85,0xFF,0x9C,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0xE7,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,
|
||||
0x8B,0xFF,0xFF,0x00,0xE1,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x85,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x89,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x89,0x00,0x83,0xFF,0x89,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0xC3,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x84,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x87,0x00,0x8B,0xFF,0x83,0x00,0x8A,0xFF,0x8A,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x85,0x00,0x89,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x88,0xFF,0x99,0x00,0xA1,0xFF,0x86,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x96,0x00,0xA5,0xFF,0x84,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x93,0x00,0x83,0xFF,0x83,0x00,0x8B,0xFF,0x8B,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x94,0x00,0xA9,0xFF,0x82,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x87,0x00,0x83,0xFF,0x88,0x00,0x88,0xFF,0x89,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x88,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x89,0x00,0x88,0xFF,0x88,0x00,0x86,0xFF,0x84,0x00,0x83,0xFF,0x81,0x00,0x83,0xFF,0x85,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x84,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x8A,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,
|
||||
0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x90,0x00,0x84,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x8F,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x91,0x00,0x83,0xFF,0x85,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x83,0x00,0x83,0xFF,0x87,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,
|
||||
0x81,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x84,0x00,0x89,0xFF,0x86,0x00,0x85,0xFF,0x87,0x00,0x8A,0xFF,0x84,0x00,0x8A,0xFF,0x87,0x00,0x86,0xFF,0x85,0x00,0x8B,0xFF,0x84,0x00,0x88,0xFF,0x85,0x00,0x89,0xFF,0x86,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x95,0x00,0xA9,0xFF,0x82,0x00,0x81,0x00,0x85,0xFF,0x8F,0x00,0x85,0xFF,0x85,0x00,0x87,0xFF,0x87,0x00,0x85,0xFF,0x87,0x00,0x89,0xFF,0x85,0x00,0x89,0xFF,0x89,0x00,0x85,0xFF,0x85,0x00,0x8B,0xFF,0x85,0x00,0x87,0xFF,0x85,0x00,0x89,0xFF,0x87,0x00,0x87,0xFF,0x87,0x00,0x87,0xFF,0x98,0x00,0xA5,0xFF,0x84,0x00,0x81,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xB8,0x00,0xA1,0xFF,0x86,0x00,0x81,0x00,
|
||||
0x8B,0xFF,0x83,0x00,0x8B,0xFF,0xFF,0x00,0xE1,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xC2,0x00,0x89,0xFF,0x97,0x00,0x85,0xFF,0xFF,0x00,0x94,0x00,0xC1,0x00,0x8B,0xFF,0x95,0x00,0x87,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x81,0xFF,0xAB,0x00,0x91,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x83,0xFF,0xA9,0x00,0x91,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,
|
||||
0x85,0xFF,0xA7,0x00,0x91,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x87,0xFF,0xA5,0x00,0x85,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x85,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,
|
||||
0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x85,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x87,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x85,0x00,0x83,0xFF,0x87,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x86,0x00,0x83,0xFF,0x88,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x89,0xFF,0x89,0x00,0x83,0xFF,0x8B,0x00,0x83,0xFF,0x85,0x00,0x91,0x00,0xAB,0xFF,0x82,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,
|
||||
0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x87,0xFF,0xA5,0x00,0x92,0x00,0xA9,0xFF,0x83,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x85,0xFF,0xA7,0x00,0x93,0x00,0xA7,0xFF,0x84,0x00,0x8D,0xFF,0x93,0x00,0x89,0xFF,0x84,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x83,0xFF,0xA9,0x00,0xC1,0x00,0x8B,0xFF,0x95,0x00,0x87,0xFF,0x85,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x83,0x00,0x8B,0xFF,0x93,0x00,0x8B,0xFF,0x93,0x00,0x81,0xFF,0xAB,0x00,0xC2,0x00,0x89,0xFF,0x97,0x00,0x85,0xFF,0xFF,0x00,0x94,0x00,0xFF,0x00,
|
||||
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x52,0x55,0x45,0x56,0x49,0x53,0x49,0x4F,0x4E,0x2D,0x58,0x46,0x49,0x4C,0x45,0x2E,0x00
|
1419
app/jni/lhnet.c
Normal file
1419
app/jni/lhnet.c
Normal file
File diff suppressed because it is too large
Load diff
52
app/jni/lhnet.h
Normal file
52
app/jni/lhnet.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
|
||||
// Written by Forest Hale 2003-06-15 and placed into public domain.
|
||||
|
||||
#ifndef LHNET_H
|
||||
#define LHNET_H
|
||||
|
||||
typedef enum lhnetaddresstype_e
|
||||
{
|
||||
LHNETADDRESSTYPE_NONE,
|
||||
LHNETADDRESSTYPE_LOOP,
|
||||
LHNETADDRESSTYPE_INET4,
|
||||
LHNETADDRESSTYPE_INET6
|
||||
}
|
||||
lhnetaddresstype_t;
|
||||
|
||||
typedef struct lhnetaddress_s
|
||||
{
|
||||
lhnetaddresstype_t addresstype;
|
||||
int port; // used by LHNETADDRESSTYPE_LOOP
|
||||
unsigned char storage[256]; // sockaddr_in or sockaddr_in6
|
||||
}
|
||||
lhnetaddress_t;
|
||||
|
||||
int LHNETADDRESS_FromPort(lhnetaddress_t *address, lhnetaddresstype_t addresstype, int port);
|
||||
int LHNETADDRESS_FromString(lhnetaddress_t *address, const char *string, int defaultport);
|
||||
int LHNETADDRESS_ToString(const lhnetaddress_t *address, char *string, int stringbuffersize, int includeport);
|
||||
int LHNETADDRESS_GetAddressType(const lhnetaddress_t *address);
|
||||
const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *address, char *ifname, size_t ifnamelength);
|
||||
int LHNETADDRESS_GetPort(const lhnetaddress_t *address);
|
||||
int LHNETADDRESS_SetPort(lhnetaddress_t *address, int port);
|
||||
int LHNETADDRESS_Compare(const lhnetaddress_t *address1, const lhnetaddress_t *address2);
|
||||
|
||||
typedef struct lhnetsocket_s
|
||||
{
|
||||
lhnetaddress_t address;
|
||||
int inetsocket;
|
||||
struct lhnetsocket_s *next, *prev;
|
||||
}
|
||||
lhnetsocket_t;
|
||||
|
||||
void LHNET_Init(void);
|
||||
void LHNET_Shutdown(void);
|
||||
int LHNET_DefaultDSCP(int dscp); // < 0: query; >= 0: set (returns previous value)
|
||||
void LHNET_SleepUntilPacket_Microseconds(int microseconds);
|
||||
lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address);
|
||||
void LHNET_CloseSocket(lhnetsocket_t *lhnetsocket);
|
||||
lhnetaddress_t *LHNET_AddressFromSocket(lhnetsocket_t *sock);
|
||||
int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, lhnetaddress_t *address);
|
||||
int LHNET_Write(lhnetsocket_t *lhnetsocket, const void *content, int contentlength, const lhnetaddress_t *address);
|
||||
|
||||
#endif
|
||||
|
1828
app/jni/libcurl.c
Normal file
1828
app/jni/libcurl.c
Normal file
File diff suppressed because it is too large
Load diff
44
app/jni/libcurl.h
Normal file
44
app/jni/libcurl.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
enum
|
||||
{
|
||||
CURLCBSTATUS_OK = 0,
|
||||
CURLCBSTATUS_FAILED = -1, // failed for generic reason (e.g. buffer too small)
|
||||
CURLCBSTATUS_ABORTED = -2, // aborted by curl --cancel
|
||||
CURLCBSTATUS_SERVERERROR = -3, // only used if no HTTP status code is available
|
||||
CURLCBSTATUS_UNKNOWN = -4 // should never happen
|
||||
};
|
||||
typedef void (*curl_callback_t) (int status, size_t length_received, unsigned char *buffer, void *cbdata);
|
||||
// code is one of the CURLCBSTATUS constants, or the HTTP error code (when > 0).
|
||||
|
||||
void Curl_Run(void);
|
||||
qboolean Curl_Running(void);
|
||||
qboolean Curl_Begin_ToFile(const char *URL, double maxspeed, const char *name, int loadtype, qboolean forthismap);
|
||||
|
||||
qboolean Curl_Begin_ToMemory(const char *URL, double maxspeed, unsigned char *buf, size_t bufsize, curl_callback_t callback, void *cbdata);
|
||||
qboolean Curl_Begin_ToMemory_POST(const char *URL, const char *extraheaders, double maxspeed, const char *post_content_type, const unsigned char *postbuf, size_t postbufsize, unsigned char *buf, size_t bufsize, curl_callback_t callback, void *cbdata);
|
||||
|
||||
void Curl_Init(void);
|
||||
void Curl_Init_Commands(void);
|
||||
void Curl_Shutdown(void);
|
||||
void Curl_CancelAll(void);
|
||||
void Curl_Clear_forthismap(void);
|
||||
qboolean Curl_Have_forthismap(void);
|
||||
void Curl_Register_predownload(void);
|
||||
|
||||
void Curl_ClearRequirements(void);
|
||||
void Curl_RequireFile(const char *filename);
|
||||
void Curl_SendRequirements(void);
|
||||
|
||||
typedef struct Curl_downloadinfo_s
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
double progress;
|
||||
double speed;
|
||||
qboolean queued;
|
||||
}
|
||||
Curl_downloadinfo_t;
|
||||
Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **additional_info, char *addinfo, size_t addinfolength);
|
||||
// this may and should be Z_Free()ed
|
||||
// the result is actually an array
|
||||
// an additional info string may be returned in additional_info as a
|
||||
// pointer to a static string (but the argument may be NULL if the caller
|
||||
// does not care)
|
805
app/jni/mathlib.c
Normal file
805
app/jni/mathlib.c
Normal file
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
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 "quakedef.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
vec3_t vec3_origin = {0,0,0};
|
||||
float ixtable[4096];
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
float m_bytenormals[NUMVERTEXNORMALS][3] =
|
||||
{
|
||||
{-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},
|
||||
};
|
||||
|
||||
#if 0
|
||||
unsigned char NormalToByte(const vec3_t n)
|
||||
{
|
||||
int i, best;
|
||||
float bestdistance, distance;
|
||||
|
||||
best = 0;
|
||||
bestdistance = DotProduct (n, m_bytenormals[0]);
|
||||
for (i = 1;i < NUMVERTEXNORMALS;i++)
|
||||
{
|
||||
distance = DotProduct (n, m_bytenormals[i]);
|
||||
if (distance > bestdistance)
|
||||
{
|
||||
bestdistance = distance;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
// note: uses byte partly to force unsigned for the validity check
|
||||
void ByteToNormal(unsigned char num, vec3_t n)
|
||||
{
|
||||
if (num < NUMVERTEXNORMALS)
|
||||
VectorCopy(m_bytenormals[num], n);
|
||||
else
|
||||
VectorClear(n); // FIXME: complain?
|
||||
}
|
||||
|
||||
// assumes "src" is normalized
|
||||
void PerpendicularVector( vec3_t dst, const vec3_t src )
|
||||
{
|
||||
// LordHavoc: optimized to death and beyond
|
||||
int pos;
|
||||
float minelem;
|
||||
|
||||
if (src[0])
|
||||
{
|
||||
dst[0] = 0;
|
||||
if (src[1])
|
||||
{
|
||||
dst[1] = 0;
|
||||
if (src[2])
|
||||
{
|
||||
dst[2] = 0;
|
||||
pos = 0;
|
||||
minelem = fabs(src[0]);
|
||||
if (fabs(src[1]) < minelem)
|
||||
{
|
||||
pos = 1;
|
||||
minelem = fabs(src[1]);
|
||||
}
|
||||
if (fabs(src[2]) < minelem)
|
||||
pos = 2;
|
||||
|
||||
dst[pos] = 1;
|
||||
dst[0] -= src[pos] * src[0];
|
||||
dst[1] -= src[pos] * src[1];
|
||||
dst[2] -= src[pos] * src[2];
|
||||
|
||||
// normalize the result
|
||||
VectorNormalize(dst);
|
||||
}
|
||||
else
|
||||
dst[2] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[1] = 1;
|
||||
dst[2] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[0] = 1;
|
||||
dst[1] = 0;
|
||||
dst[2] = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// LordHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
|
||||
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
|
||||
{
|
||||
// NOTE: this is consistent to AngleVectors applied to AnglesFromVectors
|
||||
if (forward[0] == 0 && forward[1] == 0)
|
||||
{
|
||||
if(forward[2] > 0)
|
||||
{
|
||||
VectorSet(right, 0, -1, 0);
|
||||
VectorSet(up, -1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet(right, 0, -1, 0);
|
||||
VectorSet(up, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
right[0] = forward[1];
|
||||
right[1] = -forward[0];
|
||||
right[2] = 0;
|
||||
VectorNormalize(right);
|
||||
|
||||
up[0] = (-forward[2]*forward[0]);
|
||||
up[1] = (-forward[2]*forward[1]);
|
||||
up[2] = (forward[0]*forward[0] + forward[1]*forward[1]);
|
||||
VectorNormalize(up);
|
||||
}
|
||||
}
|
||||
|
||||
void VectorVectorsDouble(const double *forward, double *right, double *up)
|
||||
{
|
||||
if (forward[0] == 0 && forward[1] == 0)
|
||||
{
|
||||
if(forward[2] > 0)
|
||||
{
|
||||
VectorSet(right, 0, -1, 0);
|
||||
VectorSet(up, -1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet(right, 0, -1, 0);
|
||||
VectorSet(up, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
right[0] = forward[1];
|
||||
right[1] = -forward[0];
|
||||
right[2] = 0;
|
||||
VectorNormalize(right);
|
||||
|
||||
up[0] = (-forward[2]*forward[0]);
|
||||
up[1] = (-forward[2]*forward[1]);
|
||||
up[2] = (forward[0]*forward[0] + forward[1]*forward[1]);
|
||||
VectorNormalize(up);
|
||||
}
|
||||
}
|
||||
|
||||
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
|
||||
{
|
||||
float t0, t1;
|
||||
float angle, c, s;
|
||||
vec3_t vr, vu, vf;
|
||||
|
||||
angle = DEG2RAD(degrees);
|
||||
c = cos(angle);
|
||||
s = sin(angle);
|
||||
VectorCopy(dir, vf);
|
||||
VectorVectors(vf, vr, vu);
|
||||
|
||||
t0 = vr[0] * c + vu[0] * -s;
|
||||
t1 = vr[0] * s + vu[0] * c;
|
||||
dst[0] = (t0 * vr[0] + t1 * vu[0] + vf[0] * vf[0]) * point[0]
|
||||
+ (t0 * vr[1] + t1 * vu[1] + vf[0] * vf[1]) * point[1]
|
||||
+ (t0 * vr[2] + t1 * vu[2] + vf[0] * vf[2]) * point[2];
|
||||
|
||||
t0 = vr[1] * c + vu[1] * -s;
|
||||
t1 = vr[1] * s + vu[1] * c;
|
||||
dst[1] = (t0 * vr[0] + t1 * vu[0] + vf[1] * vf[0]) * point[0]
|
||||
+ (t0 * vr[1] + t1 * vu[1] + vf[1] * vf[1]) * point[1]
|
||||
+ (t0 * vr[2] + t1 * vu[2] + vf[1] * vf[2]) * point[2];
|
||||
|
||||
t0 = vr[2] * c + vu[2] * -s;
|
||||
t1 = vr[2] * s + vu[2] * c;
|
||||
dst[2] = (t0 * vr[0] + t1 * vu[0] + vf[2] * vf[0]) * point[0]
|
||||
+ (t0 * vr[1] + t1 * vu[1] + vf[2] * vf[1]) * point[1]
|
||||
+ (t0 * vr[2] + t1 * vu[2] + vf[2] * vf[2]) * point[2];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
// returns the smallest integer greater than or equal to "value", or 0 if "value" is too big
|
||||
unsigned int CeilPowerOf2(unsigned int value)
|
||||
{
|
||||
unsigned int ceilvalue;
|
||||
|
||||
if (value > (1U << (sizeof(int) * 8 - 1)))
|
||||
return 0;
|
||||
|
||||
ceilvalue = 1;
|
||||
while (ceilvalue < value)
|
||||
ceilvalue <<= 1;
|
||||
|
||||
return ceilvalue;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------*/
|
||||
|
||||
|
||||
void PlaneClassify(mplane_t *p)
|
||||
{
|
||||
// for optimized plane comparisons
|
||||
if (p->normal[0] == 1)
|
||||
p->type = 0;
|
||||
else if (p->normal[1] == 1)
|
||||
p->type = 1;
|
||||
else if (p->normal[2] == 1)
|
||||
p->type = 2;
|
||||
else
|
||||
p->type = 3;
|
||||
// for BoxOnPlaneSide
|
||||
p->signbits = 0;
|
||||
if (p->normal[0] < 0) // 1
|
||||
p->signbits |= 1;
|
||||
if (p->normal[1] < 0) // 2
|
||||
p->signbits |= 2;
|
||||
if (p->normal[2] < 0) // 4
|
||||
p->signbits |= 4;
|
||||
}
|
||||
|
||||
int BoxOnPlaneSide(const vec3_t emins, const vec3_t emaxs, const mplane_t *p)
|
||||
{
|
||||
if (p->type < 3)
|
||||
return ((emaxs[p->type] >= p->dist) | ((emins[p->type] < p->dist) << 1));
|
||||
switch(p->signbits)
|
||||
{
|
||||
default:
|
||||
case 0: return (((p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2]) >= p->dist) | (((p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2]) < p->dist) << 1));
|
||||
case 1: return (((p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2]) >= p->dist) | (((p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2]) < p->dist) << 1));
|
||||
case 2: return (((p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2]) >= p->dist) | (((p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2]) < p->dist) << 1));
|
||||
case 3: return (((p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2]) >= p->dist) | (((p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2]) < p->dist) << 1));
|
||||
case 4: return (((p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2]) >= p->dist) | (((p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2]) < p->dist) << 1));
|
||||
case 5: return (((p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2]) >= p->dist) | (((p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2]) < p->dist) << 1));
|
||||
case 6: return (((p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2]) >= p->dist) | (((p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2]) < p->dist) << 1));
|
||||
case 7: return (((p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2]) >= p->dist) | (((p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2]) < p->dist) << 1));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
int BoxOnPlaneSide_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, const vec_t dist)
|
||||
{
|
||||
switch((normal[0] < 0) | ((normal[1] < 0) << 1) | ((normal[2] < 0) << 2))
|
||||
{
|
||||
default:
|
||||
case 0: return (((normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2]) >= dist) | (((normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emins[2]) < dist) << 1));
|
||||
case 1: return (((normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2]) >= dist) | (((normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emins[2]) < dist) << 1));
|
||||
case 2: return (((normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emaxs[2]) >= dist) | (((normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emins[2]) < dist) << 1));
|
||||
case 3: return (((normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emaxs[2]) >= dist) | (((normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emins[2]) < dist) << 1));
|
||||
case 4: return (((normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emins[2]) >= dist) | (((normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emaxs[2]) < dist) << 1));
|
||||
case 5: return (((normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emins[2]) >= dist) | (((normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emaxs[2]) < dist) << 1));
|
||||
case 6: return (((normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emins[2]) >= dist) | (((normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2]) < dist) << 1));
|
||||
case 7: return (((normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emins[2]) >= dist) | (((normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2]) < dist) << 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void BoxPlaneCorners(const vec3_t emins, const vec3_t emaxs, const mplane_t *p, vec3_t outnear, vec3_t outfar)
|
||||
{
|
||||
if (p->type < 3)
|
||||
{
|
||||
outnear[0] = outnear[1] = outnear[2] = outfar[0] = outfar[1] = outfar[2] = 0;
|
||||
outnear[p->type] = emins[p->type];
|
||||
outfar[p->type] = emaxs[p->type];
|
||||
return;
|
||||
}
|
||||
switch(p->signbits)
|
||||
{
|
||||
default:
|
||||
case 0: outnear[0] = emaxs[0];outnear[1] = emaxs[1];outnear[2] = emaxs[2];outfar[0] = emins[0];outfar[1] = emins[1];outfar[2] = emins[2];break;
|
||||
case 1: outnear[0] = emins[0];outnear[1] = emaxs[1];outnear[2] = emaxs[2];outfar[0] = emaxs[0];outfar[1] = emins[1];outfar[2] = emins[2];break;
|
||||
case 2: outnear[0] = emaxs[0];outnear[1] = emins[1];outnear[2] = emaxs[2];outfar[0] = emins[0];outfar[1] = emaxs[1];outfar[2] = emins[2];break;
|
||||
case 3: outnear[0] = emins[0];outnear[1] = emins[1];outnear[2] = emaxs[2];outfar[0] = emaxs[0];outfar[1] = emaxs[1];outfar[2] = emins[2];break;
|
||||
case 4: outnear[0] = emaxs[0];outnear[1] = emaxs[1];outnear[2] = emins[2];outfar[0] = emins[0];outfar[1] = emins[1];outfar[2] = emaxs[2];break;
|
||||
case 5: outnear[0] = emins[0];outnear[1] = emaxs[1];outnear[2] = emins[2];outfar[0] = emaxs[0];outfar[1] = emins[1];outfar[2] = emaxs[2];break;
|
||||
case 6: outnear[0] = emaxs[0];outnear[1] = emins[1];outnear[2] = emins[2];outfar[0] = emins[0];outfar[1] = emaxs[1];outfar[2] = emaxs[2];break;
|
||||
case 7: outnear[0] = emins[0];outnear[1] = emins[1];outnear[2] = emins[2];outfar[0] = emaxs[0];outfar[1] = emaxs[1];outfar[2] = emaxs[2];break;
|
||||
}
|
||||
}
|
||||
|
||||
void BoxPlaneCorners_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, vec3_t outnear, vec3_t outfar)
|
||||
{
|
||||
switch((normal[0] < 0) | ((normal[1] < 0) << 1) | ((normal[2] < 0) << 2))
|
||||
{
|
||||
default:
|
||||
case 0: outnear[0] = emaxs[0];outnear[1] = emaxs[1];outnear[2] = emaxs[2];outfar[0] = emins[0];outfar[1] = emins[1];outfar[2] = emins[2];break;
|
||||
case 1: outnear[0] = emins[0];outnear[1] = emaxs[1];outnear[2] = emaxs[2];outfar[0] = emaxs[0];outfar[1] = emins[1];outfar[2] = emins[2];break;
|
||||
case 2: outnear[0] = emaxs[0];outnear[1] = emins[1];outnear[2] = emaxs[2];outfar[0] = emins[0];outfar[1] = emaxs[1];outfar[2] = emins[2];break;
|
||||
case 3: outnear[0] = emins[0];outnear[1] = emins[1];outnear[2] = emaxs[2];outfar[0] = emaxs[0];outfar[1] = emaxs[1];outfar[2] = emins[2];break;
|
||||
case 4: outnear[0] = emaxs[0];outnear[1] = emaxs[1];outnear[2] = emins[2];outfar[0] = emins[0];outfar[1] = emins[1];outfar[2] = emaxs[2];break;
|
||||
case 5: outnear[0] = emins[0];outnear[1] = emaxs[1];outnear[2] = emins[2];outfar[0] = emaxs[0];outfar[1] = emins[1];outfar[2] = emaxs[2];break;
|
||||
case 6: outnear[0] = emaxs[0];outnear[1] = emins[1];outnear[2] = emins[2];outfar[0] = emins[0];outfar[1] = emaxs[1];outfar[2] = emaxs[2];break;
|
||||
case 7: outnear[0] = emins[0];outnear[1] = emins[1];outnear[2] = emins[2];outfar[0] = emaxs[0];outfar[1] = emaxs[1];outfar[2] = emaxs[2];break;
|
||||
}
|
||||
}
|
||||
|
||||
void BoxPlaneCornerDistances(const vec3_t emins, const vec3_t emaxs, const mplane_t *p, vec_t *outneardist, vec_t *outfardist)
|
||||
{
|
||||
if (p->type < 3)
|
||||
{
|
||||
*outneardist = emins[p->type] - p->dist;
|
||||
*outfardist = emaxs[p->type] - p->dist;
|
||||
return;
|
||||
}
|
||||
switch(p->signbits)
|
||||
{
|
||||
default:
|
||||
case 0: *outneardist = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2] - p->dist;*outfardist = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2] - p->dist;break;
|
||||
case 1: *outneardist = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2] - p->dist;*outfardist = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2] - p->dist;break;
|
||||
case 2: *outneardist = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2] - p->dist;*outfardist = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2] - p->dist;break;
|
||||
case 3: *outneardist = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2] - p->dist;*outfardist = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2] - p->dist;break;
|
||||
case 4: *outneardist = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2] - p->dist;*outfardist = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2] - p->dist;break;
|
||||
case 5: *outneardist = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emins[2] - p->dist;*outfardist = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emaxs[2] - p->dist;break;
|
||||
case 6: *outneardist = p->normal[0] * emaxs[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2] - p->dist;*outfardist = p->normal[0] * emins[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2] - p->dist;break;
|
||||
case 7: *outneardist = p->normal[0] * emins[0] + p->normal[1] * emins[1] + p->normal[2] * emins[2] - p->dist;*outfardist = p->normal[0] * emaxs[0] + p->normal[1] * emaxs[1] + p->normal[2] * emaxs[2] - p->dist;break;
|
||||
}
|
||||
}
|
||||
|
||||
void BoxPlaneCornerDistances_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, vec_t *outneardist, vec_t *outfardist)
|
||||
{
|
||||
switch((normal[0] < 0) | ((normal[1] < 0) << 1) | ((normal[2] < 0) << 2))
|
||||
{
|
||||
default:
|
||||
case 0: *outneardist = normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2];*outfardist = normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emins[2];break;
|
||||
case 1: *outneardist = normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2];*outfardist = normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emins[2];break;
|
||||
case 2: *outneardist = normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emaxs[2];*outfardist = normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emins[2];break;
|
||||
case 3: *outneardist = normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emaxs[2];*outfardist = normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emins[2];break;
|
||||
case 4: *outneardist = normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emins[2];*outfardist = normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emaxs[2];break;
|
||||
case 5: *outneardist = normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emins[2];*outfardist = normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emaxs[2];break;
|
||||
case 6: *outneardist = normal[0] * emaxs[0] + normal[1] * emins[1] + normal[2] * emins[2];*outfardist = normal[0] * emins[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2];break;
|
||||
case 7: *outneardist = normal[0] * emins[0] + normal[1] * emins[1] + normal[2] * emins[2];*outfardist = normal[0] * emaxs[0] + normal[1] * emaxs[1] + normal[2] * emaxs[2];break;
|
||||
}
|
||||
}
|
||||
|
||||
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
||||
{
|
||||
double angle, sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
if (forward)
|
||||
{
|
||||
forward[0] = cp*cy;
|
||||
forward[1] = cp*sy;
|
||||
forward[2] = -sp;
|
||||
}
|
||||
if (right || up)
|
||||
{
|
||||
if (angles[ROLL])
|
||||
{
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
if (right)
|
||||
{
|
||||
right[0] = -1*(sr*sp*cy+cr*-sy);
|
||||
right[1] = -1*(sr*sp*sy+cr*cy);
|
||||
right[2] = -1*(sr*cp);
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = (cr*sp*cy+-sr*-sy);
|
||||
up[1] = (cr*sp*sy+-sr*cy);
|
||||
up[2] = cr*cp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right)
|
||||
{
|
||||
right[0] = sy;
|
||||
right[1] = -cy;
|
||||
right[2] = 0;
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = (sp*cy);
|
||||
up[1] = (sp*sy);
|
||||
up[2] = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AngleVectorsFLU (const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up)
|
||||
{
|
||||
double angle, sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
if (forward)
|
||||
{
|
||||
forward[0] = cp*cy;
|
||||
forward[1] = cp*sy;
|
||||
forward[2] = -sp;
|
||||
}
|
||||
if (left || up)
|
||||
{
|
||||
if (angles[ROLL])
|
||||
{
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
if (left)
|
||||
{
|
||||
left[0] = sr*sp*cy+cr*-sy;
|
||||
left[1] = sr*sp*sy+cr*cy;
|
||||
left[2] = sr*cp;
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = cr*sp*cy+-sr*-sy;
|
||||
up[1] = cr*sp*sy+-sr*cy;
|
||||
up[2] = cr*cp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left)
|
||||
{
|
||||
left[0] = -sy;
|
||||
left[1] = cy;
|
||||
left[2] = 0;
|
||||
}
|
||||
if (up)
|
||||
{
|
||||
up[0] = sp*cy;
|
||||
up[1] = sp*sy;
|
||||
up[2] = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LordHavoc: calculates pitch/yaw/roll angles from forward and up vectors
|
||||
void AnglesFromVectors (vec3_t angles, const vec3_t forward, const vec3_t up, qboolean flippitch)
|
||||
{
|
||||
if (forward[0] == 0 && forward[1] == 0)
|
||||
{
|
||||
if(forward[2] > 0)
|
||||
{
|
||||
angles[PITCH] = -M_PI * 0.5;
|
||||
angles[YAW] = up ? atan2(-up[1], -up[0]) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
angles[PITCH] = M_PI * 0.5;
|
||||
angles[YAW] = up ? atan2(up[1], up[0]) : 0;
|
||||
}
|
||||
angles[ROLL] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
angles[YAW] = atan2(forward[1], forward[0]);
|
||||
angles[PITCH] = -atan2(forward[2], sqrt(forward[0]*forward[0] + forward[1]*forward[1]));
|
||||
// note: we know that angles[PITCH] is in ]-pi/2..pi/2[ due to atan2(anything, positive)
|
||||
if (up)
|
||||
{
|
||||
vec_t cp = cos(angles[PITCH]), sp = sin(angles[PITCH]);
|
||||
// note: we know cp > 0, due to the range angles[pitch] is in
|
||||
vec_t cy = cos(angles[YAW]), sy = sin(angles[YAW]);
|
||||
vec3_t tleft, tup;
|
||||
tleft[0] = -sy;
|
||||
tleft[1] = cy;
|
||||
tleft[2] = 0;
|
||||
tup[0] = sp*cy;
|
||||
tup[1] = sp*sy;
|
||||
tup[2] = cp;
|
||||
angles[ROLL] = -atan2(DotProduct(up, tleft), DotProduct(up, tup));
|
||||
// for up == '0 0 1', this is
|
||||
// angles[ROLL] = -atan2(0, cp);
|
||||
// which is 0
|
||||
}
|
||||
else
|
||||
angles[ROLL] = 0;
|
||||
|
||||
// so no up vector is equivalent to '1 0 0'!
|
||||
}
|
||||
|
||||
// now convert radians to degrees, and make all values positive
|
||||
VectorScale(angles, 180.0 / M_PI, angles);
|
||||
if (flippitch)
|
||||
angles[PITCH] *= -1;
|
||||
if (angles[PITCH] < 0) angles[PITCH] += 360;
|
||||
if (angles[YAW] < 0) angles[YAW] += 360;
|
||||
if (angles[ROLL] < 0) angles[ROLL] += 360;
|
||||
|
||||
#if 0
|
||||
{
|
||||
// debugging code
|
||||
vec3_t tforward, tleft, tup, nforward, nup;
|
||||
VectorCopy(forward, nforward);
|
||||
VectorNormalize(nforward);
|
||||
if (up)
|
||||
{
|
||||
VectorCopy(up, nup);
|
||||
VectorNormalize(nup);
|
||||
AngleVectors(angles, tforward, tleft, tup);
|
||||
if (VectorDistance(tforward, nforward) > 0.01 || VectorDistance(tup, nup) > 0.01)
|
||||
{
|
||||
Con_Printf("vectoangles('%f %f %f', '%f %f %f') = %f %f %f\n", nforward[0], nforward[1], nforward[2], nup[0], nup[1], nup[2], angles[0], angles[1], angles[2]);
|
||||
Con_Printf("^3But that is '%f %f %f', '%f %f %f'\n", tforward[0], tforward[1], tforward[2], tup[0], tup[1], tup[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleVectors(angles, tforward, tleft, tup);
|
||||
if (VectorDistance(tforward, nforward) > 0.01)
|
||||
{
|
||||
Con_Printf("vectoangles('%f %f %f') = %f %f %f\n", nforward[0], nforward[1], nforward[2], angles[0], angles[1], angles[2]);
|
||||
Con_Printf("^3But that is '%f %f %f'\n", tforward[0], tforward[1], tforward[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
void AngleMatrix (const vec3_t angles, const vec3_t translate, vec_t matrix[][4])
|
||||
{
|
||||
double angle, sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
matrix[0][0] = cp*cy;
|
||||
matrix[0][1] = sr*sp*cy+cr*-sy;
|
||||
matrix[0][2] = cr*sp*cy+-sr*-sy;
|
||||
matrix[0][3] = translate[0];
|
||||
matrix[1][0] = cp*sy;
|
||||
matrix[1][1] = sr*sp*sy+cr*cy;
|
||||
matrix[1][2] = cr*sp*sy+-sr*cy;
|
||||
matrix[1][3] = translate[1];
|
||||
matrix[2][0] = -sp;
|
||||
matrix[2][1] = sr*cp;
|
||||
matrix[2][2] = cr*cp;
|
||||
matrix[2][3] = translate[2];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// LordHavoc: renamed this to Length, and made the normal one a #define
|
||||
float VectorNormalizeLength (vec3_t v)
|
||||
{
|
||||
float length, ilength;
|
||||
|
||||
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||
length = sqrt (length);
|
||||
|
||||
if (length)
|
||||
{
|
||||
ilength = 1/length;
|
||||
v[0] *= ilength;
|
||||
v[1] *= ilength;
|
||||
v[2] *= ilength;
|
||||
}
|
||||
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_ConcatRotations
|
||||
================
|
||||
*/
|
||||
void R_ConcatRotations (const float in1[3*3], const float in2[3*3], float out[3*3])
|
||||
{
|
||||
out[0*3+0] = in1[0*3+0] * in2[0*3+0] + in1[0*3+1] * in2[1*3+0] + in1[0*3+2] * in2[2*3+0];
|
||||
out[0*3+1] = in1[0*3+0] * in2[0*3+1] + in1[0*3+1] * in2[1*3+1] + in1[0*3+2] * in2[2*3+1];
|
||||
out[0*3+2] = in1[0*3+0] * in2[0*3+2] + in1[0*3+1] * in2[1*3+2] + in1[0*3+2] * in2[2*3+2];
|
||||
out[1*3+0] = in1[1*3+0] * in2[0*3+0] + in1[1*3+1] * in2[1*3+0] + in1[1*3+2] * in2[2*3+0];
|
||||
out[1*3+1] = in1[1*3+0] * in2[0*3+1] + in1[1*3+1] * in2[1*3+1] + in1[1*3+2] * in2[2*3+1];
|
||||
out[1*3+2] = in1[1*3+0] * in2[0*3+2] + in1[1*3+1] * in2[1*3+2] + in1[1*3+2] * in2[2*3+2];
|
||||
out[2*3+0] = in1[2*3+0] * in2[0*3+0] + in1[2*3+1] * in2[1*3+0] + in1[2*3+2] * in2[2*3+0];
|
||||
out[2*3+1] = in1[2*3+0] * in2[0*3+1] + in1[2*3+1] * in2[1*3+1] + in1[2*3+2] * in2[2*3+1];
|
||||
out[2*3+2] = in1[2*3+0] * in2[0*3+2] + in1[2*3+1] * in2[1*3+2] + in1[2*3+2] * in2[2*3+2];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_ConcatTransforms
|
||||
================
|
||||
*/
|
||||
void R_ConcatTransforms (const float in1[3*4], const float in2[3*4], float out[3*4])
|
||||
{
|
||||
out[0*4+0] = in1[0*4+0] * in2[0*4+0] + in1[0*4+1] * in2[1*4+0] + in1[0*4+2] * in2[2*4+0];
|
||||
out[0*4+1] = in1[0*4+0] * in2[0*4+1] + in1[0*4+1] * in2[1*4+1] + in1[0*4+2] * in2[2*4+1];
|
||||
out[0*4+2] = in1[0*4+0] * in2[0*4+2] + in1[0*4+1] * in2[1*4+2] + in1[0*4+2] * in2[2*4+2];
|
||||
out[0*4+3] = in1[0*4+0] * in2[0*4+3] + in1[0*4+1] * in2[1*4+3] + in1[0*4+2] * in2[2*4+3] + in1[0*4+3];
|
||||
out[1*4+0] = in1[1*4+0] * in2[0*4+0] + in1[1*4+1] * in2[1*4+0] + in1[1*4+2] * in2[2*4+0];
|
||||
out[1*4+1] = in1[1*4+0] * in2[0*4+1] + in1[1*4+1] * in2[1*4+1] + in1[1*4+2] * in2[2*4+1];
|
||||
out[1*4+2] = in1[1*4+0] * in2[0*4+2] + in1[1*4+1] * in2[1*4+2] + in1[1*4+2] * in2[2*4+2];
|
||||
out[1*4+3] = in1[1*4+0] * in2[0*4+3] + in1[1*4+1] * in2[1*4+3] + in1[1*4+2] * in2[2*4+3] + in1[1*4+3];
|
||||
out[2*4+0] = in1[2*4+0] * in2[0*4+0] + in1[2*4+1] * in2[1*4+0] + in1[2*4+2] * in2[2*4+0];
|
||||
out[2*4+1] = in1[2*4+0] * in2[0*4+1] + in1[2*4+1] * in2[1*4+1] + in1[2*4+2] * in2[2*4+1];
|
||||
out[2*4+2] = in1[2*4+0] * in2[0*4+2] + in1[2*4+1] * in2[1*4+2] + in1[2*4+2] * in2[2*4+2];
|
||||
out[2*4+3] = in1[2*4+0] * in2[0*4+3] + in1[2*4+1] * in2[1*4+3] + in1[2*4+2] * in2[2*4+3] + in1[2*4+3];
|
||||
}
|
||||
|
||||
float RadiusFromBounds (const vec3_t mins, const vec3_t maxs)
|
||||
{
|
||||
vec3_t m1, m2;
|
||||
VectorMultiply(mins, mins, m1);
|
||||
VectorMultiply(maxs, maxs, m2);
|
||||
return sqrt(max(m1[0], m2[0]) + max(m1[1], m2[1]) + max(m1[2], m2[2]));
|
||||
}
|
||||
|
||||
float RadiusFromBoundsAndOrigin (const vec3_t mins, const vec3_t maxs, const vec3_t origin)
|
||||
{
|
||||
vec3_t m1, m2;
|
||||
VectorSubtract(mins, origin, m1);VectorMultiply(m1, m1, m1);
|
||||
VectorSubtract(maxs, origin, m2);VectorMultiply(m2, m2, m2);
|
||||
return sqrt(max(m1[0], m2[0]) + max(m1[1], m2[1]) + max(m1[2], m2[2]));
|
||||
}
|
||||
|
||||
void Mathlib_Init(void)
|
||||
{
|
||||
int a;
|
||||
|
||||
// LordHavoc: setup 1.0f / N table for quick recipricols of integers
|
||||
ixtable[0] = 0;
|
||||
for (a = 1;a < 4096;a++)
|
||||
ixtable[a] = 1.0f / a;
|
||||
}
|
||||
|
||||
#include "matrixlib.h"
|
||||
|
||||
void Matrix4x4_Print(const matrix4x4_t *in)
|
||||
{
|
||||
Con_Printf("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n"
|
||||
, in->m[0][0], in->m[0][1], in->m[0][2], in->m[0][3]
|
||||
, in->m[1][0], in->m[1][1], in->m[1][2], in->m[1][3]
|
||||
, in->m[2][0], in->m[2][1], in->m[2][2], in->m[2][3]
|
||||
, in->m[3][0], in->m[3][1], in->m[3][2], in->m[3][3]);
|
||||
}
|
||||
|
||||
int Math_atov(const char *s, prvm_vec3_t out)
|
||||
{
|
||||
int i;
|
||||
VectorClear(out);
|
||||
if (*s == '\'')
|
||||
s++;
|
||||
for (i = 0;i < 3;i++)
|
||||
{
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
out[i] = atof (s);
|
||||
if (out[i] == 0 && *s != '-' && *s != '+' && (*s < '0' || *s > '9'))
|
||||
break; // not a number
|
||||
while (*s && *s != ' ' && *s !='\t' && *s != '\'')
|
||||
s++;
|
||||
if (*s == '\'')
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void BoxFromPoints(vec3_t mins, vec3_t maxs, int numpoints, vec_t *point3f)
|
||||
{
|
||||
int i;
|
||||
VectorCopy(point3f, mins);
|
||||
VectorCopy(point3f, maxs);
|
||||
for (i = 1, point3f += 3;i < numpoints;i++, point3f += 3)
|
||||
{
|
||||
mins[0] = min(mins[0], point3f[0]);maxs[0] = max(maxs[0], point3f[0]);
|
||||
mins[1] = min(mins[1], point3f[1]);maxs[1] = max(maxs[1], point3f[1]);
|
||||
mins[2] = min(mins[2], point3f[2]);maxs[2] = max(maxs[2], point3f[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// LordHavoc: this has to be done right or you get severe precision breakdown
|
||||
int LoopingFrameNumberFromDouble(double t, int loopframes)
|
||||
{
|
||||
if (loopframes)
|
||||
return (int)(t - floor(t/loopframes)*loopframes);
|
||||
else
|
||||
return (int)t;
|
||||
}
|
||||
|
305
app/jni/mathlib.h
Normal file
305
app/jni/mathlib.h
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
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
|
||||
|
||||
#ifndef MATHLIB_H
|
||||
#define MATHLIB_H
|
||||
|
||||
#include "qtypes.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
||||
#endif
|
||||
|
||||
struct mplane_s;
|
||||
extern vec3_t vec3_origin;
|
||||
|
||||
#define float_nanmask (0x7F800000)
|
||||
#define double_nanmask (0x7FF8000000000000)
|
||||
#define FLOAT_IS_NAN(x) (((*(int *)&x)&float_nanmask)==float_nanmask)
|
||||
#define DOUBLE_IS_NAN(x) (((*(long long *)&x)&double_nanmask)==double_nanmask)
|
||||
|
||||
#ifdef VEC_64
|
||||
#define VEC_IS_NAN(x) DOUBLE_IS_NAN(x)
|
||||
#else
|
||||
#define VEC_IS_NAN(x) FLOAT_IS_NAN(x)
|
||||
#endif
|
||||
|
||||
#ifdef PRVM_64
|
||||
#define PRVM_IS_NAN(x) DOUBLE_IS_NAN(x)
|
||||
#else
|
||||
#define PRVM_IS_NAN(x) FLOAT_IS_NAN(x)
|
||||
#endif
|
||||
|
||||
#define bound(min,num,max) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
|
||||
|
||||
#ifndef min
|
||||
#define min(A,B) ((A) < (B) ? (A) : (B))
|
||||
#define max(A,B) ((A) > (B) ? (A) : (B))
|
||||
#endif
|
||||
|
||||
/// LordHavoc: this function never returns exactly MIN or exactly MAX, because
|
||||
/// of a QuakeC bug in id1 where the line
|
||||
/// self.nextthink = self.nexthink + random() * 0.5;
|
||||
/// can result in 0 (self.nextthink is 0 at this point in the code to begin
|
||||
/// with), causing "stone monsters" that never spawned properly, also MAX is
|
||||
/// avoided because some people use random() as an index into arrays or for
|
||||
/// loop conditions, where hitting exactly MAX may be a fatal error
|
||||
#define lhrandom(MIN,MAX) (((double)(rand() + 0.5) / ((double)RAND_MAX + 1)) * ((MAX)-(MIN)) + (MIN))
|
||||
|
||||
#define invpow(base,number) (log(number) / log(base))
|
||||
|
||||
/// returns log base 2 of "n"
|
||||
/// \WARNING: "n" MUST be a power of 2!
|
||||
#define log2i(n) ((((n) & 0xAAAAAAAA) != 0 ? 1 : 0) | (((n) & 0xCCCCCCCC) != 0 ? 2 : 0) | (((n) & 0xF0F0F0F0) != 0 ? 4 : 0) | (((n) & 0xFF00FF00) != 0 ? 8 : 0) | (((n) & 0xFFFF0000) != 0 ? 16 : 0))
|
||||
|
||||
/// \TODO: what is this function supposed to do?
|
||||
#define bit2i(n) log2i((n) << 1)
|
||||
|
||||
/// boolean XOR (why doesn't C have the ^^ operator for this purpose?)
|
||||
#define boolxor(a,b) (!(a) != !(b))
|
||||
|
||||
/// returns the smallest integer greater than or equal to "value", or 0 if "value" is too big
|
||||
unsigned int CeilPowerOf2(unsigned int value);
|
||||
|
||||
#define DEG2RAD(a) ((a) * ((float) M_PI / 180.0f))
|
||||
#define RAD2DEG(a) ((a) * (180.0f / (float) M_PI))
|
||||
#define ANGLEMOD(a) ((a) - 360.0 * floor((a) / 360.0))
|
||||
|
||||
#define DotProduct2(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1])
|
||||
#define Vector2Clear(a) ((a)[0]=(a)[1]=0)
|
||||
#define Vector2Compare(a,b) (((a)[0]==(b)[0])&&((a)[1]==(b)[1]))
|
||||
#define Vector2Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1])
|
||||
#define Vector2Negate(a,b) ((b)[0]=-((a)[0]),(b)[1]=-((a)[1]))
|
||||
#define Vector2Set(a,b,c) ((a)[0]=(b),(a)[1]=(c))
|
||||
#define Vector2Scale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale))
|
||||
#define Vector2Normalize2(v,dest) {float ilength = (float) sqrt(DotProduct2((v),(v)));if (ilength) ilength = 1.0f / ilength;dest[0] = (v)[0] * ilength;dest[1] = (v)[1] * ilength;}
|
||||
|
||||
#define DotProduct4(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]+(a)[3]*(b)[3])
|
||||
#define Vector4Clear(a) ((a)[0]=(a)[1]=(a)[2]=(a)[3]=0)
|
||||
#define Vector4Compare(a,b) (((a)[0]==(b)[0])&&((a)[1]==(b)[1])&&((a)[2]==(b)[2])&&((a)[3]==(b)[3]))
|
||||
#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
|
||||
#define Vector4Negate(a,b) ((b)[0]=-((a)[0]),(b)[1]=-((a)[1]),(b)[2]=-((a)[2]),(b)[3]=-((a)[3]))
|
||||
#define Vector4Set(a,b,c,d,e) ((a)[0]=(b),(a)[1]=(c),(a)[2]=(d),(a)[3]=(e))
|
||||
#define Vector4Normalize2(v,dest) {float ilength = (float) sqrt(DotProduct4((v),(v)));if (ilength) ilength = 1.0f / ilength;dest[0] = (v)[0] * ilength;dest[1] = (v)[1] * ilength;dest[2] = (v)[2] * ilength;dest[3] = (v)[3] * ilength;}
|
||||
#define Vector4Subtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3])
|
||||
#define Vector4Add(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3])
|
||||
#define Vector4Scale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale),(out)[2] = (in)[2] * (scale),(out)[3] = (in)[3] * (scale))
|
||||
#define Vector4Multiply(a,b,c) ((c)[0]=(a)[0]*(b)[0],(c)[1]=(a)[1]*(b)[1],(c)[2]=(a)[2]*(b)[2],(c)[3]=(a)[3]*(b)[3])
|
||||
#define Vector4MA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2],(c)[3] = (a)[3] + (scale) * (b)[3])
|
||||
#define Vector4Lerp(v1,lerp,v2,c) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]), (c)[3] = (v1)[3] + (lerp) * ((v2)[3] - (v1)[3]))
|
||||
|
||||
#define VectorNegate(a,b) ((b)[0]=-((a)[0]),(b)[1]=-((a)[1]),(b)[2]=-((a)[2]))
|
||||
#define VectorSet(a,b,c,d) ((a)[0]=(b),(a)[1]=(c),(a)[2]=(d))
|
||||
#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0)
|
||||
#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[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 VectorMultiply(a,b,c) ((c)[0]=(a)[0]*(b)[0],(c)[1]=(a)[1]*(b)[1],(c)[2]=(a)[2]*(b)[2])
|
||||
#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
|
||||
#define VectorNormalize(v) {float ilength = (float) sqrt(DotProduct((v),(v)));if (ilength) ilength = 1.0f / ilength;(v)[0] *= ilength;(v)[1] *= ilength;(v)[2] *= ilength;}
|
||||
#define VectorNormalize2(v,dest) {float ilength = (float) sqrt(DotProduct((v),(v)));if (ilength) ilength = 1.0f / ilength;dest[0] = (v)[0] * ilength;dest[1] = (v)[1] * ilength;dest[2] = (v)[2] * ilength;}
|
||||
#define VectorNormalizeDouble(v) {double ilength = sqrt(DotProduct((v),(v)));if (ilength) ilength = 1.0 / ilength;(v)[0] *= ilength;(v)[1] *= ilength;(v)[2] *= ilength;}
|
||||
#define VectorDistance2(a, b) (((a)[0] - (b)[0]) * ((a)[0] - (b)[0]) + ((a)[1] - (b)[1]) * ((a)[1] - (b)[1]) + ((a)[2] - (b)[2]) * ((a)[2] - (b)[2]))
|
||||
#define VectorDistance(a, b) (sqrt(VectorDistance2(a,b)))
|
||||
#define VectorLength(a) (sqrt((double)DotProduct(a, a)))
|
||||
#define VectorLength2(a) (DotProduct(a, a))
|
||||
#define VectorScale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale),(out)[2] = (in)[2] * (scale))
|
||||
#define VectorScaleCast(in, scale, outtype, out) ((out)[0] = (outtype) ((in)[0] * (scale)),(out)[1] = (outtype) ((in)[1] * (scale)),(out)[2] = (outtype) ((in)[2] * (scale)))
|
||||
#define VectorCompare(a,b) (((a)[0]==(b)[0])&&((a)[1]==(b)[1])&&((a)[2]==(b)[2]))
|
||||
#define VectorMA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2])
|
||||
#define VectorM(scale1, b1, c) ((c)[0] = (scale1) * (b1)[0],(c)[1] = (scale1) * (b1)[1],(c)[2] = (scale1) * (b1)[2])
|
||||
#define VectorMAM(scale1, b1, scale2, b2, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2])
|
||||
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2])
|
||||
#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0] + (scale4) * (b4)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1] + (scale4) * (b4)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2] + (scale4) * (b4)[2])
|
||||
#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 VectorLerp(v1,lerp,v2,c) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]))
|
||||
#define VectorReflect(a,r,b,c) do{double d;d = DotProduct((a), (b)) * -(1.0 + (r));VectorMA((a), (d), (b), (c));}while(0)
|
||||
#define BoxesOverlap(a,b,c,d) ((a)[0] <= (d)[0] && (b)[0] >= (c)[0] && (a)[1] <= (d)[1] && (b)[1] >= (c)[1] && (a)[2] <= (d)[2] && (b)[2] >= (c)[2])
|
||||
#define BoxInsideBox(a,b,c,d) ((a)[0] >= (c)[0] && (b)[0] <= (d)[0] && (a)[1] >= (c)[1] && (b)[1] <= (d)[1] && (a)[2] >= (c)[2] && (b)[2] <= (d)[2])
|
||||
#define TriangleBBoxOverlapsBox(a,b,c,d,e) (min((a)[0], min((b)[0], (c)[0])) < (e)[0] && max((a)[0], max((b)[0], (c)[0])) > (d)[0] && min((a)[1], min((b)[1], (c)[1])) < (e)[1] && max((a)[1], max((b)[1], (c)[1])) > (d)[1] && min((a)[2], min((b)[2], (c)[2])) < (e)[2] && max((a)[2], max((b)[2], (c)[2])) > (d)[2])
|
||||
|
||||
#define TriangleNormal(a,b,c,n) ( \
|
||||
(n)[0] = ((a)[1] - (b)[1]) * ((c)[2] - (b)[2]) - ((a)[2] - (b)[2]) * ((c)[1] - (b)[1]), \
|
||||
(n)[1] = ((a)[2] - (b)[2]) * ((c)[0] - (b)[0]) - ((a)[0] - (b)[0]) * ((c)[2] - (b)[2]), \
|
||||
(n)[2] = ((a)[0] - (b)[0]) * ((c)[1] - (b)[1]) - ((a)[1] - (b)[1]) * ((c)[0] - (b)[0]) \
|
||||
)
|
||||
|
||||
/*! Fast PointInfrontOfTriangle.
|
||||
* subtracts v1 from v0 and v2, combined into a crossproduct, combined with a
|
||||
* dotproduct of the light location relative to the first point of the
|
||||
* triangle (any point works, since any triangle is obviously flat), and
|
||||
* finally a comparison to determine if the light is infront of the triangle
|
||||
* (the goal of this statement) we do not need to normalize the surface
|
||||
* normal because both sides of the comparison use it, therefore they are
|
||||
* both multiplied the same amount... furthermore a subtract can be done on
|
||||
* the point to eliminate one dotproduct
|
||||
* this is ((p - a) * cross(a-b,c-b))
|
||||
*/
|
||||
#define PointInfrontOfTriangle(p,a,b,c) \
|
||||
( ((p)[0] - (a)[0]) * (((a)[1] - (b)[1]) * ((c)[2] - (b)[2]) - ((a)[2] - (b)[2]) * ((c)[1] - (b)[1])) \
|
||||
+ ((p)[1] - (a)[1]) * (((a)[2] - (b)[2]) * ((c)[0] - (b)[0]) - ((a)[0] - (b)[0]) * ((c)[2] - (b)[2])) \
|
||||
+ ((p)[2] - (a)[2]) * (((a)[0] - (b)[0]) * ((c)[1] - (b)[1]) - ((a)[1] - (b)[1]) * ((c)[0] - (b)[0])) > 0)
|
||||
|
||||
#if 0
|
||||
// readable version, kept only for explanatory reasons
|
||||
int PointInfrontOfTriangle(const float *p, const float *a, const float *b, const float *c)
|
||||
{
|
||||
float dir0[3], dir1[3], normal[3];
|
||||
|
||||
// calculate two mostly perpendicular edge directions
|
||||
VectorSubtract(a, b, dir0);
|
||||
VectorSubtract(c, b, dir1);
|
||||
|
||||
// we have two edge directions, we can calculate a third vector from
|
||||
// them, which is the direction of the surface normal (its magnitude
|
||||
// is not 1 however)
|
||||
CrossProduct(dir0, dir1, normal);
|
||||
|
||||
// compare distance of light along normal, with distance of any point
|
||||
// of the triangle along the same normal (the triangle is planar,
|
||||
// I.E. flat, so all points give the same answer)
|
||||
return DotProduct(p, normal) > DotProduct(a, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define lhcheeserand() (seed = (seed * 987211u) ^ (seed >> 13u) ^ 914867)
|
||||
#define lhcheeserandom(MIN,MAX) ((double)(lhcheeserand() + 0.5) / ((double)4096.0*1024.0*1024.0) * ((MAX)-(MIN)) + (MIN))
|
||||
#define VectorCheeseRandom(v) do{(v)[0] = lhcheeserandom(-1, 1);(v)[1] = lhcheeserandom(-1, 1);(v)[2] = lhcheeserandom(-1, 1);}while(DotProduct(v, v) > 1)
|
||||
|
||||
/*
|
||||
// LordHavoc: quaternion math, untested, don't know if these are correct,
|
||||
// need to add conversion to/from matrices
|
||||
// LordHavoc: later note: the matrix faq is useful: http://skal.planet-d.net/demo/matrixfaq.htm
|
||||
// LordHavoc: these are probably very wrong and I'm not sure I care, not used by anything
|
||||
|
||||
// returns length of quaternion
|
||||
#define qlen(a) ((float) sqrt((a)[0]*(a)[0]+(a)[1]*(a)[1]+(a)[2]*(a)[2]+(a)[3]*(a)[3]))
|
||||
// returns squared length of quaternion
|
||||
#define qlen2(a) ((a)[0]*(a)[0]+(a)[1]*(a)[1]+(a)[2]*(a)[2]+(a)[3]*(a)[3])
|
||||
// makes a quaternion from x, y, z, and a rotation angle (in degrees)
|
||||
#define QuatMake(x,y,z,r,c)\
|
||||
{\
|
||||
if (r == 0)\
|
||||
{\
|
||||
(c)[0]=(float) ((x) * (1.0f / 0.0f));\
|
||||
(c)[1]=(float) ((y) * (1.0f / 0.0f));\
|
||||
(c)[2]=(float) ((z) * (1.0f / 0.0f));\
|
||||
(c)[3]=(float) 1.0f;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
float r2 = (r) * 0.5 * (M_PI / 180);\
|
||||
float r2is = 1.0f / sin(r2);\
|
||||
(c)[0]=(float) ((x)/r2is);\
|
||||
(c)[1]=(float) ((y)/r2is);\
|
||||
(c)[2]=(float) ((z)/r2is);\
|
||||
(c)[3]=(float) (cos(r2));\
|
||||
}\
|
||||
}
|
||||
// makes a quaternion from a vector and a rotation angle (in degrees)
|
||||
#define QuatFromVec(a,r,c) QuatMake((a)[0],(a)[1],(a)[2],(r))
|
||||
// copies a quaternion
|
||||
#define QuatCopy(a,c) {(c)[0]=(a)[0];(c)[1]=(a)[1];(c)[2]=(a)[2];(c)[3]=(a)[3];}
|
||||
#define QuatSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];(c)[3]=(a)[3]-(b)[3];}
|
||||
#define QuatAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];(c)[3]=(a)[3]+(b)[3];}
|
||||
#define QuatScale(a,b,c) {(c)[0]=(a)[0]*b;(c)[1]=(a)[1]*b;(c)[2]=(a)[2]*b;(c)[3]=(a)[3]*b;}
|
||||
// FIXME: this is wrong, do some more research on quaternions
|
||||
//#define QuatMultiply(a,b,c) {(c)[0]=(a)[0]*(b)[0];(c)[1]=(a)[1]*(b)[1];(c)[2]=(a)[2]*(b)[2];(c)[3]=(a)[3]*(b)[3];}
|
||||
// FIXME: this is wrong, do some more research on quaternions
|
||||
//#define QuatMultiplyAdd(a,b,d,c) {(c)[0]=(a)[0]*(b)[0]+d[0];(c)[1]=(a)[1]*(b)[1]+d[1];(c)[2]=(a)[2]*(b)[2]+d[2];(c)[3]=(a)[3]*(b)[3]+d[3];}
|
||||
#define qdist(a,b) ((float) sqrt(((b)[0]-(a)[0])*((b)[0]-(a)[0])+((b)[1]-(a)[1])*((b)[1]-(a)[1])+((b)[2]-(a)[2])*((b)[2]-(a)[2])+((b)[3]-(a)[3])*((b)[3]-(a)[3])))
|
||||
#define qdist2(a,b) (((b)[0]-(a)[0])*((b)[0]-(a)[0])+((b)[1]-(a)[1])*((b)[1]-(a)[1])+((b)[2]-(a)[2])*((b)[2]-(a)[2])+((b)[3]-(a)[3])*((b)[3]-(a)[3]))
|
||||
*/
|
||||
|
||||
#define VectorCopy4(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];(b)[3]=(a)[3];}
|
||||
|
||||
vec_t Length (vec3_t v);
|
||||
|
||||
/// returns vector length
|
||||
float VectorNormalizeLength (vec3_t v);
|
||||
|
||||
/// returns vector length
|
||||
float VectorNormalizeLength2 (vec3_t v, vec3_t dest);
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
extern float m_bytenormals[NUMVERTEXNORMALS][3];
|
||||
|
||||
unsigned char NormalToByte(const vec3_t n);
|
||||
void ByteToNormal(unsigned char num, vec3_t n);
|
||||
|
||||
void R_ConcatRotations (const float in1[3*3], const float in2[3*3], float out[3*3]);
|
||||
void R_ConcatTransforms (const float in1[3*4], const float in2[3*4], float out[3*4]);
|
||||
|
||||
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||
/// LordHavoc: proper matrix version of AngleVectors
|
||||
void AngleVectorsFLU (const vec3_t angles, vec3_t forward, vec3_t left, vec3_t up);
|
||||
/// LordHavoc: builds a [3][4] matrix
|
||||
void AngleMatrix (const vec3_t angles, const vec3_t translate, vec_t matrix[][4]);
|
||||
/// LordHavoc: calculates pitch/yaw/roll angles from forward and up vectors
|
||||
void AnglesFromVectors (vec3_t angles, const vec3_t forward, const vec3_t up, qboolean flippitch);
|
||||
|
||||
/// LordHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
|
||||
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up);
|
||||
void VectorVectorsDouble(const double *forward, double *right, double *up);
|
||||
|
||||
void PlaneClassify(struct mplane_s *p);
|
||||
int BoxOnPlaneSide(const vec3_t emins, const vec3_t emaxs, const struct mplane_s *p);
|
||||
int BoxOnPlaneSide_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, const vec_t dist);
|
||||
void BoxPlaneCorners(const vec3_t emins, const vec3_t emaxs, const struct mplane_s *p, vec3_t outnear, vec3_t outfar);
|
||||
void BoxPlaneCorners_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, vec3_t outnear, vec3_t outfar);
|
||||
void BoxPlaneCornerDistances(const vec3_t emins, const vec3_t emaxs, const struct mplane_s *p, vec_t *outnear, vec_t *outfar);
|
||||
void BoxPlaneCornerDistances_Separate(const vec3_t emins, const vec3_t emaxs, const vec3_t normal, vec_t *outnear, vec_t *outfar);
|
||||
|
||||
#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
|
||||
#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
|
||||
|
||||
/// LordHavoc: minimal plane structure
|
||||
typedef struct tinyplane_s
|
||||
{
|
||||
float normal[3], dist;
|
||||
}
|
||||
tinyplane_t;
|
||||
|
||||
typedef struct tinydoubleplane_s
|
||||
{
|
||||
double normal[3], dist;
|
||||
}
|
||||
tinydoubleplane_t;
|
||||
|
||||
void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees);
|
||||
|
||||
float RadiusFromBounds (const vec3_t mins, const vec3_t maxs);
|
||||
float RadiusFromBoundsAndOrigin (const vec3_t mins, const vec3_t maxs, const vec3_t origin);
|
||||
|
||||
struct matrix4x4_s;
|
||||
/// print a matrix to the console
|
||||
void Matrix4x4_Print(const struct matrix4x4_s *in);
|
||||
int Math_atov(const char *s, prvm_vec3_t out);
|
||||
|
||||
void BoxFromPoints(vec3_t mins, vec3_t maxs, int numpoints, vec_t *point3f);
|
||||
|
||||
int LoopingFrameNumberFromDouble(double t, int loopframes);
|
||||
|
||||
void Mathlib_Init(void);
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue