aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Zickner <[email protected]>2004-07-09 06:50:52 +0000
committerHolger Zickner <[email protected]>2004-07-09 06:50:52 +0000
commit20a66a892a3f0704ef37f1eebb681edfee6fc165 (patch)
tree118e0e5ea00eecf450e4c63edc88c421d52a7db2
parent6b36f9e0380b7c80aecdc78ef07a0cf473712416 (diff)
import of Jake2
-rw-r--r--.classpath2
-rw-r--r--ChangeLog12
-rw-r--r--README20
-rw-r--r--README_DE55
-rw-r--r--build.xml59
-rw-r--r--scripts/Jake2.bat4
-rw-r--r--scripts/Jake2.sh6
-rw-r--r--src/META-INF/services/javax.imageio.spi.ImageReaderSpi2
-rw-r--r--src/jake2/Defines.java12
-rw-r--r--src/jake2/Jake2.java57
-rw-r--r--src/jake2/client/CL.java41
-rw-r--r--src/jake2/client/CL_ents.java10
-rw-r--r--src/jake2/client/CL_input.java7
-rw-r--r--src/jake2/client/CL_parse.java6
-rw-r--r--src/jake2/client/CL_view.java43
-rw-r--r--src/jake2/client/Key.java72
-rw-r--r--src/jake2/client/Menu.java87
-rw-r--r--src/jake2/client/SCR.java35
-rw-r--r--src/jake2/client/V.java37
-rw-r--r--src/jake2/client/VID.java17
-rw-r--r--src/jake2/client/client_state_t.java6
-rw-r--r--src/jake2/client/frame_t.java8
-rw-r--r--src/jake2/client/particle_t.java20
-rw-r--r--src/jake2/client/refdef_t.java4
-rw-r--r--src/jake2/game/Cmd.java740
-rw-r--r--src/jake2/game/GameBase.java20
-rw-r--r--src/jake2/game/GameFunc.java5
-rw-r--r--src/jake2/game/GameSVCmds.java12
-rw-r--r--src/jake2/game/GameSpawn.java6
-rw-r--r--src/jake2/game/GameUtil.java3
-rw-r--r--src/jake2/game/GameUtilAdapters.java14
-rw-r--r--src/jake2/game/M_Actor.java4
-rw-r--r--src/jake2/game/PlayerHud.java6
-rw-r--r--src/jake2/game/game_export_t.java14
-rw-r--r--src/jake2/game/player_state_t.java3
-rw-r--r--src/jake2/imageio/ImageFrame.java63
-rw-r--r--src/jake2/imageio/PCX.java229
-rw-r--r--src/jake2/imageio/PCXImageReader.java322
-rw-r--r--src/jake2/imageio/PCXImageReaderSpi.java99
-rw-r--r--src/jake2/imageio/Q2ColorMap.java91
-rw-r--r--src/jake2/imageio/WAL.java169
-rw-r--r--src/jake2/imageio/WALImageReader.java273
-rw-r--r--src/jake2/imageio/WALImageReaderSpi.java127
-rw-r--r--src/jake2/logging.properties41
-rw-r--r--src/jake2/qcommon/CM.java26
-rw-r--r--src/jake2/qcommon/CRC.java383
-rw-r--r--src/jake2/qcommon/Com.java1336
-rw-r--r--src/jake2/qcommon/FS.java14
-rw-r--r--src/jake2/qcommon/MD4.java14
-rw-r--r--src/jake2/qcommon/Qcommon.java94
-rw-r--r--src/jake2/qcommon/qfiles.java19
-rw-r--r--src/jake2/render/FastJoglRenderer.java306
-rw-r--r--src/jake2/render/JoglRenderer.java57
-rw-r--r--src/jake2/render/Renderer.java10
-rw-r--r--src/jake2/render/fastjogl/Anorms.java219
-rw-r--r--src/jake2/render/fastjogl/Base.java300
-rw-r--r--src/jake2/render/fastjogl/Draw.java406
-rw-r--r--src/jake2/render/fastjogl/Image.java1673
-rw-r--r--src/jake2/render/fastjogl/Impl.java343
-rw-r--r--src/jake2/render/fastjogl/Light.java778
-rw-r--r--src/jake2/render/fastjogl/Main.java1592
-rw-r--r--src/jake2/render/fastjogl/Mesh.java753
-rw-r--r--src/jake2/render/fastjogl/Misc.java265
-rw-r--r--src/jake2/render/fastjogl/Model.java1347
-rw-r--r--src/jake2/render/fastjogl/Surf.java1464
-rw-r--r--src/jake2/render/fastjogl/Warp.java732
-rw-r--r--src/jake2/render/glpoly_t.java10
-rw-r--r--src/jake2/render/jogl/Draw.java10
-rw-r--r--src/jake2/render/jogl/Image.java56
-rw-r--r--src/jake2/render/jogl/Impl.java183
-rw-r--r--src/jake2/render/jogl/Light.java75
-rw-r--r--src/jake2/render/jogl/Main.java210
-rw-r--r--src/jake2/render/jogl/Mesh.java53
-rw-r--r--src/jake2/render/jogl/Misc.java14
-rw-r--r--src/jake2/render/jogl/Model.java21
-rw-r--r--src/jake2/render/jogl/Surf.java126
-rw-r--r--src/jake2/render/jogl/Warp.java6
-rw-r--r--src/jake2/render/model_t.java4
-rw-r--r--src/jake2/render/msurface_t.java15
-rw-r--r--src/jake2/render/mtexinfo_t.java15
-rw-r--r--src/jake2/server/SV_CCMDS.java7
-rw-r--r--src/jake2/server/SV_GAME.java6
-rw-r--r--src/jake2/server/SV_INIT.java14
-rw-r--r--src/jake2/server/SV_MAIN.java4
-rw-r--r--src/jake2/server/SV_USER.java344
-rw-r--r--src/jake2/server/SV_WORLD.java273
-rw-r--r--src/jake2/sound/S.java6
-rw-r--r--src/jake2/sound/WaveLoader.java302
-rw-r--r--src/jake2/sound/joal/Channel.java84
-rw-r--r--src/jake2/sound/joal/JOALSoundImpl.java793
-rw-r--r--src/jake2/sound/jsound/JSoundImpl.java98
-rw-r--r--src/jake2/sound/jsound/SND_DMA.java1197
-rw-r--r--src/jake2/sound/jsound/SND_JAVA.java181
-rw-r--r--src/jake2/sound/jsound/SND_MIX.java491
-rw-r--r--src/jake2/sys/NET.java6
-rw-r--r--src/jake2/sys/Sys.java15
-rw-r--r--src/jake2/util/Lib.java156
-rw-r--r--test/AdapterRegister.java104
-rw-r--r--test/ConvertDefines.java138
-rw-r--r--test/Unpack.java202
-rw-r--r--test/jake2/imageio/TestImage.java160
-rw-r--r--test/jake2/qcommon/TestCMD.java3
-rw-r--r--test/jake2/qcommon/TestFS.java132
-rw-r--r--test/jake2/qcommon/TestLoadMap.java12
-rw-r--r--test/jake2/qcommon/TestMD4.java31
-rw-r--r--test/jake2/qcommon/TestTGA.java327
-rw-r--r--test/jake2/render/DancingQueens.java6
-rw-r--r--test/jake2/render/TestMap.java58
-rw-r--r--test/jake2/render/TestRenderer.java52
109 files changed, 17213 insertions, 3781 deletions
diff --git a/.classpath b/.classpath
index 795aa4d..dd03480 100644
--- a/.classpath
+++ b/.classpath
@@ -3,6 +3,8 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="lib/joal/linux/joal.jar"/>
+ <classpathentry kind="lib" path="lib/joal/windows/joal.jar"/>
<classpathentry kind="lib" path="lib/jogl/jogl.jar"/>
<classpathentry kind="output" path="build"/>
</classpath>
diff --git a/ChangeLog b/ChangeLog
index 8128e2a..3a1dee7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+0.9.2 2004-06-28
+
+ - joal sound
+ - new "fastjogl" OpenGL renderer for improved performance
+ - fullscreen support on windows
+ - bugfixes
+
+0.9.1 2004-05-04
+
+ - use a newer jogl build that works with windows2000
+ - minor cleanups
+
0.9.0 2004-04-28
- initial release
diff --git a/README b/README
index 6142684..46fa617 100644
--- a/README
+++ b/README
@@ -5,9 +5,14 @@ Jake2 is a port of the GPL'd Quake2 engine from id Software to Java. Jake2 is
distributed under the terms of the GPL (see LICENSE).
The port was done completely in Java. No native libraries are used for the
-game functionality. For graphics rendering we use the jogl Java OpenGL bindings.
+game functionality. We use the jogl Java OpenGL bindings for graphics rendering
+and Java OpenAL (joal) for sound.
-Currently Jake2 supports Linux and Windows2000/XP.
+Jake2 is still under development. Send bug reports and feedback to
+
+Currently Jake2 supports Linux and Windows2000/XP. We have feedback that it
+works on OS X too with the right native jogl libraries.
requirements:
400 MHz CPU
@@ -20,7 +25,8 @@ Installation
from binary distribution:
- unpack jake2-version.tar.gz or jake2-version.zip
- copy the baseq2 directory from your full version of Quake2 or from the
- demo version to the Jake2 base directory
+ demo version to the Jake2 base directory, in fact You need only
+ baseq2/pak0.pak
- run the game with Jake2.sh or Jake2.bat
build from source:
@@ -29,6 +35,12 @@ build from source:
- run "build.sh bindist" or "build.bat bindist" to build the binary
distribution
+installation of Quake2 data:
+- download ftp://ftp.idsoftware.com/idstuff/quake2/q2-314-demo-x86.exe (37 MB)
+- extract the directory Install\Data\baseq2 from q2-314-demo-x86.exe with unzip or
+ Winzip
+- copy the baseq2 directory to the Jake2 directory
+
have fun!
bytonic Software
@@ -36,3 +48,5 @@ bytonic Software
Holger Zickner <[email protected]>
Carsten Weisse <[email protected]>
Rene Stoeckel <[email protected]>
+
+Use <[email protected]> for bug reports and feedback. \ No newline at end of file
diff --git a/README_DE b/README_DE
new file mode 100644
index 0000000..7fd021e
--- /dev/null
+++ b/README_DE
@@ -0,0 +1,55 @@
+Jake2 README
+============
+
+Jake2 ist eine Java Portierung der Quake2 Engine von id Software. Id Software
+hat den Sourcecode der Quake2 Engine unter den Bedingungen der GPL
+ver�ffentlicht. Dementsprechend wird auch Jake2 unter der GPL (siehe LICENSE)
+lizensiert.
+
+Jake2 ist eine reine Java Anwendung. Als native Library kommen im Moment nur
+jogl f�r die OpenGL Anbindung und joal f�r OpenAudio Soundunterst�tzung zum
+Einsatz. Die komplette Funktionalit�t der Engine wurde ausschliesslich mit Java
+realisiert.
+
+Jake2 befindet sich noch im Entwicklungsstadium. Die Kontaktaddresse f�r
+Bugreports und R�ckmeldungen ist [email protected].
+
+Jake2 wird von uns unter Linux und Windows2000/XP getestet. Wir haben Feedback,
+dass Jake2 richtigen plattformspezifischen jogl Bibliotheken auch auf Mac OS X
+l�uft.
+
+Mindestanforderungen:
+400 MHz CPU
+Geforce2 MX oder bessere Grafikkarte
+JRE 1.4.2
+
+Installation
+------------
+
+ausgehend von der Bin�rdistribution:
+- jake2-version.tar.gz oder jake2-version.zip entpacken
+- baseq2 Verzeichnis des Quake2 Originals oder der Demoversion in das Jake2
+ Verzeichnis kopieren
+- mit Jake2.sh oder Jake2.bat starten
+
+ausgehend von Sourcedistribution:
+- jake2src-version.tar.gz oder jake2src-version.zip entpacken
+- JAVA_HOME Umgebungsvariable auf J2SDK1.4 Installationsverzeichnis setzen
+- "build.sh bindist" oder "build.bat bindist" erzeugt die Bin�rdistribution
+
+Quake2 Leveldaten installieren:
+- ftp://ftp.idsoftware.com/idstuff/quake2/q2-314-demo-x86.exe (37 MB)
+ herunterladen
+- Install\Data\baseq2\ aus q2-314-demo-x86.exe mit unzip oder Winzip
+ extrahieren
+- baseq2 ins Jake2 Verzeichnis kopieren
+
+viel Spass!
+
+bytonic Software
+
+Holger Zickner <[email protected]>
+Carsten Weisse <[email protected]>
+Rene Stoeckel <[email protected]>
+
+<[email protected]> f�r Bugreports und R�ckmeldungen. \ No newline at end of file
diff --git a/build.xml b/build.xml
index eb1f47c..7be47be 100644
--- a/build.xml
+++ b/build.xml
@@ -8,6 +8,7 @@
</taskdef>
<!-- properties -->
+ <property name="version" value="cvs"/>
<property name="src" location="src"/>
<property name="test" location="test"/>
<property name="build" location="build"/>
@@ -15,7 +16,7 @@
<!-- different classpaths -->
<path id="build.class.path">
- <pathelement location="lib/jogl/linux/jogl.jar"/>
+ <pathelement location="lib/jogl/jogl.jar"/>
<pathelement location="lib/joal/linux/joal.jar"/>
</path>
@@ -34,8 +35,13 @@
</javac>
</target>
- <!-- copy libs -->
- <target name="copylibs">
+ <!-- copy files -->
+ <target name="copy">
+ <copy todir="${dist}/lib">
+ <fileset dir="lib/jogl">
+ <include name="*.jar"/>
+ </fileset>
+ </copy>
<copy todir="${dist}/lib/linux">
<fileset dir="lib/jogl/linux">
<include name="*"/>
@@ -56,32 +62,37 @@
<fileset dir="scripts">
<include name="Jake2.*"/>
</fileset>
+ <fileset dir=".">
+ <include name="ChangeLog"/>
+ <include name="LICENSE"/>
+ <include name="README"/>
+ <include name="readme.id"/>
+ </fileset>
</copy>
<chmod perm="755">
<fileset dir="${dist}">
<include name="*.sh"/>
</fileset>
</chmod>
- </target>
-
- <!-- copy resources -->
- <target name="copyres">
- <copy todir="${build}">
- <fileset dir="src">
- <include name="jake2/*.properties"/>
- </fileset>
- </copy>
+ <fixcrlf srcdir="${dist}"
+ eol="crlf"
+ includes="*.bat"
+ />
+ <fixcrlf srcdir="${dist}"
+ eol="lf"
+ includes="*.sh"
+ />
</target>
<!-- jar -->
- <target name="jar" depends="compile,copyres">
+ <target name="jar" depends="compile">
<jar destfile="${dist}/lib/jake.jar" basedir="${build}">
<include name="jake2/**"/>
</jar>
<proguard printseeds="on" printusage="off" outjar="${dist}/lib/jake2.jar"
defaultpackage="" overloadaggressively="off">
<injar name="${dist}/lib/jake.jar"/>
- <libraryjar name="lib/jogl/linux/jogl.jar"/>
+ <libraryjar name="lib/jogl/jogl.jar"/>
<libraryjar name="lib/joal/linux/joal.jar"/>
<libraryjar name="${java.home}/lib/rt.jar"/>
<keep access="public" name="jake2.Jake2">
@@ -96,12 +107,12 @@
</target>
<!-- dist -->
- <target name="dist" depends="jar,copylibs">
+ <target name="dist" depends="jar,copy">
</target>
<!-- binary distribution -->
<target name="bindist" depends="dist">
- <tar destfile="jake2.tar.gz" compression="gzip">
+ <tar destfile="jake2-${version}.tar.gz" compression="gzip">
<tarfileset dir="${dist}" prefix="Jake2" mode="755">
<include name="*.sh"/>
</tarfileset>
@@ -110,7 +121,7 @@
<exclude name="*.sh"/>
</tarfileset>
</tar>
- <zip destfile="jake2.zip">
+ <zip destfile="jake2-${version}.zip">
<zipfileset dir="${dist}" prefix="Jake2">
<include name="**"/>
</zipfileset>
@@ -118,8 +129,8 @@
</target>
<!-- source distribution -->
- <target name="srcdist" >
- <tar destfile="jake2-src.tar.gz" compression="gzip">
+ <target name="srcdist">
+ <tar destfile="jake2src-${version}.tar.gz" compression="gzip">
<tarfileset dir="." prefix="Jake2" mode="755">
<include name="scripts/*.*"/>
<include name="build.sh"/>
@@ -129,9 +140,13 @@
<include name="lib/**"/>
<include name="build.xml"/>
<include name="build.bat"/>
+ <include name="ChangeLog"/>
+ <include name="LICENSE"/>
+ <include name="README"/>
+ <include name="readme.id"/>
</tarfileset>
</tar>
- <zip destfile="jake2-src.zip">
+ <zip destfile="jake2src-${version}.zip">
<zipfileset dir="." prefix="Jake2">
<include name="src/jake2/**"/>
<include name="scripts/*.*"/>
@@ -139,6 +154,10 @@
<include name="build.xml"/>
<include name="build.sh"/>
<include name="build.bat"/>
+ <include name="ChangeLog"/>
+ <include name="LICENSE"/>
+ <include name="README"/>
+ <include name="readme.id"/>
</zipfileset>
</zip>
</target>
diff --git a/scripts/Jake2.bat b/scripts/Jake2.bat
index 6230d9e..cfcfcc0 100644
--- a/scripts/Jake2.bat
+++ b/scripts/Jake2.bat
@@ -1 +1,3 @@
-@javaw -Xmx128M -Djava.library.path=lib/windows -cp lib/jake2.jar;lib/windows/jogl.jar;lib/windows/joal.jar jake2.Jake2 \ No newline at end of file
+@echo off
+SET PATH=lib\windows;%PATH%
+java -Xmx128M -Dsun.java2d.noddraw=true -Djava.library.path=lib/windows -cp lib/jake2.jar;lib/jogl.jar;lib/windows/joal.jar jake2.Jake2 \ No newline at end of file
diff --git a/scripts/Jake2.sh b/scripts/Jake2.sh
index 11ba52f..0c9f00d 100644
--- a/scripts/Jake2.sh
+++ b/scripts/Jake2.sh
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/bash
export LD_LIBRARY_PATH=lib/linux
-CP=lib/jake2.jar:lib/linux/jogl.jar:lib/linux/joal.jar
+CP=lib/jake2.jar:lib/jogl.jar:lib/linux/joal.jar
-exec java -Xmx128M -Djava.library.path=lib/linux -cp $CP jake2.Jake2 \ No newline at end of file
+exec java -Xmx128M -Djava.library.path=lib/linux -cp $CP jake2.Jake2
diff --git a/src/META-INF/services/javax.imageio.spi.ImageReaderSpi b/src/META-INF/services/javax.imageio.spi.ImageReaderSpi
deleted file mode 100644
index a0d3dae..0000000
--- a/src/META-INF/services/javax.imageio.spi.ImageReaderSpi
+++ /dev/null
@@ -1,2 +0,0 @@
-jake2.imageio.PCXImageReaderSpi
-jake2.imageio.WALImageReaderSpi \ No newline at end of file
diff --git a/src/jake2/Defines.java b/src/jake2/Defines.java
index 26984e9..f32845b 100644
--- a/src/jake2/Defines.java
+++ b/src/jake2/Defines.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 31.10.2003 by RST.
-// $Id: Defines.java,v 1.2 2004-07-08 15:58:46 hzi Exp $
+// $Id: Defines.java,v 1.3 2004-07-09 06:50:51 hzi Exp $
/** Contains the definitions for the game engine. */
@@ -1367,14 +1367,4 @@ public class Defines extends Math3D {
public final static int MAX_LOCAL_SERVERS = 8;
public final static String NO_SERVER_STRING = "<no server>";
public final static int NUM_ADDRESSBOOK_ENTRIES = 9;
-
- // // rserr_t
- static final int rserr_ok = 0;
-
- static final int rserr_invalid_fullscreen = 1;
-
- static final int rserr_invalid_mode = 2;
-
- static final int rserr_unknown = 3;
-
}
diff --git a/src/jake2/Jake2.java b/src/jake2/Jake2.java
index 70649b2..65c8075 100644
--- a/src/jake2/Jake2.java
+++ b/src/jake2/Jake2.java
@@ -2,7 +2,7 @@
* Jake2.java
* Copyright (C) 2003
*
- * $Id: Jake2.java,v 1.2 2004-07-08 15:58:46 hzi Exp $
+ * $Id: Jake2.java,v 1.3 2004-07-09 06:50:51 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,10 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2;
-import java.io.IOException;
-import java.util.logging.*;
-
-import jake2.qcommon.*;
+import jake2.client.SCR;
+import jake2.qcommon.Cvar;
+import jake2.qcommon.Qcommon;
import jake2.sys.Sys;
/**
@@ -36,23 +35,6 @@ import jake2.sys.Sys;
*/
public final class Jake2 {
- // R I S K Y C O D E D A T A B A S E
- // -------------------------------------
- // (m?gliche Fehlerursachen f?r sp?teres Debuggen)
- // - sicherstellen, dass svs.clients richtig durchnummeriert wird (client_t.serverindex)
- // - sicherstellen, dass SV_GAME.ge.edicts richtig durchnummeriert wird (ent.s.number der richtige index ?)
- // - CM_DecompressVis() richtig portiert ?
- // - NET.Net_Socket() sockarr_in.addr richtig ersetzt ?
- //
-
- /**
- * for all other classes it should be:
- * <code>
- * private static Logger logger = Logger.getLogger(<CLASSNAME>.class.getName());
- * </code>
- *
- */
- private static Logger logger;
/**
* main is used to start the game. Quake2 for Java supports the
@@ -61,22 +43,6 @@ public final class Jake2 {
*/
public static void main(String[] args) {
- // init the global LogManager with the logging.properties file
- try {
- LogManager.getLogManager().readConfiguration(Jake2.class.getResourceAsStream("/jake2/logging.properties"));
- }
- catch (SecurityException secEx) {
- secEx.printStackTrace();
- }
- catch (IOException ioEx) {
- System.err.println("FATAL Error: can't load /jake2/logging.properties (classpath)");
- ioEx.printStackTrace();
- }
-
- logger = Logger.getLogger(Jake2.class.getName());
-
- logger.log(Level.INFO, "Start Jake2 :-)");
-
// in C the first arg is the filename
int argc = (args == null) ? 1 : args.length + 1;
String[] c_args = new String[argc];
@@ -95,17 +61,16 @@ public final class Jake2 {
// find time spending rendering last frame
newtime = Sys.Milliseconds();
time = newtime - oldtime;
-
+
+ // TODO this is a timer hack for Win2000
+ // System.currentTimeMillis() resolution bug
+ if (time == 0 && (Globals.cl_timedemo.value != 0 || SCR.fps.value != 0)) {
+ time++;
+ }
+
if (time > 0)
Qcommon.Frame(time);
oldtime = newtime;
-
- // save cpu resources
-// try {
-// Thread.sleep(1);
-// }
-// catch (InterruptedException e) {
-// }
}
}
}
diff --git a/src/jake2/client/CL.java b/src/jake2/client/CL.java
index 5b30e34..125cedd 100644
--- a/src/jake2/client/CL.java
+++ b/src/jake2/client/CL.java
@@ -2,7 +2,7 @@
* CL.java
* Copyright (C) 2004
*
- * $Id: CL.java,v 1.4 2004-07-08 20:56:50 hzi Exp $
+ * $Id: CL.java,v 1.5 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -43,17 +43,6 @@ import java.nio.ByteBuffer;
*/
public final class CL extends CL_pred {
-
-// static cvar_t adr0;
-// static cvar_t adr1;
-// static cvar_t adr2;
-// static cvar_t adr3;
-// static cvar_t adr4;
-// static cvar_t adr5;
-// static cvar_t adr6;
-// static cvar_t adr7;
-// static cvar_t adr8;
-
/*
====================
CL_WriteDemoMessage
@@ -713,7 +702,7 @@ public final class CL extends CL_pred {
c = Cmd.Argv(0);
- Com.Printf(NET.AdrToString(net_from) + ": " + c + " \n");
+ Com.Printf(NET.AdrToString(net_from) + ": " + c + "\n");
// server connection
if (c.equals("client_connect")) {
@@ -1126,17 +1115,17 @@ public final class CL extends CL_pred {
if (precache_check == ENV_CNT) {
precache_check = ENV_CNT + 1;
- CM.intwrap iw = new CM.intwrap(map_checksum);
+ int iw[] = {map_checksum};
CM.CM_LoadMap(cl.configstrings[CS_MODELS + 1], true, iw);
- map_checksum = iw.i;
-// TODO MD4 check abgeklemmt
-// if ((map_checksum ^ atoi(cl.configstrings[CS_MAPCHECKSUM])) != 0) {
-// Com.Error(
-// ERR_DROP,
-// "Local map version differs from server: " + map_checksum + " != '" + cl.configstrings[CS_MAPCHECKSUM] + "'\n");
-// return;
-// }
+ map_checksum = iw[0];
+
+ if ((map_checksum ^ atoi(cl.configstrings[CS_MAPCHECKSUM])) != 0) {
+ Com.Error(
+ ERR_DROP,
+ "Local map version differs from server: " + map_checksum + " != '" + cl.configstrings[CS_MAPCHECKSUM] + "'\n");
+ return;
+ }
}
if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT) {
@@ -1201,10 +1190,11 @@ public final class CL extends CL_pred {
if (Cmd.Argc() < 2) {
- CM.intwrap iw = new CM.intwrap(0); // for detecting cheater maps
+ int iw[] ={0};// for detecting cheater maps
+
CM.CM_LoadMap(cl.configstrings[CS_MODELS + 1], true, iw);
-// int mapchecksum = iw.i ;
+ int mapchecksum = iw[0] ;
CL.RegisterSounds();
CL.PrepRefresh();
return;
@@ -1540,8 +1530,7 @@ public final class CL extends CL_pred {
VID.CheckChanges();
if (!cl.refresh_prepped && cls.state == ca_active) {
CL.PrepRefresh();
- // TODO force GC after level loading
- System.gc();
+ // force GC after level loading
System.gc();
}
diff --git a/src/jake2/client/CL_ents.java b/src/jake2/client/CL_ents.java
index d406ff2..ae05398 100644
--- a/src/jake2/client/CL_ents.java
+++ b/src/jake2/client/CL_ents.java
@@ -2,7 +2,7 @@
* CL_ents.java
* Copyright (C) 2004
*
- * $Id: CL_ents.java,v 1.3 2004-07-08 20:56:50 hzi Exp $
+ * $Id: CL_ents.java,v 1.4 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -53,7 +53,7 @@ public class CL_ents extends CL_inv {
=================
*/
static int bitcounts[] = new int[32]; /// just for protocol profiling
- public static int ParseEntityBits(CM.intwrap bits) {
+ public static int ParseEntityBits(int bits[]) {
int b, total;
int i;
int number;
@@ -82,7 +82,7 @@ public class CL_ents extends CL_inv {
else
number = MSG.ReadByte(net_message);
- bits.i = total;
+ bits[0] = total;
return number;
}
@@ -253,9 +253,9 @@ public class CL_ents extends CL_inv {
}
while (true) {
- CM.intwrap iw = new CM.intwrap(bits);
+ int iw[] = {bits};
newnum = ParseEntityBits(iw);
- bits = iw.i;
+ bits = iw[0];
if (newnum >= MAX_EDICTS)
Com.Error(ERR_DROP, "CL_ParsePacketEntities: bad number:" + newnum);
diff --git a/src/jake2/client/CL_input.java b/src/jake2/client/CL_input.java
index b55b866..47132bb 100644
--- a/src/jake2/client/CL_input.java
+++ b/src/jake2/client/CL_input.java
@@ -2,7 +2,7 @@
* CL_input.java
* Copyright (C) 2004
*
- * $Id: CL_input.java,v 1.2 2004-07-08 15:58:43 hzi Exp $
+ * $Id: CL_input.java,v 1.3 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -549,10 +549,7 @@ public class CL_input extends CL_ents {
MSG.WriteDeltaUsercmd(buf, oldcmd, cmd);
// calculate a checksum over the move commands
- buf.data[checksumIndex] = 0;
- /*COM_BlockSequenceCRCByte(
- buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
- cls.netchan.outgoing_sequence);*/
+ buf.data[checksumIndex] = Com.BlockSequenceCRCByte(buf.data, checksumIndex + 1, buf.cursize - checksumIndex - 1, cls.netchan.outgoing_sequence);
//
// deliver the message
diff --git a/src/jake2/client/CL_parse.java b/src/jake2/client/CL_parse.java
index ad19960..a36e677 100644
--- a/src/jake2/client/CL_parse.java
+++ b/src/jake2/client/CL_parse.java
@@ -2,7 +2,7 @@
* CL_parse.java
* Copyright (C) 2004
*
- * $Id: CL_parse.java,v 1.4 2004-07-08 20:56:49 hzi Exp $
+ * $Id: CL_parse.java,v 1.5 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -360,10 +360,10 @@ public class CL_parse extends CL_view {
entity_state_t nullstate = new entity_state_t(null);
//memset(nullstate, 0, sizeof(nullstate));
- CM.intwrap bits = new CM.intwrap(0);
+ int bits[] = {0};
newnum = CL_ents.ParseEntityBits(bits);
es = cl_entities[newnum].baseline;
- CL_ents.ParseDelta(nullstate, es, newnum, bits.i);
+ CL_ents.ParseDelta(nullstate, es, newnum, bits[0]);
}
/*
diff --git a/src/jake2/client/CL_view.java b/src/jake2/client/CL_view.java
index 08e55c3..ab9efa7 100644
--- a/src/jake2/client/CL_view.java
+++ b/src/jake2/client/CL_view.java
@@ -2,7 +2,7 @@
* CL_view.java
* Copyright (C) 2004
*
- * $Id: CL_view.java,v 1.2 2004-07-08 20:24:29 hzi Exp $
+ * $Id: CL_view.java,v 1.3 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,17 +25,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2.client;
-import java.util.StringTokenizer;
-
import jake2.qcommon.CM;
import jake2.qcommon.Com;
-import jake2.qcommon.xcommand_t;
import jake2.sys.Sys;
-import jake2.util.Vargs;
-
-
-
+import java.util.StringTokenizer;
public class CL_view extends CL_input {
@@ -50,18 +44,7 @@ public class CL_view extends CL_input {
Call before entering a new level, or after changing dlls
=================
*/
-
- private static xcommand_t prepRefreshCallback = new xcommand_t() {
- public void execute() {
- PrepRefresh2();
- }
- };
-
static void PrepRefresh() {
- re.updateScreen(prepRefreshCallback);
- }
-
- static void PrepRefresh2() {
String mapname;
int i;
String name;
@@ -80,13 +63,13 @@ public class CL_view extends CL_input {
// register models, pics, and skins
Com.Printf("Map: " + mapname + "\r");
- SCR.UpdateScreen2();
+ SCR.UpdateScreen();
re.BeginRegistration(mapname);
Com.Printf(" \r");
// precache status bar pics
Com.Printf("pics\r");
- SCR.UpdateScreen2();
+ SCR.UpdateScreen();
SCR.TouchPics();
Com.Printf(" \r");
@@ -99,11 +82,11 @@ public class CL_view extends CL_input {
name = new String(cl.configstrings[CS_MODELS+i]);
if (name.length() > 37) name = name.substring(0, 36);
- /*
+
if (name.charAt(0) != '*')
- Com.Printf("name" + "\r");
- */
- SCR.UpdateScreen2();
+ Com.Printf(name + "\r");
+
+ SCR.UpdateScreen();
Sys.SendKeyEvents(); // pump message loop
if (name.charAt(0) == '#') {
// special player weapon model
@@ -123,7 +106,7 @@ public class CL_view extends CL_input {
}
Com.Printf("images\r");
- SCR.UpdateScreen2();
+ SCR.UpdateScreen();
for (i=1 ; i<MAX_IMAGES && cl.configstrings[CS_IMAGES+i].length() > 0 ; i++) {
cl.image_precache[i] = re.RegisterPic(cl.configstrings[CS_IMAGES+i]);
Sys.SendKeyEvents(); // pump message loop
@@ -133,8 +116,8 @@ public class CL_view extends CL_input {
for (i=0 ; i<MAX_CLIENTS ; i++) {
if (cl.configstrings[CS_PLAYERSKINS+i].length() == 0)
continue;
- Com.Printf("client %i\r", new Vargs(1).add(i));
- SCR.UpdateScreen2();
+ Com.Printf("client " + i + '\r');
+ SCR.UpdateScreen();
Sys.SendKeyEvents(); // pump message loop
CL.ParseClientinfo(i);
Com.Printf(" \r");
@@ -144,7 +127,7 @@ public class CL_view extends CL_input {
// set sky textures and speed
Com.Printf("sky\r");
- SCR.UpdateScreen2();
+ SCR.UpdateScreen();
rotate = Float.parseFloat(cl.configstrings[CS_SKYROTATE]);
StringTokenizer st = new StringTokenizer(cl.configstrings[CS_SKYAXIS]);
axis[0] = Float.parseFloat(st.nextToken());
@@ -159,7 +142,7 @@ public class CL_view extends CL_input {
// clear any lines of console text
Console.ClearNotify();
- SCR.UpdateScreen2();
+ SCR.UpdateScreen();
cl.refresh_prepped = true;
cl.force_refdef = true; // make sure we have a valid refdef
}
diff --git a/src/jake2/client/Key.java b/src/jake2/client/Key.java
index 0b3e82a..5f7d921 100644
--- a/src/jake2/client/Key.java
+++ b/src/jake2/client/Key.java
@@ -2,7 +2,7 @@
* Key.java
* Copyright (C) 2003
*
- * $Id: Key.java,v 1.3 2004-07-08 20:24:29 hzi Exp $
+ * $Id: Key.java,v 1.4 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -119,7 +119,7 @@ public class Key extends Globals {
static int history_line = 0;
static boolean shift_down = false;
static int[] key_repeats = new int[256];
- static int[] keyshift = new int[256];
+ //static int[] keyshift = new int[256];
static boolean[] menubound = new boolean[256];
static boolean[] consolekeys = new boolean[256];
@@ -241,31 +241,31 @@ public class Key extends Globals {
consolekeys['`'] = false;
consolekeys['~'] = false;
- for (int i = 0; i < 256; i++)
- keyshift[i] = i;
- for (int i = 'a'; i <= 'z'; i++)
- keyshift[i] = i - 'a' + 'A';
- keyshift['1'] = '!';
- keyshift['2'] = '@';
- keyshift['3'] = '#';
- keyshift['4'] = '$';
- keyshift['5'] = '%';
- keyshift['6'] = '^';
- keyshift['7'] = '&';
- keyshift['8'] = '*';
- keyshift['9'] = '(';
- keyshift['0'] = ')';
- keyshift['-'] = '_';
- keyshift['='] = '+';
- keyshift[','] = '<';
- keyshift['.'] = '>';
- keyshift['/'] = '?';
- keyshift[';'] = ':';
- keyshift['\''] = '"';
- keyshift['['] = '{';
- keyshift[']'] = '}';
- keyshift['`'] = '~';
- keyshift['\\'] = '|';
+// for (int i = 0; i < 256; i++)
+// keyshift[i] = i;
+// for (int i = 'a'; i <= 'z'; i++)
+// keyshift[i] = i - 'a' + 'A';
+// keyshift['1'] = '!';
+// keyshift['2'] = '@';
+// keyshift['3'] = '#';
+// keyshift['4'] = '$';
+// keyshift['5'] = '%';
+// keyshift['6'] = '^';
+// keyshift['7'] = '&';
+// keyshift['8'] = '*';
+// keyshift['9'] = '(';
+// keyshift['0'] = ')';
+// keyshift['-'] = '_';
+// keyshift['='] = '+';
+// keyshift[','] = '<';
+// keyshift['.'] = '>';
+// keyshift['/'] = '?';
+// keyshift[';'] = ':';
+// keyshift['\''] = '"';
+// keyshift['['] = '{';
+// keyshift[']'] = '}';
+// keyshift['`'] = '~';
+// keyshift['\\'] = '|';
menubound[K_ESCAPE] = true;
for (int i = 0; i < 12; i++)
@@ -386,13 +386,13 @@ public class Key extends Globals {
cmd = "-" + kb.substring(1) + " " + key + " " + time + "\n";
Cbuf.AddText(cmd);
}
- if (keyshift[key] != key) {
- kb = Globals.keybindings[keyshift[key]];
- if (kb != null && kb.length()>0 && kb.charAt(0) == '+') {
- cmd = "-" + kb.substring(1) + " " + key + " " + time + "\n";
- Cbuf.AddText(cmd);
- }
- }
+// if (keyshift[key] != key) {
+// kb = Globals.keybindings[keyshift[key]];
+// if (kb != null && kb.length()>0 && kb.charAt(0) == '+') {
+// cmd = "-" + kb.substring(1) + " " + key + " " + time + "\n";
+// Cbuf.AddText(cmd);
+// }
+// }
return;
}
@@ -419,8 +419,8 @@ public class Key extends Globals {
if (!down)
return; // other systems only care about key down events
- if (shift_down)
- key = keyshift[key];
+// if (shift_down)
+// key = keyshift[key];
switch (Globals.cls.key_dest) {
case Defines.key_message :
diff --git a/src/jake2/client/Menu.java b/src/jake2/client/Menu.java
index 00944ed..faaf77c 100644
--- a/src/jake2/client/Menu.java
+++ b/src/jake2/client/Menu.java
@@ -2,7 +2,7 @@
* Menu.java
* Copyright (C) 2004
*
- * $Id: Menu.java,v 1.3 2004-07-08 20:56:49 hzi Exp $
+ * $Id: Menu.java,v 1.4 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -1226,7 +1226,7 @@ public final class Menu extends Key {
static menulist_s s_options_joystick_box = new menulist_s();
static menulist_s s_options_cdvolume_box = new menulist_s();
static menulist_s s_options_quality_list = new menulist_s();
- static menulist_s s_options_compatibility_list = new menulist_s();
+ //static menulist_s s_options_compatibility_list = new menulist_s();
static menuaction_s s_options_console_action = new menuaction_s();
static void CrosshairFunc(Object unused) {
@@ -1268,7 +1268,13 @@ public final class Menu extends Key {
static void ControlsSetMenuItemValues() {
s_options_sfxvolume_slider.curvalue = Cvar.VariableValue("s_volume") * 10;
s_options_cdvolume_box.curvalue = 1 - ((int) Cvar.VariableValue("cd_nocd"));
- s_options_quality_list.curvalue = 1 - ((int) Cvar.VariableValue("s_loadas8bit"));
+ //s_options_quality_list.curvalue = 1 - ((int) Cvar.VariableValue("s_loadas8bit"));
+ if ("joal".equals(Cvar.VariableString("s_impl"))) {
+ s_options_quality_list.curvalue = 0;
+ } else {
+ s_options_quality_list.curvalue = 1;
+ }
+
s_options_sensitivity_slider.curvalue = (sensitivity.value) * 2;
Cvar.SetValue("cl_run", ClampCvar(0, 1, cl_run.value));
@@ -1339,30 +1345,41 @@ public final class Menu extends Key {
}
static void UpdateSoundQualityFunc(Object unused) {
+ boolean driverNotChanged = false;
if (s_options_quality_list.curvalue != 0) {
- Cvar.SetValue("s_khz", 22);
- Cvar.SetValue("s_loadas8bit", 0);
+// Cvar.SetValue("s_khz", 22);
+// Cvar.SetValue("s_loadas8bit", 0);
+ driverNotChanged = S.getDriverName().equals("dummy");
+ Cvar.Set("s_impl", "dummy");
}
else {
- Cvar.SetValue("s_khz", 11);
- Cvar.SetValue("s_loadas8bit", 1);
+// Cvar.SetValue("s_khz", 11);
+// Cvar.SetValue("s_loadas8bit", 1);
+ driverNotChanged = S.getDriverName().equals("joal");
+ Cvar.Set("s_impl", "joal");
}
- Cvar.SetValue("s_primary", s_options_compatibility_list.curvalue);
+ //Cvar.SetValue("s_primary", s_options_compatibility_list.curvalue);
- DrawTextBox(8, 120 - 48, 36, 3);
- Print(16 + 16, 120 - 48 + 8, "Restarting the sound system. This");
- Print(16 + 16, 120 - 48 + 16, "could take up to a minute, so");
- Print(16 + 16, 120 - 48 + 24, "please be patient.");
+ if (driverNotChanged) {
+ re.EndFrame();
+ return;
+ } else {
- // the text box won't show up unless we do a buffer swap
- re.EndFrame();
+ DrawTextBox(8, 120 - 48, 36, 3);
+ Print(16 + 16, 120 - 48 + 8, "Restarting the sound system. This");
+ Print(16 + 16, 120 - 48 + 16, "could take up to a minute, so");
+ Print(16 + 16, 120 - 48 + 24, "please be patient.");
- CL.Snd_Restart_f.execute();
+ // the text box won't show up unless we do a buffer swap
+ re.EndFrame();
+
+ CL.Snd_Restart_f.execute();
+ }
}
static String cd_music_items[] = { "disabled", "enabled", null };
- static String quality_items[] = { "low", "high", null };
+ static String soundstate_items[] = { "on", "off", null };
static String compatibility_items[] = { "max compatibility", "max performance", null };
@@ -1410,26 +1427,27 @@ public final class Menu extends Key {
s_options_quality_list.x = 0;
s_options_quality_list.y = 20;
;
- s_options_quality_list.name = "sound quality";
+ s_options_quality_list.name = "sound";
s_options_quality_list.callback = new mcallback() {
public void execute(Object o) {
UpdateSoundQualityFunc(o);
}
};
- s_options_quality_list.itemnames = quality_items;
- s_options_quality_list.curvalue = 1 - (int) Cvar.VariableValue("s_loadas8bit");
-
- s_options_compatibility_list.type = MTYPE_SPINCONTROL;
- s_options_compatibility_list.x = 0;
- s_options_compatibility_list.y = 30;
- s_options_compatibility_list.name = "sound compatibility";
- s_options_compatibility_list.callback = new mcallback() {
- public void execute(Object o) {
- UpdateSoundQualityFunc(o);
- }
- };
- s_options_compatibility_list.itemnames = compatibility_items;
- s_options_compatibility_list.curvalue = (int) Cvar.VariableValue("s_primary");
+ s_options_quality_list.itemnames = soundstate_items;
+ //s_options_quality_list.curvalue = 1 - (int) Cvar.VariableValue("s_loadas8bit");
+
+
+// s_options_compatibility_list.type = MTYPE_SPINCONTROL;
+// s_options_compatibility_list.x = 0;
+// s_options_compatibility_list.y = 30;
+// s_options_compatibility_list.name = "sound compatibility";
+// s_options_compatibility_list.callback = new mcallback() {
+// public void execute(Object o) {
+// UpdateSoundQualityFunc(o);
+// }
+// };
+// s_options_compatibility_list.itemnames = compatibility_items;
+// s_options_compatibility_list.curvalue = (int) Cvar.VariableValue("s_primary");
s_options_sensitivity_slider.type = MTYPE_SLIDER;
s_options_sensitivity_slider.x = 0;
@@ -1563,7 +1581,7 @@ public final class Menu extends Key {
Menu_AddItem(s_options_menu, s_options_cdvolume_box);
Menu_AddItem(s_options_menu, s_options_quality_list);
- Menu_AddItem(s_options_menu, s_options_compatibility_list);
+// Menu_AddItem(s_options_menu, s_options_compatibility_list);
Menu_AddItem(s_options_menu, s_options_sensitivity_slider);
Menu_AddItem(s_options_menu, s_options_alwaysrun_box);
Menu_AddItem(s_options_menu, s_options_invertmouse_box);
@@ -1653,7 +1671,7 @@ public final class Menu extends Key {
"John Cash",
"Brian Hook",
"",
- "+JAVA PORT BY JTEAM",
+ "+JAVA PORT BY BYTONIC",
"CWEI",
"HOZ",
"RST",
@@ -2945,6 +2963,7 @@ public final class Menu extends Key {
s_hostname_field.length = 12;
s_hostname_field.visible_length = 12;
s_hostname_field.buffer = new StringBuffer(Cvar.VariableString("hostname"));
+ s_hostname_field.cursor = s_hostname_field.buffer.length();
s_startserver_dmoptions_action.type = MTYPE_ACTION;
s_startserver_dmoptions_action.name = " deathmatch flags";
@@ -4464,7 +4483,7 @@ public final class Menu extends Key {
}
Menu_DrawString(f.x + f.parent.x + 24, f.y + f.parent.y, tempbuffer);
-
+
if (Menu_ItemAtCursor(f.parent) == f) {
int offset;
diff --git a/src/jake2/client/SCR.java b/src/jake2/client/SCR.java
index 66b5c33..5df826c 100644
--- a/src/jake2/client/SCR.java
+++ b/src/jake2/client/SCR.java
@@ -2,7 +2,7 @@
* SCR.java
* Copyright (C) 2003
*
- * $Id: SCR.java,v 1.4 2004-07-08 20:56:49 hzi Exp $
+ * $Id: SCR.java,v 1.5 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -84,7 +84,7 @@ public final class SCR extends Globals
static cvar_t scr_graphscale;
static cvar_t scr_graphshift;
static cvar_t scr_drawall;
- static cvar_t fps;
+ public static cvar_t fps;
static dirty_t scr_dirty = new dirty_t();
static dirty_t[] scr_old_dirty = { new dirty_t(), new dirty_t()};
@@ -98,6 +98,17 @@ public final class SCR extends Globals
int x2;
int y1;
int y2;
+
+ void set(dirty_t src) {
+ x1 = src.x1;
+ x2 = src.x2;
+ y1 = src.y1;
+ y2 = src.y2;
+ }
+
+ void clear() {
+ x1 = x2 = y1 = y2 = 0;
+ }
}
/*
@@ -700,11 +711,14 @@ public final class SCR extends Globals
Clear any parts of the tiled background that were drawn on last frame
==============
*/
+
+ static dirty_t clear = new dirty_t();
+
static void TileClear()
{
int i;
int top, bottom, left, right;
- dirty_t clear = new dirty_t();
+ clear.clear();
if (scr_drawall.value != 0)
DirtyScreen(); // for power vr or broken page flippers...
@@ -718,7 +732,7 @@ public final class SCR extends Globals
// erase rect will be the union of the past three frames
// so tripple buffering works properly
- clear = scr_dirty;
+ clear.set(scr_dirty);
for (i = 0; i < 2; i++)
{
if (scr_old_dirty[i].x1 < clear.x1)
@@ -731,8 +745,8 @@ public final class SCR extends Globals
clear.y2 = scr_old_dirty[i].y2;
}
- scr_old_dirty[1] = scr_old_dirty[0];
- scr_old_dirty[0] = scr_dirty;
+ scr_old_dirty[1].set(scr_old_dirty[0]);
+ scr_old_dirty[0].set(scr_dirty);
scr_dirty.x1 = 9999;
scr_dirty.x2 = -9999;
@@ -1452,10 +1466,16 @@ public final class SCR extends Globals
private static int lastframes = 0;
private static int lasttime = 0;
private static String fpsvalue = "";
+
static void DrawFPS()
{
if (fps.value > 0.0f)
{
+ if (fps.modified) {
+ fps.modified = false;
+ Cvar.SetValue("cl_maxfps", 1000);
+ }
+
int diff = cls.realtime - lasttime;
if (diff > (int) (fps.value * 1000))
{
@@ -1469,6 +1489,9 @@ public final class SCR extends Globals
re.DrawChar(x, 2, fpsvalue.charAt(i));
x += 8;
}
+ } else if (fps.modified){
+ fps.modified = false;
+ Cvar.SetValue("cl_maxfps", 90);
}
}
diff --git a/src/jake2/client/V.java b/src/jake2/client/V.java
index 3b9d139..2fd3005 100644
--- a/src/jake2/client/V.java
+++ b/src/jake2/client/V.java
@@ -2,7 +2,7 @@
* V.java
* Copyright (C) 2003
*
- * $Id: V.java,v 1.1 2004-07-07 19:58:52 hzi Exp $
+ * $Id: V.java,v 1.2 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -34,6 +34,7 @@ import jake2.util.Math3D;
import jake2.util.Vargs;
import java.io.IOException;
+import java.nio.FloatBuffer;
/**
* V
@@ -53,7 +54,7 @@ public final class V extends Globals {
static entity_t[] r_entities = new entity_t[MAX_ENTITIES];
static int r_numparticles;
- static particle_t[] r_particles = new particle_t[MAX_PARTICLES];
+ //static particle_t[] r_particles = new particle_t[MAX_PARTICLES];
static lightstyle_t[] r_lightstyles = new lightstyle_t[MAX_LIGHTSTYLES];
static {
@@ -61,8 +62,6 @@ public final class V extends Globals {
r_dlights[i] = new dlight_t();
for (int i = 0; i < r_entities.length; i++)
r_entities[i] = new entity_t();
- for (int i = 0; i < r_particles.length; i++)
- r_particles[i] = new particle_t();
for (int i = 0; i < r_lightstyles.length; i++)
r_lightstyles[i] = new lightstyle_t();
}
@@ -99,16 +98,20 @@ public final class V extends Globals {
=====================
*/
static void AddParticle(float[] org, int color, float alpha) {
- particle_t p;
-
if (r_numparticles >= MAX_PARTICLES)
return;
- p = r_particles[r_numparticles++];
+ int i = r_numparticles++;
- VectorCopy(org, p.origin);
- p.color = color;
- p.alpha = alpha;
+ int c = particle_t.colorTable[color];
+ c |= (int)(alpha * 255) << 24;
+ particle_t.colorArray.put(i, c);
+
+ i *= 3;
+ FloatBuffer vertexBuf = particle_t.vertexArray;
+ vertexBuf.put(i++, org[0]);
+ vertexBuf.put(i++, org[1]);
+ vertexBuf.put(i++, org[2]);
}
/*
@@ -158,26 +161,25 @@ public final class V extends Globals {
================
*/
static void TestParticles() {
- particle_t p;
int i, j;
float d, r, u;
- r_numparticles = MAX_PARTICLES;
- for (i = 0; i < r_numparticles; i++) {
+ float[] origin = {0,0,0};
+
+ r_numparticles = 0;
+ for (i = 0; i < MAX_PARTICLES; i++) {
d = i * 0.25f;
r = 4 * ((i & 7) - 3.5f);
u = 4 * (((i >> 3) & 7) - 3.5f);
- p = r_particles[i];
for (j = 0; j < 3; j++)
- p.origin[j] =
+ origin[j] =
cl.refdef.vieworg[j]
+ cl.v_forward[j] * d
+ cl.v_right[j] * r
+ cl.v_up[j] * u;
- p.color = 8;
- p.alpha = cl_testparticles.value;
+ AddParticle(origin, 8, cl_testparticles.value);
}
}
@@ -356,7 +358,6 @@ public final class V extends Globals {
cl.refdef.num_entities = r_numentities;
cl.refdef.entities = r_entities;
cl.refdef.num_particles = r_numparticles;
- cl.refdef.particles = r_particles;
cl.refdef.num_dlights = r_numdlights;
cl.refdef.dlights = r_dlights;
cl.refdef.lightstyles = r_lightstyles;
diff --git a/src/jake2/client/VID.java b/src/jake2/client/VID.java
index 53a943f..b18683b 100644
--- a/src/jake2/client/VID.java
+++ b/src/jake2/client/VID.java
@@ -2,7 +2,7 @@
* VID.java
* Copyright (C) 2003
*
- * $Id: VID.java,v 1.4 2004-07-08 20:56:50 hzi Exp $
+ * $Id: VID.java,v 1.5 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -370,7 +370,7 @@ public class VID extends Globals {
public static void Init()
{
/* Create the video variables so we know how to start the graphics drivers */
- vid_ref = Cvar.Get("vid_ref", "jogl", CVAR_ARCHIVE);
+ vid_ref = Cvar.Get("vid_ref", "fastjogl", CVAR_ARCHIVE);
vid_xpos = Cvar.Get("vid_xpos", "3", CVAR_ARCHIVE);
vid_ypos = Cvar.Get("vid_ypos", "22", CVAR_ARCHIVE);
vid_fullscreen = Cvar.Get("vid_fullscreen", "0", CVAR_ARCHIVE);
@@ -419,6 +419,7 @@ public class VID extends Globals {
// #define REF_3DFXGL 3
// #define REF_OPENGLX 4
static final int REF_OPENGL_JOGL = 0;
+ static final int REF_OPENGL_FASTJOGL =1;
// #define REF_MESA3DGLX 5
// extern cvar_t *vid_ref;
@@ -605,6 +606,12 @@ public class VID extends Globals {
if (gl_driver.modified)
vid_ref.modified = true;
break;
+ case REF_OPENGL_FASTJOGL :
+ Cvar.Set( "vid_ref", "fastjogl" );
+ Cvar.Set( "gl_driver", "fastjogl" );
+ if (gl_driver.modified)
+ vid_ref.modified = true;
+ break;
}
Menu.ForceMenuOff();
@@ -634,6 +641,7 @@ public class VID extends Globals {
// "[OpenGL glX ]",
// "[Mesa 3-D glX ]",
"[OpenGL jogl ]",
+ "[OpenGL fastjogl]",
null
};
static final String[] yesno_names =
@@ -686,6 +694,11 @@ public class VID extends Globals {
s_current_menu_index = OPENGL_MENU;
s_ref_list[0].curvalue = s_ref_list[1].curvalue = REF_OPENGL_JOGL;
}
+ else if ( vid_ref.string.equalsIgnoreCase("fastjogl"))
+ {
+ s_current_menu_index = OPENGL_MENU;
+ s_ref_list[0].curvalue = s_ref_list[1].curvalue = REF_OPENGL_FASTJOGL;
+ }
// else if (strcmp( vid_ref->string, "softx" ) == 0 )
// {
// s_current_menu_index = SOFTWARE_MENU;
diff --git a/src/jake2/client/client_state_t.java b/src/jake2/client/client_state_t.java
index ff86070..11a3af7 100644
--- a/src/jake2/client/client_state_t.java
+++ b/src/jake2/client/client_state_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 27.11.2003 by RST.
-//$Id: client_state_t.java,v 1.2 2004-07-08 20:56:51 hzi Exp $
+//$Id: client_state_t.java,v 1.3 2004-07-09 06:50:50 hzi Exp $
package jake2.client;
@@ -57,7 +57,7 @@ public class client_state_t {
int timedemo_start;
public boolean refresh_prepped; // false if on new level or new ref dll
- boolean sound_prepped; // ambient sounds can start
+ public boolean sound_prepped; // ambient sounds can start
boolean force_refdef; // vid has changed, so we can't use a paused refdef
int parse_entities; // index (not anded off) into cl_parse_entities[]
@@ -129,7 +129,7 @@ public class client_state_t {
model_t model_draw[] = new model_t[Defines.MAX_MODELS];
cmodel_t model_clip[] = new cmodel_t[Defines.MAX_MODELS];
- sfx_t sound_precache[] = new sfx_t[Defines.MAX_SOUNDS];
+ public sfx_t sound_precache[] = new sfx_t[Defines.MAX_SOUNDS];
image_t image_precache[] = new image_t[Defines.MAX_IMAGES];
clientinfo_t clientinfo[] = new clientinfo_t[Defines.MAX_CLIENTS];
diff --git a/src/jake2/client/frame_t.java b/src/jake2/client/frame_t.java
index 1e414dc..a242217 100644
--- a/src/jake2/client/frame_t.java
+++ b/src/jake2/client/frame_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 27.11.2003 by RST.
-// $Id: frame_t.java,v 1.2 2004-07-08 20:56:50 hzi Exp $
+// $Id: frame_t.java,v 1.3 2004-07-09 06:50:50 hzi Exp $
package jake2.client;
@@ -27,7 +27,7 @@ import jake2.game.player_state_t;
import java.util.Arrays;
-public class frame_t implements Cloneable {
+public class frame_t {
public static final int MAX_MAP_AREAS = 256;
@@ -37,8 +37,8 @@ public class frame_t implements Cloneable {
int deltaframe;
byte areabits[] = new byte [MAX_MAP_AREAS/8]; // portalarea visibility bits
public player_state_t playerstate = new player_state_t(); // mem
- int num_entities;
- int parse_entities; // non-masked index into cl_parse_entities array
+ public int num_entities;
+ public int parse_entities; // non-masked index into cl_parse_entities array
public void set(frame_t from) {
valid = from.valid;
diff --git a/src/jake2/client/particle_t.java b/src/jake2/client/particle_t.java
index 2127b5d..027cadf 100644
--- a/src/jake2/client/particle_t.java
+++ b/src/jake2/client/particle_t.java
@@ -19,12 +19,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 20.11.2003 by RST.
-// $Id: particle_t.java,v 1.1 2004-07-07 19:58:52 hzi Exp $
+// $Id: particle_t.java,v 1.2 2004-07-09 06:50:50 hzi Exp $
package jake2.client;
+import jake2.Defines;
+import jake2.util.Lib;
+
+import java.nio.*;
+
public class particle_t {
- public float origin[] = { 0, 0, 0 };
- public int color;
- public float alpha;
+
+ public static FloatBuffer vertexArray = Lib.newFloatBuffer(Defines.MAX_PARTICLES * 3);
+ public static IntBuffer colorArray = Lib.newIntBuffer(Defines.MAX_PARTICLES, ByteOrder.LITTLE_ENDIAN);
+ public static int[] colorTable = new int[256];
+
+ public static void setColorPalette(int[] palette) {
+ for (int i=0; i < 256; i++) {
+ colorTable[i] = palette[i] & 0x00FFFFFF;
+ }
+ }
}
diff --git a/src/jake2/client/refdef_t.java b/src/jake2/client/refdef_t.java
index a01ab06..d5c6027 100644
--- a/src/jake2/client/refdef_t.java
+++ b/src/jake2/client/refdef_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 20.11.2003 by RST.
-// $Id: refdef_t.java,v 1.1 2004-07-07 19:58:52 hzi Exp $
+// $Id: refdef_t.java,v 1.2 2004-07-09 06:50:50 hzi Exp $
package jake2.client;
@@ -43,5 +43,5 @@ public class refdef_t {
public dlight_t dlights[];
public int num_particles;
- public particle_t particles[];
+ //public particle_t particles[];
}
diff --git a/src/jake2/game/Cmd.java b/src/jake2/game/Cmd.java
index bbb6742..a5a0a50 100644
--- a/src/jake2/game/Cmd.java
+++ b/src/jake2/game/Cmd.java
@@ -2,7 +2,7 @@
* Cmd.java
* Copyright (C) 2003
*
- * $Id: Cmd.java,v 1.2 2004-07-08 15:58:43 hzi Exp $
+ * $Id: Cmd.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -35,32 +35,40 @@ import java.util.Arrays;
/**
* Cmd
*/
-public final class Cmd extends PlayerView {
+public final class Cmd extends PlayerView
+{
- static xcommand_t List_f = new xcommand_t() {
- public void execute() {
- cmd_function_t cmd = Cmd.cmd_functions;
- int i = 0;
+ static xcommand_t List_f= new xcommand_t()
+ {
+ public void execute()
+ {
+ cmd_function_t cmd= Cmd.cmd_functions;
+ int i= 0;
- while (cmd != null) {
+ while (cmd != null)
+ {
Com.Printf(cmd.name + '\n');
i++;
- cmd = cmd.next;
+ cmd= cmd.next;
}
Com.Printf(i + " commands\n");
}
};
- static xcommand_t Exec_f = new xcommand_t() {
- public void execute() {
- if (Cmd.Argc() != 2) {
+ static xcommand_t Exec_f= new xcommand_t()
+ {
+ public void execute()
+ {
+ if (Cmd.Argc() != 2)
+ {
Com.Printf("exec <filename> : execute a script file\n");
return;
}
- byte[] f = null;
- f = FS.LoadFile(Cmd.Argv(1));
- if (f == null) {
+ byte[] f= null;
+ f= FS.LoadFile(Cmd.Argv(1));
+ if (f == null)
+ {
Com.Printf("couldn't exec " + Cmd.Argv(1) + "\n");
return;
}
@@ -71,77 +79,93 @@ public final class Cmd extends PlayerView {
FS.FreeFile(f);
}
};
- static xcommand_t Echo_f = new xcommand_t() {
- public void execute() {
- for (int i = 1; i < Cmd.Argc(); i++) {
+
+ static xcommand_t Echo_f= new xcommand_t()
+ {
+ public void execute()
+ {
+ for (int i= 1; i < Cmd.Argc(); i++)
+ {
Com.Printf(Cmd.Argv(i) + " ");
}
Com.Printf("'\n");
}
};
- static xcommand_t Alias_f = new xcommand_t() {
- public void execute() {
- cmdalias_t a = null;
- if (Cmd.Argc() == 1) {
+ static xcommand_t Alias_f= new xcommand_t()
+ {
+ public void execute()
+ {
+ cmdalias_t a= null;
+ if (Cmd.Argc() == 1)
+ {
Com.Printf("Current alias commands:\n");
- for (a = Globals.cmd_alias; a != null; a = a.next) {
+ for (a= Globals.cmd_alias; a != null; a= a.next)
+ {
Com.Printf(a.name + " : " + a.value);
}
return;
}
- String s = Cmd.Argv(1);
- if (s.length() > Globals.MAX_ALIAS_NAME) {
+ String s= Cmd.Argv(1);
+ if (s.length() > Globals.MAX_ALIAS_NAME)
+ {
Com.Printf("Alias name is too long\n");
return;
}
// if the alias already exists, reuse it
- for (a = Globals.cmd_alias; a != null; a = a.next) {
- if (s.equalsIgnoreCase(a.name)) {
- a.value = null;
+ for (a= Globals.cmd_alias; a != null; a= a.next)
+ {
+ if (s.equalsIgnoreCase(a.name))
+ {
+ a.value= null;
break;
}
}
- if (a == null) {
- a = new cmdalias_t();
- a.next = Globals.cmd_alias;
- Globals.cmd_alias = a;
+ if (a == null)
+ {
+ a= new cmdalias_t();
+ a.next= Globals.cmd_alias;
+ Globals.cmd_alias= a;
}
- a.name = s;
+ a.name= s;
// copy the rest of the command line
- String cmd = "";
- int c = Cmd.Argc();
- for (int i = 2; i < c; i++) {
- cmd = cmd + Cmd.Argv(i);
+ String cmd= "";
+ int c= Cmd.Argc();
+ for (int i= 2; i < c; i++)
+ {
+ cmd= cmd + Cmd.Argv(i);
if (i != (c - 1))
- cmd = cmd + " ";
+ cmd= cmd + " ";
}
- cmd = cmd + "\n";
+ cmd= cmd + "\n";
- a.value = cmd;
+ a.value= cmd;
}
};
- public static xcommand_t Wait_f = new xcommand_t() {
- public void execute() {
- Globals.cmd_wait = true;
+ public static xcommand_t Wait_f= new xcommand_t()
+ {
+ public void execute()
+ {
+ Globals.cmd_wait= true;
}
};
- public static cmd_function_t cmd_functions = null;
+ public static cmd_function_t cmd_functions= null;
public static int cmd_argc;
- public static String[] cmd_argv = new String[Globals.MAX_STRING_TOKENS];
+ public static String[] cmd_argv= new String[Globals.MAX_STRING_TOKENS];
public static String cmd_args;
- public static final int ALIAS_LOOP_COUNT = 16;
+ public static final int ALIAS_LOOP_COUNT= 16;
/**
* register our commands
*/
- public static void Init() {
+ public static void Init()
+ {
Cmd.AddCommand("exec", Exec_f);
Cmd.AddCommand("echo", Echo_f);
@@ -150,34 +174,37 @@ public final class Cmd extends PlayerView {
Cmd.AddCommand("wait", Wait_f);
}
- private static char expanded[] = new char[MAX_STRING_CHARS];
- private static char temporary[] = new char[MAX_STRING_CHARS];
+ private static char expanded[]= new char[MAX_STRING_CHARS];
+ private static char temporary[]= new char[MAX_STRING_CHARS];
/*
======================
Cmd_MacroExpandString
======================
*/
- public static char[] MacroExpandString(char text[], int len) {
+ public static char[] MacroExpandString(char text[], int len)
+ {
int i, j, count;
boolean inquote;
char scan[];
String token;
- inquote = false;
+ inquote= false;
- scan = text;
+ scan= text;
- if (len >= MAX_STRING_CHARS) {
+ if (len >= MAX_STRING_CHARS)
+ {
Com.Printf("Line exceeded " + MAX_STRING_CHARS + " chars, discarded.\n");
return null;
}
- count = 0;
+ count= 0;
- for (i = 0; i < len; i++) {
+ for (i= 0; i < len; i++)
+ {
if (scan[i] == '"')
- inquote = !inquote;
+ inquote= !inquote;
if (inquote)
continue; // don't expand inside quotes
@@ -186,19 +213,20 @@ public final class Cmd extends PlayerView {
continue;
// scan out the complete macro, without $
- Com.ParseHelp ph = new Com.ParseHelp(text, i + 1);
- token = Com.Parse(ph);
+ Com.ParseHelp ph= new Com.ParseHelp(text, i + 1);
+ token= Com.Parse(ph);
if (ph.data == null)
continue;
- token = Cvar.VariableString(token);
+ token= Cvar.VariableString(token);
- j = token.length();
+ j= token.length();
len += j;
- if (len >= MAX_STRING_CHARS) {
+ if (len >= MAX_STRING_CHARS)
+ {
Com.Printf("Expanded line exceeded " + MAX_STRING_CHARS + " chars, discarded.\n");
return null;
}
@@ -214,16 +242,18 @@ public final class Cmd extends PlayerView {
//strcpy(expanded, temporary);
System.arraycopy(temporary, 0, expanded, 0, 0);
- scan = expanded;
+ scan= expanded;
i--;
- if (++count == 100) {
+ if (++count == 100)
+ {
Com.Printf("Macro expansion loop, discarded.\n");
return null;
}
}
- if (inquote) {
+ if (inquote)
+ {
Com.Printf("Line has unmatched quote, discarded.\n");
return null;
}
@@ -239,31 +269,34 @@ public final class Cmd extends PlayerView {
$Cvars will be expanded unless they are in a quoted token
============
*/
- public static void TokenizeString(char text[], boolean macroExpand) {
+ public static void TokenizeString(char text[], boolean macroExpand)
+ {
String com_token;
- cmd_argc = 0;
+ cmd_argc= 0;
- int len = strlen(text);
+ int len= strlen(text);
// macro expand the text
if (macroExpand)
- text = MacroExpandString(text, len);
+ text= MacroExpandString(text, len);
if (text == null)
return;
- len = strlen(text);
+ len= strlen(text);
- Com.ParseHelp ph = new Com.ParseHelp(text);
+ Com.ParseHelp ph= new Com.ParseHelp(text);
- while (true) {
+ while (true)
+ {
// skip whitespace up to a /n
- char c = ph.skipwhitestoeol();
+ char c= ph.skipwhitestoeol();
- if (c == '\n') { // a newline seperates commands in the buffer
- c = ph.nextchar();
+ if (c == '\n')
+ { // a newline seperates commands in the buffer
+ c= ph.nextchar();
break;
}
@@ -271,46 +304,52 @@ public final class Cmd extends PlayerView {
return;
// set cmd_args to everything after the first arg
- if (cmd_argc == 1) {
- cmd_args = new String(text, ph.index, len - ph.index);
+ if (cmd_argc == 1)
+ {
+ cmd_args= new String(text, ph.index, len - ph.index);
cmd_args.trim();
}
- com_token = Com.Parse(ph);
+ com_token= Com.Parse(ph);
if (com_token.length() == 0)
return;
- if (cmd_argc < MAX_STRING_TOKENS) {
- cmd_argv[cmd_argc] = com_token;
+ if (cmd_argc < MAX_STRING_TOKENS)
+ {
+ cmd_argv[cmd_argc]= com_token;
cmd_argc++;
}
}
}
- public static void AddCommand(String cmd_name, xcommand_t function) {
+ public static void AddCommand(String cmd_name, xcommand_t function)
+ {
cmd_function_t cmd;
//Com.DPrintf("Cmd_AddCommand: " + cmd_name + "\n");
// fail if the command is a variable name
- if ((Cvar.VariableString(cmd_name)).length() > 0) {
+ if ((Cvar.VariableString(cmd_name)).length() > 0)
+ {
Com.Printf("Cmd_AddCommand: " + cmd_name + " already defined as a var\n");
return;
}
// fail if the command already exists
- for (cmd = cmd_functions; cmd != null; cmd = cmd.next) {
- if (cmd_name.equals(cmd.name)) {
+ for (cmd= cmd_functions; cmd != null; cmd= cmd.next)
+ {
+ if (cmd_name.equals(cmd.name))
+ {
Com.Printf("Cmd_AddCommand: " + cmd_name + " already defined\n");
return;
}
}
- cmd = new cmd_function_t();
- cmd.name = cmd_name;
-
- cmd.function = function;
- cmd.next = cmd_functions;
- cmd_functions = cmd;
+ cmd= new cmd_function_t();
+ cmd.name= cmd_name;
+
+ cmd.function= function;
+ cmd.next= cmd_functions;
+ cmd_functions= cmd;
}
/*
@@ -318,26 +357,30 @@ public final class Cmd extends PlayerView {
Cmd_RemoveCommand
============
*/
- public static void RemoveCommand(String cmd_name) {
- cmd_function_t cmd, back = null;
+ public static void RemoveCommand(String cmd_name)
+ {
+ cmd_function_t cmd, back= null;
- back = cmd = cmd_functions;
+ back= cmd= cmd_functions;
- while (true) {
+ while (true)
+ {
- if (cmd == null) {
+ if (cmd == null)
+ {
Com.Printf("Cmd_RemoveCommand: " + cmd_name + " not added\n");
return;
}
- if (0 == strcmp(cmd_name, cmd.name)) {
+ if (0 == strcmp(cmd_name, cmd.name))
+ {
if (cmd == cmd_functions)
- cmd_functions = cmd.next;
+ cmd_functions= cmd.next;
else
- back.next = cmd.next;
+ back.next= cmd.next;
return;
}
- back = cmd;
- cmd = cmd.next;
+ back= cmd;
+ cmd= cmd.next;
}
}
@@ -346,10 +389,12 @@ public final class Cmd extends PlayerView {
Cmd_Exists
============
*/
- public static boolean Exists(String cmd_name) {
+ public static boolean Exists(String cmd_name)
+ {
cmd_function_t cmd;
- for (cmd = cmd_functions; cmd != null; cmd = cmd.next) {
+ for (cmd= cmd_functions; cmd != null; cmd= cmd.next)
+ {
if (0 == strcmp(cmd_name, cmd.name))
return true;
}
@@ -357,17 +402,20 @@ public final class Cmd extends PlayerView {
return false;
}
- public static int Argc() {
+ public static int Argc()
+ {
return cmd_argc;
}
- public static String Argv(int i) {
+ public static String Argv(int i)
+ {
if (i < 0 || i >= cmd_argc)
return "";
return cmd_argv[i];
}
- public static String Args() {
+ public static String Args()
+ {
return new String(cmd_args);
}
@@ -379,48 +427,49 @@ public final class Cmd extends PlayerView {
FIXME: lookupnoadd the token to speed search?
============
*/
- public static void ExecuteString(String text) {
+ public static void ExecuteString(String text)
+ {
cmd_function_t cmd;
cmdalias_t a;
TokenizeString(text.toCharArray(), true);
-// if (Argc() > 0) {
-// Com.DPrintf("tokenized:");
-// for (int xxx = 0; xxx < Argc(); xxx++)
-// Com.DPrintf("[" + Argv(xxx) + "]");
-//
-// Com.DPrintf("\n");
-// }
+ // if (Argc() > 0) {
+ // Com.DPrintf("tokenized:");
+ // for (int xxx = 0; xxx < Argc(); xxx++)
+ // Com.DPrintf("[" + Argv(xxx) + "]");
+ //
+ // Com.DPrintf("\n");
+ // }
// execute the command line
if (Argc() == 0)
return; // no tokens
// check functions
- for (cmd = cmd_functions; cmd != null; cmd = cmd.next) {
- if (cmd_argv[0].equalsIgnoreCase(cmd.name)) {
- if (null == cmd.function) { // forward to server command
+ for (cmd= cmd_functions; cmd != null; cmd= cmd.next)
+ {
+ if (cmd_argv[0].equalsIgnoreCase(cmd.name))
+ {
+ if (null == cmd.function)
+ { // forward to server command
Cmd.ExecuteString("cmd " + text);
+ } else {
+ cmd.function.execute();
}
- else
- try {
- cmd.function.execute();
- }
- catch (Exception e) {
- System.err.println("Exception in executing a command " + cmd.name + ":");
- e.printStackTrace();
- }
return;
}
}
// check alias
- for (a = cmd_alias; a != null; a = a.next) {
+ for (a= cmd_alias; a != null; a= a.next)
+ {
- if (cmd_argv[0].equalsIgnoreCase(a.name)) {
+ if (cmd_argv[0].equalsIgnoreCase(a.name))
+ {
- if (++alias_count == ALIAS_LOOP_COUNT) {
+ if (++alias_count == ALIAS_LOOP_COUNT)
+ {
Com.Printf("ALIAS_LOOP_COUNT\n");
return;
}
@@ -444,7 +493,8 @@ public final class Cmd extends PlayerView {
Give items to a client
==================
*/
- public static void Give_f(edict_t ent) {
+ public static void Give_f(edict_t ent)
+ {
String name;
gitem_t it;
int index;
@@ -452,30 +502,34 @@ public final class Cmd extends PlayerView {
boolean give_all;
edict_t it_ent;
- if (GameBase.deathmatch.value == 0 && GameBase.sv_cheats.value == 0) {
+ if (GameBase.deathmatch.value == 0 && GameBase.sv_cheats.value == 0)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
return;
}
- name = GameBase.gi.args();
+ name= GameBase.gi.args();
if (0 == Lib.Q_stricmp(name, "all"))
- give_all = true;
+ give_all= true;
else
- give_all = false;
+ give_all= false;
- if (give_all || 0 == Lib.Q_stricmp(GameBase.gi.argv(1), "health")) {
+ if (give_all || 0 == Lib.Q_stricmp(GameBase.gi.argv(1), "health"))
+ {
if (GameBase.gi.argc() == 3)
- ent.health = Lib.atoi(GameBase.gi.argv(2));
+ ent.health= Lib.atoi(GameBase.gi.argv(2));
else
- ent.health = ent.max_health;
+ ent.health= ent.max_health;
if (!give_all)
return;
}
- if (give_all || 0 == Lib.Q_stricmp(name, "weapons")) {
- for (i = 1; i < GameBase.game.num_items; i++) {
- it = GameAI.itemlist[i];
+ if (give_all || 0 == Lib.Q_stricmp(name, "weapons"))
+ {
+ for (i= 1; i < GameBase.game.num_items; i++)
+ {
+ it= GameAI.itemlist[i];
if (null == it.pickup)
continue;
if (0 == (it.flags & Defines.IT_WEAPON))
@@ -486,9 +540,11 @@ public final class Cmd extends PlayerView {
return;
}
- if (give_all || 0 == Lib.Q_stricmp(name, "ammo")) {
- for (i = 1; i < GameBase.game.num_items; i++) {
- it = GameAI.itemlist[i];
+ if (give_all || 0 == Lib.Q_stricmp(name, "ammo"))
+ {
+ for (i= 1; i < GameBase.game.num_items; i++)
+ {
+ it= GameAI.itemlist[i];
if (null == it.pickup)
continue;
if (0 == (it.flags & Defines.IT_AMMO))
@@ -499,27 +555,29 @@ public final class Cmd extends PlayerView {
return;
}
- if (give_all || Lib.Q_stricmp(name, "armor") == 0) {
+ if (give_all || Lib.Q_stricmp(name, "armor") == 0)
+ {
gitem_armor_t info;
- it = GameUtil.FindItem("Jacket Armor");
- ent.client.pers.inventory[GameUtil.ITEM_INDEX(it)] = 0;
+ it= GameUtil.FindItem("Jacket Armor");
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(it)]= 0;
- it = GameUtil.FindItem("Combat Armor");
- ent.client.pers.inventory[GameUtil.ITEM_INDEX(it)] = 0;
+ it= GameUtil.FindItem("Combat Armor");
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(it)]= 0;
- it = GameUtil.FindItem("Body Armor");
- info = (gitem_armor_t) it.info;
- ent.client.pers.inventory[GameUtil.ITEM_INDEX(it)] = info.max_count;
+ it= GameUtil.FindItem("Body Armor");
+ info= (gitem_armor_t) it.info;
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(it)]= info.max_count;
if (!give_all)
return;
}
- if (give_all || Lib.Q_stricmp(name, "Power Shield") == 0) {
- it = GameUtil.FindItem("Power Shield");
- it_ent = GameUtil.G_Spawn();
- it_ent.classname = it.classname;
+ if (give_all || Lib.Q_stricmp(name, "Power Shield") == 0)
+ {
+ it= GameUtil.FindItem("Power Shield");
+ it_ent= GameUtil.G_Spawn();
+ it_ent.classname= it.classname;
GameAI.SpawnItem(it_ent, it);
GameAI.Touch_Item(it_ent, ent, GameBase.dummyplane, null);
if (it_ent.inuse)
@@ -529,44 +587,51 @@ public final class Cmd extends PlayerView {
return;
}
- if (give_all) {
- for (i = 1; i < GameBase.game.num_items; i++) {
- it = GameAI.itemlist[i];
+ if (give_all)
+ {
+ for (i= 1; i < GameBase.game.num_items; i++)
+ {
+ it= GameAI.itemlist[i];
if (it.pickup != null)
continue;
if ((it.flags & (Defines.IT_ARMOR | Defines.IT_WEAPON | Defines.IT_AMMO)) != 0)
continue;
- ent.client.pers.inventory[i] = 1;
+ ent.client.pers.inventory[i]= 1;
}
return;
}
- it = GameUtil.FindItem(name);
- if (it == null) {
- name = GameBase.gi.argv(1);
- it = GameUtil.FindItem(name);
- if (it == null) {
+ it= GameUtil.FindItem(name);
+ if (it == null)
+ {
+ name= GameBase.gi.argv(1);
+ it= GameUtil.FindItem(name);
+ if (it == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "unknown item\n");
return;
}
}
- if (it.pickup == null) {
+ if (it.pickup == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "non-pickup item\n");
return;
}
- index = GameUtil.ITEM_INDEX(it);
+ index= GameUtil.ITEM_INDEX(it);
- if ((it.flags & Defines.IT_AMMO) != 0) {
+ if ((it.flags & Defines.IT_AMMO) != 0)
+ {
if (GameBase.gi.argc() == 3)
- ent.client.pers.inventory[index] = Lib.atoi(GameBase.gi.argv(2));
+ ent.client.pers.inventory[index]= Lib.atoi(GameBase.gi.argv(2));
else
ent.client.pers.inventory[index] += it.quantity;
}
- else {
- it_ent = GameUtil.G_Spawn();
- it_ent.classname = it.classname;
+ else
+ {
+ it_ent= GameUtil.G_Spawn();
+ it_ent.classname= it.classname;
GameAI.SpawnItem(it_ent, it);
GameAI.Touch_Item(it_ent, ent, GameBase.dummyplane, null);
if (it_ent.inuse)
@@ -583,19 +648,21 @@ public final class Cmd extends PlayerView {
argv(0) god
==================
*/
- public static void God_f(edict_t ent) {
+ public static void God_f(edict_t ent)
+ {
String msg;
- if (GameBase.deathmatch.value == 0 && GameBase.sv_cheats.value == 0) {
+ if (GameBase.deathmatch.value == 0 && GameBase.sv_cheats.value == 0)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
return;
}
ent.flags ^= Defines.FL_GODMODE;
if (0 == (ent.flags & Defines.FL_GODMODE))
- msg = "godmode OFF\n";
+ msg= "godmode OFF\n";
else
- msg = "godmode ON\n";
+ msg= "godmode ON\n";
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, msg);
}
@@ -609,19 +676,21 @@ public final class Cmd extends PlayerView {
argv(0) notarget
==================
*/
- public static void Notarget_f(edict_t ent) {
+ public static void Notarget_f(edict_t ent)
+ {
String msg;
- if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0) {
+ if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
return;
}
ent.flags ^= Defines.FL_NOTARGET;
if (0 == (ent.flags & Defines.FL_NOTARGET))
- msg = "notarget OFF\n";
+ msg= "notarget OFF\n";
else
- msg = "notarget ON\n";
+ msg= "notarget ON\n";
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, msg);
}
@@ -633,21 +702,25 @@ public final class Cmd extends PlayerView {
argv(0) noclip
==================
*/
- public static void Noclip_f(edict_t ent) {
+ public static void Noclip_f(edict_t ent)
+ {
String msg;
- if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0) {
+ if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n");
return;
}
- if (ent.movetype == Defines.MOVETYPE_NOCLIP) {
- ent.movetype = Defines.MOVETYPE_WALK;
- msg = "noclip OFF\n";
+ if (ent.movetype == Defines.MOVETYPE_NOCLIP)
+ {
+ ent.movetype= Defines.MOVETYPE_WALK;
+ msg= "noclip OFF\n";
}
- else {
- ent.movetype = Defines.MOVETYPE_NOCLIP;
- msg = "noclip ON\n";
+ else
+ {
+ ent.movetype= Defines.MOVETYPE_NOCLIP;
+ msg= "noclip ON\n";
}
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, msg);
@@ -660,23 +733,27 @@ public final class Cmd extends PlayerView {
Use an inventory item
==================
*/
- public static void Use_f(edict_t ent) {
+ public static void Use_f(edict_t ent)
+ {
int index;
gitem_t it;
String s;
- s = GameBase.gi.args();
- it = GameUtil.FindItem(s);
- if (it == null) {
+ s= GameBase.gi.args();
+ it= GameUtil.FindItem(s);
+ if (it == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "unknown item: " + s + "\n");
return;
}
- if (it.use == null) {
+ if (it.use == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Item is not usable.\n");
return;
}
- index = GameUtil.ITEM_INDEX(it);
- if (0 == ent.client.pers.inventory[index]) {
+ index= GameUtil.ITEM_INDEX(it);
+ if (0 == ent.client.pers.inventory[index])
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Out of item: " + s + "\n");
return;
}
@@ -691,23 +768,27 @@ public final class Cmd extends PlayerView {
Drop an inventory item
==================
*/
- public static void Drop_f(edict_t ent) {
+ public static void Drop_f(edict_t ent)
+ {
int index;
gitem_t it;
String s;
- s = GameBase.gi.args();
- it = GameUtil.FindItem(s);
- if (it == null) {
+ s= GameBase.gi.args();
+ it= GameUtil.FindItem(s);
+ if (it == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "unknown item: " + s + "\n");
return;
}
- if (it.drop == null) {
+ if (it.drop == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Item is not dropable.\n");
return;
}
- index = GameUtil.ITEM_INDEX(it);
- if (0 == ent.client.pers.inventory[index]) {
+ index= GameUtil.ITEM_INDEX(it);
+ if (0 == ent.client.pers.inventory[index])
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Out of item: " + s + "\n");
return;
}
@@ -720,24 +801,27 @@ public final class Cmd extends PlayerView {
Cmd_Inven_f
=================
*/
- public static void Inven_f(edict_t ent) {
+ public static void Inven_f(edict_t ent)
+ {
int i;
gclient_t cl;
- cl = ent.client;
+ cl= ent.client;
- cl.showscores = false;
- cl.showhelp = false;
+ cl.showscores= false;
+ cl.showhelp= false;
- if (cl.showinventory) {
- cl.showinventory = false;
+ if (cl.showinventory)
+ {
+ cl.showinventory= false;
return;
}
- cl.showinventory = true;
+ cl.showinventory= true;
GameBase.gi.WriteByte(Defines.svc_inventory);
- for (i = 0; i < Defines.MAX_ITEMS; i++) {
+ for (i= 0; i < Defines.MAX_ITEMS; i++)
+ {
GameBase.gi.WriteShort(cl.pers.inventory[i]);
}
GameBase.gi.unicast(ent, true);
@@ -748,18 +832,21 @@ public final class Cmd extends PlayerView {
Cmd_InvUse_f
=================
*/
- public static void InvUse_f(edict_t ent) {
+ public static void InvUse_f(edict_t ent)
+ {
gitem_t it;
GameAI.ValidateSelectedItem(ent);
- if (ent.client.pers.selected_item == -1) {
+ if (ent.client.pers.selected_item == -1)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "No item to use.\n");
return;
}
- it = GameAI.itemlist[ent.client.pers.selected_item];
- if (it.use == null) {
+ it= GameAI.itemlist[ent.client.pers.selected_item];
+ if (it.use == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Item is not usable.\n");
return;
}
@@ -771,26 +858,28 @@ public final class Cmd extends PlayerView {
Cmd_WeapPrev_f
=================
*/
- public static void WeapPrev_f(edict_t ent) {
+ public static void WeapPrev_f(edict_t ent)
+ {
gclient_t cl;
int i, index;
gitem_t it;
int selected_weapon;
- cl = ent.client;
+ cl= ent.client;
if (cl.pers.weapon == null)
return;
- selected_weapon = GameUtil.ITEM_INDEX(cl.pers.weapon);
+ selected_weapon= GameUtil.ITEM_INDEX(cl.pers.weapon);
// scan for the next valid one
- for (i = 1; i <= Defines.MAX_ITEMS; i++) {
- index = (selected_weapon + i) % Defines.MAX_ITEMS;
+ for (i= 1; i <= Defines.MAX_ITEMS; i++)
+ {
+ index= (selected_weapon + i) % Defines.MAX_ITEMS;
if (0 == cl.pers.inventory[index])
continue;
- it = GameAI.itemlist[index];
+ it= GameAI.itemlist[index];
if (it.use == null)
continue;
@@ -807,27 +896,30 @@ public final class Cmd extends PlayerView {
Cmd_WeapNext_f
=================
*/
- public static void WeapNext_f(edict_t ent) {
+ public static void WeapNext_f(edict_t ent)
+ {
gclient_t cl;
int i, index;
gitem_t it;
int selected_weapon;
- cl = ent.client;
+ cl= ent.client;
if (null == cl.pers.weapon)
return;
- selected_weapon = GameUtil.ITEM_INDEX(cl.pers.weapon);
+ selected_weapon= GameUtil.ITEM_INDEX(cl.pers.weapon);
// scan for the next valid one
- for (i = 1; i <= Defines.MAX_ITEMS; i++) {
- index = (selected_weapon + Defines.MAX_ITEMS - i) % Defines.MAX_ITEMS;
+ for (i= 1; i <= Defines.MAX_ITEMS; i++)
+ {
+ index= (selected_weapon + Defines.MAX_ITEMS - i) % Defines.MAX_ITEMS;
//bugfix rst
- if (index == 0) index++;
+ if (index == 0)
+ index++;
if (0 == cl.pers.inventory[index])
continue;
- it = GameAI.itemlist[index];
+ it= GameAI.itemlist[index];
if (null == it.use)
continue;
if (0 == (it.flags & Defines.IT_WEAPON))
@@ -843,20 +935,21 @@ public final class Cmd extends PlayerView {
Cmd_WeapLast_f
=================
*/
- public static void WeapLast_f(edict_t ent) {
+ public static void WeapLast_f(edict_t ent)
+ {
gclient_t cl;
int index;
gitem_t it;
- cl = ent.client;
+ cl= ent.client;
if (null == cl.pers.weapon || null == cl.pers.lastweapon)
return;
- index = GameUtil.ITEM_INDEX(cl.pers.lastweapon);
+ index= GameUtil.ITEM_INDEX(cl.pers.lastweapon);
if (0 == cl.pers.inventory[index])
return;
- it = GameAI.itemlist[index];
+ it= GameAI.itemlist[index];
if (null == it.use)
return;
if (0 == (it.flags & Defines.IT_WEAPON))
@@ -869,18 +962,21 @@ public final class Cmd extends PlayerView {
Cmd_InvDrop_f
=================
*/
- public static void InvDrop_f(edict_t ent) {
+ public static void InvDrop_f(edict_t ent)
+ {
gitem_t it;
GameAI.ValidateSelectedItem(ent);
- if (ent.client.pers.selected_item == -1) {
+ if (ent.client.pers.selected_item == -1)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "No item to drop.\n");
return;
}
- it = GameAI.itemlist[ent.client.pers.selected_item];
- if (it.drop == null) {
+ it= GameAI.itemlist[ent.client.pers.selected_item];
+ if (it.drop == null)
+ {
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "Item is not dropable.\n");
return;
}
@@ -894,19 +990,21 @@ public final class Cmd extends PlayerView {
Display the scoreboard
==================
*/
- public static void Score_f(edict_t ent) {
- ent.client.showinventory = false;
- ent.client.showhelp = false;
+ public static void Score_f(edict_t ent)
+ {
+ ent.client.showinventory= false;
+ ent.client.showhelp= false;
if (0 == GameBase.deathmatch.value && 0 == GameBase.coop.value)
return;
- if (ent.client.showscores) {
- ent.client.showscores = false;
+ if (ent.client.showscores)
+ {
+ ent.client.showscores= false;
return;
}
- ent.client.showscores = true;
+ ent.client.showscores= true;
GameAI.DeathmatchScoreboard(ent);
}
@@ -917,23 +1015,26 @@ public final class Cmd extends PlayerView {
Display the current help message
==================
*/
- public static void Help_f(edict_t ent) {
+ public static void Help_f(edict_t ent)
+ {
// this is for backwards compatability
- if (GameBase.deathmatch.value != 0) {
+ if (GameBase.deathmatch.value != 0)
+ {
Score_f(ent);
return;
}
- ent.client.showinventory = false;
- ent.client.showscores = false;
+ ent.client.showinventory= false;
+ ent.client.showscores= false;
- if (ent.client.showhelp && (ent.client.pers.game_helpchanged == GameBase.game.helpchanged)) {
- ent.client.showhelp = false;
+ if (ent.client.showhelp && (ent.client.pers.game_helpchanged == GameBase.game.helpchanged))
+ {
+ ent.client.showhelp= false;
return;
}
- ent.client.showhelp = true;
- ent.client.pers.helpchanged = 0;
+ ent.client.showhelp= true;
+ ent.client.pers.helpchanged= 0;
GameAI.HelpComputer(ent);
}
@@ -944,12 +1045,13 @@ public final class Cmd extends PlayerView {
Cmd_Kill_f
=================
*/
- public static void Kill_f(edict_t ent) {
+ public static void Kill_f(edict_t ent)
+ {
if ((GameBase.level.time - ent.client.respawn_time) < 5)
return;
ent.flags &= ~Defines.FL_GODMODE;
- ent.health = 0;
- GameBase.meansOfDeath = Defines.MOD_SUICIDE;
+ ent.health= 0;
+ GameBase.meansOfDeath= Defines.MOD_SUICIDE;
GameAIAdapters.player_die.die(ent, ent, ent, 100000, GameBase.vec3_origin);
}
@@ -958,10 +1060,11 @@ public final class Cmd extends PlayerView {
Cmd_PutAway_f
=================
*/
- public static void PutAway_f(edict_t ent) {
- ent.client.showscores = false;
- ent.client.showhelp = false;
- ent.client.showinventory = false;
+ public static void PutAway_f(edict_t ent)
+ {
+ ent.client.showscores= false;
+ ent.client.showhelp= false;
+ ent.client.showinventory= false;
}
@@ -970,18 +1073,21 @@ public final class Cmd extends PlayerView {
Cmd_Players_f
=================
*/
- public static void Players_f(edict_t ent) {
+ public static void Players_f(edict_t ent)
+ {
int i;
int count;
String small;
String large;
- Integer index[] = new Integer[256];
+ Integer index[]= new Integer[256];
- count = 0;
- for (i = 0; i < GameBase.maxclients.value; i++) {
- if (GameBase.game.clients[i].pers.connected) {
- index[count] = new Integer(i);
+ count= 0;
+ for (i= 0; i < GameBase.maxclients.value; i++)
+ {
+ if (GameBase.game.clients[i].pers.connected)
+ {
+ index[count]= new Integer(i);
count++;
}
}
@@ -992,16 +1098,18 @@ public final class Cmd extends PlayerView {
Arrays.sort(index, 0, count - 1, GameAIAdapters.PlayerSort);
// print information
- large = "";
+ large= "";
- for (i = 0; i < count; i++) {
- small =
+ for (i= 0; i < count; i++)
+ {
+ small=
GameBase.game.clients[index[i].intValue()].ps.stats[Defines.STAT_FRAGS]
+ " "
+ GameBase.game.clients[index[i].intValue()].pers.netname
+ "\n";
- if (small.length() + large.length() > 1024 - 100) {
+ if (small.length() + large.length() > 1024 - 100)
+ {
// can't print all of them in one packet
large += "...\n";
break;
@@ -1017,10 +1125,11 @@ public final class Cmd extends PlayerView {
Cmd_Wave_f
=================
*/
- public static void Wave_f(edict_t ent) {
+ public static void Wave_f(edict_t ent)
+ {
int i;
- i = Lib.atoi(GameBase.gi.argv(1));
+ i= Lib.atoi(GameBase.gi.argv(1));
// can't wave when ducked
if ((ent.client.ps.pmove.pm_flags & Defines.PMF_DUCKED) != 0)
@@ -1029,34 +1138,35 @@ public final class Cmd extends PlayerView {
if (ent.client.anim_priority > Defines.ANIM_WAVE)
return;
- ent.client.anim_priority = Defines.ANIM_WAVE;
+ ent.client.anim_priority= Defines.ANIM_WAVE;
- switch (i) {
+ switch (i)
+ {
case 0 :
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "flipoff\n");
- ent.s.frame = M_Player.FRAME_flip01 - 1;
- ent.client.anim_end = M_Player.FRAME_flip12;
+ ent.s.frame= M_Player.FRAME_flip01 - 1;
+ ent.client.anim_end= M_Player.FRAME_flip12;
break;
case 1 :
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "salute\n");
- ent.s.frame = M_Player.FRAME_salute01 - 1;
- ent.client.anim_end = M_Player.FRAME_salute11;
+ ent.s.frame= M_Player.FRAME_salute01 - 1;
+ ent.client.anim_end= M_Player.FRAME_salute11;
break;
case 2 :
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "taunt\n");
- ent.s.frame = M_Player.FRAME_taunt01 - 1;
- ent.client.anim_end = M_Player.FRAME_taunt17;
+ ent.s.frame= M_Player.FRAME_taunt01 - 1;
+ ent.client.anim_end= M_Player.FRAME_taunt17;
break;
case 3 :
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "wave\n");
- ent.s.frame = M_Player.FRAME_wave01 - 1;
- ent.client.anim_end = M_Player.FRAME_wave11;
+ ent.s.frame= M_Player.FRAME_wave01 - 1;
+ ent.client.anim_end= M_Player.FRAME_wave11;
break;
case 4 :
default :
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "point\n");
- ent.s.frame = M_Player.FRAME_point01 - 1;
- ent.client.anim_end = M_Player.FRAME_point12;
+ ent.s.frame= M_Player.FRAME_point01 - 1;
+ ent.client.anim_end= M_Player.FRAME_point12;
break;
}
}
@@ -1066,7 +1176,8 @@ public final class Cmd extends PlayerView {
Cmd_Say_f
==================
*/
- public static void Say_f(edict_t ent, boolean team, boolean arg0) {
+ public static void Say_f(edict_t ent, boolean team, boolean arg0)
+ {
int i, j;
edict_t other;
@@ -1077,19 +1188,21 @@ public final class Cmd extends PlayerView {
return;
if (0 == ((int) (dmflags.value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
- team = false;
+ team= false;
if (team)
- text = "(" + ent.client.pers.netname + "): ";
+ text= "(" + ent.client.pers.netname + "): ";
else
- text = "" + ent.client.pers.netname + ": ";
+ text= "" + ent.client.pers.netname + ": ";
- if (arg0) {
+ if (arg0)
+ {
strcat(text, gi.argv(0));
strcat(text, " ");
strcat(text, gi.args());
}
- else {
+ else
+ {
if (gi.args().startsWith("\""))
text += gi.args().substring(1, gi.args().length() - 1);
else
@@ -1109,41 +1222,46 @@ public final class Cmd extends PlayerView {
// don't let text be too long for malicious reasons
if (text.length() > 150)
//text[150] = 0;
- text = text.substring(0, 150);
+ text= text.substring(0, 150);
strcat(text, "\n");
- if (flood_msgs.value != 0) {
- cl = ent.client;
+ if (flood_msgs.value != 0)
+ {
+ cl= ent.client;
- if (level.time < cl.flood_locktill) {
+ if (level.time < cl.flood_locktill)
+ {
gi.cprintf(ent, PRINT_HIGH, "You can't talk for " + (int) (cl.flood_locktill - level.time) + " more seconds\n");
return;
}
- i = (int) (cl.flood_whenhead - flood_msgs.value + 1);
+ i= (int) (cl.flood_whenhead - flood_msgs.value + 1);
if (i < 0)
//i = (sizeof(cl.flood_when) / sizeof(cl.flood_when[0])) + i;
- i = (10) + i;
- if (cl.flood_when[i] != 0 && level.time - cl.flood_when[i] < flood_persecond.value) {
- cl.flood_locktill = level.time + flood_waitdelay.value;
+ i= (10) + i;
+ if (cl.flood_when[i] != 0 && level.time - cl.flood_when[i] < flood_persecond.value)
+ {
+ cl.flood_locktill= level.time + flood_waitdelay.value;
gi.cprintf(ent, PRINT_CHAT, "Flood protection: You can't talk for " + (int) flood_waitdelay.value + " seconds.\n");
return;
}
//cl.flood_whenhead = (cl.flood_whenhead + 1) % (sizeof(cl.flood_when) / sizeof(cl.flood_when[0]));
- cl.flood_whenhead = (cl.flood_whenhead + 1) % 10;
- cl.flood_when[cl.flood_whenhead] = level.time;
+ cl.flood_whenhead= (cl.flood_whenhead + 1) % 10;
+ cl.flood_when[cl.flood_whenhead]= level.time;
}
if (dedicated.value != 0)
gi.cprintf(null, PRINT_CHAT, "" + text + "");
- for (j = 1; j <= game.maxclients; j++) {
- other = g_edicts[j];
+ for (j= 1; j <= game.maxclients; j++)
+ {
+ other= g_edicts[j];
if (!other.inuse)
continue;
if (other.client == null)
continue;
- if (team) {
+ if (team)
+ {
if (!OnSameTeam(ent, other))
continue;
}
@@ -1154,23 +1272,25 @@ public final class Cmd extends PlayerView {
/**
* Returns the playerlist.
- * TODO: The list is badly formatted at the moment, RST.
+ * TODO: The list is badly formatted at the moment.
*/
- public static void PlayerList_f(edict_t ent) {
+ public static void PlayerList_f(edict_t ent)
+ {
int i;
String st;
String text;
edict_t e2;
// connect time, ping, score, name
- text = "";
+ text= "";
- for (i = 0; i < GameBase.maxclients.value; i++) {
- e2 = GameBase.g_edicts[1 + i];
+ for (i= 0; i < GameBase.maxclients.value; i++)
+ {
+ e2= GameBase.g_edicts[1 + i];
if (!e2.inuse)
continue;
- st =
+ st=
""
+ (GameBase.level.framenum - e2.client.resp.enterframe) / 600
+ ":"
@@ -1185,7 +1305,8 @@ public final class Cmd extends PlayerView {
+ (e2.client.resp.spectator ? " (spectator)" : "")
+ "\n";
- if (text.length() + st.length() > 1024 - 50) {
+ if (text.length() + st.length() > 1024 - 50)
+ {
text += "And more...\n";
GameBase.gi.cprintf(ent, Defines.PRINT_HIGH, "" + text + "");
return;
@@ -1196,7 +1317,7 @@ public final class Cmd extends PlayerView {
}
// ======================================================================
-
+
/*
===================
Cmd_ForwardToServer
@@ -1206,18 +1327,21 @@ public final class Cmd extends PlayerView {
so when they are typed in at the console, they will need to be forwarded.
===================
*/
- public static void ForwardToServer() {
+ public static void ForwardToServer()
+ {
String cmd;
-
- cmd = Cmd.Argv(0);
- if (Globals.cls.state <= Defines.ca_connected || cmd.charAt(0) == '-' || cmd.charAt(0) == '+') {
+
+ cmd= Cmd.Argv(0);
+ if (Globals.cls.state <= Defines.ca_connected || cmd.charAt(0) == '-' || cmd.charAt(0) == '+')
+ {
Com.Printf("Unknown command \"" + cmd + "\"\n");
return;
}
-
+
MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_stringcmd);
SZ.Print(Globals.cls.netchan.message, cmd);
- if (Cmd.Argc() > 1) {
+ if (Cmd.Argc() > 1)
+ {
SZ.Print(Globals.cls.netchan.message, " ");
SZ.Print(Globals.cls.netchan.message, Cmd.Args());
}
diff --git a/src/jake2/game/GameBase.java b/src/jake2/game/GameBase.java
index ef1e1c9..871e084 100644
--- a/src/jake2/game/GameBase.java
+++ b/src/jake2/game/GameBase.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 30.11.2003 by RST.
-// $Id: GameBase.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: GameBase.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
/** Father of all Objects. */
@@ -817,24 +817,8 @@ public class GameBase extends Globals
continue;
}
- //TODO: RST: disabled for debugging;
- //if (!ent.classname.startsWith("monster") || ent.index == 312)
- G_RunEntity(ent);
-
- // if (ent == g_edicts[307])
- // G_RunEntity(ent);
- // else if (ent == g_edicts[1])
- // G_RunEntity(ent);
- //
- // else if (true)
- // if (ent.classname.startsWith("monster")
- // || ent.classname.startsWith("trigger")
- // || ent.classname.startsWith("target")
- // || ent.classname.startsWith(
- // "misc_explo") //ent.classname.startsWith("func_door")
- // ) //|| ent.classname.startsWith("monster"))
- // G_RunEntity(ent);
+ G_RunEntity(ent);
}
// see if it is time to end a deathmatch
diff --git a/src/jake2/game/GameFunc.java b/src/jake2/game/GameFunc.java
index 8860b00..091056f 100644
--- a/src/jake2/game/GameFunc.java
+++ b/src/jake2/game/GameFunc.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 18.11.2003 by RST.
-// $Id: GameFunc.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: GameFunc.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -38,9 +38,6 @@ public class GameFunc extends PlayerView
Math3D.VectorSubtract(dest, ent.s.origin, ent.moveinfo.dir);
ent.moveinfo.remaining_distance = Math3D.VectorNormalize(ent.moveinfo.dir);
- //TODO: BIG HACK !!!
- if (ent.moveinfo.remaining_distance == 2)
- ent.moveinfo.remaining_distance = 94;
ent.moveinfo.endfunc = func;
if (ent.moveinfo.speed == ent.moveinfo.accel && ent.moveinfo.speed == ent.moveinfo.decel)
diff --git a/src/jake2/game/GameSVCmds.java b/src/jake2/game/GameSVCmds.java
index dc0b4f9..1d1c244 100644
--- a/src/jake2/game/GameSVCmds.java
+++ b/src/jake2/game/GameSVCmds.java
@@ -19,22 +19,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 01.02.2004 by RST.
-// $Id: GameSVCmds.java,v 1.1 2004-07-07 19:59:00 hzi Exp $
+// $Id: GameSVCmds.java,v 1.2 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
+import jake2.qcommon.Com;
+
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.StringTokenizer;
-import com.sun.corba.se.internal.ior.ByteBuffer;
-
-import jake2.*;
-import jake2.client.*;
-import jake2.qcommon.*;
-import jake2.render.*;
-import jake2.server.*;
-
public class GameSVCmds extends GameSpawn {
public static void Svcmd_Test_f() {
diff --git a/src/jake2/game/GameSpawn.java b/src/jake2/game/GameSpawn.java
index edb8cab..34412fd 100644
--- a/src/jake2/game/GameSpawn.java
+++ b/src/jake2/game/GameSpawn.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 18.11.2003 by RST.
-// $Id: GameSpawn.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: GameSpawn.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -305,7 +305,7 @@ public class GameSpawn extends GameSave {
e.teammaster = e;
c++;
c2++;
- Com.Printf("Team:" + e.team+" entity: " + e.index + "\n");
+ //Com.Printf("Team:" + e.team+" entity: " + e.index + "\n");
for (j = i + 1; j < globals.num_edicts; j++) {
e2 = g_edicts[j];
if (!e2.inuse)
@@ -427,7 +427,7 @@ public class GameSpawn extends GameSave {
ED_CallSpawn(ent);
}
//gi.dprintf("player skill level:" +skill.value + "\n");
- gi.dprintf(inhibit + " entities inhibited\n");
+ //gi.dprintf(inhibit + " entities inhibited\n");
i = 1;
G_FindTeams();
PlayerTrail.Init();
diff --git a/src/jake2/game/GameUtil.java b/src/jake2/game/GameUtil.java
index ee52a89..a5d81ad 100644
--- a/src/jake2/game/GameUtil.java
+++ b/src/jake2/game/GameUtil.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 01.11.2003 by RST.
-// $Id: GameUtil.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: GameUtil.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -280,7 +280,6 @@ public class GameUtil extends GameBase
return false;
}
- /** TODO: test, / replaced the string operations. */
static String ClientTeam(edict_t ent)
{
String value;
diff --git a/src/jake2/game/GameUtilAdapters.java b/src/jake2/game/GameUtilAdapters.java
index 4a3c320..6191270 100644
--- a/src/jake2/game/GameUtilAdapters.java
+++ b/src/jake2/game/GameUtilAdapters.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 26.02.2004 by RST.
-// $Id: GameUtilAdapters.java,v 1.1 2004-07-08 15:58:44 hzi Exp $
+// $Id: GameUtilAdapters.java,v 1.2 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -310,7 +310,7 @@ public class GameUtilAdapters
if (!taken)
return;
- Com.p("Picked up:" + ent.classname);
+ //Com.p("Picked up:" + ent.classname);
if (!((GameBase.coop.value != 0) && (ent.item.flags & Defines.IT_STAY_COOP) != 0)
|| 0 != (ent.spawnflags & (Defines.DROPPED_ITEM | Defines.DROPPED_PLAYER_ITEM)))
@@ -322,6 +322,7 @@ public class GameUtilAdapters
}
}
};
+
static EntTouchAdapter drop_temp_touch = new EntTouchAdapter()
{
public void touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
@@ -332,6 +333,7 @@ public class GameUtilAdapters
Touch_Item.touch(ent, other, plane, surf);
}
};
+
static EntThinkAdapter drop_make_touchable = new EntThinkAdapter()
{
public boolean think(edict_t ent)
@@ -398,7 +400,7 @@ public class GameUtilAdapters
ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]--;
//TODO: remove this line
- ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]=0;
+ //ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]=0;
GameUtil.ValidateSelectedItem(ent);
@@ -407,7 +409,7 @@ public class GameUtilAdapters
else
ent.client.breather_framenum = GameBase.level.framenum + 300;
- // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
+ GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
}
};
// ======================================================================
@@ -424,7 +426,7 @@ public class GameUtilAdapters
else
ent.client.enviro_framenum = GameBase.level.framenum + 300;
- // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
+ GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
}
};
// ======================================================================
@@ -458,7 +460,7 @@ public class GameUtilAdapters
GameUtil.ValidateSelectedItem(ent);
ent.client.silencer_shots += 30;
- // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
+ GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
}
};
// ======================================================================
diff --git a/src/jake2/game/M_Actor.java b/src/jake2/game/M_Actor.java
index f48ff77..24484ab 100644
--- a/src/jake2/game/M_Actor.java
+++ b/src/jake2/game/M_Actor.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 11.11.2003 by RST.
-// $Id: M_Actor.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: M_Actor.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -731,7 +731,7 @@ public class M_Actor extends GameAI {
return;
self.pain_debounce_time= level.time + 3;
- // gi.sound (self, CHAN_VOICE, actor.sound_pain, 1, ATTN_NORM, 0);
+ //GameBase.gi.sound (self, CHAN_VOICE, actor.sound_pain, 1, ATTN_NORM, 0);
if ((other.client != null) && (Lib.random() < 0.4)) {
float v[]= { 0, 0, 0 };
diff --git a/src/jake2/game/PlayerHud.java b/src/jake2/game/PlayerHud.java
index b9622e3..244e398 100644
--- a/src/jake2/game/PlayerHud.java
+++ b/src/jake2/game/PlayerHud.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 28.12.2003 by RST.
-// $Id: PlayerHud.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: PlayerHud.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -100,13 +100,15 @@ public class PlayerHud extends GameTarget {
level.intermissiontime = level.time;
// TODO: BIG HACK TO IGNORE CINEMATIC
+
String xxx = targ.map;
int pos = xxx.indexOf(".cin");
if (pos != -1)
level.changemap = xxx.substring(pos + 5); // including "+"
else
level.changemap = xxx;
-
+ // ------------------------
+ //level.changemap = targ.map;
if (level.changemap.indexOf('*') > -1) {
if (coop.value != 0) {
for (i = 0; i < maxclients.value; i++) {
diff --git a/src/jake2/game/game_export_t.java b/src/jake2/game/game_export_t.java
index 792b785..9dabf51 100644
--- a/src/jake2/game/game_export_t.java
+++ b/src/jake2/game/game_export_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 31.10.2003 by RST.
-// $Id: game_export_t.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+// $Id: game_export_t.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -58,8 +58,8 @@ public class game_export_t
// ReadGame is called on a loadgame.
public void WriteGame(String filename, boolean autosave)
{
- // TODO WriteGame not implemnted!
- Com.Println("WriteGame not implemnted!");
+ // TODO WriteGame not implemented.
+ Com.Println("WriteGame not implemented.");
}
public void ReadGame(String filename)
@@ -71,14 +71,14 @@ public class game_export_t
// loaded with SpawnEntities
public void WriteLevel(String filename)
{
- // TODO WriteLevel not implemented!
- Com.Println("WriteLevel not implemented!");
+ // TODO WriteLevel not implemented.
+ Com.Println("WriteLevel not implemented.");
}
public void ReadLevel(String filename)
{
- // TODO ReadLevel not implemnted!
- Com.Println("ReadLevel not implemnted!");
+ // TODO ReadLevel not implemented.
+ Com.Println("ReadLevel not implemented.");
}
public boolean ClientConnect(edict_t ent, String userinfo)
diff --git a/src/jake2/game/player_state_t.java b/src/jake2/game/player_state_t.java
index 3ecc17d..d4ecc72 100644
--- a/src/jake2/game/player_state_t.java
+++ b/src/jake2/game/player_state_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 31.10.2003 by RST.
-// $Id: player_state_t.java,v 1.2 2004-07-08 20:24:29 hzi Exp $
+// $Id: player_state_t.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.game;
@@ -62,7 +62,6 @@ public class player_state_t {
/**
*
*/
- // TODO bugfix cwei
private static player_state_t prototype = new player_state_t();
public void clear() {
diff --git a/src/jake2/imageio/ImageFrame.java b/src/jake2/imageio/ImageFrame.java
deleted file mode 100644
index 52cf9e4..0000000
--- a/src/jake2/imageio/ImageFrame.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Created on Apr 26, 2003
- *
- */
-package jake2.imageio;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.awt.image.BufferedImage;
-import javax.swing.JFrame;
-
-/**
- * @author cwei
- *
- */
-public class ImageFrame extends JFrame {
-
- BufferedImage image;
- Component pane;
-
- public ImageFrame(BufferedImage image) {
- super();
- this.image = image;
-
- pane = getContentPane();
- setIconImage(image);
- setSize(640, 480);
-
- addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- System.exit(0);
- }
- });
- }
-
- public void paint(Graphics g) {
- super.paint(g);
- Graphics2D g2 = (Graphics2D) pane.getGraphics();
- if (this.image != null) {
- g2.drawImage(
- image,
- Math.max(0, (getWidth() - image.getWidth()) / 2),
- Math.max(0, (getHeight() - image.getHeight()) / 2),
- Color.LIGHT_GRAY,
- pane);
- } else {
- g2.drawString(
- "EMPTY IMAGE",
- this.getWidth() / 4,
- this.getHeight() / 2);
- }
- }
-
- public void showImage(BufferedImage image) {
- this.image = image;
- this.repaint();
- }
-
-}
diff --git a/src/jake2/imageio/PCX.java b/src/jake2/imageio/PCX.java
deleted file mode 100644
index eb71465..0000000
--- a/src/jake2/imageio/PCX.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Created on Nov 18, 2003
- *
- */
-package jake2.imageio;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * @author cwei
- *
- */
-public class PCX {
-
- public static final int HEADER_SIZE = 128;
-
- /**
- * <code>
- typedef struct
- {
- char manufacturer;
- char version;
- char encoding;
- char bits_per_pixel;
- unsigned short xmin,ymin,xmax,ymax;
- unsigned short horzRes,vertRes;
- unsigned char palette[48];
- char reserved;
- char color_planes;
- unsigned short bytes_per_line;
- unsigned short palette_type;
- char filler[58];
- unsigned char data; // unbounded
- } pcx_t;
-
- </code>
- */
- public static class Header {
-
- // size of byte arrays
- static final int PALETTE_SIZE = 48;
- static final int FILLER_SIZE = 58;
-
- byte manufacturer;
- byte version;
- byte encoding;
- byte bitsPerPixel;
- int xmin, ymin, xmax, ymax; // unsigned short
- int horzRes, vertRes; // unsigned short
- byte[] palette; //unsigned byte
- byte reserved;
- byte colorPlanes;
- int bytesPerLine; // unsigned short
- int paletteType; // unsigned short
- byte[] filler;
-
-
-
- public Header(byte[] headerBytes) {
- if (headerBytes == null || headerBytes.length != 128) {
- throw new IllegalArgumentException("invalid quake2 pcx header");
- }
-
- ByteBuffer b = ByteBuffer.wrap(headerBytes);
- // is stored as little endian
- b.order(ByteOrder.LITTLE_ENDIAN);
-
- // fill header
- manufacturer = b.get();
- version = b.get();
- encoding = b.get();
- bitsPerPixel = b.get();
- xmin = b.getShort() & 0xffff;
- ymin = b.getShort() & 0xffff;
- xmax = b.getShort() & 0xffff;
- ymax = b.getShort() & 0xffff;
- horzRes = b.getShort() & 0xffff;
- vertRes = b.getShort() & 0xffff;
- b.get(palette = new byte[PALETTE_SIZE]);
- reserved = b.get();
- colorPlanes = b.get();
- bytesPerLine = b.getShort() & 0xffff;
- paletteType = b.getShort() & 0xffff;
- b.get(filler = new byte[FILLER_SIZE]);
-
- // check some attributes
- checkHeader();
- }
-
- private void checkHeader() {
-
- if (this.getManufacturer() != 0x0a
- || this.getVersion() != 5
- || this.getEncoding() != 1
- || this.getBitsPerPixel() != 8
- || this.getXmax() >= 640
- || this.getYmax() >= 480) {
- throw new IllegalArgumentException("invalid quake2 pcx header");
- }
- }
-
- /**
- * @return
- */
- public byte getBitsPerPixel() {
- return bitsPerPixel;
- }
-
- /**
- * @return
- */
- public int getBytesPerLine() {
- return bytesPerLine;
- }
-
- /**
- * @return
- */
- public byte getColorPlanes() {
- return colorPlanes;
- }
-
- /**
- * @return
- */
- public byte getEncoding() {
- return encoding;
- }
-
- /**
- * @return
- */
- public byte[] getFiller() {
- return filler;
- }
-
- /**
- * @return
- */
- public int getHeight() {
- return ymax - ymin + 1;
- }
-
- /**
- * @return
- */
- public byte getManufacturer() {
- return manufacturer;
- }
-
- /**
- * @return
- */
- public byte[] getPalette() {
- return palette;
- }
-
- /**
- * @return
- */
- public int getPaletteType() {
- return paletteType;
- }
-
- /**
- * @return
- */
- public byte getReserved() {
- return reserved;
- }
-
- /**
- * @return
- */
- public byte getVersion() {
- return version;
- }
-
- /**
- * @return
- */
- public int getWidth() {
- return xmax - xmin + 1;
- }
-
- /**
- * @return
- */
- public int getXmax() {
- return xmax;
- }
-
- /**
- * @return
- */
- public int getXmin() {
- return xmin;
- }
-
- /**
- * @return
- */
- public int getYmax() {
- return ymax;
- }
-
- /**
- * @return
- */
- public int getYmin() {
- return ymin;
- }
- /**
- * @return
- */
- public int getHorzRes() {
- return horzRes;
- }
-
- /**
- * @return
- */
- public int getVertRes() {
- return vertRes;
- }
-
- }
-} \ No newline at end of file
diff --git a/src/jake2/imageio/PCXImageReader.java b/src/jake2/imageio/PCXImageReader.java
deleted file mode 100644
index c81e623..0000000
--- a/src/jake2/imageio/PCXImageReader.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Created on Nov 17, 2003
- *
- */
-package jake2.imageio;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.IIOException;
-import javax.imageio.ImageReadParam;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * @author cwei
- *
- */
-public class PCXImageReader extends ImageReader {
-
- private static Logger logger =
- Logger.getLogger(PCXImageReader.class.getName());
-
- ImageInputStream stream = null;
- PCX.Header header = null;
-
- public PCXImageReader(ImageReaderSpi originatingProvider) {
- super(originatingProvider);
- }
-
- public void setInput(Object input, boolean seekForwardOnly) {
- super.setInput(input, seekForwardOnly);
- if (input == null) {
- this.stream = null;
- return;
- }
- if (input instanceof ImageInputStream) {
- this.stream = (ImageInputStream) input;
- } else {
- throw new IllegalArgumentException("bad input");
- }
- }
-
- public int getHeight(int imageIndex) throws IOException {
- checkIndex(imageIndex);
- readHeader();
- return header.getHeight();
- }
-
- public int getWidth(int imageIndex) throws IOException {
- checkIndex(imageIndex);
- readHeader();
- return header.getWidth();
- }
-
- public int getNumImages(boolean allowSearch) throws IOException {
- // only 1 image
- return 1;
- }
-
- public Iterator getImageTypes(int imageIndex) throws IOException {
- checkIndex(imageIndex);
- readHeader();
-
- ImageTypeSpecifier imageType = null;
- java.util.List l = new ArrayList(1);
-
- imageType =
- ImageTypeSpecifier.createIndexed(
- Q2ColorMap.RED,
- Q2ColorMap.GREEN,
- Q2ColorMap.BLUE,
- Q2ColorMap.ALPHA,
- 8,
- DataBuffer.TYPE_BYTE);
-
- l.add(imageType);
- return l.iterator();
- }
-
- public IIOMetadata getStreamMetadata() throws IOException {
- return null;
- }
-
- public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
- return null;
- }
-
- public BufferedImage read(int imageIndex, ImageReadParam param)
- throws IOException {
-
- checkIndex(imageIndex);
- readHeader();
-
- int width = header.getWidth();
- int height = header.getHeight();
-
- // Compute initial source region, clip against destination later
- Rectangle sourceRegion = getSourceRegion(param, width, height);
-
- // Set everything to default values
- int sourceXSubsampling = 1;
- int sourceYSubsampling = 1;
- int[] sourceBands = null;
- int[] destinationBands = null;
- Point destinationOffset = new Point(0, 0);
-
- // Get values from the ImageReadParam, if any
- if (param != null) {
- sourceXSubsampling = param.getSourceXSubsampling();
- sourceYSubsampling = param.getSourceYSubsampling();
- sourceBands = param.getSourceBands();
- destinationBands = param.getDestinationBands();
- destinationOffset = param.getDestinationOffset();
- }
-
- // Get the specified detination image or create a new one
- BufferedImage dst =
- getDestination(param, getImageTypes(0), width, height);
-
- // Enure band settings from param are compatible with images
- int inputBands = 1;
- checkReadParamBandSettings(
- param,
- inputBands,
- dst.getSampleModel().getNumBands());
-
- int[] bandOffsets = new int[inputBands];
- for (int i = 0; i < inputBands; i++) {
- bandOffsets[i] = i;
- }
- int bytesPerRow = width * inputBands;
- DataBufferByte rowDB = new DataBufferByte(bytesPerRow);
- WritableRaster rowRas =
- Raster.createInterleavedRaster(
- rowDB,
- width,
- 1,
- bytesPerRow,
- inputBands,
- bandOffsets,
- new Point(0, 0));
- byte[] rowBuf = rowDB.getData();
-
- // Create an int[] that can a single pixel
- int[] pixel = rowRas.getPixel(0, 0, (int[]) null);
-
- WritableRaster imRas = dst.getWritableTile(0, 0);
- int dstMinX = imRas.getMinX();
- int dstMaxX = dstMinX + imRas.getWidth() - 1;
- int dstMinY = imRas.getMinY();
- int dstMaxY = dstMinY + imRas.getHeight() - 1;
-
- // Create a child raster exposing only the desired source bands
- if (sourceBands != null) {
- rowRas =
- rowRas.createWritableChild(0, 0, width, 1, 0, 0, sourceBands);
- }
-
- // Create a child raster exposing only the desired dest bands
- if (destinationBands != null) {
- imRas =
- imRas.createWritableChild(
- 0,
- 0,
- imRas.getWidth(),
- imRas.getHeight(),
- 0,
- 0,
- destinationBands);
-
- }
-
- int dataByte = 0;
- int runLength = 0;
-
- for (int srcY = 0; srcY < height; srcY++) {
- // Read the row
- try {
- /*
- * run length decoding for PCX images
- */
- int index = 0;
-
- while (index < rowBuf.length) {
- while (runLength-- > 0 && index < rowBuf.length) {
- rowBuf[index++] = (byte) (dataByte & 0xff);
- }
- dataByte = stream.readUnsignedByte();
- if ((dataByte & 0xc0) == 0xc0) {
- runLength = dataByte & 0x3f;
- dataByte = stream.readUnsignedByte();
- } else {
- runLength = 1;
- }
- }
- } catch (IOException e) {
- throw new IIOException("Error reading line " + srcY, e);
- }
-
- // Reject rows that lie outside the source region,
- // or which aren't part of the subsampling
- if ((srcY < sourceRegion.y)
- || (srcY >= sourceRegion.y + sourceRegion.height)
- || (((srcY - sourceRegion.y) % sourceYSubsampling) != 0)) {
- continue;
- }
-
- // Determine where the row will go in the destination
- int dstY =
- destinationOffset.y
- + (srcY - sourceRegion.y) / sourceYSubsampling;
- if (dstY < dstMinY) {
- continue; // The row is above imRas
- }
- if (dstY > dstMaxY) {
- break; // We're done with the image
- }
-
- // Copy each (subsampled) source pixel into imRas
- for (int srcX = sourceRegion.x;
- srcX < sourceRegion.x + sourceRegion.width;
- srcX++) {
- if (((srcX - sourceRegion.x) % sourceXSubsampling) != 0) {
- continue;
- }
- int dstX =
- destinationOffset.x
- + (srcX - sourceRegion.x) / sourceXSubsampling;
- if (dstX < dstMinX) {
- continue; // The pixel is to the left of imRas
- }
- if (dstX > dstMaxX) {
- break; // We're done with the row
- }
-
- // Copy the pixel, sub-banding is done automatically
- rowRas.getPixel(srcX, 0, pixel);
- imRas.setPixel(dstX, dstY, pixel);
- }
- }
- if ((stream.readUnsignedByte()) == 0x0c) {
- logger.log(
- Level.FINE,
- "PCX has a color palette with "
- + (stream.length() - stream.getStreamPosition())
- + " Bytes, but use the default palette (quake2)");
- }
- return dst;
- }
-
- private void checkIndex(int imageIndex) {
- if (imageIndex != 0) {
- throw new IndexOutOfBoundsException("bad image index");
- }
- }
-
-// buggy version
-/* private void decodeRow(byte[] buffer) throws IOException {
- int dataByte = 0;
- int runLength = 0;
- int index = 0;
-
- while (index < buffer.length) {
- dataByte = stream.readUnsignedByte();
- if ((dataByte & 0xc0) == 0xc0) {
- runLength = dataByte & 0x3f;
- dataByte = stream.readUnsignedByte();
- } else {
- runLength = 1;
- }
-
- while (runLength-- > 0 && index < buffer.length) {
- buffer[index++] = (byte) (dataByte & 0xff);
- }
- assert(runLength == -1) : "runLength decoding bug: " + runLength;
- }
- }
-*/
- private void readHeader() throws IIOException {
-
- if (header != null)
- return;
-
- logger.log(Level.FINE, "PCX read header");
-
- if (stream == null) {
- if (this.input == null) {
- throw new IllegalStateException("No input stream");
- }
- stream = (ImageInputStream) input;
- }
-
- byte[] buffer = new byte[PCX.HEADER_SIZE];
-
- try {
- stream.readFully(buffer);
- this.header = new PCX.Header(buffer);
- logger.log(
- Level.FINE,
- "PCX horzRes: "
- + header.getWidth()
- + " height: "
- + header.getHeight());
- } catch (IOException e) {
- throw new IIOException("Error reading quake2 PCX header", e);
- }
- }
-}
diff --git a/src/jake2/imageio/PCXImageReaderSpi.java b/src/jake2/imageio/PCXImageReaderSpi.java
deleted file mode 100644
index f4089e3..0000000
--- a/src/jake2/imageio/PCXImageReaderSpi.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Created on Nov 17, 2003
- *
- */
-package jake2.imageio;
-
-import java.io.IOException;
-import java.util.Locale;
-
-import javax.imageio.ImageReader;
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * @author cwei
- *
- * put the own ImageReaderSpi class name in the file (relative to classpath):
- * <code>
- * META-INF/services/javax.imageio.spi.ImageReaderSpi
- * </code>
- */
-public class PCXImageReaderSpi extends ImageReaderSpi {
-
- static final String vendorName = "[email protected]";
- static final String version = "1.0_beta";
- static final String[] names = { "quake2 pcx" };
- static final String[] suffixes = { "pcx" };
- static final String[] MIMETypes = { "image/x-quake2-pcx" };
- static final String readerClassName = "jake2.imageio.PCXImageReader";
- static final String[] writerSpiNames = null; // { "jake2.imageio.PCXImageWriterSpi" };
-
- // Metadata formats, more information below
- static final boolean supportsStandardStreamMetadataFormat = false;
- static final String nativeStreamMetadataFormatName = null;
-
- static final String nativeStreamMetadataFormatClassName = null;
- static final String[] extraStreamMetadataFormatNames = null;
- static final String[] extraStreamMetadataFormatClassNames = null;
- static final boolean supportsStandardImageMetadataFormat = false;
- static final String nativeImageMetadataFormatName =
- "jake2.imageio.PCXMetaData_1.0";
- static final String nativeImageMetadataFormatClassName = null; // "jake2.imageio.PCXMetadata";
- static final String[] extraImageMetadataFormatNames = null;
- static final String[] extraImageMetadataFormatClassNames = null;
-
- public PCXImageReaderSpi() {
-
- super(
- vendorName,
- version,
- names,
- suffixes,
- MIMETypes,
- readerClassName,
- ImageReaderSpi.STANDARD_INPUT_TYPE,
- // Accept ImageInputStreams
- writerSpiNames,
- supportsStandardStreamMetadataFormat,
- nativeStreamMetadataFormatName,
- nativeStreamMetadataFormatClassName,
- extraStreamMetadataFormatNames,
- extraStreamMetadataFormatClassNames,
- supportsStandardImageMetadataFormat,
- nativeImageMetadataFormatName,
- nativeImageMetadataFormatClassName,
- extraImageMetadataFormatNames,
- extraImageMetadataFormatClassNames);
- }
-
- public boolean canDecodeInput(Object source) throws IOException {
- if (!(source instanceof ImageInputStream)) {
- return false;
- }
- ImageInputStream stream = (ImageInputStream)source;
- byte[] buffer = new byte[PCX.HEADER_SIZE];
- try {
- stream.mark();
- stream.readFully(buffer);
- stream.reset();
- // buffer will be converted to members and header checked
- PCX.Header pcx = new PCX.Header(buffer);
- } catch (IllegalArgumentException e) {
- return false;
- }
- return true;
- }
-
- public ImageReader createReaderInstance(Object extension)
- throws IOException {
- return new PCXImageReader(this);
- }
-
- /**
- * @see javax.imageio.spi.IIOServiceProvider#getDescription(java.util.Locale)
- */
- public String getDescription(Locale locale) {
- return "id-software's Quake2 pcx format";
- }
-}
diff --git a/src/jake2/imageio/Q2ColorMap.java b/src/jake2/imageio/Q2ColorMap.java
deleted file mode 100644
index 6476e61..0000000
--- a/src/jake2/imageio/Q2ColorMap.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Created on Nov 18, 2003
- *
- */
-package jake2.imageio;
-
-/**
- * @author cwei
- *
- */
-public interface Q2ColorMap {
- // Red channel
- static final byte[] RED = {
- 0, 15, 31, 47, 63, 75, 91, 107, 123, -117, -101, -85, -69, -53, -37, -21,
- 99, 91, 83, 79, 71, 63, 59, 51, 47, 43, 39, 35, 27, 23, 19, 15,
- 95, 91, 91, 87, 83, 79, 71, 63, 59, 51, 47, 39, 35, 27, 23, 19,
- -113, 123, 115, 103, -49, -89, -117, 111, -21, -53, -81, -109, 119, 91, 63, 35,
- -89, -97, -105, -117, 127, 115, 103, 87, 75, 67, 59, 51, 43, 35, 27, 19,
- 123, 115, 107, 103, 95, 87, 83, 75, 67, 63, 55, 47, 39, 31, 23, 15,
- 111, 95, 83, 67, 55, 39, 27, 15, -77, -65, -53, -41, -53, -77, -97, -121,
- 115, 91, 71, 47, 23, 19, 15, 11, 7, 7, 7, 0, 0, 0, 0, 0,
- -117, -125, 123, 115, 107, 99, 91, 87, 75, 63, 51, 43, 31, 19, 11, 0,
- -105, -113, -121, 127, 119, 115, 107, 99, 91, 79, 67, 55, 47, 35, 23, 15,
- -97, -109, -117, 127, 119, 107, 99, 87, 79, 67, 55, 43, 31, 23, 11, 0,
- 119, 111, 103, 99, 91, 83, 75, 71, 63, 55, 47, 39, 35, 27, 19, 11,
- -101, -113, -121, 123, 115, 103, 95, 87, 75, 63, 55, 47, 35, 27, 19, 11,
- 0, 35, 63, 83, 95, 95, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -17, -29, -45, -57, -73, -85, -101, -113, 127, 115, 95, 71, 47, 27,
- -17, 55, -1, 0, 43, 27, 19, -21, -61, -97, 123, -21, -57, -89, -121, -97
- };
-
- // Green channel
- static final byte[] GREEN = {
- 0, 15, 31, 47, 63, 75, 91, 107, 123, -117, -101, -85, -69, -53, -37, -21,
- 75, 67, 63, 59, 55, 47, 43, 39, 35, 31, 27, 23, 19, 15, 15, 11,
- 95, 91, 83, 79, 75, 71, 63, 59, 55, 47, 43, 39, 35, 27, 23, 19,
- 119, 99, 91, 79, -105, 123, 103, 83, -97, -117, 119, 99, 79, 59, 39, 23,
- 59, 47, 43, 39, 31, 23, 23, 19, 15, 15, 15, 11, 11, 11, 7, 7,
- 95, 87, 83, 79, 71, 67, 63, 55, 51, 47, 39, 35, 27, 23, 15, 11,
- 59, 55, 47, 43, 35, 27, 19, 11, 91, 123, -101, -69, -41, -57, -73, -89,
- -105, -121, 119, 103, 83, 75, 67, 63, 55, 47, 39, 31, 23, 15, 7, 0,
- 87, 79, 71, 67, 59, 51, 47, 43, 35, 31, 27, 19, 15, 11, 7, 0,
- -97, -105, -117, -125, 123, 115, 107, 99, 91, 79, 67, 55, 47, 35, 23, 15,
- 75, 67, 59, 55, 47, 43, 35, 31, 27, 23, 19, 15, 11, 7, 0, 0,
- 123, 115, 107, 99, 91, 87, 79, 71, 63, 55, 47, 39, 31, 23, 15, 7,
- -85, -97, -105, -117, -125, 119, 111, 103, 91, 79, 67, 59, 47, 35, 23, 15,
- -1, -25, -45, -69, -89, -113, 123, -1, -1, -1, -1, -1, -1, -21, -41, -65,
- -85, -109, 127, 107, 87, 71, 59, 43, 31, 23, 15, 7, 0, 0, 0, 0,
- 0, 55, 0, 0, 43, 27, 19, -105, 115, 87, 63, -45, -85, -117, 107, 91
- };
-
- // Blue channel
- static final byte[] BLUE = {
- 0, 15, 31, 47, 63, 75, 91, 107, 123, -117, -101, -85, -69, -53, -37, -21,
- 35, 31, 31, 27, 27, 23, 23, 19, 19, 19, 15, 15, 11, 11, 7, 7,
- 111, 103, 95, 91, 83, 75, 67, 59, 55, 47, 43, 39, 35, 27, 23, 19,
- 83, 67, 59, 47, 75, 59, 47, 39, 39, 35, 31, 27, 23, 15, 11, 7,
- 43, 35, 27, 19, 15, 11, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 75, 67, 63, 59, 55, 51, 47, 43, 39, 35, 27, 23, 19, 15, 11, 7,
- 23, 23, 23, 23, 19, 15, 11, 7, 79, 111, -109, -73, -33, -45, -61, -73,
- -89, -101, -117, 127, 111, 103, 91, 83, 75, 63, 51, 43, 31, 19, 11, 0,
- 87, 79, 71, 67, 59, 51, 47, 43, 35, 31, 27, 19, 15, 11, 7, 0,
- 123, 115, 107, 99, 95, 87, 79, 71, 67, 59, 51, 43, 35, 27, 19, 11,
- 63, 55, 47, 39, 35, 27, 23, 19, 15, 11, 11, 7, 7, 0, 0, 0,
- -49, -61, -73, -89, -101, -113, 127, 115, 103, 87, 75, 63, 47, 35, 23, 7,
- 123, 111, 99, 87, 75, 67, 59, 51, 39, 27, 19, 11, 7, 0, 0, 0,
- 0, 15, 27, 39, 47, 51, 51, -1, -45, -89, 127, 83, 39, 31, 23, 15,
- 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, -1, 0, -1, 35, 23, 15, 127, 83, 51, 27, -57, -101, 119, 87, 83
- };
-
- // Alpha channel
- static final byte[] ALPHA = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
- };
-}
diff --git a/src/jake2/imageio/WAL.java b/src/jake2/imageio/WAL.java
deleted file mode 100644
index 1c499ef..0000000
--- a/src/jake2/imageio/WAL.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Created on Nov 18, 2003
- *
- */
-package jake2.imageio;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * @author cwei
- *
- */
-public class WAL {
-
- public static final int HEADER_SIZE = 100;
-
- /* struct wal_header
- {
- char name[32]; // name of the texture
-
- uint32 width; // width (in pixels) of the largest mipmap level
- uint32 height; // height (in pixels) of the largest mipmap level
-
- int32 offset[4]; // byte offset of the start of each of the 4 mipmap levels
-
- char next_name[32]; // name of the next texture in the animation
-
- uint32 flags; // ?
- uint32 contents; // ?
- uint32 value; // ?
- };
- */
- public static class Header {
-
- // size of byte arrays
- static final int NAME_SIZE = 32;
- static final int OFFSET_SIZE = 4;
-
- String name;
- int width;
- int height;
- int[] offset; // file offsets for the 4 mipmap images
- String nextName;
- int flags; // unused
- int contents; // unused
- int value; // unused
-
- public Header(byte[] headerBytes) {
- if (headerBytes == null || headerBytes.length != HEADER_SIZE) {
- throw new IllegalArgumentException("invalid quake2 wal header");
- }
-
- ByteBuffer b = ByteBuffer.wrap(headerBytes);
- // is stored as little endian
- b.order(ByteOrder.LITTLE_ENDIAN);
-
- byte[] tmp = new byte[NAME_SIZE];
- // fill header
-
- // name
- b.get(tmp);
- try {
- name = new String(tmp, "ISO-8859-1");
- } catch (UnsupportedEncodingException e) {
- name = new String(tmp);
- }
- // width
- width = b.getInt();
- assert(width >= 0) : "unsigned int bug"; // true means ok.
- // height
- height = b.getInt();
- assert(height >= 0) : "unsigned int bug"; // true means ok.
- // 4 offsets
- offset =
- new int[] { b.getInt(), b.getInt(), b.getInt(), b.getInt()};
- // nextName
- b.get(tmp);
- try {
- nextName = new String(tmp, "ISO-8859-1");
- } catch (UnsupportedEncodingException e1) {
- name = new String(tmp);
- }
- // unused entries
- flags = b.getInt();
- contents = b.getInt();
- value = b.getInt();
-
- // check some attributes
- checkHeader();
- }
-
- private void checkHeader() {
- // start of mipmaps
- int mipmap0 = HEADER_SIZE;
- int mipmap1 = mipmap0 + getWidth() * getHeight();
- int mipmap2 = mipmap1 + getWidth() / 2 * getHeight() / 2;
- int mipmap3 = mipmap2 + getWidth() / 4 * getHeight() / 4;
-
- if (offset[0] != mipmap0
- || offset[1] != mipmap1
- || offset[2] != mipmap2
- || offset[3] != mipmap3) {
- throw new IllegalArgumentException("invalid quake2 wal header");
- }
- }
-
- /**
- * @return
- */
- public int getContents() {
- return contents;
- }
-
- /**
- * @return
- */
- public int getFlags() {
- return flags;
- }
-
- /**
- * @return
- */
- public int getHeight() {
- return height;
- }
-
- /**
- * @return
- */
- public String getName() {
- return name;
- }
-
- /**
- * @return
- */
- public String getNextName() {
- return nextName;
- }
-
- /**
- * @return
- */
- public int getOffset(int index) {
- if (index < 0 || index > 3) {
- throw new ArrayIndexOutOfBoundsException("mipmap offset range is 0 to 3");
- }
- return offset[index];
- }
-
- /**
- * @return
- */
- public int getValue() {
- return value;
- }
-
- /**
- * @return
- */
- public int getWidth() {
- return width;
- }
-
- }
-} \ No newline at end of file
diff --git a/src/jake2/imageio/WALImageReader.java b/src/jake2/imageio/WALImageReader.java
deleted file mode 100644
index 949b4f1..0000000
--- a/src/jake2/imageio/WALImageReader.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Created on Nov 18, 2003
- *
- */
-package jake2.imageio;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.IIOException;
-import javax.imageio.ImageReadParam;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * @author cwei
- *
- */
-public class WALImageReader extends ImageReader {
-
- private static Logger logger =
- Logger.getLogger(WALImageReader.class.getName());
-
- ImageInputStream stream = null;
- WAL.Header header = null;
-
- public WALImageReader(ImageReaderSpi originatingProvider) {
- super(originatingProvider);
- }
-
- public void setInput(Object input, boolean seekForwardOnly) {
- super.setInput(input, seekForwardOnly);
- if (input == null) {
- this.stream = null;
- return;
- }
- if (input instanceof ImageInputStream) {
- this.stream = (ImageInputStream) input;
- } else {
- throw new IllegalArgumentException("bad input");
- }
- }
-
- public int getHeight(int imageIndex) throws IOException {
- checkIndex(imageIndex);
- readHeader();
- return header.getHeight();
- }
-
- public int getWidth(int imageIndex) throws IOException {
- checkIndex(imageIndex);
- readHeader();
- return header.getWidth();
- }
-
- public int getNumImages(boolean allowSearch) throws IOException {
- // only 1 image
- return 1;
- }
-
- public Iterator getImageTypes(int imageIndex) throws IOException {
- checkIndex(imageIndex);
- readHeader();
-
- ImageTypeSpecifier imageType = null;
- java.util.List l = new ArrayList(1);
-
- imageType =
- ImageTypeSpecifier.createIndexed(
- Q2ColorMap.RED,
- Q2ColorMap.GREEN,
- Q2ColorMap.BLUE,
- Q2ColorMap.ALPHA,
- 8,
- DataBuffer.TYPE_BYTE);
-
- l.add(imageType);
- return l.iterator();
- }
-
- public IIOMetadata getStreamMetadata() throws IOException {
- return null;
- }
-
- public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
- return null;
- }
-
- public BufferedImage read(int imageIndex, ImageReadParam param)
- throws IOException {
-
- checkIndex(imageIndex);
- readHeader();
-
- int width = header.getWidth();
- int height = header.getHeight();
-
- // Compute initial source region, clip against destination later
- Rectangle sourceRegion = getSourceRegion(param, width, height);
-
- // Set everything to default values
- int sourceXSubsampling = 1;
- int sourceYSubsampling = 1;
- int[] sourceBands = null;
- int[] destinationBands = null;
- Point destinationOffset = new Point(0, 0);
-
- // Get values from the ImageReadParam, if any
- if (param != null) {
- sourceXSubsampling = param.getSourceXSubsampling();
- sourceYSubsampling = param.getSourceYSubsampling();
- sourceBands = param.getSourceBands();
- destinationBands = param.getDestinationBands();
- destinationOffset = param.getDestinationOffset();
- }
-
- // Get the specified detination image or create a new one
- BufferedImage dst =
- getDestination(param, getImageTypes(0), width, height);
-
- // Enure band settings from param are compatible with images
- int inputBands = 1;
- checkReadParamBandSettings(
- param,
- inputBands,
- dst.getSampleModel().getNumBands());
-
- int[] bandOffsets = new int[inputBands];
- for (int i = 0; i < inputBands; i++) {
- bandOffsets[i] = i;
- }
- int bytesPerRow = width * inputBands;
- DataBufferByte rowDB = new DataBufferByte(bytesPerRow);
- WritableRaster rowRas =
- Raster.createInterleavedRaster(
- rowDB,
- width,
- 1,
- bytesPerRow,
- inputBands,
- bandOffsets,
- new Point(0, 0));
- byte[] rowBuf = rowDB.getData();
-
- // Create an int[] that can a single pixel
- int[] pixel = rowRas.getPixel(0, 0, (int[]) null);
-
- WritableRaster imRas = dst.getWritableTile(0, 0);
- int dstMinX = imRas.getMinX();
- int dstMaxX = dstMinX + imRas.getWidth() - 1;
- int dstMinY = imRas.getMinY();
- int dstMaxY = dstMinY + imRas.getHeight() - 1;
-
- // Create a child raster exposing only the desired source bands
- if (sourceBands != null) {
- rowRas =
- rowRas.createWritableChild(0, 0, width, 1, 0, 0, sourceBands);
- }
-
- // Create a child raster exposing only the desired dest bands
- if (destinationBands != null) {
- imRas =
- imRas.createWritableChild(
- 0,
- 0,
- imRas.getWidth(),
- imRas.getHeight(),
- 0,
- 0,
- destinationBands);
-
- }
-
- for (int srcY = 0; srcY < height; srcY++) {
- // Read the row
- try {
- stream.readFully(rowBuf);
- } catch (IOException e) {
- throw new IIOException("Error reading line " + srcY, e);
- }
-
- // Reject rows that lie outside the source region,
- // or which aren't part of the subsampling
- if ((srcY < sourceRegion.y)
- || (srcY >= sourceRegion.y + sourceRegion.height)
- || (((srcY - sourceRegion.y) % sourceYSubsampling) != 0)) {
- continue;
- }
-
- // Determine where the row will go in the destination
- int dstY =
- destinationOffset.y
- + (srcY - sourceRegion.y) / sourceYSubsampling;
- if (dstY < dstMinY) {
- continue; // The row is above imRas
- }
- if (dstY > dstMaxY) {
- break; // We're done with the image
- }
-
- // Copy each (subsampled) source pixel into imRas
- for (int srcX = sourceRegion.x;
- srcX < sourceRegion.x + sourceRegion.width;
- srcX++) {
- if (((srcX - sourceRegion.x) % sourceXSubsampling) != 0) {
- continue;
- }
- int dstX =
- destinationOffset.x
- + (srcX - sourceRegion.x) / sourceXSubsampling;
- if (dstX < dstMinX) {
- continue; // The pixel is to the left of imRas
- }
- if (dstX > dstMaxX) {
- break; // We're done with the row
- }
-
- // Copy the pixel, sub-banding is done automatically
- rowRas.getPixel(srcX, 0, pixel);
- imRas.setPixel(dstX, dstY, pixel);
- }
- }
- return dst;
- }
-
- private void checkIndex(int imageIndex) {
- if (imageIndex != 0) {
- throw new IndexOutOfBoundsException("bad image index");
- }
- }
-
- private void readHeader() throws IIOException {
-
- if (header != null) return;
-
- logger.log(Level.FINE, "WAL read header");
-
- if (stream == null) {
- if (this.input == null) {
- throw new IllegalStateException("No input stream");
- }
- stream = (ImageInputStream) input;
- }
-
- byte[] buffer = new byte[WAL.HEADER_SIZE];
-
- try {
- stream.readFully(buffer);
- this.header = new WAL.Header(buffer);
- logger.log(
- Level.FINE,
- "WAL width: "
- + header.getWidth()
- + " height: "
- + header.getHeight());
- } catch (IOException e) {
- throw new IIOException("Error reading quake2 WAL header", e);
- }
- }
-} \ No newline at end of file
diff --git a/src/jake2/imageio/WALImageReaderSpi.java b/src/jake2/imageio/WALImageReaderSpi.java
deleted file mode 100644
index f731165..0000000
--- a/src/jake2/imageio/WALImageReaderSpi.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Created on Nov 18, 2003
- *
- */
-package jake2.imageio;
-
-import java.io.IOException;
-import java.util.Locale;
-import javax.imageio.ImageReader;
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-
-/**
- * @author cwei
- *
- * Quake 2 stores textures in a proprietary 2D image format called WAL.
- * While this isn't actually part of the BSP file format,
- * it's essential information for loading Quake 2 maps.
- * WAL textures are stored in a 8-bit indexed color format with a specific palette being used by all textures.
- * (this palette is stored in the PAK data file that comes with Quake 2 e.g. pics/colormap.pcx).
- * Four mip-map levels are stored for each texture at sizes decreasing by a factor of two.
- * This is mostly for software rendering since most 3D APIs will automatically generate
- * the mip-map levels when you create a texture.
- * Each frame of an animated texture is stored as an individual WAL file,
- * and the animation sequence is encoded by storing the name of the next texture in the sequence for each frame;
- * texture names are stored with paths and without any extension.
- * The format for the WAL file header is the wal_header structure:
- * <code>
- struct wal_header
- {
- char name[32]; // name of the texture
-
- uint32 width; // width (in pixels) of the largest mipmap level
- uint32 height; // height (in pixels) of the largest mipmap level
-
- int32 offset[4]; // byte offset of the start of each of the 4 mipmap levels
-
- char next_name[32]; // name of the next texture in the animation
-
- uint32 flags; // ?
- uint32 contents; // ?
- uint32 value; // ?
- };
- </code>
- * The actual texture data is stored in an 8-bits-per-pixel raw format in a left-right, top-down order.
- * <br>
- * put the own ImageReaderSpi class name in the file (relative to classpath):
- * <code>META-INF/services/javax.imageio.spi.ImageReaderSpi</code>
- *
- * */
-public class WALImageReaderSpi extends ImageReaderSpi {
-
- static final String vendorName = "[email protected]";
- static final String version = "1.0_beta";
- static final String[] names = { "quake2 wal" };
- static final String[] suffixes = { "wal" };
- static final String[] MIMETypes = { "image/x-quake2-wal" };
- static final String readerClassName = "jake2.imageio.WALImageReader";
- static final String[] writerSpiNames = null; // { "jake2.imageio.WALImageWriterSpi" };
-
- // Metadata formats, more information below
- static final boolean supportsStandardStreamMetadataFormat = false;
- static final String nativeStreamMetadataFormatName = null;
-
- static final String nativeStreamMetadataFormatClassName = null;
- static final String[] extraStreamMetadataFormatNames = null;
- static final String[] extraStreamMetadataFormatClassNames = null;
- static final boolean supportsStandardImageMetadataFormat = false;
- static final String nativeImageMetadataFormatName =
- "jake2.imageio.WALMetaData_1.0";
- static final String nativeImageMetadataFormatClassName = null; // "jake2.imageio.WALMetadata";
- static final String[] extraImageMetadataFormatNames = null;
- static final String[] extraImageMetadataFormatClassNames = null;
-
- public WALImageReaderSpi() {
-
- super(
- vendorName,
- version,
- names,
- suffixes,
- MIMETypes,
- readerClassName,
- ImageReaderSpi.STANDARD_INPUT_TYPE, // Accept ImageInputStreams
- writerSpiNames,
- supportsStandardStreamMetadataFormat,
- nativeStreamMetadataFormatName,
- nativeStreamMetadataFormatClassName,
- extraStreamMetadataFormatNames,
- extraStreamMetadataFormatClassNames,
- supportsStandardImageMetadataFormat,
- nativeImageMetadataFormatName,
- nativeImageMetadataFormatClassName,
- extraImageMetadataFormatNames,
- extraImageMetadataFormatClassNames);
- }
-
- public boolean canDecodeInput(Object source) throws IOException {
- if (!(source instanceof ImageInputStream)) {
- return false;
- }
- ImageInputStream stream = (ImageInputStream)source;
- byte[] buffer = new byte[WAL.HEADER_SIZE];
- try {
- stream.mark();
- stream.readFully(buffer);
- stream.reset();
- // buffer will be converted to members and header checked
- WAL.Header wal = new WAL.Header(buffer);
- } catch (IllegalArgumentException e) {
- return false;
- }
- return true;
- }
-
- /**
- * returns a WALImageReader
- */
- public ImageReader createReaderInstance(Object extension)
- throws IOException {
- return new WALImageReader(this);
- }
-
- public String getDescription(Locale locale) {
- return "id-software's Quake2 wal format for textures";
- }
-}
diff --git a/src/jake2/logging.properties b/src/jake2/logging.properties
deleted file mode 100644
index 41c2fad..0000000
--- a/src/jake2/logging.properties
+++ /dev/null
@@ -1,41 +0,0 @@
-# Comma separated list of log Handler classes
-# These handlers will be installed during VM
-# startup.
-handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
-
-# Default global logging level.
-.level= INFO
-
-# Handler specific properties.
-# Describes specific configuration info for
-# Handlers.
-
-java.util.logging.FileHandler.level = ALL
-#
-# location is the global temp directory (linux: /tmp/jake2_0.log)
-# %t means system temp dir
-# %g means log file number
-#
-java.util.logging.FileHandler.pattern = %t/jake2_%g.log
-# ca. 100KByte
-java.util.logging.FileHandler.limit = 100000
-# max 1 file
-java.util.logging.FileHandler.count = 1
-java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
-# java.util.logging.XMLFormatter
-# java.util.logging.FileHandler.append = true
-
-
-# Limit the message that are printed on the
-# console to INFO and above.
-java.util.logging.ConsoleHandler.level = ALL
-java.util.logging.ConsoleHandler.formatter =
- java.util.logging.SimpleFormatter
-
-
-# For example, set the default jake2 package log level
-jake2.level = INFO
-
-# other individual package or class configs
-# jake2.imageio.level = FINEST
-# jake2.qcommon.FS.level = FINEST \ No newline at end of file
diff --git a/src/jake2/qcommon/CM.java b/src/jake2/qcommon/CM.java
index 8c5a203..1c3a756 100644
--- a/src/jake2/qcommon/CM.java
+++ b/src/jake2/qcommon/CM.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 02.01.2004 by RST.
-// $Id: CM.java,v 1.2 2004-07-08 15:58:46 hzi Exp $
+// $Id: CM.java,v 1.3 2004-07-09 06:50:50 hzi Exp $
package jake2.qcommon;
@@ -189,7 +189,7 @@ public class CM extends Game {
Loads in the map and all submodels
==================
*/
- public static cmodel_t CM_LoadMap(String name, boolean clientload, intwrap checksum) {
+ public static cmodel_t CM_LoadMap(String name, boolean clientload, int checksum[]) {
Com.DPrintf("CM_LoadMap...\n");
byte buf[];
int i;
@@ -200,7 +200,7 @@ public class CM extends Game {
if (0 == strcmp(map_name, name) && (clientload || 0 == Cvar.VariableValue("flushmap"))) {
- checksum.i = last_checksum;
+ checksum[0] = last_checksum;
if (!clientload) {
Arrays.fill(portalopen, false);
@@ -222,7 +222,7 @@ public class CM extends Game {
numleafs = 1;
numclusters = 1;
numareas = 1;
- checksum.i = 0;
+ checksum[0] = 0;
return map_cmodels[0];
// cinematic servers won't have anything at all
}
@@ -240,7 +240,7 @@ public class CM extends Game {
ByteBuffer bbuf = ByteBuffer.wrap(buf);
last_checksum = MD4.Com_BlockChecksum(buf, length);
- checksum.i = last_checksum;
+ checksum[0] = last_checksum;
header = new qfiles.dheader_t(bbuf.slice());
@@ -796,7 +796,6 @@ public class CM extends Game {
if (l.filelen > MAX_MAP_VISIBILITY)
Com.Error(ERR_DROP, "Map has too large visibility lump");
- //was: memcpy(map_visibility, cmod_base + l.fileofs, l.filelen);
System.arraycopy(cmod_base, l.fileofs, map_visibility, 0, l.filelen);
ByteBuffer bb = ByteBuffer.wrap(map_visibility, 0, l.filelen);
@@ -1074,7 +1073,7 @@ public class CM extends Game {
}
}
- public static int CM_BoxLeafnums_headnode(float[] mins, float[] maxs, int list[], int listsize, int headnode, intwrap topnode) {
+ public static int CM_BoxLeafnums_headnode(float[] mins, float[] maxs, int list[], int listsize, int headnode, int topnode[]) {
leaf_list = list;
leaf_count = 0;
leaf_maxcount = listsize;
@@ -1086,22 +1085,23 @@ public class CM extends Game {
CM_BoxLeafnums_r(headnode);
if (topnode != null)
- topnode.i = leaf_topnode;
+ topnode[0] = leaf_topnode;
return leaf_count;
}
- public static int CM_BoxLeafnums(float[] mins, float[] maxs, int list[], int listsize, intwrap topnode) {
+ public static int CM_BoxLeafnums(float[] mins, float[] maxs, int list[], int listsize, int topnode[]) {
return CM_BoxLeafnums_headnode(mins, maxs, list, listsize, map_cmodels[0].headnode, topnode);
}
- public static class intwrap {
+ /*
+ public static class intwrap1 {
public intwrap(int i) {
this.i = i;
}
public int i;
}
-
+ */
/*
==================
CM_PointContents
@@ -1539,10 +1539,10 @@ public class CM extends Game {
c2[i] += 1;
}
- intwrap tn = new intwrap(topnode);
+ int tn[] = {topnode};
numleafs = CM_BoxLeafnums_headnode(c1, c2, leafs, 1024, headnode, tn);
- topnode = tn.i;
+ topnode = tn[0];
for (i = 0; i < numleafs; i++) {
CM_TestInLeaf(leafs[i]);
if (trace_trace.allsolid)
diff --git a/src/jake2/qcommon/CRC.java b/src/jake2/qcommon/CRC.java
new file mode 100644
index 0000000..ca22d9b
--- /dev/null
+++ b/src/jake2/qcommon/CRC.java
@@ -0,0 +1,383 @@
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+
+// Created on 25.01.2004 by RST.
+// $Id: CRC.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+package jake2.qcommon;
+
+import jake2.util.Vargs;
+
+public class CRC
+{
+
+ public final static short CRC_INIT_VALUE= (short) 0xffff;
+ public final static short CRC_XOR_VALUE= (short) 0x0000;
+
+ private static int crctable[]=
+ {
+ 0x0000,
+ 0x1021,
+ 0x2042,
+ 0x3063,
+ 0x4084,
+ 0x50a5,
+ 0x60c6,
+ 0x70e7,
+ 0x8108,
+ 0x9129,
+ 0xa14a,
+ 0xb16b,
+ 0xc18c,
+ 0xd1ad,
+ 0xe1ce,
+ 0xf1ef,
+ 0x1231,
+ 0x0210,
+ 0x3273,
+ 0x2252,
+ 0x52b5,
+ 0x4294,
+ 0x72f7,
+ 0x62d6,
+ 0x9339,
+ 0x8318,
+ 0xb37b,
+ 0xa35a,
+ 0xd3bd,
+ 0xc39c,
+ 0xf3ff,
+ 0xe3de,
+ 0x2462,
+ 0x3443,
+ 0x0420,
+ 0x1401,
+ 0x64e6,
+ 0x74c7,
+ 0x44a4,
+ 0x5485,
+ 0xa56a,
+ 0xb54b,
+ 0x8528,
+ 0x9509,
+ 0xe5ee,
+ 0xf5cf,
+ 0xc5ac,
+ 0xd58d,
+ 0x3653,
+ 0x2672,
+ 0x1611,
+ 0x0630,
+ 0x76d7,
+ 0x66f6,
+ 0x5695,
+ 0x46b4,
+ 0xb75b,
+ 0xa77a,
+ 0x9719,
+ 0x8738,
+ 0xf7df,
+ 0xe7fe,
+ 0xd79d,
+ 0xc7bc,
+ 0x48c4,
+ 0x58e5,
+ 0x6886,
+ 0x78a7,
+ 0x0840,
+ 0x1861,
+ 0x2802,
+ 0x3823,
+ 0xc9cc,
+ 0xd9ed,
+ 0xe98e,
+ 0xf9af,
+ 0x8948,
+ 0x9969,
+ 0xa90a,
+ 0xb92b,
+ 0x5af5,
+ 0x4ad4,
+ 0x7ab7,
+ 0x6a96,
+ 0x1a71,
+ 0x0a50,
+ 0x3a33,
+ 0x2a12,
+ 0xdbfd,
+ 0xcbdc,
+ 0xfbbf,
+ 0xeb9e,
+ 0x9b79,
+ 0x8b58,
+ 0xbb3b,
+ 0xab1a,
+ 0x6ca6,
+ 0x7c87,
+ 0x4ce4,
+ 0x5cc5,
+ 0x2c22,
+ 0x3c03,
+ 0x0c60,
+ 0x1c41,
+ 0xedae,
+ 0xfd8f,
+ 0xcdec,
+ 0xddcd,
+ 0xad2a,
+ 0xbd0b,
+ 0x8d68,
+ 0x9d49,
+ 0x7e97,
+ 0x6eb6,
+ 0x5ed5,
+ 0x4ef4,
+ 0x3e13,
+ 0x2e32,
+ 0x1e51,
+ 0x0e70,
+ 0xff9f,
+ 0xefbe,
+ 0xdfdd,
+ 0xcffc,
+ 0xbf1b,
+ 0xaf3a,
+ 0x9f59,
+ 0x8f78,
+ 0x9188,
+ 0x81a9,
+ 0xb1ca,
+ 0xa1eb,
+ 0xd10c,
+ 0xc12d,
+ 0xf14e,
+ 0xe16f,
+ 0x1080,
+ 0x00a1,
+ 0x30c2,
+ 0x20e3,
+ 0x5004,
+ 0x4025,
+ 0x7046,
+ 0x6067,
+ 0x83b9,
+ 0x9398,
+ 0xa3fb,
+ 0xb3da,
+ 0xc33d,
+ 0xd31c,
+ 0xe37f,
+ 0xf35e,
+ 0x02b1,
+ 0x1290,
+ 0x22f3,
+ 0x32d2,
+ 0x4235,
+ 0x5214,
+ 0x6277,
+ 0x7256,
+ 0xb5ea,
+ 0xa5cb,
+ 0x95a8,
+ 0x8589,
+ 0xf56e,
+ 0xe54f,
+ 0xd52c,
+ 0xc50d,
+ 0x34e2,
+ 0x24c3,
+ 0x14a0,
+ 0x0481,
+ 0x7466,
+ 0x6447,
+ 0x5424,
+ 0x4405,
+ 0xa7db,
+ 0xb7fa,
+ 0x8799,
+ 0x97b8,
+ 0xe75f,
+ 0xf77e,
+ 0xc71d,
+ 0xd73c,
+ 0x26d3,
+ 0x36f2,
+ 0x0691,
+ 0x16b0,
+ 0x6657,
+ 0x7676,
+ 0x4615,
+ 0x5634,
+ 0xd94c,
+ 0xc96d,
+ 0xf90e,
+ 0xe92f,
+ 0x99c8,
+ 0x89e9,
+ 0xb98a,
+ 0xa9ab,
+ 0x5844,
+ 0x4865,
+ 0x7806,
+ 0x6827,
+ 0x18c0,
+ 0x08e1,
+ 0x3882,
+ 0x28a3,
+ 0xcb7d,
+ 0xdb5c,
+ 0xeb3f,
+ 0xfb1e,
+ 0x8bf9,
+ 0x9bd8,
+ 0xabbb,
+ 0xbb9a,
+ 0x4a75,
+ 0x5a54,
+ 0x6a37,
+ 0x7a16,
+ 0x0af1,
+ 0x1ad0,
+ 0x2ab3,
+ 0x3a92,
+ 0xfd2e,
+ 0xed0f,
+ 0xdd6c,
+ 0xcd4d,
+ 0xbdaa,
+ 0xad8b,
+ 0x9de8,
+ 0x8dc9,
+ 0x7c26,
+ 0x6c07,
+ 0x5c64,
+ 0x4c45,
+ 0x3ca2,
+ 0x2c83,
+ 0x1ce0,
+ 0x0cc1,
+ 0xef1f,
+ 0xff3e,
+ 0xcf5d,
+ 0xdf7c,
+ 0xaf9b,
+ 0xbfba,
+ 0x8fd9,
+ 0x9ff8,
+ 0x6e17,
+ 0x7e36,
+ 0x4e55,
+ 0x5e74,
+ 0x2e93,
+ 0x3eb2,
+ 0x0ed1,
+ 0x1ef0 };
+
+ static short CRC_Block(byte start[], int count)
+ {
+ short crc= CRC_INIT_VALUE;
+
+ int ndx= 0;
+
+ while (count-- > 0)
+ crc= (short) ((crc << 8) ^ crctable[0xff & ((crc >> 8) ^ start[ndx++])]);
+
+ return crc;
+ }
+
+ public static void main(String[] args)
+ {
+ byte data[]=
+ {
+ (byte) 0x71,
+ (byte) 0xa9,
+ (byte) 0x05,
+ (byte) 0xce,
+ (byte) 0x8d,
+ (byte) 0x75,
+ (byte) 0x28,
+ (byte) 0xc8,
+ (byte) 0xba,
+ (byte) 0x97,
+
+ (byte) 0x45,
+ (byte) 0xe9,
+ (byte) 0x8a,
+ (byte) 0xe0,
+ (byte) 0x37,
+ (byte) 0xbd,
+ (byte) 0x6c,
+ (byte) 0x6d,
+ (byte) 0x67,
+ (byte) 0x4a,
+ (byte) 0x21 };
+ System.out.println("crc:" + (CRC_Block(data, 21) & 0xffff));
+ System.out.println("----");
+ for (int n=0; n < 5; n++)
+ System.out.println("seq:" + (Com.BlockSequenceCRCByte( data,0, 21,n*10) & 0xff));
+
+ }
+
+/* c test:
+ *
+ * D:\Rene\gamesrc\quake2-3.21\qcommon>crc
+ * crc=-12353
+ * ----
+ * seq:215
+ * seq:252
+ * seq:164
+ * seq:202
+ * seq:201
+ *
+int main()
+{
+ byte data[21] =
+ {
+ 0x71,
+ 0xa9,
+ 0x05,
+ 0xce,
+ 0x8d,
+ 0x75,
+ 0x28,
+ 0xc8,
+ 0xba,
+ 0x97,
+
+ 0x45,
+ 0xe9,
+ 0x8a,
+ 0xe0,
+ 0x37,
+ 0xbd,
+ 0x6c,
+ 0x6d,
+ 0x67,
+ 0x4a, 0x21 };
+ int n=0;
+
+ printf("crc=%d\n", (short) CRC_Block(&data, 21));
+
+ printf("----\n");
+ for (n=0; n < 5; n++)
+ printf("seq:%d\n", COM_BlockSequenceCRCByte( &data,21, n*10) );
+}
+ */
+
+}
diff --git a/src/jake2/qcommon/Com.java b/src/jake2/qcommon/Com.java
index c938fdb..705a009 100644
--- a/src/jake2/qcommon/Com.java
+++ b/src/jake2/qcommon/Com.java
@@ -2,7 +2,7 @@
* Com.java
* Copyright (C) 2003
*
- * $Id: Com.java,v 1.2 2004-07-08 15:58:46 hzi Exp $
+ * $Id: Com.java,v 1.3 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -38,15 +38,17 @@ import java.io.*;
/**
* Com
- * TODO complete Com interface
+ *
*/
-public final class Com {
-
+public final class Com
+{
+
static int com_argc;
- static String[] com_argv = new String[Defines.MAX_NUM_ARGVS];
-
- public abstract static class RD_Flusher {
- public abstract void rd_flush(int target, byte [] buffer);
+ static String[] com_argv= new String[Defines.MAX_NUM_ARGVS];
+
+ public abstract static class RD_Flusher
+ {
+ public abstract void rd_flush(int target, byte[] buffer);
}
static int rd_target;
@@ -54,80 +56,95 @@ public final class Com {
static int rd_buffersize;
static RD_Flusher rd_flusher;
- public static void BeginRedirect(int target, byte [] buffer, int buffersize, RD_Flusher flush) {
+ public static void BeginRedirect(int target, byte[] buffer, int buffersize, RD_Flusher flush)
+ {
if (0 == target || null == buffer || 0 == buffersize || null == flush)
return;
- rd_target = target;
- rd_buffer = buffer;
- rd_buffersize = buffersize;
- rd_flusher = flush;
+ rd_target= target;
+ rd_buffer= buffer;
+ rd_buffersize= buffersize;
+ rd_flusher= flush;
- rd_buffer = null;
+ rd_buffer= null;
}
- public static void EndRedirect() {
+ public static void EndRedirect()
+ {
rd_flusher.rd_flush(rd_target, rd_buffer);
- rd_target = 0;
- rd_buffer = null;
- rd_buffersize = 0;
- rd_flusher = null;
+ rd_target= 0;
+ rd_buffer= null;
+ rd_buffersize= 0;
+ rd_flusher= null;
}
- static boolean recursive = false;
+ static boolean recursive= false;
- static String msg = "";
+ static String msg= "";
// helper class to replace the pointer-pointer
- public static class ParseHelp {
+ public static class ParseHelp
+ {
- public ParseHelp(String in, int offset) {
+ public ParseHelp(String in, int offset)
+ {
this(in.toCharArray(), offset);
}
- public ParseHelp(String in) {
- if (in == null) {
- data = null;
+ public ParseHelp(String in)
+ {
+ if (in == null)
+ {
+ data= null;
}
- else {
- data = in.toCharArray();
+ else
+ {
+ data= in.toCharArray();
}
- index = 0;
+ index= 0;
}
- public ParseHelp(char in[]) {
+ public ParseHelp(char in[])
+ {
this(in, 0);
}
- public ParseHelp(char in[], int offset) {
+ public ParseHelp(char in[], int offset)
+ {
if (in == null || in.length == 0)
- data = null;
+ data= null;
else
- data = in;
- index = offset;
+ data= in;
+ index= offset;
}
- public char getchar() {
+ public char getchar()
+ {
// faster than if
- try {
+ try
+ {
return data[index];
}
- catch (Exception e) {
- data = null;
+ catch (Exception e)
+ {
+ data= null;
// last char
return 0;
}
}
- public char nextchar() {
+ public char nextchar()
+ {
// faster than if
- try {
+ try
+ {
index++;
return data[index];
}
- catch (Exception e) {
- data = null;
+ catch (Exception e)
+ {
+ data= null;
// avoid int wraps;
index--;
// last char
@@ -135,144 +152,170 @@ public final class Com {
}
}
- public boolean isEof() {
+ public boolean isEof()
+ {
return data == null;
}
public int index;
public char data[];
- public char skipwhites() {
+ public char skipwhites()
+ {
char c;
- while (((c = getchar()) <= ' ') && c != 0)
+ while (((c= getchar()) <= ' ') && c != 0)
index++;
return c;
}
- public char skipwhitestoeol() {
+ public char skipwhitestoeol()
+ {
char c;
- while (((c = getchar()) <= ' ') && c != '\n' && c != 0)
+ while (((c= getchar()) <= ' ') && c != '\n' && c != 0)
index++;
return c;
}
- public char skiptoeol() {
+ public char skiptoeol()
+ {
char c;
- while ((c = getchar()) != '\n' && c != 0)
+ while ((c= getchar()) != '\n' && c != 0)
index++;
return c;
}
}
- public static char com_token[] = new char[Defines.MAX_TOKEN_CHARS];
+ public static char com_token[]= new char[Defines.MAX_TOKEN_CHARS];
// See GameSpanw.ED_ParseEdict() to see how to use it now.
// works perfect !
- public static String Parse(ParseHelp hlp) {
+ public static String Parse(ParseHelp hlp)
+ {
int c;
- int len = 0;
- len = 0;
+ int len= 0;
+ len= 0;
- com_token[0] = 0;
+ com_token[0]= 0;
- if (hlp.data == null) {
+ if (hlp.data == null)
+ {
return "";
}
// skip whitespace
hlp.skipwhites();
- if (hlp.isEof()) {
+ if (hlp.isEof())
+ {
return "";
}
// skip // comments
- if (hlp.getchar() == '/') {
- if (hlp.nextchar() == '/') {
- if ((hlp.skiptoeol() == 0) || (hlp.skipwhites() == 0)) {
+ if (hlp.getchar() == '/')
+ {
+ if (hlp.nextchar() == '/')
+ {
+ if ((hlp.skiptoeol() == 0) || (hlp.skipwhites() == 0))
+ {
return "";
}
}
- else {
- com_token[len] = '/';
+ else
+ {
+ com_token[len]= '/';
len++;
}
}
// handle quoted strings specially
- if (hlp.getchar() == '\"') {
- while (true) {
- c = hlp.nextchar();
- if (c == '\"' || c == 0) {
+ if (hlp.getchar() == '\"')
+ {
+ while (true)
+ {
+ c= hlp.nextchar();
+ if (c == '\"' || c == 0)
+ {
hlp.nextchar();
- com_token[len] = '?';
+ com_token[len]= '?';
return new String(com_token, 0, len);
}
- if (len < Defines.MAX_TOKEN_CHARS) {
- com_token[len] = hlp.getchar();
+ if (len < Defines.MAX_TOKEN_CHARS)
+ {
+ com_token[len]= hlp.getchar();
len++;
}
}
}
// parse a regular word
- do {
- if (len < Defines.MAX_TOKEN_CHARS) {
- com_token[len] = hlp.getchar();
+ do
+ {
+ if (len < Defines.MAX_TOKEN_CHARS)
+ {
+ com_token[len]= hlp.getchar();
len++;
}
- c = hlp.nextchar();
+ c= hlp.nextchar();
}
while (c > 32);
- if (len == Defines.MAX_TOKEN_CHARS) {
+ if (len == Defines.MAX_TOKEN_CHARS)
+ {
Printf("Token exceeded " + Defines.MAX_TOKEN_CHARS + " chars, discarded.\n");
- len = 0;
+ len= 0;
}
// trigger the eof
hlp.skipwhites();
- com_token[len] = 0;
+ com_token[len]= 0;
return new String(com_token, 0, len);
}
- public static xcommand_t Error_f = new xcommand_t() {
- public void execute() throws longjmpException {
+ public static xcommand_t Error_f= new xcommand_t()
+ {
+ public void execute() throws longjmpException
+ {
Error(Globals.ERR_FATAL, Cmd.Argv(1));
}
};
- public static void Error(int code, String fmt) throws longjmpException {
+ public static void Error(int code, String fmt) throws longjmpException
+ {
Error(code, fmt, null);
}
- public static void Error(int code, String fmt, Vargs vargs) throws longjmpException {
+ public static void Error(int code, String fmt, Vargs vargs) throws longjmpException
+ {
// va_list argptr;
// static char msg[MAXPRINTMSG];
- if (recursive) {
+ if (recursive)
+ {
Sys.Error("recursive error after: " + msg);
}
- recursive = true;
+ recursive= true;
- msg = sprintf(fmt, vargs);
+ msg= sprintf(fmt, vargs);
- if (code == Defines.ERR_DISCONNECT) {
+ if (code == Defines.ERR_DISCONNECT)
+ {
CL.Drop();
- recursive = false;
+ recursive= false;
throw new longjmpException();
}
- else if (code == Defines.ERR_DROP) {
+ else if (code == Defines.ERR_DROP)
+ {
Com.Printf("********************\nERROR: " + msg + "\n********************\n");
SV_MAIN.SV_Shutdown("Server crashed: " + msg + "\n", false);
CL.Drop();
- recursive = false;
+ recursive= false;
throw new longjmpException();
}
- else {
+ else
+ {
SV_MAIN.SV_Shutdown("Server fatal crashed: %s" + msg + "\n", false);
CL.Shutdown();
}
@@ -284,43 +327,51 @@ public final class Com {
* Com_InitArgv checks the number of command line arguments
* and copies all arguments with valid length into com_argv.
*/
- static void InitArgv(String[] args) throws longjmpException {
+ static void InitArgv(String[] args) throws longjmpException
+ {
- if (args.length > Globals.MAX_NUM_ARGVS) {
+ if (args.length > Globals.MAX_NUM_ARGVS)
+ {
Com.Error(Globals.ERR_FATAL, "argc > MAX_NUM_ARGVS");
}
- Com.com_argc = args.length;
- for (int i = 0; i < Com.com_argc; i++) {
+ Com.com_argc= args.length;
+ for (int i= 0; i < Com.com_argc; i++)
+ {
if (args[i].length() >= Globals.MAX_TOKEN_CHARS)
- Com.com_argv[i] = "";
+ Com.com_argv[i]= "";
else
- Com.com_argv[i] = args[i];
+ Com.com_argv[i]= args[i];
}
}
- public static void DPrintf(String fmt) {
+ public static void DPrintf(String fmt)
+ {
DPrintf(fmt, null);
}
-
- public static void d(String fmt) {
+
+ public static void d(String fmt)
+ {
DPrintf(fmt + "\n", null);
}
-
- public static void Printf(String fmt) {
+
+ public static void Printf(String fmt)
+ {
Printf(fmt, null);
}
- public static void DPrintf(String fmt, Vargs vargs) {
+ public static void DPrintf(String fmt, Vargs vargs)
+ {
if (Globals.developer == null || Globals.developer.value == 0)
return; // don't confuse non-developers with techie stuff...
Printf(fmt, vargs);
}
- public static void Printf(String fmt, Vargs vargs) {
+ public static void Printf(String fmt, Vargs vargs)
+ {
// TODO Com.Printf ist nur zum testen
- String msg = sprintf(fmt, vargs);
+ String msg= sprintf(fmt, vargs);
if (rd_target != 0)
{
@@ -328,7 +379,7 @@ public final class Com {
{
rd_flusher.rd_flush(rd_target, rd_buffer);
// *rd_buffer = 0;
- rd_buffer[rd_buffersize] = '\0';
+ rd_buffer[rd_buffersize]= '\0';
}
// TODO handle rd_buffer
// strcat(rd_buffer, msg);
@@ -336,7 +387,7 @@ public final class Com {
}
Console.Print(msg);
-
+
// also echo to debugging console
Sys.ConsoleOutput(msg);
@@ -344,14 +395,14 @@ public final class Com {
if (Globals.logfile_active != null && Globals.logfile_active.value != 0)
{
String name;
-
+
if (Globals.logfile == null)
{
- name = FS.Gamedir() + "/qconsole.log";
+ name= FS.Gamedir() + "/qconsole.log";
if (Globals.logfile_active.value > 2)
try
{
- Globals.logfile = new RandomAccessFile(name, "a");
+ Globals.logfile= new RandomAccessFile(name, "a");
}
catch (FileNotFoundException e)
{
@@ -361,7 +412,7 @@ public final class Com {
else
try
{
- Globals.logfile = new RandomAccessFile(name, "rw");
+ Globals.logfile= new RandomAccessFile(name, "rw");
}
catch (FileNotFoundException e1)
{
@@ -379,58 +430,68 @@ public final class Com {
// TODO: do quake2 error handling!
e.printStackTrace();
}
- if (Globals.logfile_active.value > 1)
- ; // do nothing
- // fflush (logfile); // force it to save every time
+ if (Globals.logfile_active.value > 1); // do nothing
+ // fflush (logfile); // force it to save every time
}
}
- public static void Println(String fmt) {
+ public static void Println(String fmt)
+ {
Printf(fmt);
Printf("\n");
}
-
- public static void p(String fmt) {
+
+ public static void p(String fmt)
+ {
Printf(fmt);
Printf("\n");
}
- public static String sprintf(String fmt, Vargs vargs) {
- String msg = "";
- if (vargs == null || vargs.size() == 0) {
- msg = fmt;
+ public static String sprintf(String fmt, Vargs vargs)
+ {
+ String msg= "";
+ if (vargs == null || vargs.size() == 0)
+ {
+ msg= fmt;
}
- else {
- msg = new PrintfFormat(fmt).sprintf(vargs.toArray());
+ else
+ {
+ msg= new PrintfFormat(fmt).sprintf(vargs.toArray());
}
return msg;
}
- public static int ServerState() {
+ public static int ServerState()
+ {
return Globals.server_state;
}
- public static int Argc() {
+ public static int Argc()
+ {
return Com.com_argc;
}
- public static String Argv(int arg) {
+ public static String Argv(int arg)
+ {
if (arg < 0 || arg >= Com.com_argc || Com.com_argv[arg].length() < 1)
return "";
return Com.com_argv[arg];
}
- public static void ClearArgv(int arg) {
+ public static void ClearArgv(int arg)
+ {
if (arg < 0 || arg >= Com.com_argc || Com.com_argv[arg].length() < 1)
return;
- Com.com_argv[arg] = "";
+ Com.com_argv[arg]= "";
}
- public static void Quit() {
+ public static void Quit()
+ {
SV_MAIN.SV_Shutdown("Server quit\n", false);
CL.Shutdown();
- if (Globals.logfile != null) {
+ if (Globals.logfile != null)
+ {
try
{
Globals.logfile.close();
@@ -438,25 +499,1036 @@ public final class Com {
catch (IOException e)
{
}
- Globals.logfile = null;
+ Globals.logfile= null;
}
Sys.Quit();
}
-
public static void SetServerState(int i)
{
- Globals.server_state = i;
+ Globals.server_state= i;
}
-
public static int BlockChecksum(byte[] buf, int length)
{
return MD4.Com_BlockChecksum(buf, length);
}
- public static void StripExtension(String string, String string2) {
- // TODO implement!
+ public static void StripExtension(String string, String string2)
+ {
+ // TODO implement StripExtension
}
+
+ /**
+ * CRC table.
+ */
+
+ static int chktbl[]=
+ {
+ 0x84,
+ 0x47,
+ 0x51,
+ 0xc1,
+ 0x93,
+ 0x22,
+ 0x21,
+ 0x24,
+ 0x2f,
+ 0x66,
+ 0x60,
+ 0x4d,
+ 0xb0,
+ 0x7c,
+ 0xda,
+ 0x88,
+ 0x54,
+ 0x15,
+ 0x2b,
+ 0xc6,
+ 0x6c,
+ 0x89,
+ 0xc5,
+ 0x9d,
+ 0x48,
+ 0xee,
+ 0xe6,
+ 0x8a,
+ 0xb5,
+ 0xf4,
+ 0xcb,
+ 0xfb,
+ 0xf1,
+ 0x0c,
+ 0x2e,
+ 0xa0,
+ 0xd7,
+ 0xc9,
+ 0x1f,
+ 0xd6,
+ 0x06,
+ 0x9a,
+ 0x09,
+ 0x41,
+ 0x54,
+ 0x67,
+ 0x46,
+ 0xc7,
+ 0x74,
+ 0xe3,
+ 0xc8,
+ 0xb6,
+ 0x5d,
+ 0xa6,
+ 0x36,
+ 0xc4,
+ 0xab,
+ 0x2c,
+ 0x7e,
+ 0x85,
+ 0xa8,
+ 0xa4,
+ 0xa6,
+ 0x4d,
+ 0x96,
+ 0x19,
+ 0x19,
+ 0x9a,
+ 0xcc,
+ 0xd8,
+ 0xac,
+ 0x39,
+ 0x5e,
+ 0x3c,
+ 0xf2,
+ 0xf5,
+ 0x5a,
+ 0x72,
+ 0xe5,
+ 0xa9,
+ 0xd1,
+ 0xb3,
+ 0x23,
+ 0x82,
+ 0x6f,
+ 0x29,
+ 0xcb,
+ 0xd1,
+ 0xcc,
+ 0x71,
+ 0xfb,
+ 0xea,
+ 0x92,
+ 0xeb,
+ 0x1c,
+ 0xca,
+ 0x4c,
+ 0x70,
+ 0xfe,
+ 0x4d,
+ 0xc9,
+ 0x67,
+ 0x43,
+ 0x47,
+ 0x94,
+ 0xb9,
+ 0x47,
+ 0xbc,
+ 0x3f,
+ 0x01,
+ 0xab,
+ 0x7b,
+ 0xa6,
+ 0xe2,
+ 0x76,
+ 0xef,
+ 0x5a,
+ 0x7a,
+ 0x29,
+ 0x0b,
+ 0x51,
+ 0x54,
+ 0x67,
+ 0xd8,
+ 0x1c,
+ 0x14,
+ 0x3e,
+ 0x29,
+ 0xec,
+ 0xe9,
+ 0x2d,
+ 0x48,
+ 0x67,
+ 0xff,
+ 0xed,
+ 0x54,
+ 0x4f,
+ 0x48,
+ 0xc0,
+ 0xaa,
+ 0x61,
+ 0xf7,
+ 0x78,
+ 0x12,
+ 0x03,
+ 0x7a,
+ 0x9e,
+ 0x8b,
+ 0xcf,
+ 0x83,
+ 0x7b,
+ 0xae,
+ 0xca,
+ 0x7b,
+ 0xd9,
+ 0xe9,
+ 0x53,
+ 0x2a,
+ 0xeb,
+ 0xd2,
+ 0xd8,
+ 0xcd,
+ 0xa3,
+ 0x10,
+ 0x25,
+ 0x78,
+ 0x5a,
+ 0xb5,
+ 0x23,
+ 0x06,
+ 0x93,
+ 0xb7,
+ 0x84,
+ 0xd2,
+ 0xbd,
+ 0x96,
+ 0x75,
+ 0xa5,
+ 0x5e,
+ 0xcf,
+ 0x4e,
+ 0xe9,
+ 0x50,
+ 0xa1,
+ 0xe6,
+ 0x9d,
+ 0xb1,
+ 0xe3,
+ 0x85,
+ 0x66,
+ 0x28,
+ 0x4e,
+ 0x43,
+ 0xdc,
+ 0x6e,
+ 0xbb,
+ 0x33,
+ 0x9e,
+ 0xf3,
+ 0x0d,
+ 0x00,
+ 0xc1,
+ 0xcf,
+ 0x67,
+ 0x34,
+ 0x06,
+ 0x7c,
+ 0x71,
+ 0xe3,
+ 0x63,
+ 0xb7,
+ 0xb7,
+ 0xdf,
+ 0x92,
+ 0xc4,
+ 0xc2,
+ 0x25,
+ 0x5c,
+ 0xff,
+ 0xc3,
+ 0x6e,
+ 0xfc,
+ 0xaa,
+ 0x1e,
+ 0x2a,
+ 0x48,
+ 0x11,
+ 0x1c,
+ 0x36,
+ 0x68,
+ 0x78,
+ 0x86,
+ 0x79,
+ 0x30,
+ 0xc3,
+ 0xd6,
+ 0xde,
+ 0xbc,
+ 0x3a,
+ 0x2a,
+ 0x6d,
+ 0x1e,
+ 0x46,
+ 0xdd,
+ 0xe0,
+ 0x80,
+ 0x1e,
+ 0x44,
+ 0x3b,
+ 0x6f,
+ 0xaf,
+ 0x31,
+ 0xda,
+ 0xa2,
+ 0xbd,
+ 0x77,
+ 0x06,
+ 0x56,
+ 0xc0,
+ 0xb7,
+ 0x92,
+ 0x4b,
+ 0x37,
+ 0xc0,
+ 0xfc,
+ 0xc2,
+ 0xd5,
+ 0xfb,
+ 0xa8,
+ 0xda,
+ 0xf5,
+ 0x57,
+ 0xa8,
+ 0x18,
+ 0xc0,
+ 0xdf,
+ 0xe7,
+ 0xaa,
+ 0x2a,
+ 0xe0,
+ 0x7c,
+ 0x6f,
+ 0x77,
+ 0xb1,
+ 0x26,
+ 0xba,
+ 0xf9,
+ 0x2e,
+ 0x1d,
+ 0x16,
+ 0xcb,
+ 0xb8,
+ 0xa2,
+ 0x44,
+ 0xd5,
+ 0x2f,
+ 0x1a,
+ 0x79,
+ 0x74,
+ 0x87,
+ 0x4b,
+ 0x00,
+ 0xc9,
+ 0x4a,
+ 0x3a,
+ 0x65,
+ 0x8f,
+ 0xe6,
+ 0x5d,
+ 0xe5,
+ 0x0a,
+ 0x77,
+ 0xd8,
+ 0x1a,
+ 0x14,
+ 0x41,
+ 0x75,
+ 0xb1,
+ 0xe2,
+ 0x50,
+ 0x2c,
+ 0x93,
+ 0x38,
+ 0x2b,
+ 0x6d,
+ 0xf3,
+ 0xf6,
+ 0xdb,
+ 0x1f,
+ 0xcd,
+ 0xff,
+ 0x14,
+ 0x70,
+ 0xe7,
+ 0x16,
+ 0xe8,
+ 0x3d,
+ 0xf0,
+ 0xe3,
+ 0xbc,
+ 0x5e,
+ 0xb6,
+ 0x3f,
+ 0xcc,
+ 0x81,
+ 0x24,
+ 0x67,
+ 0xf3,
+ 0x97,
+ 0x3b,
+ 0xfe,
+ 0x3a,
+ 0x96,
+ 0x85,
+ 0xdf,
+ 0xe4,
+ 0x6e,
+ 0x3c,
+ 0x85,
+ 0x05,
+ 0x0e,
+ 0xa3,
+ 0x2b,
+ 0x07,
+ 0xc8,
+ 0xbf,
+ 0xe5,
+ 0x13,
+ 0x82,
+ 0x62,
+ 0x08,
+ 0x61,
+ 0x69,
+ 0x4b,
+ 0x47,
+ 0x62,
+ 0x73,
+ 0x44,
+ 0x64,
+ 0x8e,
+ 0xe2,
+ 0x91,
+ 0xa6,
+ 0x9a,
+ 0xb7,
+ 0xe9,
+ 0x04,
+ 0xb6,
+ 0x54,
+ 0x0c,
+ 0xc5,
+ 0xa9,
+ 0x47,
+ 0xa6,
+ 0xc9,
+ 0x08,
+ 0xfe,
+ 0x4e,
+ 0xa6,
+ 0xcc,
+ 0x8a,
+ 0x5b,
+ 0x90,
+ 0x6f,
+ 0x2b,
+ 0x3f,
+ 0xb6,
+ 0x0a,
+ 0x96,
+ 0xc0,
+ 0x78,
+ 0x58,
+ 0x3c,
+ 0x76,
+ 0x6d,
+ 0x94,
+ 0x1a,
+ 0xe4,
+ 0x4e,
+ 0xb8,
+ 0x38,
+ 0xbb,
+ 0xf5,
+ 0xeb,
+ 0x29,
+ 0xd8,
+ 0xb0,
+ 0xf3,
+ 0x15,
+ 0x1e,
+ 0x99,
+ 0x96,
+ 0x3c,
+ 0x5d,
+ 0x63,
+ 0xd5,
+ 0xb1,
+ 0xad,
+ 0x52,
+ 0xb8,
+ 0x55,
+ 0x70,
+ 0x75,
+ 0x3e,
+ 0x1a,
+ 0xd5,
+ 0xda,
+ 0xf6,
+ 0x7a,
+ 0x48,
+ 0x7d,
+ 0x44,
+ 0x41,
+ 0xf9,
+ 0x11,
+ 0xce,
+ 0xd7,
+ 0xca,
+ 0xa5,
+ 0x3d,
+ 0x7a,
+ 0x79,
+ 0x7e,
+ 0x7d,
+ 0x25,
+ 0x1b,
+ 0x77,
+ 0xbc,
+ 0xf7,
+ 0xc7,
+ 0x0f,
+ 0x84,
+ 0x95,
+ 0x10,
+ 0x92,
+ 0x67,
+ 0x15,
+ 0x11,
+ 0x5a,
+ 0x5e,
+ 0x41,
+ 0x66,
+ 0x0f,
+ 0x38,
+ 0x03,
+ 0xb2,
+ 0xf1,
+ 0x5d,
+ 0xf8,
+ 0xab,
+ 0xc0,
+ 0x02,
+ 0x76,
+ 0x84,
+ 0x28,
+ 0xf4,
+ 0x9d,
+ 0x56,
+ 0x46,
+ 0x60,
+ 0x20,
+ 0xdb,
+ 0x68,
+ 0xa7,
+ 0xbb,
+ 0xee,
+ 0xac,
+ 0x15,
+ 0x01,
+ 0x2f,
+ 0x20,
+ 0x09,
+ 0xdb,
+ 0xc0,
+ 0x16,
+ 0xa1,
+ 0x89,
+ 0xf9,
+ 0x94,
+ 0x59,
+ 0x00,
+ 0xc1,
+ 0x76,
+ 0xbf,
+ 0xc1,
+ 0x4d,
+ 0x5d,
+ 0x2d,
+ 0xa9,
+ 0x85,
+ 0x2c,
+ 0xd6,
+ 0xd3,
+ 0x14,
+ 0xcc,
+ 0x02,
+ 0xc3,
+ 0xc2,
+ 0xfa,
+ 0x6b,
+ 0xb7,
+ 0xa6,
+ 0xef,
+ 0xdd,
+ 0x12,
+ 0x26,
+ 0xa4,
+ 0x63,
+ 0xe3,
+ 0x62,
+ 0xbd,
+ 0x56,
+ 0x8a,
+ 0x52,
+ 0x2b,
+ 0xb9,
+ 0xdf,
+ 0x09,
+ 0xbc,
+ 0x0e,
+ 0x97,
+ 0xa9,
+ 0xb0,
+ 0x82,
+ 0x46,
+ 0x08,
+ 0xd5,
+ 0x1a,
+ 0x8e,
+ 0x1b,
+ 0xa7,
+ 0x90,
+ 0x98,
+ 0xb9,
+ 0xbb,
+ 0x3c,
+ 0x17,
+ 0x9a,
+ 0xf2,
+ 0x82,
+ 0xba,
+ 0x64,
+ 0x0a,
+ 0x7f,
+ 0xca,
+ 0x5a,
+ 0x8c,
+ 0x7c,
+ 0xd3,
+ 0x79,
+ 0x09,
+ 0x5b,
+ 0x26,
+ 0xbb,
+ 0xbd,
+ 0x25,
+ 0xdf,
+ 0x3d,
+ 0x6f,
+ 0x9a,
+ 0x8f,
+ 0xee,
+ 0x21,
+ 0x66,
+ 0xb0,
+ 0x8d,
+ 0x84,
+ 0x4c,
+ 0x91,
+ 0x45,
+ 0xd4,
+ 0x77,
+ 0x4f,
+ 0xb3,
+ 0x8c,
+ 0xbc,
+ 0xa8,
+ 0x99,
+ 0xaa,
+ 0x19,
+ 0x53,
+ 0x7c,
+ 0x02,
+ 0x87,
+ 0xbb,
+ 0x0b,
+ 0x7c,
+ 0x1a,
+ 0x2d,
+ 0xdf,
+ 0x48,
+ 0x44,
+ 0x06,
+ 0xd6,
+ 0x7d,
+ 0x0c,
+ 0x2d,
+ 0x35,
+ 0x76,
+ 0xae,
+ 0xc4,
+ 0x5f,
+ 0x71,
+ 0x85,
+ 0x97,
+ 0xc4,
+ 0x3d,
+ 0xef,
+ 0x52,
+ 0xbe,
+ 0x00,
+ 0xe4,
+ 0xcd,
+ 0x49,
+ 0xd1,
+ 0xd1,
+ 0x1c,
+ 0x3c,
+ 0xd0,
+ 0x1c,
+ 0x42,
+ 0xaf,
+ 0xd4,
+ 0xbd,
+ 0x58,
+ 0x34,
+ 0x07,
+ 0x32,
+ 0xee,
+ 0xb9,
+ 0xb5,
+ 0xea,
+ 0xff,
+ 0xd7,
+ 0x8c,
+ 0x0d,
+ 0x2e,
+ 0x2f,
+ 0xaf,
+ 0x87,
+ 0xbb,
+ 0xe6,
+ 0x52,
+ 0x71,
+ 0x22,
+ 0xf5,
+ 0x25,
+ 0x17,
+ 0xa1,
+ 0x82,
+ 0x04,
+ 0xc2,
+ 0x4a,
+ 0xbd,
+ 0x57,
+ 0xc6,
+ 0xab,
+ 0xc8,
+ 0x35,
+ 0x0c,
+ 0x3c,
+ 0xd9,
+ 0xc2,
+ 0x43,
+ 0xdb,
+ 0x27,
+ 0x92,
+ 0xcf,
+ 0xb8,
+ 0x25,
+ 0x60,
+ 0xfa,
+ 0x21,
+ 0x3b,
+ 0x04,
+ 0x52,
+ 0xc8,
+ 0x96,
+ 0xba,
+ 0x74,
+ 0xe3,
+ 0x67,
+ 0x3e,
+ 0x8e,
+ 0x8d,
+ 0x61,
+ 0x90,
+ 0x92,
+ 0x59,
+ 0xb6,
+ 0x1a,
+ 0x1c,
+ 0x5e,
+ 0x21,
+ 0xc1,
+ 0x65,
+ 0xe5,
+ 0xa6,
+ 0x34,
+ 0x05,
+ 0x6f,
+ 0xc5,
+ 0x60,
+ 0xb1,
+ 0x83,
+ 0xc1,
+ 0xd5,
+ 0xd5,
+ 0xed,
+ 0xd9,
+ 0xc7,
+ 0x11,
+ 0x7b,
+ 0x49,
+ 0x7a,
+ 0xf9,
+ 0xf9,
+ 0x84,
+ 0x47,
+ 0x9b,
+ 0xe2,
+ 0xa5,
+ 0x82,
+ 0xe0,
+ 0xc2,
+ 0x88,
+ 0xd0,
+ 0xb2,
+ 0x58,
+ 0x88,
+ 0x7f,
+ 0x45,
+ 0x09,
+ 0x67,
+ 0x74,
+ 0x61,
+ 0xbf,
+ 0xe6,
+ 0x40,
+ 0xe2,
+ 0x9d,
+ 0xc2,
+ 0x47,
+ 0x05,
+ 0x89,
+ 0xed,
+ 0xcb,
+ 0xbb,
+ 0xb7,
+ 0x27,
+ 0xe7,
+ 0xdc,
+ 0x7a,
+ 0xfd,
+ 0xbf,
+ 0xa8,
+ 0xd0,
+ 0xaa,
+ 0x10,
+ 0x39,
+ 0x3c,
+ 0x20,
+ 0xf0,
+ 0xd3,
+ 0x6e,
+ 0xb1,
+ 0x72,
+ 0xf8,
+ 0xe6,
+ 0x0f,
+ 0xef,
+ 0x37,
+ 0xe5,
+ 0x09,
+ 0x33,
+ 0x5a,
+ 0x83,
+ 0x43,
+ 0x80,
+ 0x4f,
+ 0x65,
+ 0x2f,
+ 0x7c,
+ 0x8c,
+ 0x6a,
+ 0xa0,
+ 0x82,
+ 0x0c,
+ 0xd4,
+ 0xd4,
+ 0xfa,
+ 0x81,
+ 0x60,
+ 0x3d,
+ 0xdf,
+ 0x06,
+ 0xf1,
+ 0x5f,
+ 0x08,
+ 0x0d,
+ 0x6d,
+ 0x43,
+ 0xf2,
+ 0xe3,
+ 0x11,
+ 0x7d,
+ 0x80,
+ 0x32,
+ 0xc5,
+ 0xfb,
+ 0xc5,
+ 0xd9,
+ 0x27,
+ 0xec,
+ 0xc6,
+ 0x4e,
+ 0x65,
+ 0x27,
+ 0x76,
+ 0x87,
+ 0xa6,
+ 0xee,
+ 0xee,
+ 0xd7,
+ 0x8b,
+ 0xd1,
+ 0xa0,
+ 0x5c,
+ 0xb0,
+ 0x42,
+ 0x13,
+ 0x0e,
+ 0x95,
+ 0x4a,
+ 0xf2,
+ 0x06,
+ 0xc6,
+ 0x43,
+ 0x33,
+ 0xf4,
+ 0xc7,
+ 0xf8,
+ 0xe7,
+ 0x1f,
+ 0xdd,
+ 0xe4,
+ 0x46,
+ 0x4a,
+ 0x70,
+ 0x39,
+ 0x6c,
+ 0xd0,
+ 0xed,
+ 0xca,
+ 0xbe,
+ 0x60,
+ 0x3b,
+ 0xd1,
+ 0x7b,
+ 0x57,
+ 0x48,
+ 0xe5,
+ 0x3a,
+ 0x79,
+ 0xc1,
+ 0x69,
+ 0x33,
+ 0x53,
+ 0x1b,
+ 0x80,
+ 0xb8,
+ 0x91,
+ 0x7d,
+ 0xb4,
+ 0xf6,
+ 0x17,
+ 0x1a,
+ 0x1d,
+ 0x5a,
+ 0x32,
+ 0xd6,
+ 0xcc,
+ 0x71,
+ 0x29,
+ 0x3f,
+ 0x28,
+ 0xbb,
+ 0xf3,
+ 0x5e,
+ 0x71,
+ 0xb8,
+ 0x43,
+ 0xaf,
+ 0xf8,
+ 0xb9,
+ 0x64,
+ 0xef,
+ 0xc4,
+ 0xa5,
+ 0x6c,
+ 0x08,
+ 0x53,
+ 0xc7,
+ 0x00,
+ 0x10,
+ 0x39,
+ 0x4f,
+ 0xdd,
+ 0xe4,
+ 0xb6,
+ 0x19,
+ 0x27,
+ 0xfb,
+ 0xb8,
+ 0xf5,
+ 0x32,
+ 0x73,
+ 0xe5,
+ 0xcb,
+ 0x32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ static byte chkb[] = new byte [60 + 4];
+
+ /**
+ * Calculates a crc checksum-sequence over an array.
+ */
+ public static byte BlockSequenceCRCByte(byte base[], int offset, int length, int sequence)
+ {
+ int n;
+ int p_ndx;
+ short x;
+
+ short crc;
+
+ if (sequence < 0)
+ Sys.Error("sequence < 0, this shouldn't happen\n");
+
+ //p_ndx = (sequence % (sizeof(chktbl) - 4));
+ p_ndx = (sequence % (1024 - 4));
+
+ //memcpy(chkb, base, length);
+ System.arraycopy(base, offset , chkb, 0, Math.max(60, length));
+
+ chkb[length]= (byte) chktbl[p_ndx + 0];
+ chkb[length + 1]= (byte) chktbl[p_ndx + 1];
+ chkb[length + 2]= (byte) chktbl[p_ndx + 2];
+ chkb[length + 3]= (byte) chktbl[p_ndx + 3];
+
+
+ length += 4;
+
+ crc = CRC.CRC_Block(chkb, length);
+
+ for (x= 0, n= 0; n < length; n++)
+ x += chkb[n];
+
+ crc ^= x;
+
+ return (byte)(crc & 0xFF);
+ }
+
} \ No newline at end of file
diff --git a/src/jake2/qcommon/FS.java b/src/jake2/qcommon/FS.java
index 98975a6..a99ae28 100644
--- a/src/jake2/qcommon/FS.java
+++ b/src/jake2/qcommon/FS.java
@@ -2,7 +2,7 @@
* FS.java
* Copyright (C) 2003
*
- * $Id: FS.java,v 1.2 2004-07-08 15:58:46 hzi Exp $
+ * $Id: FS.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -33,8 +33,6 @@ import jake2.sys.Sys;
import java.io.*;
import java.nio.ByteOrder;
import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.imageio.stream.FileImageInputStream;
@@ -45,8 +43,6 @@ import javax.imageio.stream.FileImageInputStream;
*/
public final class FS extends Globals {
- private static Logger logger = Logger.getLogger(FS.class.getName());
-
/*
=============================================================================
@@ -120,7 +116,7 @@ public final class FS extends Globals {
if (index > 0) {
File f = new File(path.substring(0, index));
if (!f.mkdirs()) {
- logger.log(Level.WARNING, "can't create path \"" + path + '"');
+ Com.Printf("can't create path \"" + path + '"' + "\n" );
}
}
}
@@ -448,12 +444,12 @@ public final class FS extends Globals {
newfiles.put(entry.name.toLowerCase(), entry);
- logger.log(Level.FINEST, i + ".\t" + entry);
+ //logger.log(Level.FINEST, i + ".\t" + entry);
}
}
catch (IOException e) {
- logger.log(Level.WARNING, e.toString());
+ //logger.log(Level.WARNING, e.toString());
return null;
}
@@ -577,7 +573,7 @@ public final class FS extends Globals {
fs_searchpaths.pack.handle.close();
}
catch (IOException e) {
- logger.log(Level.WARNING, e.toString());
+ //logger.log(Level.WARNING, e.toString());
}
// clear the hashtable
fs_searchpaths.pack.files.clear();
diff --git a/src/jake2/qcommon/MD4.java b/src/jake2/qcommon/MD4.java
index 45fdf7c..2c01f08 100644
--- a/src/jake2/qcommon/MD4.java
+++ b/src/jake2/qcommon/MD4.java
@@ -19,11 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 02.02.2004 by RST.
-// $Id: MD4.java,v 1.1 2004-07-07 19:59:31 hzi Exp $
+// $Id: MD4.java,v 1.2 2004-07-09 06:50:49 hzi Exp $
package jake2.qcommon;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.security.MessageDigest;
import jake2.*;
@@ -295,17 +296,18 @@ public class MD4 extends MessageDigest implements Cloneable {
return t << s | t >>> (32 - s);
}
+ /**
+ * Bugfixed, now works prima (RST).
+ */
public static int Com_BlockChecksum(byte[] buffer, int length) {
- byte digest[] = new byte[16];
+
int val;
MD4 md4 = new MD4();
md4.engineUpdate(buffer, 0, length);
- byte data[] = md4.engineDigest();
- Com.Printf("md4: " + Lib.hexDump(data, 16, false));
-
+ byte data[] = md4.engineDigest();
ByteBuffer bb = ByteBuffer.wrap(data);
- //val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
+ bb.order(ByteOrder.LITTLE_ENDIAN);
val = bb.getInt() ^ bb.getInt() ^ bb.getInt() ^ bb.getInt();
return val;
}
diff --git a/src/jake2/qcommon/Qcommon.java b/src/jake2/qcommon/Qcommon.java
index 3da48ca..9f653d4 100644
--- a/src/jake2/qcommon/Qcommon.java
+++ b/src/jake2/qcommon/Qcommon.java
@@ -2,7 +2,7 @@
* Qcommon.java
* Copyright 2003
*
- * $Id: Qcommon.java,v 1.3 2004-07-08 20:24:48 hzi Exp $
+ * $Id: Qcommon.java,v 1.4 2004-07-09 06:50:49 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -28,8 +28,6 @@ package jake2.qcommon;
import jake2.Globals;
import jake2.client.*;
import jake2.game.Cmd;
-import jake2.game.EntThinkAdapter;
-import jake2.game.GamePWeapon;
import jake2.game.Swap;
import jake2.server.SV_MAIN;
import jake2.sys.NET;
@@ -47,95 +45,11 @@ public final class Qcommon extends Globals {
public static final String BUILDSTRING = "Java";
public static final String CPUSTRING = "jvm";
-
- /**
- * This function initializes the different subsystems of
- * the game engine. The setjmp/longjmp mechanism of the original
- * was replaced with exceptions.
- * @param args the original unmodified command line arguments
- */
- public static void InitForTestMap(String[] args) {
- try {
-
- // prepare enough of the subsystems to handle
- // cvar and command buffer management
- Com.InitArgv(args);
-
- Swap.Init();
- Cbuf.Init();
-
- Cmd.Init();
- Cvar.Init();
-
- Key.Init();
-
- // we need to add the early commands twice, because
- // a basedir or cddir needs to be set before execing
- // config files, but we want other parms to override
- // the settings of the config files
- Cbuf.AddEarlyCommands(false);
- Cbuf.Execute();
-
- FS.InitFilesystem();
-
- Cbuf.AddText("exec default.cfg\n");
- Cbuf.AddText("exec config.cfg\n");
-
- Cbuf.AddEarlyCommands(true);
- Cbuf.Execute();
-
- //
- // init commands and vars
- //
- Cmd.AddCommand("error", Com.Error_f);
-
- Globals.host_speeds= Cvar.Get("host_speeds", "0", 0);
- Globals.log_stats= Cvar.Get("log_stats", "0", 0);
- Globals.developer= Cvar.Get("developer", "0", 0);
- Globals.timescale= Cvar.Get("timescale", "1", 0);
- Globals.fixedtime= Cvar.Get("fixedtime", "0", 0);
- Globals.logfile_active= Cvar.Get("logfile", "0", 0);
- Globals.showtrace= Cvar.Get("showtrace", "0", 0);
- Globals.dedicated= Cvar.Get("dedicated", "0", CVAR_NOSET);
-
- String s = Com.sprintf("%4.2f %s %s %s",
- new Vargs(4)
- .add(Globals.VERSION)
- .add(CPUSTRING)
- .add(Globals.__DATE__)
- .add(BUILDSTRING));
-
- Cvar.Get("version", s, CVAR_SERVERINFO | CVAR_NOSET);
-
- NET.NET_Init();
- Netchan.Netchan_Init();
-
- SV_MAIN.SV_Init();
- CL.Init();
-
- // add + commands from command line
- if (!Cbuf.AddLateCommands()) {
- // if the user didn't give any commands, run default action
- //Cbuf.AddText("d1\n");
- Cbuf.Execute();
- } else {
- // the user asked for something explicit
- // so drop the loading plaque
- SCR.EndLoadingPlaque();
- }
-
- Com.Printf("====== Quake2 Initialized ======\n\n");
-
- } catch (longjmpException e) {
- Sys.Error("Error during initialization");
- }
- }
-
/**
* This function initializes the different subsystems of
- * the game engine. The setjmp/longjmp mechanism of the original
- * was replaced with exceptions.
+ * the game engine. The setjmp/longjmp mechanism of the original
+ * was replaced with exceptions.
* @param args the original unmodified command line arguments
*/
public static void Init(String[] args) {
@@ -147,8 +61,6 @@ public final class Qcommon extends Globals {
Swap.Init();
Cbuf.Init();
- //rst bugfix
- //GamePWeapon xxx = new GamePWeapon();
Cmd.Init();
Cvar.Init();
diff --git a/src/jake2/qcommon/qfiles.java b/src/jake2/qcommon/qfiles.java
index ae7fdf6..8e524a5 100644
--- a/src/jake2/qcommon/qfiles.java
+++ b/src/jake2/qcommon/qfiles.java
@@ -2,7 +2,7 @@
* qfiles.java
* Copyright (C) 2003
*
- * $Id: qfiles.java,v 1.3 2004-07-08 20:24:48 hzi Exp $
+ * $Id: qfiles.java,v 1.4 2004-07-09 06:50:50 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,14 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2.qcommon;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
+import jake2.Defines;
-import jake2.*;
-import jake2.client.*;
-import jake2.game.*;
-import jake2.render.*;
-import jake2.server.*;
+import java.nio.*;
/**
* qfiles
@@ -292,6 +287,14 @@ public class qfiles {
ofs_glcmds = b.getInt();
ofs_end = b.getInt(); // end of file
}
+
+ /*
+ * new members for vertex array handling
+ */
+ public FloatBuffer textureCoordBuf = null;
+ public IntBuffer vertexIndexBuf = null;
+ public int[] counts = null;
+ public IntBuffer[] indexElements = null;
}
/*
diff --git a/src/jake2/render/FastJoglRenderer.java b/src/jake2/render/FastJoglRenderer.java
new file mode 100644
index 0000000..da20bfd
--- /dev/null
+++ b/src/jake2/render/FastJoglRenderer.java
@@ -0,0 +1,306 @@
+/*
+ * FastJoglRenderer.java
+ * Copyright (C) 2003
+ *
+ * $Id: FastJoglRenderer.java,v 1.1 2004-07-09 06:50:47 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render;
+
+import jake2.Defines;
+import jake2.client.*;
+import jake2.qcommon.xcommand_t;
+import jake2.render.fastjogl.Impl;
+
+import java.awt.Dimension;
+
+/**
+ * FastJoglRenderer
+ *
+ * @author cwei
+ */
+final class FastJoglRenderer extends Impl implements refexport_t, Ref {
+
+ static {
+ Renderer.register(new FastJoglRenderer());
+ };
+
+ private FastJoglRenderer() {
+ }
+
+ // ============================================================================
+ // public interface for Renderer implementations
+ //
+ // refexport_t (ref.h)
+ // ============================================================================
+
+ /**
+ * @see jake2.client.refexport_t#Init()
+ */
+ public boolean Init(int vid_xpos, int vid_ypos) {
+
+ // pre init
+ if (!R_Init(vid_xpos, vid_ypos)) return false;
+ // calls the R_Init2() internally
+ updateScreen();
+ // the result from R_Init2()
+ return post_init;
+ }
+
+ /**
+ * @see jake2.client.refexport_t#Shutdown()
+ */
+ public void Shutdown() {
+ R_Shutdown();
+ }
+
+ /**
+ * @see jake2.client.refexport_t#BeginRegistration(java.lang.String)
+ */
+ public void BeginRegistration(String map) {
+ if (contextInUse) {
+ R_BeginRegistration(map);
+ return;
+ }
+ this.name = map;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ R_BeginRegistration(FastJoglRenderer.this.name);
+ }
+ });
+ }
+
+
+ private model_t model = null;
+ private String name = null;
+
+ /**
+ * @see jake2.client.refexport_t#RegisterModel(java.lang.String)
+ */
+ public model_t RegisterModel(String name) {
+
+ if (contextInUse)
+ return R_RegisterModel(name);
+
+ model = null;
+ this.name = name;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ FastJoglRenderer.this.model = R_RegisterModel(FastJoglRenderer.this.name);
+ }
+ });
+ return model;
+ }
+
+ /**
+ * @see jake2.client.refexport_t#RegisterSkin(java.lang.String)
+ */
+ public image_t RegisterSkin(String name) {
+ if (contextInUse)
+ return R_RegisterSkin(name);
+
+ this.image = null;
+ this.name = name;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ FastJoglRenderer.this.image = R_RegisterSkin(FastJoglRenderer.this.name);
+ }
+ });
+ return image;
+ }
+
+ private image_t image = null;
+
+ /**
+ * @see jake2.client.refexport_t#RegisterPic(java.lang.String)
+ */
+ public image_t RegisterPic(String name) {
+ if (contextInUse)
+ return Draw_FindPic(name);
+
+ this.image = null;
+ this.name = name;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ FastJoglRenderer.this.image = Draw_FindPic(FastJoglRenderer.this.name);
+ }
+ });
+ return image;
+ }
+
+
+ private float[] axis;
+ private float rotate;
+
+ /**
+ * @see jake2.client.refexport_t#SetSky(java.lang.String, float, float[])
+ */
+ public void SetSky(String name, float rotate, float[] axis) {
+ if (contextInUse) {
+ R_SetSky(name, rotate, axis);
+ return;
+ }
+
+ this.name = name;
+ this.rotate = rotate;
+ this.axis = axis;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ R_SetSky(FastJoglRenderer.this.name, FastJoglRenderer.this.rotate, FastJoglRenderer.this.axis);
+ }
+ });
+
+ }
+
+ /**
+ * @see jake2.client.refexport_t#EndRegistration()
+ */
+ public void EndRegistration() {
+ if (contextInUse) {
+ R_EndRegistration();
+ return;
+ }
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ R_EndRegistration();
+ }
+ });
+ }
+
+ /**
+ * @see jake2.client.refexport_t#RenderFrame(jake2.client.refdef_t)
+ */
+ public void RenderFrame(refdef_t fd) {
+ R_RenderFrame(fd);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawGetPicSize(java.awt.Dimension, java.lang.String)
+ */
+ public void DrawGetPicSize(Dimension dim, String name) {
+ Draw_GetPicSize(dim, name);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawPic(int, int, java.lang.String)
+ */
+ public void DrawPic(int x, int y, String name) {
+ Draw_Pic(x, y, name);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawStretchPic(int, int, int, int, java.lang.String)
+ */
+ public void DrawStretchPic(int x, int y, int w, int h, String name) {
+ Draw_StretchPic(x, y, w, h, name);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawChar(int, int, int)
+ */
+ public void DrawChar(int x, int y, int num) {
+ Draw_Char(x, y, num);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawTileClear(int, int, int, int, java.lang.String)
+ */
+ public void DrawTileClear(int x, int y, int w, int h, String name) {
+ Draw_TileClear(x, y, w, h, name);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawFill(int, int, int, int, int)
+ */
+ public void DrawFill(int x, int y, int w, int h, int c) {
+ Draw_Fill(x, y, w, h, c);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawFadeScreen()
+ */
+ public void DrawFadeScreen() {
+ Draw_FadeScreen();
+ }
+
+ /**
+ * @see jake2.client.refexport_t#DrawStretchRaw(int, int, int, int, int, int, byte[])
+ */
+ public void DrawStretchRaw(int x, int y, int w, int h, int cols, int rows, byte[] data) {
+ Draw_StretchRaw(x, y, w, h, cols, rows, data);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#CinematicSetPalette(byte[])
+ */
+ public void CinematicSetPalette(byte[] palette) {
+ R_SetPalette(palette);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#BeginFrame(float)
+ */
+ public void BeginFrame(float camera_separation) {
+ R_BeginFrame(camera_separation);
+ }
+
+ /**
+ * @see jake2.client.refexport_t#EndFrame()
+ */
+ public void EndFrame() {
+ GLimp_EndFrame();
+ }
+
+ /**
+ * @see jake2.client.refexport_t#AppActivate(boolean)
+ */
+ public void AppActivate(boolean activate) {
+ GLimp_AppActivate(activate);
+ }
+
+ public int apiVersion() {
+ return Defines.API_VERSION;
+ }
+
+ // ============================================================================
+ // Ref interface
+ // ============================================================================
+
+ public String getName() {
+ return DRIVER_NAME;
+ }
+
+ public String toString() {
+ return DRIVER_NAME;
+ }
+
+ public refexport_t GetRefAPI(refimport_t rimp) {
+ this.ri = rimp;
+ return this;
+ }
+
+} \ No newline at end of file
diff --git a/src/jake2/render/JoglRenderer.java b/src/jake2/render/JoglRenderer.java
index 2829a96..97e3967 100644
--- a/src/jake2/render/JoglRenderer.java
+++ b/src/jake2/render/JoglRenderer.java
@@ -2,7 +2,7 @@
* JoglRenderer.java
* Copyright (C) 2003
*
- * $Id: JoglRenderer.java,v 1.2 2004-07-08 15:58:48 hzi Exp $
+ * $Id: JoglRenderer.java,v 1.3 2004-07-09 06:50:47 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,15 +25,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2.render;
-import java.awt.Dimension;
-
import jake2.Defines;
+import jake2.client.*;
import jake2.qcommon.xcommand_t;
-import jake2.render.jogl.*;
+import jake2.render.jogl.Impl;
-import jake2.client.refdef_t;
-import jake2.client.refexport_t;
-import jake2.client.refimport_t;
+import java.awt.Dimension;
/**
* JoglRenderer
@@ -59,11 +56,10 @@ final class JoglRenderer extends Impl implements refexport_t, Ref {
* @see jake2.client.refexport_t#Init()
*/
public boolean Init(int vid_xpos, int vid_ypos) {
-
// pre init
if (!R_Init(vid_xpos, vid_ypos)) return false;
// calls the R_Init2() internally
- updateScreen(null);
+ updateScreen();
// the result from R_Init2()
return post_init;
}
@@ -79,7 +75,18 @@ final class JoglRenderer extends Impl implements refexport_t, Ref {
* @see jake2.client.refexport_t#BeginRegistration(java.lang.String)
*/
public void BeginRegistration(String map) {
- R_BeginRegistration(map);
+ if (contextInUse) {
+ R_BeginRegistration(map);
+ return;
+ }
+
+ this.name = map;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ R_BeginRegistration(JoglRenderer.this.name);
+ }
+ });
}
@@ -143,18 +150,43 @@ final class JoglRenderer extends Impl implements refexport_t, Ref {
return image;
}
+ private float[] axis;
+ private float rotate;
+
/**
* @see jake2.client.refexport_t#SetSky(java.lang.String, float, float[])
*/
public void SetSky(String name, float rotate, float[] axis) {
- R_SetSky(name, rotate, axis);
+ if (contextInUse) {
+ R_SetSky(name, rotate, axis);
+ return;
+ }
+
+ this.name = name;
+ this.rotate = rotate;
+ this.axis = axis;
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ R_SetSky(JoglRenderer.this.name, JoglRenderer.this.rotate, JoglRenderer.this.axis);
+ }
+ });
}
/**
* @see jake2.client.refexport_t#EndRegistration()
*/
public void EndRegistration() {
- R_EndRegistration();
+ if (contextInUse) {
+ R_EndRegistration();
+ return;
+ }
+
+ updateScreen(new xcommand_t() {
+ public void execute() {
+ R_EndRegistration();
+ }
+ });
}
/**
@@ -268,5 +300,4 @@ final class JoglRenderer extends Impl implements refexport_t, Ref {
this.ri = rimp;
return this;
}
-
} \ No newline at end of file
diff --git a/src/jake2/render/Renderer.java b/src/jake2/render/Renderer.java
index fbd9909..55d985c 100644
--- a/src/jake2/render/Renderer.java
+++ b/src/jake2/render/Renderer.java
@@ -2,7 +2,7 @@
* Renderer.java
* Copyright (C) 2003
*
- * $Id: Renderer.java,v 1.1 2004-07-07 19:59:34 hzi Exp $
+ * $Id: Renderer.java,v 1.2 2004-07-09 06:50:47 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -26,8 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
package jake2.render;
import java.util.Vector;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import jake2.client.refexport_t;
import jake2.client.refimport_t;
@@ -39,7 +37,6 @@ import jake2.client.refimport_t;
*/
public class Renderer {
- private static Logger logger = Logger.getLogger(Renderer.class.getName());
static Vector drivers = new Vector(3);
@@ -49,8 +46,8 @@ public class Renderer {
static {
try {
Class.forName("jake2.render.JoglRenderer");
+ Class.forName("jake2.render.FastJoglRenderer");
} catch (ClassNotFoundException e) {
- logger.log(Level.SEVERE, "can't found " + DEFAULT_CLASS);
e.printStackTrace();
}
};
@@ -74,13 +71,12 @@ public class Renderer {
// find a driver
Ref driver = null;
int count = drivers.size();
- for (int i = 0; i < count && driver == null; i++) {
+ for (int i = 0; i < count; i++) {
driver = (Ref) drivers.get(i);
if (driver.getName().equals(driverName)) {
return driver.GetRefAPI(rimp);
}
}
- logger.log(Level.INFO, "Refresh driver \"" + driverName + "\"not found");
// null if driver not found
return null;
}
diff --git a/src/jake2/render/fastjogl/Anorms.java b/src/jake2/render/fastjogl/Anorms.java
new file mode 100644
index 0000000..552b305
--- /dev/null
+++ b/src/jake2/render/fastjogl/Anorms.java
@@ -0,0 +1,219 @@
+/*
+ * Anorms.java
+ * Copyright (C) 2003
+ *
+ * $Id: Anorms.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+/**
+ * Anorms
+ *
+ * @author cwei
+ */
+public interface Anorms {
+
+ final float[][] VERTEXNORMALS = {
+ {-0.525731f, 0.000000f, 0.850651f},
+ {-0.442863f, 0.238856f, 0.864188f},
+ {-0.295242f, 0.000000f, 0.955423f},
+ {-0.309017f, 0.500000f, 0.809017f},
+ {-0.162460f, 0.262866f, 0.951056f},
+ {0.000000f, 0.000000f, 1.000000f},
+ {0.000000f, 0.850651f, 0.525731f},
+ {-0.147621f, 0.716567f, 0.681718f},
+ {0.147621f, 0.716567f, 0.681718f},
+ {0.000000f, 0.525731f, 0.850651f},
+ {0.309017f, 0.500000f, 0.809017f},
+ {0.525731f, 0.000000f, 0.850651f},
+ {0.295242f, 0.000000f, 0.955423f},
+ {0.442863f, 0.238856f, 0.864188f},
+ {0.162460f, 0.262866f, 0.951056f},
+ {-0.681718f, 0.147621f, 0.716567f},
+ {-0.809017f, 0.309017f, 0.500000f},
+ {-0.587785f, 0.425325f, 0.688191f},
+ {-0.850651f, 0.525731f, 0.000000f},
+ {-0.864188f, 0.442863f, 0.238856f},
+ {-0.716567f, 0.681718f, 0.147621f},
+ {-0.688191f, 0.587785f, 0.425325f},
+ {-0.500000f, 0.809017f, 0.309017f},
+ {-0.238856f, 0.864188f, 0.442863f},
+ {-0.425325f, 0.688191f, 0.587785f},
+ {-0.716567f, 0.681718f, -0.147621f},
+ {-0.500000f, 0.809017f, -0.309017f},
+ {-0.525731f, 0.850651f, 0.000000f},
+ {0.000000f, 0.850651f, -0.525731f},
+ {-0.238856f, 0.864188f, -0.442863f},
+ {0.000000f, 0.955423f, -0.295242f},
+ {-0.262866f, 0.951056f, -0.162460f},
+ {0.000000f, 1.000000f, 0.000000f},
+ {0.000000f, 0.955423f, 0.295242f},
+ {-0.262866f, 0.951056f, 0.162460f},
+ {0.238856f, 0.864188f, 0.442863f},
+ {0.262866f, 0.951056f, 0.162460f},
+ {0.500000f, 0.809017f, 0.309017f},
+ {0.238856f, 0.864188f, -0.442863f},
+ {0.262866f, 0.951056f, -0.162460f},
+ {0.500000f, 0.809017f, -0.309017f},
+ {0.850651f, 0.525731f, 0.000000f},
+ {0.716567f, 0.681718f, 0.147621f},
+ {0.716567f, 0.681718f, -0.147621f},
+ {0.525731f, 0.850651f, 0.000000f},
+ {0.425325f, 0.688191f, 0.587785f},
+ {0.864188f, 0.442863f, 0.238856f},
+ {0.688191f, 0.587785f, 0.425325f},
+ {0.809017f, 0.309017f, 0.500000f},
+ {0.681718f, 0.147621f, 0.716567f},
+ {0.587785f, 0.425325f, 0.688191f},
+ {0.955423f, 0.295242f, 0.000000f},
+ {1.000000f, 0.000000f, 0.000000f},
+ {0.951056f, 0.162460f, 0.262866f},
+ {0.850651f, -0.525731f, 0.000000f},
+ {0.955423f, -0.295242f, 0.000000f},
+ {0.864188f, -0.442863f, 0.238856f},
+ {0.951056f, -0.162460f, 0.262866f},
+ {0.809017f, -0.309017f, 0.500000f},
+ {0.681718f, -0.147621f, 0.716567f},
+ {0.850651f, 0.000000f, 0.525731f},
+ {0.864188f, 0.442863f, -0.238856f},
+ {0.809017f, 0.309017f, -0.500000f},
+ {0.951056f, 0.162460f, -0.262866f},
+ {0.525731f, 0.000000f, -0.850651f},
+ {0.681718f, 0.147621f, -0.716567f},
+ {0.681718f, -0.147621f, -0.716567f},
+ {0.850651f, 0.000000f, -0.525731f},
+ {0.809017f, -0.309017f, -0.500000f},
+ {0.864188f, -0.442863f, -0.238856f},
+ {0.951056f, -0.162460f, -0.262866f},
+ {0.147621f, 0.716567f, -0.681718f},
+ {0.309017f, 0.500000f, -0.809017f},
+ {0.425325f, 0.688191f, -0.587785f},
+ {0.442863f, 0.238856f, -0.864188f},
+ {0.587785f, 0.425325f, -0.688191f},
+ {0.688191f, 0.587785f, -0.425325f},
+ {-0.147621f, 0.716567f, -0.681718f},
+ {-0.309017f, 0.500000f, -0.809017f},
+ {0.000000f, 0.525731f, -0.850651f},
+ {-0.525731f, 0.000000f, -0.850651f},
+ {-0.442863f, 0.238856f, -0.864188f},
+ {-0.295242f, 0.000000f, -0.955423f},
+ {-0.162460f, 0.262866f, -0.951056f},
+ {0.000000f, 0.000000f, -1.000000f},
+ {0.295242f, 0.000000f, -0.955423f},
+ {0.162460f, 0.262866f, -0.951056f},
+ {-0.442863f, -0.238856f, -0.864188f},
+ {-0.309017f, -0.500000f, -0.809017f},
+ {-0.162460f, -0.262866f, -0.951056f},
+ {0.000000f, -0.850651f, -0.525731f},
+ {-0.147621f, -0.716567f, -0.681718f},
+ {0.147621f, -0.716567f, -0.681718f},
+ {0.000000f, -0.525731f, -0.850651f},
+ {0.309017f, -0.500000f, -0.809017f},
+ {0.442863f, -0.238856f, -0.864188f},
+ {0.162460f, -0.262866f, -0.951056f},
+ {0.238856f, -0.864188f, -0.442863f},
+ {0.500000f, -0.809017f, -0.309017f},
+ {0.425325f, -0.688191f, -0.587785f},
+ {0.716567f, -0.681718f, -0.147621f},
+ {0.688191f, -0.587785f, -0.425325f},
+ {0.587785f, -0.425325f, -0.688191f},
+ {0.000000f, -0.955423f, -0.295242f},
+ {0.000000f, -1.000000f, 0.000000f},
+ {0.262866f, -0.951056f, -0.162460f},
+ {0.000000f, -0.850651f, 0.525731f},
+ {0.000000f, -0.955423f, 0.295242f},
+ {0.238856f, -0.864188f, 0.442863f},
+ {0.262866f, -0.951056f, 0.162460f},
+ {0.500000f, -0.809017f, 0.309017f},
+ {0.716567f, -0.681718f, 0.147621f},
+ {0.525731f, -0.850651f, 0.000000f},
+ {-0.238856f, -0.864188f, -0.442863f},
+ {-0.500000f, -0.809017f, -0.309017f},
+ {-0.262866f, -0.951056f, -0.162460f},
+ {-0.850651f, -0.525731f, 0.000000f},
+ {-0.716567f, -0.681718f, -0.147621f},
+ {-0.716567f, -0.681718f, 0.147621f},
+ {-0.525731f, -0.850651f, 0.000000f},
+ {-0.500000f, -0.809017f, 0.309017f},
+ {-0.238856f, -0.864188f, 0.442863f},
+ {-0.262866f, -0.951056f, 0.162460f},
+ {-0.864188f, -0.442863f, 0.238856f},
+ {-0.809017f, -0.309017f, 0.500000f},
+ {-0.688191f, -0.587785f, 0.425325f},
+ {-0.681718f, -0.147621f, 0.716567f},
+ {-0.442863f, -0.238856f, 0.864188f},
+ {-0.587785f, -0.425325f, 0.688191f},
+ {-0.309017f, -0.500000f, 0.809017f},
+ {-0.147621f, -0.716567f, 0.681718f},
+ {-0.425325f, -0.688191f, 0.587785f},
+ {-0.162460f, -0.262866f, 0.951056f},
+ {0.442863f, -0.238856f, 0.864188f},
+ {0.162460f, -0.262866f, 0.951056f},
+ {0.309017f, -0.500000f, 0.809017f},
+ {0.147621f, -0.716567f, 0.681718f},
+ {0.000000f, -0.525731f, 0.850651f},
+ {0.425325f, -0.688191f, 0.587785f},
+ {0.587785f, -0.425325f, 0.688191f},
+ {0.688191f, -0.587785f, 0.425325f},
+ {-0.955423f, 0.295242f, 0.000000f},
+ {-0.951056f, 0.162460f, 0.262866f},
+ {-1.000000f, 0.000000f, 0.000000f},
+ {-0.850651f, 0.000000f, 0.525731f},
+ {-0.955423f, -0.295242f, 0.000000f},
+ {-0.951056f, -0.162460f, 0.262866f},
+ {-0.864188f, 0.442863f, -0.238856f},
+ {-0.951056f, 0.162460f, -0.262866f},
+ {-0.809017f, 0.309017f, -0.500000f},
+ {-0.864188f, -0.442863f, -0.238856f},
+ {-0.951056f, -0.162460f, -0.262866f},
+ {-0.809017f, -0.309017f, -0.500000f},
+ {-0.681718f, 0.147621f, -0.716567f},
+ {-0.681718f, -0.147621f, -0.716567f},
+ {-0.850651f, 0.000000f, -0.525731f},
+ {-0.688191f, 0.587785f, -0.425325f},
+ {-0.587785f, 0.425325f, -0.688191f},
+ {-0.425325f, 0.688191f, -0.587785f},
+ {-0.425325f, -0.688191f, -0.587785f},
+ {-0.587785f, -0.425325f, -0.688191f},
+ {-0.688191f, -0.587785f, -0.425325f}
+ };
+
+ final float[][] VERTEXNORMAL_DOTS = {
+ {1.23f,1.30f,1.47f,1.35f,1.56f,1.71f,1.37f,1.38f,1.59f,1.60f,1.79f,1.97f,1.88f,1.92f,1.79f,1.02f,0.93f,1.07f,0.82f,0.87f,0.88f,0.94f,0.96f,1.14f,1.11f,0.82f,0.83f,0.89f,0.89f,0.86f,0.94f,0.91f,1.00f,1.21f,0.98f,1.48f,1.30f,1.57f,0.96f,1.07f,1.14f,1.60f,1.61f,1.40f,1.37f,1.72f,1.78f,1.79f,1.93f,1.99f,1.90f,1.68f,1.71f,1.86f,1.60f,1.68f,1.78f,1.86f,1.93f,1.99f,1.97f,1.44f,1.22f,1.49f,0.93f,0.99f,0.99f,1.23f,1.22f,1.44f,1.49f,0.89f,0.89f,0.97f,0.91f,0.98f,1.19f,0.82f,0.76f,0.82f,0.71f,0.72f,0.73f,0.76f,0.79f,0.86f,0.83f,0.72f,0.76f,0.76f,0.89f,0.82f,0.89f,0.82f,0.89f,0.91f,0.83f,0.96f,1.14f,0.97f,1.40f,1.19f,0.98f,0.94f,1.00f,1.07f,1.37f,1.21f,1.48f,1.30f,1.57f,1.61f,1.37f,0.86f,0.83f,0.91f,0.82f,0.82f,0.88f,0.89f,0.96f,1.14f,0.98f,0.87f,0.93f,0.94f,1.02f,1.30f,1.07f,1.35f,1.38f,1.11f,1.56f,1.92f,1.79f,1.79f,1.59f,1.60f,1.72f,1.90f,1.79f,0.80f,0.85f,0.79f,0.93f,0.80f,0.85f,0.77f,0.74f,0.72f,0.77f,0.74f,0.72f,0.70f,0.70f,0.71f,0.76f,0.73f,0.79f,0.79f,0.73f,0.76f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.26f,1.26f,1.48f,1.23f,1.50f,1.71f,1.14f,1.19f,1.38f,1.46f,1.64f,1.94f,1.87f,1.84f,1.71f,1.02f,0.92f,1.00f,0.79f,0.85f,0.84f,0.91f,0.90f,0.98f,0.99f,0.77f,0.77f,0.83f,0.82f,0.79f,0.86f,0.84f,0.92f,0.99f,0.91f,1.24f,1.03f,1.33f,0.88f,0.94f,0.97f,1.41f,1.39f,1.18f,1.11f,1.51f,1.61f,1.59f,1.80f,1.91f,1.76f,1.54f,1.65f,1.76f,1.70f,1.70f,1.85f,1.85f,1.97f,1.99f,1.93f,1.28f,1.09f,1.39f,0.92f,0.97f,0.99f,1.18f,1.26f,1.52f,1.48f,0.83f,0.85f,0.90f,0.88f,0.93f,1.00f,0.77f,0.73f,0.78f,0.72f,0.71f,0.74f,0.75f,0.79f,0.86f,0.81f,0.75f,0.81f,0.79f,0.96f,0.88f,0.94f,0.86f,0.93f,0.92f,0.85f,1.08f,1.33f,1.05f,1.55f,1.31f,1.01f,1.05f,1.27f,1.31f,1.60f,1.47f,1.70f,1.54f,1.76f,1.76f,1.57f,0.93f,0.90f,0.99f,0.88f,0.88f,0.95f,0.97f,1.11f,1.39f,1.20f,0.92f,0.97f,1.01f,1.10f,1.39f,1.22f,1.51f,1.58f,1.32f,1.64f,1.97f,1.85f,1.91f,1.77f,1.74f,1.88f,1.99f,1.91f,0.79f,0.86f,0.80f,0.94f,0.84f,0.88f,0.74f,0.74f,0.71f,0.82f,0.77f,0.76f,0.70f,0.73f,0.72f,0.73f,0.70f,0.74f,0.85f,0.77f,0.82f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.34f,1.27f,1.53f,1.17f,1.46f,1.71f,0.98f,1.05f,1.20f,1.34f,1.48f,1.86f,1.82f,1.71f,1.62f,1.09f,0.94f,0.99f,0.79f,0.85f,0.82f,0.90f,0.87f,0.93f,0.96f,0.76f,0.74f,0.79f,0.76f,0.74f,0.79f,0.78f,0.85f,0.92f,0.85f,1.00f,0.93f,1.06f,0.81f,0.86f,0.89f,1.16f,1.12f,0.97f,0.95f,1.28f,1.38f,1.35f,1.60f,1.77f,1.57f,1.33f,1.50f,1.58f,1.69f,1.63f,1.82f,1.74f,1.91f,1.92f,1.80f,1.04f,0.97f,1.21f,0.90f,0.93f,0.97f,1.05f,1.21f,1.48f,1.37f,0.77f,0.80f,0.84f,0.85f,0.88f,0.92f,0.73f,0.71f,0.74f,0.74f,0.71f,0.75f,0.73f,0.79f,0.84f,0.78f,0.79f,0.86f,0.81f,1.05f,0.94f,0.99f,0.90f,0.95f,0.92f,0.86f,1.24f,1.44f,1.14f,1.59f,1.34f,1.02f,1.27f,1.50f,1.49f,1.80f,1.69f,1.86f,1.72f,1.87f,1.80f,1.69f,1.00f,0.98f,1.23f,0.95f,0.96f,1.09f,1.16f,1.37f,1.63f,1.46f,0.99f,1.10f,1.25f,1.24f,1.51f,1.41f,1.67f,1.77f,1.55f,1.72f,1.95f,1.89f,1.98f,1.91f,1.86f,1.97f,1.99f,1.94f,0.81f,0.89f,0.85f,0.98f,0.90f,0.94f,0.75f,0.78f,0.73f,0.89f,0.83f,0.82f,0.72f,0.77f,0.76f,0.72f,0.70f,0.71f,0.91f,0.83f,0.89f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.46f,1.34f,1.60f,1.16f,1.46f,1.71f,0.94f,0.99f,1.05f,1.26f,1.33f,1.74f,1.76f,1.57f,1.54f,1.23f,0.98f,1.05f,0.83f,0.89f,0.84f,0.92f,0.87f,0.91f,0.96f,0.78f,0.74f,0.79f,0.72f,0.72f,0.75f,0.76f,0.80f,0.88f,0.83f,0.94f,0.87f,0.95f,0.76f,0.80f,0.82f,0.97f,0.96f,0.89f,0.88f,1.08f,1.11f,1.10f,1.37f,1.59f,1.37f,1.07f,1.27f,1.34f,1.57f,1.45f,1.69f,1.55f,1.77f,1.79f,1.60f,0.93f,0.90f,0.99f,0.86f,0.87f,0.93f,0.96f,1.07f,1.35f,1.18f,0.73f,0.76f,0.77f,0.81f,0.82f,0.85f,0.70f,0.71f,0.72f,0.78f,0.73f,0.77f,0.73f,0.79f,0.82f,0.76f,0.83f,0.90f,0.84f,1.18f,0.98f,1.03f,0.92f,0.95f,0.90f,0.86f,1.32f,1.45f,1.15f,1.53f,1.27f,0.99f,1.42f,1.65f,1.58f,1.93f,1.83f,1.94f,1.81f,1.88f,1.74f,1.70f,1.19f,1.17f,1.44f,1.11f,1.15f,1.36f,1.41f,1.61f,1.81f,1.67f,1.22f,1.34f,1.50f,1.42f,1.65f,1.61f,1.82f,1.91f,1.75f,1.80f,1.89f,1.89f,1.98f,1.99f,1.94f,1.98f,1.92f,1.87f,0.86f,0.95f,0.92f,1.14f,0.98f,1.03f,0.79f,0.84f,0.77f,0.97f,0.90f,0.89f,0.76f,0.82f,0.82f,0.74f,0.72f,0.71f,0.98f,0.89f,0.97f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.60f,1.44f,1.68f,1.22f,1.49f,1.71f,0.93f,0.99f,0.99f,1.23f,1.22f,1.60f,1.68f,1.44f,1.49f,1.40f,1.14f,1.19f,0.89f,0.96f,0.89f,0.97f,0.89f,0.91f,0.98f,0.82f,0.76f,0.82f,0.71f,0.72f,0.73f,0.76f,0.79f,0.86f,0.83f,0.91f,0.83f,0.89f,0.72f,0.76f,0.76f,0.89f,0.89f,0.82f,0.82f,0.98f,0.96f,0.97f,1.14f,1.40f,1.19f,0.94f,1.00f,1.07f,1.37f,1.21f,1.48f,1.30f,1.57f,1.61f,1.37f,0.86f,0.83f,0.91f,0.82f,0.82f,0.88f,0.89f,0.96f,1.14f,0.98f,0.70f,0.72f,0.73f,0.77f,0.76f,0.79f,0.70f,0.72f,0.71f,0.82f,0.77f,0.80f,0.74f,0.79f,0.80f,0.74f,0.87f,0.93f,0.85f,1.23f,1.02f,1.02f,0.93f,0.93f,0.87f,0.85f,1.30f,1.35f,1.07f,1.38f,1.11f,0.94f,1.47f,1.71f,1.56f,1.97f,1.88f,1.92f,1.79f,1.79f,1.59f,1.60f,1.30f,1.35f,1.56f,1.37f,1.38f,1.59f,1.60f,1.79f,1.92f,1.79f,1.48f,1.57f,1.72f,1.61f,1.78f,1.79f,1.93f,1.99f,1.90f,1.86f,1.78f,1.86f,1.93f,1.99f,1.97f,1.90f,1.79f,1.72f,0.94f,1.07f,1.00f,1.37f,1.21f,1.30f,0.86f,0.91f,0.83f,1.14f,0.98f,0.96f,0.82f,0.88f,0.89f,0.79f,0.76f,0.73f,1.07f,0.94f,1.11f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.74f,1.57f,1.76f,1.33f,1.54f,1.71f,0.94f,1.05f,0.99f,1.26f,1.16f,1.46f,1.60f,1.34f,1.46f,1.59f,1.37f,1.37f,0.97f,1.11f,0.96f,1.10f,0.95f,0.94f,1.08f,0.89f,0.82f,0.88f,0.72f,0.76f,0.75f,0.80f,0.80f,0.88f,0.87f,0.91f,0.83f,0.87f,0.72f,0.76f,0.74f,0.83f,0.84f,0.78f,0.79f,0.96f,0.89f,0.92f,0.98f,1.23f,1.05f,0.86f,0.92f,0.95f,1.11f,0.98f,1.22f,1.03f,1.34f,1.42f,1.14f,0.79f,0.77f,0.84f,0.78f,0.76f,0.82f,0.82f,0.89f,0.97f,0.90f,0.70f,0.71f,0.71f,0.73f,0.72f,0.74f,0.73f,0.76f,0.72f,0.86f,0.81f,0.82f,0.76f,0.79f,0.77f,0.73f,0.90f,0.95f,0.86f,1.18f,1.03f,0.98f,0.92f,0.90f,0.83f,0.84f,1.19f,1.17f,0.98f,1.15f,0.97f,0.89f,1.42f,1.65f,1.44f,1.93f,1.83f,1.81f,1.67f,1.61f,1.36f,1.41f,1.32f,1.45f,1.58f,1.57f,1.53f,1.74f,1.70f,1.88f,1.94f,1.81f,1.69f,1.77f,1.87f,1.79f,1.89f,1.92f,1.98f,1.99f,1.98f,1.89f,1.65f,1.80f,1.82f,1.91f,1.94f,1.75f,1.61f,1.50f,1.07f,1.34f,1.27f,1.60f,1.45f,1.55f,0.93f,0.99f,0.90f,1.35f,1.18f,1.07f,0.87f,0.93f,0.96f,0.85f,0.82f,0.77f,1.15f,0.99f,1.27f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.86f,1.71f,1.82f,1.48f,1.62f,1.71f,0.98f,1.20f,1.05f,1.34f,1.17f,1.34f,1.53f,1.27f,1.46f,1.77f,1.60f,1.57f,1.16f,1.38f,1.12f,1.35f,1.06f,1.00f,1.28f,0.97f,0.89f,0.95f,0.76f,0.81f,0.79f,0.86f,0.85f,0.92f,0.93f,0.93f,0.85f,0.87f,0.74f,0.78f,0.74f,0.79f,0.82f,0.76f,0.79f,0.96f,0.85f,0.90f,0.94f,1.09f,0.99f,0.81f,0.85f,0.89f,0.95f,0.90f,0.99f,0.94f,1.10f,1.24f,0.98f,0.75f,0.73f,0.78f,0.74f,0.72f,0.77f,0.76f,0.82f,0.89f,0.83f,0.73f,0.71f,0.71f,0.71f,0.70f,0.72f,0.77f,0.80f,0.74f,0.90f,0.85f,0.84f,0.78f,0.79f,0.75f,0.73f,0.92f,0.95f,0.86f,1.05f,0.99f,0.94f,0.90f,0.86f,0.79f,0.81f,1.00f,0.98f,0.91f,0.96f,0.89f,0.83f,1.27f,1.50f,1.23f,1.80f,1.69f,1.63f,1.46f,1.37f,1.09f,1.16f,1.24f,1.44f,1.49f,1.69f,1.59f,1.80f,1.69f,1.87f,1.86f,1.72f,1.82f,1.91f,1.94f,1.92f,1.95f,1.99f,1.98f,1.91f,1.97f,1.89f,1.51f,1.72f,1.67f,1.77f,1.86f,1.55f,1.41f,1.25f,1.33f,1.58f,1.50f,1.80f,1.63f,1.74f,1.04f,1.21f,0.97f,1.48f,1.37f,1.21f,0.93f,0.97f,1.05f,0.92f,0.88f,0.84f,1.14f,1.02f,1.34f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.94f,1.84f,1.87f,1.64f,1.71f,1.71f,1.14f,1.38f,1.19f,1.46f,1.23f,1.26f,1.48f,1.26f,1.50f,1.91f,1.80f,1.76f,1.41f,1.61f,1.39f,1.59f,1.33f,1.24f,1.51f,1.18f,0.97f,1.11f,0.82f,0.88f,0.86f,0.94f,0.92f,0.99f,1.03f,0.98f,0.91f,0.90f,0.79f,0.84f,0.77f,0.79f,0.84f,0.77f,0.83f,0.99f,0.85f,0.91f,0.92f,1.02f,1.00f,0.79f,0.80f,0.86f,0.88f,0.84f,0.92f,0.88f,0.97f,1.10f,0.94f,0.74f,0.71f,0.74f,0.72f,0.70f,0.73f,0.72f,0.76f,0.82f,0.77f,0.77f,0.73f,0.74f,0.71f,0.70f,0.73f,0.83f,0.85f,0.78f,0.92f,0.88f,0.86f,0.81f,0.79f,0.74f,0.75f,0.92f,0.93f,0.85f,0.96f,0.94f,0.88f,0.86f,0.81f,0.75f,0.79f,0.93f,0.90f,0.85f,0.88f,0.82f,0.77f,1.05f,1.27f,0.99f,1.60f,1.47f,1.39f,1.20f,1.11f,0.95f,0.97f,1.08f,1.33f,1.31f,1.70f,1.55f,1.76f,1.57f,1.76f,1.70f,1.54f,1.85f,1.97f,1.91f,1.99f,1.97f,1.99f,1.91f,1.77f,1.88f,1.85f,1.39f,1.64f,1.51f,1.58f,1.74f,1.32f,1.22f,1.01f,1.54f,1.76f,1.65f,1.93f,1.70f,1.85f,1.28f,1.39f,1.09f,1.52f,1.48f,1.26f,0.97f,0.99f,1.18f,1.00f,0.93f,0.90f,1.05f,1.01f,1.31f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.97f,1.92f,1.88f,1.79f,1.79f,1.71f,1.37f,1.59f,1.38f,1.60f,1.35f,1.23f,1.47f,1.30f,1.56f,1.99f,1.93f,1.90f,1.60f,1.78f,1.61f,1.79f,1.57f,1.48f,1.72f,1.40f,1.14f,1.37f,0.89f,0.96f,0.94f,1.07f,1.00f,1.21f,1.30f,1.14f,0.98f,0.96f,0.86f,0.91f,0.83f,0.82f,0.88f,0.82f,0.89f,1.11f,0.87f,0.94f,0.93f,1.02f,1.07f,0.80f,0.79f,0.85f,0.82f,0.80f,0.87f,0.85f,0.93f,1.02f,0.93f,0.77f,0.72f,0.74f,0.71f,0.70f,0.70f,0.71f,0.72f,0.77f,0.74f,0.82f,0.76f,0.79f,0.72f,0.73f,0.76f,0.89f,0.89f,0.82f,0.93f,0.91f,0.86f,0.83f,0.79f,0.73f,0.76f,0.91f,0.89f,0.83f,0.89f,0.89f,0.82f,0.82f,0.76f,0.72f,0.76f,0.86f,0.83f,0.79f,0.82f,0.76f,0.73f,0.94f,1.00f,0.91f,1.37f,1.21f,1.14f,0.98f,0.96f,0.88f,0.89f,0.96f,1.14f,1.07f,1.60f,1.40f,1.61f,1.37f,1.57f,1.48f,1.30f,1.78f,1.93f,1.79f,1.99f,1.92f,1.90f,1.79f,1.59f,1.72f,1.79f,1.30f,1.56f,1.35f,1.38f,1.60f,1.11f,1.07f,0.94f,1.68f,1.86f,1.71f,1.97f,1.68f,1.86f,1.44f,1.49f,1.22f,1.44f,1.49f,1.22f,0.99f,0.99f,1.23f,1.19f,0.98f,0.97f,0.97f,0.98f,1.19f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.94f,1.97f,1.87f,1.91f,1.85f,1.71f,1.60f,1.77f,1.58f,1.74f,1.51f,1.26f,1.48f,1.39f,1.64f,1.99f,1.97f,1.99f,1.70f,1.85f,1.76f,1.91f,1.76f,1.70f,1.88f,1.55f,1.33f,1.57f,0.96f,1.08f,1.05f,1.31f,1.27f,1.47f,1.54f,1.39f,1.20f,1.11f,0.93f,0.99f,0.90f,0.88f,0.95f,0.88f,0.97f,1.32f,0.92f,1.01f,0.97f,1.10f,1.22f,0.84f,0.80f,0.88f,0.79f,0.79f,0.85f,0.86f,0.92f,1.02f,0.94f,0.82f,0.76f,0.77f,0.72f,0.73f,0.70f,0.72f,0.71f,0.74f,0.74f,0.88f,0.81f,0.85f,0.75f,0.77f,0.82f,0.94f,0.93f,0.86f,0.92f,0.92f,0.86f,0.85f,0.79f,0.74f,0.79f,0.88f,0.85f,0.81f,0.82f,0.83f,0.77f,0.78f,0.73f,0.71f,0.75f,0.79f,0.77f,0.74f,0.77f,0.73f,0.70f,0.86f,0.92f,0.84f,1.14f,0.99f,0.98f,0.91f,0.90f,0.84f,0.83f,0.88f,0.97f,0.94f,1.41f,1.18f,1.39f,1.11f,1.33f,1.24f,1.03f,1.61f,1.80f,1.59f,1.91f,1.84f,1.76f,1.64f,1.38f,1.51f,1.71f,1.26f,1.50f,1.23f,1.19f,1.46f,0.99f,1.00f,0.91f,1.70f,1.85f,1.65f,1.93f,1.54f,1.76f,1.52f,1.48f,1.26f,1.28f,1.39f,1.09f,0.99f,0.97f,1.18f,1.31f,1.01f,1.05f,0.90f,0.93f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.86f,1.95f,1.82f,1.98f,1.89f,1.71f,1.80f,1.91f,1.77f,1.86f,1.67f,1.34f,1.53f,1.51f,1.72f,1.92f,1.91f,1.99f,1.69f,1.82f,1.80f,1.94f,1.87f,1.86f,1.97f,1.59f,1.44f,1.69f,1.05f,1.24f,1.27f,1.49f,1.50f,1.69f,1.72f,1.63f,1.46f,1.37f,1.00f,1.23f,0.98f,0.95f,1.09f,0.96f,1.16f,1.55f,0.99f,1.25f,1.10f,1.24f,1.41f,0.90f,0.85f,0.94f,0.79f,0.81f,0.85f,0.89f,0.94f,1.09f,0.98f,0.89f,0.82f,0.83f,0.74f,0.77f,0.72f,0.76f,0.73f,0.75f,0.78f,0.94f,0.86f,0.91f,0.79f,0.83f,0.89f,0.99f,0.95f,0.90f,0.90f,0.92f,0.84f,0.86f,0.79f,0.75f,0.81f,0.85f,0.80f,0.78f,0.76f,0.77f,0.73f,0.74f,0.71f,0.71f,0.73f,0.74f,0.74f,0.71f,0.76f,0.72f,0.70f,0.79f,0.85f,0.78f,0.98f,0.92f,0.93f,0.85f,0.87f,0.82f,0.79f,0.81f,0.89f,0.86f,1.16f,0.97f,1.12f,0.95f,1.06f,1.00f,0.93f,1.38f,1.60f,1.35f,1.77f,1.71f,1.57f,1.48f,1.20f,1.28f,1.62f,1.27f,1.46f,1.17f,1.05f,1.34f,0.96f,0.99f,0.90f,1.63f,1.74f,1.50f,1.80f,1.33f,1.58f,1.48f,1.37f,1.21f,1.04f,1.21f,0.97f,0.97f,0.93f,1.05f,1.34f,1.02f,1.14f,0.84f,0.88f,0.92f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.74f,1.89f,1.76f,1.98f,1.89f,1.71f,1.93f,1.99f,1.91f,1.94f,1.82f,1.46f,1.60f,1.65f,1.80f,1.79f,1.77f,1.92f,1.57f,1.69f,1.74f,1.87f,1.88f,1.94f,1.98f,1.53f,1.45f,1.70f,1.18f,1.32f,1.42f,1.58f,1.65f,1.83f,1.81f,1.81f,1.67f,1.61f,1.19f,1.44f,1.17f,1.11f,1.36f,1.15f,1.41f,1.75f,1.22f,1.50f,1.34f,1.42f,1.61f,0.98f,0.92f,1.03f,0.83f,0.86f,0.89f,0.95f,0.98f,1.23f,1.14f,0.97f,0.89f,0.90f,0.78f,0.82f,0.76f,0.82f,0.77f,0.79f,0.84f,0.98f,0.90f,0.98f,0.83f,0.89f,0.97f,1.03f,0.95f,0.92f,0.86f,0.90f,0.82f,0.86f,0.79f,0.77f,0.84f,0.81f,0.76f,0.76f,0.72f,0.73f,0.70f,0.72f,0.71f,0.73f,0.73f,0.72f,0.74f,0.71f,0.78f,0.74f,0.72f,0.75f,0.80f,0.76f,0.94f,0.88f,0.91f,0.83f,0.87f,0.84f,0.79f,0.76f,0.82f,0.80f,0.97f,0.89f,0.96f,0.88f,0.95f,0.94f,0.87f,1.11f,1.37f,1.10f,1.59f,1.57f,1.37f,1.33f,1.05f,1.08f,1.54f,1.34f,1.46f,1.16f,0.99f,1.26f,0.96f,1.05f,0.92f,1.45f,1.55f,1.27f,1.60f,1.07f,1.34f,1.35f,1.18f,1.07f,0.93f,0.99f,0.90f,0.93f,0.87f,0.96f,1.27f,0.99f,1.15f,0.77f,0.82f,0.85f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.60f,1.78f,1.68f,1.93f,1.86f,1.71f,1.97f,1.99f,1.99f,1.97f,1.93f,1.60f,1.68f,1.78f,1.86f,1.61f,1.57f,1.79f,1.37f,1.48f,1.59f,1.72f,1.79f,1.92f,1.90f,1.38f,1.35f,1.60f,1.23f,1.30f,1.47f,1.56f,1.71f,1.88f,1.79f,1.92f,1.79f,1.79f,1.30f,1.56f,1.35f,1.37f,1.59f,1.38f,1.60f,1.90f,1.48f,1.72f,1.57f,1.61f,1.79f,1.21f,1.00f,1.30f,0.89f,0.94f,0.96f,1.07f,1.14f,1.40f,1.37f,1.14f,0.96f,0.98f,0.82f,0.88f,0.82f,0.89f,0.83f,0.86f,0.91f,1.02f,0.93f,1.07f,0.87f,0.94f,1.11f,1.02f,0.93f,0.93f,0.82f,0.87f,0.80f,0.85f,0.79f,0.80f,0.85f,0.77f,0.72f,0.74f,0.71f,0.70f,0.70f,0.71f,0.72f,0.77f,0.74f,0.72f,0.76f,0.73f,0.82f,0.79f,0.76f,0.73f,0.79f,0.76f,0.93f,0.86f,0.91f,0.83f,0.89f,0.89f,0.82f,0.72f,0.76f,0.76f,0.89f,0.82f,0.89f,0.82f,0.89f,0.91f,0.83f,0.96f,1.14f,0.97f,1.40f,1.44f,1.19f,1.22f,0.99f,0.98f,1.49f,1.44f,1.49f,1.22f,0.99f,1.23f,0.98f,1.19f,0.97f,1.21f,1.30f,1.00f,1.37f,0.94f,1.07f,1.14f,0.98f,0.96f,0.86f,0.91f,0.83f,0.88f,0.82f,0.89f,1.11f,0.94f,1.07f,0.73f,0.76f,0.79f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.46f,1.65f,1.60f,1.82f,1.80f,1.71f,1.93f,1.91f,1.99f,1.94f,1.98f,1.74f,1.76f,1.89f,1.89f,1.42f,1.34f,1.61f,1.11f,1.22f,1.36f,1.50f,1.61f,1.81f,1.75f,1.15f,1.17f,1.41f,1.18f,1.19f,1.42f,1.44f,1.65f,1.83f,1.67f,1.94f,1.81f,1.88f,1.32f,1.58f,1.45f,1.57f,1.74f,1.53f,1.70f,1.98f,1.69f,1.87f,1.77f,1.79f,1.92f,1.45f,1.27f,1.55f,0.97f,1.07f,1.11f,1.34f,1.37f,1.59f,1.60f,1.35f,1.07f,1.18f,0.86f,0.93f,0.87f,0.96f,0.90f,0.93f,0.99f,1.03f,0.95f,1.15f,0.90f,0.99f,1.27f,0.98f,0.90f,0.92f,0.78f,0.83f,0.77f,0.84f,0.79f,0.82f,0.86f,0.73f,0.71f,0.73f,0.72f,0.70f,0.73f,0.72f,0.76f,0.81f,0.76f,0.76f,0.82f,0.77f,0.89f,0.85f,0.82f,0.75f,0.80f,0.80f,0.94f,0.88f,0.94f,0.87f,0.95f,0.96f,0.88f,0.72f,0.74f,0.76f,0.83f,0.78f,0.84f,0.79f,0.87f,0.91f,0.83f,0.89f,0.98f,0.92f,1.23f,1.34f,1.05f,1.16f,0.99f,0.96f,1.46f,1.57f,1.54f,1.33f,1.05f,1.26f,1.08f,1.37f,1.10f,0.98f,1.03f,0.92f,1.14f,0.86f,0.95f,0.97f,0.90f,0.89f,0.79f,0.84f,0.77f,0.82f,0.76f,0.82f,0.97f,0.89f,0.98f,0.71f,0.72f,0.74f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.34f,1.51f,1.53f,1.67f,1.72f,1.71f,1.80f,1.77f,1.91f,1.86f,1.98f,1.86f,1.82f,1.95f,1.89f,1.24f,1.10f,1.41f,0.95f,0.99f,1.09f,1.25f,1.37f,1.63f,1.55f,0.96f,0.98f,1.16f,1.05f,1.00f,1.27f,1.23f,1.50f,1.69f,1.46f,1.86f,1.72f,1.87f,1.24f,1.49f,1.44f,1.69f,1.80f,1.59f,1.69f,1.97f,1.82f,1.94f,1.91f,1.92f,1.99f,1.63f,1.50f,1.74f,1.16f,1.33f,1.38f,1.58f,1.60f,1.77f,1.80f,1.48f,1.21f,1.37f,0.90f,0.97f,0.93f,1.05f,0.97f,1.04f,1.21f,0.99f,0.95f,1.14f,0.92f,1.02f,1.34f,0.94f,0.86f,0.90f,0.74f,0.79f,0.75f,0.81f,0.79f,0.84f,0.86f,0.71f,0.71f,0.73f,0.76f,0.73f,0.77f,0.74f,0.80f,0.85f,0.78f,0.81f,0.89f,0.84f,0.97f,0.92f,0.88f,0.79f,0.85f,0.86f,0.98f,0.92f,1.00f,0.93f,1.06f,1.12f,0.95f,0.74f,0.74f,0.78f,0.79f,0.76f,0.82f,0.79f,0.87f,0.93f,0.85f,0.85f,0.94f,0.90f,1.09f,1.27f,0.99f,1.17f,1.05f,0.96f,1.46f,1.71f,1.62f,1.48f,1.20f,1.34f,1.28f,1.57f,1.35f,0.90f,0.94f,0.85f,0.98f,0.81f,0.89f,0.89f,0.83f,0.82f,0.75f,0.78f,0.73f,0.77f,0.72f,0.76f,0.89f,0.83f,0.91f,0.71f,0.70f,0.72f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f},
+ {1.26f,1.39f,1.48f,1.51f,1.64f,1.71f,1.60f,1.58f,1.77f,1.74f,1.91f,1.94f,1.87f,1.97f,1.85f,1.10f,0.97f,1.22f,0.88f,0.92f,0.95f,1.01f,1.11f,1.39f,1.32f,0.88f,0.90f,0.97f,0.96f,0.93f,1.05f,0.99f,1.27f,1.47f,1.20f,1.70f,1.54f,1.76f,1.08f,1.31f,1.33f,1.70f,1.76f,1.55f,1.57f,1.88f,1.85f,1.91f,1.97f,1.99f,1.99f,1.70f,1.65f,1.85f,1.41f,1.54f,1.61f,1.76f,1.80f,1.91f,1.93f,1.52f,1.26f,1.48f,0.92f,0.99f,0.97f,1.18f,1.09f,1.28f,1.39f,0.94f,0.93f,1.05f,0.92f,1.01f,1.31f,0.88f,0.81f,0.86f,0.72f,0.75f,0.74f,0.79f,0.79f,0.86f,0.85f,0.71f,0.73f,0.75f,0.82f,0.77f,0.83f,0.78f,0.85f,0.88f,0.81f,0.88f,0.97f,0.90f,1.18f,1.00f,0.93f,0.86f,0.92f,0.94f,1.14f,0.99f,1.24f,1.03f,1.33f,1.39f,1.11f,0.79f,0.77f,0.84f,0.79f,0.77f,0.84f,0.83f,0.90f,0.98f,0.91f,0.85f,0.92f,0.91f,1.02f,1.26f,1.00f,1.23f,1.19f,0.99f,1.50f,1.84f,1.71f,1.64f,1.38f,1.46f,1.51f,1.76f,1.59f,0.84f,0.88f,0.80f,0.94f,0.79f,0.86f,0.82f,0.77f,0.76f,0.74f,0.74f,0.71f,0.73f,0.70f,0.72f,0.82f,0.77f,0.85f,0.74f,0.70f,0.73f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f,1.00f}
+ };
+
+}
diff --git a/src/jake2/render/fastjogl/Base.java b/src/jake2/render/fastjogl/Base.java
new file mode 100644
index 0000000..c5cc690
--- /dev/null
+++ b/src/jake2/render/fastjogl/Base.java
@@ -0,0 +1,300 @@
+/*
+ * Base.java
+ * Copyright (C) 2003
+ *
+ * $Id: Base.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import net.java.games.jogl.GL;
+
+/**
+ * Base
+ *
+ * @author cwei
+ */
+public class Base {
+
+ static final int GL_COLOR_INDEX8_EXT = GL.GL_COLOR_INDEX;
+ static final String REF_VERSION = "GL 0.01";
+
+ // up / down
+ static final int PITCH = 0;
+ // left / right
+ static final int YAW = 1;
+ // fall over
+ static final int ROLL = 2;
+
+ /*
+ skins will be outline flood filled and mip mapped
+ pics and sprites with alpha will be outline flood filled
+ pic won't be mip mapped
+
+ model skin
+ sprite frame
+ wall texture
+ pic
+ */
+ // enum imagetype_t
+ static final int it_skin = 0;
+ static final int it_sprite = 1;
+ static final int it_wall = 2;
+ static final int it_pic = 3;
+ static final int it_sky = 4;
+
+ // enum modtype_t
+ static final int mod_bad = 0;
+ static final int mod_brush = 1;
+ static final int mod_sprite = 2;
+ static final int mod_alias = 3;
+
+ static final int TEXNUM_LIGHTMAPS = 1024;
+ static final int TEXNUM_SCRAPS = 1152;
+ static final int TEXNUM_IMAGES = 1153;
+
+ static final int MAX_GLTEXTURES = 1024;
+
+// ===================================================================
+
+ // enum rserr_t
+ static final int rserr_ok = 0;
+ static final int rserr_invalid_fullscreen = 1;
+ static final int rserr_invalid_mode = 2;
+ static final int rserr_unknown = 3;
+
+//
+// #include "gl_model.h"
+//
+// void GL_BeginRendering (int *x, int *y, int *width, int *height);
+// void GL_EndRendering (void);
+//
+// void GL_SetDefaultState( void );
+// void GL_UpdateSwapInterval( void );
+
+ static class glvert_t {
+ float x, y, z;
+ float s, t;
+ float r, g, b;
+ }
+
+ static final int MAX_LBM_HEIGHT = 480;
+
+ static final float BACKFACE_EPSILON = 0.01f;
+
+// ====================================================
+//
+// void R_TranslatePlayerSkin (int playernum);
+// void GL_Bind (int texnum);
+// void GL_MBind( GLenum target, int texnum );
+// void GL_TexEnv( GLenum value );
+// void GL_EnableMultitexture( qboolean enable );
+// void GL_SelectTexture( GLenum );
+//
+// void R_LightPoint (vec3_t p, vec3_t color);
+// void R_PushDlights (void);
+//
+
+// ====================================================================
+//
+// extern int registration_sequence;
+//
+//
+// void V_AddBlend (float r, float g, float b, float a, float *v_blend);
+//
+// int R_Init( void *hinstance, void *hWnd );
+// void R_Shutdown( void );
+//
+// void R_RenderView (refdef_t *fd);
+// void GL_ScreenShot_f (void);
+// void R_DrawAliasModel (entity_t *e);
+// void R_DrawBrushModel (entity_t *e);
+// void R_DrawSpriteModel (entity_t *e);
+// void R_DrawBeam( entity_t *e );
+// void R_DrawWorld (void);
+// void R_RenderDlights (void);
+// void R_DrawAlphaSurfaces (void);
+// void R_RenderBrushPoly (msurface_t *fa);
+// void R_InitParticleTexture (void);
+// void Draw_InitLocal (void);
+// void GL_SubdivideSurface (msurface_t *fa);
+// qboolean R_CullBox (vec3_t mins, vec3_t maxs);
+// void R_RotateForEntity (entity_t *e);
+// void R_MarkLeaves (void);
+//
+// glpoly_t *WaterWarpPolyVerts (glpoly_t *p);
+// void EmitWaterPolys (msurface_t *fa);
+// void R_AddSkySurface (msurface_t *fa);
+// void R_ClearSkyBox (void);
+// void R_DrawSkyBox (void);
+// void R_MarkLights (dlight_t *light, int bit, mnode_t *node);
+//
+//
+// void COM_StripExtension (char *in, char *out);
+//
+// void Draw_GetPicSize (int *w, int *h, char *name);
+// void Draw_Pic (int x, int y, char *name);
+// void Draw_StretchPic (int x, int y, int w, int h, char *name);
+// void Draw_Char (int x, int y, int c);
+// void Draw_TileClear (int x, int y, int w, int h, char *name);
+// void Draw_Fill (int x, int y, int w, int h, int c);
+// void Draw_FadeScreen (void);
+// void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data);
+//
+// void R_BeginFrame( float camera_separation );
+// void R_SwapBuffers( int );
+// void R_SetPalette ( const unsigned char *palette);
+//
+// int Draw_GetPalette (void);
+//
+// void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight);
+//
+// struct image_s *R_RegisterSkin (char *name);
+//
+// void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height);
+// image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type, int bits);
+// image_t *GL_FindImage (char *name, imagetype_t type);
+// void GL_TextureMode( char *string );
+// void GL_ImageList_f (void);
+//
+// void GL_SetTexturePalette( unsigned palette[256] );
+//
+// void GL_InitImages (void);
+// void GL_ShutdownImages (void);
+//
+// void GL_FreeUnusedImages (void);
+//
+// void GL_TextureAlphaMode( char *string );
+// void GL_TextureSolidMode( char *string );
+//
+// /*
+// ** GL extension emulation functions
+// */
+// void GL_DrawParticles( int n, const particle_t particles[], const unsigned colortable[768] );
+//
+
+ /*
+ ** GL config stuff
+ */
+ static final int GL_RENDERER_VOODOO = 0x00000001;
+ static final int GL_RENDERER_VOODOO2 = 0x00000002;
+ static final int GL_RENDERER_VOODOO_RUSH = 0x00000004;
+ static final int GL_RENDERER_BANSHEE = 0x00000008;
+ static final int GL_RENDERER_3DFX = 0x0000000F;
+
+ static final int GL_RENDERER_PCX1 = 0x00000010;
+ static final int GL_RENDERER_PCX2 = 0x00000020;
+ static final int GL_RENDERER_PMX = 0x00000040;
+ static final int GL_RENDERER_POWERVR = 0x00000070;
+
+ static final int GL_RENDERER_PERMEDIA2 = 0x00000100;
+ static final int GL_RENDERER_GLINT_MX = 0x00000200;
+ static final int GL_RENDERER_GLINT_TX = 0x00000400;
+ static final int GL_RENDERER_3DLABS_MISC = 0x00000800;
+ static final int GL_RENDERER_3DLABS = 0x00000F00;
+
+ static final int GL_RENDERER_REALIZM = 0x00001000;
+ static final int GL_RENDERER_REALIZM2 = 0x00002000;
+ static final int GL_RENDERER_INTERGRAPH = 0x00003000;
+
+ static final int GL_RENDERER_3DPRO = 0x00004000;
+ static final int GL_RENDERER_REAL3D = 0x00008000;
+ static final int GL_RENDERER_RIVA128 = 0x00010000;
+ static final int GL_RENDERER_DYPIC = 0x00020000;
+
+ static final int GL_RENDERER_V1000 = 0x00040000;
+ static final int GL_RENDERER_V2100 = 0x00080000;
+ static final int GL_RENDERER_V2200 = 0x00100000;
+ static final int GL_RENDERER_RENDITION = 0x001C0000;
+
+ static final int GL_RENDERER_O2 = 0x00100000;
+ static final int GL_RENDERER_IMPACT = 0x00200000;
+ static final int GL_RENDERER_RE = 0x00400000;
+ static final int GL_RENDERER_IR = 0x00800000;
+ static final int GL_RENDERER_SGI = 0x00F00000;
+
+ static final int GL_RENDERER_MCD = 0x01000000;
+ static final int GL_RENDERER_OTHER = 0x80000000;
+
+
+// typedef struct
+// {
+// int renderer;
+// const char *renderer_string;
+// const char *vendor_string;
+// const char *version_string;
+// const char *extensions_string;
+//
+// qboolean allow_cds;
+// } glconfig_t;
+//
+// typedef struct
+// {
+// float inverse_intensity;
+// qboolean fullscreen;
+//
+// int prev_mode;
+//
+// unsigned char *d_16to8table;
+//
+// int lightmap_textures;
+//
+// int currenttextures[2];
+// int currenttmu;
+//
+// float camera_separation;
+// qboolean stereo_enabled;
+//
+// unsigned char originalRedGammaTable[256];
+// unsigned char originalGreenGammaTable[256];
+// unsigned char originalBlueGammaTable[256];
+// } glstate_t;
+//
+// /*
+// ====================================================================
+//
+// IMPORTED FUNCTIONS
+//
+// ====================================================================
+// */
+//
+// extern refimport_t ri;
+//
+//
+// /*
+// ====================================================================
+//
+// IMPLEMENTATION SPECIFIC FUNCTIONS
+//
+// ====================================================================
+// */
+//
+// void GLimp_BeginFrame( float camera_separation );
+// void GLimp_EndFrame( void );
+// int GLimp_Init( void *hinstance, void *hWnd );
+// void GLimp_Shutdown( void );
+// int GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen );
+// void GLimp_AppActivate( qboolean active );
+// void GLimp_EnableLogging( qboolean enable );
+// void GLimp_LogNewFrame( void );
+//
+
+}
diff --git a/src/jake2/render/fastjogl/Draw.java b/src/jake2/render/fastjogl/Draw.java
new file mode 100644
index 0000000..fcb48b6
--- /dev/null
+++ b/src/jake2/render/fastjogl/Draw.java
@@ -0,0 +1,406 @@
+/*
+ * Draw.java
+ * Copyright (C) 2003
+ *
+ * $Id: Draw.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+ /*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.Defines;
+import jake2.Globals;
+import jake2.render.image_t;
+
+import java.awt.Dimension;
+
+import net.java.games.jogl.GL;
+import net.java.games.jogl.util.GLUT;
+
+/**
+ * Draw
+ * (gl_draw.c)
+ *
+ * @author cwei
+ */
+public abstract class Draw extends Image {
+
+ /*
+ ===============
+ Draw_InitLocal
+ ===============
+ */
+ void Draw_InitLocal() {
+ // load console characters (don't bilerp characters)
+ draw_chars = GL_FindImage("pics/conchars.pcx", it_pic);
+ GL_Bind(draw_chars.texnum);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ }
+
+ /*
+ ================
+ Draw_Char
+
+ Draws one 8*8 graphics character with 0 being transparent.
+ It can be clipped to the top of the screen to allow the console to be
+ smoothly scrolled off.
+ ================
+ */
+ protected void Draw_Char(int x, int y, int num) {
+
+ num &= 255;
+
+ if ( (num&127) == 32 ) return; // space
+
+ if (y <= -8) return; // totally off screen
+
+ int row = num>>4;
+ int col = num&15;
+
+ float frow = row*0.0625f;
+ float fcol = col*0.0625f;
+ float size = 0.0625f;
+
+ GL_Bind(draw_chars.texnum);
+
+ gl.glBegin (GL.GL_QUADS);
+ gl.glTexCoord2f (fcol, frow);
+ gl.glVertex2f (x, y);
+ gl.glTexCoord2f (fcol + size, frow);
+ gl.glVertex2f (x+8, y);
+ gl.glTexCoord2f (fcol + size, frow + size);
+ gl.glVertex2f (x+8, y+8);
+ gl.glTexCoord2f (fcol, frow + size);
+ gl.glVertex2f (x, y+8);
+ gl.glEnd ();
+ }
+
+
+ /*
+ =============
+ Draw_FindPic
+ =============
+ */
+ protected image_t Draw_FindPic(String name) {
+ image_t image = null;
+ String fullname;
+
+ if (!name.startsWith("/") && !name.startsWith("\\"))
+ {
+ fullname = "pics/" + name + ".pcx";
+ image = GL_FindImage(fullname, it_pic);
+ } else {
+ image = GL_FindImage(name.substring(1), it_pic);
+ }
+ return image;
+ }
+
+
+ /*
+ =============
+ Draw_GetPicSize
+ =============
+ */
+ protected void Draw_GetPicSize(Dimension dim, String pic) {
+
+ image_t image = Draw_FindPic(pic);
+ dim.width = (image != null) ? image.width : -1;
+ dim.height = (image != null) ? image.height : -1;
+ }
+
+ /*
+ =============
+ Draw_StretchPic
+ =============
+ */
+ protected void Draw_StretchPic (int x, int y, int w, int h, String pic) {
+
+ image_t image;
+
+ image = Draw_FindPic(pic);
+ if (image == null)
+ {
+ ri.Con_Printf (Defines.PRINT_ALL, "Can't find pic: " + pic +'\n');
+ return;
+ }
+
+ if (scrap_dirty)
+ Scrap_Upload();
+
+ if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0) ) && !image.has_alpha)
+ gl.glDisable(GL.GL_ALPHA_TEST);
+
+ GL_Bind(image.texnum);
+ gl.glBegin (GL.GL_QUADS);
+ gl.glTexCoord2f (image.sl, image.tl);
+ gl.glVertex2f (x, y);
+ gl.glTexCoord2f (image.sh, image.tl);
+ gl.glVertex2f (x+w, y);
+ gl.glTexCoord2f (image.sh, image.th);
+ gl.glVertex2f (x+w, y+h);
+ gl.glTexCoord2f (image.sl, image.th);
+ gl.glVertex2f (x, y+h);
+ gl.glEnd ();
+
+ if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) !=0 ) ) && !image.has_alpha)
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ }
+
+
+ /*
+ =============
+ Draw_Pic
+ =============
+ */
+ protected void Draw_Pic(int x, int y, String pic)
+ {
+ image_t image;
+
+ image = Draw_FindPic(pic);
+ if (image == null)
+ {
+ ri.Con_Printf(Defines.PRINT_ALL, "Can't find pic: " +pic + '\n');
+ return;
+ }
+ if (scrap_dirty)
+ Scrap_Upload();
+
+ if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0 ) ) && !image.has_alpha)
+ gl.glDisable (GL.GL_ALPHA_TEST);
+
+ GL_Bind(image.texnum);
+
+ gl.glBegin (GL.GL_QUADS);
+ gl.glTexCoord2f (image.sl, image.tl);
+ gl.glVertex2f (x, y);
+ gl.glTexCoord2f (image.sh, image.tl);
+ gl.glVertex2f (x+image.width, y);
+ gl.glTexCoord2f (image.sh, image.th);
+ gl.glVertex2f (x+image.width, y+image.height);
+ gl.glTexCoord2f (image.sl, image.th);
+ gl.glVertex2f (x, y+image.height);
+ gl.glEnd ();
+
+ if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0 ) ) && !image.has_alpha)
+ gl.glEnable (GL.GL_ALPHA_TEST);
+ }
+
+ /*
+ =============
+ Draw_TileClear
+
+ This repeats a 64*64 tile graphic to fill the screen around a sized down
+ refresh window.
+ =============
+ */
+ protected void Draw_TileClear(int x, int y, int w, int h, String pic) {
+ image_t image;
+
+ image = Draw_FindPic(pic);
+ if (image == null)
+ {
+ ri.Con_Printf(Defines.PRINT_ALL, "Can't find pic: " + pic + '\n');
+ return;
+ }
+
+ if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0 ) ) && !image.has_alpha)
+ gl.glDisable(GL.GL_ALPHA_TEST);
+
+ GL_Bind(image.texnum);
+ gl.glBegin (GL.GL_QUADS);
+ gl.glTexCoord2f(x/64.0f, y/64.0f);
+ gl.glVertex2f (x, y);
+ gl.glTexCoord2f( (x+w)/64.0f, y/64.0f);
+ gl.glVertex2f(x+w, y);
+ gl.glTexCoord2f( (x+w)/64.0f, (y+h)/64.0f);
+ gl.glVertex2f(x+w, y+h);
+ gl.glTexCoord2f( x/64.0f, (y+h)/64.0f );
+ gl.glVertex2f (x, y+h);
+ gl.glEnd ();
+
+ if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0 ) ) && !image.has_alpha)
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ }
+
+
+ /*
+ =============
+ Draw_Fill
+
+ Fills a box of pixels with a single color
+ =============
+ */
+ protected void Draw_Fill(int x, int y, int w, int h, int colorIndex) {
+
+ if ( colorIndex > 255)
+ ri.Sys_Error(Defines.ERR_FATAL, "Draw_Fill: bad color");
+
+ gl.glDisable(GL.GL_TEXTURE_2D);
+
+ int color = d_8to24table[colorIndex];
+
+ gl.glColor3ub(
+ (byte)((color >> 0) & 0xff), // r
+ (byte)((color >> 8) & 0xff), // g
+ (byte)((color >> 16) & 0xff) // b
+ );
+
+ gl.glBegin (GL.GL_QUADS);
+
+ gl.glVertex2f(x,y);
+ gl.glVertex2f(x+w, y);
+ gl.glVertex2f(x+w, y+h);
+ gl.glVertex2f(x, y+h);
+
+ gl.glEnd();
+ gl.glColor3f(1,1,1);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ }
+
+// =============================================================================
+
+ /*
+ ================
+ Draw_FadeScreen
+ ================
+ */
+ protected void Draw_FadeScreen() {
+ gl.glEnable(GL.GL_BLEND);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glColor4f(0, 0, 0, 0.8f);
+ gl.glBegin(GL.GL_QUADS);
+
+ gl.glVertex2f(0,0);
+ gl.glVertex2f(vid.width, 0);
+ gl.glVertex2f(vid.width, vid.height);
+ gl.glVertex2f(0, vid.height);
+
+ gl.glEnd();
+ gl.glColor4f(1,1,1,1);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glDisable(GL.GL_BLEND);
+ }
+
+// ====================================================================
+
+
+ /*
+ =============
+ Draw_StretchRaw
+ =============
+ */
+ protected void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte[] data)
+ {
+ int i, j, trows;
+ int sourceIndex;
+ int frac, fracstep;
+ float hscale;
+ int row;
+ float t;
+
+ GL_Bind(0);
+
+ if (rows<=256)
+ {
+ hscale = 1;
+ trows = rows;
+ }
+ else
+ {
+ hscale = rows/256.0f;
+ trows = 256;
+ }
+ t = rows*hscale / 256;
+
+ if ( !qglColorTableEXT )
+ {
+ int[] image32 = new int[256*256];
+ int destIndex = 0;
+
+ for (i=0 ; i<trows ; i++)
+ {
+ row = (int)(i*hscale);
+ if (row > rows)
+ break;
+ sourceIndex = cols*row;
+ destIndex = i*256;
+ fracstep = cols*0x10000/256;
+ frac = fracstep >> 1;
+ for (j=0 ; j<256 ; j++)
+ {
+ image32[destIndex + j] = r_rawpalette[data[sourceIndex + (frac>>16)] & 0xff];
+ frac += fracstep;
+ }
+ }
+ gl.glTexImage2D (GL.GL_TEXTURE_2D, 0, gl_tex_solid_format, 256, 256, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, image32);
+ }
+ else
+ {
+ byte[] image8 = new byte[256*256];
+ int destIndex = 0;;
+
+ for (i=0 ; i<trows ; i++)
+ {
+ row = (int)(i*hscale);
+ if (row > rows)
+ break;
+ sourceIndex = cols*row;
+ destIndex = i*256;
+ fracstep = cols*0x10000/256;
+ frac = fracstep >> 1;
+ for (j=0 ; j<256 ; j++)
+ {
+ image8[destIndex + j] = data[sourceIndex + (frac>>16)];
+ frac += fracstep;
+ }
+ }
+
+ gl.glTexImage2D( GL.GL_TEXTURE_2D,
+ 0,
+ GL_COLOR_INDEX8_EXT,
+ 256, 256,
+ 0,
+ GL.GL_COLOR_INDEX,
+ GL.GL_UNSIGNED_BYTE,
+ image8 );
+ }
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+
+ if ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0 ) )
+ gl.glDisable (GL.GL_ALPHA_TEST);
+
+ gl.glBegin (GL.GL_QUADS);
+ gl.glTexCoord2f (0, 0);
+ gl.glVertex2f (x, y);
+ gl.glTexCoord2f (1, 0);
+ gl.glVertex2f (x+w, y);
+ gl.glTexCoord2f (1, t);
+ gl.glVertex2f (x+w, y+h);
+ gl.glTexCoord2f (0, t);
+ gl.glVertex2f (x, y+h);
+ gl.glEnd ();
+
+ if ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( (gl_config.renderer & GL_RENDERER_RENDITION) != 0 ) )
+ gl.glEnable (GL.GL_ALPHA_TEST);
+ }
+
+}
diff --git a/src/jake2/render/fastjogl/Image.java b/src/jake2/render/fastjogl/Image.java
new file mode 100644
index 0000000..de364c3
--- /dev/null
+++ b/src/jake2/render/fastjogl/Image.java
@@ -0,0 +1,1673 @@
+/*
+ * Image.java
+ * Copyright (C) 2003
+ *
+ * $Id: Image.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.Defines;
+import jake2.client.particle_t;
+import jake2.game.cvar_t;
+import jake2.qcommon.longjmpException;
+import jake2.qcommon.qfiles;
+import jake2.render.image_t;
+import jake2.util.Lib;
+import jake2.util.Vargs;
+
+import java.awt.Dimension;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.nio.*;
+import java.util.Arrays;
+
+import net.java.games.jogl.GL;
+
+/**
+ * Image
+ *
+ * @author cwei
+ */
+public abstract class Image extends Main {
+
+ image_t draw_chars;
+
+ image_t[] gltextures = new image_t[MAX_GLTEXTURES];
+ //Map gltextures = new Hashtable(MAX_GLTEXTURES); // image_t
+ int numgltextures;
+ int base_textureid; // gltextures[i] = base_textureid+i
+
+ byte[] intensitytable = new byte[256];
+ byte[] gammatable = new byte[256];
+
+ cvar_t intensity;
+
+ //
+ // qboolean GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean is_sky );
+ // qboolean GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap);
+ //
+
+ int gl_solid_format = 3;
+ int gl_alpha_format = 4;
+
+ int gl_tex_solid_format = 3;
+ int gl_tex_alpha_format = 4;
+
+ int gl_filter_min = GL.GL_LINEAR_MIPMAP_NEAREST;
+ int gl_filter_max = GL.GL_LINEAR;
+
+ Image() {
+ // init the texture cache
+ for (int i = 0; i < gltextures.length; i++)
+ {
+ gltextures[i] = new image_t(i);
+ }
+ numgltextures = 0;
+ }
+
+ void GL_SetTexturePalette(int[] palette) {
+
+ assert(palette != null && palette.length == 256) : "int palette[256] bug";
+
+ int i;
+ byte[] temptable = new byte[768];
+
+ if (qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f) {
+ for (i = 0; i < 256; i++) {
+ temptable[i * 3 + 0] = (byte) ((palette[i] >> 0) & 0xff);
+ temptable[i * 3 + 1] = (byte) ((palette[i] >> 8) & 0xff);
+ temptable[i * 3 + 2] = (byte) ((palette[i] >> 16) & 0xff);
+ }
+
+ gl.glColorTableEXT(GL.GL_SHARED_TEXTURE_PALETTE_EXT, GL.GL_RGB, 256, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, temptable);
+ }
+ }
+
+ void GL_EnableMultitexture(boolean enable) {
+ if (enable) {
+ GL_SelectTexture(GL_TEXTURE1);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ GL_TexEnv(GL.GL_REPLACE);
+ }
+ else {
+ GL_SelectTexture(GL_TEXTURE1);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ GL_TexEnv(GL.GL_REPLACE);
+ }
+ GL_SelectTexture(GL_TEXTURE0);
+ GL_TexEnv(GL.GL_REPLACE);
+ }
+
+ void GL_SelectTexture(int texture /* GLenum */) {
+ int tmu;
+
+ tmu = (texture == GL_TEXTURE0) ? 0 : 1;
+
+ if (tmu == gl_state.currenttmu) {
+ return;
+ }
+
+ gl_state.currenttmu = tmu;
+
+ gl.glActiveTextureARB(texture);
+ gl.glClientActiveTextureARB(texture);
+ }
+
+ int[] lastmodes = { -1, -1 };
+
+ void GL_TexEnv(int mode /* GLenum */
+ ) {
+
+ if (mode != lastmodes[gl_state.currenttmu]) {
+ gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, mode);
+ lastmodes[gl_state.currenttmu] = mode;
+ }
+ }
+
+ void GL_Bind(int texnum) {
+
+ if ((gl_nobind.value != 0) && (draw_chars != null)) {
+ // performance evaluation option
+ texnum = draw_chars.texnum;
+ }
+ if (gl_state.currenttextures[gl_state.currenttmu] == texnum)
+ return;
+
+ gl_state.currenttextures[gl_state.currenttmu] = texnum;
+ gl.glBindTexture(GL.GL_TEXTURE_2D, texnum);
+ }
+
+ void GL_MBind(int target /* GLenum */, int texnum) {
+ GL_SelectTexture(target);
+ if (target == GL_TEXTURE0) {
+ if (gl_state.currenttextures[0] == texnum)
+ return;
+ }
+ else {
+ if (gl_state.currenttextures[1] == texnum)
+ return;
+ }
+ GL_Bind(texnum);
+ }
+
+ // glmode_t
+ static class glmode_t {
+ String name;
+ int minimize, maximize;
+
+ glmode_t(String name, int minimize, int maximze) {
+ this.name = name;
+ this.minimize = minimize;
+ this.maximize = maximze;
+ }
+ }
+
+ static final glmode_t modes[] =
+ {
+ new glmode_t("GL_NEAREST", GL.GL_NEAREST, GL.GL_NEAREST),
+ new glmode_t("GL_LINEAR", GL.GL_LINEAR, GL.GL_LINEAR),
+ new glmode_t("GL_NEAREST_MIPMAP_NEAREST", GL.GL_NEAREST_MIPMAP_NEAREST, GL.GL_NEAREST),
+ new glmode_t("GL_LINEAR_MIPMAP_NEAREST", GL.GL_LINEAR_MIPMAP_NEAREST, GL.GL_LINEAR),
+ new glmode_t("GL_NEAREST_MIPMAP_LINEAR", GL.GL_NEAREST_MIPMAP_LINEAR, GL.GL_NEAREST),
+ new glmode_t("GL_LINEAR_MIPMAP_LINEAR", GL.GL_LINEAR_MIPMAP_LINEAR, GL.GL_LINEAR)};
+
+ static final int NUM_GL_MODES = modes.length;
+
+ // gltmode_t
+ static class gltmode_t {
+ String name;
+ int mode;
+
+ gltmode_t(String name, int mode) {
+ this.name = name;
+ this.mode = mode;
+ }
+ }
+
+ static final gltmode_t[] gl_alpha_modes =
+ {
+ new gltmode_t("default", 4),
+ new gltmode_t("GL_RGBA", GL.GL_RGBA),
+ new gltmode_t("GL_RGBA8", GL.GL_RGBA8),
+ new gltmode_t("GL_RGB5_A1", GL.GL_RGB5_A1),
+ new gltmode_t("GL_RGBA4", GL.GL_RGBA4),
+ new gltmode_t("GL_RGBA2", GL.GL_RGBA2),
+ };
+
+ static final int NUM_GL_ALPHA_MODES = gl_alpha_modes.length;
+
+ static final gltmode_t[] gl_solid_modes =
+ {
+ new gltmode_t("default", 3),
+ new gltmode_t("GL_RGB", GL.GL_RGB),
+ new gltmode_t("GL_RGB8", GL.GL_RGB8),
+ new gltmode_t("GL_RGB5", GL.GL_RGB5),
+ new gltmode_t("GL_RGB4", GL.GL_RGB4),
+ new gltmode_t("GL_R3_G3_B2", GL.GL_R3_G3_B2),
+ // #ifdef GL_RGB2_EXT
+ new gltmode_t("GL_RGB2", GL.GL_RGB2_EXT)
+ // #endif
+ };
+
+ static final int NUM_GL_SOLID_MODES = gl_solid_modes.length;
+
+ /*
+ ===============
+ GL_TextureMode
+ ===============
+ */
+ void GL_TextureMode(String string) {
+
+ int i;
+ for (i = 0; i < NUM_GL_MODES; i++) {
+ if (modes[i].name.equalsIgnoreCase(string))
+ break;
+ }
+
+ if (i == NUM_GL_MODES) {
+ ri.Con_Printf(Defines.PRINT_ALL, "bad filter name: [" + string + "]\n");
+ return;
+ }
+
+ gl_filter_min = modes[i].minimize;
+ gl_filter_max = modes[i].maximize;
+
+ image_t glt;
+ // change all the existing mipmap texture objects
+ for (i = 0; i < numgltextures; i++) {
+ glt = gltextures[i];
+
+ if (glt.type != it_pic && glt.type != it_sky) {
+ GL_Bind(glt.texnum);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, gl_filter_min);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, gl_filter_max);
+ }
+ }
+ }
+
+ /*
+ ===============
+ GL_TextureAlphaMode
+ ===============
+ */
+ void GL_TextureAlphaMode(String string) {
+
+ int i;
+ for (i = 0; i < NUM_GL_ALPHA_MODES; i++) {
+ if (gl_alpha_modes[i].name.equalsIgnoreCase(string))
+ break;
+ }
+
+ if (i == NUM_GL_ALPHA_MODES) {
+ ri.Con_Printf(Defines.PRINT_ALL, "bad alpha texture mode name: [" + string + "]\n");
+ return;
+ }
+
+ gl_tex_alpha_format = gl_alpha_modes[i].mode;
+ }
+
+ /*
+ ===============
+ GL_TextureSolidMode
+ ===============
+ */
+ void GL_TextureSolidMode(String string) {
+ int i;
+ for (i = 0; i < NUM_GL_SOLID_MODES; i++) {
+ if (gl_solid_modes[i].name.equalsIgnoreCase(string))
+ break;
+ }
+
+ if (i == NUM_GL_SOLID_MODES) {
+ ri.Con_Printf(Defines.PRINT_ALL, "bad solid texture mode name: [" + string + "]\n");
+ return;
+ }
+
+ gl_tex_solid_format = gl_solid_modes[i].mode;
+ }
+
+ /*
+ ===============
+ GL_ImageList_f
+ ===============
+ */
+ void GL_ImageList_f() {
+
+ image_t image;
+ int texels;
+ final String[] palstrings = { "RGB", "PAL" };
+
+ ri.Con_Printf(Defines.PRINT_ALL, "------------------\n");
+ texels = 0;
+
+ for (int i = 0; i < numgltextures; i++) {
+ image = gltextures[i];
+ if (image.texnum <= 0)
+ continue;
+
+ texels += image.upload_width * image.upload_height;
+ switch (image.type) {
+ case it_skin :
+ ri.Con_Printf(Defines.PRINT_ALL, "M");
+ break;
+ case it_sprite :
+ ri.Con_Printf(Defines.PRINT_ALL, "S");
+ break;
+ case it_wall :
+ ri.Con_Printf(Defines.PRINT_ALL, "W");
+ break;
+ case it_pic :
+ ri.Con_Printf(Defines.PRINT_ALL, "P");
+ break;
+ default :
+ ri.Con_Printf(Defines.PRINT_ALL, " ");
+ break;
+ }
+
+ ri.Con_Printf(
+ Defines.PRINT_ALL,
+ " %3i %3i %s: %s\n",
+ new Vargs(4).add(image.upload_width).add(image.upload_height).add(palstrings[(image.paletted) ? 1 : 0]).add(
+ image.name));
+ }
+ ri.Con_Printf(Defines.PRINT_ALL, "Total texel count (not counting mipmaps): " + texels + '\n');
+ }
+
+ /*
+ =============================================================================
+
+ scrap allocation
+
+ Allocate all the little status bar objects into a single texture
+ to crutch up inefficient hardware / drivers
+
+ =============================================================================
+ */
+
+ static final int MAX_SCRAPS = 1;
+ static final int BLOCK_WIDTH = 256;
+ static final int BLOCK_HEIGHT = 256;
+
+ int[][] scrap_allocated = new int[MAX_SCRAPS][BLOCK_WIDTH];
+ byte[][] scrap_texels = new byte[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT];
+ boolean scrap_dirty;
+
+ static class pos_t {
+ int x, y;
+
+ pos_t(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ }
+
+ // returns a texture number and the position inside it
+ int Scrap_AllocBlock(int w, int h, pos_t pos) {
+ int i, j;
+ int best, best2;
+ int texnum;
+
+ for (texnum = 0; texnum < MAX_SCRAPS; texnum++) {
+ best = BLOCK_HEIGHT;
+
+ for (i = 0; i < BLOCK_WIDTH - w; i++) {
+ best2 = 0;
+
+ for (j = 0; j < w; j++) {
+ if (scrap_allocated[texnum][i + j] >= best)
+ break;
+ if (scrap_allocated[texnum][i + j] > best2)
+ best2 = scrap_allocated[texnum][i + j];
+ }
+ if (j == w) { // this is a valid spot
+ pos.x = i;
+ pos.y = best = best2;
+ }
+ }
+
+ if (best + h > BLOCK_HEIGHT)
+ continue;
+
+ for (i = 0; i < w; i++)
+ scrap_allocated[texnum][pos.x + i] = best + h;
+
+ return texnum;
+ }
+
+ return -1;
+ // Sys_Error ("Scrap_AllocBlock: full");
+ }
+
+ int scrap_uploads = 0;
+
+ void Scrap_Upload() {
+ scrap_uploads++;
+ GL_Bind(TEXNUM_SCRAPS);
+ GL_Upload8(scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, false);
+ scrap_dirty = false;
+ }
+
+ /*
+ =================================================================
+
+ PCX LOADING
+
+ =================================================================
+ */
+
+ /*
+ ==============
+ LoadPCX
+ ==============
+ */
+ byte[] LoadPCX(String filename, byte[][] palette, Dimension dim) {
+ qfiles.pcx_t pcx;
+
+ //
+ // load the file
+ //
+ byte[] raw = ri.FS_LoadFile(filename);
+
+ if (raw == null) {
+ ri.Con_Printf(Defines.PRINT_DEVELOPER, "Bad pcx file " + filename + '\n');
+ return null;
+ }
+
+ //
+ // parse the PCX file
+ //
+ pcx = new qfiles.pcx_t(raw);
+
+ if (pcx.manufacturer != 0x0a
+ || pcx.version != 5
+ || pcx.encoding != 1
+ || pcx.bits_per_pixel != 8
+ || pcx.xmax >= 640
+ || pcx.ymax >= 480) {
+
+ ri.Con_Printf(Defines.PRINT_ALL, "Bad pcx file " + filename + '\n');
+ return null;
+ }
+
+ int width = pcx.xmax - pcx.xmin + 1;
+ int height = pcx.ymax - pcx.ymin + 1;
+
+ byte[] pix = new byte[width * height];
+
+ if (palette != null) {
+ palette[0] = new byte[768];
+ System.arraycopy(raw, raw.length - 768, palette[0], 0, 768);
+ }
+
+ if (dim != null) {
+ dim.width = width;
+ dim.height = height;
+ }
+
+ //
+ // decode pcx
+ //
+ int count = 0;
+ byte dataByte = 0;
+ int runLength = 0;
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width;) {
+
+ dataByte = pcx.data.get();
+
+ if ((dataByte & 0xC0) == 0xC0) {
+ runLength = dataByte & 0x3F;
+ dataByte = pcx.data.get();
+ // write runLength pixel
+ while (runLength-- > 0) {
+ pix[count++] = dataByte;
+ x++;
+ }
+ }
+ else {
+ // write one pixel
+ pix[count++] = dataByte;
+ x++;
+ }
+ }
+ }
+ return pix;
+ }
+
+ // /*
+ // =========================================================
+ //
+ // TARGA LOADING
+ //
+ // =========================================================
+ // */
+ /*
+ =============
+ LoadTGA
+ =============
+ */
+ byte[] LoadTGA(String name, Dimension dim) {
+ int columns, rows, numPixels;
+ int pixbuf; // index into pic
+ int row, column;
+ byte[] raw;
+ ByteBuffer buf_p;
+ int length;
+ qfiles.tga_t targa_header;
+ byte[] pic = null;
+
+ //
+ // load the file
+ //
+ raw = ri.FS_LoadFile (name);
+
+ if (raw == null)
+ {
+ ri.Con_Printf(Defines.PRINT_DEVELOPER, "Bad tga file "+ name +'\n');
+ return null;
+ }
+
+ targa_header = new qfiles.tga_t(raw);
+
+ if (targa_header.image_type != 2 && targa_header.image_type != 10)
+ ri.Sys_Error(Defines.ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n");
+
+ if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
+ ri.Sys_Error (Defines.ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
+
+ columns = targa_header.width;
+ rows = targa_header.height;
+ numPixels = columns * rows;
+
+ if (dim != null) {
+ dim.width = columns;
+ dim.height = rows;
+ }
+
+ pic = new byte[numPixels * 4]; // targa_rgba;
+
+ if (targa_header.id_length != 0)
+ targa_header.data.position(targa_header.id_length); // skip TARGA image comment
+
+ buf_p = targa_header.data;
+
+ byte red,green,blue,alphabyte;
+ red = green = blue = alphabyte = 0;
+ int packetHeader, packetSize, j;
+
+ if (targa_header.image_type==2) { // Uncompressed, RGB images
+ for(row=rows-1; row>=0; row--) {
+
+ pixbuf = row * columns * 4;
+
+ for(column=0; column<columns; column++) {
+ switch (targa_header.pixel_size) {
+ case 24:
+
+ blue = buf_p.get();
+ green = buf_p.get();
+ red = buf_p.get();
+ pic[pixbuf++] = red;
+ pic[pixbuf++] = green;
+ pic[pixbuf++] = blue;
+ pic[pixbuf++] = (byte)255;
+ break;
+ case 32:
+ blue = buf_p.get();
+ green = buf_p.get();
+ red = buf_p.get();
+ alphabyte = buf_p.get();
+ pic[pixbuf++] = red;
+ pic[pixbuf++] = green;
+ pic[pixbuf++] = blue;
+ pic[pixbuf++] = alphabyte;
+ break;
+ }
+ }
+ }
+ }
+ else if (targa_header.image_type==10) { // Runlength encoded RGB images
+ for(row=rows-1; row>=0; row--) {
+
+ pixbuf = row * columns * 4;
+ try {
+
+ for(column=0; column<columns; ) {
+
+ packetHeader= buf_p.get() & 0xFF;
+ packetSize = 1 + (packetHeader & 0x7f);
+
+ if ((packetHeader & 0x80) != 0) { // run-length packet
+ switch (targa_header.pixel_size) {
+ case 24:
+ blue = buf_p.get();
+ green = buf_p.get();
+ red = buf_p.get();
+ alphabyte = (byte)255;
+ break;
+ case 32:
+ blue = buf_p.get();
+ green = buf_p.get();
+ red = buf_p.get();
+ alphabyte = buf_p.get();
+ break;
+ }
+
+ for(j=0;j<packetSize;j++) {
+ pic[pixbuf++]=red;
+ pic[pixbuf++]=green;
+ pic[pixbuf++]=blue;
+ pic[pixbuf++]=alphabyte;
+ column++;
+ if (column==columns) { // run spans across rows
+ column=0;
+ if (row>0)
+ row--;
+ else
+ // goto label breakOut;
+ throw new longjmpException();
+
+ pixbuf = row * columns * 4;
+ }
+ }
+ }
+ else { // non run-length packet
+ for(j=0;j<packetSize;j++) {
+ switch (targa_header.pixel_size) {
+ case 24:
+ blue = buf_p.get();
+ green = buf_p.get();
+ red = buf_p.get();
+ pic[pixbuf++] = red;
+ pic[pixbuf++] = green;
+ pic[pixbuf++] = blue;
+ pic[pixbuf++] = (byte)255;
+ break;
+ case 32:
+ blue = buf_p.get();
+ green = buf_p.get();
+ red = buf_p.get();
+ alphabyte = buf_p.get();
+ pic[pixbuf++] = red;
+ pic[pixbuf++] = green;
+ pic[pixbuf++] = blue;
+ pic[pixbuf++] = alphabyte;
+ break;
+ }
+ column++;
+ if (column==columns) { // pixel packet run spans across rows
+ column=0;
+ if (row>0)
+ row--;
+ else
+ // goto label breakOut;
+ throw new longjmpException();
+
+ pixbuf = row * columns * 4;
+ }
+ }
+ }
+ }
+ } catch (longjmpException e){
+ // label breakOut:
+ }
+ }
+ }
+ return pic;
+ }
+
+ /*
+ ====================================================================
+
+ IMAGE FLOOD FILLING
+
+ ====================================================================
+ */
+
+ /*
+ =================
+ Mod_FloodFillSkin
+
+ Fill background pixels so mipmapping doesn't have haloes
+ =================
+ */
+
+ static class floodfill_t {
+ short x, y;
+ }
+
+ // must be a power of 2
+ static final int FLOODFILL_FIFO_SIZE = 0x1000;
+ static final int FLOODFILL_FIFO_MASK = FLOODFILL_FIFO_SIZE - 1;
+ //
+ // #define FLOODFILL_STEP( off, dx, dy ) \
+ // { \
+ // if (pos[off] == fillcolor) \
+ // { \
+ // pos[off] = 255; \
+ // fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \
+ // inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
+ // } \
+ // else if (pos[off] != 255) fdc = pos[off]; \
+ // }
+
+ // void FLOODFILL_STEP( int off, int dx, int dy )
+ // {
+ // if (pos[off] == fillcolor)
+ // {
+ // pos[off] = 255;
+ // fifo[inpt].x = x + dx; fifo[inpt].y = y + dy;
+ // inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
+ // }
+ // else if (pos[off] != 255) fdc = pos[off];
+ // }
+
+ // TODO check this: R_FloodFillSkin( byte[] skin, int skinwidth, int skinheight)
+ void R_FloodFillSkin(byte[] skin, int skinwidth, int skinheight) {
+ // byte fillcolor = *skin; // assume this is the pixel to fill
+ int fillcolor = skin[0] & 0xff;
+ floodfill_t[] fifo = new floodfill_t[FLOODFILL_FIFO_SIZE];
+ int inpt = 0, outpt = 0;
+ int filledcolor = -1;
+ int i;
+
+ for (int j = 0; j < fifo.length; j++) {
+ fifo[j] = new floodfill_t();
+ }
+
+ if (filledcolor == -1) {
+ filledcolor = 0;
+ // attempt to find opaque black
+ for (i = 0; i < 256; ++i)
+ // TODO check this
+ if (d_8to24table[i] == 0xFF000000) { // alpha 1.0
+ //if (d_8to24table[i] == (255 << 0)) // alpha 1.0
+ filledcolor = i;
+ break;
+ }
+ }
+
+ // can't fill to filled color or to transparent color (used as visited marker)
+ if ((fillcolor == filledcolor) || (fillcolor == 255)) {
+ return;
+ }
+
+ fifo[inpt].x = 0;
+ fifo[inpt].y = 0;
+ inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
+
+ while (outpt != inpt) {
+ int x = fifo[outpt].x;
+ int y = fifo[outpt].y;
+ int fdc = filledcolor;
+ // byte *pos = &skin[x + skinwidth * y];
+ int pos = x + skinwidth * y;
+ //
+ outpt = (outpt + 1) & FLOODFILL_FIFO_MASK;
+
+ int off, dx, dy;
+
+ if (x > 0) {
+ // FLOODFILL_STEP( -1, -1, 0 );
+ off = -1;
+ dx = -1;
+ dy = 0;
+ if (skin[pos + off] == (byte) fillcolor) {
+ skin[pos + off] = (byte) 255;
+ fifo[inpt].x = (short) (x + dx);
+ fifo[inpt].y = (short) (y + dy);
+ inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
+ }
+ else if (skin[pos + off] != (byte) 255)
+ fdc = skin[pos + off] & 0xff;
+ }
+
+ if (x < skinwidth - 1) {
+ // FLOODFILL_STEP( 1, 1, 0 );
+ off = 1;
+ dx = 1;
+ dy = 0;
+ if (skin[pos + off] == (byte) fillcolor) {
+ skin[pos + off] = (byte) 255;
+ fifo[inpt].x = (short) (x + dx);
+ fifo[inpt].y = (short) (y + dy);
+ inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
+ }
+ else if (skin[pos + off] != (byte) 255)
+ fdc = skin[pos + off] & 0xff;
+ }
+
+ if (y > 0) {
+ // FLOODFILL_STEP( -skinwidth, 0, -1 );
+ off = -skinwidth;
+ dx = 0;
+ dy = -1;
+ if (skin[pos + off] == (byte) fillcolor) {
+ skin[pos + off] = (byte) 255;
+ fifo[inpt].x = (short) (x + dx);
+ fifo[inpt].y = (short) (y + dy);
+ inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
+ }
+ else if (skin[pos + off] != (byte) 255)
+ fdc = skin[pos + off] & 0xff;
+ }
+
+ if (y < skinheight - 1) {
+ // FLOODFILL_STEP( skinwidth, 0, 1 );
+ off = skinwidth;
+ dx = 0;
+ dy = 1;
+ if (skin[pos + off] == (byte) fillcolor) {
+ skin[pos + off] = (byte) 255;
+ fifo[inpt].x = (short) (x + dx);
+ fifo[inpt].y = (short) (y + dy);
+ inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
+ }
+ else if (skin[pos + off] != (byte) 255)
+ fdc = skin[pos + off] & 0xff;
+
+ }
+
+ skin[x + skinwidth * y] = (byte) fdc;
+ }
+ }
+
+ // =======================================================
+
+ /*
+ ================
+ GL_ResampleTexture
+ ================
+ */
+ // cwei :-)
+ void GL_ResampleTexture(int[] in, int inwidth, int inheight, int[] out, int outwidth, int outheight) {
+ // int i, j;
+ // unsigned *inrow, *inrow2;
+ // int frac, fracstep;
+ // int[] p1 = new int[1024];
+ // int[] p2 = new int[1024];
+ //
+
+ // *** this source do the same ***
+ BufferedImage image = new BufferedImage(inwidth, inheight, BufferedImage.TYPE_INT_ARGB);
+
+ image.setRGB(0, 0, inwidth, inheight, in, 0, inwidth);
+
+ AffineTransformOp op =
+ new AffineTransformOp(
+ AffineTransform.getScaleInstance(outwidth * 1.0 / inwidth, outheight * 1.0 / inheight),
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ BufferedImage tmp = op.filter(image, null);
+
+ tmp.getRGB(0, 0, outwidth, outheight, out, 0, outwidth);
+
+ // *** end ***
+
+ // byte *pix1, *pix2, *pix3, *pix4;
+ //
+ // fracstep = inwidth*0x10000/outwidth;
+ //
+ // frac = fracstep>>2;
+ // for (i=0 ; i<outwidth ; i++)
+ // {
+ // p1[i] = 4*(frac>>16);
+ // frac += fracstep;
+ // }
+ // frac = 3*(fracstep>>2);
+ // for (i=0 ; i<outwidth ; i++)
+ // {
+ // p2[i] = 4*(frac>>16);
+ // frac += fracstep;
+ // }
+ //
+ // for (i=0 ; i<outheight ; i++, out += outwidth)
+ // {
+ // inrow = in + inwidth*(int)((i+0.25)*inheight/outheight);
+ // inrow2 = in + inwidth*(int)((i+0.75)*inheight/outheight);
+ // frac = fracstep >> 1;
+ // for (j=0 ; j<outwidth ; j++)
+ // {
+ // pix1 = (byte *)inrow + p1[j];
+ // pix2 = (byte *)inrow + p2[j];
+ // pix3 = (byte *)inrow2 + p1[j];
+ // pix4 = (byte *)inrow2 + p2[j];
+ // ((byte *)(out+j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
+ // ((byte *)(out+j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
+ // ((byte *)(out+j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
+ // ((byte *)(out+j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2;
+ // }
+ // }
+ }
+
+ /*
+ ================
+ GL_LightScaleTexture
+
+ Scale up the pixel values in a texture to increase the
+ lighting range
+ ================
+ */
+ void GL_LightScaleTexture(int[] in, int inwidth, int inheight, boolean only_gamma) {
+ if (only_gamma) {
+ int i, c;
+ int r, g, b, color;
+
+ c = inwidth * inheight;
+ for (i = 0; i < c; i++) {
+ color = in[i];
+ r = (color >> 0) & 0xFF;
+ g = (color >> 8) & 0xFF;
+ b = (color >> 16) & 0xFF;
+
+ r = gammatable[r] & 0xFF;
+ g = gammatable[g] & 0xFF;
+ b = gammatable[b] & 0xFF;
+
+ in[i] = (r << 0) | (g << 8) | (b << 16) | (color & 0xFF000000);
+ }
+ }
+ else {
+ int i, c;
+ int r, g, b, color;
+
+ c = inwidth * inheight;
+ for (i = 0; i < c; i++) {
+ color = in[i];
+ r = (color >> 0) & 0xFF;
+ g = (color >> 8) & 0xFF;
+ b = (color >> 16) & 0xFF;
+
+ r = gammatable[intensitytable[r] & 0xFF] & 0xFF;
+ g = gammatable[intensitytable[g] & 0xFF] & 0xFF;
+ b = gammatable[intensitytable[b] & 0xFF] & 0xFF;
+
+ in[i] = (r << 0) | (g << 8) | (b << 16) | (color & 0xFF000000);
+ }
+
+ }
+ }
+
+ /*
+ ================
+ GL_MipMap
+
+ Operates in place, quartering the size of the texture
+ ================
+ */
+ void GL_MipMap(int[] in, int width, int height) {
+ int i, j;
+ int[] out;
+
+ out = in;
+
+ int inIndex = 0;
+ int outIndex = 0;
+
+ int r, g, b, a;
+ int p1, p2, p3, p4;
+
+ for (i = 0; i < height; i += 2, inIndex += width) {
+ for (j = 0; j < width; j += 2, outIndex += 1, inIndex += 2) {
+
+ p1 = in[inIndex + 0];
+ p2 = in[inIndex + 1];
+ p3 = in[inIndex + width + 0];
+ p4 = in[inIndex + width + 1];
+
+ r = (((p1 >> 0) & 0xFF) + ((p2 >> 0) & 0xFF) + ((p3 >> 0) & 0xFF) + ((p4 >> 0) & 0xFF)) >> 2;
+ g = (((p1 >> 8) & 0xFF) + ((p2 >> 8) & 0xFF) + ((p3 >> 8) & 0xFF) + ((p4 >> 8) & 0xFF)) >> 2;
+ b = (((p1 >> 16) & 0xFF) + ((p2 >> 16) & 0xFF) + ((p3 >> 16) & 0xFF) + ((p4 >> 16) & 0xFF)) >> 2;
+ a = (((p1 >> 24) & 0xFF) + ((p2 >> 24) & 0xFF) + ((p3 >> 24) & 0xFF) + ((p4 >> 24) & 0xFF)) >> 2;
+
+ out[outIndex] = (r << 0) | (g << 8) | (b << 16) | (a << 24);
+ }
+ }
+ }
+
+ /*
+ ===============
+ GL_Upload32
+
+ Returns has_alpha
+ ===============
+ */
+ void GL_BuildPalettedTexture(byte[] paletted_texture, int[] scaled, int scaled_width, int scaled_height) {
+
+ int r, g, b, c;
+ int size = scaled_width * scaled_height;
+
+ for (int i = 0; i < size; i++) {
+
+ r = (scaled[i] >> 3) & 31;
+ g = (scaled[i] >> 10) & 63;
+ b = (scaled[i] >> 19) & 31;
+
+ c = r | (g << 5) | (b << 11);
+
+ paletted_texture[i] = gl_state.d_16to8table[c];
+ }
+ }
+
+ int upload_width, upload_height;
+ boolean uploaded_paletted;
+
+ /*
+ ===============
+ GL_Upload32
+
+ Returns has_alpha
+ ===============
+ */
+ int[] scaled = new int[256 * 256];
+ byte[] paletted_texture = new byte[256 * 256];
+ IntBuffer tex = Lib.newIntBuffer(512 * 256, ByteOrder.LITTLE_ENDIAN);
+
+ boolean GL_Upload32(int[] data, int width, int height, boolean mipmap) {
+ int samples;
+ int scaled_width, scaled_height;
+ int i, c;
+ int comp;
+
+ Arrays.fill(scaled, 0);
+ Arrays.fill(paletted_texture, (byte)0);
+
+ uploaded_paletted = false;
+
+ for (scaled_width = 1; scaled_width < width; scaled_width <<= 1);
+ if (gl_round_down.value > 0.0f && scaled_width > width && mipmap)
+ scaled_width >>= 1;
+ for (scaled_height = 1; scaled_height < height; scaled_height <<= 1);
+ if (gl_round_down.value > 0.0f && scaled_height > height && mipmap)
+ scaled_height >>= 1;
+
+ // let people sample down the world textures for speed
+ if (mipmap) {
+ scaled_width >>= (int) gl_picmip.value;
+ scaled_height >>= (int) gl_picmip.value;
+ }
+
+ // don't ever bother with >256 textures
+ if (scaled_width > 256)
+ scaled_width = 256;
+ if (scaled_height > 256)
+ scaled_height = 256;
+
+ if (scaled_width < 1)
+ scaled_width = 1;
+ if (scaled_height < 1)
+ scaled_height = 1;
+
+ upload_width = scaled_width;
+ upload_height = scaled_height;
+
+ if (scaled_width * scaled_height > 256 * 256)
+ ri.Sys_Error(Defines.ERR_DROP, "GL_Upload32: too big");
+
+ // scan the texture for any non-255 alpha
+ c = width * height;
+ samples = gl_solid_format;
+
+ for (i = 0; i < c; i++) {
+ if ((data[i] & 0xff000000) != 0xff000000) {
+ samples = gl_alpha_format;
+ break;
+ }
+ }
+
+ if (samples == gl_solid_format)
+ comp = gl_tex_solid_format;
+ else if (samples == gl_alpha_format)
+ comp = gl_tex_alpha_format;
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "Unknown number of texture components " + samples + '\n');
+ comp = samples;
+ }
+
+ // simulates a goto
+ try {
+ if (scaled_width == width && scaled_height == height) {
+ if (!mipmap) {
+ if (qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f && samples == gl_solid_format) {
+ uploaded_paletted = true;
+ GL_BuildPalettedTexture(paletted_texture, data, scaled_width, scaled_height);
+ gl.glTexImage2D(
+ GL.GL_TEXTURE_2D,
+ 0,
+ GL_COLOR_INDEX8_EXT,
+ scaled_width,
+ scaled_height,
+ 0,
+ GL.GL_COLOR_INDEX,
+ GL.GL_UNSIGNED_BYTE,
+ paletted_texture);
+ }
+ else {
+ tex.rewind(); tex.put(data);
+ gl.glTexImage2D(
+ GL.GL_TEXTURE_2D,
+ 0,
+ comp,
+ scaled_width,
+ scaled_height,
+ 0,
+ GL.GL_RGBA,
+ GL.GL_UNSIGNED_BYTE,
+ tex);
+ }
+ //goto done;
+ throw new longjmpException();
+ }
+ //memcpy (scaled, data, width*height*4); were bytes
+ System.arraycopy(data, 0, scaled, 0, width * height);
+ }
+ else
+ GL_ResampleTexture(data, width, height, scaled, scaled_width, scaled_height);
+
+ GL_LightScaleTexture(scaled, scaled_width, scaled_height, !mipmap);
+
+ if (qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f && (samples == gl_solid_format)) {
+ uploaded_paletted = true;
+ GL_BuildPalettedTexture(paletted_texture, scaled, scaled_width, scaled_height);
+ gl.glTexImage2D(
+ GL.GL_TEXTURE_2D,
+ 0,
+ GL_COLOR_INDEX8_EXT,
+ scaled_width,
+ scaled_height,
+ 0,
+ GL.GL_COLOR_INDEX,
+ GL.GL_UNSIGNED_BYTE,
+ paletted_texture);
+ }
+ else {
+ tex.rewind(); tex.put(scaled);
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, tex);
+ }
+
+ if (mipmap) {
+ int miplevel;
+ miplevel = 0;
+ while (scaled_width > 1 || scaled_height > 1) {
+ GL_MipMap(scaled, scaled_width, scaled_height);
+ scaled_width >>= 1;
+ scaled_height >>= 1;
+ if (scaled_width < 1)
+ scaled_width = 1;
+ if (scaled_height < 1)
+ scaled_height = 1;
+
+ miplevel++;
+ if (qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f && samples == gl_solid_format) {
+ uploaded_paletted = true;
+ GL_BuildPalettedTexture(paletted_texture, scaled, scaled_width, scaled_height);
+ gl.glTexImage2D(
+ GL.GL_TEXTURE_2D,
+ miplevel,
+ GL_COLOR_INDEX8_EXT,
+ scaled_width,
+ scaled_height,
+ 0,
+ GL.GL_COLOR_INDEX,
+ GL.GL_UNSIGNED_BYTE,
+ paletted_texture);
+ }
+ else {
+ tex.rewind(); tex.put(scaled);
+ gl.glTexImage2D(
+ GL.GL_TEXTURE_2D,
+ miplevel,
+ comp,
+ scaled_width,
+ scaled_height,
+ 0,
+ GL.GL_RGBA,
+ GL.GL_UNSIGNED_BYTE,
+ tex);
+ }
+ }
+ }
+ // label done:
+ }
+ catch (longjmpException e) {
+ ; // replaces label done
+ }
+
+ if (mipmap) {
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, gl_filter_min);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, gl_filter_max);
+ }
+ else {
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, gl_filter_max);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, gl_filter_max);
+ }
+
+ return (samples == gl_alpha_format);
+ }
+
+ /*
+ ===============
+ GL_Upload8
+
+ Returns has_alpha
+ ===============
+ */
+
+ int[] trans = new int[512 * 256];
+
+ boolean GL_Upload8(byte[] data, int width, int height, boolean mipmap, boolean is_sky) {
+
+ Arrays.fill(trans, 0);
+
+ int s = width * height;
+
+ if (s > trans.length)
+ ri.Sys_Error(Defines.ERR_DROP, "GL_Upload8: too large");
+
+ if (qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f && is_sky) {
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, width, height, 0, GL.GL_COLOR_INDEX, GL.GL_UNSIGNED_BYTE, data);
+
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, gl_filter_max);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, gl_filter_max);
+
+ // TODO check this
+ return false;
+ }
+ else {
+ int p;
+ int rgb;
+ for (int i = 0; i < s; i++) {
+ p = data[i] & 0xff;
+ trans[i] = d_8to24table[p];
+
+ if (p == 255) { // transparent, so scan around for another color
+ // to avoid alpha fringes
+ // FIXME: do a full flood fill so mips work...
+ if (i > width && (data[i - width] & 0xff) != 255)
+ p = data[i - width] & 0xff;
+ else if (i < s - width && (data[i + width] & 0xff) != 255)
+ p = data[i + width] & 0xff;
+ else if (i > 0 && (data[i - 1] & 0xff) != 255)
+ p = data[i - 1] & 0xff;
+ else if (i < s - 1 && (data[i + 1] & 0xff) != 255)
+ p = data[i + 1] & 0xff;
+ else
+ p = 0;
+ // copy rgb components
+
+ // ((byte *)&trans[i])[0] = ((byte *)&d_8to24table[p])[0];
+ // ((byte *)&trans[i])[1] = ((byte *)&d_8to24table[p])[1];
+ // ((byte *)&trans[i])[2] = ((byte *)&d_8to24table[p])[2];
+
+ trans[i] = d_8to24table[p] & 0x00FFFFFF; // only rgb
+ }
+ }
+
+ return GL_Upload32(trans, width, height, mipmap);
+ }
+ }
+
+ /*
+ ================
+ GL_LoadPic
+
+ This is also used as an entry point for the generated r_notexture
+ ================
+ */
+ image_t GL_LoadPic(String name, byte[] pic, int width, int height, int type, int bits) {
+ image_t image;
+ int i;
+
+ // find a free image_t
+ for (i = 0; i<numgltextures ; i++)
+ {
+ image = gltextures[i];
+ if (image.texnum == 0)
+ break;
+ }
+
+ if (i == numgltextures)
+ {
+ if (numgltextures == MAX_GLTEXTURES)
+ ri.Sys_Error (Defines.ERR_DROP, "MAX_GLTEXTURES");
+
+ numgltextures++;
+ }
+ image = gltextures[i];
+
+ if (name.length() > Defines.MAX_QPATH)
+ ri.Sys_Error(Defines.ERR_DROP, "Draw_LoadPic: \"" + name + "\" is too long");
+
+ image.name = name;
+ image.registration_sequence = registration_sequence;
+
+ image.width = width;
+ image.height = height;
+ image.type = type;
+
+
+ if (type == it_skin && bits == 8)
+ R_FloodFillSkin(pic, width, height);
+
+ // load little pics into the scrap
+ if (image.type == it_pic && bits == 8 && image.width < 64 && image.height < 64) {
+ pos_t pos = new pos_t(0, 0);
+ int j, k;
+
+ int texnum = Scrap_AllocBlock(image.width, image.height, pos);
+
+ if (texnum == -1) {
+ // replace goto nonscrap
+
+ image.scrap = false;
+
+ image.texnum = TEXNUM_IMAGES + image.getId(); // image pos in array
+ GL_Bind(image.texnum);
+
+ if (bits == 8) {
+ image.has_alpha =
+ GL_Upload8(pic, width, height, (image.type != it_pic && image.type != it_sky), image.type == it_sky);
+ }
+ else {
+ int[] tmp = new int[pic.length / 4];
+
+ for (i = 0; i < tmp.length; i++) {
+ tmp[i] = ((pic[4 * i + 0] & 0xFF) << 0); // & 0x000000FF;
+ tmp[i] |= ((pic[4 * i + 1] & 0xFF) << 8); // & 0x0000FF00;
+ tmp[i] |= ((pic[4 * i + 2] & 0xFF) << 16); // & 0x00FF0000;
+ tmp[i] |= ((pic[4 * i + 3] & 0xFF) << 24); // & 0xFF000000;
+ }
+
+ image.has_alpha = GL_Upload32(tmp, width, height, (image.type != it_pic && image.type != it_sky));
+ }
+
+ image.upload_width = upload_width; // after power of 2 and scales
+ image.upload_height = upload_height;
+ image.paletted = uploaded_paletted;
+ image.sl = 0;
+ image.sh = 1;
+ image.tl = 0;
+ image.th = 1;
+
+ return image;
+ }
+
+ scrap_dirty = true;
+
+ // copy the texels into the scrap block
+ k = 0;
+ for (i = 0; i < image.height; i++)
+ for (j = 0; j < image.width; j++, k++)
+ scrap_texels[texnum][(pos.y + i) * BLOCK_WIDTH + pos.x + j] = pic[k];
+
+ image.texnum = TEXNUM_SCRAPS + texnum;
+ image.scrap = true;
+ image.has_alpha = true;
+ image.sl = (pos.x + 0.01f) / (float) BLOCK_WIDTH;
+ image.sh = (pos.x + image.width - 0.01f) / (float) BLOCK_WIDTH;
+ image.tl = (pos.y + 0.01f) / (float) BLOCK_WIDTH;
+ image.th = (pos.y + image.height - 0.01f) / (float) BLOCK_WIDTH;
+
+ }
+ else {
+ // this was label nonscrap
+
+ image.scrap = false;
+
+ image.texnum = TEXNUM_IMAGES + image.getId(); //image pos in array
+ GL_Bind(image.texnum);
+
+ if (bits == 8) {
+ image.has_alpha = GL_Upload8(pic, width, height, (image.type != it_pic && image.type != it_sky), image.type == it_sky);
+ }
+ else {
+ int[] tmp = new int[pic.length / 4];
+
+ for (i = 0; i < tmp.length; i++) {
+ tmp[i] = ((pic[4 * i + 0] & 0xFF) << 0); // & 0x000000FF;
+ tmp[i] |= ((pic[4 * i + 1] & 0xFF) << 8); // & 0x0000FF00;
+ tmp[i] |= ((pic[4 * i + 2] & 0xFF) << 16); // & 0x00FF0000;
+ tmp[i] |= ((pic[4 * i + 3] & 0xFF) << 24); // & 0xFF000000;
+ }
+
+ image.has_alpha = GL_Upload32(tmp, width, height, (image.type != it_pic && image.type != it_sky));
+ }
+ image.upload_width = upload_width; // after power of 2 and scales
+ image.upload_height = upload_height;
+ image.paletted = uploaded_paletted;
+ image.sl = 0;
+ image.sh = 1;
+ image.tl = 0;
+ image.th = 1;
+ }
+ return image;
+ }
+
+ /*
+ ================
+ GL_LoadWal
+ ================
+ */
+ image_t GL_LoadWal(String name) {
+
+ image_t image = null;
+
+ byte[] raw = ri.FS_LoadFile(name);
+ if (raw == null) {
+ ri.Con_Printf(Defines.PRINT_ALL, "GL_FindImage: can't load " + name + '\n');
+ return r_notexture;
+ }
+
+ qfiles.miptex_t mt = new qfiles.miptex_t(raw);
+
+ byte[] pix = new byte[mt.width * mt.height];
+ System.arraycopy(raw, mt.offsets[0], pix, 0, pix.length);
+
+ image = GL_LoadPic(name, pix, mt.width, mt.height, it_wall, 8);
+
+ return image;
+ }
+
+ /*
+ ===============
+ GL_FindImage
+
+ Finds or loads the given image
+ ===============
+ */
+ image_t GL_FindImage(String name, int type) {
+ image_t image = null;
+
+ // TODO loest das grossschreibungs problem
+ name = name.toLowerCase();
+ // bughack for bad strings (fuck \0)
+ int index = name.indexOf('\0');
+ if (index != -1)
+ name = name.substring(0, index);
+
+ if (name == null || name.length() < 5)
+ return null; // ri.Sys_Error (ERR_DROP, "GL_FindImage: NULL name");
+ // ri.Sys_Error (ERR_DROP, "GL_FindImage: bad name: %s", name);
+
+ // look for it
+ for (int i = 0; i < numgltextures; i++)
+ {
+ image = gltextures[i];
+ if (name.equals(image.name))
+ {
+ image.registration_sequence = registration_sequence;
+ return image;
+ }
+ }
+
+ //
+ // load the pic from disk
+ //
+ byte[] pic = null;
+ Dimension dim = new Dimension();
+
+ if (name.endsWith(".pcx")) {
+
+ pic = LoadPCX(name, null, dim);
+ if (pic == null)
+ return null;
+ image = GL_LoadPic(name, pic, dim.width, dim.height, type, 8);
+
+ }
+ else if (name.endsWith(".wal")) {
+
+ image = GL_LoadWal(name);
+
+ }
+ else if (name.endsWith(".tga")) {
+
+ pic = LoadTGA(name, dim);
+
+ if (pic == null)
+ return null;
+
+ image = GL_LoadPic(name, pic, dim.width, dim.height, type, 32);
+
+ }
+ else
+ return null;
+
+ return image;
+ }
+
+ /*
+ ===============
+ R_RegisterSkin
+ ===============
+ */
+ protected image_t R_RegisterSkin(String name) {
+ return GL_FindImage(name, it_skin);
+ }
+
+ /*
+ ================
+ GL_FreeUnusedImages
+
+ Any image that was not touched on this registration sequence
+ will be freed.
+ ================
+ */
+ void GL_FreeUnusedImages() {
+
+ // never free r_notexture or particle texture
+ r_notexture.registration_sequence = registration_sequence;
+ r_particletexture.registration_sequence = registration_sequence;
+
+ image_t image = null;
+
+ for (int i = 0; i < numgltextures; i++) {
+ image = gltextures[i];
+ // used this sequence
+ if (image.registration_sequence == registration_sequence)
+ continue;
+ // free image_t slot
+ if (image.registration_sequence == 0)
+ continue;
+ // don't free pics
+ if (image.type == it_pic)
+ continue;
+
+ // free it
+ // TODO jogl bug
+ gl.glDeleteTextures(1, new int[] {image.texnum});
+ image.clear();
+ }
+ }
+
+ /*
+ ===============
+ Draw_GetPalette
+ ===============
+ */
+ protected void Draw_GetPalette() {
+ int r, g, b;
+ Dimension dim;
+ byte[] pic;
+ byte[][] palette = new byte[1][]; //new byte[768];
+
+ // get the palette
+
+ pic = LoadPCX("pics/colormap.pcx", palette, dim = new Dimension());
+
+ if (palette[0] == null || palette[0].length != 768)
+ ri.Sys_Error(Defines.ERR_FATAL, "Couldn't load pics/colormap.pcx");
+
+ byte[] pal = palette[0];
+
+ int j = 0;
+ for (int i = 0; i < 256; i++) {
+ r = pal[j++] & 0xFF;
+ g = pal[j++] & 0xFF;
+ b = pal[j++] & 0xFF;
+
+ d_8to24table[i] = (255 << 24) | (b << 16) | (g << 8) | (r << 0);
+ }
+
+ d_8to24table[255] &= 0x00FFFFFF; // 255 is transparent
+
+ particle_t.setColorPalette(d_8to24table);
+ }
+
+ /*
+ ===============
+ GL_InitImages
+ ===============
+ */
+ void GL_InitImages() {
+ int i, j;
+ float g = vid_gamma.value;
+
+ registration_sequence = 1;
+
+ // init intensity conversions
+ intensity = ri.Cvar_Get("intensity", "2", 0);
+
+ if (intensity.value <= 1)
+ ri.Cvar_Set("intensity", "1");
+
+ gl_state.inverse_intensity = 1 / intensity.value;
+
+ Draw_GetPalette();
+
+ if (qglColorTableEXT) {
+ gl_state.d_16to8table = ri.FS_LoadFile("pics/16to8.dat");
+ if (gl_state.d_16to8table == null)
+ ri.Sys_Error(Defines.ERR_FATAL, "Couldn't load pics/16to8.pcx");
+ }
+
+ if ((gl_config.renderer & (GL_RENDERER_VOODOO | GL_RENDERER_VOODOO2)) != 0) {
+ g = 1.0F;
+ }
+
+ for (i = 0; i < 256; i++) {
+
+ if (g == 1.0f) {
+ gammatable[i] = (byte) i;
+ }
+ else {
+
+ int inf = (int) (255.0f * Math.pow((i + 0.5) / 255.5, g) + 0.5);
+ if (inf < 0)
+ inf = 0;
+ if (inf > 255)
+ inf = 255;
+ gammatable[i] = (byte) inf;
+ }
+ }
+
+ for (i = 0; i < 256; i++) {
+ j = (int) (i * intensity.value);
+ if (j > 255)
+ j = 255;
+ intensitytable[i] = (byte) j;
+ }
+ }
+
+ /*
+ ===============
+ GL_ShutdownImages
+ ===============
+ */
+ void GL_ShutdownImages() {
+ image_t image;
+
+ for (int i=0; i < numgltextures ; i++)
+ {
+ image = gltextures[i];
+
+ if (image.registration_sequence == 0)
+ continue; // free image_t slot
+ // free it
+ // TODO jogl bug
+ gl.glDeleteTextures(1, new int[] {image.texnum});
+ image.clear();
+ }
+ }
+
+}
diff --git a/src/jake2/render/fastjogl/Impl.java b/src/jake2/render/fastjogl/Impl.java
new file mode 100644
index 0000000..03af496
--- /dev/null
+++ b/src/jake2/render/fastjogl/Impl.java
@@ -0,0 +1,343 @@
+/*
+ * Impl.java
+ * Copyright (C) 2003
+ *
+ * $Id: Impl.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.Defines;
+import jake2.Globals;
+import jake2.qcommon.Com;
+import jake2.qcommon.xcommand_t;
+import jake2.sys.KBD;
+
+import java.awt.*;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+
+import net.java.games.jogl.*;
+
+/**
+ * Impl
+ *
+ * @author cwei
+ */
+public class Impl extends Misc implements GLEventListener {
+
+ public static final String DRIVER_NAME = "fastjogl";
+
+ // handles the post initialization with JoglRenderer
+ protected boolean post_init = false;
+
+ private final xcommand_t INIT_CALLBACK = new xcommand_t() {
+ public void execute() {
+ // only used for the first run (initialization)
+ // clear the screen
+ gl.glClearColor(0, 0, 0, 0);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ //
+ // check the post init process
+ //
+ if (!post_init) {
+ ri.Con_Printf(Defines.PRINT_ALL, "Missing multi-texturing for FastJOGL renderer\n");
+ }
+
+ GLimp_EndFrame();
+ }
+ };
+
+ private xcommand_t callback = INIT_CALLBACK;
+ protected boolean contextInUse = false;
+
+ private GraphicsDevice device;
+ private DisplayMode oldDisplayMode;
+
+ GLCanvas canvas;
+ JFrame window;
+
+ // window position on the screen
+ int window_xpos, window_ypos;
+
+ /**
+ * @return true
+ */
+ boolean GLimp_Init(int xpos, int ypos) {
+ // do nothing
+ window_xpos = xpos;
+ window_ypos = ypos;
+ return true;
+ }
+
+ /**
+ * @param dim
+ * @param mode
+ * @param fullscreen
+ * @return enum rserr_t
+ */
+ int GLimp_SetMode(Dimension dim, int mode, boolean fullscreen) {
+
+ Dimension newDim = new Dimension();
+
+ ri.Cvar_Get("r_fakeFullscreen", "0", Globals.CVAR_ARCHIVE);
+
+ ri.Con_Printf(Defines.PRINT_ALL, "Initializing OpenGL display\n");
+
+ ri.Con_Printf(Defines.PRINT_ALL, "...setting mode " + mode + ":");
+
+ if (!ri.Vid_GetModeInfo(newDim, mode)) {
+ ri.Con_Printf(Defines.PRINT_ALL, " invalid mode\n");
+ return rserr_invalid_mode;
+ }
+
+ ri.Con_Printf(Defines.PRINT_ALL, " " + newDim.width + " " + newDim.height + '\n');
+
+ // destroy the existing window
+ GLimp_Shutdown();
+
+ window = new JFrame("Jake2");
+
+ GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
+
+ // TODO Use debug pipeline
+ //canvas.setGL(new DebugGL(canvas.getGL()));
+
+ canvas.setNoAutoRedrawMode(true);
+ canvas.addGLEventListener(this);
+
+ window.getContentPane().add(canvas);
+
+ canvas.setSize(newDim.width, newDim.height);
+
+ // register event listener
+ window.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ ri.Cmd_ExecuteText(Defines.EXEC_APPEND, "quit");
+ }
+ });
+
+ // D I F F E R E N T J A K E 2 E V E N T P R O C E S S I N G
+ window.addComponentListener(KBD.listener);
+ canvas.addKeyListener(KBD.listener);
+ canvas.addMouseListener(KBD.listener);
+ canvas.addMouseMotionListener(KBD.listener);
+
+ /*
+ * fullscreen handling
+ */
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ device = env.getDefaultScreenDevice();
+
+ if (fullscreen && !device.isFullScreenSupported()) {
+ ri.Con_Printf(Defines.PRINT_ALL, "...fullscreen not supported\n");
+ vid_fullscreen.value = 0;
+ vid_fullscreen.modified = false;
+ }
+
+ fullscreen = fullscreen && device.isFullScreenSupported();
+
+ if (oldDisplayMode == null) {
+ oldDisplayMode = device.getDisplayMode();
+ }
+
+ if (fullscreen) {
+
+ DisplayMode displayMode = findDisplayMode(newDim, oldDisplayMode.getBitDepth(), oldDisplayMode.getRefreshRate());
+
+ if (displayMode != null) {
+ newDim.width = displayMode.getWidth();
+ newDim.height = displayMode.getHeight();
+ window.setUndecorated(true);
+ window.setResizable(false);
+ device.setFullScreenWindow(window);
+ device.setDisplayMode(displayMode);
+ window.setLocation(0, 0);
+ window.setSize(displayMode.getWidth(), displayMode.getHeight());
+ canvas.setSize(displayMode.getWidth(), displayMode.getHeight());
+ ri.Con_Printf(Defines.PRINT_ALL, "...setting fullscreen " + getModeString(displayMode) + '\n');
+ }
+ } else {
+ window.setLocation(window_xpos, window_ypos);
+ window.pack();
+ window.setResizable(false);
+ window.setVisible(true);
+ }
+
+ while (!canvas.isDisplayable()) {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {}
+ }
+ canvas.requestFocus();
+
+ this.canvas = canvas;
+
+ vid.width = newDim.width;
+ vid.height = newDim.height;
+
+ // let the sound and input subsystems know about the new window
+ ri.Vid_NewWindow(vid.width, vid.height);
+
+ return rserr_ok;
+ }
+
+ DisplayMode findDisplayMode(Dimension dim, int depth, int rate) {
+ DisplayMode mode = null;
+ DisplayMode m = null;
+ DisplayMode[] modes = device.getDisplayModes();
+ int w = dim.width;
+ int h = dim.height;
+
+ for (int i = 0; i < modes.length; i++) {
+ m = modes[i];
+ if (m.getWidth() == w && m.getHeight() == h && m.getBitDepth() == depth && m.getRefreshRate() == rate) {
+ mode = m;
+ break;
+ }
+ }
+ if (mode == null) mode = oldDisplayMode;
+ Com.Printf(getModeString(mode) + '\n');
+ return mode;
+ }
+
+ String getModeString(DisplayMode m) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(m.getWidth());
+ sb.append('x');
+ sb.append(m.getHeight());
+ sb.append('x');
+ sb.append(m.getBitDepth());
+ sb.append('@');
+ sb.append(m.getRefreshRate());
+ sb.append("Hz");
+ return sb.toString();
+ }
+
+ void GLimp_BeginFrame(float camera_separation) {
+ // do nothing
+ }
+
+ protected void GLimp_EndFrame() {
+ gl.glFlush();
+ // swap buffer
+ // but jogl has no method to swap
+ }
+
+ protected void GLimp_AppActivate(boolean activate) {
+ // do nothing
+ }
+
+ boolean QGL_Init(String dll_name) {
+ // doesn't need libGL.so or .dll loading
+ return true;
+ }
+
+ void QGL_Shutdown() {
+ // doesn't need libGL.so or .dll loading
+ // do nothing
+ }
+
+ void GLimp_Shutdown() {
+ if (oldDisplayMode != null && device.getFullScreenWindow() != null) {
+ try {
+ device.setDisplayMode(oldDisplayMode);
+ device.setFullScreenWindow(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if (this.window != null) {
+ window.dispose();
+ }
+ post_init = false;
+ callback = INIT_CALLBACK;
+ }
+
+ void GLimp_EnableLogging(boolean enable) {
+ // doesn't need jogl logging
+ // do nothing
+ }
+
+ void GLimp_LogNewFrame() {
+ // doesn't need jogl logging
+ // do nothing
+ }
+
+
+
+ // ============================================================================
+ // GLEventListener interface
+ // ============================================================================
+
+ /*
+ * @see net.java.games.jogl.GLEventListener#init(net.java.games.jogl.GLDrawable)
+ */
+ public void init(GLDrawable drawable) {
+ this.gl = drawable.getGL();
+ this.glu = drawable.getGLU();
+
+ // this is a hack to run R_init() in gl context
+ post_init = R_Init2();
+ }
+
+ /*
+ * @see net.java.games.jogl.GLEventListener#display(net.java.games.jogl.GLDrawable)
+ */
+ public void display(GLDrawable drawable) {
+ this.gl = drawable.getGL();
+ this.glu = drawable.getGLU();
+
+ contextInUse = true;
+ callback.execute();
+ contextInUse = false;
+ }
+
+ /*
+ * @see net.java.games.jogl.GLEventListener#displayChanged(net.java.games.jogl.GLDrawable, boolean, boolean)
+ */
+ public void displayChanged(GLDrawable drawable, boolean arg1, boolean arg2) {
+ // do nothing
+ }
+
+ /*
+ * @see net.java.games.jogl.GLEventListener#reshape(net.java.games.jogl.GLDrawable, int, int, int, int)
+ */
+ public void reshape(GLDrawable drawable, int x, int y, int width, int height) {
+ // do nothing
+ }
+
+ /*
+ * @see jake2.client.refexport_t#updateScreen()
+ */
+ public void updateScreen() {
+ this.callback = INIT_CALLBACK;
+ canvas.display();
+ }
+
+ public void updateScreen(xcommand_t callback) {
+ this.callback = callback;
+ canvas.display();
+ }
+} \ No newline at end of file
diff --git a/src/jake2/render/fastjogl/Light.java b/src/jake2/render/fastjogl/Light.java
new file mode 100644
index 0000000..b963b21
--- /dev/null
+++ b/src/jake2/render/fastjogl/Light.java
@@ -0,0 +1,778 @@
+/*
+ * Light.java
+ * Copyright (C) 2003
+ *
+ * $Id: Light.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.Defines;
+import jake2.Globals;
+import jake2.client.dlight_t;
+import jake2.client.lightstyle_t;
+import jake2.game.GameBase;
+import jake2.game.cplane_t;
+import jake2.qcommon.longjmpException;
+import jake2.render.*;
+import jake2.util.Math3D;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.Arrays;
+
+import net.java.games.jogl.GL;
+
+/**
+ * Light
+ *
+ * @author cwei
+ */
+public abstract class Light extends Warp {
+ // r_light.c
+
+ int r_dlightframecount;
+
+ static final int DLIGHT_CUTOFF = 64;
+
+ /*
+ =============================================================================
+
+ DYNAMIC LIGHTS BLEND RENDERING
+
+ =============================================================================
+ */
+
+ void R_RenderDlight (dlight_t light)
+ {
+ int i, j;
+ float a;
+ float[] v = {0, 0, 0};
+ float rad;
+
+ rad = light.intensity * 0.35f;
+
+ Math3D.VectorSubtract (light.origin, r_origin, v);
+
+ gl.glBegin (GL.GL_TRIANGLE_FAN);
+ gl.glColor3f (light.color[0]*0.2f, light.color[1]*0.2f, light.color[2]*0.2f);
+ for (i=0 ; i<3 ; i++)
+ v[i] = light.origin[i] - vpn[i]*rad;
+ gl.glVertex3f(v[0], v[1], v[2]);
+ gl.glColor3f (0,0,0);
+ for (i=16 ; i>=0 ; i--)
+ {
+ a = (float)(i/16.0f * Math.PI*2);
+ for (j=0 ; j<3 ; j++)
+ v[j] = (float)(light.origin[j] + vright[j]*Math.cos(a)*rad
+ + vup[j]*Math.sin(a)*rad);
+ gl.glVertex3f(v[0], v[1], v[2]);
+ }
+ gl.glEnd ();
+ }
+
+ /*
+ =============
+ R_RenderDlights
+ =============
+ */
+ void R_RenderDlights()
+ {
+ if (gl_flashblend.value == 0)
+ return;
+
+ r_dlightframecount = r_framecount + 1; // because the count hasn't
+ // advanced yet for this frame
+ gl.glDepthMask(false);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glShadeModel (GL.GL_SMOOTH);
+ gl.glEnable (GL.GL_BLEND);
+ gl.glBlendFunc (GL.GL_ONE, GL.GL_ONE);
+
+ for (int i=0 ; i<r_newrefdef.num_dlights ; i++)
+ {
+ R_RenderDlight(r_newrefdef.dlights[i]);
+ }
+
+ gl.glColor3f (1,1,1);
+ gl.glDisable(GL.GL_BLEND);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
+ gl.glDepthMask(true);
+ }
+
+
+ /*
+ =============================================================================
+
+ DYNAMIC LIGHTS
+
+ =============================================================================
+ */
+
+ /*
+ =============
+ R_MarkLights
+ =============
+ */
+ void R_MarkLights (dlight_t light, int bit, mnode_t node)
+ {
+ cplane_t splitplane;
+ float dist;
+ msurface_t surf;
+ int i;
+ int sidebit;
+
+ if (node.contents != -1)
+ return;
+
+ splitplane = node.plane;
+ dist = Math3D.DotProduct (light.origin, splitplane.normal) - splitplane.dist;
+
+ if (dist > light.intensity - DLIGHT_CUTOFF)
+ {
+ R_MarkLights (light, bit, node.children[0]);
+ return;
+ }
+ if (dist < -light.intensity + DLIGHT_CUTOFF)
+ {
+ R_MarkLights (light, bit, node.children[1]);
+ return;
+ }
+
+ // mark the polygons
+ for (i=0 ; i<node.numsurfaces ; i++)
+ {
+
+ surf = r_worldmodel.surfaces[node.firstsurface + i];
+
+ /*
+ * cwei
+ * bugfix for dlight behind the walls
+ */
+ dist = Math3D.DotProduct (light.origin, surf.plane.normal) - surf.plane.dist;
+ sidebit = (dist >= 0) ? 0 : Defines.SURF_PLANEBACK;
+ if ( (surf.flags & Defines.SURF_PLANEBACK) != sidebit )
+ continue;
+ /*
+ * cwei
+ * bugfix end
+ */
+
+ if (surf.dlightframe != r_dlightframecount)
+ {
+ surf.dlightbits = 0;
+ surf.dlightframe = r_dlightframecount;
+ }
+ surf.dlightbits |= bit;
+ }
+
+ R_MarkLights (light, bit, node.children[0]);
+ R_MarkLights (light, bit, node.children[1]);
+ }
+
+
+ /*
+ =============
+ R_PushDlights
+ =============
+ */
+ void R_PushDlights()
+ {
+ int i;
+ dlight_t l;
+
+ if (gl_flashblend.value != 0)
+ return;
+
+ r_dlightframecount = r_framecount + 1; // because the count hasn't
+ // advanced yet for this frame
+ for (i=0 ; i<r_newrefdef.num_dlights ; i++) {
+ l = r_newrefdef.dlights[i];
+ R_MarkLights( l, 1<<i, r_worldmodel.nodes[0] );
+ }
+ }
+
+
+ /*
+ =============================================================================
+
+ LIGHT SAMPLING
+
+ =============================================================================
+ */
+
+ float[] pointcolor = {0, 0, 0}; // vec3_t
+ cplane_t lightplane; // used as shadow plane
+ float[] lightspot = {0, 0, 0}; // vec3_t
+
+ int RecursiveLightPoint (mnode_t node, float[] start, float[] end)
+ {
+ float front, back, frac;
+ boolean side;
+ int sideIndex;
+ cplane_t plane;
+ float[] mid = {0, 0, 0};
+ msurface_t surf;
+ int s, t, ds, dt;
+ int i;
+ mtexinfo_t tex;
+ ByteBuffer lightmap;
+ int maps;
+ int r;
+
+ if (node.contents != -1)
+ return -1; // didn't hit anything
+
+ // calculate mid point
+
+ // FIXME: optimize for axial
+ plane = node.plane;
+ front = Math3D.DotProduct (start, plane.normal) - plane.dist;
+ back = Math3D.DotProduct (end, plane.normal) - plane.dist;
+ side = (front < 0);
+ sideIndex = (side) ? 1 : 0;
+
+ if ( (back < 0) == side)
+ return RecursiveLightPoint (node.children[sideIndex], start, end);
+
+ frac = front / (front-back);
+ mid[0] = start[0] + (end[0] - start[0])*frac;
+ mid[1] = start[1] + (end[1] - start[1])*frac;
+ mid[2] = start[2] + (end[2] - start[2])*frac;
+
+ // go down front side
+ r = RecursiveLightPoint (node.children[sideIndex], start, mid);
+ if (r >= 0)
+ return r; // hit something
+
+ if ( (back < 0) == side )
+ return -1; // didn't hit anuthing
+
+ // check for impact on this node
+ Math3D.VectorCopy (mid, lightspot);
+ lightplane = plane;
+
+ int surfIndex = node.firstsurface;
+ for (i=0 ; i<node.numsurfaces ; i++, surfIndex++)
+ {
+ surf = r_worldmodel.surfaces[surfIndex];
+
+ if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0)
+ continue; // no lightmaps
+
+ tex = surf.texinfo;
+
+ s = (int)(Math3D.DotProduct (mid, tex.vecs[0]) + tex.vecs[0][3]);
+ t = (int)(Math3D.DotProduct (mid, tex.vecs[1]) + tex.vecs[1][3]);
+
+ if (s < surf.texturemins[0] || t < surf.texturemins[1])
+ continue;
+
+ ds = s - surf.texturemins[0];
+ dt = t - surf.texturemins[1];
+
+ if ( ds > surf.extents[0] || dt > surf.extents[1] )
+ continue;
+
+ if (surf.samples == null)
+ return 0;
+
+ ds >>= 4;
+ dt >>= 4;
+
+ lightmap = surf.samples;
+ int lightmapIndex = 0;
+
+ Math3D.VectorCopy (Globals.vec3_origin, pointcolor);
+ if (lightmap != null)
+ {
+ float[] scale = {0, 0, 0};
+ float[] rgb;
+ lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds);
+
+ for (maps = 0 ; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255; maps++)
+ {
+ rgb = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb;
+ scale[0] = gl_modulate.value * rgb[0];
+ scale[1] = gl_modulate.value * rgb[1];
+ scale[2] = gl_modulate.value * rgb[2];
+
+ pointcolor[0] += (lightmap.get(lightmapIndex + 0) & 0xFF) * scale[0] * (1.0f/255);
+ pointcolor[1] += (lightmap.get(lightmapIndex + 1) & 0xFF) * scale[1] * (1.0f/255);
+ pointcolor[2] += (lightmap.get(lightmapIndex + 2) & 0xFF) * scale[2] * (1.0f/255);
+ lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1);
+ }
+ }
+ return 1;
+ }
+
+ // go down back side
+ return RecursiveLightPoint (node.children[1 - sideIndex], mid, end);
+ }
+
+ /*
+ ===============
+ R_LightPoint
+ ===============
+ */
+ void R_LightPoint (float[] p, float[] color)
+ {
+ assert (p.length == 3) : "vec3_t bug";
+ assert (color.length == 3) : "rgb bug";
+
+ float[] end = {0, 0, 0};
+ float r;
+ int lnum;
+ dlight_t dl;
+ float light;
+ float[] dist = {0, 0, 0};
+ float add;
+
+ if (r_worldmodel.lightdata == null)
+ {
+ color[0] = color[1] = color[2] = 1.0f;
+ return;
+ }
+
+ end[0] = p[0];
+ end[1] = p[1];
+ end[2] = p[2] - 2048;
+
+ r = RecursiveLightPoint(r_worldmodel.nodes[0], p, end);
+
+ if (r == -1)
+ {
+ Math3D.VectorCopy (GameBase.vec3_origin, color);
+ }
+ else
+ {
+ Math3D.VectorCopy (pointcolor, color);
+ }
+
+ //
+ // add dynamic lights
+ //
+ light = 0;
+ for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
+ {
+ dl = r_newrefdef.dlights[lnum];
+
+ Math3D.VectorSubtract (currententity.origin, dl.origin, dist);
+ add = dl.intensity - Math3D.VectorLength(dist);
+ add *= (1.0f/256);
+ if (add > 0)
+ {
+ Math3D.VectorMA (color, add, dl.color, color);
+ }
+ }
+
+ Math3D.VectorScale (color, gl_modulate.value, color);
+ }
+
+
+// ===================================================================
+
+ float[] s_blocklights = new float[34 * 34 * 3];
+
+ /*
+ ===============
+ R_AddDynamicLights
+ ===============
+ */
+ void R_AddDynamicLights(msurface_t surf)
+ {
+ int lnum;
+ int sd, td;
+ float fdist, frad, fminlight;
+ float[] impact = {0, 0, 0};
+ float[] local = {0, 0, 0};
+ int s, t;
+ int i;
+ int smax, tmax;
+ mtexinfo_t tex;
+ dlight_t dl;
+ float[] pfBL;
+ float fsacc, ftacc;
+
+ smax = (surf.extents[0]>>4)+1;
+ tmax = (surf.extents[1]>>4)+1;
+ tex = surf.texinfo;
+
+ for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
+ {
+ if ( (surf.dlightbits & (1<<lnum)) == 0 )
+ continue; // not lit by this light
+
+ dl = r_newrefdef.dlights[lnum];
+ frad = dl.intensity;
+ fdist = Math3D.DotProduct (dl.origin, surf.plane.normal) -
+ surf.plane.dist;
+ frad -= Math.abs(fdist);
+ // rad is now the highest intensity on the plane
+
+ fminlight = DLIGHT_CUTOFF; // FIXME: make configurable?
+ if (frad < fminlight)
+ continue;
+ fminlight = frad - fminlight;
+
+ for (i=0 ; i<3 ; i++)
+ {
+ impact[i] = dl.origin[i] -
+ surf.plane.normal[i]*fdist;
+ }
+
+ local[0] = Math3D.DotProduct (impact, tex.vecs[0]) + tex.vecs[0][3] - surf.texturemins[0];
+ local[1] = Math3D.DotProduct (impact, tex.vecs[1]) + tex.vecs[1][3] - surf.texturemins[1];
+
+ pfBL = s_blocklights;
+ int pfBLindex = 0;
+ for (t = 0, ftacc = 0 ; t<tmax ; t++, ftacc += 16)
+ {
+ td = (int)(local[1] - ftacc);
+ if ( td < 0 )
+ td = -td;
+
+ for ( s=0, fsacc = 0 ; s<smax ; s++, fsacc += 16, pfBLindex += 3)
+ {
+ sd = (int)( local[0] - fsacc );
+
+ if ( sd < 0 )
+ sd = -sd;
+
+ if (sd > td)
+ fdist = sd + (td>>1);
+ else
+ fdist = td + (sd>>1);
+
+ if ( fdist < fminlight )
+ {
+ pfBL[pfBLindex + 0] += ( frad - fdist ) * dl.color[0];
+ pfBL[pfBLindex + 1] += ( frad - fdist ) * dl.color[1];
+ pfBL[pfBLindex + 2] += ( frad - fdist ) * dl.color[2];
+ }
+ }
+ }
+ }
+ }
+
+
+ /*
+ ** R_SetCacheState
+ */
+ void R_SetCacheState( msurface_t surf )
+ {
+ int maps;
+
+ for (maps = 0 ; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255 ;
+ maps++)
+ {
+ surf.cached_light[maps] = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].white;
+ }
+ }
+
+ /*
+ ===============
+ R_BuildLightMap
+
+ Combine and scale multiple lightmaps into the floating format in blocklights
+ ===============
+ */
+ void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride)
+ {
+ int smax, tmax;
+ int r, g, b, a, max;
+ int i, j, size;
+ ByteBuffer lightmap;
+ float[] scale = {0, 0, 0, 0};
+ int nummaps;
+ float[] bl;
+ lightstyle_t style;
+ int monolightmap;
+
+ if ( (surf.texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) != 0 )
+ ri.Sys_Error(Defines.ERR_DROP, "R_BuildLightMap called for non-lit surface");
+
+ smax = (surf.extents[0] >> 4) + 1;
+ tmax = (surf.extents[1] >> 4) + 1;
+ size = smax * tmax;
+ if (size > ((s_blocklights.length * Defines.SIZE_OF_FLOAT) >> 4) )
+ ri.Sys_Error(Defines.ERR_DROP, "Bad s_blocklights size");
+
+ try {
+ // set to full bright if no light data
+ if (surf.samples == null)
+ {
+ int maps;
+
+ for (i=0 ; i<size*3 ; i++)
+ s_blocklights[i] = 255;
+
+ for (maps = 0 ; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255; maps++)
+ {
+ style = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF];
+ }
+ // goto store;
+ throw new longjmpException();
+ }
+
+ // count the # of maps
+ for ( nummaps = 0 ; nummaps < Defines.MAXLIGHTMAPS && surf.styles[nummaps] != (byte)255 ;
+ nummaps++)
+ ;
+
+ lightmap = surf.samples;
+ int lightmapIndex = 0;
+
+ // add all the lightmaps
+ if ( nummaps == 1 )
+ {
+ int maps;
+
+ for (maps = 0 ; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255 ;
+ maps++)
+ {
+ bl = s_blocklights;
+ int blp = 0;
+
+ for (i=0 ; i<3 ; i++)
+ scale[i] = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[i];
+
+ if ( scale[0] == 1.0F &&
+ scale[1] == 1.0F &&
+ scale[2] == 1.0F )
+ {
+ for (i=0 ; i<size ; i++)
+ {
+ bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF;
+ }
+ }
+ else
+ {
+ for (i=0 ; i<size ; i++)
+ {
+ bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[0];
+ bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[1];
+ bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[2];
+ }
+ }
+ //lightmap += size*3; // skip to next lightmap
+ }
+ }
+ else
+ {
+ int maps;
+
+ // memset( s_blocklights, 0, sizeof( s_blocklights[0] ) * size * 3 );
+
+ Arrays.fill(s_blocklights, 0, size * 3, 0.0f);
+
+ for (maps = 0 ; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255 ;
+ maps++)
+ {
+ bl = s_blocklights;
+ int blp = 0;
+
+ for (i=0 ; i<3 ; i++)
+ scale[i] = gl_modulate.value*r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[i];
+
+ if ( scale[0] == 1.0F &&
+ scale[1] == 1.0F &&
+ scale[2] == 1.0F )
+ {
+ for (i=0 ; i<size ; i++)
+ {
+ bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF;
+ }
+ }
+ else
+ {
+ for (i=0 ; i<size ; i++)
+ {
+ bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[0];
+ bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[1];
+ bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[2];
+ }
+ }
+ //lightmap += size*3; // skip to next lightmap
+ }
+ }
+
+ // add all the dynamic lights
+ if (surf.dlightframe == r_framecount)
+ R_AddDynamicLights(surf);
+
+ // label store:
+ } catch (longjmpException store) {}
+
+ // put into texture format
+ stride -= smax;
+ bl = s_blocklights;
+ int blp = 0;
+
+ monolightmap = gl_monolightmap.string.charAt(0);
+
+ int destp = 0;
+
+ if ( monolightmap == '0' )
+ {
+ for (i=0 ; i<tmax ; i++, destp += stride)
+ {
+ //dest.position(destp);
+
+ for (j=0 ; j<smax ; j++)
+ {
+
+ r = (int)bl[blp++];
+ g = (int)bl[blp++];
+ b = (int)bl[blp++];
+
+ // catch negative lights
+ if (r < 0)
+ r = 0;
+ if (g < 0)
+ g = 0;
+ if (b < 0)
+ b = 0;
+
+ /*
+ ** determine the brightest of the three color components
+ */
+ if (r > g)
+ max = r;
+ else
+ max = g;
+ if (b > max)
+ max = b;
+
+ /*
+ ** alpha is ONLY used for the mono lightmap case. For this reason
+ ** we set it to the brightest of the color components so that
+ ** things don't get too dim.
+ */
+ a = max;
+
+ /*
+ ** rescale all the color components if the intensity of the greatest
+ ** channel exceeds 1.0
+ */
+ if (max > 255)
+ {
+ float t = 255.0F / max;
+
+ r = (int)(r*t);
+ g = (int)(g*t);
+ b = (int)(b*t);
+ a = (int)(a*t);
+ }
+ r &= 0xFF; g &= 0xFF; b &= 0xFF; a &= 0xFF;
+ dest.put(destp++, (a << 24) | (b << 16) | (g << 8) | (r << 0));
+ }
+ }
+ }
+ else
+ {
+ for (i=0 ; i<tmax ; i++, destp += stride)
+ {
+ //dest.position(destp);
+
+ for (j=0 ; j<smax ; j++)
+ {
+
+ r = (int) bl[blp++];
+ g = (int) bl[blp++];
+ b = (int) bl[blp++];
+
+ // catch negative lights
+ if (r < 0)
+ r = 0;
+ if (g < 0)
+ g = 0;
+ if (b < 0)
+ b = 0;
+
+ /*
+ ** determine the brightest of the three color components
+ */
+ if (r > g)
+ max = r;
+ else
+ max = g;
+ if (b > max)
+ max = b;
+
+ /*
+ ** alpha is ONLY used for the mono lightmap case. For this reason
+ ** we set it to the brightest of the color components so that
+ ** things don't get too dim.
+ */
+ a = max;
+
+ /*
+ ** rescale all the color components if the intensity of the greatest
+ ** channel exceeds 1.0
+ */
+ if (max > 255)
+ {
+ float t = 255.0F / max;
+
+ r = (int)(r*t);
+ g = (int)(g*t);
+ b = (int)(b*t);
+ a = (int)(a*t);
+ }
+
+ /*
+ ** So if we are doing alpha lightmaps we need to set the R, G, and B
+ ** components to 0 and we need to set alpha to 1-alpha.
+ */
+ switch ( monolightmap )
+ {
+ case 'L':
+ case 'I':
+ r = a;
+ g = b = 0;
+ break;
+ case 'C':
+ // try faking colored lighting
+ a = 255 - ((r+g+b)/3);
+ r *= a/255.0f;
+ g *= a/255.0f;
+ b *= a/255.0f;
+ break;
+ case 'A':
+ default:
+ r = g = b = 0;
+ a = 255 - a;
+ break;
+ }
+ r &= 0xFF; g &= 0xFF; b &= 0xFF; a &= 0xFF;
+ dest.put(destp++, (a << 24) | (b << 16) | (g << 8) | (r << 0));
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/jake2/render/fastjogl/Main.java b/src/jake2/render/fastjogl/Main.java
new file mode 100644
index 0000000..2363db4
--- /dev/null
+++ b/src/jake2/render/fastjogl/Main.java
@@ -0,0 +1,1592 @@
+/*
+ * Main.java
+ * Copyright (C) 2003
+ *
+ * $Id: Main.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.*;
+import jake2.client.*;
+import jake2.game.cplane_t;
+import jake2.game.cvar_t;
+import jake2.qcommon.qfiles;
+import jake2.qcommon.xcommand_t;
+import jake2.render.*;
+import jake2.util.Math3D;
+import jake2.util.Vargs;
+
+import java.awt.Dimension;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import net.java.games.jogl.GL;
+import net.java.games.jogl.GLU;
+import net.java.games.jogl.util.BufferUtils;
+import net.java.games.jogl.util.GLUT;
+
+/**
+ * Main
+ *
+ * @author cwei
+ */
+public abstract class Main extends Base {
+
+ GL gl;
+ GLU glu;
+ GLUT glut = new GLUT();
+
+ public static int[] d_8to24table = new int[256];
+
+ int c_visible_lightmaps;
+ int c_visible_textures;
+
+ int registration_sequence;
+
+ // this a hack for function pointer test
+ // default disabled
+ boolean qglColorTableEXT = false;
+ boolean qglActiveTextureARB = false;
+ boolean qglPointParameterfEXT = false;
+ boolean qglLockArraysEXT = false;
+ boolean qwglSwapIntervalEXT = false;
+
+ // =================
+ // abstract methods
+ // =================
+ protected abstract void Draw_GetPalette();
+
+ abstract void GL_ImageList_f();
+ abstract void GL_ScreenShot_f();
+ abstract void GL_SetTexturePalette(int[] palette);
+ abstract void GL_Strings_f();
+
+ abstract void Mod_Modellist_f();
+ abstract mleaf_t Mod_PointInLeaf(float[] point, model_t model);
+
+ abstract boolean QGL_Init(String dll_name);
+ abstract void QGL_Shutdown();
+ abstract boolean GLimp_Init(int xpos, int ypos);
+ abstract void GLimp_BeginFrame(float camera_separation);
+ abstract int GLimp_SetMode(Dimension dim, int mode, boolean fullscreen);
+ abstract void GLimp_Shutdown();
+ abstract void GLimp_EnableLogging(boolean enable);
+ abstract void GLimp_LogNewFrame();
+
+ abstract void GL_SetDefaultState();
+
+ abstract void GL_InitImages();
+ abstract void Mod_Init(); // Model.java
+ abstract void R_InitParticleTexture(); // MIsc.java
+ abstract void R_DrawAliasModel(entity_t e); // Mesh.java
+ abstract void R_DrawBrushModel(entity_t e); // Surf.java
+ abstract void Draw_InitLocal();
+ abstract void R_LightPoint(float[] p, float[] color);
+ abstract void R_PushDlights();
+ abstract void R_MarkLeaves();
+ abstract void R_DrawWorld();
+ abstract void R_RenderDlights();
+ abstract void R_DrawAlphaSurfaces();
+
+ abstract void Mod_FreeAll();
+
+ abstract void GL_ShutdownImages();
+ abstract void GL_Bind(int texnum);
+ abstract void GL_TexEnv(int mode);
+ abstract void GL_TextureMode(String string);
+ abstract void GL_TextureAlphaMode(String string);
+ abstract void GL_TextureSolidMode(String string);
+ abstract void GL_UpdateSwapInterval();
+
+ /*
+ ====================================================================
+
+ from gl_rmain.c
+
+ ====================================================================
+ */
+
+ // IMPORTED FUNCTIONS
+ protected refimport_t ri = null;
+
+ int GL_TEXTURE0 = GL.GL_TEXTURE0;
+ int GL_TEXTURE1 = GL.GL_TEXTURE1;
+
+ viddef_t vid = new viddef_t();
+
+ model_t r_worldmodel;
+
+ float gldepthmin, gldepthmax;
+
+ glconfig_t gl_config = new glconfig_t();
+ glstate_t gl_state = new glstate_t();
+
+ image_t r_notexture; // use for bad textures
+ image_t r_particletexture; // little dot for particles
+
+ entity_t currententity;
+ model_t currentmodel;
+
+ cplane_t frustum[] = { new cplane_t(), new cplane_t(), new cplane_t(), new cplane_t()};
+
+ int r_visframecount; // bumped when going to a new PVS
+ int r_framecount; // used for dlight push checking
+
+ int c_brush_polys, c_alias_polys;
+
+ float v_blend[] = { 0, 0, 0, 0 }; // final blending color
+
+ //
+ // view origin
+ //
+ float[] vup = { 0, 0, 0 };
+ float[] vpn = { 0, 0, 0 };
+ float[] vright = { 0, 0, 0 };
+ float[] r_origin = { 0, 0, 0 };
+
+ float r_world_matrix[] = new float[16];
+ float r_base_world_matrix[] = new float[16];
+
+ //
+ // screen size info
+ //
+ refdef_t r_newrefdef = new refdef_t();
+
+ int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
+
+ cvar_t r_norefresh;
+ cvar_t r_drawentities;
+ cvar_t r_drawworld;
+ cvar_t r_speeds;
+ cvar_t r_fullbright;
+ cvar_t r_novis;
+ cvar_t r_nocull;
+ cvar_t r_lerpmodels;
+ cvar_t r_lefthand;
+
+ cvar_t r_lightlevel;
+ // FIXME: This is a HACK to get the client's light level
+
+ cvar_t gl_nosubimage;
+ cvar_t gl_allow_software;
+
+ cvar_t gl_vertex_arrays;
+
+ cvar_t gl_particle_min_size;
+ cvar_t gl_particle_max_size;
+ cvar_t gl_particle_size;
+ cvar_t gl_particle_att_a;
+ cvar_t gl_particle_att_b;
+ cvar_t gl_particle_att_c;
+
+ cvar_t gl_ext_swapinterval;
+ cvar_t gl_ext_palettedtexture;
+ cvar_t gl_ext_multitexture;
+ cvar_t gl_ext_pointparameters;
+ cvar_t gl_ext_compiled_vertex_array;
+
+ cvar_t gl_log;
+ cvar_t gl_bitdepth;
+ cvar_t gl_drawbuffer;
+ cvar_t gl_driver;
+ cvar_t gl_lightmap;
+ cvar_t gl_shadows;
+ cvar_t gl_mode;
+ cvar_t gl_dynamic;
+ cvar_t gl_monolightmap;
+ cvar_t gl_modulate;
+ cvar_t gl_nobind;
+ cvar_t gl_round_down;
+ cvar_t gl_picmip;
+ cvar_t gl_skymip;
+ cvar_t gl_showtris;
+ cvar_t gl_ztrick;
+ cvar_t gl_finish;
+ cvar_t gl_clear;
+ cvar_t gl_cull;
+ cvar_t gl_polyblend;
+ cvar_t gl_flashblend;
+ cvar_t gl_playermip;
+ cvar_t gl_saturatelighting;
+ cvar_t gl_swapinterval;
+ cvar_t gl_texturemode;
+ cvar_t gl_texturealphamode;
+ cvar_t gl_texturesolidmode;
+ cvar_t gl_lockpvs;
+
+ cvar_t gl_3dlabs_broken;
+
+ cvar_t vid_fullscreen;
+ cvar_t vid_gamma;
+ cvar_t vid_ref;
+
+ // ============================================================================
+ // to port from gl_rmain.c, ...
+ // ============================================================================
+
+ /*
+ =================
+ R_CullBox
+
+ Returns true if the box is completely outside the frustom
+ =================
+ */
+ final boolean R_CullBox(float[] mins, float[] maxs) {
+ assert(mins.length == 3 && maxs.length == 3) : "vec3_t bug";
+
+ if (r_nocull.value != 0)
+ return false;
+
+ for (int i = 0; i < 4; i++) {
+ if (Math3D.BoxOnPlaneSide(mins, maxs, frustum[i]) == 2)
+ return true;
+ }
+ return false;
+ }
+
+ final void R_RotateForEntity(entity_t e) {
+
+ gl.glTranslatef(e.origin[0], e.origin[1], e.origin[2]);
+
+ gl.glRotatef(e.angles[1], 0, 0, 1);
+ gl.glRotatef(-e.angles[0], 0, 1, 0);
+ gl.glRotatef(-e.angles[2], 1, 0, 0);
+ }
+
+ /*
+ =============================================================
+
+ SPRITE MODELS
+
+ =============================================================
+ */
+
+ /*
+ =================
+ R_DrawSpriteModel
+
+ =================
+ */
+ void R_DrawSpriteModel(entity_t e) {
+ float alpha = 1.0F;
+ float[] point = { 0, 0, 0 };
+
+ qfiles.dsprframe_t frame;
+ qfiles.dsprite_t psprite;
+
+ // don't even bother culling, because it's just a single
+ // polygon without a surface cache
+
+ psprite = (qfiles.dsprite_t) currentmodel.extradata;
+
+ e.frame %= psprite.numframes;
+
+ frame = psprite.frames[e.frame];
+
+ if ((e.flags & Defines.RF_TRANSLUCENT) != 0)
+ alpha = e.alpha;
+
+ if (alpha != 1.0F)
+ gl.glEnable(GL.GL_BLEND);
+
+ gl.glColor4f(1, 1, 1, alpha);
+
+ GL_Bind(currentmodel.skins[e.frame].texnum);
+
+ GL_TexEnv(GL.GL_MODULATE);
+
+ if (alpha == 1.0)
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ else
+ gl.glDisable(GL.GL_ALPHA_TEST);
+
+ gl.glBegin(GL.GL_QUADS);
+
+ gl.glTexCoord2f(0, 1);
+ Math3D.VectorMA(e.origin, -frame.origin_y, vup, point);
+ Math3D.VectorMA(point, -frame.origin_x, vright, point);
+ gl.glVertex3f(point[0], point[1], point[2]);
+
+ gl.glTexCoord2f(0, 0);
+ Math3D.VectorMA(e.origin, frame.height - frame.origin_y, vup, point);
+ Math3D.VectorMA(point, -frame.origin_x, vright, point);
+ gl.glVertex3f(point[0], point[1], point[2]);
+
+ gl.glTexCoord2f(1, 0);
+ Math3D.VectorMA(e.origin, frame.height - frame.origin_y, vup, point);
+ Math3D.VectorMA(point, frame.width - frame.origin_x, vright, point);
+ gl.glVertex3f(point[0], point[1], point[2]);
+
+ gl.glTexCoord2f(1, 1);
+ Math3D.VectorMA(e.origin, -frame.origin_y, vup, point);
+ Math3D.VectorMA(point, frame.width - frame.origin_x, vright, point);
+ gl.glVertex3f(point[0], point[1], point[2]);
+
+ gl.glEnd();
+
+ gl.glDisable(GL.GL_ALPHA_TEST);
+ GL_TexEnv(GL.GL_REPLACE);
+
+ if (alpha != 1.0F)
+ gl.glDisable(GL.GL_BLEND);
+
+ gl.glColor4f(1, 1, 1, 1);
+ }
+
+ // ==================================================================================
+
+ /*
+ =============
+ R_DrawNullModel
+ =============
+ cwei :-)
+ */
+ void R_DrawNullModel() {
+ float[] shadelight = { 0, 0, 0 };
+
+ if ((currententity.flags & Defines.RF_FULLBRIGHT) != 0) {
+ // cwei wollte blau: shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
+ shadelight[0] = shadelight[1] = shadelight[2] = 0.0F;
+ shadelight[2] = 0.8F;
+ }
+ else {
+ R_LightPoint(currententity.origin, shadelight);
+ }
+
+ gl.glPushMatrix();
+ R_RotateForEntity(currententity);
+
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glColor3f(shadelight[0], shadelight[1], shadelight[2]);
+
+ // this replaces the TRIANGLE_FAN
+ glut.glutWireCube(gl, 20);
+
+ /*
+ gl.glBegin(GL.GL_TRIANGLE_FAN);
+ gl.glVertex3f(0, 0, -16);
+ int i;
+ for (i=0 ; i<=4 ; i++) {
+ gl.glVertex3f((float)(16.0f * Math.cos(i * Math.PI / 2)), (float)(16.0f * Math.sin(i * Math.PI / 2)), 0.0f);
+ }
+ gl.glEnd();
+
+ gl.glBegin(GL.GL_TRIANGLE_FAN);
+ gl.glVertex3f (0, 0, 16);
+ for (i=4 ; i>=0 ; i--) {
+ gl.glVertex3f((float)(16.0f * Math.cos(i * Math.PI / 2)), (float)(16.0f * Math.sin(i * Math.PI / 2)), 0.0f);
+ }
+ gl.glEnd();
+ */
+ gl.glColor3f(1, 1, 1);
+ gl.glPopMatrix();
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ }
+
+ /*
+ =============
+ R_DrawEntitiesOnList
+ =============
+ */
+ void R_DrawEntitiesOnList() {
+ int i;
+
+ if (r_drawentities.value == 0.0f)
+ return;
+
+ // draw non-transparent first
+ for (i = 0; i < r_newrefdef.num_entities; i++) {
+ currententity = r_newrefdef.entities[i];
+ if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0)
+ continue; // solid
+
+ if ((currententity.flags & Defines.RF_BEAM) != 0) {
+ R_DrawBeam(currententity);
+ }
+ else {
+ currentmodel = currententity.model;
+ if (currentmodel == null) {
+ R_DrawNullModel();
+ continue;
+ }
+ switch (currentmodel.type) {
+ case mod_alias :
+ R_DrawAliasModel(currententity);
+ break;
+ case mod_brush :
+ R_DrawBrushModel(currententity);
+ break;
+ case mod_sprite :
+ R_DrawSpriteModel(currententity);
+ break;
+ default :
+ ri.Sys_Error(Defines.ERR_DROP, "Bad modeltype");
+ break;
+ }
+ }
+ }
+ // draw transparent entities
+ // we could sort these if it ever becomes a problem...
+ gl.glDepthMask(false); // no z writes
+ for (i = 0; i < r_newrefdef.num_entities; i++) {
+ currententity = r_newrefdef.entities[i];
+ if ((currententity.flags & Defines.RF_TRANSLUCENT) == 0)
+ continue; // solid
+
+ if ((currententity.flags & Defines.RF_BEAM) != 0) {
+ R_DrawBeam(currententity);
+ }
+ else {
+ currentmodel = currententity.model;
+
+ if (currentmodel == null) {
+ R_DrawNullModel();
+ continue;
+ }
+ switch (currentmodel.type) {
+ case mod_alias :
+ R_DrawAliasModel(currententity);
+ break;
+ case mod_brush :
+ R_DrawBrushModel(currententity);
+ break;
+ case mod_sprite :
+ R_DrawSpriteModel(currententity);
+ break;
+ default :
+ ri.Sys_Error(Defines.ERR_DROP, "Bad modeltype");
+ break;
+ }
+ }
+ }
+ gl.glDepthMask(true); // back to writing
+ }
+
+ /*
+ ** GL_DrawParticles
+ **
+ */
+ void GL_DrawParticles(int num_particles) {
+ float[] up = { 0, 0, 0 };
+ float[] right = { 0, 0, 0 };
+ float scale;
+ int color;
+
+ float origin_x, origin_y, origin_z;
+
+ Math3D.VectorScale(vup, 1.5f, up);
+ Math3D.VectorScale(vright, 1.5f, right);
+
+ GL_Bind(r_particletexture.texnum);
+ gl.glDepthMask(false); // no z buffering
+ gl.glEnable(GL.GL_BLEND);
+ GL_TexEnv(GL.GL_MODULATE);
+
+ gl.glBegin(GL.GL_TRIANGLES);
+
+ FloatBuffer sourceVertices = particle_t.vertexArray;
+ IntBuffer sourceColors = particle_t.colorArray;
+ for (int j = 0, i = 0; i < num_particles; i++) {
+ origin_x = sourceVertices.get(j++);
+ origin_y = sourceVertices.get(j++);
+ origin_z = sourceVertices.get(j++);
+
+ // hack a scale up to keep particles from disapearing
+ scale =
+ (origin_x - r_origin[0]) * vpn[0]
+ + (origin_y - r_origin[1]) * vpn[1]
+ + (origin_z - r_origin[2]) * vpn[2];
+
+ scale = (scale < 20) ? 1 : 1 + scale * 0.004f;
+
+ color = sourceColors.get(i);
+ gl.glColor4ub(
+ (byte)((color >> 0) & 0xFF),
+ (byte)((color >> 8) & 0xFF),
+ (byte)((color >> 16) & 0xFF),
+ (byte)((color >> 24) & 0xFF)
+ );
+ // first vertex
+ gl.glTexCoord2f(0.0625f, 0.0625f);
+ gl.glVertex3f(origin_x, origin_y, origin_z);
+ // second vertex
+ gl.glTexCoord2f(1.0625f, 0.0625f);
+ gl.glVertex3f(origin_x + up[0] * scale, origin_y + up[1] * scale, origin_z + up[2] * scale);
+ // third vertex
+ gl.glTexCoord2f(0.0625f, 1.0625f);
+ gl.glVertex3f(origin_x + right[0] * scale, origin_y + right[1] * scale, origin_z + right[2] * scale);
+ }
+ gl.glEnd();
+
+ gl.glDisable(GL.GL_BLEND);
+ gl.glColor4f(1, 1, 1, 1);
+ gl.glDepthMask(true); // back to normal Z buffering
+ GL_TexEnv(GL.GL_REPLACE);
+ }
+
+ /*
+ ===============
+ R_DrawParticles
+ ===============
+ */
+ void R_DrawParticles() {
+
+ if (gl_ext_pointparameters.value != 0.0f && qglPointParameterfEXT) {
+
+ //gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, particle_t.vertexArray);
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ gl.glColorPointer(4, GL.GL_UNSIGNED_BYTE, 0, particle_t.colorArray);
+
+ gl.glDepthMask(false);
+ gl.glEnable(GL.GL_BLEND);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glPointSize(gl_particle_size.value);
+
+ gl.glDrawArrays(GL.GL_POINTS, 0, r_newrefdef.num_particles);
+
+ gl.glDisableClientState(GL.GL_COLOR_ARRAY);
+ //gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
+
+ gl.glDisable(GL.GL_BLEND);
+ gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+ gl.glDepthMask(true);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+
+ }
+ else {
+ GL_DrawParticles(r_newrefdef.num_particles);
+ }
+ }
+
+ /*
+ ============
+ R_PolyBlend
+ ============
+ */
+ void R_PolyBlend() {
+ if (gl_polyblend.value == 0.0f)
+ return;
+
+ if (v_blend[3] == 0.0f)
+ return;
+
+ gl.glDisable(GL.GL_ALPHA_TEST);
+ gl.glEnable(GL.GL_BLEND);
+ gl.glDisable(GL.GL_DEPTH_TEST);
+ gl.glDisable(GL.GL_TEXTURE_2D);
+
+ gl.glLoadIdentity();
+
+ // FIXME: get rid of these
+ gl.glRotatef(-90, 1, 0, 0); // put Z going up
+ gl.glRotatef(90, 0, 0, 1); // put Z going up
+
+ gl.glColor4f(v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
+
+ gl.glBegin(GL.GL_QUADS);
+
+ gl.glVertex3f(10, 100, 100);
+ gl.glVertex3f(10, -100, 100);
+ gl.glVertex3f(10, -100, -100);
+ gl.glVertex3f(10, 100, -100);
+ gl.glEnd();
+
+ gl.glDisable(GL.GL_BLEND);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glEnable(GL.GL_ALPHA_TEST);
+
+ gl.glColor4f(1, 1, 1, 1);
+ }
+
+ // =======================================================================
+
+ int SignbitsForPlane(cplane_t out) {
+ // for fast box on planeside test
+ int bits = 0;
+ for (int j = 0; j < 3; j++) {
+ if (out.normal[j] < 0)
+ bits |= (1 << j);
+ }
+ return bits;
+ }
+
+ void R_SetFrustum() {
+ // rotate VPN right by FOV_X/2 degrees
+ Math3D.RotatePointAroundVector(frustum[0].normal, vup, vpn, - (90f - r_newrefdef.fov_x / 2f));
+ // rotate VPN left by FOV_X/2 degrees
+ Math3D.RotatePointAroundVector(frustum[1].normal, vup, vpn, 90f - r_newrefdef.fov_x / 2f);
+ // rotate VPN up by FOV_X/2 degrees
+ Math3D.RotatePointAroundVector(frustum[2].normal, vright, vpn, 90f - r_newrefdef.fov_y / 2f);
+ // rotate VPN down by FOV_X/2 degrees
+ Math3D.RotatePointAroundVector(frustum[3].normal, vright, vpn, - (90f - r_newrefdef.fov_y / 2f));
+
+ for (int i = 0; i < 4; i++) {
+ frustum[i].type = Defines.PLANE_ANYZ;
+ frustum[i].dist = Math3D.DotProduct(r_origin, frustum[i].normal);
+ frustum[i].signbits = (byte) SignbitsForPlane(frustum[i]);
+ }
+ }
+
+ // =======================================================================
+
+ /*
+ ===============
+ R_SetupFrame
+ ===============
+ */
+ void R_SetupFrame() {
+ int i;
+ mleaf_t leaf;
+
+ r_framecount++;
+
+ // build the transformation matrix for the given view angles
+ Math3D.VectorCopy(r_newrefdef.vieworg, r_origin);
+
+ Math3D.AngleVectors(r_newrefdef.viewangles, vpn, vright, vup);
+
+ // current viewcluster
+ if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) == 0) {
+ r_oldviewcluster = r_viewcluster;
+ r_oldviewcluster2 = r_viewcluster2;
+ leaf = Mod_PointInLeaf(r_origin, r_worldmodel);
+ r_viewcluster = r_viewcluster2 = leaf.cluster;
+
+ // check above and below so crossing solid water doesn't draw wrong
+ if (leaf.contents == 0) { // look down a bit
+ float[] temp = { 0, 0, 0 };
+
+ Math3D.VectorCopy(r_origin, temp);
+ temp[2] -= 16;
+ leaf = Mod_PointInLeaf(temp, r_worldmodel);
+ if ((leaf.contents & Defines.CONTENTS_SOLID) == 0 && (leaf.cluster != r_viewcluster2))
+ r_viewcluster2 = leaf.cluster;
+ }
+ else { // look up a bit
+ float[] temp = { 0, 0, 0 };
+
+ Math3D.VectorCopy(r_origin, temp);
+ temp[2] += 16;
+ leaf = Mod_PointInLeaf(temp, r_worldmodel);
+ if ((leaf.contents & Defines.CONTENTS_SOLID) == 0 && (leaf.cluster != r_viewcluster2))
+ r_viewcluster2 = leaf.cluster;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ v_blend[i] = r_newrefdef.blend[i];
+
+ c_brush_polys = 0;
+ c_alias_polys = 0;
+
+ // clear out the portion of the screen that the NOWORLDMODEL defines
+ if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0) {
+ gl.glEnable(GL.GL_SCISSOR_TEST);
+ gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
+ gl.glScissor(
+ r_newrefdef.x,
+ vid.height - r_newrefdef.height - r_newrefdef.y,
+ r_newrefdef.width,
+ r_newrefdef.height);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ gl.glClearColor(1.0f, 0.0f, 0.5f, 0.5f);
+ gl.glDisable(GL.GL_SCISSOR_TEST);
+ }
+ }
+
+ void MYgluPerspective(double fovy, double aspect, double zNear, double zFar) {
+ double xmin, xmax, ymin, ymax;
+
+ ymax = zNear * Math.tan(fovy * Math.PI / 360.0);
+ ymin = -ymax;
+
+ xmin = ymin * aspect;
+ xmax = ymax * aspect;
+
+ xmin += - (2 * gl_state.camera_separation) / zNear;
+ xmax += - (2 * gl_state.camera_separation) / zNear;
+
+ gl.glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
+ }
+
+ /*
+ =============
+ R_SetupGL
+ =============
+ */
+ void R_SetupGL() {
+ float screenaspect;
+ int x, x2, y2, y, w, h;
+
+ //
+ // set up viewport
+ //
+ x = (int) Math.floor(r_newrefdef.x * vid.width / vid.width);
+ x2 = (int) Math.ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
+ y = (int) Math.floor(vid.height - r_newrefdef.y * vid.height / vid.height);
+ y2 = (int) Math.ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
+
+ w = x2 - x;
+ h = y - y2;
+
+ gl.glViewport(x, y2, w, h);
+
+ //
+ // set up projection matrix
+ //
+ screenaspect = (float) r_newrefdef.width / r_newrefdef.height;
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+ MYgluPerspective(r_newrefdef.fov_y, screenaspect, 4, 4096);
+
+ gl.glCullFace(GL.GL_FRONT);
+
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+
+ gl.glRotatef(-90, 1, 0, 0); // put Z going up
+ gl.glRotatef(90, 0, 0, 1); // put Z going up
+ gl.glRotatef(-r_newrefdef.viewangles[2], 1, 0, 0);
+ gl.glRotatef(-r_newrefdef.viewangles[0], 0, 1, 0);
+ gl.glRotatef(-r_newrefdef.viewangles[1], 0, 0, 1);
+ gl.glTranslatef(-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
+
+ gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, r_world_matrix);
+
+ //
+ // set drawing parms
+ //
+ if (gl_cull.value != 0.0f)
+ gl.glEnable(GL.GL_CULL_FACE);
+ else
+ gl.glDisable(GL.GL_CULL_FACE);
+
+ gl.glDisable(GL.GL_BLEND);
+ gl.glDisable(GL.GL_ALPHA_TEST);
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ }
+
+ /*
+ =============
+ R_Clear
+ =============
+ */
+ int trickframe = 0;
+
+ void R_Clear() {
+ if (gl_ztrick.value != 0.0f) {
+
+ if (gl_clear.value != 0.0f) {
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
+ }
+
+ trickframe++;
+ if ((trickframe & 1) != 0) {
+ gldepthmin = 0;
+ gldepthmax = 0.49999f;
+ gl.glDepthFunc(GL.GL_LEQUAL);
+ }
+ else {
+ gldepthmin = 1;
+ gldepthmax = 0.5f;
+ gl.glDepthFunc(GL.GL_GEQUAL);
+ }
+ }
+ else {
+ if (gl_clear.value != 0.0f)
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ else
+ gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
+
+ gldepthmin = 0;
+ gldepthmax = 1;
+ gl.glDepthFunc(GL.GL_LEQUAL);
+ }
+ gl.glDepthRange(gldepthmin, gldepthmax);
+ }
+
+ void R_Flash() {
+ R_PolyBlend();
+ }
+
+ /*
+ ================
+ R_RenderView
+
+ r_newrefdef must be set before the first call
+ ================
+ */
+ void R_RenderView(refdef_t fd) {
+
+ if (r_norefresh.value != 0.0f)
+ return;
+
+ r_newrefdef = fd;
+
+ // included by cwei
+ if (r_newrefdef == null) {
+ ri.Sys_Error(Defines.ERR_DROP, "R_RenderView: refdef_t fd is null");
+ }
+
+ if (r_worldmodel == null && (r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) == 0)
+ ri.Sys_Error(Defines.ERR_DROP, "R_RenderView: NULL worldmodel");
+
+ if (r_speeds.value != 0.0f) {
+ c_brush_polys = 0;
+ c_alias_polys = 0;
+ }
+
+ R_PushDlights();
+
+ if (gl_finish.value != 0.0f)
+ gl.glFinish();
+
+ R_SetupFrame();
+
+ R_SetFrustum();
+
+ R_SetupGL();
+
+ R_MarkLeaves(); // done here so we know if we're in water
+
+ R_DrawWorld();
+
+ R_DrawEntitiesOnList();
+
+ R_RenderDlights();
+
+ R_DrawParticles();
+
+ R_DrawAlphaSurfaces();
+
+ R_Flash();
+
+ if (r_speeds.value != 0.0f) {
+ ri.Con_Printf(
+ Defines.PRINT_ALL,
+ "%4i wpoly %4i epoly %i tex %i lmaps\n",
+ new Vargs(4).add(c_brush_polys).add(c_alias_polys).add(c_visible_textures).add(c_visible_lightmaps));
+ }
+ }
+
+ void R_SetGL2D() {
+ // set 2D virtual screen size
+ gl.glViewport(0, 0, vid.width, vid.height);
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(0, vid.width, vid.height, 0, -99999, 99999);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glDisable(GL.GL_DEPTH_TEST);
+ gl.glDisable(GL.GL_CULL_FACE);
+ gl.glDisable(GL.GL_BLEND);
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ gl.glColor4f(1, 1, 1, 1);
+ }
+
+ /*
+ ====================
+ R_SetLightLevel
+
+ ====================
+ */
+ void R_SetLightLevel() {
+ float[] shadelight = { 0, 0, 0 };
+
+ if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0)
+ return;
+
+ // save off light value for server to look at (BIG HACK!)
+
+ R_LightPoint(r_newrefdef.vieworg, shadelight);
+
+ // pick the greatest component, which should be the same
+ // as the mono value returned by software
+ if (shadelight[0] > shadelight[1]) {
+ if (shadelight[0] > shadelight[2])
+ r_lightlevel.value = 150 * shadelight[0];
+ else
+ r_lightlevel.value = 150 * shadelight[2];
+ }
+ else {
+ if (shadelight[1] > shadelight[2])
+ r_lightlevel.value = 150 * shadelight[1];
+ else
+ r_lightlevel.value = 150 * shadelight[2];
+ }
+ }
+
+ /*
+ @@@@@@@@@@@@@@@@@@@@@
+ R_RenderFrame
+
+ @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected void R_RenderFrame(refdef_t fd) {
+ R_RenderView(fd);
+ R_SetLightLevel();
+ R_SetGL2D();
+ }
+
+ protected void R_Register() {
+ r_lefthand = ri.Cvar_Get("hand", "0", Globals.CVAR_USERINFO | Globals.CVAR_ARCHIVE);
+ r_norefresh = ri.Cvar_Get("r_norefresh", "0", 0);
+ r_fullbright = ri.Cvar_Get("r_fullbright", "0", 0);
+ r_drawentities = ri.Cvar_Get("r_drawentities", "1", 0);
+ r_drawworld = ri.Cvar_Get("r_drawworld", "1", 0);
+ r_novis = ri.Cvar_Get("r_novis", "0", 0);
+ r_nocull = ri.Cvar_Get("r_nocull", "0", 0);
+ r_lerpmodels = ri.Cvar_Get("r_lerpmodels", "1", 0);
+ r_speeds = ri.Cvar_Get("r_speeds", "0", 0);
+
+ r_lightlevel = ri.Cvar_Get("r_lightlevel", "1", 0);
+
+ gl_nosubimage = ri.Cvar_Get("gl_nosubimage", "0", 0);
+ gl_allow_software = ri.Cvar_Get("gl_allow_software", "0", 0);
+
+ gl_particle_min_size = ri.Cvar_Get("gl_particle_min_size", "2", Globals.CVAR_ARCHIVE);
+ gl_particle_max_size = ri.Cvar_Get("gl_particle_max_size", "40", Globals.CVAR_ARCHIVE);
+ gl_particle_size = ri.Cvar_Get("gl_particle_size", "40", Globals.CVAR_ARCHIVE);
+ gl_particle_att_a = ri.Cvar_Get("gl_particle_att_a", "0.01", Globals.CVAR_ARCHIVE);
+ gl_particle_att_b = ri.Cvar_Get("gl_particle_att_b", "0.0", Globals.CVAR_ARCHIVE);
+ gl_particle_att_c = ri.Cvar_Get("gl_particle_att_c", "0.01", Globals.CVAR_ARCHIVE);
+
+ gl_modulate = ri.Cvar_Get("gl_modulate", "1", Globals.CVAR_ARCHIVE);
+ gl_log = ri.Cvar_Get("gl_log", "0", 0);
+ gl_bitdepth = ri.Cvar_Get("gl_bitdepth", "0", 0);
+ gl_mode = ri.Cvar_Get("gl_mode", "3", Globals.CVAR_ARCHIVE); // 640x480
+ gl_lightmap = ri.Cvar_Get("gl_lightmap", "0", 0);
+ gl_shadows = ri.Cvar_Get("gl_shadows", "0", Globals.CVAR_ARCHIVE);
+ gl_dynamic = ri.Cvar_Get("gl_dynamic", "1", 0);
+ gl_nobind = ri.Cvar_Get("gl_nobind", "0", 0);
+ gl_round_down = ri.Cvar_Get("gl_round_down", "1", 0);
+ gl_picmip = ri.Cvar_Get("gl_picmip", "0", 0);
+ gl_skymip = ri.Cvar_Get("gl_skymip", "0", 0);
+ gl_showtris = ri.Cvar_Get("gl_showtris", "0", 0);
+ gl_ztrick = ri.Cvar_Get("gl_ztrick", "0", 0);
+ gl_finish = ri.Cvar_Get("gl_finish", "0", Globals.CVAR_ARCHIVE);
+ gl_clear = ri.Cvar_Get("gl_clear", "0", 0);
+ gl_cull = ri.Cvar_Get("gl_cull", "1", 0);
+ gl_polyblend = ri.Cvar_Get("gl_polyblend", "1", 0);
+ gl_flashblend = ri.Cvar_Get("gl_flashblend", "0", 0);
+ gl_playermip = ri.Cvar_Get("gl_playermip", "0", 0);
+ gl_monolightmap = ri.Cvar_Get("gl_monolightmap", "0", 0);
+ gl_driver = ri.Cvar_Get("gl_driver", "opengl32", Globals.CVAR_ARCHIVE);
+ gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", Globals.CVAR_ARCHIVE);
+ gl_texturealphamode = ri.Cvar_Get("gl_texturealphamode", "default", Globals.CVAR_ARCHIVE);
+ gl_texturesolidmode = ri.Cvar_Get("gl_texturesolidmode", "default", Globals.CVAR_ARCHIVE);
+ gl_lockpvs = ri.Cvar_Get("gl_lockpvs", "0", 0);
+
+ gl_vertex_arrays = ri.Cvar_Get("gl_vertex_arrays", "1", Globals.CVAR_ARCHIVE);
+
+ gl_ext_swapinterval = ri.Cvar_Get("gl_ext_swapinterval", "1", Globals.CVAR_ARCHIVE);
+ gl_ext_palettedtexture = ri.Cvar_Get("gl_ext_palettedtexture", "0", Globals.CVAR_ARCHIVE);
+ gl_ext_multitexture = ri.Cvar_Get("gl_ext_multitexture", "1", Globals.CVAR_ARCHIVE);
+ gl_ext_pointparameters = ri.Cvar_Get("gl_ext_pointparameters", "1", Globals.CVAR_ARCHIVE);
+ gl_ext_compiled_vertex_array = ri.Cvar_Get("gl_ext_compiled_vertex_array", "1", Globals.CVAR_ARCHIVE);
+
+ gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0);
+ gl_swapinterval = ri.Cvar_Get("gl_swapinterval", "0", Globals.CVAR_ARCHIVE);
+
+ gl_saturatelighting = ri.Cvar_Get("gl_saturatelighting", "0", 0);
+
+ gl_3dlabs_broken = ri.Cvar_Get("gl_3dlabs_broken", "1", Globals.CVAR_ARCHIVE);
+
+ vid_fullscreen = ri.Cvar_Get("vid_fullscreen", "0", Globals.CVAR_ARCHIVE);
+ vid_gamma = ri.Cvar_Get("vid_gamma", "1.0", Globals.CVAR_ARCHIVE);
+ vid_ref = ri.Cvar_Get("vid_ref", "fastjogl", Globals.CVAR_ARCHIVE);
+
+ ri.Cmd_AddCommand("imagelist", new xcommand_t() {
+ public void execute() {
+ GL_ImageList_f();
+ }
+ });
+
+ ri.Cmd_AddCommand("screenshot", new xcommand_t() {
+ public void execute() {
+ GL_ScreenShot_f();
+ }
+ });
+ ri.Cmd_AddCommand("modellist", new xcommand_t() {
+ public void execute() {
+ Mod_Modellist_f();
+ }
+ });
+ ri.Cmd_AddCommand("gl_strings", new xcommand_t() {
+ public void execute() {
+ GL_Strings_f();
+ }
+ });
+ }
+
+ /*
+ ==================
+ R_SetMode
+ ==================
+ */
+ protected boolean R_SetMode() {
+
+ int err; // enum rserr_t
+ boolean fullscreen;
+
+// if (vid_fullscreen.modified && !gl_config.allow_cds) {
+// ri.Con_Printf(Defines.PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n");
+// ri.Cvar_SetValue("vid_fullscreen", (vid_fullscreen.value > 0.0f) ? 0.0f : 1.0f);
+// vid_fullscreen.modified = false;
+// }
+
+ fullscreen = (vid_fullscreen.value > 0.0f);
+
+ vid_fullscreen.modified = false;
+ gl_mode.modified = false;
+
+ Dimension dim = new Dimension(vid.width, vid.height);
+
+ if ((err = GLimp_SetMode(dim, (int) gl_mode.value, fullscreen)) == rserr_ok) {
+ gl_state.prev_mode = (int) gl_mode.value;
+ }
+ else {
+ if (err == rserr_invalid_fullscreen) {
+ ri.Cvar_SetValue("vid_fullscreen", 0);
+ vid_fullscreen.modified = false;
+ ri.Con_Printf(Defines.PRINT_ALL, "ref_gl::R_SetMode() - fullscreen unavailable in this mode\n");
+ if ((err = GLimp_SetMode(dim, (int) gl_mode.value, false)) == rserr_ok)
+ return true;
+ }
+ else if (err == rserr_invalid_mode) {
+ ri.Cvar_SetValue("gl_mode", gl_state.prev_mode);
+ gl_mode.modified = false;
+ ri.Con_Printf(Defines.PRINT_ALL, "ref_gl::R_SetMode() - invalid mode\n");
+ }
+
+ // try setting it back to something safe
+ if ((err = GLimp_SetMode(dim, gl_state.prev_mode, false)) != rserr_ok) {
+ ri.Con_Printf(Defines.PRINT_ALL, "ref_gl::R_SetMode() - could not revert to safe mode\n");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ ===============
+ R_Init
+ ===============
+ */
+ float[] r_turbsin = new float[256];
+
+ protected boolean R_Init(int vid_xpos, int vid_ypos) {
+
+ assert(Warp.SIN.length == 256) : "warpsin table bug";
+
+ // fill r_turbsin
+ for (int j = 0; j < 256; j++) {
+ r_turbsin[j] = Warp.SIN[j] * 0.5f;
+ }
+
+ ri.Con_Printf(Defines.PRINT_ALL, "ref_gl version: " + REF_VERSION + '\n');
+
+ Draw_GetPalette();
+
+ R_Register();
+
+ // initialize our QGL dynamic bindings
+ if (!QGL_Init(gl_driver.string)) {
+ QGL_Shutdown();
+ ri.Con_Printf(Defines.PRINT_ALL, "ref_gl::R_Init() - could not load \"" + gl_driver.string + "\"\n");
+ return false;
+ }
+
+ // initialize OS-specific parts of OpenGL
+ if (!GLimp_Init(vid_xpos, vid_ypos)) {
+ QGL_Shutdown();
+ return false;
+ }
+
+ // set our "safe" modes
+ gl_state.prev_mode = 3;
+
+ // create the window and set up the context
+ if (!R_SetMode()) {
+ QGL_Shutdown();
+ ri.Con_Printf(Defines.PRINT_ALL, "ref_gl::R_Init() - could not R_SetMode()\n");
+ return false;
+ }
+ return true;
+ }
+
+ boolean R_Init2() {
+ ri.Vid_MenuInit();
+
+ /*
+ ** get our various GL strings
+ */
+ gl_config.vendor_string = gl.glGetString(GL.GL_VENDOR);
+ ri.Con_Printf(Defines.PRINT_ALL, "GL_VENDOR: " + gl_config.vendor_string + '\n');
+ gl_config.renderer_string = gl.glGetString(GL.GL_RENDERER);
+ ri.Con_Printf(Defines.PRINT_ALL, "GL_RENDERER: " + gl_config.renderer_string + '\n');
+ gl_config.version_string = gl.glGetString(GL.GL_VERSION);
+ ri.Con_Printf(Defines.PRINT_ALL, "GL_VERSION: " + gl_config.version_string + '\n');
+ gl_config.extensions_string = gl.glGetString(GL.GL_EXTENSIONS);
+ ri.Con_Printf(Defines.PRINT_ALL, "GL_EXTENSIONS: " + gl_config.extensions_string + '\n');
+
+ String renderer_buffer = gl_config.renderer_string.toLowerCase();
+ String vendor_buffer = gl_config.vendor_string.toLowerCase();
+
+ if (renderer_buffer.indexOf("voodoo") >= 0) {
+ if (renderer_buffer.indexOf("rush") < 0)
+ gl_config.renderer = GL_RENDERER_VOODOO;
+ else
+ gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
+ }
+ else if (vendor_buffer.indexOf("sgi") >= 0)
+ gl_config.renderer = GL_RENDERER_SGI;
+ else if (renderer_buffer.indexOf("permedia") >= 0)
+ gl_config.renderer = GL_RENDERER_PERMEDIA2;
+ else if (renderer_buffer.indexOf("glint") >= 0)
+ gl_config.renderer = GL_RENDERER_GLINT_MX;
+ else if (renderer_buffer.indexOf("glzicd") >= 0)
+ gl_config.renderer = GL_RENDERER_REALIZM;
+ else if (renderer_buffer.indexOf("gdi") >= 0)
+ gl_config.renderer = GL_RENDERER_MCD;
+ else if (renderer_buffer.indexOf("pcx2") >= 0)
+ gl_config.renderer = GL_RENDERER_PCX2;
+ else if (renderer_buffer.indexOf("verite") >= 0)
+ gl_config.renderer = GL_RENDERER_RENDITION;
+ else
+ gl_config.renderer = GL_RENDERER_OTHER;
+
+ String monolightmap = gl_monolightmap.string.toUpperCase();
+ if (monolightmap.length() < 2 || monolightmap.charAt(1) != 'F') {
+ if (gl_config.renderer == GL_RENDERER_PERMEDIA2) {
+ ri.Cvar_Set("gl_monolightmap", "A");
+ ri.Con_Printf(Defines.PRINT_ALL, "...using gl_monolightmap 'a'\n");
+ }
+ else if ((gl_config.renderer & GL_RENDERER_POWERVR) != 0) {
+ ri.Cvar_Set("gl_monolightmap", "0");
+ }
+ else {
+ ri.Cvar_Set("gl_monolightmap", "0");
+ }
+ }
+
+ // power vr can't have anything stay in the framebuffer, so
+ // the screen needs to redraw the tiled background every frame
+ if ((gl_config.renderer & GL_RENDERER_POWERVR) != 0) {
+ ri.Cvar_Set("scr_drawall", "1");
+ }
+ else {
+ ri.Cvar_Set("scr_drawall", "0");
+ }
+
+ // #ifdef __linux__
+ ri.Cvar_SetValue("gl_finish", 1);
+ // #endif
+
+ // MCD has buffering issues
+ if (gl_config.renderer == GL_RENDERER_MCD) {
+ ri.Cvar_SetValue("gl_finish", 1);
+ }
+
+ if ((gl_config.renderer & GL_RENDERER_3DLABS) != 0) {
+ if (gl_3dlabs_broken.value != 0.0f)
+ gl_config.allow_cds = false;
+ else
+ gl_config.allow_cds = true;
+ }
+ else {
+ gl_config.allow_cds = true;
+ }
+
+ if (gl_config.allow_cds)
+ ri.Con_Printf(Defines.PRINT_ALL, "...allowing CDS\n");
+ else
+ ri.Con_Printf(Defines.PRINT_ALL, "...disabling CDS\n");
+
+ /*
+ ** grab extensions
+ */
+ if (gl_config.extensions_string.indexOf("GL_EXT_compiled_vertex_array") >= 0
+ || gl_config.extensions_string.indexOf("GL_SGI_compiled_vertex_array") >= 0) {
+ ri.Con_Printf(Defines.PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n");
+ // qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
+ if (gl_ext_compiled_vertex_array.value != 0.0f)
+ qglLockArraysEXT = true;
+ else
+ qglLockArraysEXT = false;
+ // qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
+ //qglUnlockArraysEXT = true;
+ }
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n");
+ qglLockArraysEXT = false;
+ }
+
+ if (gl_config.extensions_string.indexOf("WGL_EXT_swap_control") >= 0) {
+ qwglSwapIntervalEXT = true;
+ ri.Con_Printf(Defines.PRINT_ALL, "...enabling WGL_EXT_swap_control\n");
+ } else {
+ qwglSwapIntervalEXT = false;
+ ri.Con_Printf(Defines.PRINT_ALL, "...WGL_EXT_swap_control not found\n");
+ }
+
+ if (gl_config.extensions_string.indexOf("GL_EXT_point_parameters") >= 0) {
+ if (gl_ext_pointparameters.value != 0.0f) {
+ // qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
+ qglPointParameterfEXT = true;
+ // qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
+ ri.Con_Printf(Defines.PRINT_ALL, "...using GL_EXT_point_parameters\n");
+ }
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "...ignoring GL_EXT_point_parameters\n");
+ }
+ }
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "...GL_EXT_point_parameters not found\n");
+ }
+
+ // #ifdef __linux__
+ // if ( strstr( gl_config.extensions_string, "3DFX_set_global_palette" ))
+ // {
+ // if ( gl_ext_palettedtexture->value )
+ // {
+ // ri.Con_Printf( Defines.PRINT_ALL, "...using 3DFX_set_global_palette\n" );
+ // qgl3DfxSetPaletteEXT = ( void ( APIENTRY * ) (GLuint *) )qwglGetProcAddress( "gl3DfxSetPaletteEXT" );
+ //// qglColorTableEXT = Fake_glColorTableEXT;
+ // }
+ // else
+ // {
+ // ri.Con_Printf( Defines.PRINT_ALL, "...ignoring 3DFX_set_global_palette\n" );
+ // }
+ // }
+ // else
+ // {
+ // ri.Con_Printf( Defines.PRINT_ALL, "...3DFX_set_global_palette not found\n" );
+ // }
+ // #endif
+
+ if (!qglColorTableEXT
+ && gl_config.extensions_string.indexOf("GL_EXT_paletted_texture") >= 0
+ && gl_config.extensions_string.indexOf("GL_EXT_shared_texture_palette") >= 0) {
+ if (gl_ext_palettedtexture.value != 0.0f) {
+ ri.Con_Printf(Defines.PRINT_ALL, "...using GL_EXT_shared_texture_palette\n");
+ qglColorTableEXT = false; // true; TODO jogl bug
+ }
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "...ignoring GL_EXT_shared_texture_palette\n");
+ qglColorTableEXT = false;
+ }
+ }
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "...GL_EXT_shared_texture_palette not found\n");
+ }
+
+ if (gl_config.extensions_string.indexOf("GL_ARB_multitexture") >= 0) {
+ ri.Con_Printf(Defines.PRINT_ALL, "...using GL_ARB_multitexture\n");
+ qglActiveTextureARB = true;
+ GL_TEXTURE0 = GL.GL_TEXTURE0_ARB;
+ GL_TEXTURE1 = GL.GL_TEXTURE1_ARB;
+ }
+ else {
+ ri.Con_Printf(Defines.PRINT_ALL, "...GL_ARB_multitexture not found\n");
+ }
+
+ if (!(qglActiveTextureARB))
+ return false;
+
+ GL_SetDefaultState();
+
+ GL_InitImages();
+ Mod_Init();
+ R_InitParticleTexture();
+ Draw_InitLocal();
+
+ int err = gl.glGetError();
+ if (err != GL.GL_NO_ERROR)
+ ri.Con_Printf(
+ Defines.PRINT_ALL,
+ "glGetError() = 0x%x\n\t%s\n",
+ new Vargs(2).add(err).add("" + gl.glGetString(err)));
+
+ return true;
+ }
+
+ /*
+ ===============
+ R_Shutdown
+ ===============
+ */
+ protected void R_Shutdown() {
+ ri.Cmd_RemoveCommand("modellist");
+ ri.Cmd_RemoveCommand("screenshot");
+ ri.Cmd_RemoveCommand("imagelist");
+ ri.Cmd_RemoveCommand("gl_strings");
+
+ Mod_FreeAll();
+
+ GL_ShutdownImages();
+
+ /*
+ * shut down OS specific OpenGL stuff like contexts, etc.
+ */
+ GLimp_Shutdown();
+
+ /*
+ * shutdown our QGL subsystem
+ */
+ QGL_Shutdown();
+ }
+
+ /*
+ @@@@@@@@@@@@@@@@@@@@@
+ R_BeginFrame
+ @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected void R_BeginFrame(float camera_separation) {
+
+ gl_state.camera_separation = camera_separation;
+
+ /*
+ ** change modes if necessary
+ */
+ if (gl_mode.modified || vid_fullscreen.modified) {
+ // FIXME: only restart if CDS is required
+ cvar_t ref;
+
+ ref = ri.Cvar_Get("vid_ref", "fastjogl", 0);
+ ref.modified = true;
+ }
+
+ if (gl_log.modified) {
+ GLimp_EnableLogging((gl_log.value != 0.0f));
+ gl_log.modified = false;
+ }
+
+ if (gl_log.value != 0.0f) {
+ GLimp_LogNewFrame();
+ }
+
+ /*
+ ** update 3Dfx gamma -- it is expected that a user will do a vid_restart
+ ** after tweaking this value
+ */
+ if (vid_gamma.modified) {
+ vid_gamma.modified = false;
+
+ if ((gl_config.renderer & GL_RENDERER_VOODOO) != 0) {
+ // wird erstmal nicht gebraucht
+
+ /*
+ char envbuffer[1024];
+ float g;
+
+ g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
+ Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
+ putenv( envbuffer );
+ Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
+ putenv( envbuffer );
+ */
+ ri.Con_Printf(Defines.PRINT_DEVELOPER, "gamma anpassung fuer VOODOO nicht gesetzt");
+ }
+ }
+
+ GLimp_BeginFrame(camera_separation);
+
+ /*
+ ** go into 2D mode
+ */
+ gl.glViewport(0, 0, vid.width, vid.height);
+ gl.glMatrixMode(GL.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(0, vid.width, vid.height, 0, -99999, 99999);
+ gl.glMatrixMode(GL.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glDisable(GL.GL_DEPTH_TEST);
+ gl.glDisable(GL.GL_CULL_FACE);
+ gl.glDisable(GL.GL_BLEND);
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ gl.glColor4f(1, 1, 1, 1);
+
+ /*
+ ** draw buffer stuff
+ */
+ if (gl_drawbuffer.modified) {
+ gl_drawbuffer.modified = false;
+
+ if (gl_state.camera_separation == 0 || !gl_state.stereo_enabled) {
+ if (gl_drawbuffer.string.equalsIgnoreCase("GL_FRONT"))
+ gl.glDrawBuffer(GL.GL_FRONT);
+ else
+ gl.glDrawBuffer(GL.GL_BACK);
+ }
+ }
+
+ /*
+ ** texturemode stuff
+ */
+ if (gl_texturemode.modified) {
+ GL_TextureMode(gl_texturemode.string);
+ gl_texturemode.modified = false;
+ }
+
+ if (gl_texturealphamode.modified) {
+ GL_TextureAlphaMode(gl_texturealphamode.string);
+ gl_texturealphamode.modified = false;
+ }
+
+ if (gl_texturesolidmode.modified) {
+ GL_TextureSolidMode(gl_texturesolidmode.string);
+ gl_texturesolidmode.modified = false;
+ }
+
+ /*
+ ** swapinterval stuff
+ */
+ GL_UpdateSwapInterval();
+
+ //
+ // clear screen if desired
+ //
+ R_Clear();
+ }
+
+ int[] r_rawpalette = new int[256];
+
+ /*
+ =============
+ R_SetPalette
+ =============
+ */
+ protected void R_SetPalette(byte[] palette) {
+ // 256 RGB values (768 bytes)
+ // or null
+ int i;
+ int color = 0;
+
+ if (palette != null) {
+ int j =0;
+ for (i = 0; i < 256; i++) {
+ color = (palette[j++] & 0xFF) << 0;
+ color |= (palette[j++] & 0xFF) << 8;
+ color |= (palette[j++] & 0xFF) << 16;
+ color |= 0xFF000000;
+ r_rawpalette[i] = color;
+ }
+ }
+ else {
+ for (i = 0; i < 256; i++) {
+ r_rawpalette[i] = d_8to24table[i] | 0xff000000;
+ }
+ }
+ GL_SetTexturePalette(r_rawpalette);
+
+ gl.glClearColor(0, 0, 0, 0);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
+ gl.glClearColor(1f, 0f, 0.5f, 0.5f);
+ }
+
+ static final int NUM_BEAM_SEGS = 6;
+ float[][] start_points = new float[NUM_BEAM_SEGS][3];
+ // array of vec3_t
+ float[][] end_points = new float[NUM_BEAM_SEGS][3]; // array of vec3_t
+
+ /*
+ ** R_DrawBeam
+ */
+ void R_DrawBeam(entity_t e) {
+
+ int i;
+ float r, g, b;
+
+ float[] perpvec = { 0, 0, 0 }; // vec3_t
+ float[] direction = { 0, 0, 0 }; // vec3_t
+ float[] normalized_direction = { 0, 0, 0 }; // vec3_t
+
+ float[] oldorigin = { 0, 0, 0 }; // vec3_t
+ float[] origin = { 0, 0, 0 }; // vec3_t
+
+ oldorigin[0] = e.oldorigin[0];
+ oldorigin[1] = e.oldorigin[1];
+ oldorigin[2] = e.oldorigin[2];
+
+ origin[0] = e.origin[0];
+ origin[1] = e.origin[1];
+ origin[2] = e.origin[2];
+
+ normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
+ normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
+ normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
+
+ if (Math3D.VectorNormalize(normalized_direction) == 0.0f)
+ return;
+
+ Math3D.PerpendicularVector(perpvec, normalized_direction);
+ Math3D.VectorScale(perpvec, e.frame / 2, perpvec);
+
+ for (i = 0; i < 6; i++) {
+ Math3D.RotatePointAroundVector(
+ start_points[i],
+ normalized_direction,
+ perpvec,
+ (360.0f / NUM_BEAM_SEGS) * i);
+
+ Math3D.VectorAdd(start_points[i], origin, start_points[i]);
+ Math3D.VectorAdd(start_points[i], direction, end_points[i]);
+ }
+
+ gl.glDisable(GL.GL_TEXTURE_2D);
+ gl.glEnable(GL.GL_BLEND);
+ gl.glDepthMask(false);
+
+ r = (d_8to24table[e.skinnum & 0xFF]) & 0xFF;
+ g = (d_8to24table[e.skinnum & 0xFF] >> 8) & 0xFF;
+ b = (d_8to24table[e.skinnum & 0xFF] >> 16) & 0xFF;
+
+ r *= 1 / 255.0f;
+ g *= 1 / 255.0f;
+ b *= 1 / 255.0f;
+
+ gl.glColor4f(r, g, b, e.alpha);
+
+ gl.glBegin(GL.GL_TRIANGLE_STRIP);
+
+ float[] v;
+
+ for (i = 0; i < NUM_BEAM_SEGS; i++) {
+ v = start_points[i];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ v = end_points[i];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ v = start_points[(i + 1) % NUM_BEAM_SEGS];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ v = end_points[(i + 1) % NUM_BEAM_SEGS];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ }
+ gl.glEnd();
+
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ gl.glDisable(GL.GL_BLEND);
+ gl.glDepthMask(true);
+ }
+
+}
diff --git a/src/jake2/render/fastjogl/Mesh.java b/src/jake2/render/fastjogl/Mesh.java
new file mode 100644
index 0000000..e7da997
--- /dev/null
+++ b/src/jake2/render/fastjogl/Mesh.java
@@ -0,0 +1,753 @@
+/*
+ * Mesh.java
+ * Copyright (C) 2003
+ *
+ * $Id: Mesh.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import net.java.games.gluegen.runtime.BufferFactory;
+import net.java.games.jogl.GL;
+import net.java.games.jogl.util.BufferUtils;
+import jake2.Defines;
+import jake2.Globals;
+import jake2.client.entity_t;
+import jake2.qcommon.qfiles;
+import jake2.render.image_t;
+import jake2.util.Math3D;
+
+/**
+ * Mesh
+ *
+ * @author cwei
+ */
+public abstract class Mesh extends Light {
+
+ // g_mesh.c: triangle model functions
+
+ /*
+ =============================================================
+
+ ALIAS MODELS
+
+ =============================================================
+ */
+
+ static final int NUMVERTEXNORMALS = 162;
+
+ float[][] r_avertexnormals = Anorms.VERTEXNORMALS;
+ float[] shadevector = {0, 0, 0};
+ float[] shadelight = {0, 0, 0};
+
+ // precalculated dot products for quantized angles
+ static final int SHADEDOT_QUANT = 16;
+
+ float[][] r_avertexnormal_dots = Anorms.VERTEXNORMAL_DOTS;
+
+ float[] shadedots = r_avertexnormal_dots[0];
+
+ void GL_LerpVerts( int nverts, qfiles.dtrivertx_t[] v, qfiles.dtrivertx_t[] ov, qfiles.dtrivertx_t[] verts, FloatBuffer lerp, float[] move, float[] frontv, float[] backv )
+ {
+ int i;
+ int lerpIndex = 0;
+
+ int[] ovv;
+ int[] vv;
+
+ //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
+ if ( (currententity.flags & ( Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0 )
+ {
+ float[] normal;
+ int j = 0;
+ for (i=0 ; i < nverts; i++/* , v++, ov++, lerp+=4 */)
+ {
+ normal = r_avertexnormals[verts[i].lightnormalindex];
+ ovv = ov[i].v;
+ vv = v[i].v;
+
+ lerp.put(j, move[0] + ovv[0]*backv[0] + vv[0]*frontv[0] + normal[0] * Defines.POWERSUIT_SCALE);
+ lerp.put(j + 1, move[1] + ovv[1]*backv[1] + vv[1]*frontv[1] + normal[1] * Defines.POWERSUIT_SCALE);
+ lerp.put(j + 2, move[2] + ovv[2]*backv[2] + vv[2]*frontv[2] + normal[2] * Defines.POWERSUIT_SCALE);
+ j+=3;
+ }
+ }
+ else
+ {
+ int j = 0;
+ for (i=0 ; i < nverts; i++ /* , v++, ov++, lerp+=4 */)
+ {
+ ovv = ov[i].v;
+ vv = v[i].v;
+
+ lerp.put(j, move[0] + ovv[0]*backv[0] + vv[0]*frontv[0]);
+ lerp.put(j + 1, move[1] + ovv[1]*backv[1] + vv[1]*frontv[1]);
+ lerp.put(j + 2, move[2] + ovv[2]*backv[2] + vv[2]*frontv[2]);
+ j+=3;
+ }
+ }
+ }
+
+ FloatBuffer colorArrayBuf = BufferUtils.newFloatBuffer(qfiles.MAX_VERTS * 4);
+ FloatBuffer vertexArrayBuf = BufferUtils.newFloatBuffer(qfiles.MAX_VERTS * 3);
+ FloatBuffer textureArrayBuf = BufferUtils.newFloatBuffer(qfiles.MAX_VERTS * 2);
+ boolean isFilled = false;
+ float[] tmpVec = {0, 0, 0};
+ float[][] vectors = {
+ {0, 0, 0}, {0, 0, 0}, {0, 0, 0} // 3 mal vec3_t
+ };
+
+ /*
+ =============
+ GL_DrawAliasFrameLerp
+
+ interpolates between two frames and origins
+ FIXME: batch lerp all vertexes
+ =============
+ */
+
+ void GL_DrawAliasFrameLerp(qfiles.dmdl_t paliashdr, float backlerp)
+ {
+ float l;
+ qfiles.daliasframe_t frame, oldframe;
+ qfiles.dtrivertx_t[] v, ov, verts;
+
+ int[] order;
+ int orderIndex = 0;
+ int count;
+
+ float frontlerp;
+ float alpha;
+
+ float[] move = {0, 0, 0}; // vec3_t
+ float[] delta = {0, 0, 0}; // vec3_t
+
+ float[] frontv = {0, 0, 0}; // vec3_t
+ float[] backv = {0, 0, 0}; // vec3_t
+
+ int i;
+ int index_xyz;
+
+ frame = paliashdr.aliasFrames[currententity.frame];
+
+ verts = v = frame.verts;
+
+ oldframe = paliashdr.aliasFrames[currententity.oldframe];
+
+ ov = oldframe.verts;
+
+ if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0)
+ alpha = currententity.alpha;
+ else
+ alpha = 1.0f;
+
+ // PMM - added double shell
+ if ( (currententity.flags & ( Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0)
+ gl.glDisable( GL.GL_TEXTURE_2D );
+
+ frontlerp = 1.0f - backlerp;
+
+ // move should be the delta back to the previous frame * backlerp
+ Math3D.VectorSubtract (currententity.oldorigin, currententity.origin, delta);
+ Math3D.AngleVectors (currententity.angles, vectors[0], vectors[1], vectors[2]);
+
+ move[0] = Math3D.DotProduct (delta, vectors[0]); // forward
+ move[1] = -Math3D.DotProduct (delta, vectors[1]); // left
+ move[2] = Math3D.DotProduct (delta, vectors[2]); // up
+
+ Math3D.VectorAdd (move, oldframe.translate, move);
+
+ for (i=0 ; i<3 ; i++)
+ {
+ move[i] = backlerp*move[i] + frontlerp*frame.translate[i];
+ }
+
+ for (i=0 ; i<3 ; i++)
+ {
+ frontv[i] = frontlerp*frame.scale[i];
+ backv[i] = backlerp*oldframe.scale[i];
+ }
+
+ // ab hier wird optimiert
+
+ GL_LerpVerts( paliashdr.num_xyz, v, ov, verts, vertexArrayBuf, move, frontv, backv );
+
+ //gl.glEnableClientState( GL.GL_VERTEX_ARRAY );
+ gl.glVertexPointer( 3, GL.GL_FLOAT, 0, vertexArrayBuf );
+
+ // PMM - added double damage shell
+ if ( (currententity.flags & ( Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0)
+ {
+ gl.glColor4f( shadelight[0], shadelight[1], shadelight[2], alpha );
+ }
+ else
+ {
+ gl.glEnableClientState( GL.GL_COLOR_ARRAY );
+ gl.glColorPointer( 4, GL.GL_FLOAT, 0, colorArrayBuf );
+
+ //
+ // pre light everything
+ //
+ FloatBuffer color = colorArrayBuf;
+ int j = 0;
+ for ( i = 0; i < paliashdr.num_xyz; i++ )
+ {
+ l = shadedots[verts[i].lightnormalindex];
+ color.put(j++, l * shadelight[0]);
+ color.put(j++, l * shadelight[1]);
+ color.put(j++, l * shadelight[2]);
+ color.put(j++, alpha);
+ }
+ }
+
+ gl.glClientActiveTextureARB(GL_TEXTURE0);
+ gl.glTexCoordPointer( 2, GL.GL_FLOAT, 0, textureArrayBuf);
+ //gl.glEnableClientState( GL.GL_TEXTURE_COORD_ARRAY);
+
+ int pos = 0;
+ int[] counts = paliashdr.counts;
+
+ IntBuffer srcIndexBuf = null;
+
+ FloatBuffer dstTextureCoords = textureArrayBuf;
+ FloatBuffer srcTextureCoords = paliashdr.textureCoordBuf;
+
+ int size = 0;
+ int dstIndex = 0;
+ int srcIndex = 0;
+
+ for (int j = 0; j < counts.length; j++) {
+
+ // get the vertex count and primitive type
+ count = counts[j];
+ if (count == 0)
+ break; // done
+
+ srcIndexBuf = paliashdr.indexElements[j];
+
+ size = (count < 0) ? -count + pos : count + pos;
+ for (int k = pos; k < size; k++) {
+ srcIndex = 2 * k;
+ dstIndex = 2 * srcIndexBuf.get(k-pos);
+ dstTextureCoords.put(dstIndex, srcTextureCoords.get(srcIndex));
+ dstTextureCoords.put(dstIndex + 1, srcTextureCoords.get(srcIndex + 1));
+ }
+
+ if (count < 0) {
+ count = -count;
+ gl.glDrawElements(GL.GL_TRIANGLE_FAN, count, GL.GL_UNSIGNED_INT, srcIndexBuf);
+ } else {
+ gl.glDrawElements(GL.GL_TRIANGLE_STRIP, count, GL.GL_UNSIGNED_INT, srcIndexBuf);
+ }
+ pos += count;
+ }
+
+ // PMM - added double damage shell
+ if ( (currententity.flags & ( Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0 )
+ gl.glEnable( GL.GL_TEXTURE_2D );
+
+ gl.glDisableClientState( GL.GL_COLOR_ARRAY );
+
+ }
+
+ /*
+ =============
+ GL_DrawAliasShadow
+ =============
+ */
+ void GL_DrawAliasShadow(qfiles.dmdl_t paliashdr, int posenum)
+ {
+ qfiles.dtrivertx_t[] verts;
+ int[] order;
+ float[] point = {0, 0, 0};
+ float height, lheight;
+ int count;
+ qfiles.daliasframe_t frame;
+
+ lheight = currententity.origin[2] - lightspot[2];
+
+ frame = paliashdr.aliasFrames[currententity.frame];
+
+ verts = frame.verts;
+
+ height = 0;
+
+ order = paliashdr.glCmds;
+
+ height = -lheight + 1.0f;
+
+ int orderIndex = 0;
+ int index = 0;
+
+ // TODO shadow drawing with vertex arrays
+
+ while (true)
+ {
+ // get the vertex count and primitive type
+ count = order[orderIndex++];
+ if (count == 0)
+ break; // done
+ if (count < 0)
+ {
+ count = -count;
+ gl.glBegin (GL.GL_TRIANGLE_FAN);
+ }
+ else
+ gl.glBegin (GL.GL_TRIANGLE_STRIP);
+
+ do
+ {
+ index = order[orderIndex + 2] * 3;
+ point[0] = vertexArrayBuf.get(index);
+ point[1] = vertexArrayBuf.get(index + 1);
+ point[2] = vertexArrayBuf.get(index + 2);
+
+ point[0] -= shadevector[0]*(point[2]+lheight);
+ point[1] -= shadevector[1]*(point[2]+lheight);
+ point[2] = height;
+ gl.glVertex3f(point[0], point[1], point[2]);
+
+ orderIndex += 3;
+
+ } while (--count != 0);
+
+ gl.glEnd ();
+ }
+ }
+
+
+ /*
+ ** R_CullAliasModel
+ */
+ boolean R_CullAliasModel( float[][] bbox, entity_t e )
+ {
+ int i;
+ float[] mins = {0, 0, 0};
+ float[] maxs = {0, 0, 0};
+
+ qfiles.dmdl_t paliashdr;
+
+ float[] thismins = {0, 0, 0};
+ float[] oldmins = {0, 0, 0};
+ float[] thismaxs = {0, 0, 0};
+ float[] oldmaxs = {0, 0, 0};
+ qfiles.daliasframe_t pframe, poldframe;
+ float[] angles = {0, 0, 0};
+
+ paliashdr = (qfiles.dmdl_t)currentmodel.extradata;
+
+ if ( ( e.frame >= paliashdr.num_frames ) || ( e.frame < 0 ) )
+ {
+ ri.Con_Printf (Defines.PRINT_ALL, "R_CullAliasModel " + currentmodel.name +": no such frame " + e.frame + '\n');
+ e.frame = 0;
+ }
+ if ( ( e.oldframe >= paliashdr.num_frames ) || ( e.oldframe < 0 ) )
+ {
+ ri.Con_Printf (Defines.PRINT_ALL, "R_CullAliasModel " + currentmodel.name + ": no such oldframe " + e.oldframe + '\n');
+ e.oldframe = 0;
+ }
+
+ pframe = paliashdr.aliasFrames[e.frame];
+ poldframe = paliashdr.aliasFrames[e.oldframe];
+
+ /*
+ ** compute axially aligned mins and maxs
+ */
+ if ( pframe == poldframe )
+ {
+ for ( i = 0; i < 3; i++ )
+ {
+ mins[i] = pframe.translate[i];
+ maxs[i] = mins[i] + pframe.scale[i]*255;
+ }
+ }
+ else
+ {
+ for ( i = 0; i < 3; i++ )
+ {
+ thismins[i] = pframe.translate[i];
+ thismaxs[i] = thismins[i] + pframe.scale[i]*255;
+
+ oldmins[i] = poldframe.translate[i];
+ oldmaxs[i] = oldmins[i] + poldframe.scale[i]*255;
+
+ if ( thismins[i] < oldmins[i] )
+ mins[i] = thismins[i];
+ else
+ mins[i] = oldmins[i];
+
+ if ( thismaxs[i] > oldmaxs[i] )
+ maxs[i] = thismaxs[i];
+ else
+ maxs[i] = oldmaxs[i];
+ }
+ }
+
+ /*
+ ** compute a full bounding box
+ */
+ for ( i = 0; i < 8; i++ )
+ {
+ float[] tmp = {0, 0, 0};
+
+ if ( (i & 1) != 0 )
+ tmp[0] = mins[0];
+ else
+ tmp[0] = maxs[0];
+
+ if ( (i & 2) != 0)
+ tmp[1] = mins[1];
+ else
+ tmp[1] = maxs[1];
+
+ if ( (i & 4) != 0)
+ tmp[2] = mins[2];
+ else
+ tmp[2] = maxs[2];
+
+ Math3D.VectorCopy( tmp, bbox[i] );
+ }
+
+ /*
+ ** rotate the bounding box
+ */
+ Math3D.VectorCopy( e.angles, angles );
+ angles[YAW] = -angles[YAW];
+ Math3D.AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
+
+ float[] tmp = {0, 0, 0};
+
+ for ( i = 0; i < 8; i++ )
+ {
+ Math3D.VectorCopy( bbox[i], tmp );
+
+ bbox[i][0] = Math3D.DotProduct( vectors[0], tmp );
+ bbox[i][1] = -Math3D.DotProduct( vectors[1], tmp );
+ bbox[i][2] = Math3D.DotProduct( vectors[2], tmp );
+
+ Math3D.VectorAdd( e.origin, bbox[i], bbox[i] );
+ }
+
+ {
+ int p, f;
+ int aggregatemask = ~0; // 0xFFFFFFFF
+
+ for ( p = 0; p < 8; p++ )
+ {
+ int mask = 0;
+
+ for ( f = 0; f < 4; f++ )
+ {
+ float dp = Math3D.DotProduct( frustum[f].normal, bbox[p] );
+
+ if ( ( dp - frustum[f].dist ) < 0 )
+ {
+ mask |= ( 1 << f );
+ }
+ }
+
+ aggregatemask &= mask;
+ }
+
+ if ( aggregatemask != 0 )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+
+ // bounding box
+ float[][] bbox = {
+ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
+ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}
+ };
+
+ /*
+ =================
+ R_DrawAliasModel
+
+ =================
+ */
+ void R_DrawAliasModel(entity_t e)
+ {
+ int i;
+ qfiles.dmdl_t paliashdr;
+ float an;
+
+ image_t skin;
+
+ if ( ( e.flags & Defines.RF_WEAPONMODEL ) == 0)
+ {
+ if ( R_CullAliasModel( bbox, e ) )
+ return;
+ }
+
+ if ( (e.flags & Defines.RF_WEAPONMODEL) != 0 )
+ {
+ if ( r_lefthand.value == 2.0f )
+ return;
+ }
+
+ paliashdr = (qfiles.dmdl_t)currentmodel.extradata;
+
+ //
+ // get lighting information
+ //
+ // PMM - rewrote, reordered to handle new shells & mixing
+ // PMM - 3.20 code .. replaced with original way of doing it to keep mod authors happy
+ //
+ if ( (currententity.flags & ( Defines.RF_SHELL_HALF_DAM | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_RED | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE )) != 0 )
+ {
+ Math3D.VectorClear(shadelight);
+ if ((currententity.flags & Defines.RF_SHELL_HALF_DAM) != 0)
+ {
+ shadelight[0] = 0.56f;
+ shadelight[1] = 0.59f;
+ shadelight[2] = 0.45f;
+ }
+ if ( (currententity.flags & Defines.RF_SHELL_DOUBLE) != 0 )
+ {
+ shadelight[0] = 0.9f;
+ shadelight[1] = 0.7f;
+ }
+ if ( (currententity.flags & Defines.RF_SHELL_RED) != 0 )
+ shadelight[0] = 1.0f;
+ if ( (currententity.flags & Defines.RF_SHELL_GREEN) != 0 )
+ shadelight[1] = 1.0f;
+ if ( (currententity.flags & Defines.RF_SHELL_BLUE) != 0 )
+ shadelight[2] = 1.0f;
+ }
+
+ else if ( (currententity.flags & Defines.RF_FULLBRIGHT) != 0 )
+ {
+ for (i=0 ; i<3 ; i++)
+ shadelight[i] = 1.0f;
+ }
+ else
+ {
+ R_LightPoint (currententity.origin, shadelight);
+
+ // player lighting hack for communication back to server
+ // big hack!
+ if ( (currententity.flags & Defines.RF_WEAPONMODEL) != 0 )
+ {
+ // pick the greatest component, which should be the same
+ // as the mono value returned by software
+ if (shadelight[0] > shadelight[1])
+ {
+ if (shadelight[0] > shadelight[2])
+ r_lightlevel.value = 150*shadelight[0];
+ else
+ r_lightlevel.value = 150*shadelight[2];
+ }
+ else
+ {
+ if (shadelight[1] > shadelight[2])
+ r_lightlevel.value = 150*shadelight[1];
+ else
+ r_lightlevel.value = 150*shadelight[2];
+ }
+ }
+
+ if ( gl_monolightmap.string.charAt(0) != '0' )
+ {
+ float s = shadelight[0];
+
+ if ( s < shadelight[1] )
+ s = shadelight[1];
+ if ( s < shadelight[2] )
+ s = shadelight[2];
+
+ shadelight[0] = s;
+ shadelight[1] = s;
+ shadelight[2] = s;
+ }
+ }
+
+ if ( (currententity.flags & Defines.RF_MINLIGHT) != 0 )
+ {
+ for (i=0 ; i<3 ; i++)
+ if (shadelight[i] > 0.1f)
+ break;
+ if (i == 3)
+ {
+ shadelight[0] = 0.1f;
+ shadelight[1] = 0.1f;
+ shadelight[2] = 0.1f;
+ }
+ }
+
+ if ( (currententity.flags & Defines.RF_GLOW) != 0 )
+ { // bonus items will pulse with time
+ float scale;
+ float min;
+
+ scale = (float)(0.1f * Math.sin(r_newrefdef.time*7));
+ for (i=0 ; i<3 ; i++)
+ {
+ min = shadelight[i] * 0.8f;
+ shadelight[i] += scale;
+ if (shadelight[i] < min)
+ shadelight[i] = min;
+ }
+ }
+
+ // =================
+ // PGM ir goggles color override
+ if ( (r_newrefdef.rdflags & Defines.RDF_IRGOGGLES) != 0 && (currententity.flags & Defines.RF_IR_VISIBLE) != 0)
+ {
+ shadelight[0] = 1.0f;
+ shadelight[1] = 0.0f;
+ shadelight[2] = 0.0f;
+ }
+ // PGM
+ // =================
+
+ shadedots = r_avertexnormal_dots[((int)(currententity.angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
+
+ an = (float)(currententity.angles[1]/180*Math.PI);
+ shadevector[0] = (float)Math.cos(-an);
+ shadevector[1] = (float)Math.sin(-an);
+ shadevector[2] = 1;
+ Math3D.VectorNormalize(shadevector);
+
+ //
+ // locate the proper data
+ //
+
+ c_alias_polys += paliashdr.num_tris;
+
+ //
+ // draw all the triangles
+ //
+ if ( (currententity.flags & Defines.RF_DEPTHHACK) != 0) // hack the depth range to prevent view model from poking into walls
+ gl.glDepthRange(gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
+
+ if ( (currententity.flags & Defines.RF_WEAPONMODEL) != 0 && (r_lefthand.value == 1.0f) )
+ {
+ gl.glMatrixMode( GL.GL_PROJECTION );
+ gl.glPushMatrix();
+ gl.glLoadIdentity();
+ gl.glScalef( -1, 1, 1 );
+ MYgluPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height, 4, 4096);
+ gl.glMatrixMode( GL.GL_MODELVIEW );
+
+ gl.glCullFace( GL.GL_BACK );
+ }
+
+ gl.glPushMatrix ();
+ e.angles[PITCH] = -e.angles[PITCH]; // sigh.
+ R_RotateForEntity (e);
+ e.angles[PITCH] = -e.angles[PITCH]; // sigh.
+
+ // select skin
+ if (currententity.skin != null)
+ skin = currententity.skin; // custom player skin
+ else
+ {
+ if (currententity.skinnum >= qfiles.MAX_MD2SKINS)
+ skin = currentmodel.skins[0];
+ else
+ {
+ skin = currentmodel.skins[currententity.skinnum];
+ if (skin == null)
+ skin = currentmodel.skins[0];
+ }
+ }
+ if (skin == null)
+ skin = r_notexture; // fallback...
+ GL_Bind(skin.texnum);
+
+ // draw it
+
+ gl.glShadeModel (GL.GL_SMOOTH);
+
+ GL_TexEnv( GL.GL_MODULATE );
+ if ( (currententity.flags & Defines.RF_TRANSLUCENT) != 0 )
+ {
+ gl.glEnable (GL.GL_BLEND);
+ }
+
+
+ if ( (currententity.frame >= paliashdr.num_frames)
+ || (currententity.frame < 0) )
+ {
+ ri.Con_Printf (Defines.PRINT_ALL, "R_DrawAliasModel " + currentmodel.name +": no such frame " + currententity.frame + '\n');
+ currententity.frame = 0;
+ currententity.oldframe = 0;
+ }
+
+ if ( (currententity.oldframe >= paliashdr.num_frames)
+ || (currententity.oldframe < 0))
+ {
+ ri.Con_Printf (Defines.PRINT_ALL, "R_DrawAliasModel " + currentmodel.name +": no such oldframe " + currententity.oldframe + '\n');
+ currententity.frame = 0;
+ currententity.oldframe = 0;
+ }
+
+ if ( r_lerpmodels.value == 0.0f)
+ currententity.backlerp = 0;
+
+ GL_DrawAliasFrameLerp(paliashdr, currententity.backlerp);
+
+ GL_TexEnv( GL.GL_REPLACE );
+ gl.glShadeModel (GL.GL_FLAT);
+
+ gl.glPopMatrix ();
+
+ if ( ( currententity.flags & Defines.RF_WEAPONMODEL ) != 0 && ( r_lefthand.value == 1.0F ) )
+ {
+ gl.glMatrixMode( GL.GL_PROJECTION );
+ gl.glPopMatrix();
+ gl.glMatrixMode( GL.GL_MODELVIEW );
+ gl.glCullFace( GL.GL_FRONT );
+ }
+
+ if ( (currententity.flags & Defines.RF_TRANSLUCENT) != 0 )
+ {
+ gl.glDisable (GL.GL_BLEND);
+ }
+
+ if ( (currententity.flags & Defines.RF_DEPTHHACK) != 0)
+ gl.glDepthRange (gldepthmin, gldepthmax);
+
+ if ( gl_shadows.value != 0.0f && (currententity.flags & (Defines.RF_TRANSLUCENT | Defines.RF_WEAPONMODEL)) == 0)
+ {
+ gl.glPushMatrix ();
+ R_RotateForEntity (e);
+ gl.glDisable (GL.GL_TEXTURE_2D);
+ gl.glEnable (GL.GL_BLEND);
+ gl.glColor4f (0,0,0,0.5f);
+ GL_DrawAliasShadow (paliashdr, currententity.frame );
+ gl.glEnable (GL.GL_TEXTURE_2D);
+ gl.glDisable (GL.GL_BLEND);
+ gl.glPopMatrix ();
+ }
+ gl.glColor4f (1,1,1,1);
+ }
+
+}
diff --git a/src/jake2/render/fastjogl/Misc.java b/src/jake2/render/fastjogl/Misc.java
new file mode 100644
index 0000000..bcd2a5f
--- /dev/null
+++ b/src/jake2/render/fastjogl/Misc.java
@@ -0,0 +1,265 @@
+/*
+ * Misc.java
+ * Copyright (C) 2003
+ *
+ * $Id: Misc.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import net.java.games.jogl.GL;
+import net.java.games.jogl.WGL;
+
+import jake2.Defines;
+
+/**
+ * Misc
+ *
+ * @author cwei
+ */
+public abstract class Misc extends Mesh {
+
+ /*
+ ==================
+ R_InitParticleTexture
+ ==================
+ */
+ byte[][] dottexture =
+ {
+ {0,0,0,0,0,0,0,0},
+ {0,0,1,1,0,0,0,0},
+ {0,1,1,1,1,0,0,0},
+ {0,1,1,1,1,0,0,0},
+ {0,0,1,1,0,0,0,0},
+ {0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0},
+ };
+
+ void R_InitParticleTexture()
+ {
+ int x,y;
+ byte[] data = new byte[8 * 8 * 4];
+
+ //
+ // particle texture
+ //
+ for (x=0 ; x<8 ; x++)
+ {
+ for (y=0 ; y<8 ; y++)
+ {
+ data[y * 32 + x * 4 + 0] = (byte)255;
+ data[y * 32 + x * 4 + 1] = (byte)255;
+ data[y * 32 + x * 4 + 2] = (byte)255;
+ data[y * 32 + x * 4 + 3] = (byte)(dottexture[x][y]*255);
+
+ }
+ }
+ r_particletexture = GL_LoadPic("***particle***", data, 8, 8, it_sprite, 32);
+
+ //
+ // also use this for bad textures, but without alpha
+ //
+ for (x=0 ; x<8 ; x++)
+ {
+ for (y=0 ; y<8 ; y++)
+ {
+ data[y * 32 + x * 4 + 0] = (byte)(dottexture[x&3][y&3]*255);
+ data[y * 32 + x * 4 + 1] = 0; // dottexture[x&3][y&3]*255;
+ data[y * 32 + x * 4 + 2] = 0; //dottexture[x&3][y&3]*255;
+ data[y * 32 + x * 4 + 3] = (byte)255;
+ }
+ }
+ r_notexture = GL_LoadPic("***r_notexture***", data, 8, 8, it_wall, 32);
+ }
+
+
+// /*
+// ==============================================================================
+//
+// SCREEN SHOTS
+//
+// ==============================================================================
+// */
+//
+// typedef struct _TargaHeader {
+// unsigned char id_length, colormap_type, image_type;
+// unsigned short colormap_index, colormap_length;
+// unsigned char colormap_size;
+// unsigned short x_origin, y_origin, width, height;
+// unsigned char pixel_size, attributes;
+// } TargaHeader;
+
+
+ /*
+ ==================
+ GL_ScreenShot_f
+ ==================
+ */
+ void GL_ScreenShot_f()
+ {
+// byte *buffer;
+// char picname[80];
+// char checkname[MAX_OSPATH];
+// int i, c, temp;
+// FILE *f;
+//
+// // create the scrnshots directory if it doesn't exist
+// Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir());
+// Sys_Mkdir (checkname);
+//
+////
+//// find a file name to save it to
+////
+// strcpy(picname,"quake00.tga");
+//
+// for (i=0 ; i<=99 ; i++)
+// {
+// picname[5] = i/10 + '0';
+// picname[6] = i%10 + '0';
+// Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname);
+// f = fopen (checkname, "r");
+// if (!f)
+// break; // file doesn't exist
+// fclose (f);
+// }
+// if (i==100)
+// {
+// ri.Con_Printf (PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n");
+// return;
+// }
+//
+//
+// buffer = malloc(vid.width*vid.height*3 + 18);
+// memset (buffer, 0, 18);
+// buffer[2] = 2; // uncompressed type
+// buffer[12] = vid.width&255;
+// buffer[13] = vid.width>>8;
+// buffer[14] = vid.height&255;
+// buffer[15] = vid.height>>8;
+// buffer[16] = 24; // pixel size
+//
+// qglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );
+//
+// // swap rgb to bgr
+// c = 18+vid.width*vid.height*3;
+// for (i=18 ; i<c ; i+=3)
+// {
+// temp = buffer[i];
+// buffer[i] = buffer[i+2];
+// buffer[i+2] = temp;
+// }
+//
+// f = fopen (checkname, "rw");
+// fwrite (buffer, 1, c, f);
+// fclose (f);
+//
+// free (buffer);
+// ri.Con_Printf (PRINT_ALL, "Wrote %s\n", picname);
+ }
+
+ /*
+ ** GL_Strings_f
+ */
+ void GL_Strings_f() {
+ ri.Con_Printf (Defines.PRINT_ALL, "GL_VENDOR: " + gl_config.vendor_string + '\n');
+ ri.Con_Printf (Defines.PRINT_ALL, "GL_RENDERER: " + gl_config.renderer_string + '\n');
+ ri.Con_Printf (Defines.PRINT_ALL, "GL_VERSION: " + gl_config.version_string + '\n');
+ ri.Con_Printf (Defines.PRINT_ALL, "GL_EXTENSIONS: " + gl_config.extensions_string + '\n');
+ }
+
+ /*
+ ** GL_SetDefaultState
+ */
+ void GL_SetDefaultState()
+ {
+ gl.glClearColor(1f,0f, 0.5f , 0.5f); // original quake2
+ //gl.glClearColor(0, 0, 0, 0); // replaced with black
+ gl.glCullFace(GL.GL_FRONT);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+
+ gl.glEnable(GL.GL_ALPHA_TEST);
+ gl.glAlphaFunc(GL.GL_GREATER, 0.666f);
+
+ gl.glDisable (GL.GL_DEPTH_TEST);
+ gl.glDisable (GL.GL_CULL_FACE);
+ gl.glDisable (GL.GL_BLEND);
+
+ gl.glColor4f (1,1,1,1);
+
+ gl.glPolygonMode (GL.GL_FRONT_AND_BACK, GL.GL_FILL);
+ gl.glShadeModel (GL.GL_FLAT);
+
+ GL_TextureMode( gl_texturemode.string );
+ GL_TextureAlphaMode( gl_texturealphamode.string );
+ GL_TextureSolidMode( gl_texturesolidmode.string );
+
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, gl_filter_min);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, gl_filter_max);
+
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+
+ gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
+
+ GL_TexEnv( GL.GL_REPLACE );
+
+ if ( qglPointParameterfEXT )
+ {
+ float[] attenuations = { gl_particle_att_a.value, gl_particle_att_b.value, gl_particle_att_c.value };
+
+ gl.glEnable( GL.GL_POINT_SMOOTH );
+ gl.glPointParameterfEXT( GL.GL_POINT_SIZE_MIN_EXT, gl_particle_min_size.value );
+ gl.glPointParameterfEXT( GL.GL_POINT_SIZE_MAX_EXT, gl_particle_max_size.value );
+ gl.glPointParameterfvEXT( GL.GL_DISTANCE_ATTENUATION_EXT, attenuations );
+ }
+
+ if ( qglColorTableEXT && gl_ext_palettedtexture.value != 0.0f )
+ {
+ gl.glEnable( GL.GL_SHARED_TEXTURE_PALETTE_EXT );
+
+ GL_SetTexturePalette( d_8to24table );
+ }
+
+ GL_UpdateSwapInterval();
+
+ /*
+ * vertex array extension
+ */
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ gl.glClientActiveTextureARB(GL_TEXTURE0);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+ }
+
+ void GL_UpdateSwapInterval()
+ {
+ if ( gl_swapinterval.modified )
+ {
+ gl_swapinterval.modified = false;
+ if ( !gl_state.stereo_enabled )
+ {
+ if (qwglSwapIntervalEXT) {
+ ((WGL)gl).wglSwapIntervalEXT((int)gl_swapinterval.value);
+ }
+ }
+ }
+ }
+}
diff --git a/src/jake2/render/fastjogl/Model.java b/src/jake2/render/fastjogl/Model.java
new file mode 100644
index 0000000..4b781be
--- /dev/null
+++ b/src/jake2/render/fastjogl/Model.java
@@ -0,0 +1,1347 @@
+/*
+ * Model.java
+ * Copyright (C) 2003
+ *
+ * $Id: Model.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.Defines;
+import jake2.game.cplane_t;
+import jake2.game.cvar_t;
+import jake2.qcommon.*;
+import jake2.render.*;
+import jake2.util.Math3D;
+import jake2.util.Vargs;
+
+import java.nio.*;
+import java.util.Arrays;
+import java.util.Vector;
+
+import net.java.games.jogl.util.BufferUtils;
+
+/**
+ * Model
+ *
+ * @author cwei
+ */
+public abstract class Model extends Surf {
+
+ // models.c -- model loading and caching
+
+ model_t loadmodel;
+ int modfilelen;
+
+ byte[] mod_novis = new byte[Defines.MAX_MAP_LEAFS/8];
+
+ static final int MAX_MOD_KNOWN = 512;
+ model_t[] mod_known = new model_t[MAX_MOD_KNOWN];
+ int mod_numknown;
+
+ // the inline * models from the current map are kept seperate
+ model_t[] mod_inline = new model_t[MAX_MOD_KNOWN];
+
+ abstract void GL_SubdivideSurface(msurface_t surface); // Warp.java
+
+ /*
+ ===============
+ Mod_PointInLeaf
+ ===============
+ */
+ mleaf_t Mod_PointInLeaf(float[] p, model_t model)
+ {
+ mnode_t node;
+ float d;
+ cplane_t plane;
+
+ if (model == null || model.nodes == null)
+ ri.Sys_Error (Defines.ERR_DROP, "Mod_PointInLeaf: bad model");
+
+ node = model.nodes[0]; // root node
+ while (true)
+ {
+ if (node.contents != -1)
+ return (mleaf_t)node;
+
+ plane = node.plane;
+ d = Math3D.DotProduct(p, plane.normal) - plane.dist;
+ if (d > 0)
+ node = node.children[0];
+ else
+ node = node.children[1];
+ }
+ // never reached
+ }
+
+
+ byte[] decompressed = new byte[Defines.MAX_MAP_LEAFS / 8];
+ byte[] model_visibility = new byte[Defines.MAX_MAP_VISIBILITY];
+
+ /*
+ ===================
+ Mod_DecompressVis
+ ===================
+ */
+ byte[] Mod_DecompressVis(byte[] in, int offset, model_t model)
+ {
+ int c;
+ byte[] out;
+ int outp, inp;
+ int row;
+
+ row = (model.vis.numclusters+7)>>3;
+ out = decompressed;
+ outp = 0;
+ inp = offset;
+
+ if (in == null)
+ { // no vis info, so make all visible
+ while (row != 0)
+ {
+ out[outp++] = (byte)0xFF;
+ row--;
+ }
+ return decompressed;
+ }
+
+ do
+ {
+ if (in[inp] != 0)
+ {
+ out[outp++] = in[inp++];
+ continue;
+ }
+
+ c = in[inp + 1] & 0xFF;
+ inp += 2;
+ while (c != 0)
+ {
+ out[outp++] = 0;
+ c--;
+ }
+ } while (outp < row);
+
+ return decompressed;
+ }
+
+ /*
+ ==============
+ Mod_ClusterPVS
+ ==============
+ */
+ byte[] Mod_ClusterPVS(int cluster, model_t model)
+ {
+ if (cluster == -1 || model.vis == null)
+ return mod_novis;
+ //return Mod_DecompressVis( (byte *)model.vis + model.vis.bitofs[cluster][Defines.DVIS_PVS], model);
+ return Mod_DecompressVis(model_visibility, model.vis.bitofs[cluster][Defines.DVIS_PVS], model);
+ }
+
+
+// ===============================================================================
+
+ /*
+ ================
+ Mod_Modellist_f
+ ================
+ */
+ void Mod_Modellist_f()
+ {
+ int i;
+ model_t mod;
+ int total;
+
+ total = 0;
+ ri.Con_Printf(Defines.PRINT_ALL,"Loaded models:\n");
+ for (i=0; i < mod_numknown ; i++)
+ {
+ mod = mod_known[i];
+ if (mod.name == "")
+ continue;
+
+ ri.Con_Printf (Defines.PRINT_ALL, "%8i : %s\n", new Vargs(2).add(mod.extradatasize).add(mod.name));
+ total += mod.extradatasize;
+ }
+ ri.Con_Printf (Defines.PRINT_ALL, "Total resident: " + total +'\n');
+ }
+
+ /*
+ ===============
+ Mod_Init
+ ===============
+ */
+ void Mod_Init()
+ {
+ // init mod_known
+ for (int i=0; i < MAX_MOD_KNOWN; i++) {
+ mod_known[i] = new model_t();
+ }
+ Arrays.fill(mod_novis, (byte)0xff);
+ }
+
+ byte[] fileBuffer;
+
+ /*
+ ==================
+ Mod_ForName
+
+ Loads in a model for the given name
+ ==================
+ */
+ model_t Mod_ForName(String name, boolean crash)
+ {
+ model_t mod = null;
+ int i;
+
+ if (name == null || name.length() == 0)
+ ri.Sys_Error(Defines.ERR_DROP, "Mod_ForName: NULL name");
+
+ //
+ // inline models are grabbed only from worldmodel
+ //
+ if (name.charAt(0) == '*')
+ {
+ i = Integer.parseInt(name.substring(1));
+ if (i < 1 || r_worldmodel == null || i >= r_worldmodel.numsubmodels)
+ ri.Sys_Error (Defines.ERR_DROP, "bad inline model number");
+ return mod_inline[i];
+ }
+
+ //
+ // search the currently loaded models
+ //
+ for (i=0; i<mod_numknown ; i++)
+ {
+ mod = mod_known[i];
+
+ if (mod.name == "")
+ continue;
+ if (mod.name.equals(name) )
+ return mod;
+ }
+
+ //
+ // find a free model slot spot
+ //
+ for (i=0; i<mod_numknown ; i++)
+ {
+ mod = mod_known[i];
+
+ if (mod.name == "")
+ break; // free spot
+ }
+ if (i == mod_numknown)
+ {
+ if (mod_numknown == MAX_MOD_KNOWN)
+ ri.Sys_Error (Defines.ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
+ mod_numknown++;
+ mod = mod_known[i];
+ }
+
+ mod.name = name;
+
+ //
+ // load the file
+ //
+ fileBuffer = ri.FS_LoadFile(name);
+
+ if (fileBuffer == null)
+ {
+ if (crash)
+ ri.Sys_Error(Defines.ERR_DROP, "Mod_NumForName: " + mod.name + " not found");
+
+ mod.name = "";
+ return null;
+ }
+
+ modfilelen = fileBuffer.length;
+
+ loadmodel = mod;
+
+ //
+ // fill it in
+ //
+ ByteBuffer bb = ByteBuffer.wrap(fileBuffer);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ // call the apropriate loader
+
+ bb.mark();
+ int ident = bb.getInt();
+
+ bb.reset();
+
+ switch (ident)
+ {
+ case qfiles.IDALIASHEADER:
+ Mod_LoadAliasModel(mod, bb);
+ break;
+ case qfiles.IDSPRITEHEADER:
+ Mod_LoadSpriteModel(mod, bb);
+ break;
+ case qfiles.IDBSPHEADER:
+ Mod_LoadBrushModel(mod, bb);
+ break;
+ default:
+ ri.Sys_Error(Defines.ERR_DROP,"Mod_NumForName: unknown fileid for " + mod.name);
+ break;
+ }
+
+ this.fileBuffer = null; // free it for garbage collection
+ return mod;
+ }
+
+ /*
+ ===============================================================================
+
+ BRUSHMODEL LOADING
+
+ ===============================================================================
+ */
+
+ byte[] mod_base;
+
+
+ /*
+ =================
+ Mod_LoadLighting
+ =================
+ */
+ void Mod_LoadLighting(lump_t l)
+ {
+ if (l.filelen == 0)
+ {
+ loadmodel.lightdata = null;
+ return;
+ }
+ // memcpy (loadmodel.lightdata, mod_base + l.fileofs, l.filelen);
+ loadmodel.lightdata = new byte[l.filelen];
+ System.arraycopy(mod_base, l.fileofs, loadmodel.lightdata, 0, l.filelen);
+ }
+
+
+ /*
+ =================
+ Mod_LoadVisibility
+ =================
+ */
+ void Mod_LoadVisibility(lump_t l)
+ {
+ int i;
+
+ if (l.filelen == 0)
+ {
+ loadmodel.vis = null;
+ return;
+ }
+
+ System.arraycopy(mod_base, l.fileofs, model_visibility, 0, l.filelen);
+
+ ByteBuffer bb = ByteBuffer.wrap(model_visibility, 0, l.filelen);
+
+ loadmodel.vis = new qfiles.dvis_t(bb.order(ByteOrder.LITTLE_ENDIAN));
+
+ /* done:
+ memcpy (loadmodel.vis, mod_base + l.fileofs, l.filelen);
+
+ loadmodel.vis.numclusters = LittleLong (loadmodel.vis.numclusters);
+ for (i=0 ; i<loadmodel.vis.numclusters ; i++)
+ {
+ loadmodel.vis.bitofs[i][0] = LittleLong (loadmodel.vis.bitofs[i][0]);
+ loadmodel.vis.bitofs[i][1] = LittleLong (loadmodel.vis.bitofs[i][1]);
+ }
+ */
+ }
+
+
+ /*
+ =================
+ Mod_LoadVertexes
+ =================
+ */
+ void Mod_LoadVertexes(lump_t l)
+ {
+ mvertex_t[] vertexes;
+ int i, count;
+
+ if ( (l.filelen % mvertex_t.DISK_SIZE) != 0)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / mvertex_t.DISK_SIZE;
+
+ vertexes = new mvertex_t[count];
+
+ loadmodel.vertexes = vertexes;
+ loadmodel.numvertexes = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++)
+ {
+ vertexes[i] = new mvertex_t(bb);
+ }
+ }
+
+ /*
+ =================
+ RadiusFromBounds
+ =================
+ */
+ float RadiusFromBounds(float[] mins, float[] maxs)
+ {
+ float[] corner = {0, 0, 0};
+
+ for (int i=0 ; i<3 ; i++)
+ {
+ corner[i] = Math.abs(mins[i]) > Math.abs(maxs[i]) ? Math.abs(mins[i]) : Math.abs(maxs[i]);
+ }
+ return Math3D.VectorLength(corner);
+ }
+
+
+ /*
+ =================
+ Mod_LoadSubmodels
+ =================
+ */
+ void Mod_LoadSubmodels(lump_t l)
+ {
+ qfiles.dmodel_t in;
+ mmodel_t[] out;
+ int i, j, count;
+
+ if ((l.filelen % qfiles.dmodel_t.SIZE) != 0)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / qfiles.dmodel_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mmodel_t[count];
+
+ loadmodel.submodels = out;
+ loadmodel.numsubmodels = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++)
+ {
+ in = new qfiles.dmodel_t(bb);
+ out[i] = new mmodel_t();
+ for (j=0 ; j<3 ; j++)
+ { // spread the mins / maxs by a pixel
+ out[i].mins[j] = in.mins[j] - 1;
+ out[i].maxs[j] = in.maxs[j] + 1;
+ out[i].origin[j] = in.origin[j];
+ }
+ out[i].radius = RadiusFromBounds(out[i].mins, out[i].maxs);
+ out[i].headnode = in.headnode;
+ out[i].firstface = in.firstface;
+ out[i].numfaces = in.numfaces;
+ }
+ }
+
+ /*
+ =================
+ Mod_LoadEdges
+ =================
+ */
+ void Mod_LoadEdges (lump_t l)
+ {
+ medge_t[] edges;
+ int i, count;
+
+ if ( (l.filelen % medge_t.DISK_SIZE) != 0)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / medge_t.DISK_SIZE;
+ // out = Hunk_Alloc ( (count + 1) * sizeof(*out));
+ edges = new medge_t[count + 1];
+
+ loadmodel.edges = edges;
+ loadmodel.numedges = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++)
+ {
+ edges[i] = new medge_t(bb);
+ }
+ }
+
+ /*
+ =================
+ Mod_LoadTexinfo
+ =================
+ */
+ void Mod_LoadTexinfo(lump_t l)
+ {
+ texinfo_t in;
+ mtexinfo_t[] out;
+ mtexinfo_t step;
+ int i, j, count;
+ int next;
+ String name;
+
+ if ((l.filelen % texinfo_t.SIZE) != 0)
+ ri.Sys_Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / texinfo_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mtexinfo_t[count];
+ for ( i=0 ; i<count ; i++) {
+ out[i] = new mtexinfo_t();
+ }
+
+ loadmodel.texinfo = out;
+ loadmodel.numtexinfo = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++) {
+
+ in = new texinfo_t(bb);
+ out[i].vecs = in.vecs;
+ out[i].flags = in.flags;
+ next = in.nexttexinfo;
+ if (next > 0)
+ out[i].next = loadmodel.texinfo[next];
+ else
+ out[i].next = null;
+
+ name = "textures/" + in.texture + ".wal";
+
+ out[i].image = GL_FindImage(name, it_wall);
+ if (out[i].image == null) {
+ ri.Con_Printf(Defines.PRINT_ALL, "Couldn't load " + name + '\n');
+ out[i].image = r_notexture;
+ }
+ }
+
+ // count animation frames
+ for (i=0 ; i<count ; i++) {
+ out[i].numframes = 1;
+ for (step = out[i].next ; (step != null) && (step != out[i]) ; step=step.next)
+ out[i].numframes++;
+ }
+ }
+
+ /*
+ ================
+ CalcSurfaceExtents
+
+ Fills in s.texturemins[] and s.extents[]
+ ================
+ */
+ void CalcSurfaceExtents(msurface_t s)
+ {
+ float[] mins = {0, 0};
+ float[] maxs = {0, 0};
+ float val;
+
+ int i, j, e;
+ mvertex_t v;
+ mtexinfo_t tex;
+ int[] bmins = {0, 0};
+ int[] bmaxs = {0, 0};
+
+ mins[0] = mins[1] = 999999;
+ maxs[0] = maxs[1] = -99999;
+
+ tex = s.texinfo;
+
+ for (i=0 ; i<s.numedges ; i++)
+ {
+ e = loadmodel.surfedges[s.firstedge+i];
+ if (e >= 0)
+ v = loadmodel.vertexes[loadmodel.edges[e].v[0]];
+ else
+ v = loadmodel.vertexes[loadmodel.edges[-e].v[1]];
+
+ for (j=0 ; j<2 ; j++)
+ {
+ val = v.position[0] * tex.vecs[j][0] +
+ v.position[1] * tex.vecs[j][1] +
+ v.position[2] * tex.vecs[j][2] +
+ tex.vecs[j][3];
+ if (val < mins[j])
+ mins[j] = val;
+ if (val > maxs[j])
+ maxs[j] = val;
+ }
+ }
+
+ for (i=0 ; i<2 ; i++)
+ {
+ bmins[i] = (int)Math.floor(mins[i]/16);
+ bmaxs[i] = (int)Math.ceil(maxs[i]/16);
+
+ s.texturemins[i] = (short)(bmins[i] * 16);
+ s.extents[i] = (short)((bmaxs[i] - bmins[i]) * 16);
+
+ }
+ }
+
+ /*
+ =================
+ Mod_LoadFaces
+ =================
+ */
+ void Mod_LoadFaces (lump_t l)
+ {
+ qfiles.dface_t in;
+ msurface_t[] out;
+ int i, count, surfnum;
+ int planenum, side;
+ int ti;
+
+ if ((l.filelen % qfiles.dface_t.SIZE) != 0)
+ ri.Sys_Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / qfiles.dface_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new msurface_t[count];
+
+ loadmodel.surfaces = out;
+ loadmodel.numsurfaces = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ currentmodel = loadmodel;
+
+ GL_BeginBuildingLightmaps(loadmodel);
+
+ for ( surfnum=0 ; surfnum<count ; surfnum++)
+ {
+ in = new qfiles.dface_t(bb);
+ out[surfnum] = new msurface_t();
+ out[surfnum].firstedge = in.firstedge;
+ out[surfnum].numedges = in.numedges;
+ out[surfnum].flags = 0;
+ out[surfnum].polys = null;
+
+ planenum = in.planenum;
+ side = in.side;
+ if (side != 0)
+ out[surfnum].flags |= Defines.SURF_PLANEBACK;
+
+ out[surfnum].plane = loadmodel.planes[planenum];
+
+ ti = in.texinfo;
+ if (ti < 0 || ti >= loadmodel.numtexinfo)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: bad texinfo number");
+
+ out[surfnum].texinfo = loadmodel.texinfo[ti];
+
+ CalcSurfaceExtents(out[surfnum]);
+
+ // lighting info
+
+ for (i=0 ; i<Defines.MAXLIGHTMAPS ; i++)
+ out[surfnum].styles[i] = in.styles[i];
+
+ i = in.lightofs;
+ if (i == -1)
+ out[surfnum].samples = null;
+ else {
+ ByteBuffer pointer = ByteBuffer.wrap(loadmodel.lightdata);
+ pointer.position(i);
+ pointer = pointer.slice();
+ pointer.mark();
+ out[surfnum].samples = pointer; // subarray
+ }
+
+ // set the drawing flags
+
+ if ((out[surfnum].texinfo.flags & Defines.SURF_WARP) != 0)
+ {
+ out[surfnum].flags |= Defines.SURF_DRAWTURB;
+ for (i=0 ; i<2 ; i++)
+ {
+ out[surfnum].extents[i] = 16384;
+ out[surfnum].texturemins[i] = -8192;
+ }
+ GL_SubdivideSurface(out[surfnum]); // cut up polygon for warps
+ }
+
+ // create lightmaps and polygons
+ if ((out[surfnum].texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) == 0)
+ GL_CreateSurfaceLightmap(out[surfnum]);
+
+ if ((out[surfnum].texinfo.flags & Defines.SURF_WARP) == 0)
+ GL_BuildPolygonFromSurface(out[surfnum]);
+
+ }
+ GL_EndBuildingLightmaps ();
+ }
+
+
+ /*
+ =================
+ Mod_SetParent
+ =================
+ */
+ void Mod_SetParent(mnode_t node, mnode_t parent)
+ {
+ node.parent = parent;
+ if (node.contents != -1) return;
+ Mod_SetParent(node.children[0], node);
+ Mod_SetParent(node.children[1], node);
+ }
+
+ /*
+ =================
+ Mod_LoadNodes
+ =================
+ */
+ void Mod_LoadNodes(lump_t l)
+ {
+ int i, j, count, p;
+ qfiles.dnode_t in;
+ mnode_t[] out;
+
+ if ((l.filelen % qfiles.dnode_t.SIZE) != 0)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / qfiles.dnode_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mnode_t[count];
+
+ loadmodel.nodes = out;
+ loadmodel.numnodes = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ // initialize the tree array
+ for ( i=0 ; i<count ; i++) out[i] = new mnode_t(); // do first before linking
+
+ // fill and link the nodes
+ for ( i=0 ; i<count ; i++)
+ {
+ in = new qfiles.dnode_t(bb);
+ for (j=0 ; j<3 ; j++)
+ {
+ out[i].mins[j] = in.mins[j];
+ out[i].maxs[j] = in.maxs[j];
+ }
+
+ p = in.planenum;
+ out[i].plane = loadmodel.planes[p];
+
+ out[i].firstsurface = in.firstface;
+ out[i].numsurfaces = in.numfaces;
+ out[i].contents = -1; // differentiate from leafs
+
+ for (j=0 ; j<2 ; j++)
+ {
+ p = in.children[j];
+ if (p >= 0)
+ out[i].children[j] = loadmodel.nodes[p];
+ else
+ out[i].children[j] = loadmodel.leafs[-1 - p]; // mleaf_t extends mnode_t
+ }
+ }
+
+ Mod_SetParent(loadmodel.nodes[0], null); // sets nodes and leafs
+ }
+
+ /*
+ =================
+ Mod_LoadLeafs
+ =================
+ */
+ void Mod_LoadLeafs(lump_t l)
+ {
+ qfiles.dleaf_t in;
+ mleaf_t[] out;
+ int i, j, count, p;
+
+ if ((l.filelen % qfiles.dleaf_t.SIZE) != 0)
+ ri.Sys_Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / qfiles.dleaf_t.SIZE;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new mleaf_t[count];
+
+ loadmodel.leafs = out;
+ loadmodel.numleafs = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++)
+ {
+ in = new qfiles.dleaf_t(bb);
+ out[i] = new mleaf_t();
+ for (j=0 ; j<3 ; j++)
+ {
+ out[i].mins[j] = in.mins[j];
+ out[i].maxs[j] = in.maxs[j];
+
+ }
+
+ out[i].contents = in.contents;
+ out[i].cluster = in.cluster;
+ out[i].area = in.area;
+
+ out[i].setMarkSurface(in.firstleafface, loadmodel.marksurfaces);
+ out[i].nummarksurfaces = in.numleaffaces;
+ }
+ }
+
+
+ /*
+ =================
+ Mod_LoadMarksurfaces
+ =================
+ */
+ void Mod_LoadMarksurfaces(lump_t l)
+ {
+ int i, j, count;
+
+ msurface_t[] out;
+
+ if ((l.filelen % Defines.SIZE_OF_SHORT) != 0)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+ count = l.filelen / Defines.SIZE_OF_SHORT;
+ // out = Hunk_Alloc ( count*sizeof(*out));
+ out = new msurface_t[count];
+
+ loadmodel.marksurfaces = out;
+ loadmodel.nummarksurfaces = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++)
+ {
+ j = bb.getShort();
+ if (j < 0 || j >= loadmodel.numsurfaces)
+ ri.Sys_Error(Defines.ERR_DROP, "Mod_ParseMarksurfaces: bad surface number");
+
+ out[i] = loadmodel.surfaces[j];
+ }
+ }
+
+
+ /*
+ =================
+ Mod_LoadSurfedges
+ =================
+ */
+ void Mod_LoadSurfedges(lump_t l)
+ {
+ int i, count;
+ int[] offsets;
+
+ if ( (l.filelen % Defines.SIZE_OF_INT) != 0)
+ ri.Sys_Error (Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / Defines.SIZE_OF_INT;
+ if (count < 1 || count >= Defines.MAX_MAP_SURFEDGES)
+ ri.Sys_Error (Defines.ERR_DROP, "MOD_LoadBmodel: bad surfedges count in " + loadmodel.name + ": " + count);
+
+ offsets = new int[count];
+
+ loadmodel.surfedges = offsets;
+ loadmodel.numsurfedges = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++) offsets[i] = bb.getInt();
+ }
+
+
+ /*
+ =================
+ Mod_LoadPlanes
+ =================
+ */
+ void Mod_LoadPlanes(lump_t l)
+ {
+ int i, j;
+ cplane_t[] out;
+ qfiles.dplane_t in;
+ int count;
+ int bits;
+
+ if ((l.filelen % qfiles.dplane_t.SIZE) != 0)
+ ri.Sys_Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
+
+ count = l.filelen / qfiles.dplane_t.SIZE;
+ // out = Hunk_Alloc ( count*2*sizeof(*out));
+ out = new cplane_t[count * 2];
+
+ loadmodel.planes = out;
+ loadmodel.numplanes = count;
+
+ ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+
+ for ( i=0 ; i<count ; i++)
+ {
+ bits = 0;
+ in = new qfiles.dplane_t(bb);
+ out[i] = new cplane_t();
+ for (j=0 ; j<3 ; j++)
+ {
+ out[i].normal[j] = in.normal[j];
+ if (out[i].normal[j] < 0)
+ bits |= (1<<j);
+ }
+
+ out[i].dist = in.dist;
+ out[i].type = (byte)in.type;
+ out[i].signbits = (byte)bits;
+ }
+ }
+
+ /*
+ =================
+ Mod_LoadBrushModel
+ =================
+ */
+ void Mod_LoadBrushModel(model_t mod, ByteBuffer buffer)
+ {
+ int i;
+ qfiles.dheader_t header;
+ mmodel_t bm;
+
+ loadmodel.type = mod_brush;
+ if (loadmodel != mod_known[0])
+ ri.Sys_Error(Defines.ERR_DROP, "Loaded a brush model after the world");
+
+ header = new qfiles.dheader_t(buffer);
+
+ i = header.version;
+ if (i != Defines.BSPVERSION)
+ ri.Sys_Error (Defines.ERR_DROP, "Mod_LoadBrushModel: " + mod.name + " has wrong version number (" + i + " should be " + Defines.BSPVERSION + ")");
+
+ mod_base = fileBuffer; //(byte *)header;
+
+ // load into heap
+ Mod_LoadVertexes(header.lumps[Defines.LUMP_VERTEXES]); // ok
+ Mod_LoadEdges(header.lumps[Defines.LUMP_EDGES]); // ok
+ Mod_LoadSurfedges(header.lumps[Defines.LUMP_SURFEDGES]); // ok
+ Mod_LoadLighting(header.lumps[Defines.LUMP_LIGHTING]); // ok
+ Mod_LoadPlanes(header.lumps[Defines.LUMP_PLANES]); // ok
+ Mod_LoadTexinfo(header.lumps[Defines.LUMP_TEXINFO]); // ok
+ Mod_LoadFaces(header.lumps[Defines.LUMP_FACES]); // ok
+ Mod_LoadMarksurfaces(header.lumps[Defines.LUMP_LEAFFACES]);
+ Mod_LoadVisibility(header.lumps[Defines.LUMP_VISIBILITY]); // ok
+ Mod_LoadLeafs(header.lumps[Defines.LUMP_LEAFS]); // ok
+ Mod_LoadNodes(header.lumps[Defines.LUMP_NODES]); // ok
+ Mod_LoadSubmodels(header.lumps[Defines.LUMP_MODELS]);
+ mod.numframes = 2; // regular and alternate animation
+
+ //
+ // set up the submodels
+ //
+ model_t starmod;
+
+ for (i=0 ; i<mod.numsubmodels ; i++)
+ {
+
+ bm = mod.submodels[i];
+ starmod = mod_inline[i] = loadmodel.copy();
+
+ starmod.firstmodelsurface = bm.firstface;
+ starmod.nummodelsurfaces = bm.numfaces;
+ starmod.firstnode = bm.headnode;
+ if (starmod.firstnode >= loadmodel.numnodes)
+ ri.Sys_Error(Defines.ERR_DROP, "Inline model " + i + " has bad firstnode");
+
+ Math3D.VectorCopy(bm.maxs, starmod.maxs);
+ Math3D.VectorCopy(bm.mins, starmod.mins);
+ starmod.radius = bm.radius;
+
+ if (i == 0)
+ loadmodel = starmod.copy();
+
+ starmod.numleafs = bm.visleafs;
+ }
+ }
+
+ /*
+ ==============================================================================
+
+ ALIAS MODELS
+
+ ==============================================================================
+ */
+
+ /*
+ =================
+ Mod_LoadAliasModel
+ =================
+ */
+ void Mod_LoadAliasModel (model_t mod, ByteBuffer buffer)
+ {
+ int i, j;
+ qfiles.dmdl_t pheader;
+ qfiles.dstvert_t[] poutst;
+ qfiles.dtriangle_t[] pouttri;
+ qfiles.daliasframe_t[] poutframe;
+ int[] poutcmd;
+
+ pheader = new qfiles.dmdl_t(buffer);
+
+ if (pheader.version != qfiles.ALIAS_VERSION)
+ ri.Sys_Error(Defines.ERR_DROP, "%s has wrong version number (%i should be %i)",
+ new Vargs(3).add(mod.name).add(pheader.version).add(qfiles.ALIAS_VERSION));
+
+ if (pheader.skinheight > MAX_LBM_HEIGHT)
+ ri.Sys_Error(Defines.ERR_DROP, "model "+ mod.name +" has a skin taller than " + MAX_LBM_HEIGHT);
+
+ if (pheader.num_xyz <= 0)
+ ri.Sys_Error(Defines.ERR_DROP, "model " + mod.name + " has no vertices");
+
+ if (pheader.num_xyz > qfiles.MAX_VERTS)
+ ri.Sys_Error(Defines.ERR_DROP, "model " + mod.name +" has too many vertices");
+
+ if (pheader.num_st <= 0)
+ ri.Sys_Error(Defines.ERR_DROP, "model " + mod.name + " has no st vertices");
+
+ if (pheader.num_tris <= 0)
+ ri.Sys_Error(Defines.ERR_DROP, "model " + mod.name + " has no triangles");
+
+ if (pheader.num_frames <= 0)
+ ri.Sys_Error(Defines.ERR_DROP, "model " + mod.name + " has no frames");
+
+ //
+ // load base s and t vertices (not used in gl version)
+ //
+ poutst = new qfiles.dstvert_t[pheader.num_st];
+ buffer.position(pheader.ofs_st);
+ for (i=0 ; i<pheader.num_st ; i++)
+ {
+ poutst[i] = new qfiles.dstvert_t(buffer);
+ }
+
+ //
+ // load triangle lists
+ //
+ pouttri = new qfiles.dtriangle_t[pheader.num_tris];
+ buffer.position(pheader.ofs_tris);
+ for (i=0 ; i<pheader.num_tris ; i++)
+ {
+ pouttri[i] = new qfiles.dtriangle_t(buffer);
+ }
+
+ //
+ // load the frames
+ //
+ poutframe = new qfiles.daliasframe_t[pheader.num_frames];
+ buffer.position(pheader.ofs_frames);
+ for (i=0 ; i<pheader.num_frames ; i++)
+ {
+ poutframe[i] = new qfiles.daliasframe_t(buffer);
+ // verts are all 8 bit, so no swapping needed
+ poutframe[i].verts = new qfiles.dtrivertx_t[pheader.num_xyz];
+ for (int k=0; k < pheader.num_xyz; k++) {
+ poutframe[i].verts[k] = new qfiles.dtrivertx_t(buffer);
+ }
+ }
+
+ mod.type = mod_alias;
+
+ //
+ // load the glcmds
+ //
+ poutcmd = new int[pheader.num_glcmds];
+ buffer.position(pheader.ofs_glcmds);
+ for (i=0 ; i<pheader.num_glcmds ; i++)
+ poutcmd[i] = buffer.getInt(); // LittleLong (pincmd[i]);
+
+ // register all skins
+ String[] skinNames = new String[pheader.num_skins];
+ byte[] nameBuf = new byte[qfiles.MAX_SKINNAME];
+ buffer.position(pheader.ofs_skins);
+ for (i=0 ; i<pheader.num_skins ; i++)
+ {
+ buffer.get(nameBuf);
+ skinNames[i] = new String(nameBuf).trim();
+ mod.skins[i] = GL_FindImage(skinNames[i], it_skin);
+ }
+
+ // set the model arrays
+ pheader.skinNames = skinNames; // skin names
+ pheader.stVerts = poutst; // textur koordinaten
+ pheader.triAngles = pouttri; // dreiecke
+ pheader.glCmds = poutcmd; // STRIP or FAN
+ pheader.aliasFrames = poutframe; // frames mit vertex array
+
+ mod.extradata = pheader;
+
+ mod.mins[0] = -32;
+ mod.mins[1] = -32;
+ mod.mins[2] = -32;
+ mod.maxs[0] = 32;
+ mod.maxs[1] = 32;
+ mod.maxs[2] = 32;
+
+ precompileGLCmds(pheader);
+ }
+
+ /*
+ ==============================================================================
+
+ SPRITE MODELS
+
+ ==============================================================================
+ */
+
+ /*
+ =================
+ Mod_LoadSpriteModel
+ =================
+ */
+ void Mod_LoadSpriteModel(model_t mod, ByteBuffer buffer)
+ {
+ qfiles.dsprite_t sprout = new qfiles.dsprite_t(buffer);
+
+ if (sprout.version != qfiles.SPRITE_VERSION)
+ ri.Sys_Error(Defines.ERR_DROP, "%s has wrong version number (%i should be %i)",
+ new Vargs(3).add(mod.name).add(sprout.version).add(qfiles.SPRITE_VERSION));
+
+ if (sprout.numframes > qfiles.MAX_MD2SKINS)
+ ri.Sys_Error(Defines.ERR_DROP, "%s has too many frames (%i > %i)",
+ new Vargs(3).add(mod.name).add(sprout.numframes).add(qfiles.MAX_MD2SKINS));
+
+ for (int i=0 ; i<sprout.numframes ; i++)
+ {
+ mod.skins[i] = GL_FindImage(sprout.frames[i].name, it_sprite);
+ }
+
+ mod.type = mod_sprite;
+ mod.extradata = sprout;
+ }
+
+// =============================================================================
+
+ /*
+ @@@@@@@@@@@@@@@@@@@@@
+ R_BeginRegistration
+
+ Specifies the model that will be used as the world
+ @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected void R_BeginRegistration(String model)
+ {
+ resetModelArrays();
+ resetPolygonArrays();
+
+ cvar_t flushmap;
+
+ registration_sequence++;
+ r_oldviewcluster = -1; // force markleafs
+
+ String fullname = "maps/" + model + ".bsp";
+
+ // explicitly free the old map if different
+ // this guarantees that mod_known[0] is the world map
+ flushmap = ri.Cvar_Get("flushmap", "0", 0);
+ if ( !mod_known[0].name.equals(fullname) || flushmap.value != 0.0f)
+ Mod_Free(mod_known[0]);
+ r_worldmodel = Mod_ForName(fullname, true);
+
+ r_viewcluster = -1;
+ }
+
+
+ /*
+ @@@@@@@@@@@@@@@@@@@@@
+ R_RegisterModel
+
+ @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected model_t R_RegisterModel(String name)
+ {
+ model_t mod = null;
+ int i;
+ qfiles.dsprite_t sprout;
+ qfiles.dmdl_t pheader;
+
+ mod = Mod_ForName(name, false);
+ if (mod != null)
+ {
+ mod.registration_sequence = registration_sequence;
+
+ // register any images used by the models
+ if (mod.type == mod_sprite)
+ {
+ sprout = (qfiles.dsprite_t)mod.extradata;
+ for (i=0 ; i<sprout.numframes ; i++)
+ mod.skins[i] = GL_FindImage(sprout.frames[i].name, it_sprite);
+ }
+ else if (mod.type == mod_alias)
+ {
+ pheader = (qfiles.dmdl_t)mod.extradata;
+ for (i=0 ; i<pheader.num_skins ; i++)
+ mod.skins[i] = GL_FindImage(pheader.skinNames[i], it_skin);
+ // PGM
+ mod.numframes = pheader.num_frames;
+ // PGM
+ }
+ else if (mod.type == mod_brush)
+ {
+ for (i=0 ; i<mod.numtexinfo ; i++)
+ mod.texinfo[i].image.registration_sequence = registration_sequence;
+ }
+ }
+ return mod;
+ }
+
+
+ /*
+ @@@@@@@@@@@@@@@@@@@@@
+ R_EndRegistration
+
+ @@@@@@@@@@@@@@@@@@@@@
+ */
+ protected void R_EndRegistration()
+ {
+ model_t mod;
+
+ for (int i=0; i<mod_numknown ; i++)
+ {
+ mod = mod_known[i];
+ if (mod.name == "")
+ continue;
+ if (mod.registration_sequence != registration_sequence)
+ { // don't need this model
+ Mod_Free(mod);
+ } else {
+ // precompile AliasModels
+ if (mod.type == mod_alias)
+ precompileGLCmds((qfiles.dmdl_t)mod.extradata);
+ }
+ }
+ GL_FreeUnusedImages();
+
+ //modelMemoryUsage();
+ }
+
+
+// =============================================================================
+
+
+ /*
+ ================
+ Mod_Free
+ ================
+ */
+ void Mod_Free (model_t mod)
+ {
+ mod.clear();
+ }
+
+ /*
+ ================
+ Mod_FreeAll
+ ================
+ */
+ void Mod_FreeAll()
+ {
+ for (int i=0 ; i<mod_numknown ; i++)
+ {
+ if (mod_known[i].extradata != null)
+ Mod_Free(mod_known[i]);
+ }
+ }
+
+ /*
+ * new functions for vertex array handling
+ */
+ static final int MODEL_BUFFER_SIZE = 50000;
+ static FloatBuffer globalModelTextureCoordBuf = BufferUtils.newFloatBuffer(MODEL_BUFFER_SIZE * 2);
+ static IntBuffer globalModelVertexIndexBuf = BufferUtils.newIntBuffer(MODEL_BUFFER_SIZE);
+
+ void precompileGLCmds(qfiles.dmdl_t model) {
+ model.textureCoordBuf = globalModelTextureCoordBuf.slice();
+ model.vertexIndexBuf = globalModelVertexIndexBuf.slice();
+ Vector tmp = new Vector();
+
+ int count = 0;
+ int[] order = model.glCmds;
+ int orderIndex = 0;
+ while (true)
+ {
+ // get the vertex count and primitive type
+ count = order[orderIndex++];
+ if (count == 0)
+ break; // done
+
+ tmp.addElement(new Integer(count));
+
+ if (count < 0)
+ {
+ count = -count;
+ //gl.glBegin (GL.GL_TRIANGLE_FAN);
+ }
+ else
+ {
+ //gl.glBegin (GL.GL_TRIANGLE_STRIP);
+ }
+
+ do {
+ // texture coordinates come from the draw list
+ globalModelTextureCoordBuf.put(Float.intBitsToFloat(order[orderIndex + 0]));
+ globalModelTextureCoordBuf.put(Float.intBitsToFloat(order[orderIndex + 1]));
+ globalModelVertexIndexBuf.put(order[orderIndex + 2]);
+
+ orderIndex += 3;
+ } while (--count != 0);
+ }
+
+ int size = tmp.size();
+
+ model.counts = new int[size];
+ model.indexElements = new IntBuffer[size];
+
+ count = 0;
+ int pos = 0;
+ for (int i = 0; i < model.counts.length; i++) {
+ count = ((Integer)tmp.get(i)).intValue();
+ model.counts[i] = count;
+
+ count = (count < 0) ? -count : count;
+ model.vertexIndexBuf.position(pos);
+ model.indexElements[i] = model.vertexIndexBuf.slice();
+ pos += count;
+ }
+ }
+
+ static void resetModelArrays() {
+ globalModelTextureCoordBuf.rewind();
+ globalModelVertexIndexBuf.rewind();
+ }
+
+ static void modelMemoryUsage() {
+ System.out.println("AliasModels: globalVertexBuffer size " + globalModelVertexIndexBuf.position());
+ }
+}
diff --git a/src/jake2/render/fastjogl/Surf.java b/src/jake2/render/fastjogl/Surf.java
new file mode 100644
index 0000000..c7e7bc0
--- /dev/null
+++ b/src/jake2/render/fastjogl/Surf.java
@@ -0,0 +1,1464 @@
+/*
+ * Surf.java
+ * Copyright (C) 2003
+ *
+ * $Id: Surf.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import jake2.Defines;
+import jake2.client.*;
+import jake2.game.cplane_t;
+import jake2.render.*;
+import jake2.util.Lib;
+import jake2.util.Math3D;
+
+import java.nio.*;
+import java.util.Arrays;
+
+import net.java.games.jogl.GL;
+import net.java.games.jogl.util.BufferUtils;
+
+/**
+ * Surf
+ *
+ * @author cwei
+ */
+public abstract class Surf extends Draw {
+
+ // GL_RSURF.C: surface-related refresh code
+ float[] modelorg = {0, 0, 0}; // relative to viewpoint
+
+ msurface_t r_alpha_surfaces;
+
+ static final int DYNAMIC_LIGHT_WIDTH = 128;
+ static final int DYNAMIC_LIGHT_HEIGHT = 128;
+
+ static final int LIGHTMAP_BYTES = 4;
+
+ static final int BLOCK_WIDTH = 128;
+ static final int BLOCK_HEIGHT = 128;
+
+ static final int MAX_LIGHTMAPS = 128;
+
+ int c_visible_lightmaps;
+ int c_visible_textures;
+
+ static final int GL_LIGHTMAP_FORMAT = GL.GL_RGBA;
+
+ static class gllightmapstate_t
+ {
+ int internal_format;
+ int current_lightmap_texture;
+
+ msurface_t[] lightmap_surfaces = new msurface_t[MAX_LIGHTMAPS];
+ int[] allocated = new int[BLOCK_WIDTH];
+
+ // the lightmap texture data needs to be kept in
+ // main memory so texsubimage can update properly
+ //byte[] lightmap_buffer = new byte[4 * BLOCK_WIDTH * BLOCK_HEIGHT];
+ IntBuffer lightmap_buffer = Lib.newIntBuffer(BLOCK_WIDTH * BLOCK_HEIGHT, ByteOrder.LITTLE_ENDIAN);
+
+ public gllightmapstate_t() {
+ for (int i = 0; i < MAX_LIGHTMAPS; i++)
+ lightmap_surfaces[i] = new msurface_t();
+ }
+
+ public void clearLightmapSurfaces() {
+ for (int i = 0; i < MAX_LIGHTMAPS; i++)
+ // TODO lightmap_surfaces[i].clear();
+ lightmap_surfaces[i] = new msurface_t();
+ }
+
+ }
+
+ gllightmapstate_t gl_lms = new gllightmapstate_t();
+
+ // Model.java
+ abstract byte[] Mod_ClusterPVS(int cluster, model_t model);
+ // Warp.java
+ abstract void R_DrawSkyBox();
+ abstract void R_AddSkySurface(msurface_t surface);
+ abstract void R_ClearSkyBox();
+ abstract void EmitWaterPolys(msurface_t fa);
+ // Light.java
+ abstract void R_MarkLights (dlight_t light, int bit, mnode_t node);
+ abstract void R_SetCacheState( msurface_t surf );
+ abstract void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride);
+
+ /*
+ =============================================================
+
+ BRUSH MODELS
+
+ =============================================================
+ */
+
+ /*
+ ===============
+ R_TextureAnimation
+
+ Returns the proper texture for a given time and base texture
+ ===============
+ */
+ image_t R_TextureAnimation(mtexinfo_t tex)
+ {
+ int c;
+
+ if (tex.next == null)
+ return tex.image;
+
+ c = currententity.frame % tex.numframes;
+ while (c != 0)
+ {
+ tex = tex.next;
+ c--;
+ }
+
+ return tex.image;
+ }
+
+ /*
+ ================
+ DrawGLPoly
+ ================
+ */
+ void DrawGLPoly(glpoly_t p)
+ {
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+
+ // ============
+ // PGM
+ /*
+ ================
+ DrawGLFlowingPoly -- version of DrawGLPoly that handles scrolling texture
+ ================
+ */
+ void DrawGLFlowingPoly(glpoly_t p)
+ {
+ int i;
+ float scroll;
+
+ scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );
+ if(scroll == 0.0f)
+ scroll = -64.0f;
+
+ FloatBuffer texCoord = globalPolygonInterleavedBuf;
+ float[][] v = p.verts;
+ int index = p.pos * POLYGON_STRIDE;
+ for (i=0 ; i<p.numverts ; i++) {
+ texCoord.put(index, v[i][3] + scroll);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ // PGM
+ // ============
+
+ /*
+ ** R_DrawTriangleOutlines
+ */
+ void R_DrawTriangleOutlines()
+ {
+ int i, j;
+ glpoly_t p;
+
+ if (gl_showtris.value == 0)
+ return;
+
+ gl.glDisable (GL.GL_TEXTURE_2D);
+ gl.glDisable (GL.GL_DEPTH_TEST);
+ gl.glColor4f (1,1,1,1);
+
+ for (i=0 ; i<MAX_LIGHTMAPS ; i++)
+ {
+ msurface_t surf;
+
+ for ( surf = gl_lms.lightmap_surfaces[i]; surf != null; surf = surf.lightmapchain )
+ {
+ p = surf.polys;
+ for ( ; p != null ; p=p.chain)
+ {
+ for (j=2 ; j<p.numverts ; j++ )
+ {
+ gl.glBegin (GL.GL_LINE_STRIP);
+ gl.glVertex3fv (p.verts[0]);
+ gl.glVertex3fv (p.verts[j-1]);
+ gl.glVertex3fv (p.verts[j]);
+ gl.glVertex3fv (p.verts[0]);
+ gl.glEnd ();
+ }
+ }
+ }
+ }
+
+ gl.glEnable (GL.GL_DEPTH_TEST);
+ gl.glEnable (GL.GL_TEXTURE_2D);
+ }
+
+ private IntBuffer temp2 = Lib.newIntBuffer(34 * 34, ByteOrder.LITTLE_ENDIAN);
+
+ /*
+ ================
+ R_RenderBrushPoly
+ ================
+ */
+ void R_RenderBrushPoly(msurface_t fa)
+ {
+ int maps;
+ image_t image;
+ boolean is_dynamic = false;
+
+ c_brush_polys++;
+
+ image = R_TextureAnimation(fa.texinfo);
+
+ if ((fa.flags & Defines.SURF_DRAWTURB) != 0)
+ {
+ GL_Bind( image.texnum );
+
+ // warp texture, no lightmaps
+ GL_TexEnv( GL.GL_MODULATE );
+ gl.glColor4f( gl_state.inverse_intensity,
+ gl_state.inverse_intensity,
+ gl_state.inverse_intensity,
+ 1.0F );
+ EmitWaterPolys (fa);
+ GL_TexEnv( GL.GL_REPLACE );
+
+ return;
+ }
+ else
+ {
+ GL_Bind( image.texnum );
+ GL_TexEnv( GL.GL_REPLACE );
+ }
+
+ // ======
+ // PGM
+ if((fa.texinfo.flags & Defines.SURF_FLOWING) != 0)
+ DrawGLFlowingPoly(fa.polys);
+ else
+ DrawGLPoly (fa.polys);
+ // PGM
+ // ======
+
+ // ersetzt goto
+ boolean gotoDynamic = false;
+ /*
+ ** check for lightmap modification
+ */
+ for ( maps = 0; maps < Defines.MAXLIGHTMAPS && fa.styles[maps] != (byte)255; maps++ )
+ {
+ if ( r_newrefdef.lightstyles[fa.styles[maps] & 0xFF].white != fa.cached_light[maps] ) {
+ gotoDynamic = true;
+ break;
+ }
+ }
+
+ // this is a hack from cwei
+ if (maps == 4) maps--;
+
+ // dynamic this frame or dynamic previously
+ if ( gotoDynamic || ( fa.dlightframe == r_framecount ) )
+ {
+ // label dynamic:
+ if ( gl_dynamic.value != 0 )
+ {
+ if (( fa.texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP ) ) == 0)
+ {
+ is_dynamic = true;
+ }
+ }
+ }
+
+ if ( is_dynamic )
+ {
+ if ( ( (fa.styles[maps] & 0xFF) >= 32 || fa.styles[maps] == 0 ) && ( fa.dlightframe != r_framecount ) )
+ {
+ // ist ersetzt durch temp2: unsigned temp[34*34];
+ int smax, tmax;
+
+ smax = (fa.extents[0]>>4)+1;
+ tmax = (fa.extents[1]>>4)+1;
+
+ R_BuildLightMap( fa, temp2, smax);
+ R_SetCacheState( fa );
+
+ GL_Bind( gl_state.lightmap_textures + fa.lightmaptexturenum );
+
+ gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0,
+ fa.light_s, fa.light_t,
+ smax, tmax,
+ GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, temp2 );
+
+ fa.lightmapchain = gl_lms.lightmap_surfaces[fa.lightmaptexturenum];
+ gl_lms.lightmap_surfaces[fa.lightmaptexturenum] = fa;
+ }
+ else
+ {
+ fa.lightmapchain = gl_lms.lightmap_surfaces[0];
+ gl_lms.lightmap_surfaces[0] = fa;
+ }
+ }
+ else
+ {
+ fa.lightmapchain = gl_lms.lightmap_surfaces[fa.lightmaptexturenum];
+ gl_lms.lightmap_surfaces[fa.lightmaptexturenum] = fa;
+ }
+ }
+
+
+ /*
+ ================
+ R_DrawAlphaSurfaces
+
+ Draw water surfaces and windows.
+ The BSP tree is waled front to back, so unwinding the chain
+ of alpha_surfaces will draw back to front, giving proper ordering.
+ ================
+ */
+ void R_DrawAlphaSurfaces()
+ {
+ msurface_t s;
+ float intens;
+
+ //
+ // go back to the world matrix
+ //
+ gl.glLoadMatrixf(r_world_matrix);
+
+ gl.glEnable (GL.GL_BLEND);
+ GL_TexEnv(GL.GL_MODULATE );
+
+
+ // the textures are prescaled up for a better lighting range,
+ // so scale it back down
+ intens = gl_state.inverse_intensity;
+
+ gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE, globalPolygonInterleavedBuf);
+
+ for (s=r_alpha_surfaces ; s != null ; s=s.texturechain)
+ {
+ GL_Bind(s.texinfo.image.texnum);
+ c_brush_polys++;
+ if ((s.texinfo.flags & Defines.SURF_TRANS33) != 0)
+ gl.glColor4f (intens, intens, intens, 0.33f);
+ else if ((s.texinfo.flags & Defines.SURF_TRANS66) != 0)
+ gl.glColor4f (intens, intens, intens, 0.66f);
+ else
+ gl.glColor4f (intens,intens,intens,1);
+ if ((s.flags & Defines.SURF_DRAWTURB) != 0)
+ EmitWaterPolys(s);
+ else if((s.texinfo.flags & Defines.SURF_FLOWING) != 0) // PGM 9/16/98
+ DrawGLFlowingPoly(s.polys); // PGM
+ else
+ DrawGLPoly(s.polys);
+ }
+
+ GL_TexEnv( GL.GL_REPLACE );
+ gl.glColor4f (1,1,1,1);
+ gl.glDisable (GL.GL_BLEND);
+
+ r_alpha_surfaces = null;
+ }
+
+ /*
+ ================
+ DrawTextureChains
+ ================
+ */
+ void DrawTextureChains()
+ {
+ int i;
+ msurface_t s;
+ image_t image;
+
+ c_visible_textures = 0;
+
+ for (i = 0; i < numgltextures ; i++)
+ {
+ image = gltextures[i];
+
+ if (image.registration_sequence == 0)
+ continue;
+ if (image.texturechain == null)
+ continue;
+ c_visible_textures++;
+
+ for ( s = image.texturechain; s != null ; s=s.texturechain)
+ {
+ if ( ( s.flags & Defines.SURF_DRAWTURB) == 0 )
+ R_RenderBrushPoly(s);
+ }
+ }
+
+ GL_EnableMultitexture( false );
+ for (i = 0; i < numgltextures ; i++)
+ {
+ image = gltextures[i];
+
+ if (image.registration_sequence == 0)
+ continue;
+ s = image.texturechain;
+ if (s == null)
+ continue;
+
+ for ( ; s != null ; s=s.texturechain)
+ {
+ if ( (s.flags & Defines.SURF_DRAWTURB) != 0 )
+ R_RenderBrushPoly(s);
+ }
+
+ image.texturechain = null;
+ }
+
+ GL_TexEnv( GL.GL_REPLACE );
+ }
+
+ // direct buffer
+ private IntBuffer temp = Lib.newIntBuffer(128 * 128, ByteOrder.LITTLE_ENDIAN);
+
+ void GL_RenderLightmappedPoly( msurface_t surf )
+ {
+ int i, nv = surf.polys.numverts;
+ int map = 0;
+ int index;
+ float[][] v;
+ FloatBuffer texCoord = globalPolygonInterleavedBuf;
+ image_t image = R_TextureAnimation( surf.texinfo );
+ boolean is_dynamic = false;
+ int lmtex = surf.lightmaptexturenum;
+ glpoly_t p;
+
+ // ersetzt goto
+ boolean gotoDynamic = false;
+
+ for ( map = 0; map < Defines.MAXLIGHTMAPS && (surf.styles[map] != (byte)255); map++ )
+ {
+ if ( r_newrefdef.lightstyles[surf.styles[map] & 0xFF].white != surf.cached_light[map] ) {
+ gotoDynamic = true;
+ break;
+ }
+ }
+
+ // this is a hack from cwei
+ if (map == 4) map--;
+
+ // dynamic this frame or dynamic previously
+ if ( gotoDynamic || ( surf.dlightframe == r_framecount ) )
+ {
+ // label dynamic:
+ if ( gl_dynamic.value != 0 )
+ {
+ if ( (surf.texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP )) == 0 )
+ {
+ is_dynamic = true;
+ }
+ }
+ }
+
+ if ( is_dynamic )
+ {
+ // ist raus gezogen worden int[] temp = new int[128*128];
+ int smax, tmax;
+
+ if ( ( (surf.styles[map] & 0xFF) >= 32 || surf.styles[map] == 0 ) && ( surf.dlightframe != r_framecount ) )
+ {
+ smax = (surf.extents[0]>>4)+1;
+ tmax = (surf.extents[1]>>4)+1;
+
+ R_BuildLightMap( surf, temp, smax);
+ R_SetCacheState( surf );
+
+ GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + surf.lightmaptexturenum );
+
+ lmtex = surf.lightmaptexturenum;
+
+ gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0,
+ surf.light_s, surf.light_t,
+ smax, tmax,
+ GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, temp );
+
+ }
+ else
+ {
+ smax = (surf.extents[0]>>4)+1;
+ tmax = (surf.extents[1]>>4)+1;
+
+ R_BuildLightMap( surf, temp, smax);
+
+ GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + 0 );
+
+ lmtex = 0;
+
+ gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0,
+ surf.light_s, surf.light_t,
+ smax, tmax,
+ GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, temp );
+
+ }
+
+ c_brush_polys++;
+
+ GL_MBind( GL_TEXTURE0, image.texnum );
+ GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
+
+ // ==========
+ // PGM
+ if ((surf.texinfo.flags & Defines.SURF_FLOWING) != 0)
+ {
+ float scroll;
+
+ scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );
+ if(scroll == 0.0f)
+ scroll = -64.0f;
+
+ for ( p = surf.polys; p != null; p = p.chain )
+ {
+ v = p.verts;
+ index = p.pos * POLYGON_STRIDE;
+ for (i=0 ; i<p.numverts ; i++) {
+ texCoord.put(index, v[i][3] + scroll);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ }
+ else
+ {
+ for ( p = surf.polys; p != null; p = p.chain )
+ {
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ }
+ // PGM
+ // ==========
+ }
+ else
+ {
+ c_brush_polys++;
+
+ GL_MBind( GL_TEXTURE0, image.texnum );
+ GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex);
+
+ // ==========
+ // PGM
+ if ((surf.texinfo.flags & Defines.SURF_FLOWING) != 0)
+ {
+ float scroll;
+
+ scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );
+ if(scroll == 0.0)
+ scroll = -64.0f;
+
+ for ( p = surf.polys; p != null; p = p.chain )
+ {
+ v = p.verts;
+ index = p.pos * POLYGON_STRIDE;
+ for (i=0 ; i<p.numverts ; i++) {
+ texCoord.put(index, v[i][3] + scroll);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ }
+ else
+ {
+ // PGM
+ // ==========
+ for ( p = surf.polys; p != null; p = p.chain )
+ {
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+
+ // ==========
+ // PGM
+ }
+ // PGM
+ // ==========
+ }
+ }
+
+ /*
+ =================
+ R_DrawInlineBModel
+ =================
+ */
+ void R_DrawInlineBModel()
+ {
+ int i, k;
+ cplane_t pplane;
+ float dot;
+ msurface_t psurf;
+ dlight_t lt;
+
+ // calculate dynamic lighting for bmodel
+ if ( gl_flashblend.value == 0 )
+ {
+ for (k=0 ; k<r_newrefdef.num_dlights ; k++)
+ {
+ lt = r_newrefdef.dlights[k];
+ R_MarkLights(lt, 1<<k, currentmodel.nodes[currentmodel.firstnode]);
+ }
+ }
+
+ // psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
+ int psurfp = currentmodel.firstmodelsurface;
+ msurface_t[] surfaces;
+ surfaces = currentmodel.surfaces;
+ //psurf = surfaces[psurfp];
+
+ if ( (currententity.flags & Defines.RF_TRANSLUCENT) != 0 )
+ {
+ gl.glEnable (GL.GL_BLEND);
+ gl.glColor4f (1,1,1,0.25f);
+ GL_TexEnv( GL.GL_MODULATE );
+ }
+
+ //
+ // draw texture
+ //
+ for (i=0 ; i<currentmodel.nummodelsurfaces ; i++)
+ {
+ psurf = surfaces[psurfp++];
+ // find which side of the node we are on
+ pplane = psurf.plane;
+
+ dot = Math3D.DotProduct(modelorg, pplane.normal) - pplane.dist;
+
+ // draw the polygon
+ if (((psurf.flags & Defines.SURF_PLANEBACK) != 0 && (dot < -BACKFACE_EPSILON)) ||
+ ((psurf.flags & Defines.SURF_PLANEBACK) == 0 && (dot > BACKFACE_EPSILON)))
+ {
+ if ((psurf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0 )
+ { // add to the translucent chain
+ psurf.texturechain = r_alpha_surfaces;
+ r_alpha_surfaces = psurf;
+ }
+ else if ( (psurf.flags & Defines.SURF_DRAWTURB) == 0 )
+ {
+ GL_RenderLightmappedPoly( psurf );
+ }
+ else
+ {
+ GL_EnableMultitexture( false );
+ R_RenderBrushPoly( psurf );
+ GL_EnableMultitexture( true );
+ }
+ }
+ }
+
+ if ( (currententity.flags & Defines.RF_TRANSLUCENT) != 0 ) {
+ gl.glDisable (GL.GL_BLEND);
+ gl.glColor4f (1,1,1,1);
+ GL_TexEnv( GL.GL_REPLACE );
+ }
+ }
+
+ /*
+ =================
+ R_DrawBrushModel
+ =================
+ */
+ void R_DrawBrushModel(entity_t e)
+ {
+ float[] mins = {0, 0, 0};
+ float[] maxs = {0, 0, 0};
+ int i;
+ boolean rotated;
+
+ if (currentmodel.nummodelsurfaces == 0)
+ return;
+
+ currententity = e;
+ gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
+
+ if (e.angles[0] != 0 || e.angles[1] != 0 || e.angles[2] != 0)
+ {
+ rotated = true;
+ for (i=0 ; i<3 ; i++)
+ {
+ mins[i] = e.origin[i] - currentmodel.radius;
+ maxs[i] = e.origin[i] + currentmodel.radius;
+ }
+ }
+ else
+ {
+ rotated = false;
+ Math3D.VectorAdd(e.origin, currentmodel.mins, mins);
+ Math3D.VectorAdd(e.origin, currentmodel.maxs, maxs);
+ }
+
+ if (R_CullBox(mins, maxs)) return;
+
+ gl.glColor3f (1,1,1);
+
+ // memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
+
+ // TODO wird beim multitexturing nicht gebraucht
+ //gl_lms.clearLightmapSurfaces();
+
+ Math3D.VectorSubtract (r_newrefdef.vieworg, e.origin, modelorg);
+ if (rotated)
+ {
+ float[] temp = {0, 0, 0};
+ float[] forward = {0, 0, 0};
+ float[] right = {0, 0, 0};
+ float[] up = {0, 0, 0};
+
+ Math3D.VectorCopy (modelorg, temp);
+ Math3D.AngleVectors (e.angles, forward, right, up);
+ modelorg[0] = Math3D.DotProduct (temp, forward);
+ modelorg[1] = -Math3D.DotProduct (temp, right);
+ modelorg[2] = Math3D.DotProduct (temp, up);
+ }
+
+ gl.glPushMatrix();
+
+ e.angles[0] = -e.angles[0]; // stupid quake bug
+ e.angles[2] = -e.angles[2]; // stupid quake bug
+ R_RotateForEntity(e);
+ e.angles[0] = -e.angles[0]; // stupid quake bug
+ e.angles[2] = -e.angles[2]; // stupid quake bug
+
+ GL_EnableMultitexture( true );
+ GL_SelectTexture(GL_TEXTURE0);
+ GL_TexEnv( GL.GL_REPLACE );
+ gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE, globalPolygonInterleavedBuf);
+ GL_SelectTexture(GL_TEXTURE1);
+ GL_TexEnv( GL.GL_MODULATE );
+ gl.glTexCoordPointer(2, GL.GL_FLOAT, POLYGON_BYTE_STRIDE, globalPolygonTexCoord1Buf);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ R_DrawInlineBModel();
+
+ gl.glClientActiveTextureARB(GL_TEXTURE1);
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ GL_EnableMultitexture( false );
+
+ gl.glPopMatrix();
+ }
+
+ /*
+ =============================================================
+
+ WORLD MODEL
+
+ =============================================================
+ */
+
+ /*
+ ================
+ R_RecursiveWorldNode
+ ================
+ */
+ void R_RecursiveWorldNode (mnode_t node)
+ {
+ int c, side, sidebit;
+ cplane_t plane;
+ msurface_t surf;
+ msurface_t mark;
+ mleaf_t pleaf;
+ float dot = 0;
+ image_t image;
+
+ if (node.contents == Defines.CONTENTS_SOLID)
+ return; // solid
+
+ if (node.visframe != r_visframecount)
+ return;
+
+ if (R_CullBox(node.mins, node.maxs))
+ return;
+
+ // if a leaf node, draw stuff
+ if (node.contents != -1)
+ {
+ pleaf = (mleaf_t)node;
+
+ // check for door connected areas
+ if (r_newrefdef.areabits != null)
+ {
+ if ( ((r_newrefdef.areabits[pleaf.area >> 3] & 0xFF) & (1 << (pleaf.area & 7)) ) == 0 )
+ return; // not visible
+ }
+
+ int markp = 0;
+
+ mark = pleaf.getMarkSurface(markp); // first marked surface
+ c = pleaf.nummarksurfaces;
+
+ if (c != 0)
+ {
+ do
+ {
+ mark.visframe = r_framecount;
+ mark = pleaf.getMarkSurface(++markp); // next surface
+ } while (--c != 0);
+ }
+
+ return;
+ }
+
+ // node is just a decision point, so go down the apropriate sides
+
+ // find which side of the node we are on
+ plane = node.plane;
+
+ switch (plane.type)
+ {
+ case Defines.PLANE_X:
+ dot = modelorg[0] - plane.dist;
+ break;
+ case Defines.PLANE_Y:
+ dot = modelorg[1] - plane.dist;
+ break;
+ case Defines.PLANE_Z:
+ dot = modelorg[2] - plane.dist;
+ break;
+ default:
+ dot = Math3D.DotProduct(modelorg, plane.normal) - plane.dist;
+ break;
+ }
+
+ if (dot >= 0.0f)
+ {
+ side = 0;
+ sidebit = 0;
+ }
+ else
+ {
+ side = 1;
+ sidebit = Defines.SURF_PLANEBACK;
+ }
+
+ // recurse down the children, front side first
+ R_RecursiveWorldNode(node.children[side]);
+
+ // draw stuff
+ //for ( c = node.numsurfaces, surf = r_worldmodel.surfaces[node.firstsurface]; c != 0 ; c--, surf++)
+ for ( c = 0; c < node.numsurfaces; c++)
+ {
+ surf = r_worldmodel.surfaces[node.firstsurface + c];
+ if (surf.visframe != r_framecount)
+ continue;
+
+ if ( (surf.flags & Defines.SURF_PLANEBACK) != sidebit )
+ continue; // wrong side
+
+ if ((surf.texinfo.flags & Defines.SURF_SKY) != 0)
+ { // just adds to visible sky bounds
+ R_AddSkySurface(surf);
+ }
+ else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0)
+ { // add to the translucent chain
+ surf.texturechain = r_alpha_surfaces;
+ r_alpha_surfaces = surf;
+ }
+ else
+ {
+ if ( ( surf.flags & Defines.SURF_DRAWTURB) == 0 )
+ {
+ GL_RenderLightmappedPoly( surf );
+ }
+ else
+ {
+ // the polygon is visible, so add it to the texture
+ // sorted chain
+ // FIXME: this is a hack for animation
+ image = R_TextureAnimation(surf.texinfo);
+ surf.texturechain = image.texturechain;
+ image.texturechain = surf;
+ }
+ }
+ }
+
+ // recurse down the back side
+ R_RecursiveWorldNode(node.children[1 - side]);
+ }
+
+
+ /*
+ =============
+ R_DrawWorld
+ =============
+ */
+ void R_DrawWorld()
+ {
+ entity_t ent = new entity_t();
+
+ if (r_drawworld.value == 0)
+ return;
+
+ if ( (r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0 )
+ return;
+
+ currentmodel = r_worldmodel;
+
+ Math3D.VectorCopy(r_newrefdef.vieworg, modelorg);
+
+ // auto cycle the world frame for texture animation
+ // memset (&ent, 0, sizeof(ent));
+ ent.frame = (int)(r_newrefdef.time*2);
+ currententity = ent;
+
+ gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
+
+ gl.glColor3f (1,1,1);
+ // memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
+ // TODO wird bei multitexture nicht gebraucht
+ //gl_lms.clearLightmapSurfaces();
+
+ R_ClearSkyBox();
+
+ GL_EnableMultitexture( true );
+
+ GL_SelectTexture( GL_TEXTURE0);
+ GL_TexEnv( GL.GL_REPLACE );
+ gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE, globalPolygonInterleavedBuf);
+ GL_SelectTexture( GL_TEXTURE1);
+ gl.glTexCoordPointer(2, GL.GL_FLOAT, POLYGON_BYTE_STRIDE, globalPolygonTexCoord1Buf);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ if ( gl_lightmap.value != 0)
+ GL_TexEnv( GL.GL_REPLACE );
+ else
+ GL_TexEnv( GL.GL_MODULATE );
+
+ R_RecursiveWorldNode(r_worldmodel.nodes[0]); // root node
+
+ gl.glClientActiveTextureARB(GL_TEXTURE1);
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ GL_EnableMultitexture( false );
+
+ DrawTextureChains();
+ R_DrawSkyBox();
+ R_DrawTriangleOutlines();
+ }
+
+ byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8];
+
+ /*
+ ===============
+ R_MarkLeaves
+
+ Mark the leaves and nodes that are in the PVS for the current
+ cluster
+ ===============
+ */
+ void R_MarkLeaves()
+ {
+ byte[] vis;
+ //byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8];
+
+ Arrays.fill(fatvis, (byte)0);
+
+ mnode_t node;
+ int i, c;
+ mleaf_t leaf;
+ int cluster;
+
+ if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && r_novis.value == 0 && r_viewcluster != -1)
+ return;
+
+ // development aid to let you run around and see exactly where
+ // the pvs ends
+ if (gl_lockpvs.value != 0)
+ return;
+
+ r_visframecount++;
+ r_oldviewcluster = r_viewcluster;
+ r_oldviewcluster2 = r_viewcluster2;
+
+ if (r_novis.value != 0 || r_viewcluster == -1 || r_worldmodel.vis == null)
+ {
+ // mark everything
+ for (i=0 ; i<r_worldmodel.numleafs ; i++)
+ r_worldmodel.leafs[i].visframe = r_visframecount;
+ for (i=0 ; i<r_worldmodel.numnodes ; i++)
+ r_worldmodel.nodes[i].visframe = r_visframecount;
+ return;
+ }
+
+ vis = Mod_ClusterPVS(r_viewcluster, r_worldmodel);
+ // may have to combine two clusters because of solid water boundaries
+ if (r_viewcluster2 != r_viewcluster)
+ {
+ // memcpy (fatvis, vis, (r_worldmodel.numleafs+7)/8);
+ System.arraycopy(vis, 0, fatvis, 0, (r_worldmodel.numleafs+7) / 8);
+ vis = Mod_ClusterPVS(r_viewcluster2, r_worldmodel);
+ c = (r_worldmodel.numleafs + 31) / 32;
+ int k = 0;
+ for (i=0 ; i<c ; i++) {
+ fatvis[k] |= vis[k++];
+ fatvis[k] |= vis[k++];
+ fatvis[k] |= vis[k++];
+ fatvis[k] |= vis[k++];
+ }
+
+ vis = fatvis;
+ }
+
+ for ( i=0; i < r_worldmodel.numleafs; i++)
+ {
+ leaf = r_worldmodel.leafs[i];
+ cluster = leaf.cluster;
+ if (cluster == -1)
+ continue;
+ if (((vis[cluster>>3] & 0xFF) & (1 << (cluster & 7))) != 0)
+ {
+ node = (mnode_t)leaf;
+ do
+ {
+ if (node.visframe == r_visframecount)
+ break;
+ node.visframe = r_visframecount;
+ node = node.parent;
+ } while (node != null);
+ }
+ }
+ }
+
+
+
+ /*
+ =============================================================================
+
+ LIGHTMAP ALLOCATION
+
+ =============================================================================
+ */
+
+ void LM_InitBlock()
+ {
+ Arrays.fill(gl_lms.allocated, 0);
+ }
+
+ void LM_UploadBlock( boolean dynamic )
+ {
+ int texture;
+ int height = 0;
+
+ if ( dynamic )
+ {
+ texture = 0;
+ }
+ else
+ {
+ texture = gl_lms.current_lightmap_texture;
+ }
+
+ GL_Bind( gl_state.lightmap_textures + texture );
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+
+ if ( dynamic )
+ {
+ int i;
+
+ for ( i = 0; i < BLOCK_WIDTH; i++ )
+ {
+ if ( gl_lms.allocated[i] > height )
+ height = gl_lms.allocated[i];
+ }
+
+ gl.glTexSubImage2D( GL.GL_TEXTURE_2D,
+ 0,
+ 0, 0,
+ BLOCK_WIDTH, height,
+ GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE,
+ gl_lms.lightmap_buffer );
+ }
+ else
+ {
+ gl.glTexImage2D( GL.GL_TEXTURE_2D,
+ 0,
+ gl_lms.internal_format,
+ BLOCK_WIDTH, BLOCK_HEIGHT,
+ 0,
+ GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE,
+ gl_lms.lightmap_buffer );
+ if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
+ ri.Sys_Error( Defines.ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
+
+
+ //debugLightmap(gl_lms.lightmap_buffer, 128, 128, 4);
+
+ }
+ }
+
+ // returns a texture number and the position inside it
+ boolean LM_AllocBlock (int w, int h, pos_t pos)
+ {
+ int x = pos.x;
+ int y = pos.y;
+ int i, j;
+ int best, best2;
+
+ best = BLOCK_HEIGHT;
+
+ for (i=0 ; i<BLOCK_WIDTH-w ; i++)
+ {
+ best2 = 0;
+
+ for (j=0 ; j<w ; j++)
+ {
+ if (gl_lms.allocated[i+j] >= best)
+ break;
+ if (gl_lms.allocated[i+j] > best2)
+ best2 = gl_lms.allocated[i+j];
+ }
+ if (j == w)
+ { // this is a valid spot
+ pos.x = x = i;
+ pos.y = y = best = best2;
+ }
+ }
+
+ if (best + h > BLOCK_HEIGHT)
+ return false;
+
+ for (i=0 ; i<w ; i++)
+ gl_lms.allocated[x + i] = best + h;
+
+ return true;
+ }
+
+ /*
+ ================
+ GL_BuildPolygonFromSurface
+ ================
+ */
+ void GL_BuildPolygonFromSurface(msurface_t fa)
+ {
+ int i, lindex, lnumverts;
+ medge_t[] pedges;
+ medge_t r_pedge;
+ int vertpage;
+ float[] vec;
+ float s, t;
+ glpoly_t poly;
+ float[] total = {0, 0, 0};
+
+ // reconstruct the polygon
+ pedges = currentmodel.edges;
+ lnumverts = fa.numedges;
+ vertpage = 0;
+
+ Math3D.VectorClear(total);
+ //
+ // draw texture
+ //
+ // poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
+ poly = new glpoly_t(lnumverts);
+
+ poly.next = fa.polys;
+ poly.flags = fa.flags;
+ fa.polys = poly;
+ poly.numverts = lnumverts;
+
+ for (i=0 ; i<lnumverts ; i++)
+ {
+ lindex = currentmodel.surfedges[fa.firstedge + i];
+
+ if (lindex > 0)
+ {
+ r_pedge = pedges[lindex];
+ vec = currentmodel.vertexes[r_pedge.v[0]].position;
+ }
+ else
+ {
+ r_pedge = pedges[-lindex];
+ vec = currentmodel.vertexes[r_pedge.v[1]].position;
+ }
+ s = Math3D.DotProduct (vec, fa.texinfo.vecs[0]) + fa.texinfo.vecs[0][3];
+ s /= fa.texinfo.image.width;
+
+ t = Math3D.DotProduct (vec, fa.texinfo.vecs[1]) + fa.texinfo.vecs[1][3];
+ t /= fa.texinfo.image.height;
+
+ Math3D.VectorAdd (total, vec, total);
+ Math3D.VectorCopy (vec, poly.verts[i]);
+ poly.verts[i][3] = s;
+ poly.verts[i][4] = t;
+
+ //
+ // lightmap texture coordinates
+ //
+ s = Math3D.DotProduct (vec, fa.texinfo.vecs[0]) + fa.texinfo.vecs[0][3];
+ s -= fa.texturemins[0];
+ s += fa.light_s*16;
+ s += 8;
+ s /= BLOCK_WIDTH*16; //fa.texinfo.texture.width;
+
+ t = Math3D.DotProduct (vec, fa.texinfo.vecs[1]) + fa.texinfo.vecs[1][3];
+ t -= fa.texturemins[1];
+ t += fa.light_t*16;
+ t += 8;
+ t /= BLOCK_HEIGHT*16; //fa.texinfo.texture.height;
+
+ poly.verts[i][5] = s;
+ poly.verts[i][6] = t;
+ }
+
+ poly.numverts = lnumverts;
+
+ precompilePolygon(poly);
+
+ }
+
+ /*
+ ========================
+ GL_CreateSurfaceLightmap
+ ========================
+ */
+ void GL_CreateSurfaceLightmap(msurface_t surf)
+ {
+ int smax, tmax;
+ IntBuffer base;
+
+ if ( (surf.flags & (Defines.SURF_DRAWSKY | Defines.SURF_DRAWTURB)) != 0)
+ return;
+
+ smax = (surf.extents[0]>>4)+1;
+ tmax = (surf.extents[1]>>4)+1;
+
+ pos_t lightPos = new pos_t(surf.light_s, surf.light_t);
+
+ if ( !LM_AllocBlock( smax, tmax, lightPos ) )
+ {
+ LM_UploadBlock( false );
+ LM_InitBlock();
+ lightPos = new pos_t(surf.light_s, surf.light_t);
+ if ( !LM_AllocBlock( smax, tmax, lightPos ) )
+ {
+ ri.Sys_Error( Defines.ERR_FATAL, "Consecutive calls to LM_AllocBlock(" + smax +"," + tmax +") failed\n");
+ }
+ }
+
+ // kopiere die koordinaten zurueck
+ surf.light_s = lightPos.x;
+ surf.light_t = lightPos.y;
+
+ surf.lightmaptexturenum = gl_lms.current_lightmap_texture;
+
+ base = gl_lms.lightmap_buffer;
+ base.position(surf.light_t * BLOCK_WIDTH + surf.light_s);
+
+ R_SetCacheState( surf );
+ R_BuildLightMap(surf, base.slice(), BLOCK_WIDTH);
+ }
+
+ lightstyle_t[] lightstyles;
+ IntBuffer dummy = BufferUtils.newIntBuffer(128*128);
+
+ /*
+ ==================
+ GL_BeginBuildingLightmaps
+
+ ==================
+ */
+ void GL_BeginBuildingLightmaps(model_t m)
+ {
+ // static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
+ int i;
+
+ // init lightstyles
+ if ( lightstyles == null ) {
+ lightstyles = new lightstyle_t[Defines.MAX_LIGHTSTYLES];
+ for (i = 0; i < lightstyles.length; i++)
+ {
+ lightstyles[i] = new lightstyle_t();
+ }
+ }
+
+ // memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
+ Arrays.fill(gl_lms.allocated, 0);
+
+ r_framecount = 1; // no dlightcache
+
+ GL_EnableMultitexture( true );
+ GL_SelectTexture( GL_TEXTURE1);
+
+ /*
+ ** setup the base lightstyles so the lightmaps won't have to be regenerated
+ ** the first time they're seen
+ */
+ for (i=0 ; i < Defines.MAX_LIGHTSTYLES ; i++)
+ {
+ lightstyles[i].rgb[0] = 1;
+ lightstyles[i].rgb[1] = 1;
+ lightstyles[i].rgb[2] = 1;
+ lightstyles[i].white = 3;
+ }
+ r_newrefdef.lightstyles = lightstyles;
+
+ if (gl_state.lightmap_textures == 0)
+ {
+ gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
+ }
+
+ gl_lms.current_lightmap_texture = 1;
+
+ /*
+ ** if mono lightmaps are enabled and we want to use alpha
+ ** blending (a,1-a) then we're likely running on a 3DLabs
+ ** Permedia2. In a perfect world we'd use a GL_ALPHA lightmap
+ ** in order to conserve space and maximize bandwidth, however
+ ** this isn't a perfect world.
+ **
+ ** So we have to use alpha lightmaps, but stored in GL_RGBA format,
+ ** which means we only get 1/16th the color resolution we should when
+ ** using alpha lightmaps. If we find another board that supports
+ ** only alpha lightmaps but that can at least support the GL_ALPHA
+ ** format then we should change this code to use real alpha maps.
+ */
+
+ char format = gl_monolightmap.string.toUpperCase().charAt(0);
+
+ if ( format == 'A' )
+ {
+ gl_lms.internal_format = gl_tex_alpha_format;
+ }
+ /*
+ ** try to do hacked colored lighting with a blended texture
+ */
+ else if ( format == 'C' )
+ {
+ gl_lms.internal_format = gl_tex_alpha_format;
+ }
+ else if ( format == 'I' )
+ {
+ gl_lms.internal_format = GL.GL_INTENSITY8;
+ }
+ else if ( format == 'L' )
+ {
+ gl_lms.internal_format = GL.GL_LUMINANCE8;
+ }
+ else
+ {
+ gl_lms.internal_format = gl_tex_solid_format;
+ }
+
+ /*
+ ** initialize the dynamic lightmap texture
+ */
+ GL_Bind( gl_state.lightmap_textures + 0 );
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+ gl.glTexImage2D( GL.GL_TEXTURE_2D,
+ 0,
+ gl_lms.internal_format,
+ BLOCK_WIDTH, BLOCK_HEIGHT,
+ 0,
+ GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE,
+ dummy );
+ }
+
+ /*
+ =======================
+ GL_EndBuildingLightmaps
+ =======================
+ */
+ void GL_EndBuildingLightmaps()
+ {
+ LM_UploadBlock( false );
+ GL_EnableMultitexture( false );
+ }
+
+ /*
+ * new functions for vertex array handling
+ */
+ static final int POLYGON_BUFFER_SIZE = 120000;
+ static final int POLYGON_STRIDE = 7;
+ static final int POLYGON_BYTE_STRIDE = POLYGON_STRIDE * BufferUtils.SIZEOF_FLOAT;
+
+ static FloatBuffer globalPolygonInterleavedBuf = BufferUtils.newFloatBuffer(POLYGON_BUFFER_SIZE * 7);
+ static FloatBuffer globalPolygonTexCoord1Buf = null;
+
+ static {
+ globalPolygonInterleavedBuf.position(POLYGON_STRIDE - 2);
+ globalPolygonTexCoord1Buf = globalPolygonInterleavedBuf.slice();
+ globalPolygonInterleavedBuf.position(0);
+ };
+
+ void precompilePolygon(glpoly_t p) {
+
+ p.pos = globalPolygonInterleavedBuf.position() / POLYGON_STRIDE;
+
+ float[] v;
+ FloatBuffer buffer = globalPolygonInterleavedBuf;
+
+ for (int i = 0; i < p.verts.length; i++) {
+ v = p.verts[i];
+ // textureCoord0
+ buffer.put(v[3]);
+ buffer.put(v[4]);
+
+ // vertex
+ buffer.put(v[0]);
+ buffer.put(v[1]);
+ buffer.put(v[2]);
+
+ // textureCoord1
+ buffer.put(v[5]);
+ buffer.put(v[6]);
+ }
+ }
+
+ public static void resetPolygonArrays() {
+ globalPolygonInterleavedBuf.rewind();
+ }
+
+ //ImageFrame frame;
+
+// void debugLightmap(byte[] buf, int w, int h, float scale) {
+// IntBuffer pix = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
+//
+// int[] pixel = new int[w * h];
+//
+// pix.get(pixel);
+//
+// BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
+// image.setRGB(0, 0, w, h, pixel, 0, w);
+// AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+// BufferedImage tmp = op.filter(image, null);
+//
+// if (frame == null) {
+// frame = new ImageFrame(null);
+// frame.show();
+// }
+// frame.showImage(tmp);
+//
+// }
+
+}
diff --git a/src/jake2/render/fastjogl/Warp.java b/src/jake2/render/fastjogl/Warp.java
new file mode 100644
index 0000000..f9a5b07
--- /dev/null
+++ b/src/jake2/render/fastjogl/Warp.java
@@ -0,0 +1,732 @@
+/*
+ * Warp.java
+ * Copyright (C) 2003
+ *
+ * $Id: Warp.java,v 1.1 2004-07-09 06:50:49 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.render.fastjogl;
+
+import java.nio.FloatBuffer;
+
+import jake2.Defines;
+import jake2.Globals;
+import jake2.game.GameBase;
+import jake2.render.glpoly_t;
+import jake2.render.image_t;
+import jake2.render.msurface_t;
+import jake2.util.Math3D;
+import net.java.games.jogl.GL;
+
+/**
+ * Warp
+ *
+ * @author cwei
+ */
+public abstract class Warp extends Model {
+
+
+ // warpsin.h
+ public static final float[] SIN = {
+ 0f, 0.19633f, 0.392541f, 0.588517f, 0.784137f, 0.979285f, 1.17384f, 1.3677f,
+ 1.56072f, 1.75281f, 1.94384f, 2.1337f, 2.32228f, 2.50945f, 2.69512f, 2.87916f,
+ 3.06147f, 3.24193f, 3.42044f, 3.59689f, 3.77117f, 3.94319f, 4.11282f, 4.27998f,
+ 4.44456f, 4.60647f, 4.76559f, 4.92185f, 5.07515f, 5.22538f, 5.37247f, 5.51632f,
+ 5.65685f, 5.79398f, 5.92761f, 6.05767f, 6.18408f, 6.30677f, 6.42566f, 6.54068f,
+ 6.65176f, 6.75883f, 6.86183f, 6.9607f, 7.05537f, 7.14579f, 7.23191f, 7.31368f,
+ 7.39104f, 7.46394f, 7.53235f, 7.59623f, 7.65552f, 7.71021f, 7.76025f, 7.80562f,
+ 7.84628f, 7.88222f, 7.91341f, 7.93984f, 7.96148f, 7.97832f, 7.99036f, 7.99759f,
+ 8f, 7.99759f, 7.99036f, 7.97832f, 7.96148f, 7.93984f, 7.91341f, 7.88222f,
+ 7.84628f, 7.80562f, 7.76025f, 7.71021f, 7.65552f, 7.59623f, 7.53235f, 7.46394f,
+ 7.39104f, 7.31368f, 7.23191f, 7.14579f, 7.05537f, 6.9607f, 6.86183f, 6.75883f,
+ 6.65176f, 6.54068f, 6.42566f, 6.30677f, 6.18408f, 6.05767f, 5.92761f, 5.79398f,
+ 5.65685f, 5.51632f, 5.37247f, 5.22538f, 5.07515f, 4.92185f, 4.76559f, 4.60647f,
+ 4.44456f, 4.27998f, 4.11282f, 3.94319f, 3.77117f, 3.59689f, 3.42044f, 3.24193f,
+ 3.06147f, 2.87916f, 2.69512f, 2.50945f, 2.32228f, 2.1337f, 1.94384f, 1.75281f,
+ 1.56072f, 1.3677f, 1.17384f, 0.979285f, 0.784137f, 0.588517f, 0.392541f, 0.19633f,
+ 9.79717e-16f, -0.19633f, -0.392541f, -0.588517f, -0.784137f, -0.979285f, -1.17384f, -1.3677f,
+ -1.56072f, -1.75281f, -1.94384f, -2.1337f, -2.32228f, -2.50945f, -2.69512f, -2.87916f,
+ -3.06147f, -3.24193f, -3.42044f, -3.59689f, -3.77117f, -3.94319f, -4.11282f, -4.27998f,
+ -4.44456f, -4.60647f, -4.76559f, -4.92185f, -5.07515f, -5.22538f, -5.37247f, -5.51632f,
+ -5.65685f, -5.79398f, -5.92761f, -6.05767f, -6.18408f, -6.30677f, -6.42566f, -6.54068f,
+ -6.65176f, -6.75883f, -6.86183f, -6.9607f, -7.05537f, -7.14579f, -7.23191f, -7.31368f,
+ -7.39104f, -7.46394f, -7.53235f, -7.59623f, -7.65552f, -7.71021f, -7.76025f, -7.80562f,
+ -7.84628f, -7.88222f, -7.91341f, -7.93984f, -7.96148f, -7.97832f, -7.99036f, -7.99759f,
+ -8f, -7.99759f, -7.99036f, -7.97832f, -7.96148f, -7.93984f, -7.91341f, -7.88222f,
+ -7.84628f, -7.80562f, -7.76025f, -7.71021f, -7.65552f, -7.59623f, -7.53235f, -7.46394f,
+ -7.39104f, -7.31368f, -7.23191f, -7.14579f, -7.05537f, -6.9607f, -6.86183f, -6.75883f,
+ -6.65176f, -6.54068f, -6.42566f, -6.30677f, -6.18408f, -6.05767f, -5.92761f, -5.79398f,
+ -5.65685f, -5.51632f, -5.37247f, -5.22538f, -5.07515f, -4.92185f, -4.76559f, -4.60647f,
+ -4.44456f, -4.27998f, -4.11282f, -3.94319f, -3.77117f, -3.59689f, -3.42044f, -3.24193f,
+ -3.06147f, -2.87916f, -2.69512f, -2.50945f, -2.32228f, -2.1337f, -1.94384f, -1.75281f,
+ -1.56072f, -1.3677f, -1.17384f, -0.979285f, -0.784137f, -0.588517f, -0.392541f, -0.19633f
+ };
+
+ // gl_warp.c -- sky and water polygons
+ //extern model_t *loadmodel; // Model.java
+
+ String skyname;
+ float skyrotate;
+ float[] skyaxis = {0, 0, 0};
+ image_t[] sky_images = new image_t[6];
+
+ msurface_t warpface;
+
+ static final int SUBDIVIDE_SIZE = 64;
+
+ void BoundPoly(int numverts, float[][] verts, float[] mins, float[] maxs)
+ {
+ int i, j;
+ float[] v;
+
+ mins[0] = mins[1] = mins[2] = 9999;
+ maxs[0] = maxs[1] = maxs[2] = -9999;
+ for (i=0 ; i<numverts ; i++)
+ {
+ v = verts[i];
+ for (j=0 ; j<3 ; j++)
+ {
+ if (v[j] < mins[j])
+ mins[j] = v[j];
+ if (v[j] > maxs[j])
+ maxs[j] = v[j];
+ }
+ }
+ }
+
+ void SubdividePolygon(int numverts, float[][] verts)
+ {
+ int i, j, k;
+ float[] mins = {0, 0, 0};
+ float[] maxs = {0, 0, 0};
+ float m;
+ float[] v = {0, 0, 0};
+ float[][] front = new float[64][3];
+ float[][] back = new float[64][3];
+
+ int f, b;
+ float[] dist = new float[64];
+ float frac;
+ glpoly_t poly;
+ float s, t;
+ float[] total = {0, 0, 0};
+ float total_s, total_t;
+
+ if (numverts > 60)
+ ri.Sys_Error(Defines.ERR_DROP, "numverts = " + numverts);
+
+ BoundPoly(numverts, verts, mins, maxs);
+
+ // x,y und z
+ for (i=0 ; i<3 ; i++)
+ {
+ m = (mins[i] + maxs[i]) * 0.5f;
+ m = SUBDIVIDE_SIZE * (float)Math.floor(m / SUBDIVIDE_SIZE + 0.5f);
+ if (maxs[i] - m < 8)
+ continue;
+ if (m - mins[i] < 8)
+ continue;
+
+ // cut it
+ for (j=0 ; j<numverts ; j++) {
+ dist[j] = verts[j][i] - m;
+ }
+
+ // wrap cases
+ dist[j] = dist[0];
+
+ Math3D.VectorCopy(verts[0], verts[numverts]);
+
+ f = b = 0;
+ for (j=0 ; j<numverts ; j++)
+ {
+ v = verts[j];
+ if (dist[j] >= 0)
+ {
+ Math3D.VectorCopy(v, front[f]);
+ f++;
+ }
+ if (dist[j] <= 0)
+ {
+ Math3D.VectorCopy(v, back[b]);
+ b++;
+ }
+ if (dist[j] == 0 || dist[j+1] == 0) continue;
+
+ if ( (dist[j] > 0) != (dist[j+1] > 0) )
+ {
+ // clip point
+ frac = dist[j] / (dist[j] - dist[j+1]);
+ for (k=0 ; k<3 ; k++)
+ front[f][k] = back[b][k] = v[k] + frac*(verts[j+1][k] - v[k]);
+
+ f++;
+ b++;
+ }
+ }
+
+ SubdividePolygon(f, front);
+ SubdividePolygon(b, back);
+ return;
+ }
+
+ // add a point in the center to help keep warp valid
+
+ // wird im Konstruktor erschlagen
+ // poly = Hunk_Alloc (sizeof(glpoly_t) + ((numverts-4)+2) * VERTEXSIZE*sizeof(float));
+
+ // init polys
+ poly = new glpoly_t(numverts + 2);
+
+ poly.next = warpface.polys;
+ warpface.polys = poly;
+ poly.numverts = numverts + 2;
+ Math3D.VectorClear(total);
+ total_s = 0;
+ total_t = 0;
+ for (i=0 ; i<numverts ; i++)
+ {
+ Math3D.VectorCopy(verts[i], poly.verts[i+1]);
+ s = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[0]);
+ t = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[1]);
+
+ total_s += s;
+ total_t += t;
+ Math3D.VectorAdd(total, verts[i], total);
+
+ poly.verts[i+1][3] = s;
+ poly.verts[i+1][4] = t;
+ }
+
+ Math3D.VectorScale(total, (1.0f/numverts), poly.verts[0]);
+ poly.verts[0][3] = total_s/numverts;
+ poly.verts[0][4] = total_t/numverts;
+
+ // memcpy (poly.verts[i+1], poly.verts[1], sizeof(poly.verts[0]));
+ System.arraycopy(poly.verts[1], 0, poly.verts[i+1], 0, poly.verts[1].length); // :-)
+
+ precompilePolygon(poly);
+ }
+
+ /*
+ ================
+ GL_SubdivideSurface
+
+ Breaks a polygon up along axial 64 unit
+ boundaries so that turbulent and sky warps
+ can be done reasonably.
+ ================
+ */
+ void GL_SubdivideSurface(msurface_t fa)
+ {
+ float[][] verts = new float[64][3];
+
+ int numverts;
+ int i;
+ int lindex;
+ float[] vec;
+
+ warpface = fa;
+
+ //
+ // convert edges back to a normal polygon
+ //
+ numverts = 0;
+ for (i=0 ; i < fa.numedges ; i++)
+ {
+ lindex = loadmodel.surfedges[fa.firstedge + i];
+
+ if (lindex > 0)
+ vec = loadmodel.vertexes[loadmodel.edges[lindex].v[0]].position;
+ else
+ vec = loadmodel.vertexes[loadmodel.edges[-lindex].v[1]].position;
+ Math3D.VectorCopy(vec, verts[numverts]);
+ numverts++;
+ }
+
+ SubdividePolygon(numverts, verts);
+ }
+
+// =========================================================
+
+
+
+//// speed up sin calculations - Ed
+// float r_turbsin[] =
+// {
+// #include "warpsin.h"
+// };
+ static final float TURBSCALE = (float)(256.0f / (2 * Math.PI));
+
+ /*
+ =============
+ EmitWaterPolys
+
+ Does a water warp on the pre-fragmented glpoly_t chain
+ =============
+ */
+ void EmitWaterPolys(msurface_t fa)
+ {
+ glpoly_t p, bp;
+ float[] v;
+ int i;
+ float s = 0;
+ float t = 0;
+ float os, ot;
+ float scroll;
+ float rdt = r_newrefdef.time;
+
+ if ((fa.texinfo.flags & Defines.SURF_FLOWING) != 0)
+ scroll = -64 * ( (r_newrefdef.time*0.5f) - (int)(r_newrefdef.time*0.5f) );
+ else
+ scroll = 0;
+
+ int index;
+ FloatBuffer texCoord = globalPolygonInterleavedBuf;
+ for (bp=fa.polys ; bp != null ; bp=bp.next)
+ {
+ p = bp;
+
+ index = p.pos * POLYGON_STRIDE;
+ for (i=0; i<p.numverts ; i++)
+ {
+ v = p.verts[i];
+ os = v[3];
+ ot = v[4];
+
+ s = os + Warp.SIN[(int)((ot * 0.125f + r_newrefdef.time) * TURBSCALE) & 255];
+ s += scroll;
+ s *= (1.0f/64);
+
+ t = ot + Warp.SIN[(int)((os * 0.125f + rdt) * TURBSCALE) & 255];
+ t *= (1.0f/64);
+
+ texCoord.put(index, s);
+ texCoord.put(index + 1, t);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_TRIANGLE_FAN, p.pos, p.numverts);
+ }
+ }
+
+// ===================================================================
+
+
+ float[][] skyclip = {
+ { 1, 1, 0},
+ { 1, -1, 0},
+ { 0, -1, 1},
+ { 0, 1, 1},
+ { 1, 0, 1},
+ {-1, 0, 1}
+ };
+
+ int c_sky;
+
+ // 1 = s, 2 = t, 3 = 2048
+ int[][] st_to_vec =
+ {
+ {3,-1,2},
+ {-3,1,2},
+
+ {1,3,2},
+ {-1,-3,2},
+
+ {-2,-1,3}, // 0 degrees yaw, look straight up
+ {2,-1,-3} // look straight down
+
+ };
+
+ int[][] vec_to_st =
+ {
+ {-2,3,1},
+ {2,3,-1},
+
+ {1,3,2},
+ {-1,3,-2},
+
+ {-2,-1,3},
+ {-2,1,-3}
+
+ };
+
+ float[][] skymins = new float[2][6];
+ float[][] skymaxs = new float[2][6];
+ float sky_min, sky_max;
+
+ void DrawSkyPolygon (int nump, float[][] vecs)
+ {
+ int i,j;
+ float[] v = {0, 0, 0};
+ float[] av = {0, 0, 0};
+ float s, t, dv;
+ int axis;
+ float[] vp;
+
+ c_sky++;
+ // decide which face it maps to
+ Math3D.VectorCopy(Globals.vec3_origin, v);
+ for (i=0; i<nump ; i++)
+ {
+ Math3D.VectorAdd(vecs[i], v, v);
+ }
+ av[0] = Math.abs(v[0]);
+ av[1] = Math.abs(v[1]);
+ av[2] = Math.abs(v[2]);
+ if (av[0] > av[1] && av[0] > av[2])
+ {
+ if (v[0] < 0)
+ axis = 1;
+ else
+ axis = 0;
+ }
+ else if (av[1] > av[2] && av[1] > av[0])
+ {
+ if (v[1] < 0)
+ axis = 3;
+ else
+ axis = 2;
+ }
+ else
+ {
+ if (v[2] < 0)
+ axis = 5;
+ else
+ axis = 4;
+ }
+
+ // project new texture coords
+ for (i=0 ; i<nump ; i++)
+ {
+ j = vec_to_st[axis][2];
+ if (j > 0)
+ dv = vecs[i][j - 1];
+ else
+ dv = -vecs[i][-j - 1];
+ if (dv < 0.001f)
+ continue; // don't divide by zero
+ j = vec_to_st[axis][0];
+ if (j < 0)
+ s = -vecs[i][-j -1] / dv;
+ else
+ s = vecs[i][j-1] / dv;
+ j = vec_to_st[axis][1];
+ if (j < 0)
+ t = -vecs[i][-j -1] / dv;
+ else
+ t = vecs[i][j-1] / dv;
+
+ if (s < skymins[0][axis])
+ skymins[0][axis] = s;
+ if (t < skymins[1][axis])
+ skymins[1][axis] = t;
+ if (s > skymaxs[0][axis])
+ skymaxs[0][axis] = s;
+ if (t > skymaxs[1][axis])
+ skymaxs[1][axis] = t;
+ }
+ }
+
+ static final float ON_EPSILON = 0.1f; // point on plane side epsilon
+ static final int MAX_CLIP_VERTS = 64;
+
+ static final int SIDE_BACK = 1;
+ static final int SIDE_FRONT = 0;
+ static final int SIDE_ON = 2;
+
+ float[] dists = new float[MAX_CLIP_VERTS];
+ int[] sides = new int[MAX_CLIP_VERTS];
+ float[][][][] newv = new float[6][2][MAX_CLIP_VERTS][3];
+
+ void ClipSkyPolygon(int nump, float[][] vecs, int stage)
+ {
+ float[] norm;
+ float[] v;
+ boolean front, back;
+ float d, e;
+ int[] newc = { 0, 0 };
+ int i, j;
+
+ if (nump > MAX_CLIP_VERTS-2)
+ ri.Sys_Error(Defines.ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS");
+ if (stage == 6)
+ { // fully clipped, so draw it
+ DrawSkyPolygon(nump, vecs);
+ return;
+ }
+
+ front = back = false;
+ norm = skyclip[stage];
+ for (i=0 ; i<nump ; i++)
+ {
+ d = Math3D.DotProduct(vecs[i], norm);
+ if (d > ON_EPSILON)
+ {
+ front = true;
+ sides[i] = SIDE_FRONT;
+ }
+ else if (d < -ON_EPSILON)
+ {
+ back = true;
+ sides[i] = SIDE_BACK;
+ }
+ else
+ sides[i] = SIDE_ON;
+ dists[i] = d;
+ }
+
+ if (!front || !back)
+ { // not clipped
+ ClipSkyPolygon (nump, vecs, stage+1);
+ return;
+ }
+
+ // clip it
+ sides[i] = sides[0];
+ dists[i] = dists[0];
+ Math3D.VectorCopy(vecs[0], vecs[i]);
+ newc[0] = newc[1] = 0;
+
+ for (i=0; i<nump ; i++)
+ {
+ v = vecs[i];
+ switch (sides[i])
+ {
+ case SIDE_FRONT:
+ Math3D.VectorCopy(v, newv[stage][0][newc[0]]);
+ newc[0]++;
+ break;
+ case SIDE_BACK:
+ Math3D.VectorCopy(v, newv[stage][1][newc[1]]);
+ newc[1]++;
+ break;
+ case SIDE_ON:
+ Math3D.VectorCopy(v, newv[stage][0][newc[0]]);
+ newc[0]++;
+ Math3D.VectorCopy (v, newv[stage][1][newc[1]]);
+ newc[1]++;
+ break;
+ }
+
+ if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
+ continue;
+
+ d = dists[i] / (dists[i] - dists[i+1]);
+ for (j=0 ; j<3 ; j++)
+ {
+ e = v[j] + d * (vecs[i + 1][j] - v[j]);
+ newv[stage][0][newc[0]][j] = e;
+ newv[stage][1][newc[1]][j] = e;
+ }
+ newc[0]++;
+ newc[1]++;
+ }
+
+ // continue
+ ClipSkyPolygon(newc[0], newv[stage][0], stage+1);
+ ClipSkyPolygon(newc[1], newv[stage][1], stage+1);
+ }
+
+ float[][] verts = new float[MAX_CLIP_VERTS][3];
+
+ /*
+ =================
+ R_AddSkySurface
+ =================
+ */
+ void R_AddSkySurface(msurface_t fa)
+ {
+ int i;
+ glpoly_t p;
+
+ // calculate vertex values for sky box
+ for (p=fa.polys ; p != null ; p=p.next)
+ {
+ for (i=0 ; i < p.numverts ; i++)
+ {
+ Math3D.VectorSubtract(p.verts[i], r_origin, verts[i]);
+ }
+ ClipSkyPolygon (p.numverts, verts, 0);
+ }
+ }
+
+
+ /*
+ ==============
+ R_ClearSkyBox
+ ==============
+ */
+ void R_ClearSkyBox()
+ {
+ int i;
+
+ for (i=0 ; i<6 ; i++)
+ {
+ skymins[0][i] = skymins[1][i] = 9999;
+ skymaxs[0][i] = skymaxs[1][i] = -9999;
+ }
+ }
+
+
+ void MakeSkyVec (float s, float t, int axis)
+ {
+ float[] v = {0, 0, 0};
+ float[] b = {0, 0, 0};
+ int j, k;
+
+ b[0] = s*2300;
+ b[1] = t*2300;
+ b[2] = 2300;
+
+ for (j=0 ; j<3 ; j++)
+ {
+ k = st_to_vec[axis][j];
+ if (k < 0)
+ v[j] = -b[-k - 1];
+ else
+ v[j] = b[k - 1];
+ }
+
+ // avoid bilerp seam
+ s = (s + 1) * 0.5f;
+ t = (t + 1) * 0.5f;
+
+ if (s < sky_min)
+ s = sky_min;
+ else if (s > sky_max)
+ s = sky_max;
+ if (t < sky_min)
+ t = sky_min;
+ else if (t > sky_max)
+ t = sky_max;
+
+ t = 1.0f - t;
+ gl.glTexCoord2f (s, t);
+ gl.glVertex3f(v[0], v[1], v[2]);
+ }
+
+ /*
+ ==============
+ R_DrawSkyBox
+ ==============
+ */
+ int[] skytexorder = {0,2,1,3,4,5};
+
+ void R_DrawSkyBox()
+ {
+ int i;
+
+ if (skyrotate != 0)
+ { // check for no sky at all
+ for (i=0 ; i<6 ; i++)
+ if (skymins[0][i] < skymaxs[0][i]
+ && skymins[1][i] < skymaxs[1][i])
+ break;
+ if (i == 6)
+ return; // nothing visible
+ }
+
+ gl.glPushMatrix ();
+ gl.glTranslatef (r_origin[0], r_origin[1], r_origin[2]);
+ gl.glRotatef (r_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]);
+
+ for (i=0 ; i<6 ; i++)
+ {
+ if (skyrotate != 0)
+ { // hack, forces full sky to draw when rotating
+ skymins[0][i] = -1;
+ skymins[1][i] = -1;
+ skymaxs[0][i] = 1;
+ skymaxs[1][i] = 1;
+ }
+
+ if (skymins[0][i] >= skymaxs[0][i]
+ || skymins[1][i] >= skymaxs[1][i])
+ continue;
+
+ GL_Bind(sky_images[skytexorder[i]].texnum);
+
+ gl.glBegin(GL.GL_QUADS);
+ MakeSkyVec(skymins[0][i], skymins[1][i], i);
+ MakeSkyVec(skymins[0][i], skymaxs[1][i], i);
+ MakeSkyVec(skymaxs[0][i], skymaxs[1][i], i);
+ MakeSkyVec(skymaxs[0][i], skymins[1][i], i);
+ gl.glEnd ();
+ }
+ gl.glPopMatrix ();
+ }
+
+
+ /*
+ ============
+ R_SetSky
+ ============
+ */
+ // 3dstudio environment map names
+ String[] suf = {"rt", "bk", "lf", "ft", "up", "dn"};
+
+ protected void R_SetSky(String name, float rotate, float[] axis)
+ {
+ assert (axis.length == 3) : "vec3_t bug";
+ int i;
+ String pathname;
+
+// strncpy (skyname, name, sizeof(skyname)-1);
+ skyname = name;
+
+ skyrotate = rotate;
+ Math3D.VectorCopy(axis, skyaxis);
+
+ for (i=0 ; i<6 ; i++)
+ {
+ // chop down rotating skies for less memory
+ if (gl_skymip.value != 0 || skyrotate != 0)
+ gl_picmip.value++;
+
+ if ( qglColorTableEXT && gl_ext_palettedtexture.value != 0) {
+ // Com_sprintf (pathname, sizeof(pathname), "env/%s%s.pcx", skyname, suf[i]);
+ pathname = "env/" + skyname + suf[i] + ".pcx";
+ } else {
+ // Com_sprintf (pathname, sizeof(pathname), "env/%s%s.tga", skyname, suf[i]);
+ pathname = "env/" + skyname + suf[i] + ".tga";
+ }
+
+ sky_images[i] = GL_FindImage(pathname, it_sky);
+
+ if (sky_images[i] == null)
+ sky_images[i] = r_notexture;
+
+ if (gl_skymip.value != 0 || skyrotate != 0)
+ { // take less memory
+ gl_picmip.value--;
+ sky_min = 1.0f / 256;
+ sky_max = 255.0f / 256;
+ }
+ else
+ {
+ sky_min = 1.0f / 512;
+ sky_max = 511.0f / 512;
+ }
+ }
+ }
+
+
+}
diff --git a/src/jake2/render/glpoly_t.java b/src/jake2/render/glpoly_t.java
index 25cff9c..85b1fd0 100644
--- a/src/jake2/render/glpoly_t.java
+++ b/src/jake2/render/glpoly_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 20.11.2003 by RST.
-// $Id: glpoly_t.java,v 1.1 2004-07-07 19:59:35 hzi Exp $
+// $Id: glpoly_t.java,v 1.2 2004-07-09 06:50:47 hzi Exp $
package jake2.render;
@@ -35,4 +35,12 @@ public class glpoly_t {
public glpoly_t(int numverts) {
this.verts = new float[numverts][VERTEXSIZE];
}
+
+ /*
+ * vertex array extension
+ */
+
+ // the array position (glDrawArrays)
+ public int pos = 0;
+
}
diff --git a/src/jake2/render/jogl/Draw.java b/src/jake2/render/jogl/Draw.java
index eac0a1e..3251b0e 100644
--- a/src/jake2/render/jogl/Draw.java
+++ b/src/jake2/render/jogl/Draw.java
@@ -2,7 +2,7 @@
* Draw.java
* Copyright (C) 2003
*
- * $Id: Draw.java,v 1.2 2004-07-08 15:58:45 hzi Exp $
+ * $Id: Draw.java,v 1.3 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -257,10 +257,10 @@ public abstract class Draw extends Image {
int color = d_8to24table[colorIndex];
- gl.glColor3f(
- ((color >> 0) & 0xff)/255.0f, // r
- ((color >> 8) & 0xff)/255.0f, // g
- ((color >> 16) & 0xff)/255.0f // b
+ gl.glColor3ub(
+ (byte)((color >> 0) & 0xff), // r
+ (byte)((color >> 8) & 0xff), // g
+ (byte)((color >> 16) & 0xff) // b
);
gl.glBegin (GL.GL_QUADS);
diff --git a/src/jake2/render/jogl/Image.java b/src/jake2/render/jogl/Image.java
index 4e65481..f0034fe 100644
--- a/src/jake2/render/jogl/Image.java
+++ b/src/jake2/render/jogl/Image.java
@@ -2,7 +2,7 @@
* Image.java
* Copyright (C) 2003
*
- * $Id: Image.java,v 1.2 2004-07-08 20:24:30 hzi Exp $
+ * $Id: Image.java,v 1.3 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -26,27 +26,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
package jake2.render.jogl;
import jake2.Defines;
+import jake2.client.particle_t;
import jake2.game.cvar_t;
import jake2.qcommon.longjmpException;
import jake2.qcommon.qfiles;
import jake2.render.image_t;
+import jake2.util.Lib;
import jake2.util.Vargs;
import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.awt.image.Raster;
-import java.awt.image.SampleModel;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
+import java.nio.*;
import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
import net.java.games.jogl.GL;
@@ -128,8 +121,7 @@ public abstract class Image extends Main {
GL_TexEnv(GL.GL_REPLACE);
}
- void GL_SelectTexture(int texture /* GLenum */
- ) {
+ void GL_SelectTexture(int texture /* GLenum */) {
int tmu;
if (!qglSelectTextureSGIS && !qglActiveTextureARB)
@@ -787,9 +779,9 @@ public abstract class Image extends Main {
filledcolor = 0;
// attempt to find opaque black
for (i = 0; i < 256; ++i)
- if (d_8to24table[i] == (255 << 0)) // alpha 1.0
- // TODO check this: if ((d_8to24table[i] & 0xFF000000) == 0xFF000000) // alpha 1.0
- {
+ // TODO check this
+ if (d_8to24table[i] == 0xFF000000) { // alpha 1.0
+ //if (d_8to24table[i] == (255 << 0)) // alpha 1.0
filledcolor = i;
break;
}
@@ -1068,6 +1060,7 @@ public abstract class Image extends Main {
*/
int[] scaled = new int[256 * 256];
byte[] paletted_texture = new byte[256 * 256];
+ IntBuffer tex = Lib.newIntBuffer(512 * 256, ByteOrder.LITTLE_ENDIAN);
boolean GL_Upload32(int[] data, int width, int height, boolean mipmap) {
int samples;
@@ -1149,6 +1142,7 @@ public abstract class Image extends Main {
paletted_texture);
}
else {
+ tex.rewind(); tex.put(data);
gl.glTexImage2D(
GL.GL_TEXTURE_2D,
0,
@@ -1158,13 +1152,13 @@ public abstract class Image extends Main {
0,
GL.GL_RGBA,
GL.GL_UNSIGNED_BYTE,
- data);
+ tex);
}
//goto done;
throw new longjmpException();
}
//memcpy (scaled, data, width*height*4); were bytes
- IntBuffer.wrap(data).get(scaled, 0, width * height);
+ System.arraycopy(data, 0, scaled, 0, width * height);
}
else
@@ -1187,7 +1181,8 @@ public abstract class Image extends Main {
paletted_texture);
}
else {
- gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, scaled);
+ tex.rewind(); tex.put(scaled);
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, comp, scaled_width, scaled_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, tex);
}
if (mipmap) {
@@ -1218,6 +1213,7 @@ public abstract class Image extends Main {
paletted_texture);
}
else {
+ tex.rewind(); tex.put(scaled);
gl.glTexImage2D(
GL.GL_TEXTURE_2D,
miplevel,
@@ -1227,14 +1223,14 @@ public abstract class Image extends Main {
0,
GL.GL_RGBA,
GL.GL_UNSIGNED_BYTE,
- scaled);
+ tex);
}
}
}
// label done:
}
catch (longjmpException e) {
- ; // replaces labe done
+ ; // replaces label done
}
if (mipmap) {
@@ -1578,7 +1574,7 @@ public abstract class Image extends Main {
// free it
// TODO jogl bug
- //gl.glDeleteTextures(1, new int[] {image.texnum});
+ gl.glDeleteTextures(1, new int[] {image.texnum});
image.clear();
}
}
@@ -1590,7 +1586,6 @@ public abstract class Image extends Main {
*/
protected void Draw_GetPalette() {
int r, g, b;
- int v;
Dimension dim;
byte[] pic;
byte[][] palette = new byte[1][]; //new byte[768];
@@ -1604,15 +1599,18 @@ public abstract class Image extends Main {
byte[] pal = palette[0];
+ int j = 0;
for (int i = 0; i < 256; i++) {
- r = pal[i * 3 + 0];
- g = pal[i * 3 + 1];
- b = pal[i * 3 + 2];
+ r = pal[j++] & 0xFF;
+ g = pal[j++] & 0xFF;
+ b = pal[j++] & 0xFF;
- d_8to24table[i] = (255 << 24) + (r << 0) + (g << 8) + (b << 16);
+ d_8to24table[i] = (255 << 24) | (b << 16) | (g << 8) | (r << 0);
}
- d_8to24table[255] &= 0x00ffffff; // 255 is transparent
+ d_8to24table[255] &= 0x00FFFFFF; // 255 is transparent
+
+ particle_t.setColorPalette(d_8to24table);
}
/*
@@ -1686,7 +1684,7 @@ public abstract class Image extends Main {
continue; // free image_t slot
// free it
// TODO jogl bug
- //gl.glDeleteTextures(1, new int[] {image.texnum});
+ gl.glDeleteTextures(1, new int[] {image.texnum});
image.clear();
}
}
diff --git a/src/jake2/render/jogl/Impl.java b/src/jake2/render/jogl/Impl.java
index 991c349..cfaec7e 100644
--- a/src/jake2/render/jogl/Impl.java
+++ b/src/jake2/render/jogl/Impl.java
@@ -2,7 +2,7 @@
* Impl.java
* Copyright (C) 2003
*
- * $Id: Impl.java,v 1.4 2004-07-08 20:56:55 hzi Exp $
+ * $Id: Impl.java,v 1.5 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -27,13 +27,11 @@ package jake2.render.jogl;
import jake2.Defines;
import jake2.Globals;
-import jake2.client.CL;
import jake2.qcommon.Com;
import jake2.qcommon.xcommand_t;
-import jake2.server.SV;
import jake2.sys.KBD;
-import java.awt.Dimension;
+import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
@@ -48,17 +46,34 @@ import net.java.games.jogl.*;
*/
public class Impl extends Misc implements GLEventListener {
-
-
public static final String DRIVER_NAME = "jogl";
// handles the post initialization with JoglRenderer
protected boolean post_init = false;
- // switch to updateScreen callback
- private boolean switchToCallback = false;
- private xcommand_t callback = null;
+ private final xcommand_t INIT_CALLBACK = new xcommand_t() {
+ public void execute() {
+ // only used for the first run (initialization)
+ // clear the screen
+ gl.glClearColor(0, 0, 0, 0);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ //
+ // check the post init process
+ //
+ if (!post_init) {
+ ri.Con_Printf(Defines.PRINT_ALL, "Missing multi-texturing for FastJOGL renderer\n");
+ }
+
+ GLimp_EndFrame();
+ }
+ };
+
+ private xcommand_t callback = INIT_CALLBACK;
protected boolean contextInUse = false;
+
+ private GraphicsDevice device;
+ private DisplayMode oldDisplayMode;
GLCanvas canvas;
JFrame window;
@@ -88,13 +103,9 @@ public class Impl extends Misc implements GLEventListener {
ri.Cvar_Get("r_fakeFullscreen", "0", Globals.CVAR_ARCHIVE);
- ri.Con_Printf(Defines.PRINT_ALL, "Initializing OpenGL display\n", null);
+ ri.Con_Printf(Defines.PRINT_ALL, "Initializing OpenGL display\n");
- if (fullscreen) {
- ri.Con_Printf(Defines.PRINT_ALL, "...setting fullscreen mode " + mode + ":");
- }
- else
- ri.Con_Printf(Defines.PRINT_ALL, "...setting mode " + mode + ":");
+ ri.Con_Printf(Defines.PRINT_ALL, "...setting mode " + mode + ":");
if (!ri.Vid_GetModeInfo(newDim, mode)) {
ri.Con_Printf(Defines.PRINT_ALL, " invalid mode\n");
@@ -113,18 +124,12 @@ public class Impl extends Misc implements GLEventListener {
// TODO Use debug pipeline
//canvas.setGL(new DebugGL(canvas.getGL()));
- //canvas.setRenderingThread(Thread.currentThread());
-
canvas.setNoAutoRedrawMode(true);
canvas.addGLEventListener(this);
- window.getContentPane().add(canvas);
-
+ window.getContentPane().add(canvas);
canvas.setSize(newDim.width, newDim.height);
- window.setLocation(window_xpos, window_ypos);
- //window.setUndecorated(true);
- window.setResizable(false);
// register event listener
window.addWindowListener(new WindowAdapter() {
@@ -134,14 +139,57 @@ public class Impl extends Misc implements GLEventListener {
});
// D I F F E R E N T J A K E 2 E V E N T P R O C E S S I N G
+ window.addComponentListener(KBD.listener);
canvas.addKeyListener(KBD.listener);
canvas.addMouseListener(KBD.listener);
canvas.addMouseMotionListener(KBD.listener);
- window.addComponentListener(KBD.listener);
- canvas.requestFocus();
- window.pack();
- window.show();
+ /*
+ * fullscreen handling
+ */
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ device = env.getDefaultScreenDevice();
+
+ if (fullscreen && !device.isFullScreenSupported()) {
+ ri.Con_Printf(Defines.PRINT_ALL, "...fullscreen not supported\n");
+ vid_fullscreen.value = 0;
+ vid_fullscreen.modified = false;
+ }
+
+ fullscreen = fullscreen && device.isFullScreenSupported();
+
+ if (oldDisplayMode == null) {
+ oldDisplayMode = device.getDisplayMode();
+ }
+
+ if (fullscreen) {
+
+ DisplayMode displayMode = findDisplayMode(newDim, oldDisplayMode.getBitDepth(), oldDisplayMode.getRefreshRate());
+
+ if (displayMode != null) {
+ newDim.width = displayMode.getWidth();
+ newDim.height = displayMode.getHeight();
+ window.setUndecorated(true);
+ window.setResizable(false);
+ device.setFullScreenWindow(window);
+ device.setDisplayMode(displayMode);
+ window.setLocation(0, 0);
+ window.setSize(displayMode.getWidth(), displayMode.getHeight());
+ canvas.setSize(displayMode.getWidth(), displayMode.getHeight());
+ ri.Con_Printf(Defines.PRINT_ALL, "...setting fullscreen " + getModeString(displayMode) + '\n');
+ }
+ } else {
+ window.setLocation(window_xpos, window_ypos);
+ window.pack();
+ window.setResizable(false);
+ window.setVisible(true);
+ }
+
+ while (!canvas.isDisplayable()) {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {}
+ }
canvas.requestFocus();
this.canvas = canvas;
@@ -154,6 +202,38 @@ public class Impl extends Misc implements GLEventListener {
return rserr_ok;
}
+
+ DisplayMode findDisplayMode(Dimension dim, int depth, int rate) {
+ DisplayMode mode = null;
+ DisplayMode m = null;
+ DisplayMode[] modes = device.getDisplayModes();
+ int w = dim.width;
+ int h = dim.height;
+
+ for (int i = 0; i < modes.length; i++) {
+ m = modes[i];
+ if (m.getWidth() == w && m.getHeight() == h && m.getBitDepth() == depth && m.getRefreshRate() == rate) {
+ mode = m;
+ break;
+ }
+ }
+ if (mode == null) mode = oldDisplayMode;
+ Com.Printf(getModeString(mode) + '\n');
+ return mode;
+ }
+
+ String getModeString(DisplayMode m) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(m.getWidth());
+ sb.append('x');
+ sb.append(m.getHeight());
+ sb.append('x');
+ sb.append(m.getBitDepth());
+ sb.append('@');
+ sb.append(m.getRefreshRate());
+ sb.append("Hz");
+ return sb.toString();
+ }
void GLimp_BeginFrame(float camera_separation) {
// do nothing
@@ -180,11 +260,19 @@ public class Impl extends Misc implements GLEventListener {
}
void GLimp_Shutdown() {
+ if (oldDisplayMode != null && device.getFullScreenWindow() != null) {
+ try {
+ device.setDisplayMode(oldDisplayMode);
+ device.setFullScreenWindow(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
if (this.window != null) {
window.dispose();
}
post_init = false;
- switchToCallback = false;
+ callback = INIT_CALLBACK;
}
void GLimp_EnableLogging(boolean enable) {
@@ -221,31 +309,8 @@ public class Impl extends Misc implements GLEventListener {
this.gl = drawable.getGL();
this.glu = drawable.getGLU();
- this.contextInUse = true;
-
- if (switchToCallback) {
- callback.execute();
- }
- else
- {
-
- // after the first run (initialization) switch to callback
- switchToCallback = true;
-
- // clear the screen
- gl.glClearColor(0, 0, 0, 0);
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
-
- //
- // check the post init process
- //
- if (!post_init) {
- ri.Sys_Error(Defines.ERR_FATAL, "Error: can't init JOGL renderer");
- }
-
- GLimp_EndFrame();
- }
-
+ contextInUse = true;
+ callback.execute();
contextInUse = false;
}
@@ -260,20 +325,18 @@ public class Impl extends Misc implements GLEventListener {
* @see net.java.games.jogl.GLEventListener#reshape(net.java.games.jogl.GLDrawable, int, int, int, int)
*/
public void reshape(GLDrawable drawable, int x, int y, int width, int height) {
-
- vid.height = height;
- vid.width = width;
-
- ri.Vid_NewWindow(width, height);
+ // do nothing
}
/*
* @see jake2.client.refexport_t#updateScreen()
*/
+ public void updateScreen() {
+ this.callback = INIT_CALLBACK;
+ canvas.display();
+ }
+
public void updateScreen(xcommand_t callback) {
-// if (canvas == null) {
-// throw new IllegalStateException("Refresh modul \"" + DRIVER_NAME + "\" have to be initialized.");
-// }
this.callback = callback;
canvas.display();
}
diff --git a/src/jake2/render/jogl/Light.java b/src/jake2/render/jogl/Light.java
index 686884a..851f4e6 100644
--- a/src/jake2/render/jogl/Light.java
+++ b/src/jake2/render/jogl/Light.java
@@ -2,7 +2,7 @@
* Light.java
* Copyright (C) 2003
*
- * $Id: Light.java,v 1.3 2004-07-08 20:56:55 hzi Exp $
+ * $Id: Light.java,v 1.4 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,12 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2.render.jogl;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.Arrays;
-
-import net.java.games.jogl.GL;
-
import jake2.Defines;
import jake2.Globals;
import jake2.client.dlight_t;
@@ -38,12 +32,15 @@ import jake2.client.lightstyle_t;
import jake2.game.GameBase;
import jake2.game.cplane_t;
import jake2.qcommon.longjmpException;
-import jake2.render.mnode_t;
-import jake2.render.msurface_t;
-import jake2.render.mtexinfo_t;
-import jake2.util.Lib;
+import jake2.render.*;
import jake2.util.Math3D;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.Arrays;
+
+import net.java.games.jogl.GL;
+
/**
* Light
*
@@ -79,7 +76,7 @@ public abstract class Light extends Warp {
gl.glColor3f (light.color[0]*0.2f, light.color[1]*0.2f, light.color[2]*0.2f);
for (i=0 ; i<3 ; i++)
v[i] = light.origin[i] - vpn[i]*rad;
- gl.glVertex3fv (v);
+ gl.glVertex3f(v[0], v[1], v[2]);
gl.glColor3f (0,0,0);
for (i=16 ; i>=0 ; i--)
{
@@ -87,7 +84,7 @@ public abstract class Light extends Warp {
for (j=0 ; j<3 ; j++)
v[j] = (float)(light.origin[j] + vright[j]*Math.cos(a)*rad
+ vup[j]*Math.sin(a)*rad);
- gl.glVertex3fv (v);
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd ();
}
@@ -306,16 +303,13 @@ public abstract class Light extends Warp {
ds >>= 4;
dt >>= 4;
- //surf.samples.reset();
- lightmap = surf.samples.slice();
-
+ lightmap = surf.samples;
int lightmapIndex = 0;
+
Math3D.VectorCopy (Globals.vec3_origin, pointcolor);
if (lightmap != null)
{
float[] scale = {0, 0, 0};
-
-// lightmap += 3*(dt * ((surf.extents[0]>>4)+1) + ds);
lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds);
for (maps = 0 ; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255; maps++)
@@ -326,15 +320,11 @@ public abstract class Light extends Warp {
pointcolor[0] += (lightmap.get(lightmapIndex + 0) & 0xFF) * scale[0] * (1.0f/255);
pointcolor[1] += (lightmap.get(lightmapIndex + 1) & 0xFF) * scale[1] * (1.0f/255);
pointcolor[2] += (lightmap.get(lightmapIndex + 2) & 0xFF) * scale[2] * (1.0f/255);
-// lightmap += 3*((surf.extents[0]>>4)+1) *
-// ((surf.extents[1]>>4)+1);
lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1);
}
}
-
return 1;
}
-
// go down back side
return RecursiveLightPoint (node.children[1 - sideIndex], mid, end);
}
@@ -506,7 +496,7 @@ public abstract class Light extends Warp {
Combine and scale multiple lightmaps into the floating format in blocklights
===============
*/
- void R_BuildLightMap(msurface_t surf, ByteBuffer dest, int stride)
+ void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride)
{
int smax, tmax;
int r, g, b, a, max;
@@ -549,8 +539,8 @@ public abstract class Light extends Warp {
nummaps++)
;
- //surf.samples.reset();
- lightmap = surf.samples.slice();
+ lightmap = surf.samples;
+ int lightmapIndex = 0;
// add all the lightmaps
if ( nummaps == 1 )
@@ -572,18 +562,18 @@ public abstract class Light extends Warp {
{
for (i=0 ; i<size ; i++)
{
- bl[blp++] = lightmap.get() & 0xFF;
- bl[blp++] = lightmap.get() & 0xFF;
- bl[blp++] = lightmap.get() & 0xFF;
+ bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF;
}
}
else
{
for (i=0 ; i<size ; i++)
{
- bl[blp++] = (lightmap.get() & 0xFF) * scale[0];
- bl[blp++] = (lightmap.get() & 0xFF) * scale[1];
- bl[blp++] = (lightmap.get() & 0xFF) * scale[2];
+ bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[0];
+ bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[1];
+ bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[2];
}
}
//lightmap += size*3; // skip to next lightmap
@@ -612,18 +602,18 @@ public abstract class Light extends Warp {
{
for (i=0 ; i<size ; i++)
{
- bl[blp++] += lightmap.get() & 0xFF;
- bl[blp++] += lightmap.get() & 0xFF;
- bl[blp++] += lightmap.get() & 0xFF;
+ bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF;
+ bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF;
}
}
else
{
for (i=0 ; i<size ; i++)
{
- bl[blp++] += (lightmap.get() & 0xFF) * scale[0];
- bl[blp++] += (lightmap.get() & 0xFF) * scale[1];
- bl[blp++] += (lightmap.get() & 0xFF) * scale[2];
+ bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[0];
+ bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[1];
+ bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[2];
}
}
//lightmap += size*3; // skip to next lightmap
@@ -638,7 +628,7 @@ public abstract class Light extends Warp {
} catch (longjmpException store) {}
// put into texture format
- stride -= (smax<<2);
+ stride -= smax;
bl = s_blocklights;
int blp = 0;
@@ -697,8 +687,8 @@ public abstract class Light extends Warp {
b = (int)(b*t);
a = (int)(a*t);
}
- dest.put((byte)r).put((byte)g).put((byte)b).put((byte)a);
- destp += 4;
+ r &= 0xFF; g &= 0xFF; b &= 0xFF; a &= 0xFF;
+ dest.put(destp++, (a << 24) | (b << 16) | (g << 8) | (r << 0));
}
}
}
@@ -778,9 +768,8 @@ public abstract class Light extends Warp {
a = 255 - a;
break;
}
-
- dest.put((byte)r).put((byte)g).put((byte)b).put((byte)a);
- destp += 4;
+ r &= 0xFF; g &= 0xFF; b &= 0xFF; a &= 0xFF;
+ dest.put(destp++, (a << 24) | (b << 16) | (g << 8) | (r << 0));
}
}
}
diff --git a/src/jake2/render/jogl/Main.java b/src/jake2/render/jogl/Main.java
index 32442ba..2b46501 100644
--- a/src/jake2/render/jogl/Main.java
+++ b/src/jake2/render/jogl/Main.java
@@ -2,7 +2,7 @@
* Main.java
* Copyright (C) 2003
*
- * $Id: Main.java,v 1.2 2004-07-08 15:58:44 hzi Exp $
+ * $Id: Main.java,v 1.3 2004-07-09 06:50:47 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -29,6 +29,7 @@ import jake2.*;
import jake2.client.*;
import jake2.game.cplane_t;
import jake2.game.cvar_t;
+import jake2.qcommon.Cvar;
import jake2.qcommon.qfiles;
import jake2.qcommon.xcommand_t;
import jake2.render.*;
@@ -36,9 +37,12 @@ import jake2.util.Math3D;
import jake2.util.Vargs;
import java.awt.Dimension;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
import net.java.games.jogl.GL;
import net.java.games.jogl.GLU;
+import net.java.games.jogl.util.BufferUtils;
import net.java.games.jogl.util.GLUT;
/**
@@ -52,7 +56,7 @@ public abstract class Main extends Base {
GLU glu;
GLUT glut = new GLUT();
- int[] d_8to24table = new int[256];
+ public static int[] d_8to24table = new int[256];
int c_visible_lightmaps;
int c_visible_textures;
@@ -66,8 +70,8 @@ public abstract class Main extends Base {
boolean qglActiveTextureARB = false;
boolean qglPointParameterfEXT = false;
boolean qglLockArraysEXT = false;
- boolean qglUnlockArraysEXT = false;
boolean qglMTexCoord2fSGIS = false;
+ boolean qwglSwapIntervalEXT = false;
// =================
// abstract methods
@@ -323,22 +327,22 @@ public abstract class Main extends Base {
gl.glTexCoord2f(0, 1);
Math3D.VectorMA(e.origin, -frame.origin_y, vup, point);
Math3D.VectorMA(point, -frame.origin_x, vright, point);
- gl.glVertex3fv(point);
+ gl.glVertex3f(point[0], point[1], point[2]);
gl.glTexCoord2f(0, 0);
Math3D.VectorMA(e.origin, frame.height - frame.origin_y, vup, point);
Math3D.VectorMA(point, -frame.origin_x, vright, point);
- gl.glVertex3fv(point);
+ gl.glVertex3f(point[0], point[1], point[2]);
gl.glTexCoord2f(1, 0);
Math3D.VectorMA(e.origin, frame.height - frame.origin_y, vup, point);
Math3D.VectorMA(point, frame.width - frame.origin_x, vright, point);
- gl.glVertex3fv(point);
+ gl.glVertex3f(point[0], point[1], point[2]);
gl.glTexCoord2f(1, 1);
Math3D.VectorMA(e.origin, -frame.origin_y, vup, point);
Math3D.VectorMA(point, frame.width - frame.origin_x, vright, point);
- gl.glVertex3fv(point);
+ gl.glVertex3f(point[0], point[1], point[2]);
gl.glEnd();
@@ -375,7 +379,7 @@ public abstract class Main extends Base {
R_RotateForEntity(currententity);
gl.glDisable(GL.GL_TEXTURE_2D);
- gl.glColor3fv(shadelight);
+ gl.glColor3f(shadelight[0], shadelight[1], shadelight[2]);
// this replaces the TRIANGLE_FAN
glut.glutWireCube(gl, 20);
@@ -479,63 +483,63 @@ public abstract class Main extends Base {
}
gl.glDepthMask(true); // back to writing
}
-
+
/*
** GL_DrawParticles
**
*/
- void GL_DrawParticles(int num_particles, particle_t[] particles) {
- particle_t p;
- int i;
+ void GL_DrawParticles(int num_particles) {
float[] up = { 0, 0, 0 };
float[] right = { 0, 0, 0 };
float scale;
int color;
+ float origin_x, origin_y, origin_z;
+
+ Math3D.VectorScale(vup, 1.5f, up);
+ Math3D.VectorScale(vright, 1.5f, right);
+
GL_Bind(r_particletexture.texnum);
gl.glDepthMask(false); // no z buffering
gl.glEnable(GL.GL_BLEND);
GL_TexEnv(GL.GL_MODULATE);
+
gl.glBegin(GL.GL_TRIANGLES);
- Math3D.VectorScale(vup, 1.5f, up);
- Math3D.VectorScale(vright, 1.5f, right);
+ FloatBuffer sourceVertices = particle_t.vertexArray;
+ IntBuffer sourceColors = particle_t.colorArray;
+ for (int j = 0, i = 0; i < num_particles; i++) {
+ origin_x = sourceVertices.get(j++);
+ origin_y = sourceVertices.get(j++);
+ origin_z = sourceVertices.get(j++);
- for (i = 0; i < num_particles; i++) {
- p = particles[i];
// hack a scale up to keep particles from disapearing
scale =
- (p.origin[0] - r_origin[0]) * vpn[0]
- + (p.origin[1] - r_origin[1]) * vpn[1]
- + (p.origin[2] - r_origin[2]) * vpn[2];
+ (origin_x - r_origin[0]) * vpn[0]
+ + (origin_y - r_origin[1]) * vpn[1]
+ + (origin_z - r_origin[2]) * vpn[2];
- if (scale < 20)
- scale = 1;
- else
- scale = 1 + scale * 0.004f;
-
- color = d_8to24table[p.color];
+ scale = (scale < 20) ? 1 : 1 + scale * 0.004f;
+ color = sourceColors.get(i);
gl.glColor4ub(
- (byte) ((color >> 0) & 0xff),
- (byte) ((color >> 8) & 0xff),
- (byte) ((color >> 16) & 0xff),
- (byte) (p.alpha * 255));
-
+ (byte)((color >> 0) & 0xFF),
+ (byte)((color >> 8) & 0xFF),
+ (byte)((color >> 16) & 0xFF),
+ (byte)((color >> 24) & 0xFF)
+ );
+ // first vertex
gl.glTexCoord2f(0.0625f, 0.0625f);
- gl.glVertex3fv(p.origin);
-
+ gl.glVertex3f(origin_x, origin_y, origin_z);
+ // second vertex
gl.glTexCoord2f(1.0625f, 0.0625f);
- gl.glVertex3f(p.origin[0] + up[0] * scale, p.origin[1] + up[1] * scale, p.origin[2] + up[2] * scale);
-
+ gl.glVertex3f(origin_x + up[0] * scale, origin_y + up[1] * scale, origin_z + up[2] * scale);
+ // third vertex
gl.glTexCoord2f(0.0625f, 1.0625f);
- gl.glVertex3f(
- p.origin[0] + right[0] * scale,
- p.origin[1] + right[1] * scale,
- p.origin[2] + right[2] * scale);
+ gl.glVertex3f(origin_x + right[0] * scale, origin_y + right[1] * scale, origin_z + right[2] * scale);
}
-
gl.glEnd();
+
gl.glDisable(GL.GL_BLEND);
gl.glColor4f(1, 1, 1, 1);
gl.glDepthMask(true); // back to normal Z buffering
@@ -550,29 +554,21 @@ public abstract class Main extends Base {
void R_DrawParticles() {
if (gl_ext_pointparameters.value != 0.0f && qglPointParameterfEXT) {
- int color;
- particle_t p;
+ gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
+ gl.glVertexPointer(3, GL.GL_FLOAT, 0, particle_t.vertexArray);
+ gl.glEnableClientState(GL.GL_COLOR_ARRAY);
+ gl.glColorPointer(4, GL.GL_UNSIGNED_BYTE, 0, particle_t.colorArray);
+
gl.glDepthMask(false);
gl.glEnable(GL.GL_BLEND);
gl.glDisable(GL.GL_TEXTURE_2D);
-
gl.glPointSize(gl_particle_size.value);
-
- gl.glBegin(GL.GL_POINTS);
- for (int i = 0; i < r_newrefdef.num_particles; i++) {
- p = r_newrefdef.particles[i];
- color = d_8to24table[p.color];
-
- gl.glColor4ub(
- (byte) ((color >> 0) & 0xff),
- (byte) ((color >> 8) & 0xff),
- (byte) ((color >> 16) & 0xff),
- (byte) (p.alpha * 255));
-
- gl.glVertex3fv(p.origin);
- }
- gl.glEnd();
+
+ gl.glDrawArrays(GL.GL_POINTS, 0, r_newrefdef.num_particles);
+
+ gl.glDisableClientState(GL.GL_COLOR_ARRAY);
+ gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
gl.glDisable(GL.GL_BLEND);
gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
@@ -581,7 +577,7 @@ public abstract class Main extends Base {
}
else {
- GL_DrawParticles(r_newrefdef.num_particles, r_newrefdef.particles);
+ GL_DrawParticles(r_newrefdef.num_particles);
}
}
@@ -608,7 +604,7 @@ public abstract class Main extends Base {
gl.glRotatef(-90, 1, 0, 0); // put Z going up
gl.glRotatef(90, 0, 0, 1); // put Z going up
- gl.glColor4fv(v_blend);
+ gl.glColor4f(v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
gl.glBegin(GL.GL_QUADS);
@@ -958,7 +954,7 @@ public abstract class Main extends Base {
protected void R_Register() {
r_lefthand = ri.Cvar_Get("hand", "0", Globals.CVAR_USERINFO | Globals.CVAR_ARCHIVE);
r_norefresh = ri.Cvar_Get("r_norefresh", "0", 0);
- r_fullbright = ri.Cvar_Get("r_fullbright", "1", 0);
+ r_fullbright = ri.Cvar_Get("r_fullbright", "0", 0);
r_drawentities = ri.Cvar_Get("r_drawentities", "1", 0);
r_drawworld = ri.Cvar_Get("r_drawworld", "1", 0);
r_novis = ri.Cvar_Get("r_novis", "0", 0);
@@ -1007,7 +1003,7 @@ public abstract class Main extends Base {
gl_vertex_arrays = ri.Cvar_Get("gl_vertex_arrays", "0", Globals.CVAR_ARCHIVE);
gl_ext_swapinterval = ri.Cvar_Get("gl_ext_swapinterval", "1", Globals.CVAR_ARCHIVE);
- gl_ext_palettedtexture = ri.Cvar_Get("gl_ext_palettedtexture", "1", Globals.CVAR_ARCHIVE);
+ gl_ext_palettedtexture = ri.Cvar_Get("gl_ext_palettedtexture", "0", Globals.CVAR_ARCHIVE);
gl_ext_multitexture = ri.Cvar_Get("gl_ext_multitexture", "1", Globals.CVAR_ARCHIVE);
gl_ext_pointparameters = ri.Cvar_Get("gl_ext_pointparameters", "1", Globals.CVAR_ARCHIVE);
gl_ext_compiled_vertex_array = ri.Cvar_Get("gl_ext_compiled_vertex_array", "1", Globals.CVAR_ARCHIVE);
@@ -1056,11 +1052,11 @@ public abstract class Main extends Base {
int err; // enum rserr_t
boolean fullscreen;
- if (vid_fullscreen.modified && !gl_config.allow_cds) {
- ri.Con_Printf(Defines.PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n");
- ri.Cvar_SetValue("vid_fullscreen", (vid_fullscreen.value > 0.0f) ? 0.0f : 1.0f);
- vid_fullscreen.modified = false;
- }
+// if (vid_fullscreen.modified && !gl_config.allow_cds) {
+// ri.Con_Printf(Defines.PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n");
+// ri.Cvar_SetValue("vid_fullscreen", (vid_fullscreen.value > 0.0f) ? 0.0f : 1.0f);
+// vid_fullscreen.modified = false;
+// }
fullscreen = (vid_fullscreen.value > 0.0f);
@@ -1237,25 +1233,24 @@ public abstract class Main extends Base {
|| gl_config.extensions_string.indexOf("GL_SGI_compiled_vertex_array") >= 0) {
ri.Con_Printf(Defines.PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n");
// qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
- qglLockArraysEXT = true;
+ if (gl_ext_compiled_vertex_array.value != 0.0f)
+ qglLockArraysEXT = true;
+ else
+ qglLockArraysEXT = false;
// qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
- qglUnlockArraysEXT = true;
+ //qglUnlockArraysEXT = true;
}
else {
ri.Con_Printf(Defines.PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n");
}
- // #ifdef _WIN32
- // if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) )
- // {
- // qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
- // ri.Con_Printf( Defines.PRINT_ALL, "...enabling WGL_EXT_swap_control\n" );
- // }
- // else
- // {
- // ri.Con_Printf( Defines.PRINT_ALL, "...WGL_EXT_swap_control not found\n" );
- // }
- // #endif
+ if (gl_config.extensions_string.indexOf("WGL_EXT_swap_control") >= 0) {
+ qwglSwapIntervalEXT = true;
+ ri.Con_Printf(Defines.PRINT_ALL, "...enabling WGL_EXT_swap_control\n");
+ } else {
+ qwglSwapIntervalEXT = false;
+ ri.Con_Printf(Defines.PRINT_ALL, "...WGL_EXT_swap_control not found\n");
+ }
if (gl_config.extensions_string.indexOf("GL_EXT_point_parameters") >= 0) {
if (gl_ext_pointparameters.value != 0.0f) {
@@ -1301,6 +1296,7 @@ public abstract class Main extends Base {
}
else {
ri.Con_Printf(Defines.PRINT_ALL, "...ignoring GL_EXT_shared_texture_palette\n");
+ qglColorTableEXT = false;
}
}
else {
@@ -1317,34 +1313,40 @@ public abstract class Main extends Base {
qglMTexCoord2fSGIS = true;
GL_TEXTURE0 = GL.GL_TEXTURE0_ARB;
GL_TEXTURE1 = GL.GL_TEXTURE1_ARB;
+ Cvar.SetValue("r_fullbright", 1);
}
else {
ri.Con_Printf(Defines.PRINT_ALL, "...ignoring GL_ARB_multitexture\n");
+ Cvar.SetValue("r_fullbright", 0);
}
}
else {
ri.Con_Printf(Defines.PRINT_ALL, "...GL_ARB_multitexture not found\n");
+ Cvar.SetValue("r_fullbright", 0);
}
if (gl_config.extensions_string.indexOf("GL_SGIS_multitexture") >= 0) {
if (qglActiveTextureARB) {
ri.Con_Printf(Defines.PRINT_ALL, "...GL_SGIS_multitexture deprecated in favor of ARB_multitexture\n");
- }
- else if (gl_ext_multitexture.value != 0.0f) {
+ Cvar.SetValue("r_fullbright", 1);
+ } else if (gl_ext_multitexture.value != 0.0f) {
ri.Con_Printf(Defines.PRINT_ALL, "...using GL_SGIS_multitexture\n");
// qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" );
// qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" );
qglSelectTextureSGIS = true;
qglMTexCoord2fSGIS = true;
+ Cvar.SetValue("r_fullbright", 1);
// //GL_TEXTURE0 = GL.GL_TEXTURE0_SGIS;
// //GL_TEXTURE1 = GL.GL_TEXTURE1_SGIS;
- }
- else {
+ } else {
ri.Con_Printf(Defines.PRINT_ALL, "...ignoring GL_SGIS_multitexture\n");
+ Cvar.SetValue("r_fullbright", 0);
}
}
else {
ri.Con_Printf(Defines.PRINT_ALL, "...GL_SGIS_multitexture not found\n");
+ if (!qglActiveTextureARB)
+ Cvar.SetValue("r_fullbright", 0);
}
GL_SetDefaultState();
@@ -1359,7 +1361,7 @@ public abstract class Main extends Base {
ri.Con_Printf(
Defines.PRINT_ALL,
"glGetError() = 0x%x\n\t%s\n",
- new Vargs(2).add(err).add(gl.glGetString(err)));
+ new Vargs(2).add(err).add("" + gl.glGetString(err)));
return true;
}
@@ -1406,7 +1408,7 @@ public abstract class Main extends Base {
// FIXME: only restart if CDS is required
cvar_t ref;
- ref = ri.Cvar_Get("vid_ref", "gl", 0);
+ ref = ri.Cvar_Get("vid_ref", "jogl", 0);
ref.modified = true;
}
@@ -1511,26 +1513,22 @@ public abstract class Main extends Base {
=============
*/
protected void R_SetPalette(byte[] palette) {
-
- //assert(palette != null && palette.length == 768) : "byte palette[768] bug";
- // es darf auch null sein
-
+ // 256 RGB values (768 bytes)
+ // or null
int i;
int color = 0;
if (palette != null) {
-
+ int j =0;
for (i = 0; i < 256; i++) {
- color = (palette[i * 3 + 0] << 0) & 0x000000FF;
- color |= (palette[i * 3 + 1] << 8) & 0x0000FF00;
- color |= (palette[i * 3 + 2] << 8) & 0x00FF0000;
+ color = (palette[j++] & 0xFF) << 0;
+ color |= (palette[j++] & 0xFF) << 8;
+ color |= (palette[j++] & 0xFF) << 16;
color |= 0xFF000000;
r_rawpalette[i] = color;
}
-
}
else {
-
for (i = 0; i < 256; i++) {
r_rawpalette[i] = d_8to24table[i] | 0xff000000;
}
@@ -1543,6 +1541,9 @@ public abstract class Main extends Base {
}
static final int NUM_BEAM_SEGS = 6;
+ float[][] start_points = new float[NUM_BEAM_SEGS][3];
+ // array of vec3_t
+ float[][] end_points = new float[NUM_BEAM_SEGS][3]; // array of vec3_t
/*
** R_DrawBeam
@@ -1556,10 +1557,6 @@ public abstract class Main extends Base {
float[] direction = { 0, 0, 0 }; // vec3_t
float[] normalized_direction = { 0, 0, 0 }; // vec3_t
- float[][] start_points = new float[NUM_BEAM_SEGS][3];
- // array of vec3_t
- float[][] end_points = new float[NUM_BEAM_SEGS][3]; // array of vec3_t
-
float[] oldorigin = { 0, 0, 0 }; // vec3_t
float[] origin = { 0, 0, 0 }; // vec3_t
@@ -1607,11 +1604,18 @@ public abstract class Main extends Base {
gl.glColor4f(r, g, b, e.alpha);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
+
+ float[] v;
+
for (i = 0; i < NUM_BEAM_SEGS; i++) {
- gl.glVertex3fv(start_points[i]);
- gl.glVertex3fv(end_points[i]);
- gl.glVertex3fv(start_points[(i + 1) % NUM_BEAM_SEGS]);
- gl.glVertex3fv(end_points[(i + 1) % NUM_BEAM_SEGS]);
+ v = start_points[i];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ v = end_points[i];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ v = start_points[(i + 1) % NUM_BEAM_SEGS];
+ gl.glVertex3f(v[0], v[1], v[2]);
+ v = end_points[(i + 1) % NUM_BEAM_SEGS];
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd();
diff --git a/src/jake2/render/jogl/Mesh.java b/src/jake2/render/jogl/Mesh.java
index 37e4445..991bf37 100644
--- a/src/jake2/render/jogl/Mesh.java
+++ b/src/jake2/render/jogl/Mesh.java
@@ -2,7 +2,7 @@
* Mesh.java
* Copyright (C) 2003
*
- * $Id: Mesh.java,v 1.3 2004-07-08 20:24:30 hzi Exp $
+ * $Id: Mesh.java,v 1.4 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -104,36 +104,36 @@ public abstract class Mesh extends Light {
{
int i;
int lerpIndex = 0;
- lerp.position(0);
//PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
if ( (currententity.flags & ( Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0 )
{
float[] normal;
+ int j = 0;
for (i=0 ; i < nverts; i++/* , v++, ov++, lerp+=4 */)
{
normal = r_avertexnormals[verts[i].lightnormalindex];
- lerp.put(move[0] + ov[i].v[0]*backv[0] + v[i].v[0]*frontv[0] + normal[0] * Defines.POWERSUIT_SCALE);
- lerp.put(move[1] + ov[i].v[1]*backv[1] + v[i].v[1]*frontv[1] + normal[1] * Defines.POWERSUIT_SCALE);
- lerp.put(move[2] + ov[i].v[2]*backv[2] + v[i].v[2]*frontv[2] + normal[2] * Defines.POWERSUIT_SCALE);
- lerp.get();
+ lerp.put(j++, move[0] + ov[i].v[0]*backv[0] + v[i].v[0]*frontv[0] + normal[0] * Defines.POWERSUIT_SCALE);
+ lerp.put(j++, move[1] + ov[i].v[1]*backv[1] + v[i].v[1]*frontv[1] + normal[1] * Defines.POWERSUIT_SCALE);
+ lerp.put(j++, move[2] + ov[i].v[2]*backv[2] + v[i].v[2]*frontv[2] + normal[2] * Defines.POWERSUIT_SCALE);
}
}
else
{
+ int j = 0;
for (i=0 ; i < nverts; i++ /* , v++, ov++, lerp+=4 */)
{
- lerp.put(move[0] + ov[i].v[0]*backv[0] + v[i].v[0]*frontv[0]);
- lerp.put(move[1] + ov[i].v[1]*backv[1] + v[i].v[1]*frontv[1]);
- lerp.put(move[2] + ov[i].v[2]*backv[2] + v[i].v[2]*frontv[2]);
- lerp.get();
+
+ lerp.put(j++, move[0] + ov[i].v[0]*backv[0] + v[i].v[0]*frontv[0]);
+ lerp.put(j++, move[1] + ov[i].v[1]*backv[1] + v[i].v[1]*frontv[1]);
+ lerp.put(j++, move[2] + ov[i].v[2]*backv[2] + v[i].v[2]*frontv[2]);
}
}
}
FloatBuffer colorArrayBuf = BufferUtils.newFloatBuffer(qfiles.MAX_VERTS * 4);
- FloatBuffer vertexArrayBuf = BufferUtils.newFloatBuffer(qfiles.MAX_VERTS * 4);
+ FloatBuffer vertexArrayBuf = BufferUtils.newFloatBuffer(qfiles.MAX_VERTS * 3);
boolean isFilled = false;
float[] tmpVec = {0, 0, 0};
@@ -218,7 +218,7 @@ public abstract class Mesh extends Light {
GL_LerpVerts( paliashdr.num_xyz, v, ov, verts, vertexArrayBuf, move, frontv, backv );
gl.glEnableClientState( GL.GL_VERTEX_ARRAY );
- gl.glVertexPointer( 3, GL.GL_FLOAT, 16, vertexArrayBuf ); // padded for SIMD
+ gl.glVertexPointer( 3, GL.GL_FLOAT, 0, vertexArrayBuf );
// PMM - added double damage shell
if ( (currententity.flags & ( Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0)
@@ -233,11 +233,15 @@ public abstract class Mesh extends Light {
//
// pre light everything
//
- colorArrayBuf.position(0);
+ FloatBuffer color = colorArrayBuf;
+ int j = 0;
for ( i = 0; i < paliashdr.num_xyz; i++ )
{
l = shadedots[verts[i].lightnormalindex];
- colorArrayBuf.put(l * shadelight[0]).put(l * shadelight[1]).put(l * shadelight[2]).put(alpha);
+ color.put(j++, l * shadelight[0]);
+ color.put(j++, l * shadelight[1]);
+ color.put(j++, l * shadelight[2]);
+ color.put(j++, alpha);
}
}
@@ -294,13 +298,15 @@ public abstract class Mesh extends Light {
gl.glEnd ();
}
- if ( qglUnlockArraysEXT )
+ if ( qglLockArraysEXT )
gl.glUnlockArraysEXT();
}
else
{
GL_LerpVerts( paliashdr.num_xyz, v, ov, verts, s_lerped, move, frontv, backv );
+ float[] tmp;
+
while (true)
{
// get the vertex count and primitive type
@@ -325,7 +331,8 @@ public abstract class Mesh extends Light {
orderIndex += 3;
gl.glColor4f( shadelight[0], shadelight[1], shadelight[2], alpha);
- gl.glVertex3fv (s_lerped[index_xyz]);
+ tmp = s_lerped[index_xyz];
+ gl.glVertex3f(tmp[0], tmp[1], tmp[2]);
} while (--count != 0);
}
@@ -344,7 +351,8 @@ public abstract class Mesh extends Light {
l = shadedots[verts[index_xyz].lightnormalindex];
gl.glColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha);
- gl.glVertex3fv (s_lerped[index_xyz]);
+ tmp = s_lerped[index_xyz];
+ gl.glVertex3f(tmp[0], tmp[1], tmp[2]);
} while (--count != 0);
}
gl.glEnd ();
@@ -384,6 +392,7 @@ public abstract class Mesh extends Light {
height = -lheight + 1.0f;
int orderIndex = 0;
+ int index = 0;
while (true)
{
@@ -410,18 +419,20 @@ public abstract class Mesh extends Light {
if ( gl_vertex_arrays.value != 0.0f )
{
- vertexArrayBuf.position(order[orderIndex + 2] * 4);
- vertexArrayBuf.get(point);
+ index = order[orderIndex + 2] * 3;
+ point[0] = vertexArrayBuf.get(index);
+ point[1] = vertexArrayBuf.get(index + 1);
+ point[2] = vertexArrayBuf.get(index + 2);
}
else
{
- System.arraycopy(s_lerped[order[orderIndex + 2]], 0, point, 0, 3);
+ Math3D.VectorCopy(s_lerped[order[orderIndex + 2]], point);
}
point[0] -= shadevector[0]*(point[2]+lheight);
point[1] -= shadevector[1]*(point[2]+lheight);
point[2] = height;
- gl.glVertex3fv (point);
+ gl.glVertex3f(point[0], point[1], point[2]);
orderIndex += 3;
diff --git a/src/jake2/render/jogl/Misc.java b/src/jake2/render/jogl/Misc.java
index 8f04a84..a1d2e70 100644
--- a/src/jake2/render/jogl/Misc.java
+++ b/src/jake2/render/jogl/Misc.java
@@ -2,7 +2,7 @@
* Misc.java
* Copyright (C) 2003
*
- * $Id: Misc.java,v 1.1 2004-07-07 19:59:41 hzi Exp $
+ * $Id: Misc.java,v 1.2 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,9 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2.render.jogl;
-import net.java.games.jogl.GL;
-
import jake2.Defines;
+import net.java.games.jogl.GL;
+import net.java.games.jogl.WGL;
/**
* Misc
@@ -249,13 +249,11 @@ public abstract class Misc extends Mesh {
if ( gl_swapinterval.modified )
{
gl_swapinterval.modified = false;
-
if ( !gl_state.stereo_enabled )
{
-// #ifdef _WIN32
-// if ( qwglSwapIntervalEXT )
-// qwglSwapIntervalEXT( gl_swapinterval->value );
-// #endif
+ if (qwglSwapIntervalEXT) {
+ ((WGL)gl).wglSwapIntervalEXT((int)gl_swapinterval.value);
+ }
}
}
}
diff --git a/src/jake2/render/jogl/Model.java b/src/jake2/render/jogl/Model.java
index 8c2cfc8..75357c3 100644
--- a/src/jake2/render/jogl/Model.java
+++ b/src/jake2/render/jogl/Model.java
@@ -2,7 +2,7 @@
* Model.java
* Copyright (C) 2003
*
- * $Id: Model.java,v 1.1 2004-07-07 19:59:42 hzi Exp $
+ * $Id: Model.java,v 1.2 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -517,6 +517,9 @@ public abstract class Model extends Surf {
count = l.filelen / texinfo_t.SIZE;
// out = Hunk_Alloc ( count*sizeof(*out));
out = new mtexinfo_t[count];
+ for ( i=0 ; i<count ; i++) {
+ out[i] = new mtexinfo_t();
+ }
loadmodel.texinfo = out;
loadmodel.numtexinfo = count;
@@ -524,13 +527,10 @@ public abstract class Model extends Surf {
ByteBuffer bb = ByteBuffer.wrap(mod_base, l.fileofs, l.filelen);
bb.order(ByteOrder.LITTLE_ENDIAN);
- for ( i=0 ; i<count ; i++)
- {
- in = new texinfo_t(bb);
- out[i] = new mtexinfo_t();
- //for (j=0 ; j<8 ; j++)
- out[i].vecs = in.vecs;
+ for ( i=0 ; i<count ; i++) {
+ in = new texinfo_t(bb);
+ out[i].vecs = in.vecs;
out[i].flags = in.flags;
next = in.nexttexinfo;
if (next > 0)
@@ -541,17 +541,14 @@ public abstract class Model extends Surf {
name = "textures/" + in.texture + ".wal";
out[i].image = GL_FindImage(name, it_wall);
- if (out[i].image == null)
- {
+ if (out[i].image == null) {
ri.Con_Printf(Defines.PRINT_ALL, "Couldn't load " + name + '\n');
out[i].image = r_notexture;
}
}
// count animation frames
- for (i=0 ; i<count ; i++)
- {
- // out = &loadmodel.texinfo[i];
+ for (i=0 ; i<count ; i++) {
out[i].numframes = 1;
for (step = out[i].next ; (step != null) && (step != out[i]) ; step=step.next)
out[i].numframes++;
diff --git a/src/jake2/render/jogl/Surf.java b/src/jake2/render/jogl/Surf.java
index 7f05332..54e0e77 100644
--- a/src/jake2/render/jogl/Surf.java
+++ b/src/jake2/render/jogl/Surf.java
@@ -2,7 +2,7 @@
* Surf.java
* Copyright (C) 2003
*
- * $Id: Surf.java,v 1.2 2004-07-08 20:24:30 hzi Exp $
+ * $Id: Surf.java,v 1.3 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -25,35 +25,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package jake2.render.jogl;
-import java.awt.geom.AffineTransform;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.BufferedImage;
-import java.nio.ByteBuffer;
+import jake2.Defines;
+import jake2.client.*;
+import jake2.game.cplane_t;
+import jake2.render.*;
+import jake2.util.Lib;
+import jake2.util.Math3D;
+
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
import net.java.games.jogl.GL;
-import net.java.games.jogl.util.BufferUtils;
-
-import jake2.Defines;
-import jake2.client.dlight_t;
-import jake2.client.entity_t;
-import jake2.client.lightstyle_t;
-import jake2.game.cplane_t;
-import jake2.imageio.ImageFrame;
-import jake2.render.glpoly_t;
-import jake2.render.image_t;
-import jake2.render.medge_t;
-import jake2.render.mleaf_t;
-import jake2.render.mnode_t;
-import jake2.render.model_t;
-import jake2.render.msurface_t;
-import jake2.render.mtexinfo_t;
-import jake2.util.Lib;
-import jake2.util.Math3D;
/**
* Surf
@@ -92,7 +75,7 @@ public abstract class Surf extends Draw {
// the lightmap texture data needs to be kept in
// main memory so texsubimage can update properly
- byte[] lightmap_buffer = new byte[4 * BLOCK_WIDTH * BLOCK_HEIGHT];
+ IntBuffer lightmap_buffer = Lib.newIntBuffer(BLOCK_WIDTH * BLOCK_HEIGHT, ByteOrder.LITTLE_ENDIAN);
public gllightmapstate_t() {
@@ -129,7 +112,7 @@ public abstract class Surf extends Draw {
// Light.java
abstract void R_MarkLights (dlight_t light, int bit, mnode_t node);
abstract void R_SetCacheState( msurface_t surf );
- abstract void R_BuildLightMap(msurface_t surf, ByteBuffer dest, int stride);
+ abstract void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride);
/*
=============================================================
@@ -178,7 +161,7 @@ public abstract class Surf extends Draw {
{
v = p.verts[i];
gl.glTexCoord2f(v[3], v[4]);
- gl.glVertex3fv(v);
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd();
}
@@ -208,7 +191,7 @@ public abstract class Surf extends Draw {
{
v = p.verts[i];
gl.glTexCoord2f ((v[3] + scroll), v[4]);
- gl.glVertex3fv( v );
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd ();
}
@@ -273,7 +256,7 @@ public abstract class Surf extends Draw {
{
v = p.verts[j];
gl.glTexCoord2f (v[5], v[6] );
- gl.glVertex3fv( v );
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd();
}
@@ -290,7 +273,7 @@ public abstract class Surf extends Draw {
{
v = p.verts[j];
gl.glTexCoord2f (v[5] - soffset, v[6] - toffset );
- gl.glVertex3fv( v );
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd();
}
@@ -399,7 +382,7 @@ public abstract class Surf extends Draw {
for ( surf = gl_lms.lightmap_surfaces[0]; surf != null; surf = surf.lightmapchain )
{
int smax, tmax;
- ByteBuffer base;
+ IntBuffer base;
smax = (surf.extents[0]>>4)+1;
tmax = (surf.extents[1]>>4)+1;
@@ -412,10 +395,10 @@ public abstract class Surf extends Draw {
surf.dlight_s = lightPos.x;
surf.dlight_t = lightPos.y;
- base = ByteBuffer.wrap(gl_lms.lightmap_buffer);
- base.position( ( surf.dlight_t * BLOCK_WIDTH + surf.dlight_s ) * LIGHTMAP_BYTES);
+ base = gl_lms.lightmap_buffer;
+ base.position(surf.dlight_t * BLOCK_WIDTH + surf.dlight_s );
- R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
+ R_BuildLightMap (surf, base.slice(), BLOCK_WIDTH);
}
else
{
@@ -448,10 +431,10 @@ public abstract class Surf extends Draw {
surf.dlight_s = lightPos.x;
surf.dlight_t = lightPos.y;
- base = ByteBuffer.wrap(gl_lms.lightmap_buffer);
- base.position( ( surf.dlight_t * BLOCK_WIDTH + surf.dlight_s ) * LIGHTMAP_BYTES);
+ base = gl_lms.lightmap_buffer;
+ base.position(surf.dlight_t * BLOCK_WIDTH + surf.dlight_s );
- R_BuildLightMap (surf, base, BLOCK_WIDTH*LIGHTMAP_BYTES);
+ R_BuildLightMap (surf, base.slice(), BLOCK_WIDTH);
}
}
@@ -476,7 +459,7 @@ public abstract class Surf extends Draw {
gl.glDepthMask( true );
}
- private ByteBuffer temp2 = BufferUtils.newByteBuffer(34 * 34 * 4);
+ private IntBuffer temp2 = Lib.newIntBuffer(34 * 34, ByteOrder.LITTLE_ENDIAN);
/*
================
@@ -562,7 +545,7 @@ public abstract class Surf extends Draw {
smax = (fa.extents[0]>>4)+1;
tmax = (fa.extents[1]>>4)+1;
- R_BuildLightMap( fa, temp2, smax*4 );
+ R_BuildLightMap( fa, temp2, smax);
R_SetCacheState( fa );
GL_Bind( gl_state.lightmap_textures + fa.lightmaptexturenum );
@@ -717,7 +700,7 @@ public abstract class Surf extends Draw {
}
// direct buffer
- ByteBuffer temp = BufferUtils.newByteBuffer(128 * 128 * 4);
+ private IntBuffer temp = Lib.newIntBuffer(128 * 128, ByteOrder.LITTLE_ENDIAN);
void GL_RenderLightmappedPoly( msurface_t surf )
{
@@ -766,7 +749,7 @@ public abstract class Surf extends Draw {
smax = (surf.extents[0]>>4)+1;
tmax = (surf.extents[1]>>4)+1;
- R_BuildLightMap( surf, temp, smax*4 );
+ R_BuildLightMap( surf, temp, smax);
R_SetCacheState( surf );
GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + surf.lightmaptexturenum );
@@ -785,7 +768,7 @@ public abstract class Surf extends Draw {
smax = (surf.extents[0]>>4)+1;
tmax = (surf.extents[1]>>4)+1;
- R_BuildLightMap( surf, temp, smax*4 );
+ R_BuildLightMap( surf, temp, smax);
GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + 0 );
@@ -825,7 +808,7 @@ public abstract class Surf extends Draw {
gl.glMultiTexCoord2fARB(GL_TEXTURE1, v[5], v[6]);
//gglMTexCoord2fSGIS( GL_TEXTURE0, v[3], v[4]);
//gglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
- gl.glVertex3fv(v);
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd ();
}
@@ -843,7 +826,7 @@ public abstract class Surf extends Draw {
gl.glMultiTexCoord2fARB(GL_TEXTURE1, v[5], v[6]);
//gglMTexCoord2fSGIS( GL_TEXTURE0, v[3], v[4]);
//gglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
- gl.glVertex3fv(v);
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd ();
}
@@ -879,7 +862,7 @@ public abstract class Surf extends Draw {
gl.glMultiTexCoord2fARB(GL_TEXTURE1, v[5], v[6]);
// qglMTexCoord2fSGIS( GL_TEXTURE0, (v[3]+scroll), v[4]);
// qglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
- gl.glVertex3fv(v);
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd();
}
@@ -899,7 +882,7 @@ public abstract class Surf extends Draw {
gl.glMultiTexCoord2fARB(GL_TEXTURE1, v[5], v[6]);
//gglMTexCoord2fSGIS( GL_TEXTURE0, v[3], v[4]);
//gglMTexCoord2fSGIS( GL_TEXTURE1, v[5], v[6]);
- gl.glVertex3fv(v);
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd ();
}
@@ -1558,7 +1541,7 @@ public abstract class Surf extends Draw {
void GL_CreateSurfaceLightmap(msurface_t surf)
{
int smax, tmax;
- ByteBuffer base;
+ IntBuffer base;
if ( (surf.flags & (Defines.SURF_DRAWSKY | Defines.SURF_DRAWTURB)) != 0)
return;
@@ -1585,13 +1568,12 @@ public abstract class Surf extends Draw {
surf.lightmaptexturenum = gl_lms.current_lightmap_texture;
- // base = gl_lms.lightmap_buffer;
- base = ByteBuffer.wrap(gl_lms.lightmap_buffer);
- int basep = (surf.light_t * BLOCK_WIDTH + surf.light_s) * LIGHTMAP_BYTES;
+ int basep = (surf.light_t * BLOCK_WIDTH + surf.light_s);// * LIGHTMAP_BYTES;
+ base = gl_lms.lightmap_buffer;
base.position(basep);
R_SetCacheState( surf );
- R_BuildLightMap(surf, base.slice(), BLOCK_WIDTH * LIGHTMAP_BYTES);
+ R_BuildLightMap(surf, base.slice(), BLOCK_WIDTH);
}
lightstyle_t[] lightstyles;
@@ -1713,26 +1695,26 @@ public abstract class Surf extends Draw {
}
- ImageFrame frame;
+ //ImageFrame frame;
- void debugLightmap(byte[] buf, int w, int h, float scale) {
- IntBuffer pix = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
-
- int[] pixel = new int[w * h];
-
- pix.get(pixel);
-
- BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
- image.setRGB(0, 0, w, h, pixel, 0, w);
- AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
- BufferedImage tmp = op.filter(image, null);
-
- if (frame == null) {
- frame = new ImageFrame(null);
- frame.show();
- }
- frame.showImage(tmp);
-
- }
+// void debugLightmap(byte[] buf, int w, int h, float scale) {
+// IntBuffer pix = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
+//
+// int[] pixel = new int[w * h];
+//
+// pix.get(pixel);
+//
+// BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
+// image.setRGB(0, 0, w, h, pixel, 0, w);
+// AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+// BufferedImage tmp = op.filter(image, null);
+//
+// if (frame == null) {
+// frame = new ImageFrame(null);
+// frame.show();
+// }
+// frame.showImage(tmp);
+//
+// }
}
diff --git a/src/jake2/render/jogl/Warp.java b/src/jake2/render/jogl/Warp.java
index 8ccb93a..6dc5145 100644
--- a/src/jake2/render/jogl/Warp.java
+++ b/src/jake2/render/jogl/Warp.java
@@ -2,7 +2,7 @@
* Warp.java
* Copyright (C) 2003
*
- * $Id: Warp.java,v 1.3 2004-07-08 20:24:30 hzi Exp $
+ * $Id: Warp.java,v 1.4 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -313,7 +313,7 @@ public abstract class Warp extends Model {
t *= (1.0f/64);
gl.glTexCoord2f (s, t);
- gl.glVertex3fv( v );
+ gl.glVertex3f(v[0], v[1], v[2]);
}
gl.glEnd ();
}
@@ -612,7 +612,7 @@ public abstract class Warp extends Model {
t = 1.0f - t;
gl.glTexCoord2f (s, t);
- gl.glVertex3fv( v );
+ gl.glVertex3f(v[0], v[1], v[2]);
}
/*
diff --git a/src/jake2/render/model_t.java b/src/jake2/render/model_t.java
index 5807568..5ee824c 100644
--- a/src/jake2/render/model_t.java
+++ b/src/jake2/render/model_t.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 20.11.2003 by RST.
-// $Id: model_t.java,v 1.2 2004-07-08 15:58:48 hzi Exp $
+// $Id: model_t.java,v 1.3 2004-07-09 06:50:47 hzi Exp $
package jake2.render;
@@ -119,7 +119,7 @@ public class model_t implements Cloneable {
//
Math3D.VectorClear(mins);
Math3D.VectorClear(maxs);
- radius = 0;;
+ radius = 0;
//
// solid volume for clipping
diff --git a/src/jake2/render/msurface_t.java b/src/jake2/render/msurface_t.java
index c6247d9..9a64c88 100644
--- a/src/jake2/render/msurface_t.java
+++ b/src/jake2/render/msurface_t.java
@@ -19,11 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 20.11.2003 by RST.
-// $Id: msurface_t.java,v 1.2 2004-07-08 20:24:29 hzi Exp $
+// $Id: msurface_t.java,v 1.3 2004-07-09 06:50:47 hzi Exp $
package jake2.render;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import jake2.game.*;
import jake2.qcommon.texinfo_t;
@@ -67,23 +68,25 @@ public class msurface_t
public void clear() {
visframe = 0;
- //plane = null;
+ plane = null;
+ plane = new cplane_t();
flags = 0;
firstedge = 0;
numedges = 0;
- texturemins[0] = texturemins[1] = 0;
+ texturemins[0] = texturemins[1] = -1;
extents[0] = extents[1] = 0;
light_s = light_t = 0;
dlight_s = dlight_t = 0;
- //polys = null;
+ polys = null;
texturechain = null;
lightmapchain = null;
- //texinfo = null;
+ //texinfo = new mtexinfo_t();
+ texinfo.clear();
dlightframe = 0;
dlightbits = 0;
@@ -98,6 +101,6 @@ public class msurface_t
{
cached_light[i] = 0;
}
- //samples = null;
+ if (samples != null) samples.clear();
}
}
diff --git a/src/jake2/render/mtexinfo_t.java b/src/jake2/render/mtexinfo_t.java
index a78af9f..d545210 100644
--- a/src/jake2/render/mtexinfo_t.java
+++ b/src/jake2/render/mtexinfo_t.java
@@ -19,10 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 20.11.2003 by RST.
-// $Id: mtexinfo_t.java,v 1.1 2004-07-07 19:59:35 hzi Exp $
+// $Id: mtexinfo_t.java,v 1.2 2004-07-09 06:50:47 hzi Exp $
package jake2.render;
+import java.util.Arrays;
+
public class mtexinfo_t {
// [s/t][xyz offset]
public float vecs[][] = {
@@ -33,4 +35,15 @@ public class mtexinfo_t {
public int numframes;
public mtexinfo_t next; // animation chain
public image_t image;
+
+ public void clear() {
+ Arrays.fill(vecs[0], 0);
+ Arrays.fill(vecs[1], 0);
+
+ flags = 0;
+ numframes = 0;
+ next = null;
+ image = null;
+ }
+
}
diff --git a/src/jake2/server/SV_CCMDS.java b/src/jake2/server/SV_CCMDS.java
index 6c71224..76e348d 100644
--- a/src/jake2/server/SV_CCMDS.java
+++ b/src/jake2/server/SV_CCMDS.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 18.01.2004 by RST.
-// $Id: SV_CCMDS.java,v 1.2 2004-07-08 15:58:45 hzi Exp $
+// $Id: SV_CCMDS.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.server;
@@ -228,7 +228,6 @@ public class SV_CCMDS extends SV_ENTS {
f1.close();
}
catch (IOException e1) {
- // TODO Auto-generated catch block
e1.printStackTrace();
}
return;
@@ -627,7 +626,7 @@ public class SV_CCMDS extends SV_ENTS {
// copy off the level to the autosave slot
if (0 == dedicated.value) {
- //TODO: SV_WriteServerFile!
+ //TODO: SV_WriteServerFile.
//SV_WriteServerFile(true);
//SV_CopySaveGame("current", "save0");
@@ -658,7 +657,7 @@ public class SV_CCMDS extends SV_ENTS {
}
sv.state = ss_dead; // don't save current level when changing
- //TODO: RST: disabled for debugging
+ //TODO: savegame
//SV_WipeSavegame("current");
SV_GameMap_f();
}
diff --git a/src/jake2/server/SV_GAME.java b/src/jake2/server/SV_GAME.java
index 8f6eec4..9e3d8d2 100644
--- a/src/jake2/server/SV_GAME.java
+++ b/src/jake2/server/SV_GAME.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 14.01.2004 by RST.
-// $Id: SV_GAME.java,v 1.4 2004-07-08 20:56:54 hzi Exp $
+// $Id: SV_GAME.java,v 1.5 2004-07-09 06:50:49 hzi Exp $
package jake2.server;
@@ -308,11 +308,11 @@ public class SV_GAME extends SV_INIT {
}
public static void PF_StartSound(edict_t entity, int channel, int sound_num, float volume, float attenuation, float timeofs) {
+
if (null == entity)
return;
-
- //TODO: impl SV_StartSound
SV_SEND.SV_StartSound (null, entity, channel, sound_num, volume, attenuation, timeofs);
+
}
//==============================================
diff --git a/src/jake2/server/SV_INIT.java b/src/jake2/server/SV_INIT.java
index b4b4ee6..631e898 100644
--- a/src/jake2/server/SV_INIT.java
+++ b/src/jake2/server/SV_INIT.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 14.01.2004 by RST.
-// $Id: SV_INIT.java,v 1.3 2004-07-08 20:24:30 hzi Exp $
+// $Id: SV_INIT.java,v 1.4 2004-07-09 06:50:49 hzi Exp $
package jake2.server;
@@ -250,16 +250,16 @@ public class SV_INIT extends Globals {
sv.name=server;
sv.configstrings[CS_NAME] = server;
- CM.intwrap checksum_iw = new CM.intwrap(checksum);
+ int iw[] = {checksum};
if (serverstate != ss_game) {
- sv.models[1] = CM.CM_LoadMap("", false, checksum_iw); // no real map
+ sv.models[1] = CM.CM_LoadMap("", false, iw); // no real map
}
else {
- sv.configstrings[CS_MODELS + 1] = "maps/" + server + ".bsp";
- sv.models[1] = CM.CM_LoadMap(sv.configstrings[CS_MODELS + 1], false, checksum_iw);
+ sv.configstrings[CS_MODELS + 1] = "maps/" + server + ".bsp";
+ sv.models[1] = CM.CM_LoadMap(sv.configstrings[CS_MODELS + 1], false, iw);
}
- checksum = checksum_iw.i;
+ checksum = iw[0];
sv.configstrings[CS_MAPCHECKSUM] = "" + checksum;
//
@@ -302,7 +302,7 @@ public class SV_INIT extends Globals {
// set serverinfo variable
Cvar.FullSet("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
- Com.Printf("-------------------------------------\n");
+ //Com.Printf("-------------------------------------\n");
}
/*
diff --git a/src/jake2/server/SV_MAIN.java b/src/jake2/server/SV_MAIN.java
index 464b056..510decc 100644
--- a/src/jake2/server/SV_MAIN.java
+++ b/src/jake2/server/SV_MAIN.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 13.01.2004 by RST.
-// $Id: SV_MAIN.java,v 1.2 2004-07-08 15:58:45 hzi Exp $
+// $Id: SV_MAIN.java,v 1.3 2004-07-09 06:50:49 hzi Exp $
package jake2.server;
@@ -476,7 +476,7 @@ public class SV_MAIN extends SV_GAME {
Cmd.TokenizeString(s.toCharArray(), false);
c = Cmd.Argv(0);
- Com.Printf("Packet " + NET.AdrToString(Netchan.net_from) + " : " + c + "\n");
+ //Com.Printf("Packet " + NET.AdrToString(Netchan.net_from) + " : " + c + "\n");
//Com.Printf(Lib.hexDump(net_message.data, 64, false) + "\n");
if (0 == strcmp(c, "ping"))
diff --git a/src/jake2/server/SV_USER.java b/src/jake2/server/SV_USER.java
index c6e355e..65e5262 100644
--- a/src/jake2/server/SV_USER.java
+++ b/src/jake2/server/SV_USER.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 17.01.2004 by RST.
-// $Id: SV_USER.java,v 1.3 2004-07-08 20:24:30 hzi Exp $
+// $Id: SV_USER.java,v 1.4 2004-07-09 06:50:49 hzi Exp $
package jake2.server;
@@ -29,7 +29,8 @@ import jake2.util.Lib;
import java.io.IOException;
-public class SV_USER extends SV_SEND {
+public class SV_USER extends SV_SEND
+{
static edict_t sv_player;
@@ -47,14 +48,17 @@ public class SV_USER extends SV_SEND {
SV_BeginDemoServer
==================
*/
- public static void SV_BeginDemoserver() {
+ public static void SV_BeginDemoserver()
+ {
String name;
- name = "demos/" + sv.name;
- try {
- sv.demofile = FS.FOpenFile(name);
+ name= "demos/" + sv.name;
+ try
+ {
+ sv.demofile= FS.FOpenFile(name);
}
- catch (IOException e) {
+ catch (IOException e)
+ {
Com.Error(ERR_DROP, "Couldn't open " + name + "\n");
}
if (sv.demofile == null)
@@ -69,20 +73,23 @@ public class SV_USER extends SV_SEND {
This will be sent on the initial connection and upon each server load.
================
*/
- public static void SV_New_f() {
+ public static void SV_New_f()
+ {
String gamedir;
int playernum;
edict_t ent;
Com.DPrintf("New() from " + sv_client.name + "\n");
- if (sv_client.state != cs_connected) {
+ if (sv_client.state != cs_connected)
+ {
Com.Printf("New not valid -- already spawned\n");
return;
}
// demo servers just dump the file message
- if (sv.state == ss_demo) {
+ if (sv.state == ss_demo)
+ {
SV_BeginDemoserver();
return;
}
@@ -91,7 +98,7 @@ public class SV_USER extends SV_SEND {
// serverdata needs to go over for all types of servers
// to make sure the protocol is right, and to set the gamedir
//
- gamedir = Cvar.VariableString("gamedir");
+ gamedir= Cvar.VariableString("gamedir");
// send the serverdata
MSG.WriteByte(sv_client.netchan.message, svc_serverdata);
@@ -101,10 +108,10 @@ public class SV_USER extends SV_SEND {
MSG.WriteString(sv_client.netchan.message, gamedir);
if (sv.state == ss_cinematic || sv.state == ss_pic)
- playernum = -1;
+ playernum= -1;
else
//playernum = sv_client - svs.clients;
- playernum = sv_client.serverindex;
+ playernum= sv_client.serverindex;
MSG.WriteShort(sv_client.netchan.message, playernum);
@@ -114,12 +121,13 @@ public class SV_USER extends SV_SEND {
//
// game server
//
- if (sv.state == ss_game) {
+ if (sv.state == ss_game)
+ {
// set up the entity for the client
- ent = SV_GAME.ge.edicts[playernum + 1];
- ent.s.number = playernum + 1;
- sv_client.edict = ent;
- sv_client.lastcmd = new usercmd_t();
+ ent= SV_GAME.ge.edicts[playernum + 1];
+ ent.s.number= playernum + 1;
+ sv_client.edict= ent;
+ sv_client.lastcmd= new usercmd_t();
// begin fetching configstrings
MSG.WriteByte(sv_client.netchan.message, svc_stufftext);
@@ -133,29 +141,34 @@ public class SV_USER extends SV_SEND {
SV_Configstrings_f
==================
*/
- public static void SV_Configstrings_f() {
+ public static void SV_Configstrings_f()
+ {
int start;
Com.DPrintf("Configstrings() from " + sv_client.name + "\n");
- if (sv_client.state != cs_connected) {
+ if (sv_client.state != cs_connected)
+ {
Com.Printf("configstrings not valid -- already spawned\n");
return;
}
// handle the case of a level changing while a client was connecting
- if (atoi(Cmd.Argv(1)) != svs.spawncount) {
+ if (atoi(Cmd.Argv(1)) != svs.spawncount)
+ {
Com.Printf("SV_Configstrings_f from different level\n");
SV_New_f();
return;
}
- start = atoi(Cmd.Argv(2));
+ start= atoi(Cmd.Argv(2));
// write a packet full of data
- while (sv_client.netchan.message.cursize < MAX_MSGLEN / 2 && start < MAX_CONFIGSTRINGS) {
- if (sv.configstrings[start] != null && sv.configstrings[start].length() != 0) {
+ while (sv_client.netchan.message.cursize < MAX_MSGLEN / 2 && start < MAX_CONFIGSTRINGS)
+ {
+ if (sv.configstrings[start] != null && sv.configstrings[start].length() != 0)
+ {
MSG.WriteByte(sv_client.netchan.message, svc_configstring);
MSG.WriteShort(sv_client.netchan.message, start);
MSG.WriteString(sv_client.netchan.message, sv.configstrings[start]);
@@ -165,11 +178,13 @@ public class SV_USER extends SV_SEND {
// send next command
- if (start == MAX_CONFIGSTRINGS) {
+ if (start == MAX_CONFIGSTRINGS)
+ {
MSG.WriteByte(sv_client.netchan.message, svc_stufftext);
MSG.WriteString(sv_client.netchan.message, "cmd baselines " + svs.spawncount + " 0\n");
}
- else {
+ else
+ {
MSG.WriteByte(sv_client.netchan.message, svc_stufftext);
MSG.WriteString(sv_client.netchan.message, "cmd configstrings " + svs.spawncount + " " + start + "\n");
}
@@ -180,35 +195,40 @@ public class SV_USER extends SV_SEND {
SV_Baselines_f
==================
*/
- public static void SV_Baselines_f() {
+ public static void SV_Baselines_f()
+ {
int start;
entity_state_t nullstate;
entity_state_t base;
Com.DPrintf("Baselines() from " + sv_client.name + "\n");
- if (sv_client.state != cs_connected) {
+ if (sv_client.state != cs_connected)
+ {
Com.Printf("baselines not valid -- already spawned\n");
return;
}
// handle the case of a level changing while a client was connecting
- if (atoi(Cmd.Argv(1)) != svs.spawncount) {
+ if (atoi(Cmd.Argv(1)) != svs.spawncount)
+ {
Com.Printf("SV_Baselines_f from different level\n");
SV_New_f();
return;
}
- start = atoi(Cmd.Argv(2));
+ start= atoi(Cmd.Argv(2));
//memset (&nullstate, 0, sizeof(nullstate));
- nullstate = new entity_state_t(null);
+ nullstate= new entity_state_t(null);
// write a packet full of data
- while (sv_client.netchan.message.cursize < MAX_MSGLEN / 2 && start < MAX_EDICTS) {
- base = sv.baselines[start];
- if (base.modelindex != 0 || base.sound != 0 || base.effects != 0) {
+ while (sv_client.netchan.message.cursize < MAX_MSGLEN / 2 && start < MAX_EDICTS)
+ {
+ base= sv.baselines[start];
+ if (base.modelindex != 0 || base.sound != 0 || base.effects != 0)
+ {
MSG.WriteByte(sv_client.netchan.message, svc_spawnbaseline);
MSG.WriteDeltaEntity(nullstate, base, sv_client.netchan.message, true, true);
}
@@ -217,11 +237,13 @@ public class SV_USER extends SV_SEND {
// send next command
- if (start == MAX_EDICTS) {
+ if (start == MAX_EDICTS)
+ {
MSG.WriteByte(sv_client.netchan.message, svc_stufftext);
MSG.WriteString(sv_client.netchan.message, "precache " + svs.spawncount + "\n");
}
- else {
+ else
+ {
MSG.WriteByte(sv_client.netchan.message, svc_stufftext);
MSG.WriteString(sv_client.netchan.message, "cmd baselines " + svs.spawncount + " " + start + "\n");
}
@@ -232,17 +254,19 @@ public class SV_USER extends SV_SEND {
SV_Begin_f
==================
*/
- public static void SV_Begin_f() {
+ public static void SV_Begin_f()
+ {
Com.DPrintf("Begin() from " + sv_client.name + "\n");
// handle the case of a level changing while a client was connecting
- if (atoi(Cmd.Argv(1)) != svs.spawncount) {
+ if (atoi(Cmd.Argv(1)) != svs.spawncount)
+ {
Com.Printf("SV_Begin_f from different level\n");
SV_New_f();
return;
}
- sv_client.state = cs_spawned;
+ sv_client.state= cs_spawned;
// call the game begin function
SV_GAME.ge.ClientBegin(sv_player);
@@ -257,7 +281,8 @@ public class SV_USER extends SV_SEND {
SV_NextDownload_f
==================
*/
- public static void SV_NextDownload_f() {
+ public static void SV_NextDownload_f()
+ {
int r;
int percent;
int size;
@@ -265,18 +290,18 @@ public class SV_USER extends SV_SEND {
if (sv_client.download == null)
return;
- r = sv_client.downloadsize - sv_client.downloadcount;
+ r= sv_client.downloadsize - sv_client.downloadcount;
if (r > 1024)
- r = 1024;
+ r= 1024;
MSG.WriteByte(sv_client.netchan.message, svc_download);
MSG.WriteShort(sv_client.netchan.message, r);
sv_client.downloadcount += r;
- size = sv_client.downloadsize;
+ size= sv_client.downloadsize;
if (size == 0)
- size = 1;
- percent = sv_client.downloadcount * 100 / size;
+ size= 1;
+ percent= sv_client.downloadcount * 100 / size;
MSG.WriteByte(sv_client.netchan.message, percent);
SZ.Write(sv_client.netchan.message, sv_client.download, sv_client.downloadcount - r, r);
@@ -284,7 +309,7 @@ public class SV_USER extends SV_SEND {
return;
FS.FreeFile(sv_client.download);
- sv_client.download = null;
+ sv_client.download= null;
}
/*
@@ -292,14 +317,15 @@ public class SV_USER extends SV_SEND {
SV_BeginDownload_f
==================
*/
- public static void SV_BeginDownload_f() {
+ public static void SV_BeginDownload_f()
+ {
String name;
- int offset = 0;
+ int offset= 0;
- name = Cmd.Argv(1);
+ name= Cmd.Argv(1);
if (Cmd.Argc() > 2)
- offset = atoi(Cmd.Argv(2)); // downloaded offset
+ offset= atoi(Cmd.Argv(2)); // downloaded offset
// hacked by zoid to allow more conrol over download
// first off, no .. or global allow check
@@ -310,9 +336,11 @@ public class SV_USER extends SV_SEND {
|| name.charAt(0) == '/' // next up, skin check
|| (name.startsWith("players/") && 0 == allow_download_players.value) // now models
|| (name.startsWith("models/") && 0 == allow_download_models.value) // now sounds
- || (name.startsWith("sound/") && 0 == allow_download_sounds.value) // now maps (note special case for maps, must not be in pak)
+ || (name.startsWith("sound/")
+ && 0 == allow_download_sounds.value) // now maps (note special case for maps, must not be in pak)
|| (name.startsWith("maps/") && 0 == allow_download_maps.value) // MUST be in a subdirectory
- || name.indexOf('/') == -1) { // don't allow anything with .. path
+ || name.indexOf('/') == -1)
+ { // don't allow anything with .. path
MSG.WriteByte(sv_client.netchan.message, svc_download);
MSG.WriteShort(sv_client.netchan.message, -1);
MSG.WriteByte(sv_client.netchan.message, 0);
@@ -322,20 +350,22 @@ public class SV_USER extends SV_SEND {
if (sv_client.download != null)
FS.FreeFile(sv_client.download);
- sv_client.download = FS.LoadFile(name);
- sv_client.downloadsize = sv_client.download.length;
- sv_client.downloadcount = offset;
+ sv_client.download= FS.LoadFile(name);
+ sv_client.downloadsize= sv_client.download.length;
+ sv_client.downloadcount= offset;
if (offset > sv_client.downloadsize)
- sv_client.downloadcount = sv_client.downloadsize;
+ sv_client.downloadcount= sv_client.downloadsize;
if (sv_client.download == null // special check for maps, if it came from a pak file, don't allow
// download ZOID
- || (name.startsWith("maps/") && FS.file_from_pak != 0)) {
+ || (name.startsWith("maps/") && FS.file_from_pak != 0))
+ {
Com.DPrintf("Couldn't download " + name + " to " + sv_client.name + "\n");
- if (sv_client.download != null) {
+ if (sv_client.download != null)
+ {
FS.FreeFile(sv_client.download);
- sv_client.download = null;
+ sv_client.download= null;
}
MSG.WriteByte(sv_client.netchan.message, svc_download);
@@ -357,7 +387,8 @@ public class SV_USER extends SV_SEND {
The client is going to disconnect, so remove the connection immediately
=================
*/
- public static void SV_Disconnect_f() {
+ public static void SV_Disconnect_f()
+ {
// SV_EndRedirect ();
SV_DropClient(sv_client);
}
@@ -369,11 +400,13 @@ public class SV_USER extends SV_SEND {
Dumps the serverinfo info string
==================
*/
- public static void SV_ShowServerinfo_f() {
+ public static void SV_ShowServerinfo_f()
+ {
Info.Print(Cvar.Serverinfo());
}
- public static void SV_Nextserver() {
+ public static void SV_Nextserver()
+ {
String v;
//ZOID, ss_pic can be nextserver'd in coop mode
@@ -381,11 +414,12 @@ public class SV_USER extends SV_SEND {
return; // can't nextserver while playing a normal game
svs.spawncount++; // make sure another doesn't sneak in
- v = Cvar.VariableString("nextserver");
+ v= Cvar.VariableString("nextserver");
//if (!v[0])
if (v.length() == 0)
Cbuf.AddText("killserver\n");
- else {
+ else
+ {
Cbuf.AddText(v);
Cbuf.AddText("\n");
}
@@ -400,8 +434,10 @@ public class SV_USER extends SV_SEND {
to the next server,
==================
*/
- public static void SV_Nextserver_f() {
- if (Lib.atoi(Cmd.Argv(1)) != svs.spawncount) {
+ public static void SV_Nextserver_f()
+ {
+ if (Lib.atoi(Cmd.Argv(1)) != svs.spawncount)
+ {
Com.DPrintf("Nextserver() from wrong level, from " + sv_client.name + "\n");
return; // leftover from last server
}
@@ -411,58 +447,80 @@ public class SV_USER extends SV_SEND {
SV_Nextserver();
}
- public static class ucmd_t {
- public ucmd_t(String n, Runnable r) {
- name = n;
- this.r = r;
+ public static class ucmd_t
+ {
+ public ucmd_t(String n, Runnable r)
+ {
+ name= n;
+ this.r= r;
}
String name;
Runnable r;
}
- static ucmd_t u1 = new ucmd_t("new", new Runnable() {
- public void run() {
+ static ucmd_t u1= new ucmd_t("new", new Runnable()
+ {
+ public void run()
+ {
SV_New_f();
}
});
- static ucmd_t ucmds[] = {
+ static ucmd_t ucmds[]= {
// auto issued
- new ucmd_t("new", new Runnable() { public void run() { SV_New_f();
+ new ucmd_t("new", new Runnable()
+ { public void run()
+ { SV_New_f();
}
- }), new ucmd_t("configstrings", new Runnable() {
- public void run() {
+ }), new ucmd_t("configstrings", new Runnable()
+ {
+ public void run()
+ {
SV_Configstrings_f();
}
- }), new ucmd_t("baselines", new Runnable() {
- public void run() {
+ }), new ucmd_t("baselines", new Runnable()
+ {
+ public void run()
+ {
SV_Baselines_f();
}
- }), new ucmd_t("begin", new Runnable() {
- public void run() {
+ }), new ucmd_t("begin", new Runnable()
+ {
+ public void run()
+ {
SV_Begin_f();
}
- }), new ucmd_t("nextserver", new Runnable() {
- public void run() {
+ }), new ucmd_t("nextserver", new Runnable()
+ {
+ public void run()
+ {
SV_Nextserver_f();
}
- }), new ucmd_t("disconnect", new Runnable() {
- public void run() {
+ }), new ucmd_t("disconnect", new Runnable()
+ {
+ public void run()
+ {
SV_Disconnect_f();
}
}),
// issued by hand at client consoles
- new ucmd_t("info", new Runnable() {
- public void run() {
+ new ucmd_t("info", new Runnable()
+ {
+ public void run()
+ {
SV_ShowServerinfo_f();
}
- }), new ucmd_t("download", new Runnable() {
- public void run() {
+ }), new ucmd_t("download", new Runnable()
+ {
+ public void run()
+ {
SV_BeginDownload_f();
}
- }), new ucmd_t("nextdl", new Runnable() {
- public void run() {
+ }), new ucmd_t("nextdl", new Runnable()
+ {
+ public void run()
+ {
SV_NextDownload_f();
}
})
@@ -473,23 +531,26 @@ public class SV_USER extends SV_SEND {
SV_ExecuteUserCommand
==================
*/
- public static void SV_ExecuteUserCommand(String s) {
- ucmd_t u = null;
+ public static void SV_ExecuteUserCommand(String s)
+ {
+ ucmd_t u= null;
Cmd.TokenizeString(s.toCharArray(), true);
- sv_player = sv_client.edict;
+ sv_player= sv_client.edict;
// SV_BeginRedirect (RD_CLIENT);
- int i=0;
- for (; i < ucmds.length; i++) {
- u = ucmds[i];
- if (0 == strcmp(Cmd.Argv(0), u.name)) {
+ int i= 0;
+ for (; i < ucmds.length; i++)
+ {
+ u= ucmds[i];
+ if (0 == strcmp(Cmd.Argv(0), u.name))
+ {
u.r.run();
break;
}
}
-
+
if (i == ucmds.length && sv.state == ss_game)
SV_GAME.ge.ClientCommand(sv_player);
@@ -504,10 +565,12 @@ public class SV_USER extends SV_SEND {
===========================================================================
*/
- public static void SV_ClientThink(client_t cl, usercmd_t cmd) {
+ public static void SV_ClientThink(client_t cl, usercmd_t cmd)
+ {
cl.commandMsec -= cmd.msec & 0xFF;
- if (cl.commandMsec < 0 && sv_enforcetime.value != 0) {
+ if (cl.commandMsec < 0 && sv_enforcetime.value != 0)
+ {
Com.DPrintf("commandMsec underflow from " + cl.name + "\n");
return;
}
@@ -515,7 +578,7 @@ public class SV_USER extends SV_SEND {
SV_GAME.ge.ClientThink(cl.edict, cmd);
}
- public static final int MAX_STRINGCMDS = 8;
+ public static final int MAX_STRINGCMDS= 8;
/*
===================
SV_ExecuteClientMessage
@@ -523,12 +586,13 @@ public class SV_USER extends SV_SEND {
The current net_message is parsed for the given client
===================
*/
- public static void SV_ExecuteClientMessage(client_t cl) {
+ public static void SV_ExecuteClientMessage(client_t cl)
+ {
int c;
String s;
- usercmd_t nullcmd = new usercmd_t();
- usercmd_t oldest = new usercmd_t(), oldcmd = new usercmd_t(), newcmd = new usercmd_t();
+ usercmd_t nullcmd= new usercmd_t();
+ usercmd_t oldest= new usercmd_t(), oldcmd= new usercmd_t(), newcmd= new usercmd_t();
int net_drop;
int stringCmdCount;
int checksum, calculatedChecksum;
@@ -536,26 +600,29 @@ public class SV_USER extends SV_SEND {
boolean move_issued;
int lastframe;
- sv_client = cl;
- sv_player = sv_client.edict;
+ sv_client= cl;
+ sv_player= sv_client.edict;
// only allow one move command
- move_issued = false;
- stringCmdCount = 0;
+ move_issued= false;
+ stringCmdCount= 0;
- while (true) {
- if (net_message.readcount > net_message.cursize) {
+ while (true)
+ {
+ if (net_message.readcount > net_message.cursize)
+ {
Com.Printf("SV_ReadClientMessage: bad read:\n");
Com.Printf(Lib.hexDump(net_message.data, 32, false));
SV_DropClient(cl);
return;
}
- c = MSG.ReadByte(net_message);
+ c= MSG.ReadByte(net_message);
if (c == -1)
break;
- switch (c) {
+ switch (c)
+ {
default :
Com.Printf("SV_ReadClientMessage: unknown command char\n");
SV_DropClient(cl);
@@ -565,7 +632,7 @@ public class SV_USER extends SV_SEND {
break;
case clc_userinfo :
- cl.userinfo = MSG.ReadString(net_message);
+ cl.userinfo= MSG.ReadString(net_message);
SV_MAIN.SV_UserinfoChanged(cl);
break;
@@ -573,41 +640,43 @@ public class SV_USER extends SV_SEND {
if (move_issued)
return; // someone is trying to cheat...
- move_issued = true;
- checksumIndex = net_message.readcount;
- checksum = MSG.ReadByte(net_message);
- lastframe = MSG.ReadLong(net_message);
-
- if (lastframe != cl.lastframe) {
- cl.lastframe = lastframe;
- if (cl.lastframe > 0) {
- cl.frame_latency[cl.lastframe & (LATENCY_COUNTS - 1)] =
+ move_issued= true;
+ checksumIndex= net_message.readcount;
+ checksum= MSG.ReadByte(net_message);
+ lastframe= MSG.ReadLong(net_message);
+
+ if (lastframe != cl.lastframe)
+ {
+ cl.lastframe= lastframe;
+ if (cl.lastframe > 0)
+ {
+ cl.frame_latency[cl.lastframe & (LATENCY_COUNTS - 1)]=
svs.realtime - cl.frames[cl.lastframe & UPDATE_MASK].senttime;
}
}
//memset (nullcmd, 0, sizeof(nullcmd));
- nullcmd = new usercmd_t();
+ nullcmd= new usercmd_t();
MSG.ReadDeltaUsercmd(net_message, nullcmd, oldest);
MSG.ReadDeltaUsercmd(net_message, oldest, oldcmd);
MSG.ReadDeltaUsercmd(net_message, oldcmd, newcmd);
- if (cl.state != cs_spawned) {
- cl.lastframe = -1;
+ if (cl.state != cs_spawned)
+ {
+ cl.lastframe= -1;
break;
}
// if the checksum fails, ignore the rest of the packet
- calculatedChecksum = 0;
- /*
- = Com.BlockSequenceCRCByte(
- net_message.data + checksumIndex + 1,
+ calculatedChecksum=
+ Com.BlockSequenceCRCByte(
+ net_message.data, checksumIndex + 1,
net_message.readcount - checksumIndex - 1,
cl.netchan.incoming_sequence);
- */
- if (calculatedChecksum != checksum) {
+ if ((calculatedChecksum &0xff) != checksum)
+ {
Com.DPrintf(
"Failed command checksum for "
+ cl.name
@@ -621,14 +690,17 @@ public class SV_USER extends SV_SEND {
return;
}
- if (0 == sv_paused.value) {
- net_drop = cl.netchan.dropped;
- if (net_drop < 20) {
+ if (0 == sv_paused.value)
+ {
+ net_drop= cl.netchan.dropped;
+ if (net_drop < 20)
+ {
//if (net_drop > 2)
// Com.Printf ("drop %i\n", net_drop);
- while (net_drop > 2) {
+ while (net_drop > 2)
+ {
SV_ClientThink(cl, cl.lastcmd);
net_drop--;
@@ -648,7 +720,7 @@ public class SV_USER extends SV_SEND {
break;
case clc_stringcmd :
- s = MSG.ReadString(net_message);
+ s= MSG.ReadString(net_message);
// malicious users may try using too many string commands
if (++stringCmdCount < MAX_STRINGCMDS)
diff --git a/src/jake2/server/SV_WORLD.java b/src/jake2/server/SV_WORLD.java
index 4e78084..2eb2ca6 100644
--- a/src/jake2/server/SV_WORLD.java
+++ b/src/jake2/server/SV_WORLD.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 07.01.2000 by RST.
-// $Id: SV_WORLD.java,v 1.3 2004-07-08 20:24:30 hzi Exp $
+// $Id: SV_WORLD.java,v 1.4 2004-07-09 06:50:49 hzi Exp $
package jake2.server;
@@ -48,14 +48,13 @@ public class SV_WORLD extends SV_CCMDS
//===============================================================================
//
-
public static void initNodes()
{
- for (int n = 0; n < AREA_NODES; n++)
- sv_areanodes[n] = new areanode_t();
+ for (int n= 0; n < AREA_NODES; n++)
+ sv_areanodes[n]= new areanode_t();
}
- public static areanode_t sv_areanodes[] = new areanode_t[AREA_NODES];
+ public static areanode_t sv_areanodes[]= new areanode_t[AREA_NODES];
static {
initNodes();
@@ -70,21 +69,21 @@ public class SV_WORLD extends SV_CCMDS
// ClearLink is used for new headnodes
public static void ClearLink(link_t l)
{
- l.prev = l.next = l;
+ l.prev= l.next= l;
}
public static void RemoveLink(link_t l)
{
- l.next.prev = l.prev;
- l.prev.next = l.next;
+ l.next.prev= l.prev;
+ l.prev.next= l.next;
}
public static void InsertLinkBefore(link_t l, link_t before)
{
- l.next = before;
- l.prev = before.prev;
- l.prev.next = l;
- l.next.prev = l;
+ l.next= before;
+ l.prev= before.prev;
+ l.prev.next= l;
+ l.next.prev= l;
}
/*
@@ -97,10 +96,10 @@ public class SV_WORLD extends SV_CCMDS
public static areanode_t SV_CreateAreaNode(int depth, float[] mins, float[] maxs)
{
areanode_t anode;
- float[] size = { 0, 0, 0 };
- float[] mins1 = { 0, 0, 0 }, maxs1 = { 0, 0, 0 }, mins2 = { 0, 0, 0 }, maxs2 = { 0, 0, 0 };
+ float[] size= { 0, 0, 0 };
+ float[] mins1= { 0, 0, 0 }, maxs1= { 0, 0, 0 }, mins2= { 0, 0, 0 }, maxs2= { 0, 0, 0 };
- anode = sv_areanodes[sv_numareanodes];
+ anode= sv_areanodes[sv_numareanodes];
// just for debugging (rst)
VectorCopy(mins, anode.mins_rst);
@@ -113,27 +112,27 @@ public class SV_WORLD extends SV_CCMDS
if (depth == AREA_DEPTH)
{
- anode.axis = -1;
- anode.children[0] = anode.children[1] = null;
+ anode.axis= -1;
+ anode.children[0]= anode.children[1]= null;
return anode;
}
VectorSubtract(maxs, mins, size);
if (size[0] > size[1])
- anode.axis = 0;
+ anode.axis= 0;
else
- anode.axis = 1;
+ anode.axis= 1;
- anode.dist = 0.5f * (maxs[anode.axis] + mins[anode.axis]);
+ anode.dist= 0.5f * (maxs[anode.axis] + mins[anode.axis]);
VectorCopy(mins, mins1);
VectorCopy(mins, mins2);
VectorCopy(maxs, maxs1);
VectorCopy(maxs, maxs2);
- maxs1[anode.axis] = mins2[anode.axis] = anode.dist;
+ maxs1[anode.axis]= mins2[anode.axis]= anode.dist;
- anode.children[0] = SV_CreateAreaNode(depth + 1, mins2, maxs2);
- anode.children[1] = SV_CreateAreaNode(depth + 1, mins1, maxs1);
+ anode.children[0]= SV_CreateAreaNode(depth + 1, mins2, maxs2);
+ anode.children[1]= SV_CreateAreaNode(depth + 1, mins1, maxs1);
return anode;
}
@@ -147,7 +146,7 @@ public class SV_WORLD extends SV_CCMDS
public static void SV_ClearWorld()
{
initNodes();
- sv_numareanodes = 0;
+ sv_numareanodes= 0;
SV_CreateAreaNode(0, sv.models[1].mins, sv.models[1].maxs);
/*
@@ -178,7 +177,7 @@ public class SV_WORLD extends SV_CCMDS
if (null == ent.area.prev)
return; // not linked in anywhere
RemoveLink(ent.area);
- ent.area.prev = ent.area.next = null;
+ ent.area.prev= ent.area.next= null;
}
/*
@@ -186,18 +185,18 @@ public class SV_WORLD extends SV_CCMDS
SV_LinkEdict
===============
*/
- public static final int MAX_TOTAL_ENT_LEAFS = 128;
-
+ public static final int MAX_TOTAL_ENT_LEAFS= 128;
+ private static int leafs[]= new int[MAX_TOTAL_ENT_LEAFS];
+ private static int clusters[]= new int[MAX_TOTAL_ENT_LEAFS];
+
public static void SV_LinkEdict(edict_t ent)
{
areanode_t node;
- // TODO: make static instead of new
- int leafs[] = new int[MAX_TOTAL_ENT_LEAFS];
- int clusters[] = new int[MAX_TOTAL_ENT_LEAFS];
+
int num_leafs;
int j, k;
int area;
- int topnode = 0;
+ int topnode= 0;
if (ent.area.prev != null)
SV_UnlinkEdict(ent); // unlink from old position
@@ -214,54 +213,54 @@ public class SV_WORLD extends SV_CCMDS
// encode the size into the entity_state for client prediction
if (ent.solid == SOLID_BBOX && 0 == (ent.svflags & SVF_DEADMONSTER))
{ // assume that x/y are equal and symetric
- int i = (int) (ent.maxs[0] / 8);
+ int i= (int) (ent.maxs[0] / 8);
if (i < 1)
- i = 1;
+ i= 1;
if (i > 31)
- i = 31;
+ i= 31;
// z is not symetric
- j = (int) ((-ent.mins[2]) / 8);
+ j= (int) ((-ent.mins[2]) / 8);
if (j < 1)
- j = 1;
+ j= 1;
if (j > 31)
- j = 31;
+ j= 31;
// and z maxs can be negative...
- k = (int) ((ent.maxs[2] + 32) / 8);
+ k= (int) ((ent.maxs[2] + 32) / 8);
if (k < 1)
- k = 1;
+ k= 1;
if (k > 63)
- k = 63;
+ k= 63;
- ent.s.solid = (k << 10) | (j << 5) | i;
+ ent.s.solid= (k << 10) | (j << 5) | i;
}
else if (ent.solid == SOLID_BSP)
{
- ent.s.solid = 31; // a solid_bbox will never create this value
+ ent.s.solid= 31; // a solid_bbox will never create this value
}
else
- ent.s.solid = 0;
+ ent.s.solid= 0;
// set the abs box
if (ent.solid == SOLID_BSP && (ent.s.angles[0] != 0 || ent.s.angles[1] != 0 || ent.s.angles[2] != 0))
{ // expand for rotation
float max, v;
- max = 0;
- for (int i = 0; i < 3; i++)
+ max= 0;
+ for (int i= 0; i < 3; i++)
{
- v = Math.abs(ent.mins[i]);
+ v= Math.abs(ent.mins[i]);
if (v > max)
- max = v;
- v = Math.abs(ent.maxs[i]);
+ max= v;
+ v= Math.abs(ent.maxs[i]);
if (v > max)
- max = v;
+ max= v;
}
- for (int i = 0; i < 3; i++)
+ for (int i= 0; i < 3; i++)
{
- ent.absmin[i] = ent.s.origin[i] - max;
- ent.absmax[i] = ent.s.origin[i] + max;
+ ent.absmin[i]= ent.s.origin[i] - max;
+ ent.absmax[i]= ent.s.origin[i] + max;
}
}
else
@@ -281,62 +280,65 @@ public class SV_WORLD extends SV_CCMDS
ent.absmax[2]++;
// link to PVS leafs
- ent.num_clusters = 0;
- ent.areanum = 0;
- ent.areanum2 = 0;
+ ent.num_clusters= 0;
+ ent.areanum= 0;
+ ent.areanum2= 0;
//get all leafs, including solids
- CM.intwrap iw = new CM.intwrap(topnode);
+ int iw[] = {topnode};
- num_leafs = CM.CM_BoxLeafnums(ent.absmin, ent.absmax, leafs, MAX_TOTAL_ENT_LEAFS, iw);
+ num_leafs= CM.CM_BoxLeafnums(ent.absmin, ent.absmax, leafs, MAX_TOTAL_ENT_LEAFS, iw);
- topnode = iw.i;
+ topnode= iw[0];
// set areas
- for (int i = 0; i < num_leafs; i++)
+ for (int i= 0; i < num_leafs; i++)
{
- clusters[i] = CM.CM_LeafCluster(leafs[i]);
- area = CM.CM_LeafArea(leafs[i]);
+ clusters[i]= CM.CM_LeafCluster(leafs[i]);
+ area= CM.CM_LeafArea(leafs[i]);
if (area != 0)
- { // doors may legally straggle two areas,
+ {
+ // doors may legally straggle two areas,
// but nothing should evern need more than that
if (ent.areanum != 0 && ent.areanum != area)
{
if (ent.areanum2 != 0 && ent.areanum2 != area && sv.state == ss_loading)
Com.DPrintf("Object touching 3 areas at " + ent.absmin[0] + " " + ent.absmin[1] + " " + ent.absmin[2] + "\n");
- ent.areanum2 = area;
+ ent.areanum2= area;
}
else
- ent.areanum = area;
+ ent.areanum= area;
}
}
if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
- { // assume we missed some leafs, and mark by headnode
- ent.num_clusters = -1;
- ent.headnode = topnode;
+ {
+ // assume we missed some leafs, and mark by headnode
+ ent.num_clusters= -1;
+ ent.headnode= topnode;
}
else
{
- ent.num_clusters = 0;
- for (int i = 0; i < num_leafs; i++)
+ ent.num_clusters= 0;
+ for (int i= 0; i < num_leafs; i++)
{
if (clusters[i] == -1)
continue; // not a visible leaf
- for (j = 0; j < i; j++)
+ for (j= 0; j < i; j++)
if (clusters[j] == clusters[i])
break;
if (j == i)
{
if (ent.num_clusters == MAX_ENT_CLUSTERS)
- { // assume we missed some leafs, and mark by headnode
- ent.num_clusters = -1;
- ent.headnode = topnode;
+ {
+ // assume we missed some leafs, and mark by headnode
+ ent.num_clusters= -1;
+ ent.headnode= topnode;
break;
}
- ent.clusternums[ent.num_clusters++] = clusters[i];
+ ent.clusternums[ent.num_clusters++]= clusters[i];
}
}
}
@@ -352,16 +354,16 @@ public class SV_WORLD extends SV_CCMDS
return;
// find the first node that the ent's box crosses
- node = sv_areanodes[0];
+ node= sv_areanodes[0];
while (true)
{
if (node.axis == -1)
break;
if (ent.absmin[node.axis] > node.dist)
- node = node.children[0];
+ node= node.children[0];
else if (ent.absmax[node.axis] < node.dist)
- node = node.children[1];
+ node= node.children[1];
else
break; // crosses the node
}
@@ -386,19 +388,18 @@ public class SV_WORLD extends SV_CCMDS
edict_t check;
int count;
- count = 0;
+ count= 0;
// touch linked edicts
if (area_type == AREA_SOLID)
- start = node.solid_edicts;
+ start= node.solid_edicts;
else
- start = node.trigger_edicts;
+ start= node.trigger_edicts;
- for (l = start.next; l != start; l = next)
+ for (l= start.next; l != start; l= next)
{
- next = l.next;
- check = //EDICT_FROM_AREA(l);
- (edict_t) l.o;
+ next= l.next;
+ check= (edict_t) l.o;
if (check.solid == SOLID_NOT)
continue; // deactivated
@@ -416,7 +417,7 @@ public class SV_WORLD extends SV_CCMDS
return;
}
- area_list[area_count] = check;
+ area_list[area_count]= check;
area_count++;
}
@@ -438,57 +439,53 @@ public class SV_WORLD extends SV_CCMDS
*/
public static int SV_AreaEdicts(float[] mins, float[] maxs, edict_t list[], int maxcount, int areatype)
{
- area_mins = mins;
- area_maxs = maxs;
- area_list = list;
- area_count = 0;
- area_maxcount = maxcount;
- area_type = areatype;
+ area_mins= mins;
+ area_maxs= maxs;
+ area_list= list;
+ area_count= 0;
+ area_maxcount= maxcount;
+ area_type= areatype;
SV_AreaEdicts_r(sv_areanodes[0]);
- /*
- Com.Printf("found edicts in area:" + area_count + "\n");
- for (int n = 0; n < area_count; n++) {
- Com.Printf("%4i : %25s", new Vargs().add(n).add(list[n].classname));
- }
- */
return area_count;
}
//===========================================================================
+ private static edict_t touch[]= new edict_t[MAX_EDICTS];
/*
=============
SV_PointContents
=============
*/
+
public static int SV_PointContents(float[] p)
{
- // TODO: make static instead new
- edict_t touch[] = new edict_t[MAX_EDICTS], hit;
+ edict_t hit;
+
int i, num;
int contents, c2;
int headnode;
float angles[];
// get base contents from world
- contents = CM.PointContents(p, sv.models[1].headnode);
+ contents= CM.PointContents(p, sv.models[1].headnode);
// or in contents from all the other entities
- num = SV_AreaEdicts(p, p, touch, MAX_EDICTS, AREA_SOLID);
+ num= SV_AreaEdicts(p, p, touch, MAX_EDICTS, AREA_SOLID);
- for (i = 0; i < num; i++)
+ for (i= 0; i < num; i++)
{
- hit = touch[i];
+ hit= touch[i];
// might intersect, so do an exact clip
- headnode = SV_HullForEntity(hit);
- angles = hit.s.angles;
+ headnode= SV_HullForEntity(hit);
+ angles= hit.s.angles;
if (hit.solid != SOLID_BSP)
- angles = vec3_origin; // boxes don't rotate
+ angles= vec3_origin; // boxes don't rotate
- c2 = CM.TransformedPointContents(p, headnode, hit.s.origin, hit.s.angles);
+ c2= CM.TransformedPointContents(p, headnode, hit.s.origin, hit.s.angles);
contents |= c2;
}
@@ -514,7 +511,7 @@ public class SV_WORLD extends SV_CCMDS
// decide which clipping hull to use, based on the size
if (ent.solid == SOLID_BSP)
{ // explicit hulls in the BSP model
- model = sv.models[ent.s.modelindex];
+ model= sv.models[ent.s.modelindex];
if (null == model)
Com.Error(ERR_FATAL, "MOVETYPE_PUSH with a non bsp model");
@@ -535,23 +532,23 @@ public class SV_WORLD extends SV_CCMDS
====================
*/
+ private static edict_t touchlist[]= new edict_t[MAX_EDICTS];
public static void SV_ClipMoveToEntities(moveclip_t clip)
{
int i, num;
- // TODO: make static instead of new
- edict_t touchlist[] = new edict_t[MAX_EDICTS];
+
edict_t touch;
trace_t trace;
int headnode;
float angles[];
- num = SV_AreaEdicts(clip.boxmins, clip.boxmaxs, touchlist, MAX_EDICTS, AREA_SOLID);
+ num= SV_AreaEdicts(clip.boxmins, clip.boxmaxs, touchlist, MAX_EDICTS, AREA_SOLID);
// be careful, it is possible to have an entity in this
// list removed before we get to it (killtriggered)
- for (i = 0; i < num; i++)
+ for (i= 0; i < num; i++)
{
- touch = touchlist[i];
+ touch= touchlist[i];
if (touch.solid == SOLID_NOT)
continue;
if (touch == clip.passedict)
@@ -570,13 +567,13 @@ public class SV_WORLD extends SV_CCMDS
continue;
// might intersect, so do an exact clip
- headnode = SV_HullForEntity(touch);
- angles = touch.s.angles;
+ headnode= SV_HullForEntity(touch);
+ angles= touch.s.angles;
if (touch.solid != SOLID_BSP)
- angles = vec3_origin; // boxes don't rotate
+ angles= vec3_origin; // boxes don't rotate
if ((touch.svflags & SVF_MONSTER) != 0)
- trace =
+ trace=
CM.TransformedBoxTrace(
clip.start,
clip.end,
@@ -587,7 +584,7 @@ public class SV_WORLD extends SV_CCMDS
touch.s.origin,
angles);
else
- trace =
+ trace=
CM.TransformedBoxTrace(
clip.start,
clip.end,
@@ -600,17 +597,17 @@ public class SV_WORLD extends SV_CCMDS
if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction)
{
- trace.ent = touch;
+ trace.ent= touch;
if (clip.trace.startsolid)
{
- clip.trace = trace;
- clip.trace.startsolid = true;
+ clip.trace= trace;
+ clip.trace.startsolid= true;
}
else
clip.trace.set(trace);
}
else if (trace.startsolid)
- clip.trace.startsolid = true;
+ clip.trace.startsolid= true;
}
}
@@ -623,17 +620,17 @@ public class SV_WORLD extends SV_CCMDS
{
int i;
- for (i = 0; i < 3; i++)
+ for (i= 0; i < 3; i++)
{
if (end[i] > start[i])
{
- boxmins[i] = start[i] + mins[i] - 1;
- boxmaxs[i] = end[i] + maxs[i] + 1;
+ boxmins[i]= start[i] + mins[i] - 1;
+ boxmaxs[i]= end[i] + maxs[i] + 1;
}
else
{
- boxmins[i] = end[i] + mins[i] - 1;
- boxmaxs[i] = start[i] + maxs[i] + 1;
+ boxmins[i]= end[i] + mins[i] - 1;
+ boxmaxs[i]= start[i] + maxs[i] + 1;
}
}
@@ -651,27 +648,27 @@ public class SV_WORLD extends SV_CCMDS
*/
public static trace_t SV_Trace(float[] start, float[] mins, float[] maxs, float[] end, edict_t passedict, int contentmask)
{
- moveclip_t clip = new moveclip_t();
+ moveclip_t clip= new moveclip_t();
if (mins == null)
- mins = vec3_origin;
+ mins= vec3_origin;
if (maxs == null)
- maxs = vec3_origin;
+ maxs= vec3_origin;
//memset ( clip, 0, sizeof ( moveclip_t ) );
// clip to world
- clip.trace = CM.BoxTrace(start, end, mins, maxs, 0, contentmask);
- clip.trace.ent = ge.edicts[0];
+ clip.trace= CM.BoxTrace(start, end, mins, maxs, 0, contentmask);
+ clip.trace.ent= ge.edicts[0];
if (clip.trace.fraction == 0)
return clip.trace; // blocked by the world
- clip.contentmask = contentmask;
- clip.start = start;
- clip.end = end;
- clip.mins = mins;
- clip.maxs = maxs;
- clip.passedict = passedict;
+ clip.contentmask= contentmask;
+ clip.start= start;
+ clip.end= end;
+ clip.mins= mins;
+ clip.maxs= maxs;
+ clip.passedict= passedict;
VectorCopy(mins, clip.mins2);
VectorCopy(maxs, clip.maxs2);
diff --git a/src/jake2/sound/S.java b/src/jake2/sound/S.java
index c696501..55588b5 100644
--- a/src/jake2/sound/S.java
+++ b/src/jake2/sound/S.java
@@ -2,7 +2,7 @@
* S.java
* Copyright (C) 2003
*
- * $Id: S.java,v 1.1 2004-07-08 20:56:49 hzi Exp $
+ * $Id: S.java,v 1.2 2004-07-09 06:50:48 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -184,4 +184,8 @@ public class S {
public static void StopAllSounds() {
impl.StopAllSounds();
}
+
+ public static String getDriverName() {
+ return impl.getName();
+ }
}
diff --git a/src/jake2/sound/WaveLoader.java b/src/jake2/sound/WaveLoader.java
new file mode 100644
index 0000000..020ab52
--- /dev/null
+++ b/src/jake2/sound/WaveLoader.java
@@ -0,0 +1,302 @@
+/*
+ * SND_MEM.java
+ * Copyright (C) 2004
+ *
+ * $Id: WaveLoader.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.sound;
+
+import jake2.Defines;
+import jake2.qcommon.Com;
+import jake2.qcommon.FS;
+import jake2.sys.Sys;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import javax.sound.sampled.*;
+
+/**
+ * SND_MEM
+ */
+public class WaveLoader {
+
+ private static final AudioFormat sampleFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 22050, 16, 1, 2, 22050, false);
+
+ /*
+ ==============
+ S_LoadSound
+ ==============
+ */
+ public static sfxcache_t LoadSound(sfx_t s) {
+ String namebuffer;
+ byte[] data;
+ wavinfo_t info;
+ int len;
+ float stepscale;
+ sfxcache_t sc = null;
+ int size;
+ String name;
+
+ if (s.name.charAt(0) == '*')
+ return null;
+
+ // see if still in memory
+ sc = s.cache;
+ if (sc != null)
+ return sc;
+
+ // load it in
+ if (s.truename != null)
+ name = s.truename;
+ else
+ name = s.name;
+
+ if (name.charAt(0) == '#')
+ namebuffer = name.substring(1);
+
+ else
+ namebuffer = "sound/" + name;
+
+ data = FS.LoadFile(namebuffer);
+
+ if (data == null) {
+ Com.DPrintf("Couldn't load " + namebuffer + "\n");
+ return null;
+ }
+ size = data.length;
+
+ info = GetWavinfo(s.name, data, size);
+
+ AudioInputStream in = null;
+ AudioInputStream out = null;
+ try {
+ in = AudioSystem.getAudioInputStream(new ByteArrayInputStream(data));
+ if (in.getFormat().getSampleSizeInBits() == 8) {
+ in = convertTo16bit(in);
+ }
+ out = AudioSystem.getAudioInputStream(sampleFormat, in);
+ int l = (int)out.getFrameLength();
+ sc = s.cache = new sfxcache_t(l*2);
+ sc.length = l;
+ int c = out.read(sc.data, 0, l * 2);
+ out.close();
+ in.close();
+ } catch (Exception e) {
+ Com.Printf("Couldn't load " + namebuffer + "\n");
+ return null;
+ }
+
+ sc.loopstart = info.loopstart * ((int)sampleFormat.getSampleRate() / info.rate);
+ sc.speed = (int)sampleFormat.getSampleRate();
+ sc.width = sampleFormat.getSampleSizeInBits() / 8;
+ sc.stereo = 0;
+
+ data = null;
+
+ return sc;
+ }
+
+ static AudioInputStream convertTo16bit(AudioInputStream in) throws IOException {
+ AudioFormat format = in.getFormat();
+ int length = (int)in.getFrameLength();
+ byte[] samples = new byte[2*length];
+
+ for (int i = 0; i < length; i++) {
+ in.read(samples, 2*i+1, 1);
+ samples[2*i+1] -= 128;
+ }
+ in.close();
+
+ AudioFormat newformat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(), 2, format.getFrameRate(), false);
+ return new AudioInputStream(new ByteArrayInputStream(samples), newformat, length);
+ }
+
+ /*
+ ===============================================================================
+
+ WAV loading
+
+ ===============================================================================
+ */
+
+ static byte[] data_b;
+ static int data_p;
+ static int iff_end;
+ static int last_chunk;
+ static int iff_data;
+ static int iff_chunk_len;
+
+
+ static short GetLittleShort() {
+ int val = 0;
+ val = data_b[data_p] & 0xFF;
+ data_p++;
+ val |= ((data_b[data_p] & 0xFF) << 8);
+ data_p++;
+ return (short)val;
+ }
+
+ static int GetLittleLong() {
+ int val = 0;
+ val = data_b[data_p] & 0xFF;
+ data_p++;
+ val |= ((data_b[data_p] & 0xFF) << 8);
+ data_p++;
+ val |= ((data_b[data_p] & 0xFF) << 16);
+ data_p++;
+ val |= ((data_b[data_p] & 0xFF) << 24);
+ data_p++;
+ return val;
+ }
+
+ static void FindNextChunk(String name) {
+ while (true) {
+ data_p = last_chunk;
+
+ if (data_p >= iff_end) { // didn't find the chunk
+ data_p = 0;
+ return;
+ }
+
+ data_p += 4;
+
+ iff_chunk_len = GetLittleLong();
+
+ if (iff_chunk_len < 0) {
+ data_p = 0;
+ return;
+ }
+ if (iff_chunk_len > 1024*1024)
+ Sys.Error("FindNextChunk: length is past the 1 meg sanity limit");
+
+ data_p -= 8;
+ last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1);
+ String s = new String(data_b, data_p, 4);
+ if (s.equals(name))
+ return;
+ }
+ }
+
+ static void FindChunk(String name) {
+ last_chunk = iff_data;
+ FindNextChunk(name);
+ }
+
+ /*
+ ============
+ GetWavinfo
+ ============
+ */
+ static wavinfo_t GetWavinfo(String name, byte[] wav, int wavlength) {
+ wavinfo_t info = new wavinfo_t();
+ int i;
+ int format;
+ int samples;
+
+ if (wav == null)
+ return info;
+
+ iff_data = 0;
+ iff_end = wavlength;
+ data_b = wav;
+
+ // find "RIFF" chunk
+ FindChunk("RIFF");
+ String s = new String(data_b, data_p + 8, 4);
+ if (!s.equals("WAVE")) {
+ Com.Printf("Missing RIFF/WAVE chunks\n");
+ return info;
+ }
+
+ // get "fmt " chunk
+ iff_data = data_p + 12;
+ // DumpChunks ();
+
+ FindChunk("fmt ");
+ if (data_p == 0) {
+ Com.Printf("Missing fmt chunk\n");
+ return info;
+ }
+ data_p += 8;
+ format = GetLittleShort();
+ if (format != 1) {
+ Com.Printf("Microsoft PCM format only\n");
+ return info;
+ }
+
+ info.channels = GetLittleShort();
+ info.rate = GetLittleLong();
+ data_p += 4 + 2;
+ info.width = GetLittleShort() / 8;
+
+ // get cue chunk
+ FindChunk("cue ");
+ if (data_p != 0) {
+ data_p += 32;
+ info.loopstart = GetLittleLong();
+ // Com_Printf("loopstart=%d\n", sfx->loopstart);
+
+ // if the next chunk is a LIST chunk, look for a cue length marker
+ FindNextChunk("LIST");
+ if (data_p != 0) {
+ s = new String(data_b, data_p + 28, 4);
+ if (s.equals("MARK")) { // this is not a proper parse, but it works with cooledit...
+ data_p += 24;
+ i = GetLittleLong(); // samples in loop
+ info.samples = info.loopstart + i;
+ // Com_Printf("looped length: %i\n", i);
+ }
+ }
+ } else
+ info.loopstart = -1;
+
+ // find data chunk
+ FindChunk("data");
+ if (data_p == 0) {
+ Com.Printf("Missing data chunk\n");
+ return info;
+ }
+
+ data_p += 4;
+ samples = GetLittleLong() / info.width;
+
+ if (info.samples != 0) {
+ if (samples < info.samples)
+ Com.Error(Defines.ERR_DROP, "Sound " + name + " has a bad loop length");
+ } else
+ info.samples = samples;
+
+ info.dataofs = data_p;
+
+ return info;
+ }
+
+ static class wavinfo_t {
+ int rate;
+ int width;
+ int channels;
+ int loopstart;
+ int samples;
+ int dataofs; // chunk starts this many bytes from file start
+ }
+}
diff --git a/src/jake2/sound/joal/Channel.java b/src/jake2/sound/joal/Channel.java
new file mode 100644
index 0000000..ced496f
--- /dev/null
+++ b/src/jake2/sound/joal/Channel.java
@@ -0,0 +1,84 @@
+/*
+ * Created on Jun 19, 2004
+ *
+ * Copyright (C) 2003
+ *
+ * $Id: Channel.java,v 1.1 2004-07-09 06:50:52 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.sound.joal;
+
+/**
+ * Channel
+ *
+ * @author cwei
+ */
+public class Channel {
+
+ final static int LISTENER = 0;
+ final static int FIXED = 1;
+ final static int DYNAMIC = 2;
+
+ int entnum;
+ int entchannel;
+ int bufferId;
+ float rolloff;
+ boolean autosound = false;
+ int sourceId;
+ boolean active = false;
+ boolean modified = false;
+ boolean bufferChanged = false;
+
+ // sound attributes
+ int type;
+ int entity;
+ float[] origin = {0, 0, 0};
+
+ Channel(int sourceId) {
+ this.sourceId = sourceId;
+ clear();
+ }
+
+ void addListener() {
+ type = LISTENER;
+ }
+
+ void addFixed(float[] origin) {
+ type = FIXED;
+ this.origin = origin;
+ }
+
+ void addDynamic(int entity) {
+ type = DYNAMIC;
+ this.entity = entity;
+ }
+
+ void clear() {
+ entnum = -1;
+ entchannel = -1;
+ bufferId = -1;
+ bufferChanged = false;
+ rolloff = 0;
+ autosound = false;
+ active = false;
+ modified = false;
+ }
+}
diff --git a/src/jake2/sound/joal/JOALSoundImpl.java b/src/jake2/sound/joal/JOALSoundImpl.java
new file mode 100644
index 0000000..8a005ce
--- /dev/null
+++ b/src/jake2/sound/joal/JOALSoundImpl.java
@@ -0,0 +1,793 @@
+/*
+ * JOALSoundImpl.java
+ * Copyright (C) 2004
+ *
+ * $Id: JOALSoundImpl.java,v 1.1 2004-07-09 06:50:52 hzi Exp $
+ */
+package jake2.sound.joal;
+
+
+import jake2.Defines;
+import jake2.Globals;
+import jake2.client.CL;
+import jake2.game.*;
+import jake2.qcommon.*;
+import jake2.sound.*;
+import jake2.util.Math3D;
+import jake2.util.Vargs;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.*;
+
+import net.java.games.joal.*;
+
+/**
+ * JOALSoundImpl
+ */
+public final class JOALSoundImpl implements Sound {
+
+ static {
+ S.register(new JOALSoundImpl());
+ };
+
+ static AL al;
+ static ALC alc;
+
+ cvar_t s_volume;
+
+ private static final int MAX_SFX = Defines.MAX_SOUNDS * 2;
+ private static final int MAX_CHANNELS = 32;
+
+ private int[] buffers = new int[MAX_SFX];
+ private int[] sources = new int[MAX_CHANNELS];
+ private Channel[] channels = null;
+
+ private JOALSoundImpl() {
+ }
+
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#Init()
+ */
+ public boolean Init() {
+
+ try {
+ initOpenAL();
+ al = ALFactory.getAL();
+ checkError();
+ } catch (OpenALException e) {
+ Com.Printf(e.getMessage() + '\n');
+ return false;
+ }
+
+ checkError();
+ al.alGenBuffers(MAX_SFX, buffers);
+ al.alGenSources(MAX_CHANNELS, sources);
+ checkError();
+ s_volume = Cvar.Get("s_volume", "0.7", Defines.CVAR_ARCHIVE);
+ initChannels();
+ al.alDistanceModel(AL.AL_INVERSE_DISTANCE_CLAMPED);
+// al.alDistanceModel(AL.AL_INVERSE_DISTANCE);
+ Cmd.AddCommand("play", new xcommand_t() {
+ public void execute() {
+ Play();
+ }
+ });
+ Cmd.AddCommand("stopsound", new xcommand_t() {
+ public void execute() {
+ StopAllSounds();
+ }
+ });
+ Cmd.AddCommand("soundlist", new xcommand_t() {
+ public void execute() {
+ SoundList();
+ }
+ });
+ Cmd.AddCommand("soundinfo", new xcommand_t() {
+ public void execute() {
+ SoundInfo_f();
+ }
+ });
+
+ num_sfx = 0;
+
+
+ Com.Printf("sound sampling rate: 44100Hz\n");
+
+ StopAllSounds();
+ Com.Printf("------------------------------------\n");
+ return true;
+ }
+
+
+ private void initOpenAL() throws OpenALException {
+ ALFactory.initialize();
+ alc = ALFactory.getALC();
+ String deviceName = null;
+
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Windows")) {
+ deviceName = "DirectSound3D";
+ }
+ ALC.Device device = alc.alcOpenDevice(deviceName);
+ String deviceSpecifier = alc.alcGetString(device, ALC.ALC_DEVICE_SPECIFIER);
+ String defaultSpecifier = alc.alcGetString(device, ALC.ALC_DEFAULT_DEVICE_SPECIFIER);
+
+ Com.Printf(os + " using " + ((deviceName == null) ? defaultSpecifier : deviceName) + '\n');
+
+ ALC.Context context = alc.alcCreateContext(device, new int[] {0});
+ alc.alcMakeContextCurrent(context);
+ // Check for an error.
+ if (alc.alcGetError(device) != ALC.ALC_NO_ERROR) {
+ Com.DPrintf("Error with SoundDevice");
+ }
+ }
+
+ void exitOpenAL() {
+ // Get the current context.
+ ALC.Context curContext = alc.alcGetCurrentContext();
+ // Get the device used by that context.
+ ALC.Device curDevice = alc.alcGetContextsDevice(curContext);
+ // Reset the current context to NULL.
+ alc.alcMakeContextCurrent(null);
+ // Release the context and the device.
+ alc.alcDestroyContext(curContext);
+ alc.alcCloseDevice(curDevice);
+ }
+
+ private void initChannels() {
+
+ // create channels
+ channels = new Channel[MAX_CHANNELS];
+
+ int sourceId;
+ for (int i = 0; i < MAX_CHANNELS; i++) {
+ sourceId = sources[i];
+ channels[i] = new Channel(sourceId);
+
+ // set default values for AL sources
+ al.alSourcef (sourceId, AL.AL_GAIN, s_volume.value);
+ al.alSourcef (sourceId, AL.AL_PITCH, 1.0f);
+ al.alSourcei (sourceId, AL.AL_SOURCE_ABSOLUTE, AL.AL_TRUE);
+ al.alSourcefv(sourceId, AL.AL_VELOCITY, NULLVECTOR);
+ al.alSourcei (sourceId, AL.AL_LOOPING, AL.AL_FALSE);
+ al.alSourcef (sourceId, AL.AL_REFERENCE_DISTANCE, 300.0f);
+ al.alSourcef (sourceId, AL.AL_MIN_GAIN, 0.0005f);
+ al.alSourcef (sourceId, AL.AL_MAX_GAIN, 1.0f);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#RegisterSound(jake2.sound.sfx_t)
+ */
+ private void initBuffer(sfx_t sfx)
+ {
+ if (sfx.cache == null ) {
+ //System.out.println(sfx.name + " " + sfx.cache.length+ " " + sfx.cache.loopstart + " " + sfx.cache.speed + " " + sfx.cache.stereo + " " + sfx.cache.width);
+ return;
+ }
+
+ int format = AL.AL_FORMAT_MONO16;
+ byte[] data = sfx.cache.data;
+ int freq = sfx.cache.speed;
+ int size = data.length;
+
+// if (buffers[sfx.id] != 0)
+// al.alDeleteBuffers(1, new int[] {buffers[sfx.id] });
+//
+// int[] bid = new int[1];
+// al.alBufferData( bid[0], format, data, size, freq);
+// buffers[sfx.id] = bid[0];
+// al.alBufferData( bid[0], format, data, size, freq);
+
+ al.alBufferData( buffers[sfx.id], format, data, size, freq);
+// int error;
+// if ((error = al.alGetError()) != AL.AL_NO_ERROR) {
+// String message;
+// switch(error) {
+// case AL.AL_INVALID_OPERATION: message = "invalid operation"; break;
+// case AL.AL_INVALID_VALUE: message = "invalid value"; break;
+// case AL.AL_INVALID_ENUM: message = "invalid enum"; break;
+// case AL.AL_INVALID_NAME: message = "invalid name"; break;
+// default: message = "" + error;
+// }
+// Com.DPrintf("Error Buffer " + sfx.id + ": " + sfx.name + " (" + size + ") --> " + message + '\n');
+// }
+ }
+
+ private void checkError() {
+ int error;
+ if ((error = al.alGetError()) != AL.AL_NO_ERROR) {
+ String message;
+ switch(error) {
+ case AL.AL_INVALID_OPERATION: message = "invalid operation"; break;
+ case AL.AL_INVALID_VALUE: message = "invalid value"; break;
+ case AL.AL_INVALID_ENUM: message = "invalid enum"; break;
+ case AL.AL_INVALID_NAME: message = "invalid name"; break;
+ default: message = "" + error;
+ }
+ Com.DPrintf("AL Error: " + message +'\n');
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#Shutdown()
+ */
+ public void Shutdown() {
+ StopAllSounds();
+ al.alDeleteSources(sources.length, sources);
+ al.alDeleteBuffers(buffers.length, buffers);
+ exitOpenAL();
+ //ALut.alutExit();
+ Cmd.RemoveCommand("play");
+ Cmd.RemoveCommand("stopsound");
+ Cmd.RemoveCommand("soundlist");
+ Cmd.RemoveCommand("soundinfo");
+
+ // free all sounds
+ for (int i = 0; i < num_sfx; i++) {
+ if (known_sfx[i].name == null)
+ continue;
+ known_sfx[i].clear();
+ }
+ num_sfx = 0;
+ }
+
+ private final static float[] NULLVECTOR = {0, 0, 0};
+ private float[] entityOrigin = {0, 0, 0};
+ private float[] sourceOrigin = {0, 0, 0};
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#StartSound(float[], int, int, jake2.sound.sfx_t, float, float, float)
+ */
+ public void StartSound(float[] origin, int entnum, int entchannel, sfx_t sfx, float fvol, float attenuation, float timeofs) {
+
+ if (sfx == null)
+ return;
+
+ if (sfx.name.charAt(0) == '*')
+ sfx = RegisterSexedSound(Globals.cl_entities[entnum].current, sfx.name);
+
+ if (LoadSound(sfx) == null)
+ return; // can't load sound
+
+ if (attenuation != Defines.ATTN_STATIC)
+ attenuation *= 0.5f;
+
+ Channel ch = pickChannel(entnum, entchannel, buffers[sfx.id], attenuation);
+
+ if (ch == null) return;
+
+ if (entnum == Globals.cl.playernum + 1) {
+ ch.addListener();
+ } else if (origin != null) {
+ ch.addFixed(origin);
+ } else {
+ ch.addDynamic(entnum);
+ }
+ }
+
+ Channel pickChannel(int entnum, int entchannel, int bufferId, float rolloff) {
+
+ Channel ch = null;
+ int state;
+ int i;
+
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ ch = channels[i];
+
+ if (entchannel != 0 && ch.entnum == entnum && ch.entchannel == entchannel) {
+ // always override sound from same entity
+ break;
+ }
+
+ // don't let monster sounds override player sounds
+ if ((ch.entnum == Globals.cl.playernum+1) && (entnum != Globals.cl.playernum+1) && ch.bufferId != -1)
+ continue;
+
+ // looking for a free AL source
+ if (!ch.active) {
+ break;
+ }
+ }
+
+ if (i == MAX_CHANNELS)
+ return null;
+
+ ch.entnum = entnum;
+ ch.entchannel = entchannel;
+ if (ch.bufferId != bufferId) {
+ ch.bufferId = bufferId;
+ ch.bufferChanged = true;
+ }
+ ch.rolloff = rolloff * 2;
+ ch.active = true;
+ ch.modified = true;
+
+ return ch;
+ }
+
+ private float[] listenerOrigin = {0, 0, 0};
+ private float[] listenerOrientation = {0, 0, 0, 0, 0, 0};
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#Update(float[], float[], float[], float[])
+ */
+ public void Update(float[] origin, float[] forward, float[] right, float[] up) {
+
+ convertVector(origin, listenerOrigin);
+ al.alListenerfv(AL.AL_POSITION, listenerOrigin);
+
+ convertOrientation(forward, up, listenerOrientation);
+ al.alListenerfv(AL.AL_ORIENTATION, listenerOrientation);
+
+ AddLoopSounds(origin);
+ playChannels(listenerOrigin);
+ }
+
+ Map looptable = new Hashtable(2 * MAX_CHANNELS);
+
+ /*
+ ==================
+ S_AddLoopSounds
+
+ Entities with a ->sound field will generated looped sounds
+ that are automatically started, stopped, and merged together
+ as the entities are sent to the client
+ ==================
+ */
+ void AddLoopSounds(float[] listener) {
+
+ if (Globals.cl_paused.value != 0.0f) {
+ removeUnusedLoopSounds();
+ return;
+ }
+
+ if (Globals.cls.state != Globals.ca_active) {
+ removeUnusedLoopSounds();
+ return;
+ }
+
+ if (!Globals.cl.sound_prepped) {
+ removeUnusedLoopSounds();
+ return;
+ }
+
+ Channel ch;
+ sfx_t sfx;
+ sfxcache_t sc;
+ int num;
+ entity_state_t ent;
+ Object key;
+ int sound = 0;
+
+ for (int i=0 ; i<Globals.cl.frame.num_entities ; i++) {
+ num = (Globals.cl.frame.parse_entities + i)&(Defines.MAX_PARSE_ENTITIES-1);
+ ent = Globals.cl_parse_entities[num];
+ sound = ent.sound;
+
+ if (sound == 0) continue;
+
+ key = new Integer(ent.number);
+ ch = (Channel)looptable.get(key);
+
+ if (ch != null) {
+ // keep on looping
+ ch.autosound = true;
+ ch.origin = ent.origin;
+ continue;
+ }
+
+ sfx = Globals.cl.sound_precache[sound];
+ if (sfx == null)
+ continue; // bad sound effect
+
+ sc = sfx.cache;
+ if (sc == null)
+ continue;
+
+ // allocate a channel
+ ch = pickChannel(0, 0, buffers[sfx.id], 6);
+ if (ch == null)
+ break;
+
+ ch.addFixed(ent.origin);
+ ch.autosound = true;
+
+ looptable.put(key, ch);
+ al.alSourcei(ch.sourceId, AL.AL_LOOPING, AL.AL_TRUE);
+ }
+
+ removeUnusedLoopSounds();
+
+ }
+
+ void removeUnusedLoopSounds() {
+ Channel ch;
+ // stop unused loopsounds
+ for (Iterator iter = looptable.values().iterator(); iter.hasNext();) {
+ ch = (Channel)iter.next();
+ if (!ch.autosound) {
+ al.alSourceStop(ch.sourceId);
+ al.alSourcei(ch.sourceId, AL.AL_LOOPING, AL.AL_FALSE);
+ iter.remove();
+ ch.clear();
+ }
+ }
+ }
+
+ void playChannels(float[] listenerOrigin) {
+
+ float[] sourceOrigin = {0, 0, 0};
+ float[] entityOrigin = {0, 0, 0};
+ Channel ch;
+ int sourceId;
+ int state;
+
+ for (int i = 0; i < MAX_CHANNELS; i++) {
+ ch = channels[i];
+ if (ch.active) {
+ sourceId = ch.sourceId;
+
+ switch (ch.type) {
+ case Channel.LISTENER:
+ Math3D.VectorCopy(listenerOrigin, sourceOrigin);
+ break;
+ case Channel.DYNAMIC:
+ CL.GetEntitySoundOrigin(ch.entity, entityOrigin);
+ convertVector(entityOrigin, sourceOrigin);
+ break;
+ case Channel.FIXED:
+ convertVector(ch.origin, sourceOrigin);
+ break;
+ }
+
+ if (ch.modified) {
+ if (ch.bufferChanged)
+ al.alSourcei (sourceId, AL.AL_BUFFER, ch.bufferId);
+
+ al.alSourcef (sourceId, AL.AL_GAIN, s_volume.value);
+ al.alSourcef (sourceId, AL.AL_ROLLOFF_FACTOR, ch.rolloff);
+ al.alSourcefv(sourceId, AL.AL_POSITION, sourceOrigin);
+ al.alSourcePlay(sourceId);
+ ch.modified = false;
+ } else {
+ state = al.alGetSourcei(ch.sourceId, AL.AL_SOURCE_STATE);
+ if (state == AL.AL_PLAYING) {
+ al.alSourcefv(sourceId, AL.AL_POSITION, sourceOrigin);
+ } else {
+ ch.clear();
+ }
+ }
+ ch.autosound = false;
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#StopAllSounds()
+ */
+ public void StopAllSounds() {
+ for (int i = 0; i < MAX_CHANNELS; i++) {
+ al.alSourceStop(sources[i]);
+ al.alSourcei(sources[i], AL.AL_BUFFER, 0);
+ channels[i].clear();
+ }
+ }
+
+ static void convertVector(float[] from, float[] to) {
+ to[0] = from[0];
+ to[1] = from[2];
+ to[2] = -from[1];
+ }
+
+ static void convertOrientation(float[] forward, float[] up, float[] orientation) {
+ orientation[0] = forward[0];
+ orientation[1] = forward[2];
+ orientation[2] = -forward[1];
+ orientation[3] = up[0];
+ orientation[4] = up[2];
+ orientation[5] = -up[1];
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#getName()
+ */
+ public String getName() {
+ return "joal";
+ }
+
+
+ int s_registration_sequence;
+ boolean s_registering;
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#BeginRegistration()
+ */
+ public void BeginRegistration() {
+ s_registration_sequence++;
+ s_registering = true;
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#RegisterSound(java.lang.String)
+ */
+ public sfx_t RegisterSound(String name) {
+ sfx_t sfx = FindName(name, true);
+ sfx.registration_sequence = s_registration_sequence;
+
+ if (!s_registering)
+ LoadSound(sfx);
+
+ return sfx;
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#EndRegistration()
+ */
+ public void EndRegistration() {
+ int i;
+ sfx_t sfx;
+ int size;
+
+ // free any sounds not from this registration sequence
+ for (i = 0; i < num_sfx; i++) {
+ sfx = known_sfx[i];
+ if (sfx.name == null)
+ continue;
+ if (sfx.registration_sequence != s_registration_sequence) {
+ // don't need this sound
+ sfx.clear();
+ }
+ }
+
+ // load everything in
+ for (i = 0; i < num_sfx; i++) {
+ sfx = known_sfx[i];
+ if (sfx.name == null)
+ continue;
+ LoadSound(sfx);
+ }
+
+ s_registering = false;
+ }
+
+ sfx_t RegisterSexedSound(entity_state_t ent, String base) {
+
+ sfx_t sfx = null;
+
+ // determine what model the client is using
+ String model = "male";
+ int n = Globals.CS_PLAYERSKINS + ent.number - 1;
+ if (Globals.cl.configstrings[n] != null) {
+ int p = Globals.cl.configstrings[n].indexOf('\\');
+ if (p >= 0) {
+ p++;
+ model = Globals.cl.configstrings[n].substring(p);
+ //strcpy(model, p);
+ p = model.indexOf('/');
+ if (p > 0)
+ model = model.substring(0, p);
+ }
+ }
+ // if we can't figure it out, they're male
+ if (model == null || model.length() == 0)
+ model = "male";
+
+ // see if we already know of the model specific sound
+ String sexedFilename = "#players/" + model + "/" + base.substring(1);
+ //Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1);
+ sfx = FindName(sexedFilename, false);
+
+ if (sfx == null) {
+ // no, so see if it exists
+ RandomAccessFile f = null;
+ try {
+ f = FS.FOpenFile(sexedFilename.substring(1));
+ } catch (IOException e) {}
+ if (f != null) {
+ // yes, close the file and register it
+ try {
+ FS.FCloseFile(f);
+ } catch (IOException e1) {}
+ sfx = RegisterSound(sexedFilename);
+ } else {
+ // no, revert to the male sound in the pak0.pak
+ //Com_sprintf (maleFilename, sizeof(maleFilename), "player/%s/%s", "male", base+1);
+ String maleFilename = "player/male/" + base.substring(1);
+ sfx = AliasName(sexedFilename, maleFilename);
+ }
+ }
+
+ //System.out.println(sfx.name);
+ return sfx;
+ }
+
+
+ static sfx_t[] known_sfx = new sfx_t[MAX_SFX];
+ static {
+ for (int i = 0; i< known_sfx.length; i++)
+ known_sfx[i] = new sfx_t();
+ }
+ static int num_sfx;
+
+ sfx_t FindName(String name, boolean create) {
+ int i;
+ sfx_t sfx = null;
+
+ if (name == null)
+ Com.Error(Defines.ERR_FATAL, "S_FindName: NULL\n");
+ if (name.length() == 0)
+ Com.Error(Defines.ERR_FATAL, "S_FindName: empty name\n");
+
+ if (name.length() >= Defines.MAX_QPATH)
+ Com.Error(Defines.ERR_FATAL, "Sound name too long: " + name);
+
+ // see if already loaded
+ for (i = 0; i < num_sfx; i++)
+ if (name.equals(known_sfx[i].name)) {
+ return known_sfx[i];
+ }
+
+ if (!create)
+ return null;
+
+ // find a free sfx
+ for (i = 0; i < num_sfx; i++)
+ if (known_sfx[i].name == null)
+ // registration_sequence < s_registration_sequence)
+ break;
+
+ if (i == num_sfx) {
+ if (num_sfx == MAX_SFX)
+ Com.Error(Defines.ERR_FATAL, "S_FindName: out of sfx_t");
+ num_sfx++;
+ }
+
+ sfx = known_sfx[i];
+ sfx.clear();
+ sfx.name = name;
+ sfx.registration_sequence = s_registration_sequence;
+ // cwei
+ sfx.id = i;
+
+ return sfx;
+ }
+
+ /*
+ ==================
+ S_AliasName
+
+ ==================
+ */
+ sfx_t AliasName(String aliasname, String truename)
+ {
+ sfx_t sfx = null;
+ String s;
+ int i;
+
+ s = new String(truename);
+
+ // find a free sfx
+ for (i=0 ; i < num_sfx ; i++)
+ if (known_sfx[i].name == null)
+ break;
+
+ if (i == num_sfx)
+ {
+ if (num_sfx == MAX_SFX)
+ Com.Error(Defines.ERR_FATAL, "S_FindName: out of sfx_t");
+ num_sfx++;
+ }
+
+ sfx = known_sfx[i];
+ sfx.clear();
+ sfx.name = new String(aliasname);
+ sfx.registration_sequence = s_registration_sequence;
+ sfx.truename = s;
+ // cwei
+ sfx.id = i;
+
+ return sfx;
+ }
+
+ /*
+ ==============
+ S_LoadSound
+ ==============
+ */
+ public sfxcache_t LoadSound(sfx_t s) {
+ sfxcache_t sc = WaveLoader.LoadSound(s);
+ initBuffer(s);
+ return sc;
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#StartLocalSound(java.lang.String)
+ */
+ public void StartLocalSound(String sound) {
+ sfx_t sfx;
+
+ sfx = RegisterSound(sound);
+ if (sfx == null) {
+ Com.Printf("S_StartLocalSound: can't cache " + sound + "\n");
+ return;
+ }
+ StartSound(null, Globals.cl.playernum + 1, 0, sfx, 1, 1, 0);
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#RawSamples(int, int, int, int, byte[])
+ */
+ public void RawSamples(int samples, int rate, int width, int channels, byte[] data) {
+ // TODO implement RawSamples
+ }
+
+ /*
+ ===============================================================================
+
+ console functions
+
+ ===============================================================================
+ */
+
+ void Play() {
+ int i;
+ String name;
+ sfx_t sfx;
+
+ i = 1;
+ while (i < Cmd.Argc()) {
+ name = new String(Cmd.Argv(i));
+ if (name.indexOf('.') == -1)
+ name += ".wav";
+
+ sfx = RegisterSound(name);
+ StartSound(null, Globals.cl.playernum + 1, 0, sfx, 1.0f, 1.0f, 0.0f);
+ i++;
+ }
+ }
+
+ void SoundList() {
+ int i;
+ sfx_t sfx;
+ sfxcache_t sc;
+ int size, total;
+
+ total = 0;
+ for (i = 0; i < num_sfx; i++) {
+ sfx = known_sfx[i];
+ if (sfx.registration_sequence == 0)
+ continue;
+ sc = sfx.cache;
+ if (sc != null) {
+ size = sc.length * sc.width * (sc.stereo + 1);
+ total += size;
+ if (sc.loopstart >= 0)
+ Com.Printf("L");
+ else
+ Com.Printf(" ");
+ Com.Printf("(%2db) %6i : %s\n", new Vargs(3).add(sc.width * 8).add(size).add(sfx.name));
+ } else {
+ if (sfx.name.charAt(0) == '*')
+ Com.Printf(" placeholder : " + sfx.name + "\n");
+ else
+ Com.Printf(" not loaded : " + sfx.name + "\n");
+ }
+ }
+ Com.Printf("Total resident: " + total + "\n");
+ }
+
+ void SoundInfo_f() {
+
+ Com.Printf("%5d stereo\n", new Vargs(1).add(1));
+ Com.Printf("%5d samples\n", new Vargs(1).add(22050));
+ Com.Printf("%5d samplebits\n", new Vargs(1).add(16));
+ Com.Printf("%5d speed\n", new Vargs(1).add(44100));
+ }
+
+}
diff --git a/src/jake2/sound/jsound/JSoundImpl.java b/src/jake2/sound/jsound/JSoundImpl.java
new file mode 100644
index 0000000..3a3cc46
--- /dev/null
+++ b/src/jake2/sound/jsound/JSoundImpl.java
@@ -0,0 +1,98 @@
+/*
+ * JSoundImpl.java
+ * Copyright (C) 2004
+ *
+ * $Id: JSoundImpl.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+package jake2.sound.jsound;
+
+import jake2.sound.*;
+import jake2.sound.Sound;
+import jake2.sound.sfx_t;
+
+/**
+ * JSoundImpl
+ */
+public class JSoundImpl implements Sound {
+
+ static {
+ S.register(new JSoundImpl());
+ };
+
+ public boolean Init() {
+ SND_DMA.Init();
+ if (SND_DMA.sound_started) return true;
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#Shutdown()
+ */
+ public void Shutdown() {
+ SND_DMA.Shutdown();
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#StartSound(float[], int, int, jake2.sound.sfx_t, float, float, float)
+ */
+ public void StartSound(float[] origin, int entnum, int entchannel, sfx_t sfx, float fvol, float attenuation, float timeofs) {
+ SND_DMA.StartSound(origin, entnum, entchannel, sfx, fvol, attenuation, timeofs);
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#StopAllSounds()
+ */
+ public void StopAllSounds() {
+ SND_DMA.StopAllSounds();
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.SoundImpl#Update(float[], float[], float[], float[])
+ */
+ public void Update(float[] origin, float[] forward, float[] right, float[] up) {
+ SND_DMA.Update(origin, forward, right, up);
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#getName()
+ */
+ public String getName() {
+ return "jsound";
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#BeginRegistration()
+ */
+ public void BeginRegistration() {
+ SND_DMA.BeginRegistration();
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#RegisterSound(java.lang.String)
+ */
+ public sfx_t RegisterSound(String sample) {
+ return SND_DMA.RegisterSound(sample);
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#EndRegistration()
+ */
+ public void EndRegistration() {
+ SND_DMA.EndRegistration();
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#StartLocalSound(java.lang.String)
+ */
+ public void StartLocalSound(String sound) {
+ SND_DMA.StartLocalSound(sound);
+ }
+
+ /* (non-Javadoc)
+ * @see jake2.sound.Sound#RawSamples(int, int, int, int, byte[])
+ */
+ public void RawSamples(int samples, int rate, int width, int channels, byte[] data) {
+ SND_DMA.RawSamples(samples, rate, width, channels, data);
+ }
+
+}
diff --git a/src/jake2/sound/jsound/SND_DMA.java b/src/jake2/sound/jsound/SND_DMA.java
new file mode 100644
index 0000000..9fe7930
--- /dev/null
+++ b/src/jake2/sound/jsound/SND_DMA.java
@@ -0,0 +1,1197 @@
+/*
+ * S_DMA.java
+ * Copyright (C) 2004
+ *
+ * $Id: SND_DMA.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+
+// Created on 26.01.2004 by RST.
+
+package jake2.sound.jsound;
+
+import jake2.Defines;
+import jake2.client.CL;
+import jake2.game.*;
+import jake2.qcommon.*;
+import jake2.sound.*;
+import jake2.util.Vargs;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+
+
+/**
+ * SND_DMA
+ * TODO implement sound system
+ */
+public class SND_DMA extends SND_MIX {
+
+//// =======================================================================
+//// Internal sound data & structures
+//// =======================================================================
+//
+//// only begin attenuating sound volumes when outside the FULLVOLUME range
+ static final int SOUND_FULLVOLUME = 80;
+ static final float SOUND_LOOPATTENUATE = 0.003f;
+ static int s_registration_sequence;
+
+ static boolean sound_started = false;
+
+ static float[] listener_origin = {0, 0, 0};
+ static float[] listener_forward = {0, 0, 0};
+ static float[] listener_right = {0, 0, 0};
+ static float[] listener_up = {0, 0, 0};
+
+ static boolean s_registering;
+
+ static int soundtime; // sample PAIRS
+
+ // during registration it is possible to have more sounds
+ // than could actually be referenced during gameplay,
+ // because we don't want to free anything until we are
+ // sure we won't need it.
+ static final int MAX_SFX = (MAX_SOUNDS*2);
+ static sfx_t[] known_sfx = new sfx_t[MAX_SFX];
+ static {
+ for (int i = 0; i< known_sfx.length; i++)
+ known_sfx[i] = new sfx_t();
+ }
+ static int num_sfx;
+
+ static final int MAX_PLAYSOUNDS = 128;
+ static playsound_t[] s_playsounds = new playsound_t[MAX_PLAYSOUNDS];
+ static {
+ for( int i = 0; i < MAX_PLAYSOUNDS; i++) {
+ s_playsounds[i] = new playsound_t();
+ }
+ }
+ static playsound_t s_freeplays = new playsound_t();
+
+ static int s_beginofs;
+
+ static cvar_t s_testsound;
+ static cvar_t s_loadas8bit;
+ static cvar_t s_khz;
+ static cvar_t s_show;
+ static cvar_t s_mixahead;
+ static cvar_t s_primary;
+//
+//
+// int s_rawend;
+// portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
+//
+//
+// ====================================================================
+// User-setable variables
+// ====================================================================
+
+
+ static void SoundInfo_f() {
+ if (!sound_started) {
+ Com.Printf("sound system not started\n");
+ return;
+ }
+
+ Com.Printf("%5d stereo\n", new Vargs(1).add(dma.channels - 1));
+ Com.Printf("%5d samples\n", new Vargs(1).add(dma.samples));
+ //Com.Printf("%5d samplepos\n", new Vargs(1).add(dma.samplepos));
+ Com.Printf("%5d samplebits\n", new Vargs(1).add(dma.samplebits));
+ Com.Printf("%5d submission_chunk\n", new Vargs(1).add(dma.submission_chunk));
+ Com.Printf("%5d speed\n", new Vargs(1).add(dma.speed));
+ }
+
+ /*
+ ================
+ S_Init
+ ================
+ */
+ public static void Init() {
+ cvar_t cv;
+
+ Com.Printf("\n------- sound initialization -------\n");
+
+ cv = Cvar.Get("s_initsound", "0", 0);
+ if (cv.value == 0.0f)
+ Com.Printf("not initializing.\n");
+ else {
+ s_volume = Cvar.Get("s_volume", "0.7", CVAR_ARCHIVE);
+ s_khz = Cvar.Get("s_khz", "11", CVAR_ARCHIVE);
+ s_loadas8bit = Cvar.Get("s_loadas8bit", "1", CVAR_ARCHIVE);
+ s_mixahead = Cvar.Get("s_mixahead", "0.2", CVAR_ARCHIVE);
+ s_show = Cvar.Get("s_show", "0", 0);
+ s_testsound = Cvar.Get("s_testsound", "0", 0);
+ s_primary = Cvar.Get("s_primary", "0", CVAR_ARCHIVE); // win32 specific
+
+ Cmd.AddCommand("play", new xcommand_t() {
+ public void execute() {
+ Play();
+ }
+ });
+ Cmd.AddCommand("stopsound", new xcommand_t() {
+ public void execute() {
+ StopAllSounds();
+ }
+ });
+ Cmd.AddCommand("soundlist", new xcommand_t() {
+ public void execute() {
+ SoundList();
+ }
+ });
+ Cmd.AddCommand("soundinfo", new xcommand_t() {
+ public void execute() {
+ SoundInfo_f();
+ }
+ });
+
+ if (!SNDDMA_Init())
+ return;
+
+ InitScaletable();
+
+ sound_started = true;
+ num_sfx = 0;
+
+ soundtime = 0;
+ paintedtime = 0;
+
+ Com.Printf("sound sampling rate: " + dma.speed + "\n");
+
+ StopAllSounds();
+ }
+ Com.Printf("------------------------------------\n");
+ }
+
+
+// =======================================================================
+// Shutdown sound engine
+// =======================================================================
+
+ public static void Shutdown() {
+ int i;
+ sfx_t[] sfx;
+
+ if (!sound_started)
+ return;
+
+ SNDDMA_Shutdown();
+
+ sound_started = false;
+
+ Cmd.RemoveCommand("play");
+ Cmd.RemoveCommand("stopsound");
+ Cmd.RemoveCommand("soundlist");
+ Cmd.RemoveCommand("soundinfo");
+
+ // free all sounds
+ for (i = 0, sfx = known_sfx; i < num_sfx; i++) {
+ if (sfx[i].name == null)
+ continue;
+
+ //memset (sfx, 0, sizeof(*sfx));
+ sfx[i].clear();
+ }
+
+ num_sfx = 0;
+ }
+
+// =======================================================================
+// Load a sound
+// =======================================================================
+
+ /*
+ ==================
+ S_FindName
+
+ ==================
+ */
+ static sfx_t FindName(String name, boolean create) {
+ int i;
+ sfx_t sfx = null;
+
+ if (name == null)
+ Com.Error(ERR_FATAL, "S_FindName: NULL\n");
+ if (name.length() == 0)
+ Com.Error(ERR_FATAL, "S_FindName: empty name\n");
+
+ if (name.length() >= MAX_QPATH)
+ Com.Error(ERR_FATAL, "Sound name too long: " + name);
+
+ // see if already loaded
+ for (i = 0; i < num_sfx; i++)
+ if (name.equals(known_sfx[i].name)) {
+ return known_sfx[i];
+ }
+
+ if (!create)
+ return null;
+
+ // find a free sfx
+ for (i = 0; i < num_sfx; i++)
+ if (known_sfx[i].name == null)
+ // registration_sequence < s_registration_sequence)
+ break;
+
+ if (i == num_sfx) {
+ if (num_sfx == MAX_SFX)
+ Com.Error(ERR_FATAL, "S_FindName: out of sfx_t");
+ num_sfx++;
+ }
+
+ sfx = known_sfx[i];
+ //memset (sfx, 0, sizeof(*sfx));
+ sfx.clear();
+ sfx.name = name;
+ sfx.registration_sequence = s_registration_sequence;
+
+ return sfx;
+ }
+
+ /*
+ ==================
+ S_AliasName
+
+ ==================
+ */
+ static sfx_t AliasName(String aliasname, String truename)
+ {
+ sfx_t sfx = null;
+// char *s;
+ int i;
+
+// s = Z_Malloc (MAX_QPATH);
+// strcpy (s, truename);
+
+ // find a free sfx
+ for (i=0 ; i < num_sfx ; i++)
+ if (known_sfx[i].name == null)
+ break;
+
+ if (i == num_sfx)
+ {
+ if (num_sfx == MAX_SFX)
+ Com.Error(ERR_FATAL, "S_FindName: out of sfx_t");
+ num_sfx++;
+ }
+
+ sfx = known_sfx[i];
+ //memset (sfx, 0, sizeof(*sfx));
+ //strcpy (sfx->name, aliasname);
+ sfx.name = aliasname;
+ sfx.registration_sequence = s_registration_sequence;
+ sfx.truename = truename;
+
+ return sfx;
+ }
+
+
+ /*
+ =====================
+ S_BeginRegistration
+
+ =====================
+ */
+ public static void BeginRegistration() {
+ s_registration_sequence++;
+ s_registering = true;
+ }
+
+ /*
+ ==================
+ S_RegisterSound
+
+ ==================
+ */
+ public static sfx_t RegisterSound(String name) {
+ sfx_t sfx = null;
+
+ if (!sound_started)
+ return null;
+
+ sfx = FindName(name, true);
+ sfx.registration_sequence = s_registration_sequence;
+
+ if (!s_registering)
+ WaveLoader.LoadSound(sfx);
+
+ return sfx;
+ }
+
+
+ /*
+ =====================
+ S_EndRegistration
+
+ =====================
+ */
+ public static void EndRegistration() {
+ int i;
+ sfx_t sfx;
+ int size;
+
+ // free any sounds not from this registration sequence
+ for (i = 0; i < num_sfx; i++) {
+ sfx = known_sfx[i];
+ if (sfx.name == null)
+ continue;
+ if (sfx.registration_sequence != s_registration_sequence) { // don't need this sound
+ //memset (sfx, 0, sizeof(*sfx));
+ sfx.clear();
+ } else {
+ // make sure it is paged in
+ // if (sfx->cache)
+ // {
+ // size = sfx->cache->length*sfx->cache->width;
+ // Com_PageInMemory ((byte *)sfx->cache, size);
+ // }
+ }
+
+ }
+
+ // load everything in
+ for (i = 0; i < num_sfx; i++) {
+ sfx = known_sfx[i];
+ if (sfx.name == null)
+ continue;
+ WaveLoader.LoadSound(sfx);
+ }
+
+ s_registering = false;
+ }
+
+
+// =============================================================================
+
+ /*
+ =================
+ S_PickChannel
+ =================
+ */
+ static channel_t PickChannel(int entnum, int entchannel)
+ {
+ int ch_idx;
+ int first_to_die;
+ int life_left;
+ channel_t ch;
+
+ if (entchannel<0)
+ Com.Error(ERR_DROP, "S_PickChannel: entchannel<0");
+
+ // Check for replacement sound, or find the best one to replace
+ first_to_die = -1;
+ life_left = 0x7fffffff;
+ for (ch_idx=0 ; ch_idx < MAX_CHANNELS ; ch_idx++)
+ {
+ if (entchannel != 0 // channel 0 never overrides
+ && channels[ch_idx].entnum == entnum
+ && channels[ch_idx].entchannel == entchannel)
+ { // always override sound from same entity
+ first_to_die = ch_idx;
+ break;
+ }
+
+ // don't let monster sounds override player sounds
+ if ((channels[ch_idx].entnum == cl.playernum+1) && (entnum != cl.playernum+1) && channels[ch_idx].sfx != null)
+ continue;
+
+ if (channels[ch_idx].end - paintedtime < life_left)
+ {
+ life_left = channels[ch_idx].end - paintedtime;
+ first_to_die = ch_idx;
+ }
+ }
+
+ if (first_to_die == -1)
+ return null;
+
+ ch = channels[first_to_die];
+ //memset (ch, 0, sizeof(*ch));
+ ch.clear();
+
+ return ch;
+ }
+
+ /*
+ =================
+ S_SpatializeOrigin
+
+ Used for spatializing channels and autosounds
+ =================
+ */
+ static void SpatializeOrigin(float[] origin, float master_vol, float dist_mult, channel_t ch)
+ {
+ float dot;
+ float dist;
+ float lscale, rscale, scale;
+ float[] source_vec = {0, 0, 0};
+
+ if (cls.state != ca_active)
+ {
+ ch.leftvol = ch.rightvol = 255;
+ return;
+ }
+
+// calculate stereo seperation and distance attenuation
+ VectorSubtract(origin, listener_origin, source_vec);
+
+ dist = VectorNormalize(source_vec);
+ dist -= SOUND_FULLVOLUME;
+ if (dist < 0)
+ dist = 0; // close enough to be at full volume
+ dist *= dist_mult; // different attenuation levels
+
+ dot = DotProduct(listener_right, source_vec);
+
+ if (dma.channels == 1 || dist_mult == 0.0f)
+ { // no attenuation = no spatialization
+ rscale = 1.0f;
+ lscale = 1.0f;
+ }
+ else
+ {
+ rscale = 0.5f * (1.0f + dot);
+ lscale = 0.5f * (1.0f - dot);
+ }
+
+ // add in distance effect
+ scale = (1.0f - dist) * rscale;
+ ch.rightvol = (int) (master_vol * scale);
+ if (ch.rightvol < 0)
+ ch.rightvol = 0;
+
+ scale = (1.0f - dist) * lscale;
+ ch.leftvol = (int) (master_vol * scale);
+ if (ch.leftvol < 0)
+ ch.leftvol = 0;
+ }
+
+ /*
+ =================
+ S_Spatialize
+ =================
+ */
+ static void Spatialize(channel_t ch)
+ {
+ float[] origin = {0, 0, 0};
+
+ // anything coming from the view entity will always be full volume
+ if (ch.entnum == cl.playernum+1)
+ {
+ ch.leftvol = ch.master_vol;
+ ch.rightvol = ch.master_vol;
+ return;
+ }
+
+ if (ch.fixed_origin)
+ {
+ VectorCopy(ch.origin, origin);
+ }
+ else
+ CL.GetEntitySoundOrigin(ch.entnum, origin);
+
+ SpatializeOrigin(origin, (float)ch.master_vol, ch.dist_mult, ch);
+ }
+
+ /*
+ =================
+ S_AllocPlaysound
+ =================
+ */
+ static playsound_t AllocPlaysound ()
+ {
+ playsound_t ps;
+
+ ps = s_freeplays.next;
+ if (ps == s_freeplays)
+ return null; // no free playsounds
+
+ // unlink from freelist
+ ps.prev.next = ps.next;
+ ps.next.prev = ps.prev;
+
+ return ps;
+ }
+
+
+ /*
+ =================
+ S_FreePlaysound
+ =================
+ */
+ static void FreePlaysound(playsound_t ps)
+ {
+ // unlink from channel
+ ps.prev.next = ps.next;
+ ps.next.prev = ps.prev;
+
+ // add to free list
+ ps.next = s_freeplays.next;
+ s_freeplays.next.prev = ps;
+ ps.prev = s_freeplays;
+ s_freeplays.next = ps;
+ }
+
+ /*
+ ===============
+ S_IssuePlaysound
+
+ Take the next playsound and begin it on the channel
+ This is never called directly by S_Play*, but only
+ by the update loop.
+ ===============
+ */
+ static void IssuePlaysound (playsound_t ps)
+ {
+ channel_t ch;
+ sfxcache_t sc;
+
+ if (s_show.value != 0.0f)
+ Com.Printf("Issue " + ps.begin + "\n");
+ // pick a channel to play on
+ ch = PickChannel(ps.entnum, ps.entchannel);
+ if (ch == null)
+ {
+ FreePlaysound(ps);
+ return;
+ }
+
+ // spatialize
+ if (ps.attenuation == ATTN_STATIC)
+ ch.dist_mult = ps.attenuation * 0.001f;
+ else
+ ch.dist_mult = ps.attenuation * 0.0005f;
+ ch.master_vol = (int)ps.volume;
+ ch.entnum = ps.entnum;
+ ch.entchannel = ps.entchannel;
+ ch.sfx = ps.sfx;
+ VectorCopy (ps.origin, ch.origin);
+ ch.fixed_origin = ps.fixed_origin;
+
+ Spatialize(ch);
+
+ ch.pos = 0;
+ sc = WaveLoader.LoadSound(ch.sfx);
+ ch.end = paintedtime + sc.length;
+
+ // free the playsound
+ FreePlaysound(ps);
+ }
+
+ static sfx_t RegisterSexedSound(entity_state_t ent, String base) {
+ sfx_t sfx = null;
+
+ // determine what model the client is using
+ String model = "male";
+ int n = CS_PLAYERSKINS + ent.number - 1;
+ if (cl.configstrings[n] != null) {
+ int p = cl.configstrings[n].indexOf('\\');
+ if (p >= 0) {
+ p++;
+ model = cl.configstrings[n].substring(p);
+ //strcpy(model, p);
+ p = model.indexOf('/');
+ if (p > 0)
+ model = model.substring(0, p - 1);
+ }
+ }
+ // if we can't figure it out, they're male
+ if (model == null || model.length() == 0)
+ model = "male";
+
+ // see if we already know of the model specific sound
+ String sexedFilename = "#players/" + model + "/" + base.substring(1);
+ //Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1);
+ sfx = FindName(sexedFilename, false);
+
+ if (sfx == null) {
+ // no, so see if it exists
+ RandomAccessFile f = null;
+ try {
+ f = FS.FOpenFile(sexedFilename.substring(1));
+ } catch (IOException e) {}
+ if (f != null) {
+ // yes, close the file and register it
+ try {
+ FS.FCloseFile(f);
+ } catch (IOException e1) {}
+ sfx = RegisterSound(sexedFilename);
+ } else {
+ // no, revert to the male sound in the pak0.pak
+ //Com_sprintf (maleFilename, sizeof(maleFilename), "player/%s/%s", "male", base+1);
+ String maleFilename = "player/male/" + base.substring(1);
+ sfx = AliasName(sexedFilename, maleFilename);
+ }
+ }
+
+ return sfx;
+ }
+
+
+// =======================================================================
+// Start a sound effect
+// =======================================================================
+
+ /*
+ ====================
+ S_StartSound
+
+ Validates the parms and ques the sound up
+ if pos is NULL, the sound will be dynamically sourced from the entity
+ Entchannel 0 will never override a playing sound
+ ====================
+ */
+ public static void StartSound(float[] origin, int entnum, int entchannel, sfx_t sfx, float fvol, float attenuation, float timeofs) {
+
+ if (!sound_started)
+ return;
+
+ if (sfx == null)
+ return;
+
+ if (sfx.name.charAt(0) == '*')
+ sfx = RegisterSexedSound(cl_entities[entnum].current, sfx.name);
+
+ // make sure the sound is loaded
+ sfxcache_t sc = WaveLoader.LoadSound(sfx);
+ if (sc == null)
+ return; // couldn't load the sound's data
+
+ int vol = (int) (fvol * 255);
+
+ // make the playsound_t
+ playsound_t ps = AllocPlaysound();
+ if (ps == null)
+ return;
+
+ if (origin != null) {
+ VectorCopy(origin, ps.origin);
+ ps.fixed_origin = true;
+ } else
+ ps.fixed_origin = false;
+
+ ps.entnum = entnum;
+ ps.entchannel = entchannel;
+ ps.attenuation = attenuation;
+ ps.volume = vol;
+ ps.sfx = sfx;
+
+ // drift s_beginofs
+ int start = (int) (cl.frame.servertime * 0.001f * dma.speed + s_beginofs);
+ if (start < paintedtime) {
+ start = paintedtime;
+ s_beginofs = (int) (start - (cl.frame.servertime * 0.001f * dma.speed));
+ } else if (start > paintedtime + 0.3f * dma.speed) {
+ start = (int) (paintedtime + 0.1f * dma.speed);
+ s_beginofs = (int) (start - (cl.frame.servertime * 0.001f * dma.speed));
+ } else {
+ s_beginofs -= 10;
+ }
+
+ if (timeofs == 0.0f)
+ ps.begin = paintedtime;
+ else
+ ps.begin = (long) (start + timeofs * dma.speed);
+
+ // sort into the pending sound list
+ playsound_t sort;
+ for (sort = s_pendingplays.next; sort != s_pendingplays && sort.begin < ps.begin; sort = sort.next);
+
+ ps.next = sort;
+ ps.prev = sort.prev;
+
+ ps.next.prev = ps;
+ ps.prev.next = ps;
+ }
+
+ /*
+ ==================
+ S_StartLocalSound
+ ==================
+ */
+ public static void StartLocalSound(String sound) {
+ sfx_t sfx;
+
+ if (!sound_started)
+ return;
+
+ sfx = RegisterSound(sound);
+ if (sfx == null) {
+ Com.Printf("S_StartLocalSound: can't cache " + sound + "\n");
+ return;
+ }
+ StartSound(null, cl.playernum + 1, 0, sfx, 1, 1, 0);
+ }
+
+
+ /*
+ ==================
+ S_ClearBuffer
+ ==================
+ */
+ static void ClearBuffer()
+ {
+ int clear;
+
+ if (!sound_started)
+ return;
+
+ s_rawend = 0;
+
+ if (dma.samplebits == 8)
+ clear = 0x80;
+ else
+ clear = 0;
+
+ SNDDMA_BeginPainting ();
+ if (dma.buffer != null)
+ //memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
+ //Arrays.fill(dma.buffer, (byte)clear);
+ SNDDMA_Submit ();
+ }
+
+ /*
+ ==================
+ S_StopAllSounds
+ ==================
+ */
+ public static void StopAllSounds()
+ {
+ int i;
+
+ if (!sound_started)
+ return;
+
+ // clear all the playsounds
+ //memset(s_playsounds, 0, sizeof(s_playsounds));
+ s_freeplays.next = s_freeplays.prev = s_freeplays;
+ s_pendingplays.next = s_pendingplays.prev = s_pendingplays;
+
+ for (i=0 ; i<MAX_PLAYSOUNDS ; i++)
+ {
+ s_playsounds[i].clear();
+ s_playsounds[i].prev = s_freeplays;
+ s_playsounds[i].next = s_freeplays.next;
+ s_playsounds[i].prev.next = s_playsounds[i];
+ s_playsounds[i].next.prev = s_playsounds[i];
+ }
+
+ // clear all the channels
+ //memset(channels, 0, sizeof(channels));
+ for (i = 0; i < MAX_CHANNELS; i++)
+ channels[i].clear();
+
+ ClearBuffer();
+ }
+
+ /*
+ ==================
+ S_AddLoopSounds
+
+ Entities with a ->sound field will generated looped sounds
+ that are automatically started, stopped, and merged together
+ as the entities are sent to the client
+ ==================
+ */
+ static void AddLoopSounds()
+ {
+ int i, j;
+ int[] sounds = new int[Defines.MAX_EDICTS];
+ int left, right, left_total, right_total;
+ channel_t ch;
+ sfx_t sfx;
+ sfxcache_t sc;
+ int num;
+ entity_state_t ent;
+
+ if (cl_paused.value != 0.0f)
+ return;
+
+ if (cls.state != ca_active)
+ return;
+
+ if (!cl.sound_prepped)
+ return;
+
+ for (i=0 ; i<cl.frame.num_entities ; i++)
+ {
+ num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
+ ent = cl_parse_entities[num];
+ sounds[i] = ent.sound;
+ }
+
+ for (i=0 ; i<cl.frame.num_entities ; i++)
+ {
+ if (sounds[i] == 0)
+ continue;
+
+ sfx = cl.sound_precache[sounds[i]];
+ if (sfx == null)
+ continue; // bad sound effect
+ sc = sfx.cache;
+ if (sc == null)
+ continue;
+
+ num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
+ ent = cl_parse_entities[num];
+
+ channel_t tch = new channel_t();
+ // find the total contribution of all sounds of this type
+ SpatializeOrigin(ent.origin, 255.0f, SOUND_LOOPATTENUATE, tch);
+ left_total = tch.leftvol;
+ right_total = tch.rightvol;
+ for (j=i+1 ; j<cl.frame.num_entities ; j++)
+ {
+ if (sounds[j] != sounds[i])
+ continue;
+ sounds[j] = 0; // don't check this again later
+
+ num = (cl.frame.parse_entities + j)&(MAX_PARSE_ENTITIES-1);
+ ent = cl_parse_entities[num];
+
+ SpatializeOrigin(ent.origin, 255.0f, SOUND_LOOPATTENUATE, tch);
+ left_total += tch.leftvol;
+ right_total += tch.rightvol;
+ }
+
+ if (left_total == 0 && right_total == 0)
+ continue; // not audible
+
+ // allocate a channel
+ ch = PickChannel(0, 0);
+ if (ch == null)
+ return;
+
+ if (left_total > 255)
+ left_total = 255;
+ if (right_total > 255)
+ right_total = 255;
+ ch.leftvol = left_total;
+ ch.rightvol = right_total;
+ ch.autosound = true; // remove next frame
+ ch.sfx = sfx;
+ ch.pos = paintedtime % sc.length;
+ ch.end = paintedtime + sc.length - ch.pos;
+ }
+ }
+
+// =============================================================================
+
+ /*
+ ============
+ S_RawSamples
+
+ Cinematic streaming and voice over network
+ ============
+ */
+ static void RawSamples(int samples, int rate, int width, int channels, byte[] data)
+ {
+ //TODO RawSamples
+ int i;
+ int src, dst;
+ float scale;
+
+ if (!sound_started)
+ return;
+
+ if (s_rawend < paintedtime)
+ s_rawend = paintedtime;
+ scale = (float)rate / dma.speed;
+
+// Com_Printf ("%i < %i < %i\n", soundtime, paintedtime, s_rawend);
+ if (channels == 2 && width == 2)
+ {
+ if (scale == 1.0)
+ { // optimized case
+// for (i=0 ; i<samples ; i++)
+// {
+// dst = s_rawend&(MAX_RAW_SAMPLES-1);
+// s_rawend++;
+// s_rawsamples[dst].left =
+// LittleShort(((short *)data)[i*2]) << 8;
+// s_rawsamples[dst].right =
+// LittleShort(((short *)data)[i*2+1]) << 8;
+// }
+ }
+ else
+ {
+ for (i=0 ; ; i++)
+ {
+// src = i*scale;
+// if (src >= samples)
+// break;
+// dst = s_rawend&(MAX_RAW_SAMPLES-1);
+// s_rawend++;
+// s_rawsamples[dst].left =
+// LittleShort(((short *)data)[src*2]) << 8;
+// s_rawsamples[dst].right =
+// LittleShort(((short *)data)[src*2+1]) << 8;
+ }
+ }
+ }
+ else if (channels == 1 && width == 2)
+ {
+ for (i=0 ; ; i++)
+ {
+// src = i*scale;
+// if (src >= samples)
+// break;
+// dst = s_rawend&(MAX_RAW_SAMPLES-1);
+// s_rawend++;
+// s_rawsamples[dst].left =
+// LittleShort(((short *)data)[src]) << 8;
+// s_rawsamples[dst].right =
+// LittleShort(((short *)data)[src]) << 8;
+ }
+ }
+ else if (channels == 2 && width == 1)
+ {
+ for (i=0 ; ; i++)
+ {
+// src = i*scale;
+// if (src >= samples)
+// break;
+// dst = s_rawend&(MAX_RAW_SAMPLES-1);
+// s_rawend++;
+// s_rawsamples[dst].left =
+// ((char *)data)[src*2] << 16;
+// s_rawsamples[dst].right =
+// ((char *)data)[src*2+1] << 16;
+ }
+ }
+ else if (channels == 1 && width == 1)
+ {
+ for (i=0 ; ; i++)
+ {
+// src = i*scale;
+// if (src >= samples)
+// break;
+// dst = s_rawend&(MAX_RAW_SAMPLES-1);
+// s_rawend++;
+// s_rawsamples[dst].left =
+// (((byte *)data)[src]-128) << 16;
+// s_rawsamples[dst].right = (((byte *)data)[src]-128) << 16;
+ }
+ }
+ }
+
+//// =============================================================================
+
+ /*
+ ============
+ S_Update
+
+ Called once each time through the main loop
+ ============
+ */
+ public static void Update(float[] origin, float[] forward, float[] right, float[] up) {
+
+ if (!sound_started)
+ return;
+
+ // if the laoding plaque is up, clear everything
+ // out to make sure we aren't looping a dirty
+ // dma buffer while loading
+ if (cls.disable_screen != 0.0f) {
+ ClearBuffer();
+ return;
+ }
+
+ // rebuild scale tables if volume is modified
+ if (s_volume.modified)
+ InitScaletable();
+
+ VectorCopy(origin, listener_origin);
+ VectorCopy(forward, listener_forward);
+ VectorCopy(right, listener_right);
+ VectorCopy(up, listener_up);
+
+ channel_t combine = null;
+
+ // update spatialization for dynamic sounds
+ channel_t ch;
+ for (int i = 0; i < MAX_CHANNELS; i++) {
+ ch = channels[i];
+ if (ch.sfx == null)
+ continue;
+ if (ch.autosound) { // autosounds are regenerated fresh each frame
+ //memset (ch, 0, sizeof(*ch));
+ ch.clear();
+ continue;
+ }
+ Spatialize(ch); // respatialize channel
+ if (ch.leftvol == 0 && ch.rightvol == 0) {
+ //memset (ch, 0, sizeof(*ch));
+ ch.clear();
+ continue;
+ }
+ }
+
+ // add loopsounds
+ AddLoopSounds();
+
+ //
+ // debugging output
+ //
+ if (s_show.value != 0.0f) {
+ int total = 0;
+
+ for (int i = 0; i < MAX_CHANNELS; i++) {
+ ch = channels[i];
+ if (ch.sfx != null && (ch.leftvol != 0 || ch.rightvol != 0)) {
+ Com.Printf(ch.leftvol + " " + ch.rightvol + " " + ch.sfx.name + "\n");
+ total++;
+ }
+ }
+
+ //Com.Printf("----(" + total + ")---- painted: " + paintedtime + "\n");
+ }
+
+ // mix some sound
+ Update_();
+ }
+
+ static int buffers = 0;
+ static int oldsamplepos = 0;
+ static void GetSoundtime()
+ {
+ int samplepos;
+ //static int buffers;
+ //static int oldsamplepos;
+ int fullsamples;
+
+ fullsamples = dma.samples / dma.channels;
+
+// it is possible to miscount buffers if it has wrapped twice between
+// calls to S_Update. Oh well.
+ samplepos = SNDDMA_GetDMAPos();
+
+ if (samplepos < oldsamplepos)
+ {
+ buffers++; // buffer wrapped
+
+ if (paintedtime > 0x40000000)
+ { // time to chop things off to avoid 32 bit limits
+ buffers = 0;
+ paintedtime = fullsamples;
+ StopAllSounds();
+ }
+ }
+ oldsamplepos = samplepos;
+
+ soundtime = buffers*fullsamples + samplepos/dma.channels;
+ }
+
+ static void Update_()
+ {
+ int endtime;
+ int samps;
+
+ if (!sound_started)
+ return;
+
+ SNDDMA_BeginPainting();
+
+ if (dma.buffer == null)
+ return;
+
+ // Updates DMA time
+ GetSoundtime();
+
+ // check to make sure that we haven't overshot
+ if (paintedtime < soundtime)
+ {
+ Com.DPrintf("S_Update_ : overflow\n");
+ paintedtime = soundtime;
+ }
+
+ // mix ahead of current position
+ endtime = (int)(soundtime + s_mixahead.value * dma.speed);
+ // endtime = (soundtime + 4096) & ~4095;
+
+ // mix to an even submission block size
+ endtime = (endtime + dma.submission_chunk-1)
+ & ~(dma.submission_chunk-1);
+ samps = dma.samples >> (dma.channels-1);
+ if (endtime - soundtime > samps)
+ endtime = soundtime + samps;
+
+ PaintChannels(endtime);
+
+ SNDDMA_Submit();
+ }
+
+ /*
+ ===============================================================================
+
+ console functions
+
+ ===============================================================================
+ */
+
+ static void Play() {
+ int i;
+ String name;
+ sfx_t sfx;
+
+ i = 1;
+ while (i < Cmd.Argc()) {
+ name = new String(Cmd.Argv(i));
+ if (name.indexOf('.') == -1)
+ name += ".wav";
+
+ sfx = RegisterSound(name);
+ StartSound(null, cl.playernum + 1, 0, sfx, 1.0f, 1.0f, 0.0f);
+ i++;
+ }
+ }
+
+ static void SoundList() {
+ int i;
+ sfx_t sfx;
+ sfxcache_t sc;
+ int size, total;
+
+ total = 0;
+ for (i = 0; i < num_sfx; i++) {
+ sfx = known_sfx[i];
+ if (sfx.registration_sequence == 0)
+ continue;
+ sc = sfx.cache;
+ if (sc != null) {
+ size = sc.length * sc.width * (sc.stereo + 1);
+ total += size;
+ if (sc.loopstart >= 0)
+ Com.Printf("L");
+ else
+ Com.Printf(" ");
+ Com.Printf("(%2db) %6i : %s\n", new Vargs(3).add(sc.width * 8).add(size).add(sfx.name));
+ } else {
+ if (sfx.name.charAt(0) == '*')
+ Com.Printf(" placeholder : " + sfx.name + "\n");
+ else
+ Com.Printf(" not loaded : " + sfx.name + "\n");
+ }
+ }
+ Com.Printf("Total resident: " + total + "\n");
+ }
+
+}
diff --git a/src/jake2/sound/jsound/SND_JAVA.java b/src/jake2/sound/jsound/SND_JAVA.java
new file mode 100644
index 0000000..679c64e
--- /dev/null
+++ b/src/jake2/sound/jsound/SND_JAVA.java
@@ -0,0 +1,181 @@
+/*
+ * SND_JAVA.java
+ * Copyright (C) 2004
+ *
+ * $Id: SND_JAVA.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.sound.jsound;
+
+import jake2.Globals;
+import jake2.game.cvar_t;
+import jake2.qcommon.Cvar;
+
+import javax.sound.sampled.*;
+
+/**
+ * SND_JAVA
+ */
+public class SND_JAVA extends Globals {
+
+ static boolean snd_inited= false;
+
+ static cvar_t sndbits;
+ static cvar_t sndspeed;
+ static cvar_t sndchannels;
+
+ static class dma_t {
+ int channels;
+ int samples; // mono samples in buffer
+ int submission_chunk; // don't mix less than this #
+ //int samplepos; // in mono samples
+ int samplebits;
+ int speed;
+ byte[] buffer;
+ }
+ static SND_DMA.dma_t dma = new dma_t();
+
+ static class SoundThread extends Thread {
+ byte[] b;
+ SourceDataLine l;
+ int pos = 0;
+ boolean running = false;
+ public SoundThread(byte[] buffer, SourceDataLine line) {
+ b = buffer;
+ l = line;
+ }
+ public void run() {
+ running = true;
+ while (running) {
+ line.write(b, pos, 512);
+ pos = (pos+512) % b.length;
+ }
+ }
+ public synchronized void stopLoop() {
+ running = false;
+ }
+ public int getSamplePos() {
+ return pos >> 1;
+ }
+ }
+ static SoundThread thread;
+ static SourceDataLine line;
+ static AudioFormat format;
+
+
+ static boolean SNDDMA_Init() {
+
+ if (snd_inited)
+ return true;
+
+ if (sndbits == null) {
+ sndbits = Cvar.Get("sndbits", "16", CVAR_ARCHIVE);
+ sndspeed = Cvar.Get("sndspeed", "0", CVAR_ARCHIVE);
+ sndchannels = Cvar.Get("sndchannels", "1", CVAR_ARCHIVE);
+ }
+
+// byte[] sound = FS.LoadFile("sound/misc/menu1.wav");
+// AudioInputStream stream;
+// try {
+// stream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(sound));
+// } catch (UnsupportedAudioFileException e) {
+// return false;
+// } catch (IOException e) {
+// return false;
+// }
+ //format = stream.getFormat();
+ format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 22050, 16, 1, 2, 22050, false);
+ DataLine.Info dinfo = new DataLine.Info(SourceDataLine.class, format);
+
+ try {
+ line = (SourceDataLine)AudioSystem.getLine(dinfo);
+ } catch (LineUnavailableException e4) {
+ return false;
+ }
+
+ dma.buffer = new byte[65536];
+ dma.channels = format.getChannels();
+ dma.samplebits = format.getSampleSizeInBits();
+ dma.samples = dma.buffer.length / format.getFrameSize();
+ dma.speed = (int)format.getSampleRate();
+ //dma.samplepos = 0;
+ dma.submission_chunk = 1;
+
+ try {
+ line.open(format, 4096);
+ } catch (LineUnavailableException e5) {
+ return false;
+ }
+
+ line.start();
+ thread = new SoundThread(dma.buffer, line);
+ //thread.setPriority(Thread.MAX_PRIORITY);
+ thread.start();
+
+ snd_inited = true;
+ return true;
+
+ }
+
+ static int SNDDMA_GetDMAPos() {
+ //dma.samplepos = line.getFramePosition() % dma.samples;
+ return thread.getSamplePos(); //dma.samplepos;
+ }
+
+ static void SNDDMA_Shutdown() {
+ thread.stopLoop();
+ line.stop();
+ line.flush();
+ line.close();
+ line=null;
+ snd_inited = false;
+ }
+
+ /*
+ ==============
+ SNDDMA_Submit
+
+ Send sound to device if buffer isn't really the dma buffer
+ ===============
+ */
+ public static void SNDDMA_Submit() {
+// runLine();
+ }
+
+ static void SNDDMA_BeginPainting() {}
+
+// private static int pos = 0;
+// static void runLine() {
+//
+// int p = line.getFramePosition() * format.getFrameSize() % dma.buffer.length;
+// if (p == 0) {
+// writeLine();
+// }
+// else if (pos - p < 4096 ) writeLine();
+// }
+//
+// static void writeLine() {
+// line.write(dma.buffer, pos, 4096);
+// pos+=4096;
+// if (pos>=dma.buffer.length) pos = 0;
+// }
+
+}
diff --git a/src/jake2/sound/jsound/SND_MIX.java b/src/jake2/sound/jsound/SND_MIX.java
new file mode 100644
index 0000000..c3aae2c
--- /dev/null
+++ b/src/jake2/sound/jsound/SND_MIX.java
@@ -0,0 +1,491 @@
+/*
+ * SND_MIX.java
+ * Copyright (C) 2004
+ *
+ * $Id: SND_MIX.java,v 1.1 2004-07-09 06:50:48 hzi Exp $
+ */
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+package jake2.sound.jsound;
+
+import java.nio.*;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+
+import jake2.game.cvar_t;
+import jake2.sound.*;
+import jake2.sound.sfx_t;
+import jake2.sound.sfxcache_t;
+import jake2.util.Math3D;
+
+/**
+ * SND_MIX
+ */
+public class SND_MIX extends SND_JAVA {
+
+ static final int MAX_CHANNELS = 32;
+ static final int MAX_RAW_SAMPLES = 8192;
+
+ static class playsound_t {
+ playsound_t prev, next;
+ sfx_t sfx;
+ float volume;
+ float attenuation;
+ int entnum;
+ int entchannel;
+ boolean fixed_origin; // use origin field instead of entnum's origin
+ float[] origin = { 0, 0, 0 };
+ long begin; // begin on this sample
+
+ public void clear() {
+ prev = next = null;
+ sfx = null;
+ volume = attenuation = begin = entnum = entchannel = 0;
+ fixed_origin = false;
+ Math3D.VectorClear(origin);
+ }
+ };
+
+ static class channel_t {
+ sfx_t sfx; // sfx number
+ int leftvol; // 0-255 volume
+ int rightvol; // 0-255 volume
+ int end; // end time in global paintsamples
+ int pos; // sample position in sfx
+ int looping; // where to loop, -1 = no looping OBSOLETE?
+ int entnum; // to allow overriding a specific sound
+ int entchannel; //
+ float[] origin = { 0, 0, 0 }; // only use if fixed_origin is set
+ float dist_mult; // distance multiplier (attenuation/clipK)
+ int master_vol; // 0-255 master volume
+ boolean fixed_origin; // use origin instead of fetching entnum's origin
+ boolean autosound; // from an entity->sound, cleared each frame
+
+ void clear() {
+ sfx = null;
+ dist_mult = leftvol = rightvol = end = pos = looping = entnum = entchannel = master_vol = 0;
+ Math3D.VectorClear(origin);
+ fixed_origin = autosound = false;
+ }
+ };
+
+ static class portable_samplepair_t {
+ int left;
+ int right;
+ };
+
+ static cvar_t s_volume;
+ static int s_rawend;
+//// snd_mix.c -- portable code to mix sounds for snd_dma.c
+//
+// #include "client.h"
+// #include "snd_loc.h"
+//
+ static final int PAINTBUFFER_SIZE = 2048;
+ //static portable_samplepair_t[] paintbuffer = new portable_samplepair_t[PAINTBUFFER_SIZE];
+ static IntBuffer paintbuffer = IntBuffer.allocate(PAINTBUFFER_SIZE*2);
+ static int[][] snd_scaletable = new int[32][256];
+// int *snd_p, snd_linear_count, snd_vol;
+// short *snd_out;
+ static IntBuffer snd_p;
+ static ShortBuffer snd_out;
+ static int snd_linear_count;
+ static int snd_vol;
+
+ static int paintedtime; // sample PAIRS
+ static playsound_t s_pendingplays = new playsound_t();
+
+ //static portable_samplepair_t[] s_rawsamples = new portable_samplepair_t[MAX_RAW_SAMPLES];
+ static IntBuffer s_rawsamples = IntBuffer.allocate(MAX_RAW_SAMPLES*2);
+ static channel_t[] channels = new channel_t[MAX_CHANNELS];
+ static {
+ for(int i=0; i < MAX_CHANNELS; i++)
+ channels[i] = new channel_t();
+ }
+
+ static void WriteLinearBlastStereo16()
+ {
+ int i;
+ int val;
+
+ for (i=0 ; i<snd_linear_count ; i+=2)
+ {
+ val = snd_p.get(i)>>8;
+ if (val > 0x7fff)
+ snd_out.put(i, (short)0x7fff);
+ else if (val < (short)0x8000)
+ snd_out.put(i,(short)0x8000);
+ else
+ snd_out.put(i, (short)val);
+
+ val = snd_p.get(i+1)>>8;
+ if (val > 0x7fff)
+ snd_out.put(i+1, (short)0x7fff);
+ else if (val < (short)0x8000)
+ snd_out.put(i+1, (short)0x8000);
+ else
+ snd_out.put(i+1, (short)val);
+ }
+ }
+
+ static void TransferStereo16(ByteBuffer pbuf, int endtime)
+ {
+ int lpos;
+ int lpaintedtime;
+
+ snd_p = paintbuffer;
+ lpaintedtime = paintedtime;
+
+ while (lpaintedtime < endtime)
+ {
+ // handle recirculating buffer issues
+ lpos = lpaintedtime & ((dma.samples>>1)-1);
+
+// snd_out = (short *) pbuf + (lpos<<1);
+ snd_out = pbuf.asShortBuffer();
+ snd_out.position(lpos<<1);
+ snd_out = snd_out.slice();
+
+ snd_linear_count = (dma.samples>>1) - lpos;
+ if (lpaintedtime + snd_linear_count > endtime)
+ snd_linear_count = endtime - lpaintedtime;
+
+ snd_linear_count <<= 1;
+
+ // write a linear blast of samples
+ WriteLinearBlastStereo16();
+
+ //snd_p += snd_linear_count;
+ paintbuffer.position(snd_linear_count);
+ snd_p = paintbuffer.slice();
+
+ lpaintedtime += (snd_linear_count>>1);
+ }
+ }
+
+ /*
+ ===================
+ S_TransferPaintBuffer
+
+ ===================
+ */
+ static void TransferPaintBuffer(int endtime)
+ {
+ int out_idx;
+ int count;
+ int out_mask;
+ int p;
+ int step;
+ int val;
+ //unsigned long *pbuf;
+
+ ByteBuffer pbuf = ByteBuffer.wrap(dma.buffer);
+ pbuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ if (SND_DMA.s_testsound.value != 0.0f)
+ {
+ int i;
+ int count2;
+
+ // write a fixed sine wave
+ count2 = (endtime - paintedtime)*2;
+ int v;
+ for (i=0 ; i<count2 ; i+=2) {
+ v = (int)(Math.sin((paintedtime+i)*0.1)*20000*256);
+ paintbuffer.put(i, v);
+ paintbuffer.put(i+1, v);
+ }
+ }
+
+
+ if (dma.samplebits == 16 && dma.channels == 2)
+ { // optimized case
+ TransferStereo16(pbuf, endtime);
+ }
+ else
+ { // general case
+ p = 0;
+ count = (endtime - paintedtime) * dma.channels;
+ out_mask = dma.samples - 1;
+ out_idx = paintedtime * dma.channels & out_mask;
+ step = 3 - dma.channels;
+
+ if (dma.samplebits == 16)
+ {
+// short *out = (short *) pbuf;
+ ShortBuffer out = pbuf.asShortBuffer();
+ while (count-- > 0)
+ {
+ val = paintbuffer.get(p) >> 8;
+ p+= step;
+ if (val > 0x7fff)
+ val = 0x7fff;
+ else if (val < (short)0x8000)
+ val = (short)0x8000;
+ out.put(out_idx, (short)val);
+//System.out.println(out_idx + " " + val);
+ out_idx = (out_idx + 1) & out_mask;
+ }
+ }
+ else if (dma.samplebits == 8)
+ {
+// unsigned char *out = (unsigned char *) pbuf;
+ ByteBuffer out = pbuf;
+ while (count-- > 0)
+ {
+ val = paintbuffer.get(p) >> 8;
+ p += step;
+ if (val > 0x7fff)
+ val = 0x7fff;
+ else if (val < (short)0x8000)
+ val = (short)0x8000;
+ out.put(out_idx,(byte)(val>>>8));
+ out_idx = (out_idx + 1) & out_mask;
+ }
+ }
+ }
+ }
+
+
+ /*
+ ===============================================================================
+
+ CHANNEL MIXING
+
+ ===============================================================================
+ */
+ static void PaintChannels(int endtime)
+ {
+ int i;
+ int end;
+ channel_t ch;
+ sfxcache_t sc;
+ int ltime, count;
+ playsound_t ps;
+
+ snd_vol = (int)(s_volume.value*256);
+
+// Com_Printf ("%i to %i\n", paintedtime, endtime);
+ while (paintedtime < endtime)
+ {
+ // if paintbuffer is smaller than DMA buffer
+ end = endtime;
+ if (endtime - paintedtime > PAINTBUFFER_SIZE)
+ end = paintedtime + PAINTBUFFER_SIZE;
+
+ // start any playsounds
+ while (true)
+ {
+ ps = s_pendingplays.next;
+ if (ps == s_pendingplays)
+ break; // no more pending sounds
+ if (ps.begin <= paintedtime)
+ {
+ SND_DMA.IssuePlaysound(ps);
+ continue;
+ }
+
+ if (ps.begin < end)
+ end = (int)ps.begin; // stop here
+ break;
+ }
+
+ // clear the paint buffer
+ if (s_rawend < paintedtime)
+ {
+// Com_Printf ("clear\n");
+ for (i = 0; i < (end-paintedtime)*2; i++) {
+ paintbuffer.put(i, 0);
+ }
+ //memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
+ }
+ else
+ { // copy from the streaming sound source
+ int s;
+ int stop;
+
+ stop = (end < s_rawend) ? end : s_rawend;
+
+ for (i=paintedtime ; i<stop ; i++)
+ {
+ s = i&(MAX_RAW_SAMPLES-1);
+ //paintbuffer[i-paintedtime] = s_rawsamples[s];
+ paintbuffer.put((i-paintedtime)*2, s_rawsamples.get(2*s));
+ paintbuffer.put((i-paintedtime)*2+1, s_rawsamples.get(2*s)+1);
+ }
+// if (i != end)
+// Com_Printf ("partial stream\n");
+// else
+// Com_Printf ("full stream\n");
+ for ( ; i<end ; i++)
+ {
+ //paintbuffer[i-paintedtime].left =
+ //paintbuffer[i-paintedtime].right = 0;
+ paintbuffer.put((i-paintedtime)*2, 0);
+ paintbuffer.put((i-paintedtime)*2+1, 0);
+ }
+ }
+
+
+ // paint in the channels.
+ //ch = channels;
+ for (i=0; i<MAX_CHANNELS ; i++)
+ {
+ ch = channels[i];
+ ltime = paintedtime;
+
+ while (ltime < end)
+ {
+ if (ch.sfx == null || (ch.leftvol == 0 && ch.rightvol == 0))
+ break;
+
+ // max painting is to the end of the buffer
+ count = end - ltime;
+
+ // might be stopped by running out of data
+ if (ch.end - ltime < count)
+ count = ch.end - ltime;
+
+ sc = WaveLoader.LoadSound(ch.sfx);
+ if (sc == null)
+ break;
+
+ if (count > 0 && ch.sfx != null)
+ {
+ if (sc.width == 1)// FIXME; 8 bit asm is wrong now
+ PaintChannelFrom8(ch, sc, count, ltime - paintedtime);
+ else
+ PaintChannelFrom16(ch, sc, count, ltime - paintedtime);
+
+ ltime += count;
+ }
+
+ // if at end of loop, restart
+ if (ltime >= ch.end)
+ {
+ if (ch.autosound)
+ { // autolooping sounds always go back to start
+ ch.pos = 0;
+ ch.end = ltime + sc.length;
+ }
+ else if (sc.loopstart >= 0)
+ {
+ ch.pos = sc.loopstart;
+ ch.end = ltime + sc.length - ch.pos;
+ }
+ else
+ { // channel just stopped
+ ch.sfx = null;
+ }
+ }
+ }
+
+ }
+
+ // transfer out according to DMA format
+ TransferPaintBuffer(end);
+ paintedtime = end;
+ }
+ }
+
+ static void InitScaletable ()
+ {
+ int i, j;
+ int scale;
+
+ s_volume.modified = false;
+ for (i=0 ; i<32 ; i++)
+ {
+ scale = (int)(i * 8 * 256 * s_volume.value);
+ for (j=0 ; j<256 ; j++)
+ snd_scaletable[i][j] = ((byte)j) * scale;
+ }
+ }
+
+ static void PaintChannelFrom8(channel_t ch, sfxcache_t sc, int count, int offset)
+ {
+ int data;
+ int[] lscale;
+ int[] rscale;
+ int sfx;
+ int i;
+ portable_samplepair_t samp;
+
+ if (ch.leftvol > 255)
+ ch.leftvol = 255;
+ if (ch.rightvol > 255)
+ ch.rightvol = 255;
+
+ //ZOID-- >>11 has been changed to >>3, >>11 didn't make much sense
+ //as it would always be zero.
+ lscale = snd_scaletable[ ch.leftvol >> 3];
+ rscale = snd_scaletable[ ch.rightvol >> 3];
+ sfx = ch.pos;
+
+ //samp = paintbuffer[offset];
+
+ for (i=0 ; i<count ; i++, offset++)
+ {
+ int left = paintbuffer.get(offset*2);
+ int right = paintbuffer.get(offset*2+1);
+ data = sc.data[sfx+i];
+ left += lscale[data];
+ right += rscale[data];
+ paintbuffer.put(offset*2, left);
+ paintbuffer.put(offset*2+1, right);
+ }
+
+ ch.pos += count;
+ }
+
+ private static ByteBuffer bb;
+ private static ShortBuffer sb;
+ static void PaintChannelFrom16(channel_t ch, sfxcache_t sc, int count, int offset)
+ {
+ int data;
+ int left, right;
+ int leftvol, rightvol;
+ int sfx;
+ int i;
+ portable_samplepair_t samp;
+
+ leftvol = ch.leftvol*snd_vol;
+ rightvol = ch.rightvol*snd_vol;
+ ByteBuffer bb = ByteBuffer.wrap(sc.data);
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+ sb = bb.asShortBuffer();
+ sfx = ch.pos;
+
+ //samp = paintbuffer[offset];
+ for (i=0 ; i<count ; i++, offset++)
+ {
+ left = paintbuffer.get(offset*2);
+ right = paintbuffer.get(offset*2+1);
+ data = sb.get(sfx+i);
+ left += (data * leftvol)>>8;
+ right += (data * rightvol)>>8;
+ paintbuffer.put(offset*2, left);
+ paintbuffer.put(offset*2+1, right);
+ }
+
+ ch.pos += count;
+ }
+
+} \ No newline at end of file
diff --git a/src/jake2/sys/NET.java b/src/jake2/sys/NET.java
index 19a3a59..50f7ceb 100644
--- a/src/jake2/sys/NET.java
+++ b/src/jake2/sys/NET.java
@@ -2,7 +2,7 @@
* NET.java
* Copyright (C) 2003
*
- * $Id: NET.java,v 1.1 2004-07-07 19:59:51 hzi Exp $
+ * $Id: NET.java,v 1.2 2004-07-09 06:50:47 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -686,8 +686,8 @@ public final class NET extends Defines {
====================
*/
public static String NET_ErrorString() {
+
int code;
-
//code = errno;
//return strerror (code);
return "errno can not yet resolved in java";
@@ -700,7 +700,7 @@ public final class NET extends Defines {
return; // we're not a server, just run full speed
try {
- //TODO: check for
+ //TODO: check for timeout
Thread.sleep(msec);
}
catch (InterruptedException e) {
diff --git a/src/jake2/sys/Sys.java b/src/jake2/sys/Sys.java
index 8a08956..b65098c 100644
--- a/src/jake2/sys/Sys.java
+++ b/src/jake2/sys/Sys.java
@@ -2,7 +2,7 @@
* Sys.java
* Copyright (C) 2003
*
- * $Id: Sys.java,v 1.3 2004-07-08 20:24:30 hzi Exp $
+ * $Id: Sys.java,v 1.4 2004-07-09 06:50:47 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -44,14 +44,6 @@ import jake2.util.Lib;
*/
public final class Sys extends Defines {
- public static void StackTrace() {
-
- StackTraceElement trace[] = new Throwable().getStackTrace();
- Com.Println("StackTrace:");
- for (int i = 0; i < trace.length; i++)
- Com.Println("" + trace[i]);
- }
-
public static void Error(String error) {
CL.Shutdown();
@@ -259,11 +251,6 @@ public final class Sys extends Defines {
Globals.sys_frame_time = Sys.Milliseconds();
}
- public static game_export_t GetGameAPI(game_import_t gimport)
- {
- return Game.GetGameApi(gimport);
- }
-
public static String GetClipboardData() {
// TODO: implement GetClipboardData
return null;
diff --git a/src/jake2/util/Lib.java b/src/jake2/util/Lib.java
index bab5ff0..8a965ab 100644
--- a/src/jake2/util/Lib.java
+++ b/src/jake2/util/Lib.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 09.12.2003 by RST.
-// $Id: Lib.java,v 1.2 2004-07-08 15:58:48 hzi Exp $
+// $Id: Lib.java,v 1.3 2004-07-09 06:50:51 hzi Exp $
package jake2.util;
@@ -28,37 +28,17 @@ import jake2.qcommon.Com;
import jake2.qcommon.FS;
import java.io.*;
+import java.nio.*;
import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
import java.util.Arrays;
import java.util.StringTokenizer;
-public class Lib {
-
- /*
- =============
- TempVector
-
- This is just a convenience function
- for making temporary vectors for function calls
- =============
- */
- public static float tv_vecs[][] = new float[8][3];
- public static int tv_index;
- public static float[] tv(float x, float y, float z) {
+import net.java.games.jogl.util.BufferUtils;
- float[] v;
-
- // use an array so that multiple tempvectors won't collide
- // for a while
- v = tv_vecs[tv_index];
- tv_index = (tv_index++) & 7;
+public class Lib {
- v[0] = x;
- v[1] = y;
- v[2] = z;
- return v;
- }
/*
=============
VectorToString
@@ -92,9 +72,6 @@ public class Lib {
public static float crand() {
return (Globals.rnd.nextFloat() - 0.5f) * 2.0f;
}
- public static float frand() {
- return Globals.rnd.nextFloat();
- }
public static int strcmp(String in1, String in2) {
return in1.compareTo(in2);
@@ -108,25 +85,6 @@ public class Lib {
return (i1.indexOf(i2) != -1);
}
- public static int strncmp(String in1, String in2, int len) {
- int i1 = Math.min(len, in1.length());
- int i2 = Math.min(len, in2.length());
-
- if (i1 < i2)
- return -1;
- if (i1 > i2)
- return 1;
-
- for (int n = 0; n < i1; n++) {
- char c1 = in1.charAt(n);
- char c2 = in2.charAt(n);
- if (c1 < c2)
- return -1;
- if (c1 > c2)
- return 1;
- }
- return 0;
- }
public static float atof(String in) {
float res = 0;
@@ -189,17 +147,6 @@ public class Lib {
in += i;
}
- public static void strcpy(char dest[], char src[]) {
- for (int i = 0; i < dest.length && i < src.length; i++)
- if (src[i] == 0) {
- dest[i] = 0;
- return;
- }
- else
- dest[i] = src[i];
-
- }
-
public static void strcpy(byte dest[], byte src[]) {
for (int i = 0; i < dest.length && i < src.length; i++)
if (src[i] == 0) {
@@ -385,33 +332,6 @@ public class Lib {
return result;
}
- public static void main(String[] args) {
- System.out.println("testing Lib...");
-
- String linetest = "line 1\r\n line zwo\nline drei\n\r line4\n.line5";
-
- String line[] = linesplit(linetest);
-
- for (int n = 0; n < line.length; n++) {
- System.out.println("[" + line[n] + "]");
- }
-
- String v = "0.234 1.23423 7.23423";
-
- int i1 = v.indexOf(" ");
- int i2 = v.indexOf(" ", i1 + 1);
-
- System.out.println("testing substring...");
-
- System.out.println("[" + v.substring(0, i1) + "]");
- System.out.println("[" + v.substring(i1 + 1, i2) + "]");
- System.out.println("[" + v.substring(i2 + 1, v.length()) + "]");
-
- System.out.println("rightfrom[" + rightFrom("abcdefg#hijklm", '#') + "]");
- System.out.println("leftfrom[" + leftFrom("abcdefghijk#12", '#') + "]");
- System.out.println("leftfrom[" + leftFrom("abcdefghi", '#') + "]");
- }
-
public static int rename(String oldn, String newn) {
try {
File f1 = new File(oldn);
@@ -436,23 +356,6 @@ public class Lib {
public static int getInt(byte b[]) {
return (b[0] & 0xff) | ((b[1] & 0xff) << 8) | ((b[2] & 0xff) << 16) | ((b[3] & 0xff) << 24);
}
-
- public static void sleep(int sec) {
- try {
- Thread.sleep(sec * 1000);
- }
- catch (InterruptedException e) {
- }
- }
-
- public static byte[] clone(byte in[]) {
- byte out[] = new byte[in.length];
-
- if (in.length != 0)
- System.arraycopy(in, 0, out, 0, in.length);
-
- return out;
- }
public static float[] clone(float in[]) {
float out[] = new float[in.length];
@@ -463,15 +366,6 @@ public class Lib {
return out;
}
- public static short[] clone(short in[]) {
- short out[] = new short[in.length];
-
- if (in.length != 0)
- System.arraycopy(in, 0, out, 0, in.length);
-
- return out;
- }
-
public static long[] clone(long in[]) {
long out[] = new long[in.length];
@@ -516,4 +410,44 @@ public class Lib {
return out;
}
+
+ /*
+ * java.nio.* Buffer util functions
+ */
+
+ public static final int SIZEOF_FLOAT = BufferUtils.SIZEOF_FLOAT;
+ public static final int SIZEOF_INT = BufferUtils.SIZEOF_INT;
+
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ public static FloatBuffer newFloatBuffer(int numElements, ByteOrder order) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT, order);
+ return bb.asFloatBuffer();
+ }
+
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ public static IntBuffer newIntBuffer(int numElements, ByteOrder order) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT, order);
+ return bb.asIntBuffer();
+ }
+
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ bb.order(ByteOrder.nativeOrder());
+ return bb;
+ }
+
+ public static ByteBuffer newByteBuffer(int numElements, ByteOrder order) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ bb.order(order);
+ return bb;
+ }
+
}
diff --git a/test/AdapterRegister.java b/test/AdapterRegister.java
new file mode 100644
index 0000000..5e56c0b
--- /dev/null
+++ b/test/AdapterRegister.java
@@ -0,0 +1,104 @@
+/*
+Copyright (C) 1997-2001 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.
+
+*/
+
+// Created on 08.01.2004 by RST.
+// $Id: AdapterRegister.java,v 1.1 2004-07-09 06:50:51 hzi Exp $
+// $Log: AdapterRegister.java,v $
+// Revision 1.1 2004-07-09 06:50:51 hzi
+// import of Jake2
+//
+// Revision 1.1 2004/02/25 21:30:15 hoz
+// *** empty log message ***
+//
+// Revision 1.2 2004/02/02 22:19:17 rst
+// cosmetic
+//
+// Revision 1.1 2004/02/02 22:16:05 rst
+// cosmetic
+//
+// Revision 1.2 2004/01/09 18:30:57 rst
+// Superadapter replaces function pointers in save games.
+//
+// Revision 1.1 2004/01/08 23:56:43 rst
+// some preisfrage
+//
+
+// import jake2.*;
+// import jake2.client.*;
+// import jake2.game.*;
+// import jake2.qcommon.*;
+// import jake2.render.*;
+// import jake2.server.*;
+
+public class AdapterRegister {
+
+ // concept for adapter indexing for function pointers
+
+
+ // the counter
+ static int id =0;
+
+ static class t0
+ {
+ // the identificator
+ public int myid = id++;
+
+ public String test()
+ {
+ return ("t0, id = " + myid);
+ }
+
+ };
+ // any stupid adapter
+ static class t1 extends t0
+ {
+ public String test()
+ {
+ return ("t1, id = " + myid);
+ }
+ };
+ // second adapter
+ static class t2 extends t0
+ {
+ public String test(int x)
+ {
+ return ("t2, id = " + myid);
+ }
+ }
+
+
+ // an auto test client
+ public static void main(String[] args) {
+
+ // program starts
+ System.out.println("hello world.");
+
+ t1 t1 = new t1();
+ t2 t2 = new t2();
+ t2 t3 = new t2();
+ System.out.println(t1.test());
+ System.out.println(t2.test());
+ System.out.println(t2.test(5));
+ System.out.println(t3.test(5));
+
+ System.out.println("good bye world.");
+ // program ends
+ }
+}
diff --git a/test/ConvertDefines.java b/test/ConvertDefines.java
new file mode 100644
index 0000000..9a411a3
--- /dev/null
+++ b/test/ConvertDefines.java
@@ -0,0 +1,138 @@
+import java.io.*;
+import java.util.StringTokenizer;
+
+
+/** This class converts the #define statements into java
+ * public static final int statements.
+ *
+ * Additionally it converts some mframe_t statements, when the filename
+ * starts with "jake2/game/M_" .
+ */
+
+public class ConvertDefines
+{
+ public static String convertDefine(String in)
+ {
+ StringBuffer out= new StringBuffer();
+
+ StringTokenizer tk= new StringTokenizer(in);
+ while (tk.hasMoreElements())
+ {
+ String token= tk.nextToken();
+
+ // finds the define
+ if (token.equals("#define"))
+ {
+ out.append(" public final static int ");
+ out.append(tk.nextToken());
+ out.append("= ");
+ out.append(tk.nextToken());
+ out.append(";\t");
+
+ // append rest and out.
+ while (tk.hasMoreElements())
+ {
+ out.append(tk.nextToken());
+ out.append(" ");
+ }
+ }
+ else
+ {
+ out.append(token);
+ out.append(" ");
+ }
+ }
+ return out.toString();
+ }
+
+ /********************************************/
+ public static void main(String args[])
+ {
+ try
+ {
+
+ System.out.println("\n".trim().length());
+ String line;
+ String filename;
+ boolean m_doc = true;
+
+ if (args.length == 0)
+ {
+ filename= "jake2/Defines.java";
+ }
+ else
+ filename= args[0];
+
+ if (filename.startsWith("jake2/game/M_"))
+ m_doc = true;
+ else m_doc = false;
+
+ FileWriter fw= new FileWriter(filename + ".new");
+ FileReader fr= new FileReader(filename);
+ BufferedReader br= new BufferedReader(fr);
+
+ while (br.ready())
+ {
+ line= br.readLine();
+ if (line.indexOf("#define") != -1)
+ fw.write(convertDefine(line) + "\n");
+
+
+ else if (m_doc && line.trim().startsWith("mframe_t ") && line.indexOf("new") == -1)
+ {
+ fw.write(" static " + line + " new mframe_t[] \n");
+ while (br.ready())
+ {
+ line= br.readLine();
+ // opening brace
+
+ if (line.indexOf("{")!=-1)
+ fw.write(line + "\n");
+ // opening brace
+ else if (line.indexOf("}")!=-1)
+ {
+ fw.write(line + "\n");
+ break;
+
+ }
+ else if (line.trim().length()==0)
+ fw.write("\n");
+ else
+ {
+ String comma ="";
+ String line1 = line;
+
+ if (line.endsWith(","))
+ {
+ line1=line.substring(0,line1.length()-1);
+ comma = ",";
+ }
+ fw.write("\tnew mframe_t (" + line1 + ")" + comma + "\n");
+ }
+ }
+ }
+ else if (m_doc && line.trim().startsWith("mmove_t"))
+ {
+ int pos1 = line.indexOf("{");
+ int pos2 = line.indexOf("}");
+ String seg1 = line.substring(0,pos1);
+ String seg2 = line.substring(pos1+1, pos2);
+ String seg3 = line.substring(pos2+1, line.length());
+ fw.write("static " + seg1 + " new mmove_t (" + seg2 + ")" + seg3 + "\n\n");
+ //fw.write(line);
+ }
+ else
+ fw.write(line + "\n");
+ }
+ fr.close();
+ fw.close();
+
+ //System.out.println(convertDefine("#define IT_WEAPON 1 // use makes active weapon"));
+ //System.out.println(convertDefine("#define IT_AMMO 2"));
+ }
+ catch (Exception e)
+ {
+ System.err.println("Exception:" + e);
+ }
+ }
+}
diff --git a/test/Unpack.java b/test/Unpack.java
new file mode 100644
index 0000000..dc302ea
--- /dev/null
+++ b/test/Unpack.java
@@ -0,0 +1,202 @@
+/*
+ * Unpack -- a completely non-object oriented utility...
+ *
+ */
+
+import java.io.*;
+
+class Unpack
+{
+ static final int IDPAKHEADER= (('K' << 24) + ('C' << 16) + ('A' << 8) + 'P');
+
+ static int intSwap(int i)
+ {
+ int a, b, c, d;
+
+ a= i & 255;
+ b= (i >> 8) & 255;
+ c= (i >> 16) & 255;
+ d= (i >> 24) & 255;
+
+ return (a << 24) + (b << 16) + (c << 8) + d;
+ }
+
+ static boolean patternMatch(String pattern, String s)
+ {
+ int index;
+ int remaining;
+
+ if (pattern.equals(s))
+ {
+ return true;
+ }
+
+ // fairly lame single wildcard matching
+ index= pattern.indexOf('*');
+ if (index == -1)
+ {
+ return false;
+ }
+ if (!pattern.regionMatches(0, s, 0, index))
+ {
+ return false;
+ }
+
+ index += 1; // skip the *
+ remaining= pattern.length() - index;
+ if (s.length() < remaining)
+ {
+ return false;
+ }
+
+ if (!pattern.regionMatches(index, s, s.length() - remaining, remaining))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ static void usage()
+ {
+ System.out.println("Usage: unpack <packfile> <match> <basedir>");
+ System.out.println(" or: unpack -list <packfile>");
+ System.out.println("<match> may contain a single * wildcard");
+ System.exit(1);
+ }
+
+ public static void main(String[] args)
+ {
+ int ident;
+ int dirofs;
+ int dirlen;
+ int i;
+ int numLumps;
+ byte[] name= new byte[56];
+ String nameString;
+ int filepos;
+ int filelen;
+ RandomAccessFile readLump;
+ DataInputStream directory;
+ String pakName;
+ String pattern;
+
+ if (args.length == 2)
+ {
+ if (!args[0].equals("-list"))
+ {
+ usage();
+ }
+ pakName= args[1];
+ pattern= null;
+ }
+ else if (args.length == 3)
+ {
+ pakName= args[0];
+ pattern= args[1];
+ }
+ else
+ {
+ pakName= null;
+ pattern= null;
+ usage();
+ }
+
+ try
+ {
+ // one stream to read the directory
+ directory= new DataInputStream(new FileInputStream(pakName));
+
+ // another to read lumps
+ readLump= new RandomAccessFile(pakName, "r");
+
+ // read the header
+ ident= intSwap(directory.readInt());
+ dirofs= intSwap(directory.readInt());
+ dirlen= intSwap(directory.readInt());
+
+ if (ident != IDPAKHEADER)
+ {
+ System.out.println(pakName + " is not a pakfile.");
+ System.exit(1);
+ }
+
+ // read the directory
+ directory.skipBytes(dirofs - 12);
+ numLumps= dirlen / 64;
+
+ System.out.println(numLumps + " lumps in " + pakName);
+
+ for (i= 0; i < numLumps; i++)
+ {
+ directory.readFully(name);
+ filepos= intSwap(directory.readInt());
+ filelen= intSwap(directory.readInt());
+
+ nameString= new String(name);
+ // chop to the first 0 byte
+ nameString= nameString.substring(0, nameString.indexOf(0));
+
+ if (pattern == null)
+ {
+ // listing mode
+ System.out.println(nameString + " : " + filelen + "bytes");
+ }
+ else if (patternMatch(pattern, nameString))
+ {
+ File writeFile;
+ DataOutputStream writeLump;
+ byte[] buffer= new byte[filelen];
+ StringBuffer fixedString;
+ String finalName;
+ int index;
+
+ System.out.println("Unpaking " + nameString + " " + filelen + " bytes");
+
+ // load the lump
+ readLump.seek(filepos);
+ readLump.readFully(buffer);
+
+ // quake uses forward slashes, but java requires
+ // they only by the host's seperator, which
+ // varies from win to unix
+ fixedString= new StringBuffer(args[2] + File.separator + nameString);
+ for (index= 0; index < fixedString.length(); index++)
+ {
+ if (fixedString.charAt(index) == '/')
+ {
+ fixedString.setCharAt(index, File.separatorChar);
+ }
+ }
+ finalName= fixedString.toString();
+
+ index= finalName.lastIndexOf(File.separatorChar);
+ if (index != -1)
+ {
+ String finalPath;
+ File writePath;
+
+ finalPath= finalName.substring(0, index);
+ writePath= new File(finalPath);
+ writePath.mkdirs();
+ }
+
+ writeFile= new File(finalName);
+ writeLump= new DataOutputStream(new FileOutputStream(writeFile));
+ writeLump.write(buffer);
+ writeLump.close();
+
+ }
+ }
+
+ readLump.close();
+ directory.close();
+
+ }
+ catch (IOException e)
+ {
+ System.out.println(e.toString());
+ }
+ }
+
+}
diff --git a/test/jake2/imageio/TestImage.java b/test/jake2/imageio/TestImage.java
deleted file mode 100644
index 4290359..0000000
--- a/test/jake2/imageio/TestImage.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Created on Nov 17, 2003
- *
- */
-package jake2.imageio;
-
-import java.awt.geom.AffineTransform;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.imageio.*;
-
-/**
- * @author cwei
- *
- */
-public class TestImage {
-
- static final String TEST_FILE = "pics/colormap.pcx";
- static final long PAUSE = 15; // ms
- static final int ENTRIES = 2501;
-
- File pakPath;
- List imageFiles;
-
- TestImage(File pakPath) {
- this.pakPath = pakPath;
- this.imageFiles = new ArrayList(ENTRIES);
- }
-
- public static void main(String[] args) throws Exception {
-
-
- if (args == null || args.length == 0) {
- usage();
- }
-
- File path = new File(args[0]);
-
- if (!path.isDirectory()) {
- System.err.println(path.toString() + " is not a directory");
- usage();
- }
-
- if (!new File(path.getPath() + "/" + TEST_FILE).canRead()) {
- System.err.println(
- path.getPath() + " is not a unpacked quake2-pak file location");
- usage();
- }
-
- System.out.println("*** Start Image test ***\n");
-
- ImageIO.scanForPlugins();
-
- TestImage test = new TestImage(path);
- test.run();
-
- System.gc();
- Runtime rt = Runtime.getRuntime();
- System.out.println(
- "JVM total memory: " + rt.totalMemory() / 1024 + " Kbytes\n");
-
- System.out.println("*** Image test is succeeded :-) ***\n");
- }
-
- static void usage() {
- System.out.println(
- "usage: TestImage <path to unpacked quake2-pak file>");
- System.exit(0);
- }
-
- void run() {
-
- System.out.println("begin directory scanning ...");
- scanDirectory(pakPath);
- System.out.println(imageFiles.size() + " graphic files found\n");
-
- ImageFrame frame = new ImageFrame(null);
- frame.setVisible(true);
-
- File f = null;
- BufferedImage image = null;
-
- for (Iterator it = imageFiles.iterator(); it.hasNext();) {
- f = (File) it.next();
- try {
- image = scale(ImageIO.read(f));
- frame.showImage(image);
- frame.setTitle(f.getPath());
-
- Thread.sleep(PAUSE);
-
- } catch (IOException e) {
- System.err.println(e.getMessage());
- } catch (InterruptedException e) {
- }
- }
- frame.dispose();
- imageFiles.clear();
- }
-
- void scanDirectory(File dir) {
- File[] files = dir.listFiles(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- /* matches *.pcx or *.wal files */
- return name.matches(".*(pcx|wal)$");
- }
- });
-
- if (files != null && files.length > 0) {
- imageFiles.addAll(Arrays.asList(files));
- }
-
- File[] dirs = dir.listFiles(new FileFilter() {
- public boolean accept(File pathname) {
- return pathname.isDirectory();
- }
- });
-
- if (dirs != null && dirs.length > 0) {
- for (int i = 0; i < dirs.length; i++) {
- System.out.println(dirs[i]);
- // recursive directory scanning
- scanDirectory(dirs[i]);
- }
- }
- }
-
- BufferedImage scale(BufferedImage src) {
- BufferedImage dst = null;
-
- int size = Math.max(src.getHeight(), src.getWidth());
-
- double scale = 1.5;
-
- if (size < 50) {
- scale = 4.0;
- } else if (size < 200) {
- scale = 2.5;
- } else if (size > 400) {
- scale = 1.5;
- }
- BufferedImageOp op =
- new AffineTransformOp(
- AffineTransform.getScaleInstance(scale, scale),
- AffineTransformOp.TYPE_NEAREST_NEIGHBOR/*TYPE_BILINEAR*/);
- dst = op.filter(src, null);
-
- return (dst != null) ? dst : src;
- }
-}
diff --git a/test/jake2/qcommon/TestCMD.java b/test/jake2/qcommon/TestCMD.java
index 140f075..3316fd7 100644
--- a/test/jake2/qcommon/TestCMD.java
+++ b/test/jake2/qcommon/TestCMD.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 29.12.2003 by RST.
-// $Id: TestCMD.java,v 1.1 2004-07-07 19:59:56 hzi Exp $
+// $Id: TestCMD.java,v 1.2 2004-07-09 06:50:51 hzi Exp $
package jake2.qcommon;
@@ -49,7 +49,6 @@ public class TestCMD {
}
}
catch (Exception e) {
- // TODO: handle exception
e.printStackTrace();
}
}
diff --git a/test/jake2/qcommon/TestFS.java b/test/jake2/qcommon/TestFS.java
deleted file mode 100644
index f46f43f..0000000
--- a/test/jake2/qcommon/TestFS.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * TestFS.java
- * Copyright (C) 2003
- *
- * $Id: TestFS.java,v 1.1 2004-07-07 19:59:56 hzi Exp $
- */
-/*
-Copyright (C) 1997-2001 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.
-
-*/
-package jake2.qcommon;
-
-import jake2.game.Cmd;
-import jake2.imageio.ImageFrame;
-
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.TreeSet;
-import java.util.logging.*;
-
-import javax.imageio.ImageIO;
-import javax.imageio.stream.MemoryCacheImageInputStream;
-
-/**
- * TestFS
- *
- * @author cwei
- */
-public class TestFS {
-
- public static void main(String[] args) {
- System.out.println("*** Start FS test ***\n");
-
- init();
-
- FS.InitFilesystem();
-
- Cmd.ExecuteString("link unknown.pcx ../../baseq2/space.pcx");
- Cmd.ExecuteString("link unknown1.pcx ../../baseq2/config.cfg");
-
- FS.Path_f();
-
- // loescht den link
- Cmd.ExecuteString("link unknown1.pcx");
-
- FS.Path_f();
-
- Cmd.ExecuteString("dir players/male/*.[a-zA-Z_0-9]?x");
-
- // search for pack_t
- FS.searchpath_t search;
- Collection filenames = new TreeSet();
- for (search = FS.fs_searchpaths; search != null; search = search.next) {
- // is the element a pak file?
- if (search.pack != null) {
- // add all the pak file names
- filenames.addAll(search.pack.files.keySet());
- }
- }
-
- ImageFrame frame = new ImageFrame(null);
- frame.setVisible(true);
- byte[] buffer = null;
-
- BufferedImage image = null;
- for (Iterator it = filenames.iterator(); it.hasNext();) {
-
- String filename = it.next().toString();
- if (!filename.endsWith(".wal") && !filename.endsWith(".pcx")) continue;
-
- buffer = FS.LoadFile(filename);
-
- if (buffer != null) {
- try {
- image =
- ImageIO.read(
- new MemoryCacheImageInputStream(
- new ByteArrayInputStream(buffer)));
-
- frame.showImage(image);
- frame.setTitle(filename);
-
- Thread.sleep(15);
-
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e1) {
- }
- }
- }
- frame.dispose();
-
- System.gc();
- Runtime rt = Runtime.getRuntime();
- System.out.println(
- "\nJVM total memory: " + rt.totalMemory() / 1024 + " Kbytes");
-
- System.out.println("\n*** FS test is succeeded :-) ***");
- }
-
- static void init() {
- // init the global LogManager with the logging.properties file
- try {
- LogManager.getLogManager().readConfiguration(
- TestFS.class.getResourceAsStream("/jake2/logging.properties"));
- } catch (SecurityException secEx) {
- secEx.printStackTrace();
- } catch (IOException ioEx) {
- System.err.println(
- "FATAL Error: can't load /jake2/logging.properties (classpath)");
- ioEx.printStackTrace();
- }
- }
-}
diff --git a/test/jake2/qcommon/TestLoadMap.java b/test/jake2/qcommon/TestLoadMap.java
index 3410ca2..bc3efca 100644
--- a/test/jake2/qcommon/TestLoadMap.java
+++ b/test/jake2/qcommon/TestLoadMap.java
@@ -19,24 +19,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 02.01.2004 by RST.
-// $Id: TestLoadMap.java,v 1.1 2004-07-07 19:59:56 hzi Exp $
+// $Id: TestLoadMap.java,v 1.2 2004-07-09 06:50:51 hzi Exp $
package jake2.qcommon;
-
-// import jake2.*;
-// import jake2.client.*;
-// import jake2.game.*;
-// import jake2.qcommon.*;
-// import jake2.render.*;
-// import jake2.server.*;
-
public class TestLoadMap {
public static void main(String[] args) {
Com.DPrintf("hello!\n");
FS.InitFilesystem();
- CM.CM_LoadMap("maps/base1.bsp", true, new CM.intwrap(0));
+ CM.CM_LoadMap("maps/base1.bsp", true, new int[]{0});
}
}
diff --git a/test/jake2/qcommon/TestMD4.java b/test/jake2/qcommon/TestMD4.java
index 9b86058..5a0d84a 100644
--- a/test/jake2/qcommon/TestMD4.java
+++ b/test/jake2/qcommon/TestMD4.java
@@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Created on 02.02.2004 by RST.
-// $Id: TestMD4.java,v 1.1 2004-07-07 19:59:57 hzi Exp $
+// $Id: TestMD4.java,v 1.2 2004-07-09 06:50:51 hzi Exp $
package jake2.qcommon;
@@ -1133,6 +1133,35 @@ public class TestMD4 {
test("abc");
test("abcdefghijklmnopqrstuvwxyz");
test("hi");
+ MD4 md4 = new MD4();
+
+ byte data[]=
+ {
+ (byte) 0x71,
+ (byte) 0xa9,
+ (byte) 0x05,
+ (byte) 0xce,
+ (byte) 0x8d,
+ (byte) 0x75,
+ (byte) 0x28,
+ (byte) 0xc8,
+ (byte) 0xba,
+ (byte) 0x97,
+
+ (byte) 0x45,
+ (byte) 0xe9,
+ (byte) 0x8a,
+ (byte) 0xe0,
+ (byte) 0x37,
+ (byte) 0xbd,
+ (byte) 0x6c,
+ (byte) 0x6d,
+ (byte) 0x67,
+ (byte) 0x4a,
+ (byte) 0x21 };
+
+ System.out.println("checksum=" + MD4.Com_BlockChecksum(data, 21));
+
}
public static void test(String s) {
diff --git a/test/jake2/qcommon/TestTGA.java b/test/jake2/qcommon/TestTGA.java
deleted file mode 100644
index 32d45cd..0000000
--- a/test/jake2/qcommon/TestTGA.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * TestTGA.java
- * Copyright (C) 2003
- *
- * $Id: TestTGA.java,v 1.1 2004-07-08 20:24:31 hzi Exp $
- */
-/*
-Copyright (C) 1997-2001 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.
-
-*/
-package jake2.qcommon;
-
-import jake2.game.Cmd;
-import jake2.imageio.ImageFrame;
-
-import java.awt.Dimension;
-import java.awt.geom.AffineTransform;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.TreeSet;
-import java.util.logging.*;
-
-import javax.imageio.stream.MemoryCacheImageInputStream;
-
-
-
-/**
- * TestTGA
- *
- * @author cwei
- */
-public class TestTGA {
-
- public static void main(String[] args) {
- System.out.println("*** Start TGA test ***\n");
-
- init();
-
- FS.InitFilesystem();
-
- // search for pack_t
- FS.searchpath_t search;
- Collection filenames = new TreeSet();
- for (search = FS.fs_searchpaths; search != null; search = search.next) {
- // is the element a pak file?
- if (search.pack != null) {
- // add all the pak file names
- filenames.addAll(search.pack.files.keySet());
- }
- }
-
- ImageFrame frame = new ImageFrame(null);
- frame.setVisible(true);
- frame.setLocation(50, 50);
- frame.setSize(800, 800);
-
- byte[] buffer = null;
- Dimension dim = new Dimension();
- BufferedImage image = null;
-
- int[] pixel = new int[512 * 512];
-
-
- for (Iterator it = filenames.iterator(); it.hasNext();) {
-
- String filename = it.next().toString();
- if (!filename.endsWith(".tga")) continue;
-
- System.out.println(filename);
- buffer = LoadTGA(filename, dim);
-
- if (buffer != null) {
- try {
-
- int w = dim.width;
- int h = dim.height;
- int size = w * h;
-
- int r, g, b, a;
-
- for (int i = 0; i < size; i++)
- {
- r = buffer[4* i + 0] & 0xFF;
- g = buffer[4* i + 1] & 0xFF;
- b = buffer[4* i + 2] & 0xFF;
- a = buffer[4* i +3] & 0xFF;
-
- pixel[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0);
- }
-
- image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
- image.setRGB(0, 0, w, h, pixel, 0, w);
-
- AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(3, 3), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
- BufferedImage tmp = op.filter(image, null);
-
- frame.showImage(tmp);
- frame.setTitle(filename);
-
- Thread.sleep(500);
-
- } catch (InterruptedException e) {
- }
- }
- }
- frame.dispose();
-
- System.gc();
- Runtime rt = Runtime.getRuntime();
- System.out.println(
- "\nJVM total memory: " + rt.totalMemory() / 1024 + " Kbytes");
-
- System.out.println("\n*** TGA test is succeeded :-) ***");
- }
-
- static void init() {
- // init the global LogManager with the logging.properties file
- try {
- LogManager.getLogManager().readConfiguration(
- TestFS.class.getResourceAsStream("/jake2/logging.properties"));
- } catch (SecurityException secEx) {
- secEx.printStackTrace();
- } catch (IOException ioEx) {
- System.err.println(
- "FATAL Error: can't load /jake2/logging.properties (classpath)");
- ioEx.printStackTrace();
- }
- }
-
- /*
- =============
- LoadTGA
- =============
- */
- static byte[] LoadTGA(String name, Dimension dim) {
- int columns, rows, numPixels;
- int pixbuf; // index into pic
- int row, column;
- byte[] raw;
- ByteBuffer buf_p;
- int length;
- qfiles.tga_t targa_header;
- byte[] pic = null;
-
- //
- // load the file
- //
- raw = FS.LoadFile(name);
-
- if (raw == null)
- {
- System.out.println("Bad tga file "+ name +'\n');
- return null;
- }
-
- targa_header = new qfiles.tga_t(raw);
-
- if (targa_header.image_type != 2 && targa_header.image_type != 10)
- System.out.println("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
-
- if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
- System.out.println("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
-
- columns = targa_header.width;
- rows = targa_header.height;
- numPixels = columns * rows;
-
- if (dim != null) {
- dim.width = columns;
- dim.height = rows;
- }
-
- pic = new byte[numPixels * 4]; // targa_rgba;
-
- if (targa_header.id_length != 0)
- targa_header.data.position(targa_header.id_length); // skip TARGA image comment
-
- buf_p = targa_header.data;
-
- byte red,green,blue,alphabyte;
- red = green = blue = alphabyte = 0;
- int packetHeader, packetSize, j;
-
- if (targa_header.image_type==2) { // Uncompressed, RGB images
- for(row=rows-1; row>=0; row--) {
-
- pixbuf = row * columns * 4;
-
- for(column=0; column<columns; column++) {
- switch (targa_header.pixel_size) {
- case 24:
-
- blue = buf_p.get();
- green = buf_p.get();
- red = buf_p.get();
- pic[pixbuf++] = red;
- pic[pixbuf++] = green;
- pic[pixbuf++] = blue;
- pic[pixbuf++] = (byte)255;
- break;
- case 32:
- blue = buf_p.get();
- green = buf_p.get();
- red = buf_p.get();
- alphabyte = buf_p.get();
- pic[pixbuf++] = red;
- pic[pixbuf++] = green;
- pic[pixbuf++] = blue;
- pic[pixbuf++] = alphabyte;
- break;
- }
- }
- }
- }
- else if (targa_header.image_type==10) { // Runlength encoded RGB images
- for(row=rows-1; row>=0; row--) {
-
- pixbuf = row * columns * 4;
- try {
-
- for(column=0; column<columns; ) {
-
- packetHeader= buf_p.get() & 0xFF;
- packetSize = 1 + (packetHeader & 0x7f);
-
- if ((packetHeader & 0x80) != 0) { // run-length packet
- switch (targa_header.pixel_size) {
- case 24:
- blue = buf_p.get();
- green = buf_p.get();
- red = buf_p.get();
- alphabyte = (byte)255;
- break;
- case 32:
- blue = buf_p.get();
- green = buf_p.get();
- red = buf_p.get();
- alphabyte = buf_p.get();
- break;
- }
-
- for(j=0;j<packetSize;j++) {
- pic[pixbuf++]=red;
- pic[pixbuf++]=green;
- pic[pixbuf++]=blue;
- pic[pixbuf++]=alphabyte;
- column++;
- if (column==columns) { // run spans across rows
- column=0;
- if (row>0)
- row--;
- else
- // goto label breakOut;
- throw new longjmpException();
-
- pixbuf = row * columns * 4;
- }
- }
- }
- else { // non run-length packet
- for(j=0;j<packetSize;j++) {
- switch (targa_header.pixel_size) {
- case 24:
- blue = buf_p.get();
- green = buf_p.get();
- red = buf_p.get();
- pic[pixbuf++] = red;
- pic[pixbuf++] = green;
- pic[pixbuf++] = blue;
- pic[pixbuf++] = (byte)255;
- break;
- case 32:
- blue = buf_p.get();
- green = buf_p.get();
- red = buf_p.get();
- alphabyte = buf_p.get();
- pic[pixbuf++] = red;
- pic[pixbuf++] = green;
- pic[pixbuf++] = blue;
- pic[pixbuf++] = alphabyte;
- break;
- }
- column++;
- if (column==columns) { // pixel packet run spans across rows
- column=0;
- if (row>0)
- row--;
- else
- // goto label breakOut;
- throw new longjmpException();
-
- pixbuf = row * columns * 4;
- }
- }
- }
- }
- } catch (longjmpException e){
- // label breakOut:
- }
- }
- }
- return pic;
- }
-
-}
diff --git a/test/jake2/render/DancingQueens.java b/test/jake2/render/DancingQueens.java
index d7d2ea4..db4200c 100644
--- a/test/jake2/render/DancingQueens.java
+++ b/test/jake2/render/DancingQueens.java
@@ -2,7 +2,7 @@
* DancingQueens.java
* Copyright (C) 2003
*
- * $Id: DancingQueens.java,v 1.2 2004-07-08 20:24:31 hzi Exp $
+ * $Id: DancingQueens.java,v 1.3 2004-07-09 06:50:51 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -152,14 +152,14 @@ public class DancingQueens
};
- Qcommon.InitForTestMap(new String[] {"DancingQueens"});
+ Qcommon.Init(new String[] {"DancingQueens"});
// sehr wichtig !!!
VID.Shutdown();
String[] names = Renderer.getDriverNames();
System.out.println("Registered Drivers: " + Arrays.asList(names));
- this.re = Renderer.getDriver("jogl", ri);
+ this.re = Renderer.getDriver("fastjogl", ri);
System.out.println("Use driver: " + re);
System.out.println();
diff --git a/test/jake2/render/TestMap.java b/test/jake2/render/TestMap.java
index 711b159..e6670dc 100644
--- a/test/jake2/render/TestMap.java
+++ b/test/jake2/render/TestMap.java
@@ -2,7 +2,7 @@
* TestMap.java
* Copyright (C) 2003
*
- * $Id: TestMap.java,v 1.2 2004-07-08 20:24:31 hzi Exp $
+ * $Id: TestMap.java,v 1.3 2004-07-09 06:50:51 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -36,6 +36,7 @@ import jake2.sys.KBD;
import jake2.util.*;
import java.awt.Dimension;
+import java.nio.FloatBuffer;
import java.util.*;
/**
@@ -177,7 +178,7 @@ public class TestMap
}
};
- Qcommon.InitForTestMap(new String[] { "TestMap $Id: TestMap.java,v 1.2 2004-07-08 20:24:31 hzi Exp $" });
+ Qcommon.Init(new String[] { "TestMap $Id: TestMap.java,v 1.3 2004-07-09 06:50:51 hzi Exp $" });
// sehr wichtig !!!
VID.Shutdown();
@@ -246,8 +247,8 @@ public class TestMap
break;
case 1 :
// register the map
- re.SetSky("space1", 0, new float[]{ 0, 0, 0 });
re.BeginRegistration("base1");
+ re.SetSky("space1", 0, new float[]{ 0, 0, 0 });
re.EndRegistration();
currentState = 2;
//break;
@@ -431,7 +432,7 @@ public class TestMap
refdef.time = time() * 0.001f;
// particle init
- particles.clear();
+ r_numparticles = 0;
// check the enemy distance
float[] diff = {0, 0, 0};
@@ -451,11 +452,7 @@ public class TestMap
// particles
animateParticles();
- particle_t[] tmp = new particle_t[particles.size()];
- particles.toArray(tmp);
-
- refdef.particles = tmp;
- refdef.num_particles = tmp.length;
+ refdef.num_particles = r_numparticles;
}
else {
ent.frame = 0;
@@ -463,10 +460,11 @@ public class TestMap
}
}
+ refdef.num_dlights = 0;
+
re.RenderFrame(refdef);
}
- private Vector particles = new Vector(1024); // = new particle_t[20];
private LinkedList active_particles = new LinkedList();
private boolean explode = false;
private float[] target;
@@ -480,8 +478,7 @@ public class TestMap
float time, time2;
float[] org = {0, 0, 0};
int color;
- particle_t particle;
-
+
time = 0.0f;
for (Iterator it = active_particles.iterator(); it.hasNext();)
@@ -514,13 +511,8 @@ public class TestMap
org[1] = p.org[1] + p.vel[1]*time + p.accel[1]*time2;
org[2] = p.org[2] + p.vel[2]*time + p.accel[2]*time2;
- particle = new particle_t();
- particle.alpha = alpha;
- Math3D.VectorCopy(org, particle.origin);
- particle.color = color;
-
- particles.add(particle);
-
+ AddParticle(org, color, alpha);
+
// PMM
if (p.alphavel == INSTANT_PARTICLE)
{
@@ -565,7 +557,7 @@ public class TestMap
Math3D.VectorMA (dir, s, up, dir);
p.alpha = 1.0f;
- p.alphavel = -1.0f / (1 + Lib.frand() * 0.2f);
+ p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.2f);
p.color = 0x74 + (Lib.rand() & 7);
for (j=0 ; j<3 ; j++)
{
@@ -592,7 +584,7 @@ public class TestMap
Math3D.VectorClear (p.accel);
p.alpha = 1.0f;
- p.alphavel = -1.0f / (0.6f + Lib.frand() * 0.2f);
+ p.alphavel = -1.0f / (0.6f + Globals.rnd.nextFloat() * 0.2f);
p.color = 0x0 + Lib.rand()&15;
for (j=0 ; j<3 ; j++)
@@ -625,4 +617,28 @@ public class TestMap
IN.toggleMouse();
}
};
+
+ int r_numparticles = 0;
+ /*
+ =====================
+ V_AddParticle
+
+ =====================
+ */
+ void AddParticle(float[] org, int color, float alpha) {
+ if (r_numparticles >= Defines.MAX_PARTICLES)
+ return;
+
+ int i = r_numparticles++;
+
+ int c = particle_t.colorTable[color];
+ c |= (int)(alpha * 255) << 24;
+ particle_t.colorArray.put(i, c);
+
+ i *= 3;
+ FloatBuffer vertexBuf = particle_t.vertexArray;
+ vertexBuf.put(i++, org[0]);
+ vertexBuf.put(i++, org[1]);
+ vertexBuf.put(i++, org[2]);
+ }
}
diff --git a/test/jake2/render/TestRenderer.java b/test/jake2/render/TestRenderer.java
index e152747..376bb60 100644
--- a/test/jake2/render/TestRenderer.java
+++ b/test/jake2/render/TestRenderer.java
@@ -2,7 +2,7 @@
* TestRenderer.java
* Copyright (C) 2003
*
- * $Id: TestRenderer.java,v 1.2 2004-07-08 20:24:31 hzi Exp $
+ * $Id: TestRenderer.java,v 1.3 2004-07-09 06:50:51 hzi Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
package jake2.render;
import java.awt.Dimension;
+import java.nio.FloatBuffer;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
@@ -441,7 +442,6 @@ public class TestRenderer {
re.RenderFrame(refdef);
}
- private Vector particles = new Vector(1024); // = new particle_t[20];
private LinkedList active_particles = new LinkedList();
private boolean explode = false;
private float[] target;
@@ -450,7 +450,7 @@ public class TestRenderer {
private void testParticles() {
- particles.clear();
+ r_numparticles = 0;
if (active_particles.size() == 0) {
if (explode)
@@ -474,14 +474,9 @@ public class TestRenderer {
animateParticles();
- drawString(refdef.x, refdef.y - 20, "active particles: " + particles.size());
+ drawString(refdef.x, refdef.y - 20, "active particles: " + r_numparticles);
- particle_t[] tmp = new particle_t[particles.size()];
-
- particles.toArray(tmp);
-
- refdef.particles = tmp;
- refdef.num_particles = tmp.length;
+ refdef.num_particles = r_numparticles;
refdef.areabits = null;
refdef.num_entities = 0;
@@ -582,7 +577,7 @@ public class TestRenderer {
p.accel[0] = p.accel[1] = 0;
p.accel[2] = -PARTICLE_GRAVITY;
p.alpha = 1.0f;
- p.alphavel = -0.8f / (0.5f + Lib.frand() * 0.3f);
+ p.alphavel = -0.8f / (0.5f + Globals.rnd.nextFloat() * 0.3f);
active_particles.add(p);
}
@@ -604,7 +599,6 @@ public class TestRenderer {
float time, time2;
float[] org = {0, 0, 0};
int color;
- particle_t particle;
time = 0.0f;
@@ -637,13 +631,8 @@ public class TestRenderer {
org[0] = p.org[0] + p.vel[0]*time + p.accel[0]*time2;
org[1] = p.org[1] + p.vel[1]*time + p.accel[1]*time2;
org[2] = p.org[2] + p.vel[2]*time + p.accel[2]*time2;
-
- particle = new particle_t();
- particle.alpha = alpha;
- Math3D.VectorCopy(org, particle.origin);
- particle.color = color;
- particles.add(particle);
+ AddParticle(org, color, alpha);
// PMM
if (p.alphavel == INSTANT_PARTICLE)
@@ -778,7 +767,7 @@ public class TestRenderer {
Math3D.VectorMA (dir, s, up, dir);
p.alpha = 1.0f;
- p.alphavel = -1.0f / (1 + Lib.frand() * 0.2f);
+ p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.2f);
p.color = 0x74 + (Lib.rand() & 7);
for (j=0 ; j<3 ; j++)
{
@@ -805,7 +794,7 @@ public class TestRenderer {
Math3D.VectorClear (p.accel);
p.alpha = 1.0f;
- p.alphavel = -1.0f / (0.6f + Lib.frand() * 0.2f);
+ p.alphavel = -1.0f / (0.6f + Globals.rnd.nextFloat() * 0.2f);
p.color = 0x0 + Lib.rand()&15;
for (j=0 ; j<3 ; j++)
@@ -830,5 +819,28 @@ public class TestRenderer {
testnr = testnr % 3;
}
};
+
+ int r_numparticles = 0;
+ /*
+ =====================
+ V_AddParticle
+ =====================
+ */
+ void AddParticle(float[] org, int color, float alpha) {
+ if (r_numparticles >= Defines.MAX_PARTICLES)
+ return;
+
+ int i = r_numparticles++;
+
+ int c = particle_t.colorTable[color];
+ c |= (int)(alpha * 255) << 24;
+ particle_t.colorArray.put(i, c);
+
+ i *= 3;
+ FloatBuffer vertexBuf = particle_t.vertexArray;
+ vertexBuf.put(i++, org[0]);
+ vertexBuf.put(i++, org[1]);
+ vertexBuf.put(i++, org[2]);
+ }
}