diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..f3e9c36 --- /dev/null +++ b/build.gradle @@ -0,0 +1,83 @@ + +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'io.github.zebalu:teavm-gradle-plugin:1.0.0' + } +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'io.github.zebalu.teavm-gradle-plugin' + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +sourceSets { + main { + java { + srcDir 'src/main/java' + srcDir 'src/teavm/java' + } + } +} + +repositories { + jcenter() +} + +dependencies { + implementation 'org.teavm:teavm-platform:0.6.1' + implementation 'org.teavm:teavm-classlib:0.6.1' +} + +teavm { + + compileScopes = null; + minifying = false; + maxTopLevelNames = 10000; + properties = null; + debugInformationGenerated = false; + sourceMapsGenerated = true; + sourceFilesCopied = false; + incremental = false; + transformers = null; + + /** Where to save the result */ + targetDirectory = file("javascript"); + + /** The directory to monitor to decide if compile is up-to-date or not */ + sourceDirectory = file("src"); + + /** How to name the result file. */ + targetFileName = "classes.js"; + + /** Which class holds your public static void main(Strin[] args) method */ + mainClass = 'net.lax1dude.eaglercraft.Client'; + + /** This will be the name of your main method after compilation. */ + entryPointName = 'main'; + + classesToPreserve = null; + stopOnErrors = false; + optimizationLevel = "FULL"; //org.teavm.vm.TeaVMOptimizationLevel.SIMPLE; + fastGlobalAnalysis = false; + targetType = "JAVASCRIPT"; //org.teavm.tooling.TeaVMTargetType.JAVASCRIPT; + cacheDirectory = null; + wasmVersion = "V_0x1"; //org.teavm.backend.wasm.render.WasmBinaryVersion.V_0x1; + minHeapSize = 4; + maxHeapSize = 128; + outOfProcess = false; + processMemory = 512; + longjmpSupported = true; + heapDump = false; + + /** Add name of configurations here where to look for jarfiles. */ + includeJarsFrom = []; + + /** By default teavmc taskd epends on javaCompile task, unless this varaibale is true. */ + skipJavaCompile = false; +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..cc4fdc2 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..6ce793f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9618d8d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lwjgl-rundir/Java-WebSocket-1.5.1-with-dependencies.jar b/lwjgl-rundir/Java-WebSocket-1.5.1-with-dependencies.jar new file mode 100644 index 0000000..8fb33ad Binary files /dev/null and b/lwjgl-rundir/Java-WebSocket-1.5.1-with-dependencies.jar differ diff --git a/lwjgl-rundir/OpenAL32.dll b/lwjgl-rundir/OpenAL32.dll new file mode 100644 index 0000000..1f69e94 Binary files /dev/null and b/lwjgl-rundir/OpenAL32.dll differ diff --git a/lwjgl-rundir/OpenAL64.dll b/lwjgl-rundir/OpenAL64.dll new file mode 100644 index 0000000..6f2a2fe Binary files /dev/null and b/lwjgl-rundir/OpenAL64.dll differ diff --git a/lwjgl-rundir/liblwjgl.jnilib b/lwjgl-rundir/liblwjgl.jnilib new file mode 100644 index 0000000..227ccf5 Binary files /dev/null and b/lwjgl-rundir/liblwjgl.jnilib differ diff --git a/lwjgl-rundir/liblwjgl.so b/lwjgl-rundir/liblwjgl.so new file mode 100644 index 0000000..4beea98 Binary files /dev/null and b/lwjgl-rundir/liblwjgl.so differ diff --git a/lwjgl-rundir/liblwjgl64.so b/lwjgl-rundir/liblwjgl64.so new file mode 100644 index 0000000..314b892 Binary files /dev/null and b/lwjgl-rundir/liblwjgl64.so differ diff --git a/lwjgl-rundir/libopenal.so b/lwjgl-rundir/libopenal.so new file mode 100644 index 0000000..0a3a619 Binary files /dev/null and b/lwjgl-rundir/libopenal.so differ diff --git a/lwjgl-rundir/libopenal64.so b/lwjgl-rundir/libopenal64.so new file mode 100644 index 0000000..e0693c0 Binary files /dev/null and b/lwjgl-rundir/libopenal64.so differ diff --git a/lwjgl-rundir/lwjgl.dll b/lwjgl-rundir/lwjgl.dll new file mode 100644 index 0000000..f095831 Binary files /dev/null and b/lwjgl-rundir/lwjgl.dll differ diff --git a/lwjgl-rundir/lwjgl.jar b/lwjgl-rundir/lwjgl.jar new file mode 100644 index 0000000..4cb7cda Binary files /dev/null and b/lwjgl-rundir/lwjgl.jar differ diff --git a/lwjgl-rundir/lwjgl64.dll b/lwjgl-rundir/lwjgl64.dll new file mode 100644 index 0000000..240dd2c Binary files /dev/null and b/lwjgl-rundir/lwjgl64.dll differ diff --git a/lwjgl-rundir/lwjgl_util.jar b/lwjgl-rundir/lwjgl_util.jar new file mode 100644 index 0000000..c055bff Binary files /dev/null and b/lwjgl-rundir/lwjgl_util.jar differ diff --git a/lwjgl-rundir/openal.dylib b/lwjgl-rundir/openal.dylib new file mode 100644 index 0000000..3c6d0f7 Binary files /dev/null and b/lwjgl-rundir/openal.dylib differ diff --git a/lwjgl-rundir/options.txt b/lwjgl-rundir/options.txt new file mode 100644 index 0000000..3b663ac --- /dev/null +++ b/lwjgl-rundir/options.txt @@ -0,0 +1,23 @@ +music:1.0 +sound:1.0 +invertYMouse:false +mouseSensitivity:0.5 +viewDistance:1 +bobView:true +anaglyph3d:false +limitFramerate:false +difficulty:2 +fancyGraphics:false +ao:true +skin:Default +lastServer: +key_key.forward:17 +key_key.left:30 +key_key.back:31 +key_key.right:32 +key_key.jump:57 +key_key.sneak:42 +key_key.drop:16 +key_key.inventory:18 +key_key.chat:20 +key_key.fog:33 diff --git a/lwjgl-rundir/resources/armor/chain_1.png b/lwjgl-rundir/resources/armor/chain_1.png new file mode 100644 index 0000000..3632af5 Binary files /dev/null and b/lwjgl-rundir/resources/armor/chain_1.png differ diff --git a/lwjgl-rundir/resources/armor/chain_2.png b/lwjgl-rundir/resources/armor/chain_2.png new file mode 100644 index 0000000..330425b Binary files /dev/null and b/lwjgl-rundir/resources/armor/chain_2.png differ diff --git a/lwjgl-rundir/resources/armor/cloth_1.png b/lwjgl-rundir/resources/armor/cloth_1.png new file mode 100644 index 0000000..f3cf4aa Binary files /dev/null and b/lwjgl-rundir/resources/armor/cloth_1.png differ diff --git a/lwjgl-rundir/resources/armor/cloth_2.png b/lwjgl-rundir/resources/armor/cloth_2.png new file mode 100644 index 0000000..15fb908 Binary files /dev/null and b/lwjgl-rundir/resources/armor/cloth_2.png differ diff --git a/lwjgl-rundir/resources/armor/diamond_1.png b/lwjgl-rundir/resources/armor/diamond_1.png new file mode 100644 index 0000000..339da65 Binary files /dev/null and b/lwjgl-rundir/resources/armor/diamond_1.png differ diff --git a/lwjgl-rundir/resources/armor/diamond_2.png b/lwjgl-rundir/resources/armor/diamond_2.png new file mode 100644 index 0000000..c220c12 Binary files /dev/null and b/lwjgl-rundir/resources/armor/diamond_2.png differ diff --git a/lwjgl-rundir/resources/armor/gold_1.png b/lwjgl-rundir/resources/armor/gold_1.png new file mode 100644 index 0000000..885f309 Binary files /dev/null and b/lwjgl-rundir/resources/armor/gold_1.png differ diff --git a/lwjgl-rundir/resources/armor/gold_2.png b/lwjgl-rundir/resources/armor/gold_2.png new file mode 100644 index 0000000..9d1ea3b Binary files /dev/null and b/lwjgl-rundir/resources/armor/gold_2.png differ diff --git a/lwjgl-rundir/resources/armor/iron_1.png b/lwjgl-rundir/resources/armor/iron_1.png new file mode 100644 index 0000000..374ab07 Binary files /dev/null and b/lwjgl-rundir/resources/armor/iron_1.png differ diff --git a/lwjgl-rundir/resources/armor/iron_2.png b/lwjgl-rundir/resources/armor/iron_2.png new file mode 100644 index 0000000..53af4f4 Binary files /dev/null and b/lwjgl-rundir/resources/armor/iron_2.png differ diff --git a/lwjgl-rundir/resources/art/kz.png b/lwjgl-rundir/resources/art/kz.png new file mode 100644 index 0000000..ecc4823 Binary files /dev/null and b/lwjgl-rundir/resources/art/kz.png differ diff --git a/lwjgl-rundir/resources/environment/clouds.png b/lwjgl-rundir/resources/environment/clouds.png new file mode 100644 index 0000000..b4a78c2 Binary files /dev/null and b/lwjgl-rundir/resources/environment/clouds.png differ diff --git a/lwjgl-rundir/resources/environment/rain.png b/lwjgl-rundir/resources/environment/rain.png new file mode 100644 index 0000000..e9dc16c Binary files /dev/null and b/lwjgl-rundir/resources/environment/rain.png differ diff --git a/lwjgl-rundir/resources/environment/snow.png b/lwjgl-rundir/resources/environment/snow.png new file mode 100644 index 0000000..84417c5 Binary files /dev/null and b/lwjgl-rundir/resources/environment/snow.png differ diff --git a/lwjgl-rundir/resources/font.txt b/lwjgl-rundir/resources/font.txt new file mode 100644 index 0000000..59c1d31 --- /dev/null +++ b/lwjgl-rundir/resources/font.txt @@ -0,0 +1,10 @@ +# This file NEEDS to be in UTF-8 format! + !"#$%&'()*+,-./ +0123456789:;<=>? +@ABCDEFGHIJKLMNO +PQRSTUVWXYZ[\]^_ +'abcdefghijklmno +pqrstuvwxyz{|}~⌂ +ÇüéâäàåçêëèïîìÄÅ +ÉæÆôöòûùÿÖÜø£Ø׃ +áíóúñѪº¿®¬½¼¡«» \ No newline at end of file diff --git a/lwjgl-rundir/resources/font/default.png b/lwjgl-rundir/resources/font/default.png new file mode 100644 index 0000000..fb7686e Binary files /dev/null and b/lwjgl-rundir/resources/font/default.png differ diff --git a/lwjgl-rundir/resources/gui/background.png b/lwjgl-rundir/resources/gui/background.png new file mode 100644 index 0000000..b29e009 Binary files /dev/null and b/lwjgl-rundir/resources/gui/background.png differ diff --git a/lwjgl-rundir/resources/gui/container.png b/lwjgl-rundir/resources/gui/container.png new file mode 100644 index 0000000..bd1d383 Binary files /dev/null and b/lwjgl-rundir/resources/gui/container.png differ diff --git a/lwjgl-rundir/resources/gui/crafting.png b/lwjgl-rundir/resources/gui/crafting.png new file mode 100644 index 0000000..da83118 Binary files /dev/null and b/lwjgl-rundir/resources/gui/crafting.png differ diff --git a/lwjgl-rundir/resources/gui/furnace.png b/lwjgl-rundir/resources/gui/furnace.png new file mode 100644 index 0000000..a5834e1 Binary files /dev/null and b/lwjgl-rundir/resources/gui/furnace.png differ diff --git a/lwjgl-rundir/resources/gui/gui.png b/lwjgl-rundir/resources/gui/gui.png new file mode 100644 index 0000000..81af329 Binary files /dev/null and b/lwjgl-rundir/resources/gui/gui.png differ diff --git a/lwjgl-rundir/resources/gui/icons.png b/lwjgl-rundir/resources/gui/icons.png new file mode 100644 index 0000000..73fe9bb Binary files /dev/null and b/lwjgl-rundir/resources/gui/icons.png differ diff --git a/lwjgl-rundir/resources/gui/inventory.png b/lwjgl-rundir/resources/gui/inventory.png new file mode 100644 index 0000000..0b5f291 Binary files /dev/null and b/lwjgl-rundir/resources/gui/inventory.png differ diff --git a/lwjgl-rundir/resources/gui/items.png b/lwjgl-rundir/resources/gui/items.png new file mode 100644 index 0000000..363e99d Binary files /dev/null and b/lwjgl-rundir/resources/gui/items.png differ diff --git a/lwjgl-rundir/resources/gui/logo.png b/lwjgl-rundir/resources/gui/logo.png new file mode 100644 index 0000000..b7c2879 Binary files /dev/null and b/lwjgl-rundir/resources/gui/logo.png differ diff --git a/lwjgl-rundir/resources/gui/trap.png b/lwjgl-rundir/resources/gui/trap.png new file mode 100644 index 0000000..e8d25ab Binary files /dev/null and b/lwjgl-rundir/resources/gui/trap.png differ diff --git a/lwjgl-rundir/resources/gui/unknown_pack.png b/lwjgl-rundir/resources/gui/unknown_pack.png new file mode 100644 index 0000000..3a45a90 Binary files /dev/null and b/lwjgl-rundir/resources/gui/unknown_pack.png differ diff --git a/lwjgl-rundir/resources/item/arrows.png b/lwjgl-rundir/resources/item/arrows.png new file mode 100644 index 0000000..75c5828 Binary files /dev/null and b/lwjgl-rundir/resources/item/arrows.png differ diff --git a/lwjgl-rundir/resources/item/boat.png b/lwjgl-rundir/resources/item/boat.png new file mode 100644 index 0000000..132a0f7 Binary files /dev/null and b/lwjgl-rundir/resources/item/boat.png differ diff --git a/lwjgl-rundir/resources/item/cart.png b/lwjgl-rundir/resources/item/cart.png new file mode 100644 index 0000000..32af68e Binary files /dev/null and b/lwjgl-rundir/resources/item/cart.png differ diff --git a/lwjgl-rundir/resources/item/door.png b/lwjgl-rundir/resources/item/door.png new file mode 100644 index 0000000..52df2d9 Binary files /dev/null and b/lwjgl-rundir/resources/item/door.png differ diff --git a/lwjgl-rundir/resources/item/sign.png b/lwjgl-rundir/resources/item/sign.png new file mode 100644 index 0000000..e829472 Binary files /dev/null and b/lwjgl-rundir/resources/item/sign.png differ diff --git a/lwjgl-rundir/resources/lang/en_US.lang b/lwjgl-rundir/resources/lang/en_US.lang new file mode 100644 index 0000000..8471bde --- /dev/null +++ b/lwjgl-rundir/resources/lang/en_US.lang @@ -0,0 +1,531 @@ + +gui.done=Done +gui.cancel=Cancel +gui.toMenu=Back to title screen +gui.up=Up +gui.down=Down +gui.yes=Yes +gui.no=No + +menu.singleplayer=Singleplayer +menu.multiplayer=Multiplayer +menu.mods=Mods and Texture Packs +menu.options=Options... +menu.quit=Quit Game + +selectWorld.title=Select World +selectWorld.empty=empty +selectWorld.world=World +selectWorld.select=Play Selected World +selectWorld.create=Create New World +selectWorld.delete=Delete +selectWorld.rename=Rename +selectWorld.deleteQuestion=Are you sure you want to delete this world? +selectWorld.deleteWarning=will be lost forever! (A long time!) +selectWorld.deleteButton=Delete +selectWorld.renameButton=Rename +selectWorld.renameTitle=Rename World +selectWorld.conversion=Must be converted! +selectWorld.newWorld=New World +selectWorld.enterName=World Name +selectWorld.resultFolder=Will be saved in: +selectWorld.enterSeed=Seed for the World Generator +selectWorld.seedInfo=Leave blank for a random seed + +multiplayer.title=Play Multiplayer +multiplayer.connect=Connect +multiplayer.info1=Minecraft Multiplayer is currently not finished, but there +multiplayer.info2=is some buggy early testing going on. +multiplayer.ipinfo=Enter the IP of a server to connect to it: + +multiplayer.downloadingTerrain=Downloading terrain + +multiplayer.stopSleeping=Leave Bed + +connect.connecting=Connecting to the server... +connect.authorizing=Logging in... +connect.failed=Failed to connect to the server + +disconnect.genericReason=%s +disconnect.disconnected=Disconnected by Server +disconnect.lost=Connection Lost +disconnect.kicked=Was kicked from the game +disconnect.timeout=Timed out +disconnect.closed=Connection closed +disconnect.loginFailed=Failed to login +disconnect.loginFailedInfo=Failed to login: %s +disconnect.quitting=Quitting +disconnect.endOfStream=End of stream +disconnect.overflow=Buffer overflow + +options.off=OFF +options.on=ON +options.title=Options +options.controls=Controls... +options.video=Video Settings... +options.videoTitle=Video Settings +options.music=Music +options.sound=Sound +options.invertMouse=Invert Mouse +options.sensitivity=Sensitivity +options.sensitivity.min=*yawn* +options.sensitivity.max=HYPERSPEED!!! +options.renderDistance=Render Distance +options.renderDistance.tiny=Tiny +options.renderDistance.short=Short +options.renderDistance.normal=Normal +options.renderDistance.far=Far +options.viewBobbing=View Bobbing +options.ao=Smooth Lighting +options.anaglyph=3D Anaglyph +options.limitFramerate=Limit Framerate +options.difficulty=Difficulty +options.difficulty.peaceful=Peaceful +options.difficulty.easy=Easy +options.difficulty.normal=Normal +options.difficulty.hard=Hard +options.graphics=Graphics +options.graphics.fancy=Fancy +options.graphics.fast=Fast + +controls.title=Controls + +key.forward=Forward +key.left=Left +key.back=Back +key.right=Right +key.jump=Jump +key.inventory=Inventory +key.drop=Drop +key.chat=Chat +key.fog=Toggle Fog +key.sneak=Sneak +key.playerlist=List players + +texturePack.openFolder=Open texture pack folder +texturePack.title=Select Texture Pack +texturePack.folderInfo=(Place texture pack files here) + +tile.stone.name=Stone +tile.stone.desc= +tile.grass.name=Grass +tile.grass.desc= +tile.dirt.name=Dirt +tile.dirt.desc= +tile.stonebrick.name=Cobblestone +tile.stonebrick.desc= +tile.wood.name=Wooden Planks +tile.wood.desc= +tile.sapling.name=Sapling +tile.sapling.desc= +tile.bedrock.name=Bedrock +tile.bedrock.desc= +tile.water.name=Water +tile.water.desc= +tile.lava.name=Lava +tile.lava.desc= +tile.sand.name=Sand +tile.sand.desc= +tile.sandStone.name=Sandstone +tile.sand.desc= +tile.gravel.name=Gravel +tile.gravel.desc= +tile.oreGold.name=Gold Ore +tile.oreGold.desc= +tile.oreIron.name=Iron Ore +tile.oreIron.desc= +tile.oreCoal.name=Coal Ore +tile.oreCoal.desc= +tile.log.name=Wood +tile.log.desc= +tile.leaves.name=Leaves +tile.leaves.desc= +tile.sponge.name=Sponge +tile.sponge.desc= +tile.glass.name=Glass +tile.glass.desc= +tile.cloth.name=Wool +tile.cloth.desc= +tile.flower.name=Flower +tile.flower.desc= +tile.rose.name=Rose +tile.rose.desc= +tile.mushroom.name=Mushroom +tile.mushroom.desc= +tile.blockGold.name=Block of Gold +tile.blockGold.desc= +tile.blockIron.name=Block of Iron +tile.blockIron.desc= +tile.stoneSlab.stone.name=Stone Slab +tile.stoneSlab.stone.desc= +tile.stoneSlab.sand.name=Sandstone Slab +tile.stoneSlab.sand.desc= +tile.stoneSlab.wood.name=Wooden Slab +tile.stoneSlab.wood.desc= +tile.stoneSlab.cobble.name=Stone Slab +tile.stoneSlab.cobble.desc= +tile.brick.name=Bricks +tile.brick.desc= +tile.tnt.name=TNT +tile.tnt.desc= +tile.bookshelf.name=Bookshelf +tile.bookshelf.desc= +tile.stoneMoss.name=Moss Stone +tile.stoneMoss.desc= +tile.obsidian.name=Obsidian +tile.obsidian.desc= +tile.torch.name=Torch +tile.torch.desc= +tile.fire.name=Fire +tile.fire.desc= +tile.mobSpawner.name=Monster Spawner +tile.mobSpawner.desc= +tile.stairsWood.name=Wooden Stairs +tile.stairsWood.desc= +tile.chest.name=Chest +tile.chest.desc= +tile.redstoneDust.name=Redstone Dust +tile.redstoneDust.desc= +tile.oreDiamond.name=Diamond Ore +tile.oreDiamond.desc= +tile.blockDiamond.name=Block of Diamond +tile.blockDiamond.desc= +tile.workbench.name=Crafting Table +tile.workbench.desc= +tile.crops.name=Crops +tile.crops.desc= +tile.farmland.name=Farmland +tile.farmland.desc= +tile.furnace.name=Furnace +tile.furnace.desc= +tile.sign.name=Sign +tile.sign.desc= +tile.doorWood.name=Wooden Door +tile.doorWood.desc= +tile.ladder.name=Ladder +tile.ladder.desc= +tile.rail.name=Rail +tile.rail.desc= +tile.stairsStone.name=Stone Stairs +tile.stairsStone.desc= +tile.lever.name=Lever +tile.lever.desc= +tile.pressurePlate.name=Pressure Plate +tile.pressurePlate.desc= +tile.doorIron.name=Iron Door +tile.doorIron.desc= +tile.oreRedstone.name=Redstone Ore +tile.oreRedstone.desc= +tile.notGate.name=Redstone Torch +tile.notGate.desc= +tile.button.name=Button +tile.button.desc= +tile.snow.name=Snow +tile.snow.desc= +tile.ice.name=Ice +tile.ice.desc= +tile.cactus.name=Cactus +tile.cactus.desc= +tile.clay.name=Clay +tile.clay.desc= +tile.reeds.name=Reeds +tile.reeds.desc= +tile.jukebox.name=Jukebox +tile.jukebox.desc= +tile.fence.name=Fence +tile.fence.desc= +tile.pumpkin.name=Pumpkin +tile.pumpkin.desc= +tile.litpumpkin.name=Jack 'o' Lantern +tile.litpumpkin.desc= +tile.hellrock.name=Netherrack +tile.hellrock.desc= +tile.hellsand.name=Soul Sand +tile.hellsand.desc= +tile.lightgem.name=Glowstone +tile.lightgem.desc= +tile.portal.name=Portal +tile.portal.desc= +tile.cloth.black.name=Black Wool +tile.cloth.black.desc= +tile.cloth.red.name=Red Wool +tile.cloth.red.desc= +tile.cloth.green.name=Green Wool +tile.cloth.green.desc= +tile.cloth.brown.name=Brown Wool +tile.cloth.brown.desc= +tile.cloth.blue.name=Blue Wool +tile.cloth.blue.desc= +tile.cloth.purple.name=Purple Wool +tile.cloth.purple.desc= +tile.cloth.cyan.name=Cyan Wool +tile.cloth.cyan.desc= +tile.cloth.silver.name=Light Gray Wool +tile.cloth.silver.desc= +tile.cloth.gray.name=Gray Wool +tile.cloth.gray.desc= +tile.cloth.pink.name=Pink Wool +tile.cloth.pink.desc= +tile.cloth.lime.name=Lime Wool +tile.cloth.lime.desc= +tile.cloth.yellow.name=Yellow Wool +tile.cloth.yellow.desc= +tile.cloth.lightBlue.name=Light Blue Wool +tile.cloth.lightBlue.desc= +tile.cloth.magenta.name=Magenta Wool +tile.cloth.magenta.desc= +tile.cloth.orange.name=Orange Wool +tile.cloth.orange.desc= +tile.cloth.white.name=Wool +tile.cloth.white.desc= +tile.oreLapis.name=Lapis Lazuli Ore +tile.oreLapis.desc= +tile.blockLapis.name=Lapis Lazuli Block +tile.blockLapis.desc= +tile.dispenser.name=Dispenser +tile.dispenser.desc= +tile.musicBlock.name=Note Block +tile.musicBlock.desc= +tile.cake.name=Cake +tile.cake.desc= +tile.bed.name=Bed +tile.bed.desc= +tile.bed.occupied=This bed is occupied +tile.bed.noSleep=You can only sleep at night + +item.shovelIron.name=Iron Shovel +item.shovelIron.desc= +item.pickaxeIron.name=Iron Pickaxe +item.pickaxeIron.desc= +item.hatchetIron.name=Iron Axe +item.hatchetIron.desc= +item.flintAndSteel.name=Flint and Steel +item.flintAndSteel.desc= +item.apple.name=Apple +item.apple.desc= +item.bow.name=Bow +item.bow.desc= +item.arrow.name=Arrow +item.arrow.desc= +item.coal.name=Coal +item.coal.desc= +item.charcoal.name=Charcoal +item.charcoal.desc= +item.emerald.name=Diamond +item.emerald.desc= +item.ingotIron.name=Iron Ingot +item.ingotIron.desc= +item.ingotGold.name=Gold Ingot +item.ingotGold.desc= +item.swordIron.name=Iron Sword +item.swordIron.desc= +item.swordWood.name=Wooden Sword +item.swordWood.desc= +item.shovelWood.name=Wooden Shovel +item.shovelWood.desc= +item.pickaxeWood.name=Wooden Pickaxe +item.pickaxeWood.desc= +item.hatchetWood.name=Wooden Axe +item.hatchetWood.desc= +item.swordStone.name=Stone Sword +item.swordStone.desc= +item.shovelStone.name=Stone Shovel +item.shovelStone.desc= +item.pickaxeStone.name=Stone Pickaxe +item.pickaxeStone.desc= +item.hatchetStone.name=Stone Axe +item.hatchetStone.desc= +item.swordDiamond.name=Diamond Sword +item.swordDiamond.desc= +item.shovelDiamond.name=Diamond Shovel +item.shovelDiamond.desc= +item.pickaxeDiamond.name=Diamond Pickaxe +item.pickaxeDiamond.desc= +item.hatchetDiamond.name=Diamond Axe +item.hatchetDiamond.desc= +item.stick.name=Stick +item.stick.desc= +item.bowl.name=Bowl +item.bowl.desc= +item.mushroomStew.name=Mushroom Stew +item.mushroomStew.desc= +item.swordGold.name=Golden Sword +item.swordGold.desc= +item.shovelGold.name=Golden Shovel +item.shovelGold.desc= +item.pickaxeGold.name=Golden Pickaxe +item.pickaxeGold.desc= +item.hatchetGold.name=Golden Axe +item.hatchetGold.desc= +item.string.name=String +item.string.desc= +item.feather.name=Feather +item.feather.desc= +item.sulphur.name=Gunpowder +item.sulphur.desc= +item.hoeWood.name=Wooden Hoe +item.hoeWood.desc= +item.hoeStone.name=Stone Hoe +item.hoeStone.desc= +item.hoeIron.name=Iron Hoe +item.hoeIron.desc= +item.hoeDiamond.name=Diamond Hoe +item.hoeDiamond.desc= +item.hoeGold.name=Golden Hoe +item.hoeGold.desc= +item.seeds.name=Seeds +item.seeds.desc= +item.wheat.name=Wheat +item.wheat.desc= +item.bread.name=Bread +item.bread.desc= +item.helmetCloth.name=Leather Cap +item.helmetCloth.desc= +item.chestplateCloth.name=Leather Tunic +item.chestplateCloth.desc= +item.leggingsCloth.name=Leather Pants +item.leggingsCloth.desc= +item.bootsCloth.name=Leather Boots +item.bootsCloth.desc= +item.helmetChain.name=Chain Helmet +item.helmetChain.desc= +item.chestplateChain.name=Chain Chestplate +item.chestplateChain.desc= +item.leggingsChain.name=Chain Leggings +item.leggingsChain.desc= +item.bootsChain.name=Chain Boots +item.bootsChain.desc= +item.helmetIron.name=Iron Helmet +item.helmetIron.desc= +item.chestplateIron.name=Iron Chestplate +item.chestplateIron.desc= +item.leggingsIron.name=Iron Leggings +item.leggingsIron.desc= +item.bootsIron.name=Iron Boots +item.bootsIron.desc= +item.helmetDiamond.name=Diamond Helmet +item.helmetDiamond.desc= +item.chestplateDiamond.name=Diamond Chestplate +item.chestplateDiamond.desc= +item.leggingsDiamond.name=Diamond Leggings +item.leggingsDiamond.desc= +item.bootsDiamond.name=Diamond Boots +item.bootsDiamond.desc= +item.helmetGold.name=Golden Helmet +item.helmetGold.desc= +item.chestplateGold.name=Golden Chestplate +item.chestplateGold.desc= +item.leggingsGold.name=Golden Leggings +item.leggingsGold.desc= +item.bootsGold.name=Golden boots +item.bootsGold.desc= +item.flint.name=Flint +item.flint.desc= +item.porkchopRaw.name=Raw Porkchop +item.porkchopRaw.desc= +item.porkchopCooked.name=Cooked Porkchop +item.porkchopCooked.desc= +item.painting.name=Painting +item.painting.desc= +item.appleGold.name=Golden Apple +item.appleGold.desc= +item.sign.name=Sign +item.sign.desc= +item.doorWood.name=Wooden Door +item.doorWood.desc= +item.bucket.name=Bucket +item.bucket.desc= +item.bucketWater.name=Water Bucket +item.bucketWater.desc= +item.bucketLava.name=Lava bucket +item.bucketLava.desc= +item.minecart.name=Minecart +item.minecart.desc= +item.saddle.name=Saddle +item.saddle.desc= +item.doorIron.name=Iron Door +item.doorIron.desc= +item.redstone.name=Redstone +item.redstone.desc= +item.snowball.name=Snowball +item.snowball.desc= +item.boat.name=Boat +item.boat.desc= +item.leather.name=Leather +item.leather.desc= +item.milk.name=Milk +item.milk.desc= +item.brick.name=Brick +item.brick.desc= +item.clay.name=Clay +item.clay.desc= +item.reeds.name=Sugar Canes +item.reeds.desc= +item.paper.name=Paper +item.paper.desc= +item.book.name=Book +item.book.desc= +item.slimeball.name=Slimeball +item.slimeball.desc= +item.minecartChest.name=Minecart with Chest +item.minecartChest.desc= +item.minecartFurnace.name=Minecart with Furnace +item.minecartFurnace.desc= +item.egg.name=Egg +item.egg.desc= +item.compass.name=Compass +item.compass.desc= +item.fishingRod.name=Fishing Rod +item.fishingRod.desc= +item.clock.name=Clock +item.clock.desc= +item.yellowDust.name=Glowstone Dust +item.yellowDust.desc= +item.fishRaw.name=Raw Fish +item.fishRaw.desc= +item.fishCooked.name=Cooked Fish +item.fishCooked.desc= +item.record.name=Music Disc +item.record.desc= +item.bone.name=Bone +item.bone.desc= +item.dyePowder.black.name=Ink Sac +item.dyePowder.black.desc= +item.dyePowder.red.name=Rose Red +item.dyePowder.red.desc= +item.dyePowder.green.name=Cactus Green +item.dyePowder.green.desc= +item.dyePowder.brown.name=Cocoa Beans +item.dyePowder.brown.desc= +item.dyePowder.blue.name=Lapis Lazuli +item.dyePowder.blue.desc= +item.dyePowder.purple.name=Purple Dye +item.dyePowder.purple.desc= +item.dyePowder.cyan.name=Cyan Dye +item.dyePowder.cyan.desc= +item.dyePowder.silver.name=Light Gray Dye +item.dyePowder.silver.desc= +item.dyePowder.gray.name=Gray Dye +item.dyePowder.gray.desc= +item.dyePowder.pink.name=Pink Dye +item.dyePowder.pink.desc= +item.dyePowder.lime.name=Lime Dye +item.dyePowder.lime.desc= +item.dyePowder.yellow.name=Dandelion Yellow +item.dyePowder.yellow.desc= +item.dyePowder.lightBlue.name=Light Blue Dye +item.dyePowder.lightBlue.desc= +item.dyePowder.magenta.name=Magenta Dye +item.dyePowder.magenta.desc= +item.dyePowder.orange.name=Orange Dye +item.dyePowder.orange.desc= +item.dyePowder.white.name=Bone Meal +item.dyePowder.white.desc= +item.sugar.name=Sugar +item.sugar.desc= +item.cake.name=Cake +item.cake.desc= +item.bed.name=Bed +item.bed.desc= +item.diode.name=Redstone Repeater +item.diode.desc= diff --git a/lwjgl-rundir/resources/misc/dial.png b/lwjgl-rundir/resources/misc/dial.png new file mode 100644 index 0000000..140e7e3 Binary files /dev/null and b/lwjgl-rundir/resources/misc/dial.png differ diff --git a/lwjgl-rundir/resources/misc/foliagecolor.png b/lwjgl-rundir/resources/misc/foliagecolor.png new file mode 100644 index 0000000..81673ca Binary files /dev/null and b/lwjgl-rundir/resources/misc/foliagecolor.png differ diff --git a/lwjgl-rundir/resources/misc/grasscolor.png b/lwjgl-rundir/resources/misc/grasscolor.png new file mode 100644 index 0000000..a6d9c20 Binary files /dev/null and b/lwjgl-rundir/resources/misc/grasscolor.png differ diff --git a/lwjgl-rundir/resources/misc/pumpkinblur.png b/lwjgl-rundir/resources/misc/pumpkinblur.png new file mode 100644 index 0000000..c6e2ffc Binary files /dev/null and b/lwjgl-rundir/resources/misc/pumpkinblur.png differ diff --git a/lwjgl-rundir/resources/misc/shadow.png b/lwjgl-rundir/resources/misc/shadow.png new file mode 100644 index 0000000..06d999b Binary files /dev/null and b/lwjgl-rundir/resources/misc/shadow.png differ diff --git a/lwjgl-rundir/resources/misc/vignette.png b/lwjgl-rundir/resources/misc/vignette.png new file mode 100644 index 0000000..f236acb Binary files /dev/null and b/lwjgl-rundir/resources/misc/vignette.png differ diff --git a/lwjgl-rundir/resources/misc/water.png b/lwjgl-rundir/resources/misc/water.png new file mode 100644 index 0000000..8b92f9b Binary files /dev/null and b/lwjgl-rundir/resources/misc/water.png differ diff --git a/lwjgl-rundir/resources/mob/char.png b/lwjgl-rundir/resources/mob/char.png new file mode 100644 index 0000000..7cfa08a Binary files /dev/null and b/lwjgl-rundir/resources/mob/char.png differ diff --git a/lwjgl-rundir/resources/mob/chicken.png b/lwjgl-rundir/resources/mob/chicken.png new file mode 100644 index 0000000..d481293 Binary files /dev/null and b/lwjgl-rundir/resources/mob/chicken.png differ diff --git a/lwjgl-rundir/resources/mob/cow.png b/lwjgl-rundir/resources/mob/cow.png new file mode 100644 index 0000000..2080ebc Binary files /dev/null and b/lwjgl-rundir/resources/mob/cow.png differ diff --git a/lwjgl-rundir/resources/mob/creeper.png b/lwjgl-rundir/resources/mob/creeper.png new file mode 100644 index 0000000..e0a5e0a Binary files /dev/null and b/lwjgl-rundir/resources/mob/creeper.png differ diff --git a/lwjgl-rundir/resources/mob/ghast.png b/lwjgl-rundir/resources/mob/ghast.png new file mode 100644 index 0000000..e83a60d Binary files /dev/null and b/lwjgl-rundir/resources/mob/ghast.png differ diff --git a/lwjgl-rundir/resources/mob/ghast_fire.png b/lwjgl-rundir/resources/mob/ghast_fire.png new file mode 100644 index 0000000..fff9718 Binary files /dev/null and b/lwjgl-rundir/resources/mob/ghast_fire.png differ diff --git a/lwjgl-rundir/resources/mob/pig.png b/lwjgl-rundir/resources/mob/pig.png new file mode 100644 index 0000000..5c1efc2 Binary files /dev/null and b/lwjgl-rundir/resources/mob/pig.png differ diff --git a/lwjgl-rundir/resources/mob/pigman.png b/lwjgl-rundir/resources/mob/pigman.png new file mode 100644 index 0000000..c900b36 Binary files /dev/null and b/lwjgl-rundir/resources/mob/pigman.png differ diff --git a/lwjgl-rundir/resources/mob/pigzombie.png b/lwjgl-rundir/resources/mob/pigzombie.png new file mode 100644 index 0000000..0a0a25a Binary files /dev/null and b/lwjgl-rundir/resources/mob/pigzombie.png differ diff --git a/lwjgl-rundir/resources/mob/saddle.png b/lwjgl-rundir/resources/mob/saddle.png new file mode 100644 index 0000000..aaea7a6 Binary files /dev/null and b/lwjgl-rundir/resources/mob/saddle.png differ diff --git a/lwjgl-rundir/resources/mob/sheep.png b/lwjgl-rundir/resources/mob/sheep.png new file mode 100644 index 0000000..98cfa9a Binary files /dev/null and b/lwjgl-rundir/resources/mob/sheep.png differ diff --git a/lwjgl-rundir/resources/mob/sheep_fur.png b/lwjgl-rundir/resources/mob/sheep_fur.png new file mode 100644 index 0000000..f1291a5 Binary files /dev/null and b/lwjgl-rundir/resources/mob/sheep_fur.png differ diff --git a/lwjgl-rundir/resources/mob/skeleton.png b/lwjgl-rundir/resources/mob/skeleton.png new file mode 100644 index 0000000..9d22339 Binary files /dev/null and b/lwjgl-rundir/resources/mob/skeleton.png differ diff --git a/lwjgl-rundir/resources/mob/slime.png b/lwjgl-rundir/resources/mob/slime.png new file mode 100644 index 0000000..42fc873 Binary files /dev/null and b/lwjgl-rundir/resources/mob/slime.png differ diff --git a/lwjgl-rundir/resources/mob/spider.png b/lwjgl-rundir/resources/mob/spider.png new file mode 100644 index 0000000..08344a8 Binary files /dev/null and b/lwjgl-rundir/resources/mob/spider.png differ diff --git a/lwjgl-rundir/resources/mob/spider_eyes.png b/lwjgl-rundir/resources/mob/spider_eyes.png new file mode 100644 index 0000000..2a7734f Binary files /dev/null and b/lwjgl-rundir/resources/mob/spider_eyes.png differ diff --git a/lwjgl-rundir/resources/mob/squid.png b/lwjgl-rundir/resources/mob/squid.png new file mode 100644 index 0000000..ff3f5b0 Binary files /dev/null and b/lwjgl-rundir/resources/mob/squid.png differ diff --git a/lwjgl-rundir/resources/mob/zombie.png b/lwjgl-rundir/resources/mob/zombie.png new file mode 100644 index 0000000..0ab7089 Binary files /dev/null and b/lwjgl-rundir/resources/mob/zombie.png differ diff --git a/lwjgl-rundir/resources/pack.png b/lwjgl-rundir/resources/pack.png new file mode 100644 index 0000000..973a7cf Binary files /dev/null and b/lwjgl-rundir/resources/pack.png differ diff --git a/lwjgl-rundir/resources/pack.txt b/lwjgl-rundir/resources/pack.txt new file mode 100644 index 0000000..c14bb3b --- /dev/null +++ b/lwjgl-rundir/resources/pack.txt @@ -0,0 +1,2 @@ +The default look of Minecraft + diff --git a/lwjgl-rundir/resources/particles.png b/lwjgl-rundir/resources/particles.png new file mode 100644 index 0000000..03f7beb Binary files /dev/null and b/lwjgl-rundir/resources/particles.png differ diff --git a/lwjgl-rundir/resources/terrain.png b/lwjgl-rundir/resources/terrain.png new file mode 100644 index 0000000..ab9846a Binary files /dev/null and b/lwjgl-rundir/resources/terrain.png differ diff --git a/lwjgl-rundir/resources/terrain/moon.png b/lwjgl-rundir/resources/terrain/moon.png new file mode 100644 index 0000000..61cebbc Binary files /dev/null and b/lwjgl-rundir/resources/terrain/moon.png differ diff --git a/lwjgl-rundir/resources/terrain/sun.png b/lwjgl-rundir/resources/terrain/sun.png new file mode 100644 index 0000000..d343344 Binary files /dev/null and b/lwjgl-rundir/resources/terrain/sun.png differ diff --git a/lwjgl-rundir/resources/title/black.png b/lwjgl-rundir/resources/title/black.png new file mode 100644 index 0000000..dc2ad3e Binary files /dev/null and b/lwjgl-rundir/resources/title/black.png differ diff --git a/lwjgl-rundir/resources/title/mojang.png b/lwjgl-rundir/resources/title/mojang.png new file mode 100644 index 0000000..829cfc4 Binary files /dev/null and b/lwjgl-rundir/resources/title/mojang.png differ diff --git a/lwjgl-rundir/resources/title/splashes.txt b/lwjgl-rundir/resources/title/splashes.txt new file mode 100644 index 0000000..758eb6e --- /dev/null +++ b/lwjgl-rundir/resources/title/splashes.txt @@ -0,0 +1,223 @@ +As seen on TV! +Awesome! +100% pure! +May contain nuts! +Better than Prey! +More polygons! +Sexy! +Limited edition! +Flashing letters! +Made by Notch! +Coming soon! +Best in class! +When it's finished! +Absolutely dragon free! +Excitement! +More than 500 sold! +One of a kind! +Heaps of hits on YouTube! +Indev! +Spiders everywhere! +Check it out! +Holy cow, man! +It's a game! +Made in Sweden! +Uses LWJGL! +Reticulating splines! +Minecraft! +Yaaay! +Singleplayer! +Keyboard compatible! +Undocumented! +Ingots! +Exploding creepers! +That's not a moon! +l33t! +Create! +Survive! +Dungeon! +Exclusive! +The bee's knees! +Down with O.P.P.! +Closed source! +Classy! +Wow! +Not on steam! +Oh man! +Check it out! +Awesome community! +Pixels! +Teetsuuuuoooo! +Kaaneeeedaaaa! +Now with difficulty! +Enhanced! +90% bug free! +Pretty! +12 herbs and spices! +Fat free! +Absolutely no memes! +Free dental! +Ask your doctor! +Minors welcome! +Cloud computing! +Legal in Finland! +Hard to label! +Technically good! +Bringing home the bacon! +Indie! +GOTY! +Ceci n'est pas une title screen! +Euclidian! +Now in 3D! +Inspirational! +Herregud! +Complex cellular automata! +Yes, sir! +Played by cowboys! +OpenGL 1.1! +Thousands of colors! +Try it! +Age of Wonders is better! +Try the mushroom stew! +Sensational! +Hot tamale, hot hot tamale! +Play him off, keyboard cat! +Guaranteed! +Macroscopic! +Bring it on! +Random splash! +Call your mother! +Monster infighting! +Loved by millions! +Ultimate edition! +Freaky! +You've got a brand new key! +Water proof! +Uninflammable! +Whoa, dude! +All inclusive! +Tell your friends! +NP is not in P! +Notch <3 ez! +Music by C418! +Livestreamed! +Haunted! +Polynomial! +Terrestrial! +All is full of love! +Full of stars! +Scientific! +Cooler than Spock! +Collaborate and listen! +Never dig down! +Take frequent breaks! +Not linear! +Han shot first! +Nice to meet you! +Buckets of lava! +Ride the pig! +Larger than Earth! +sqrt(-1) love you! +Phobos anomaly! +Punching wood! +Falling off cliffs! +0% sugar! +150% hyperbole! +Synecdoche! +Let's danec! +Seecret Friday update! +Reference implementation! +Lewd with two dudes with food! +Kiss the sky! +20 GOTO 10! +Verlet intregration! +Peter Griffin! +Do not distribute! +Cogito ergo sum! +4815162342 lines of code! +A skeleton popped out! +The Work of Notch! +The sum of its parts! +BTAF used to be good! +I miss ADOM! +umop-apisdn! +OICU812! +Bring me Ray Cokes! +Finger-licking! +Thematic! +Pneumatic! +Sublime! +Octagonal! +Une baguette! +Gargamel plays it! +Rita is the new top dog! +SWM forever! +Representing Edsbyn! +Matt Damon! +Superfragilisticexpialidocious! +Consummate V's! +Cow Tools! +Double buffered! +Fan fiction! +Flaxkikare! +Jason! Jason! Jason! +Hotter than the sun! +Internet enabled! +Autonomous! +Engage! +Fantasy! +DRR! DRR! DRR! +Kick it root down! +Regional resources! +Woo, facepunch! +Woo, somethingawful! +Woo, /v/! +Woo, tigsource! +Woo, minecraftforum! +Woo, worldofminecraft! +Woo, reddit! +Woo, 2pp! +Google anlyticsed! +Now supports åäö! +Give us Gordon! +Tip your waiter! +Very fun! +12345 is a bad password! +Vote for net neutrality! +Lives in a pineapple under the sea! +MAP11 has two names! +Omnipotent! +Gasp! +...! +Bees, bees, bees, bees! +Jag känner en bot! +This text is hard to read if you play the game at the default resolution, but at 1080p it's fine! +Haha, LOL! +Hampsterdance! +Switches and ores! +Menger sponge! +idspispopd! +Eple (original edit)! +So fresh, so clean! +Slow acting portals! +Try the Nether! +Don't look directly at the bugs! +Oh, ok, Pigmen! +Finally with ladders! +Scary! +Play Minecraft, Watch Topgear, Get Pig! +Twittered about! +Jump up, jump up, and get down! +Joel is neat! +A riddle, wrapped in a mystery! +Huge tracts of land! +Welcome to your Doom! +Stay a while, stay forever! +Stay a while and listen! +Treatment for your rash! +"Noun" is an autonym! +Information wants to be free! +"Almost never" is an interesting concept! +Lots of truthiness! +The creeper is a spy! +Turing complete! diff --git a/lwjgl-rundir/saves/New World/level.dat b/lwjgl-rundir/saves/New World/level.dat new file mode 100644 index 0000000..68aae3b Binary files /dev/null and b/lwjgl-rundir/saves/New World/level.dat differ diff --git a/lwjgl-rundir/saves/New World/level.dat_old b/lwjgl-rundir/saves/New World/level.dat_old new file mode 100644 index 0000000..f92a7c1 Binary files /dev/null and b/lwjgl-rundir/saves/New World/level.dat_old differ diff --git a/lwjgl-rundir/saves/New World/region/r.-1.-1.mcr b/lwjgl-rundir/saves/New World/region/r.-1.-1.mcr new file mode 100644 index 0000000..418c9ea Binary files /dev/null and b/lwjgl-rundir/saves/New World/region/r.-1.-1.mcr differ diff --git a/lwjgl-rundir/saves/New World/region/r.-1.0.mcr b/lwjgl-rundir/saves/New World/region/r.-1.0.mcr new file mode 100644 index 0000000..213d0ed Binary files /dev/null and b/lwjgl-rundir/saves/New World/region/r.-1.0.mcr differ diff --git a/lwjgl-rundir/saves/New World/region/r.0.-1.mcr b/lwjgl-rundir/saves/New World/region/r.0.-1.mcr new file mode 100644 index 0000000..afaf91c Binary files /dev/null and b/lwjgl-rundir/saves/New World/region/r.0.-1.mcr differ diff --git a/lwjgl-rundir/saves/New World/region/r.0.0.mcr b/lwjgl-rundir/saves/New World/region/r.0.0.mcr new file mode 100644 index 0000000..48be7c4 Binary files /dev/null and b/lwjgl-rundir/saves/New World/region/r.0.0.mcr differ diff --git a/lwjgl-rundir/saves/New World/session.lock b/lwjgl-rundir/saves/New World/session.lock new file mode 100644 index 0000000..d3e2e6a Binary files /dev/null and b/lwjgl-rundir/saves/New World/session.lock differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b21209d --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.0/userguide/multi_project_builds.html + */ + +rootProject.name = 'eaglercraft-beta' diff --git a/src/lwjgl/java/com/jcraft/jzlib/Adler32.java b/src/lwjgl/java/com/jcraft/jzlib/Adler32.java new file mode 100644 index 0000000..02a07e1 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Adler32.java @@ -0,0 +1,118 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Adler32 implements Checksum { + + // largest prime smaller than 65536 + static final private int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + static final private int NMAX=5552; + + private long s1=1L; + private long s2=0L; + + public void reset(long init){ + s1=init&0xffff; + s2=(init>>16)&0xffff; + } + + public void reset(){ + s1=1L; + s2=0L; + } + + public long getValue(){ + return ((s2<<16)|s1); + } + + public void update(byte[] buf, int index, int len){ + + if(len==1){ + s1+=buf[index++]&0xff; s2+=s1; + s1%=BASE; + s2%=BASE; + return; + } + + int len1 = len/NMAX; + int len2 = len%NMAX; + while(len1-->0) { + int k=NMAX; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + int k=len2; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + public Adler32 copy(){ + Adler32 foo = new Adler32(); + foo.s1 = this.s1; + foo.s2 = this.s2; + return foo; + } + + // The following logic has come from zlib.1.2. + static long combine(long adler1, long adler2, long len2){ + long BASEL = (long)BASE; + long sum1; + long sum2; + long rem; // unsigned int + + rem = len2 % BASEL; + sum1 = adler1 & 0xffffL; + sum2 = rem * sum1; + sum2 %= BASEL; // MOD(sum2); + sum1 += (adler2 & 0xffffL) + BASEL - 1; + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); + if (sum2 >= BASEL) sum2 -= BASEL; + return sum1 | (sum2 << 16); + } + +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/CRC32.java b/src/lwjgl/java/com/jcraft/jzlib/CRC32.java new file mode 100644 index 0000000..a1b6e75 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/CRC32.java @@ -0,0 +1,157 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class CRC32 implements Checksum { + + /* + * The following logic has come from RFC1952. + */ + private int v = 0; + private static int[] crc_table = null; + static { + crc_table = new int[256]; + for (int n = 0; n < 256; n++) { + int c = n; + for (int k = 8; --k >= 0; ) { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + } + + public void update (byte[] buf, int index, int len) { + int c = ~v; + while (--len >= 0) + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); + v = ~c; + } + + public void reset(){ + v = 0; + } + + public void reset(long vv){ + v = (int)(vv&0xffffffffL); + } + + public long getValue(){ + return (long)(v&0xffffffffL); + } + + // The following logic has come from zlib.1.2. + private static final int GF2_DIM = 32; + static long combine(long crc1, long crc2, long len2){ + long row; + long[] even = new long[GF2_DIM]; + long[] odd = new long[GF2_DIM]; + + // degenerate case (also disallow negative lengths) + if (len2 <= 0) + return crc1; + + // put operator for one zero bit in odd + odd[0] = 0xedb88320L; // CRC-32 polynomial + row = 1; + for (int n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + // if no more bits set, then done + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + // if no more bits set, then done + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; + } + + private static long gf2_matrix_times(long[] mat, long vec){ + long sum = 0; + int index = 0; + while (vec!=0) { + if ((vec & 1)!=0) + sum ^= mat[index]; + vec >>= 1; + index++; + } + return sum; + } + + static final void gf2_matrix_square(long[] square, long[] mat) { + for (int n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); + } + + public CRC32 copy(){ + CRC32 foo = new CRC32(); + foo.v = this.v; + return foo; + } + + public static int[] getCRC32Table(){ + int[] tmp = new int[crc_table.length]; + System.arraycopy(crc_table, 0, tmp, 0, tmp.length); + return tmp; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Checksum.java b/src/lwjgl/java/com/jcraft/jzlib/Checksum.java new file mode 100644 index 0000000..1139093 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Checksum.java @@ -0,0 +1,43 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +interface Checksum { + void update(byte[] buf, int index, int len); + void reset(); + void reset(long init); + long getValue(); + Checksum copy(); +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Deflate.java b/src/lwjgl/java/com/jcraft/jzlib/Deflate.java new file mode 100644 index 0000000..cfda0f0 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Deflate.java @@ -0,0 +1,1757 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public +final class Deflate implements Cloneable { + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_DEFAULT_COMPRESSION=-1; + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_MEM_LEVEL=8; + + static class Config{ + int good_length; // reduce lazy search above this match length + int max_lazy; // do not perform lazy search above this match length + int nice_length; // quit search above this match length + int max_chain; + int func; + Config(int good_length, int max_lazy, + int nice_length, int max_chain, int func){ + this.good_length=good_length; + this.max_lazy=max_lazy; + this.nice_length=nice_length; + this.max_chain=max_chain; + this.func=func; + } + } + + static final private int STORED=0; + static final private int FAST=1; + static final private int SLOW=2; + static final private Config[] config_table; + static{ + config_table=new Config[10]; + // good lazy nice chain + config_table[0]=new Config(0, 0, 0, 0, STORED); + config_table[1]=new Config(4, 4, 8, 4, FAST); + config_table[2]=new Config(4, 5, 16, 8, FAST); + config_table[3]=new Config(4, 6, 32, 32, FAST); + + config_table[4]=new Config(4, 4, 16, 16, SLOW); + config_table[5]=new Config(8, 16, 32, 32, SLOW); + config_table[6]=new Config(8, 16, 128, 128, SLOW); + config_table[7]=new Config(8, 32, 128, 256, SLOW); + config_table[8]=new Config(32, 128, 258, 1024, SLOW); + config_table[9]=new Config(32, 258, 258, 4096, SLOW); + } + + static final private String[] z_errmsg = { + "need dictionary", // Z_NEED_DICT 2 + "stream end", // Z_STREAM_END 1 + "", // Z_OK 0 + "file error", // Z_ERRNO (-1) + "stream error", // Z_STREAM_ERROR (-2) + "data error", // Z_DATA_ERROR (-3) + "insufficient memory", // Z_MEM_ERROR (-4) + "buffer error", // Z_BUF_ERROR (-5) + "incompatible version",// Z_VERSION_ERROR (-6) + "" + }; + + // block not completed, need more input or more output + static final private int NeedMore=0; + + // block flush performed + static final private int BlockDone=1; + + // finish started, need only more output at next deflate + static final private int FinishStarted=2; + + // finish done, accept no more input or output + static final private int FinishDone=3; + + // preset dictionary flag in zlib header + static final private int PRESET_DICT=0x20; + + static final private int Z_FILTERED=1; + static final private int Z_HUFFMAN_ONLY=2; + static final private int Z_DEFAULT_STRATEGY=0; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final private int INIT_STATE=42; + static final private int BUSY_STATE=113; + static final private int FINISH_STATE=666; + + // The deflate compression method + static final private int Z_DEFLATED=8; + + static final private int STORED_BLOCK=0; + static final private int STATIC_TREES=1; + static final private int DYN_TREES=2; + + // The three kinds of block type + static final private int Z_BINARY=0; + static final private int Z_ASCII=1; + static final private int Z_UNKNOWN=2; + + static final private int Buf_size=8*2; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final private int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final private int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final private int REPZ_11_138=18; + + static final private int MIN_MATCH=3; + static final private int MAX_MATCH=258; + static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); + + static final private int MAX_BITS=15; + static final private int D_CODES=30; + static final private int BL_CODES=19; + static final private int LENGTH_CODES=29; + static final private int LITERALS=256; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + static final private int END_BLOCK=256; + + ZStream strm; // pointer back to this zlib stream + int status; // as the name implies + byte[] pending_buf; // output still pending + int pending_buf_size; // size of pending_buf + int pending_out; // next pending byte to output to the stream + int pending; // nb of bytes in the pending buffer + int wrap = 1; + byte data_type; // UNKNOWN, BINARY or ASCII + byte method; // STORED (for zip only) or DEFLATED + int last_flush; // value of flush param for previous deflate call + + int w_size; // LZ77 window size (32K by default) + int w_bits; // log2(w_size) (8..16) + int w_mask; // w_size - 1 + + byte[] window; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: use the user input buffer as sliding window. + + int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + short[] head; // Heads of the hash chains or NIL. + + int ins_h; // hash index of string to be inserted + int hash_size; // number of elements in hash table + int hash_bits; // log2(hash_size) + int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + int block_start; + + int match_length; // length of best match + int prev_match; // previous match + int match_available; // set if previous match exists + int strstart; // start of string to insert + int match_start; // start of matching string + int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + int prev_length; + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + int max_chain_length; + + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + int max_lazy_match; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + int level; // compression level (1..9) + int strategy; // favor or force Huffman coding + + // Use a faster search when the previous match is longer than this + int good_match; + + // Stop searching when current match exceeds this + int nice_match; + + short[] dyn_ltree; // literal and length tree + short[] dyn_dtree; // distance tree + short[] bl_tree; // Huffman tree for bit lengths + + Tree l_desc=new Tree(); // desc for literal tree + Tree d_desc=new Tree(); // desc for distance tree + Tree bl_desc=new Tree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + short[] bl_count=new short[MAX_BITS+1]; + // working area to be used in Tree#gen_codes() + short[] next_code=new short[MAX_BITS+1]; + + // heap used to build the Huffman trees + int[] heap=new int[2*L_CODES+1]; + + int heap_len; // number of elements in the heap + int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + byte[] depth=new byte[2*L_CODES+1]; + + byte[] l_buf; // index for literals or lengths */ + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + // - I can't count above 4 + int lit_bufsize; + + int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + int d_buf; // index of pendig_buf + + int opt_len; // bit length of current block with optimal trees + int static_len; // bit length of current block with static trees + int matches; // number of string matches in current block + int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + short bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + int bi_valid; + + GZIPHeader gheader = null; + + Deflate(ZStream strm){ + this.strm=strm; + dyn_ltree=new short[HEAP_SIZE*2]; + dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree + bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths + } + + void lm_init() { + window_size=2*w_size; + + head[hash_size-1]=0; + for(int i=0; i= 3; max_blindex--) { + if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + void send_all_trees(int lcodes, int dcodes, int blcodes){ + int rank; // index in bl_order + + send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes-1, 5); + send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); + } + send_tree(dyn_ltree, lcodes-1); // literal tree + send_tree(dyn_dtree, dcodes-1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + void send_tree (short[] tree,// the tree to be sent + int max_code // and its largest code of non zero frequency + ){ + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0*2+1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0){ max_count = 138; min_count = 3; } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[(n+1)*2+1]; + if(++count < max_count && curlen == nextlen) { + continue; + } + else if(count < min_count) { + do { send_code(curlen, bl_tree); } while (--count != 0); + } + else if(curlen != 0){ + if(curlen != prevlen){ + send_code(curlen, bl_tree); count--; + } + send_code(REP_3_6, bl_tree); + send_bits(count-3, 2); + } + else if(count <= 10){ + send_code(REPZ_3_10, bl_tree); + send_bits(count-3, 3); + } + else{ + send_code(REPZ_11_138, bl_tree); + send_bits(count-11, 7); + } + count = 0; prevlen = curlen; + if(nextlen == 0){ + max_count = 138; min_count = 3; + } + else if(curlen == nextlen){ + max_count = 6; min_count = 3; + } + else{ + max_count = 7; min_count = 4; + } + } + } + + // Output a byte on the stream. + // IN assertion: there is enough room in pending_buf. + final void put_byte(byte[] p, int start, int len){ + System.arraycopy(p, start, pending_buf, pending, len); + pending+=len; + } + + final void put_byte(byte c){ + pending_buf[pending++]=c; + } + final void put_short(int w) { + put_byte((byte)(w/*&0xff*/)); + put_byte((byte)(w>>>8)); + } + final void putShortMSB(int b){ + put_byte((byte)(b>>8)); + put_byte((byte)(b/*&0xff*/)); + } + + final void send_code(int c, short[] tree){ + int c2=c*2; + send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); + } + + void send_bits(int value, int length){ + int len = length; + if (bi_valid > (int)Buf_size - len) { + int val = value; +// bi_buf |= (val << bi_valid); + bi_buf |= ((val << bi_valid)&0xffff); + put_short(bi_buf); + bi_buf = (short)(val >>> (Buf_size - bi_valid)); + bi_valid += len - Buf_size; + } else { +// bi_buf |= (value) << bi_valid; + bi_buf |= (((value) << bi_valid)&0xffff); + bi_valid += len; + } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + void _tr_align(){ + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) { + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + boolean _tr_tally (int dist, // distance of matched string + int lc // match length-MIN_MATCH or unmatched char (if dist==0) + ){ + + pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); + pending_buf[d_buf+last_lit*2+1] = (byte)dist; + + l_buf[last_lit] = (byte)lc; last_lit++; + + if (dist == 0) { + // lc is the unmatched char + dyn_ltree[lc*2]++; + } + else { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; + dyn_dtree[Tree.d_code(dist)*2]++; + } + + if ((last_lit & 0x1fff) == 0 && level > 2) { + // Compute an upper bound for the compressed length + int out_length = last_lit*8; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (int)dyn_dtree[dcode*2] * + (5L+Tree.extra_dbits[dcode]); + } + out_length >>>= 3; + if ((matches < (last_lit/2)) && out_length < in_length/2) return true; + } + + return (last_lit == lit_bufsize-1); + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + // Send the block data compressed using the given Huffman trees + void compress_block(short[] ltree, short[] dtree){ + int dist; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0){ + do{ + dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| + (pending_buf[d_buf+lx*2+1]&0xff); + lc=(l_buf[lx])&0xff; lx++; + + if(dist == 0){ + send_code(lc, ltree); // send a literal byte + } + else{ + // Here, lc is the match length - MIN_MATCH + code = Tree._length_code[lc]; + + send_code(code+LITERALS+1, ltree); // send the length code + extra = Tree.extra_lbits[code]; + if(extra != 0){ + lc -= Tree.base_length[code]; + send_bits(lc, extra); // send the extra length bits + } + dist--; // dist is now the match distance - 1 + code = Tree.d_code(dist); + + send_code(code, dtree); // send the distance code + extra = Tree.extra_dbits[code]; + if (extra != 0) { + dist -= Tree.base_dist[code]; + send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + + // Check that the overlay between pending_buf and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK*2+1]; + } + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + void set_data_type(){ + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} + while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} + while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); + } + + // Flush the bit buffer, keeping at most 7 bits in it. + void bi_flush(){ + if (bi_valid == 16) { + put_short(bi_buf); + bi_buf=0; + bi_valid=0; + } + else if (bi_valid >= 8) { + put_byte((byte)bi_buf); + bi_buf>>>=8; + bi_valid-=8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + void bi_windup(){ + if (bi_valid > 8) { + put_short(bi_buf); + } else if (bi_valid > 0) { + put_byte((byte)bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + void copy_block(int buf, // the input data + int len, // its length + boolean header // true if block header must be written + ){ + int index=0; + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) { + put_short((short)len); + put_short((short)~len); + } + + // while(len--!=0) { + // put_byte(window[buf+index]); + // index++; + // } + put_byte(window, buf, len); + } + + void flush_block_only(boolean eof){ + _tr_flush_block(block_start>=0 ? block_start : -1, + strstart-block_start, + eof); + block_start=strstart; + strm.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + int deflate_stored(int flush){ + // Stored blocks are limited to 0xffff bytes, pending_buf is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if(max_block_size > pending_buf_size - 5) { + max_block_size = pending_buf_size - 5; + } + + // Copy as much as possible from input to output: + while(true){ + // Fill the window as much as possible: + if(lookahead<=1){ + fill_window(); + if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; + if(lookahead==0) break; // flush the current block + } + + strstart+=lookahead; + lookahead=0; + + // Emit a stored block if pending_buf will be full: + max_start=block_start+max_block_size; + if(strstart==0|| strstart>=max_start) { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = (int)(strstart-max_start); + strstart = (int)max_start; + + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + } + } + + flush_block_only(flush == Z_FINISH); + if(strm.avail_out==0) + return (flush == Z_FINISH) ? FinishStarted : NeedMore; + + return flush == Z_FINISH ? FinishDone : BlockDone; + } + + // Send a stored block + void _tr_stored_block(int buf, // input block + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ){ + send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + void _tr_flush_block(int buf, // input block, or NULL if too old + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ) { + int opt_lenb, static_lenb;// opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if(level > 0) { + // Check if the file is ascii or binary + if(data_type == Z_UNKNOWN) set_data_type(); + + // Construct the literal and distance trees + l_desc.build_tree(this); + + d_desc.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex=build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb=(opt_len+3+7)>>>3; + static_lenb=(static_len+3+7)>>>3; + + if(static_lenb<=opt_lenb) opt_lenb=static_lenb; + } + else { + opt_lenb=static_lenb=stored_len+5; // force a stored block + } + + if(stored_len+4<=opt_lenb && buf != -1){ + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if(static_lenb == opt_lenb){ + send_bits((STATIC_TREES<<1)+(eof?1:0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else{ + send_bits((DYN_TREES<<1)+(eof?1:0), 3); + send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); + compress_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + init_block(); + + if(eof){ + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + void fill_window(){ + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do{ + more = (window_size-lookahead-strstart); + + // Deal with !@#$% 64K limit: + if(more==0 && strstart==0 && lookahead==0){ + more = w_size; + } + else if(more==-1) { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { + System.arraycopy(window, w_size, window, 0, w_size); + match_start-=w_size; + strstart-=w_size; // we now have strstart >= MAX_DIST + block_start-=w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p=n; + do { + m = (head[--p]&0xffff); + head[p]=(m>=w_size ? (short)(m-w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do { + m = (prev[--p]&0xffff); + prev[p] = (m >= w_size ? (short)(m-w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n!=0); + more += w_size; + } + + if (strm.avail_in == 0) return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = strm.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if(lookahead >= MIN_MATCH) { + ins_h = window[strstart]&0xff; + ins_h=(((ins_h)<= MIN_MATCH){ + ins_h=(((ins_h)<=MIN_MATCH){ + // check_match(strstart, match_start, match_length); + + bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if(match_length <= max_lazy_match && + lookahead >= MIN_MATCH) { + match_length--; // string at strstart already in hash table + do{ + strstart++; + + ins_h=((ins_h<= MIN_MATCH) { + ins_h=(((ins_h)< 4096))) { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH-1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if(prev_length >= MIN_MATCH && match_length <= prev_length) { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= prev_length-1; + prev_length -= 2; + do{ + if(++strstart <= max_insert) { + ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? + strstart-(w_size-MIN_LOOKAHEAD) : 0; + int nice_match=this.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan+best_len-1]; + byte scan_end = window[scan+best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= good_match) { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (nice_match > lookahead) nice_match = lookahead; + + do { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match+best_len] != scan_end || + window[match+best_len-1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan+1]) continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do { + } while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + scan < strend); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + if(len>best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; + scan_end1 = window[scan+best_len-1]; + scan_end = window[scan+best_len]; + } + + } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit + && --chain_length != 0); + + if (best_len <= lookahead) return best_len; + return lookahead; + } + + int deflateInit(int level, int bits, int memlevel){ + return deflateInit(level, Z_DEFLATED, bits, memlevel, + Z_DEFAULT_STRATEGY); + } + + int deflateInit(int level, int bits){ + return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY); + } + int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + private int deflateInit(int level, int method, int windowBits, + int memLevel, int strategy){ + int wrap = 1; + // byte[] my_version=ZLIB_VERSION; + + // + // if (version == null || version[0] != my_version[0] + // || stream_size != sizeof(z_stream)) { + // return Z_VERSION_ERROR; + // } + + strm.msg = null; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { // undocumented feature: suppress zlib header + wrap = 0; + windowBits = -windowBits; + } + else if(windowBits > 15){ + wrap = 2; + windowBits -= 16; + strm.adler=new CRC32(); + } + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || + method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + strm.dstate = (Deflate)this; + + this.wrap = wrap; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); + + window = new byte[w_size*2]; + prev = new short[w_size]; + head = new short[hash_size]; + + lit_bufsize = 1 << (memLevel + 6); // 16K elements by default + + // We overlay pending_buf and d_buf+l_buf. This works since the average + // output size for (length,distance) codes is <= 24 bits. + pending_buf = new byte[lit_bufsize*3]; + pending_buf_size = lit_bufsize*3; + + d_buf = lit_bufsize; + l_buf = new byte[lit_bufsize]; + + this.level = level; + + this.strategy = strategy; + this.method = (byte)method; + + return deflateReset(); + } + + int deflateReset(){ + strm.total_in = strm.total_out = 0; + strm.msg = null; // + strm.data_type = Z_UNKNOWN; + + pending = 0; + pending_out = 0; + + if(wrap < 0){ + wrap = -wrap; + } + status = (wrap==0) ? BUSY_STATE : INIT_STATE; + strm.adler.reset(); + + last_flush = Z_NO_FLUSH; + + tr_init(); + lm_init(); + return Z_OK; + } + + int deflateEnd(){ + if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ + return Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending_buf=null; + l_buf=null; + head=null; + prev=null; + window=null; + // free + // dstate=null; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + } + + int deflateParams(int _level, int _strategy){ + int err=Z_OK; + + if(_level == Z_DEFAULT_COMPRESSION){ + _level = 6; + } + if(_level < 0 || _level > 9 || + _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + if(config_table[level].func!=config_table[_level].func && + strm.total_in != 0) { + // Flush the last buffer: + err = strm.deflate(Z_PARTIAL_FLUSH); + } + + if(level != _level) { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return err; + } + + int deflateSetDictionary (byte[] dictionary, int dictLength){ + int length = dictLength; + int index=0; + + if(dictionary == null || status != INIT_STATE) + return Z_STREAM_ERROR; + + strm.adler.update(dictionary, 0, dictLength); + + if(length < MIN_MATCH) return Z_OK; + if(length > w_size-MIN_LOOKAHEAD){ + length = w_size-MIN_LOOKAHEAD; + index=dictLength-length; // use the tail of the dictionary + } + System.arraycopy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0]&0xff; + ins_h=(((ins_h)<Z_FINISH || flush<0){ + return Z_STREAM_ERROR; + } + + if(strm.next_out == null || + (strm.next_in == null && strm.avail_in != 0) || + (status == FINISH_STATE && flush != Z_FINISH)) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; + return Z_STREAM_ERROR; + } + if(strm.avail_out == 0){ + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + old_flush = last_flush; + last_flush = flush; + + // Write the zlib header + if(status == INIT_STATE) { + if(wrap == 2){ + getGZIPHeader().put(this); + status=BUSY_STATE; + strm.adler.reset(); + } + else{ + int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; + int level_flags=((level-1)&0xff)>>1; + + if(level_flags>3) level_flags=3; + header |= (level_flags<<6); + if(strstart!=0) header |= PRESET_DICT; + header+=31-(header % 31); + + status=BUSY_STATE; + putShortMSB(header); + + + // Save the adler32 of the preset dictionary: + if(strstart!=0){ + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + strm.adler.reset(); + } + } + + // Flush as much pending output as possible + if(pending != 0) { + strm.flush_pending(); + if(strm.avail_out == 0) { + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if(strm.avail_in==0 && flush <= old_flush && + flush != Z_FINISH) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // User must not provide more input after the first FINISH: + if(status == FINISH_STATE && strm.avail_in != 0) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // Start a new block or continue the current one. + if(strm.avail_in!=0 || lookahead!=0 || + (flush != Z_NO_FLUSH && status != FINISH_STATE)) { + int bstate=-1; + switch(config_table[level].func){ + case STORED: + bstate = deflate_stored(flush); + break; + case FAST: + bstate = deflate_fast(flush); + break; + case SLOW: + bstate = deflate_slow(flush); + break; + default: + } + + if (bstate==FinishStarted || bstate==FinishDone) { + status = FINISH_STATE; + } + if (bstate==NeedMore || bstate==FinishStarted) { + if(strm.avail_out == 0) { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate==BlockDone) { + if(flush == Z_PARTIAL_FLUSH) { + _tr_align(); + } + else { // FULL_FLUSH or SYNC_FLUSH + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if(flush == Z_FULL_FLUSH) { + //state.head[s.hash_size-1]=0; + for(int i=0; i>8)&0xff)); + put_byte((byte)((adler>>16)&0xff)); + put_byte((byte)((adler>>24)&0xff)); + put_byte((byte)(strm.total_in&0xff)); + put_byte((byte)((strm.total_in>>8)&0xff)); + put_byte((byte)((strm.total_in>>16)&0xff)); + put_byte((byte)((strm.total_in>>24)&0xff)); + + getGZIPHeader().setCRC(adler); + } + else{ + // Write the zlib trailer (adler32) + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + + strm.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + + if(wrap > 0) wrap = -wrap; // write the trailer only once! + return pending != 0 ? Z_OK : Z_STREAM_END; + } + + static int deflateCopy(ZStream dest, ZStream src){ + + if(src.dstate == null){ + return Z_STREAM_ERROR; + } + + if(src.next_in!=null){ + dest.next_in = new byte[src.next_in.length]; + System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); + } + dest.next_in_index = src.next_in_index; + dest.avail_in = src.avail_in; + dest.total_in = src.total_in; + + if(src.next_out!=null){ + dest.next_out = new byte[src.next_out.length]; + System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); + } + + dest.next_out_index = src.next_out_index; + dest.avail_out = src.avail_out; + dest.total_out = src.total_out; + + dest.msg = src.msg; + dest.data_type = src.data_type; + dest.adler = src.adler.copy(); + + try{ + dest.dstate = (Deflate)src.dstate.clone(); + dest.dstate.strm = dest; + } + catch(CloneNotSupportedException e){ + // + } + return Z_OK; + } + + public Object clone() throws CloneNotSupportedException { + Deflate dest = (Deflate)super.clone(); + + dest.pending_buf = dup(dest.pending_buf); + dest.d_buf = dest.d_buf; + dest.l_buf = dup(dest.l_buf); + dest.window = dup(dest.window); + + dest.prev = dup(dest.prev); + dest.head = dup(dest.head); + dest.dyn_ltree = dup(dest.dyn_ltree); + dest.dyn_dtree = dup(dest.dyn_dtree); + dest.bl_tree = dup(dest.bl_tree); + + dest.bl_count = dup(dest.bl_count); + dest.next_code = dup(dest.next_code); + dest.heap = dup(dest.heap); + dest.depth = dup(dest.depth); + + dest.l_desc.dyn_tree = dest.dyn_ltree; + dest.d_desc.dyn_tree = dest.dyn_dtree; + dest.bl_desc.dyn_tree = dest.bl_tree; + + /* + dest.l_desc.stat_desc = StaticTree.static_l_desc; + dest.d_desc.stat_desc = StaticTree.static_d_desc; + dest.bl_desc.stat_desc = StaticTree.static_bl_desc; + */ + + if(dest.gheader!=null){ + dest.gheader = (GZIPHeader)dest.gheader.clone(); + } + + return dest; + } + + private byte[] dup(byte[] buf){ + byte[] foo = new byte[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private short[] dup(short[] buf){ + short[] foo = new short[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private int[] dup(int[] buf){ + int[] foo = new int[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + + synchronized GZIPHeader getGZIPHeader(){ + if(gheader==null){ + gheader = new GZIPHeader(); + } + return gheader; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Deflater.java b/src/lwjgl/java/com/jcraft/jzlib/Deflater.java new file mode 100644 index 0000000..ce0580d --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Deflater.java @@ -0,0 +1,171 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Deflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + private boolean finished = false; + + public Deflater(){ + super(); + } + + public Deflater(int level) throws GZIPException { + this(level, MAX_WBITS); + } + + public Deflater(int level, boolean nowrap) throws GZIPException { + this(level, MAX_WBITS, nowrap); + } + + public Deflater(int level, int bits) throws GZIPException { + this(level, bits, false); + } + + public Deflater(int level, int bits, boolean nowrap) throws GZIPException { + super(); + int ret = init(level, bits, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(level, bits, memlevel, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Deflater(int level, int bits, int memlevel) throws GZIPException { + super(); + int ret = init(level, bits, memlevel); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public int init(int level){ + return init(level, MAX_WBITS); + } + public int init(int level, boolean nowrap){ + return init(level, MAX_WBITS, nowrap); + } + public int init(int level, int bits){ + return init(level, bits, false); + } + public int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(level, bits, memlevel); + } + public int init(int level, int bits, int memlevel){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + public int init(int level, int bits, boolean nowrap){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + int ret = dstate.deflate(flush); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + public int end(){ + finished = true; + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + free(); + return ret; + } + public int params(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + public int setDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return finished; + } + + public int copy(Deflater src){ + this.finished = src.finished; + return Deflate.deflateCopy(this, src); + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/DeflaterOutputStream.java b/src/lwjgl/java/com/jcraft/jzlib/DeflaterOutputStream.java new file mode 100644 index 0000000..3c18836 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/DeflaterOutputStream.java @@ -0,0 +1,181 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class DeflaterOutputStream extends FilterOutputStream { + + protected final Deflater deflater; + + protected byte[] buffer; + + private boolean closed = false; + + private boolean syncFlush = false; + + private final byte[] buf1 = new byte[1]; + + protected boolean mydeflater = false; + + private boolean close_out = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + public DeflaterOutputStream(OutputStream out) throws IOException { + this(out, + new Deflater(JZlib.Z_DEFAULT_COMPRESSION), + DEFAULT_BUFSIZE, true); + mydeflater = true; + } + + public DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { + this(out, def, DEFAULT_BUFSIZE, true); + } + + public DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size) throws IOException { + this(out, deflater, size, true); + } + public DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size, + boolean close_out) throws IOException { + super(out); + if (out == null || deflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.deflater = deflater; + buffer = new byte[size]; + this.close_out = close_out; + } + + public void write(int b) throws IOException { + buf1[0] = (byte)(b & 0xff); + write(buf1, 0, 1); + } + + public void write(byte[] b, int off, int len) throws IOException { + if (deflater.finished()) { + throw new IOException("finished"); + } + else if (off<0 | len<0 | off+len>b.length) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return; + } + else { + int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; + deflater.setInput(b, off, len, true); + while (deflater.avail_in>0) { + int err = deflate(flush); + if (err == JZlib.Z_STREAM_END) + break; + } + } + } + + public void finish() throws IOException { + while (!deflater.finished()) { + deflate(JZlib.Z_FINISH); + } + } + + public void close() throws IOException { + if (!closed) { + finish(); + if (mydeflater){ + deflater.end(); + } + if(close_out) + out.close(); + closed = true; + } + } + + protected int deflate(int flush) throws IOException { + deflater.setOutput(buffer, 0, buffer.length); + int err = deflater.deflate(flush); + switch(err) { + case JZlib.Z_OK: + case JZlib.Z_STREAM_END: + break; + case JZlib.Z_BUF_ERROR: + if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ + // flush() without any data + break; + } + default: + throw new IOException("failed to deflate: error="+err+" avail_out="+deflater.avail_out); + } + int len = deflater.next_out_index; + if (len > 0) { + out.write(buffer, 0, len); + } + return err; + } + + public void flush() throws IOException { + if (syncFlush && !deflater.finished()) { + while (true) { + int err = deflate(JZlib.Z_SYNC_FLUSH); + if (deflater.next_out_index < buffer.length) + break; + if (err == JZlib.Z_STREAM_END) + break; + } + } + out.flush(); + } + + public long getTotalIn() { + return deflater.getTotalIn(); + } + + public long getTotalOut() { + return deflater.getTotalOut(); + } + + public void setSyncFlush(boolean syncFlush){ + this.syncFlush = syncFlush; + } + + public boolean getSyncFlush(){ + return this.syncFlush; + } + + public Deflater getDeflater(){ + return deflater; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/GZIPException.java b/src/lwjgl/java/com/jcraft/jzlib/GZIPException.java new file mode 100644 index 0000000..0beef40 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/GZIPException.java @@ -0,0 +1,44 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public class GZIPException extends java.io.IOException { + public GZIPException() { + super(); + } + public GZIPException(String s) { + super(s); + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/GZIPHeader.java b/src/lwjgl/java/com/jcraft/jzlib/GZIPHeader.java new file mode 100644 index 0000000..0405e00 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/GZIPHeader.java @@ -0,0 +1,214 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +import java.io.UnsupportedEncodingException; + +/** + * @see "http://www.ietf.org/rfc/rfc1952.txt" + */ +public class GZIPHeader implements Cloneable { + + public static final byte OS_MSDOS = (byte) 0x00; + public static final byte OS_AMIGA = (byte) 0x01; + public static final byte OS_VMS = (byte) 0x02; + public static final byte OS_UNIX = (byte) 0x03; + public static final byte OS_ATARI = (byte) 0x05; + public static final byte OS_OS2 = (byte) 0x06; + public static final byte OS_MACOS = (byte) 0x07; + public static final byte OS_TOPS20 = (byte) 0x0a; + public static final byte OS_WIN32 = (byte) 0x0b; + public static final byte OS_VMCMS = (byte) 0x04; + public static final byte OS_ZSYSTEM = (byte) 0x08; + public static final byte OS_CPM = (byte) 0x09; + public static final byte OS_QDOS = (byte) 0x0c; + public static final byte OS_RISCOS = (byte) 0x0d; + public static final byte OS_UNKNOWN = (byte) 0xff; + + boolean text = false; + private boolean fhcrc = false; + long time; + int xflags; + int os = 255; + byte[] extra; + byte[] name; + byte[] comment; + int hcrc; + long crc; + boolean done = false; + long mtime = 0; + + public void setModifiedTime(long mtime) { + this.mtime = mtime; + } + + public long getModifiedTime() { + return mtime; + } + + public void setOS(int os) { + if((0<=os && os <=13) || os==255) + this.os=os; + else + throw new IllegalArgumentException("os: "+os); + } + + public int getOS(){ + return os; + } + + public void setName(String name) { + try{ + this.name=name.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); + } + } + + public String getName(){ + if(name==null) return ""; + try { + return new String(name, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setComment(String comment) { + try{ + this.comment=comment.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); + } + } + + public String getComment(){ + if(comment==null) return ""; + try { + return new String(comment, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new InternalError(e.toString()); + } + } + + public void setCRC(long crc){ + this.crc = crc; + } + + public long getCRC(){ + return crc; + } + + void put(Deflate d){ + int flag = 0; + if(text){ + flag |= 1; // FTEXT + } + if(fhcrc){ + flag |= 2; // FHCRC + } + if(extra!=null){ + flag |= 4; // FEXTRA + } + if(name!=null){ + flag |= 8; // FNAME + } + if(comment!=null){ + flag |= 16; // FCOMMENT + } + int xfl = 0; + if(d.level == JZlib.Z_BEST_SPEED){ + xfl |= 4; + } + else if (d.level == JZlib.Z_BEST_COMPRESSION){ + xfl |= 2; + } + + d.put_short((short)0x8b1f); // ID1 ID2 + d.put_byte((byte)8); // CM(Compression Method) + d.put_byte((byte)flag); + d.put_byte((byte)mtime); + d.put_byte((byte)(mtime>>8)); + d.put_byte((byte)(mtime>>16)); + d.put_byte((byte)(mtime>>24)); + d.put_byte((byte)xfl); + d.put_byte((byte)os); + + if(extra!=null){ + d.put_byte((byte)extra.length); + d.put_byte((byte)(extra.length>>8)); + d.put_byte(extra, 0, extra.length); + } + + if(name!=null){ + d.put_byte(name, 0, name.length); + d.put_byte((byte)0); + } + + if(comment!=null){ + d.put_byte(comment, 0, comment.length); + d.put_byte((byte)0); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + GZIPHeader gheader = (GZIPHeader)super.clone(); + byte[] tmp; + if(gheader.extra!=null){ + tmp=new byte[gheader.extra.length]; + System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); + gheader.extra = tmp; + } + + if(gheader.name!=null){ + tmp=new byte[gheader.name.length]; + System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); + gheader.name = tmp; + } + + if(gheader.comment!=null){ + tmp=new byte[gheader.comment.length]; + System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); + gheader.comment = tmp; + } + + return gheader; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/GZIPInputStream.java b/src/lwjgl/java/com/jcraft/jzlib/GZIPInputStream.java new file mode 100644 index 0000000..5d29dca --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/GZIPInputStream.java @@ -0,0 +1,145 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class GZIPInputStream extends InflaterInputStream { + + public GZIPInputStream(InputStream in) throws IOException { + this(in, DEFAULT_BUFSIZE, true); + } + + public GZIPInputStream(InputStream in, + int size, + boolean close_in) throws IOException { + this(in, new Inflater(15+16), size, close_in); + myinflater = true; + } + + public GZIPInputStream(InputStream in, + Inflater inflater, + int size, + boolean close_in) throws IOException { + super(in, inflater, size, close_in); + } + + public long getModifiedtime() { + return inflater.istate.getGZIPHeader().getModifiedTime(); + } + + public int getOS() { + return inflater.istate.getGZIPHeader().getOS(); + } + + public String getName() { + return inflater.istate.getGZIPHeader().getName(); + } + + public String getComment() { + return inflater.istate.getGZIPHeader().getComment(); + } + + public long getCRC() throws GZIPException { + if(inflater.istate.mode != 12 /*DONE*/) + throw new GZIPException("checksum is not calculated yet."); + return inflater.istate.getGZIPHeader().getCRC(); + } + + public void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setOutput(empty, 0, 0); + inflater.setInput(empty, 0, 0, false); + + byte[] b = new byte[10]; + + int n = fill(b); + if(n!=10){ + if(n>0){ + inflater.setInput(b, 0, n, false); + //inflater.next_in_index = n; + inflater.next_in_index = 0; + inflater.avail_in = n; + } + throw new IOException("no input"); + } + + inflater.setInput(b, 0, n, false); + + byte[] b1 = new byte[1]; + do{ + if(inflater.avail_in<=0){ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1, 0, 1, true); + } + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + + if(err!=0/*Z_OK*/){ + int len = 2048-inflater.next_in.length; + if(len>0){ + byte[] tmp = new byte[len]; + n = fill(tmp); + if(n>0){ + inflater.avail_in += inflater.next_in_index; + inflater.next_in_index = 0; + inflater.setInput(tmp, 0, n, true); + } + } + //inflater.next_in_index = inflater.next_in.length; + inflater.avail_in += inflater.next_in_index; + inflater.next_in_index = 0; + throw new IOException(inflater.msg); + } + } + while(inflater.istate.inParsingHeader()); + } + + private int fill(byte[] buf) { + int len = buf.length; + int n = 0; + do{ + int i = -1; + try { + i = in.read(buf, n, buf.length - n); + } + catch(IOException e){ + } + if(i == -1){ + break; + } + n+=i; + } + while(n>> 1){ + case 0: // stored + {b>>>=(3);k-=(3);} + t = k & 7; // go to byte boundary + + {b>>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: // fixed + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); + + {b>>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: // dynamic + + {b>>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: // illegal + + {b>>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(int)(qn) t = n; + if(t>m) t = m; + System.arraycopy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) + { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.length>>=(14);k-=(14);} + + index = 0; + mode = BTREE; + case BTREE: + while (index < 4 + (table >>> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + index = 0; + mode = DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int[] h; + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; + { + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tli, tdi, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); + } + mode = CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(r)) != Z_STREAM_END){ + return inflate_flush(r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(int)(q z.avail_out) n = z.avail_out; + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy as far as end of window + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/InfCodes.java b/src/lwjgl/java/com/jcraft/jzlib/InfCodes.java new file mode 100644 index 0000000..aaf69cd --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/InfCodes.java @@ -0,0 +1,610 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class InfCodes{ + + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + static final private int START=0; // x: set up for LEN + static final private int LEN=1; // i: get length/literal/eob next + static final private int LENEXT=2; // i: getting length extra (have base) + static final private int DIST=3; // i: get distance next + static final private int DISTEXT=4;// i: getting distance extra + static final private int COPY=5; // o: copying bytes in window, waiting for space + static final private int LIT=6; // o: got literal, waiting for output space + static final private int WASH=7; // o: got eob, possibly still output waiting + static final private int END=8; // x: got eob and all data flushed + static final private int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + private final ZStream z; + private final InfBlocks s; + InfCodes(ZStream z, InfBlocks s){ + this.z=z; + this.s=s; + } + + void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + int proc(int r){ + int j; // temporary storage + int[] t; // temporary pointer + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + System.arraycopy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/InfTree.java b/src/lwjgl/java/com/jcraft/jzlib/InfTree.java new file mode 100644 index 0000000..80a2b7b --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/InfTree.java @@ -0,0 +1,518 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class InfTree{ + + static final private int MANY=1440; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final int fixed_bl = 9; + static final int fixed_bd = 5; + + static final int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static final int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static final int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static final int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static final int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static final int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + static final int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>>(w - l); + r[2] = (int)(q - u[h-1] - j); // offset to this table + System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>>w;j>>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.length> 4) + 1; + if(w < 48) + w &= 15; + } + + if(w<8 ||w>15){ + inflateEnd(); + return Z_STREAM_ERROR; + } + if(blocks != null && wbits != w){ + blocks.free(); + blocks=null; + } + + // set window size + wbits=w; + + this.blocks=new InfBlocks(z, 1<>8))&0xff; + + if(((wrap&1)==0 || // check if zlib header allowed + (((this.method << 8)+b) % 31)!=0) && + (this.method&0xf)!=Z_DEFLATED){ + if(wrap == 4){ + z.next_in_index -= 2; + z.avail_in += 2; + z.total_in -= 2; + wrap = 0; + this.mode = BLOCKS; + break; + } + this.mode = BAD; + z.msg = "incorrect header check"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method&0xf)!=Z_DEFLATED){ + this.mode = BAD; + z.msg="unknown compression method"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if(wrap == 4){ + wrap = 1; + } + + if((this.method>>4)+8>this.wbits){ + this.mode = BAD; + z.msg="invalid window size"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + z.adler=new Adler32(); + + if((b&PRESET_DICT)==0){ + this.mode = BLOCKS; + break; + } + this.mode = DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode=DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode=DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler.reset(this.need); + this.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + this.mode = BAD; + z.msg = "need dictionary"; + this.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + r = this.blocks.proc(r); + if(r == Z_DATA_ERROR){ + this.mode = BAD; + this.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + this.was=z.adler.getValue(); + this.blocks.reset(); + if(this.wrap==0){ + this.mode=DONE; + break; + } + this.mode=CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode = CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode = CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(flags!=0){ // gzip + this.need = ((this.need&0xff000000)>>24 | + (this.need&0x00ff0000)>>8 | + (this.need&0x0000ff00)<<8 | + (this.need&0x0000ffff)<<24)&0xffffffffL; + } + + if(((int)(this.was)) != ((int)(this.need))){ + z.msg = "incorrect data check"; + // chack is delayed + /* + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + */ + } + else if(flags!=0 && gheader!=null){ + gheader.crc = this.need; + } + + this.mode = LENGTH; + case LENGTH: + if (wrap!=0 && flags!=0) { + + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + + if (this.need != (z.total_out & 0xffffffffL)) { + z.msg = "incorrect length check"; + this.mode = BAD; + break; + } + z.msg = null; + } + else { + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + } + + this.mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + + case FLAGS: + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + flags = ((int)this.need)&0xffff; + + if ((flags & 0xff) != Z_DEFLATED) { + z.msg = "unknown compression method"; + this.mode = BAD; + break; + } + if ((flags & 0xe000)!=0) { + z.msg = "unknown header flags set"; + this.mode = BAD; + break; + } + + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + + this.mode = TIME; + + case TIME: + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null) + gheader.time = this.need; + if ((flags & 0x0200)!=0){ + checksum(4, this.need); + } + this.mode = OS; + case OS: + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.xflags = ((int)this.need)&0xff; + gheader.os = (((int)this.need)>>8)&0xff; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + this.mode = EXLEN; + case EXLEN: + if ((flags & 0x0400)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.extra = new byte[((int)this.need)&0xffff]; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = EXTRA; + + case EXTRA: + if ((flags & 0x0400)!=0) { + try { + r=readBytes(r, f); + if(gheader!=null){ + byte[] foo = tmp_string.toByteArray(); + tmp_string=null; + if(foo.length == gheader.extra.length){ + System.arraycopy(foo, 0, gheader.extra, 0, foo.length); + } + else{ + z.msg = "bad extra field length"; + this.mode = BAD; + break; + } + } + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = NAME; + case NAME: + if ((flags & 0x0800)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.name=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.name=null; + } + this.mode = COMMENT; + case COMMENT: + if ((flags & 0x1000)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.comment=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.comment=null; + } + this.mode = HCRC; + case HCRC: + if ((flags & 0x0200)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.hcrc=(int)(this.need&0xffff); + } + if(this.need != (z.adler.getValue()&0xffffL)){ + this.mode = BAD; + z.msg = "header crc mismatch"; + this.marker = 5; // can't try inflateSync + break; + } + } + z.adler = new CRC32(); + + this.mode = BLOCKS; + break; + default: + return Z_STREAM_ERROR; + } + } + } + + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(z==null || (this.mode != DICT0 && this.wrap != 0)){ + return Z_STREAM_ERROR; + } + + int index=0; + int length = dictLength; + + if(this.mode==DICT0){ + long adler_need=z.adler.getValue(); + z.adler.reset(); + z.adler.update(dictionary, 0, dictLength); + if(z.adler.getValue()!=adler_need){ + return Z_DATA_ERROR; + } + } + + z.adler.reset(); + + if(length >= (1<0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + this.need = this.need | + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); + need_bytes--; + } + if(n==2){ + this.need&=0xffffL; + } + else if(n==4) { + this.need&=0xffffffffL; + } + need_bytes=-1; + return r; + } + class Return extends Exception{ + int r; + Return(int r){this.r=r; } + } + + private java.io.ByteArrayOutputStream tmp_string = null; + private int readString(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + do { + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + }while(b!=0); + return r; + } + + private int readBytes(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new java.io.ByteArrayOutputStream(); + } + int b=0; + while(this.need>0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + this.need--; + } + return r; + } + + private void checksum(int n, long v){ + for(int i=0; i>=8; + } + z.adler.update(crcbuf, 0, n); + } + + public GZIPHeader getGZIPHeader(){ + return gheader; + } + + boolean inParsingHeader(){ + switch(mode){ + case HEAD: + case DICT4: + case DICT3: + case DICT2: + case DICT1: + case FLAGS: + case TIME: + case OS: + case EXLEN: + case EXTRA: + case NAME: + case COMMENT: + case HCRC: + return true; + default: + return false; + } + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Inflater.java b/src/lwjgl/java/com/jcraft/jzlib/Inflater.java new file mode 100644 index 0000000..0fb0b09 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Inflater.java @@ -0,0 +1,168 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class Inflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public Inflater() { + super(); + init(); + } + + public Inflater(JZlib.WrapperType wrapperType) throws GZIPException { + this(DEF_WBITS, wrapperType); + } + + public Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(w, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + public Inflater(int w) throws GZIPException { + this(w, false); + } + + public Inflater(boolean nowrap) throws GZIPException { + this(DEF_WBITS, nowrap); + } + + public Inflater(int w, boolean nowrap) throws GZIPException { + super(); + int ret = init(w, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + private boolean finished = false; + + public int init(){ + return init(DEF_WBITS); + } + + public int init(JZlib.WrapperType wrapperType){ + return init(DEF_WBITS, wrapperType); + } + + public int init(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(w, nowrap); + } + + public int init(boolean nowrap){ + return init(DEF_WBITS, nowrap); + } + + public int init(int w){ + return init(w, false); + } + + public int init(int w, boolean nowrap){ + finished = false; + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + int ret = istate.inflate(f); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + + public int end(){ + finished = true; + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + + public int sync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + + public int syncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + + public int setDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return istate.mode==12 /*DONE*/; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/InflaterInputStream.java b/src/lwjgl/java/com/jcraft/jzlib/InflaterInputStream.java new file mode 100644 index 0000000..0420582 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/InflaterInputStream.java @@ -0,0 +1,247 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +public class InflaterInputStream extends FilterInputStream { + protected final Inflater inflater; + protected byte[] buf; + + private boolean closed = false; + + private boolean eof = false; + + private boolean close_in = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + public InflaterInputStream(InputStream in) throws IOException { + this(in, false); + } + + public InflaterInputStream(InputStream in, boolean nowrap) throws IOException { + this(in, new Inflater(nowrap)); + myinflater = true; + } + + public InflaterInputStream(InputStream in, Inflater inflater) throws IOException { + this(in, inflater, DEFAULT_BUFSIZE); + } + + public InflaterInputStream(InputStream in, + Inflater inflater, int size) throws IOException { + this(in, inflater, size, true); + } + + public InflaterInputStream(InputStream in, + Inflater inflater, + int size, boolean close_in) throws IOException { + super(in); + if (in == null || inflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.inflater = inflater; + buf = new byte[size]; + this.close_in = close_in; + } + + protected boolean myinflater = false; + + private byte[] byte1 = new byte[1]; + + public int read() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (b == null) { + throw new NullPointerException(); + } + else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return 0; + } + else if (eof) { + return -1; + } + + int n = 0; + inflater.setOutput(b, off, len); + while(!eof) { + if(inflater.avail_in==0) + fill(); + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + n += inflater.next_out_index - off; + off = inflater.next_out_index; + switch(err) { + case JZlib.Z_DATA_ERROR: + throw new IOException(inflater.msg); + case JZlib.Z_STREAM_END: + case JZlib.Z_NEED_DICT: + eof = true; + if(err == JZlib.Z_NEED_DICT) + return -1; + break; + default: + } + if(inflater.avail_out==0) + break; + } + return n; + } + + public int available() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (eof) { + return 0; + } + else { + return 1; + } + } + + private byte[] b = new byte[512]; + + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("negative skip length"); + } + + if (closed) { throw new IOException("Stream closed"); } + + int max = (int)Math.min(n, Integer.MAX_VALUE); + int total = 0; + while (total < max) { + int len = max - total; + if (len > b.length) { + len = b.length; + } + len = read(b, 0, len); + if (len == -1) { + eof = true; + break; + } + total += len; + } + return total; + } + + public void close() throws IOException { + if (!closed) { + if (myinflater) + inflater.end(); + if(close_in) + in.close(); + closed = true; + } + } + + protected void fill() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + int len = in.read(buf, 0, buf.length); + if (len == -1) { + if(inflater.istate.wrap == 0 && + !inflater.finished()){ + buf[0]=0; + len=1; + } + else if(inflater.istate.was != -1){ // in reading trailer + throw new IOException("footer is not found"); + } + else{ + throw new EOFException("Unexpected end of ZLIB input stream"); + } + } + inflater.setInput(buf, 0, len, true); + } + + public boolean markSupported() { + return false; + } + + public synchronized void mark(int readlimit) { + } + + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + public long getTotalIn() { + return inflater.getTotalIn(); + } + + public long getTotalOut() { + return inflater.getTotalOut(); + } + + public byte[] getAvailIn() { + if(inflater.avail_in<=0) + return null; + byte[] tmp = new byte[inflater.avail_in]; + System.arraycopy(inflater.next_in, inflater.next_in_index, + tmp, 0, inflater.avail_in); + return tmp; + } + + public void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setInput(empty, 0, 0, false); + inflater.setOutput(empty, 0, 0); + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(!inflater.istate.inParsingHeader()){ + return; + } + + byte[] b1 = new byte[1]; + do{ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1); + err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(err!=0/*Z_OK*/) + throw new IOException(inflater.msg); + } + while(inflater.istate.inParsingHeader()); + } + + public Inflater getInflater(){ + return inflater; + } +} \ No newline at end of file diff --git a/src/lwjgl/java/com/jcraft/jzlib/JZlib.java b/src/lwjgl/java/com/jcraft/jzlib/JZlib.java new file mode 100644 index 0000000..a4bb341 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/JZlib.java @@ -0,0 +1,92 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final public class JZlib{ + private static final String version="1.1.0"; + public static String version(){return version;} + + static final public int MAX_WBITS=15; // 32K LZ77 window + static final public int DEF_WBITS=MAX_WBITS; + + public enum WrapperType { + NONE, ZLIB, GZIP, ANY + } + + public static final WrapperType W_NONE = WrapperType.NONE; + public static final WrapperType W_ZLIB = WrapperType.ZLIB; + public static final WrapperType W_GZIP = WrapperType.GZIP; + public static final WrapperType W_ANY = WrapperType.ANY; + + // compression levels + static final public int Z_NO_COMPRESSION=0; + static final public int Z_BEST_SPEED=1; + static final public int Z_BEST_COMPRESSION=9; + static final public int Z_DEFAULT_COMPRESSION=(-1); + + // compression strategy + static final public int Z_FILTERED=1; + static final public int Z_HUFFMAN_ONLY=2; + static final public int Z_DEFAULT_STRATEGY=0; + + static final public int Z_NO_FLUSH=0; + static final public int Z_PARTIAL_FLUSH=1; + static final public int Z_SYNC_FLUSH=2; + static final public int Z_FULL_FLUSH=3; + static final public int Z_FINISH=4; + + static final public int Z_OK=0; + static final public int Z_STREAM_END=1; + static final public int Z_NEED_DICT=2; + static final public int Z_ERRNO=-1; + static final public int Z_STREAM_ERROR=-2; + static final public int Z_DATA_ERROR=-3; + static final public int Z_MEM_ERROR=-4; + static final public int Z_BUF_ERROR=-5; + static final public int Z_VERSION_ERROR=-6; + + // The three kinds of block type + static final public byte Z_BINARY = 0; + static final public byte Z_ASCII = 1; + static final public byte Z_UNKNOWN = 2; + + public static long adler32_combine(long adler1, long adler2, long len2){ + return Adler32.combine(adler1, adler2, len2); + } + + public static long crc32_combine(long crc1, long crc2, long len2){ + return CRC32.combine(crc1, crc2, len2); + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/StaticTree.java b/src/lwjgl/java/com/jcraft/jzlib/StaticTree.java new file mode 100644 index 0000000..e35931c --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/StaticTree.java @@ -0,0 +1,148 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class StaticTree{ + static final private int MAX_BITS=15; + + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + static final short[] static_ltree = { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, + 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, + 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, + 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, + 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, + 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, + 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, + 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, + 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, + 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, + 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, + 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, + 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, + 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, + 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, + 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, + 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, + 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, + 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, + 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, + 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, + 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, + 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, + 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, + 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, + 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, + 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, + 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, + 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, + 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, + 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, + 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, + 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, + 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, + 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, + 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, + 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, + 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, + 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, + 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, + 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, + 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, + 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, + 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, + 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, + 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, + 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, + 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, + 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, + 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, + 163, 8, 99, 8, 227, 8 + }; + + static final short[] static_dtree = { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, + 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, + 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, + 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, + 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, + 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 + }; + + static StaticTree static_l_desc = + new StaticTree(static_ltree, Tree.extra_lbits, + LITERALS+1, L_CODES, MAX_BITS); + + static StaticTree static_d_desc = + new StaticTree(static_dtree, Tree.extra_dbits, + 0, D_CODES, MAX_BITS); + + static StaticTree static_bl_desc = + new StaticTree(null, Tree.extra_blbits, + 0, BL_CODES, MAX_BL_BITS); + + short[] static_tree; // static tree or null + int[] extra_bits; // extra bits for each code or null + int extra_base; // base index for extra_bits + int elems; // max number of elements in the tree + int max_length; // max bit length for the codes + + private StaticTree(short[] static_tree, + int[] extra_bits, + int extra_base, + int elems, + int max_length){ + this.static_tree=static_tree; + this.extra_bits=extra_bits; + this.extra_base=extra_base; + this.elems=elems; + this.max_length=max_length; + } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/Tree.java b/src/lwjgl/java/com/jcraft/jzlib/Tree.java new file mode 100644 index 0000000..38cb40f --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/Tree.java @@ -0,0 +1,367 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +final class Tree{ + static final private int MAX_BITS=15; + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + // end of block literal code + static final int END_BLOCK=256; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final int REPZ_11_138=18; + + // extra bits for each length code + static final int[] extra_lbits={ + 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 + }; + + // extra bits for each distance code + static final int[] extra_dbits={ + 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 + }; + + // extra bits for each bit length code + static final int[] extra_blbits={ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 + }; + + static final byte[] bl_order={ + 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + static final int Buf_size=8*2; + + // see definition of array dist_code below + static final int DIST_CODE_LEN=512; + + static final byte[] _dist_code = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + static final byte[] _length_code={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + static final int[] base_length = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + static final int[] base_dist = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + // Mapping from a distance to a distance code. dist is the distance - 1 and + // must not have side effects. _dist_code[256] and _dist_code[257] are never + // used. + static int d_code(int dist){ + return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); + } + + short[] dyn_tree; // the dynamic tree + int max_code; // largest code with non zero frequency + StaticTree stat_desc; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + void gen_bitlen(Deflate s){ + short[] tree = dyn_tree; + short[] stree = stat_desc.static_tree; + int[] extra = stat_desc.extra_bits; + int base = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap + + for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } + tree[n*2+1] = (short)bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n*2]; + s.opt_len += f * (bits + xbits); + if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); + } + if (overflow == 0) return; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do { + bits = max_length-1; + while(s.bl_count[bits]==0) bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits+1]+=2; // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = s.bl_count[bits]; + while (n != 0) { + m = s.heap[--h]; + if (m > max_code) continue; + if (tree[m*2+1] != bits) { + s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; + tree[m*2+1] = (short)bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + void build_tree(Deflate s){ + short[] tree=dyn_tree; + short[] stree=stat_desc.static_tree; + int elems=stat_desc.elems; + int n, m; // iterate over heap elements + int max_code=-1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for(n=0; n=1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node=elems; // next internal node of the tree + do{ + // n = node of least frequency + n=s.heap[1]; + s.heap[1]=s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m=s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node*2] = (short)(tree[n*2] + tree[m*2]); + s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); + tree[n*2+1] = tree[m*2+1] = (short)node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while(s.heap_len>=2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count, s.next_code); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + private final static void gen_codes( + short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count, // number of codes at each bit length + short[] next_code){ + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + next_code[0]=0; + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; + res<<=1; + } + while(--len>0); + return res>>>1; + } +} + diff --git a/src/lwjgl/java/com/jcraft/jzlib/ZInputStream.java b/src/lwjgl/java/com/jcraft/jzlib/ZInputStream.java new file mode 100644 index 0000000..cbd38e1 --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/ZInputStream.java @@ -0,0 +1,126 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jcraft.jzlib; +import java.io.*; + +/** + * ZInputStream + * + * @deprecated use DeflaterOutputStream or InflaterInputStream + */ +@Deprecated +public class ZInputStream extends FilterInputStream { + + protected int flush=JZlib.Z_NO_FLUSH; + protected boolean compress; + protected InputStream in=null; + + protected Deflater deflater; + protected InflaterInputStream iis; + + public ZInputStream(InputStream in) throws IOException { + this(in, false); + } + public ZInputStream(InputStream in, boolean nowrap) throws IOException { + super(in); + iis = new InflaterInputStream(in, nowrap); + compress=false; + } + + public ZInputStream(InputStream in, int level) throws IOException { + super(in); + this.in=in; + deflater = new Deflater(); + deflater.init(level); + compress=true; + } + + private byte[] buf1 = new byte[1]; + public int read() throws IOException { + if(read(buf1, 0, 1)==-1) return -1; + return(buf1[0]&0xFF); + } + + private byte[] buf = new byte[512]; + + public int read(byte[] b, int off, int len) throws IOException { + if(compress){ + deflater.setOutput(b, off, len); + while(true){ + int datalen = in.read(buf, 0, buf.length); + if(datalen == -1) return -1; + deflater.setInput(buf, 0, datalen, true); + int err = deflater.deflate(flush); + if(deflater.next_out_index>0) + return deflater.next_out_index; + if(err == JZlib.Z_STREAM_END) + return 0; + if(err == JZlib.Z_STREAM_ERROR || + err == JZlib.Z_DATA_ERROR){ + throw new ZStreamException("deflating: "+deflater.msg); + } + } + } + else{ + return iis.read(b, off, len); + } + } + + public long skip(long n) throws IOException { + int len=512; + if(n0){ + inflater.setOutput(buf, 0, buf.length); + err = inflater.inflate(flush); + if(inflater.next_out_index>0) + out.write(buf, 0, inflater.next_out_index); + if(err != JZlib.Z_OK) + break; + } + if(err != JZlib.Z_OK) + throw new ZStreamException("inflating: "+inflater.msg); + return; + } + } + + public int getFlushMode() { + return flush; + } + + public void setFlushMode(int flush) { + this.flush=flush; + } + + public void finish() throws IOException { + int err; + if(compress){ + int tmp = flush; + int flush = JZlib.Z_FINISH; + try{ + write("".getBytes(), 0, 0); + } + finally { flush = tmp; } + } + else{ + dos.finish(); + } + flush(); + } + public synchronized void end() { + if(end) return; + if(compress){ + try { dos.finish(); } catch(Exception e){} + } + else{ + inflater.end(); + } + end=true; + } + public void close() throws IOException { + try{ + try{finish();} + catch (IOException ignored) {} + } + finally{ + end(); + out.close(); + out=null; + } + } + + public long getTotalIn() { + if(compress) return dos.getTotalIn(); + else return inflater.total_in; + } + + public long getTotalOut() { + if(compress) return dos.getTotalOut(); + else return inflater.total_out; + } + + public void flush() throws IOException { + out.flush(); + } + +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/ZStream.java b/src/lwjgl/java/com/jcraft/jzlib/ZStream.java new file mode 100644 index 0000000..0afa4fd --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/ZStream.java @@ -0,0 +1,377 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +/** + * ZStream + * + * @deprecated Not for public use in the future. + */ +@Deprecated +public class ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public byte[] next_in; // next input byte + public int next_in_index; + public int avail_in; // number of bytes available at next_in + public long total_in; // total nb of input bytes read so far + + public byte[] next_out; // next output byte should be put there + public int next_out_index; + public int avail_out; // remaining free space at next_out + public long total_out; // total nb of bytes output so far + + public String msg; + + Deflate dstate; + Inflate istate; + + int data_type; // best guess about the data type: ascii or binary + + Checksum adler; + + public ZStream(){ + this(new Adler32()); + } + + public ZStream(Checksum adler){ + this.adler=adler; + } + + public int inflateInit(){ + return inflateInit(DEF_WBITS); + } + public int inflateInit(boolean nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + public int inflateInit(int w){ + return inflateInit(w, false); + } + public int inflateInit(JZlib.WrapperType wrapperType) { + return inflateInit(DEF_WBITS, wrapperType); + } + public int inflateInit(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return inflateInit(w, nowrap); + } + public int inflateInit(int w, boolean nowrap){ + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(f); + } + public int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + public int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + public int inflateSyncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + public int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + public boolean inflateFinished(){ + return istate.mode==12 /*DONE*/; + } + + public int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + public int deflateInit(int level, boolean nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + public int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + public int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return this.deflateInit(level, bits, memlevel); + } + public int deflateInit(int level, int bits, int memlevel){ + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + public int deflateInit(int level, int bits, boolean nowrap){ + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + public int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(flush); + } + public int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + public int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + public int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.length<=dstate.pending_out || + next_out.length<=next_out_index || + dstate.pending_buf.length<(dstate.pending_out+len) || + next_out.length<(next_out_index+len)){ + //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + //System.out.println("avail_out="+avail_out); + } + + System.arraycopy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.wrap!=0) { + adler.update(next_in, next_in_index, len); + } + System.arraycopy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + public long getAdler(){ + return adler.getValue(); + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + } + + public void setOutput(byte[] buf){ + setOutput(buf, 0, buf.length); + } + + public void setOutput(byte[] buf, int off, int len){ + next_out = buf; + next_out_index = off; + avail_out = len; + } + + public void setInput(byte[] buf){ + setInput(buf, 0, buf.length, false); + } + + public void setInput(byte[] buf, boolean append){ + setInput(buf, 0, buf.length, append); + } + + public void setInput(byte[] buf, int off, int len, boolean append){ + if(len<=0 && append && next_in!=null) return; + + if(avail_in>0 && append){ + byte[] tmp = new byte[avail_in+len]; + System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); + System.arraycopy(buf, off, tmp, avail_in, len); + next_in=tmp; + next_in_index=0; + avail_in+=len; + } + else{ + next_in=buf; + next_in_index=off; + avail_in=len; + } + } + + public byte[] getNextIn(){ + return next_in; + } + + public void setNextIn(byte[] next_in){ + this.next_in = next_in; + } + + public int getNextInIndex(){ + return next_in_index; + } + + public void setNextInIndex(int next_in_index){ + this.next_in_index = next_in_index; + } + + public int getAvailIn(){ + return avail_in; + } + + public void setAvailIn(int avail_in){ + this.avail_in = avail_in; + } + + public byte[] getNextOut(){ + return next_out; + } + + public void setNextOut(byte[] next_out){ + this.next_out = next_out; + } + + public int getNextOutIndex(){ + return next_out_index; + } + + public void setNextOutIndex(int next_out_index){ + this.next_out_index = next_out_index; + } + + public int getAvailOut(){ + return avail_out; + + } + + public void setAvailOut(int avail_out){ + this.avail_out = avail_out; + } + + public long getTotalOut(){ + return total_out; + } + + public long getTotalIn(){ + return total_in; + } + + public String getMessage(){ + return msg; + } + + /** + * Those methods are expected to be override by Inflater and Deflater. + * In the future, they will become abstract methods. + */ + public int end(){ return Z_OK; } + public boolean finished(){ return false; } +} diff --git a/src/lwjgl/java/com/jcraft/jzlib/ZStreamException.java b/src/lwjgl/java/com/jcraft/jzlib/ZStreamException.java new file mode 100644 index 0000000..308bb8a --- /dev/null +++ b/src/lwjgl/java/com/jcraft/jzlib/ZStreamException.java @@ -0,0 +1,44 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jzlib; + +public class ZStreamException extends java.io.IOException { + public ZStreamException() { + super(); + } + public ZStreamException(String s) { + super(s); + } +} diff --git a/src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java b/src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java new file mode 100644 index 0000000..3049639 --- /dev/null +++ b/src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java @@ -0,0 +1,586 @@ +package de.cuina.fireandfuel; + +/* + * CodecJLayerMP3 - an ICodec interface for Paulscode Sound System + * Copyright (C) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see http://www.gnu.org/licenses/lgpl.txt + */ + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.net.URL; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.Obuffer; +import javazoom.mp3spi.DecodedMpegAudioInputStream; + +import paulscode.sound.ICodec; +import paulscode.sound.SoundBuffer; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.SoundSystemLogger; + +/** + * The CodecJLayer class provides an ICodec interface to the external JLayer + * library. + * + *
+ *
+ * This software is based on or using the JLayer and mp3spi library from + * http://www.javazoom.net/javalayer/javalayer.html and Tritonus library from + * http://www.tritonus.org/. + * + * JLayer, mp3spi and Tritonus library are released under the conditions of + * GNU Library General Public License version 2 or (at your option) + * any later version of the License. + *

+ */ + +public class CodecJLayerMP3 implements ICodec +{ + /** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + + /** + * Used to set the value in one of the synchronized boolean-interface + * methods. + */ + private static final boolean SET = true; + + /** + * Used when a parameter for one of the synchronized boolean-interface + * methods is not applicable. + */ + private static final boolean XXX = false; + + /** + * True if there is no more data to read in. + */ + private boolean endOfStream = false; + + /** + * True if the stream has finished initializing. + */ + private boolean initialized = false; + + private Decoder decoder; + private Bitstream bitstream; + private DMAISObuffer buffer; + + private Header mainHeader; + + /** + * Audio format to use when playing back the wave data. + */ + private AudioFormat myAudioFormat = null; + + /** + * Input stream to use for reading in pcm data. + */ + private DecodedMpegAudioInputStream myAudioInputStream = null; + + /** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + + public CodecJLayerMP3() + { + logger = SoundSystemConfig.getLogger(); + } + + @Override + public void reverseByteOrder(boolean b) + { + } + + @Override + public boolean initialize(URL url) + { + initialized(SET, false); + cleanup(); + if(url == null) + { + errorMessage("url null in method 'initialize'"); + cleanup(); + return false; + } + + try + { + bitstream = new Bitstream(new BufferedInputStream(url.openStream())); + decoder = new Decoder(); + + mainHeader = bitstream.readFrame(); + + buffer = new DMAISObuffer(2); + decoder.setOutputBuffer(buffer); + + int channels; + if(mainHeader.mode() < 3) + channels = 2; + else channels = 1; + + bitstream.closeFrame(); + bitstream.close(); + + myAudioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, + mainHeader.frequency(), 16, channels, channels * 2, mainHeader.frequency(), + false); + + AudioFormat mpegAudioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, -1.0f, + 16, channels, channels * 2, -1.0f, false); + + myAudioInputStream = new DecodedMpegAudioInputStream(myAudioFormat, + new AudioInputStream(new BufferedInputStream(url.openStream()), + mpegAudioFormat, -1)); + myAudioInputStream.skip((int)(myAudioInputStream.getFormat().getFrameRate() * 0.018f) * myAudioInputStream.getFormat().getFrameSize()); + } catch (Exception e) + { + errorMessage("Unable to set up input streams in method " + "'initialize'"); + printStackTrace(e); + cleanup(); + return false; + } + + if(myAudioInputStream == null) + { + errorMessage("Unable to set up audio input stream in method " + "'initialize'"); + cleanup(); + return false; + } + + endOfStream(SET, false); + initialized(SET, true); + return true; + } + + @Override + public boolean initialized() + { + return initialized(GET, XXX); + } + + @Override + public SoundBuffer read() + { + if(myAudioInputStream == null) + { + endOfStream(SET, true); + return null; + } + + // Get the format for the audio data: + AudioFormat audioFormat = myAudioInputStream.getFormat(); + + // Check to make sure there is an audio format: + if(audioFormat == null) + { + errorMessage("Audio Format null in method 'read'"); + endOfStream(SET, true); + return null; + } + + // Variables used when reading from the audio input stream: + int bytesRead = 0, cnt = 0; + + // Allocate memory for the audio data: + byte[] streamBuffer = new byte[SoundSystemConfig.getStreamingBufferSize()]; + + try + { + // Read until buffer is full or end of stream is reached: + while((!endOfStream(GET, XXX)) && (bytesRead < streamBuffer.length)) + { + myAudioInputStream.execute(); + if((cnt = myAudioInputStream.read(streamBuffer, bytesRead, streamBuffer.length + - bytesRead)) < 0) + { + endOfStream(SET, true); + break; + } + // keep track of how many bytes were read: + bytesRead += cnt; + } + } catch (IOException ioe) + { + + /* + * errorMessage( "Exception thrown while reading from the " + + * "AudioInputStream (location #3)." ); printStackTrace( e ); return + * null; + */// TODO: Figure out why this exceptions is being thrown at end of + // MP3 files! + endOfStream(SET, true); + return null; + } catch (ArrayIndexOutOfBoundsException e) + { + //this exception is thrown at the end of the mp3's + endOfStream(SET, true); + return null; + } + + // Return null if no data was read: + if(bytesRead <= 0) + { + endOfStream(SET, true); + return null; + } + + // Insert the converted data into a ByteBuffer: + // byte[] data = convertAudioBytes(streamBuffer, + // audioFormat.getSampleSizeInBits() == 16); + + // Wrap the data into a SoundBuffer: + SoundBuffer buffer = new SoundBuffer(streamBuffer, audioFormat); + + // Return the result: + return buffer; + } + + @Override + public SoundBuffer readAll() + { + // Check to make sure there is an audio format: + if(myAudioFormat == null) + { + errorMessage("Audio Format null in method 'readAll'"); + return null; + } + + // Array to contain the audio data: + byte[] fullBuffer = null; + + // Determine how much data will be read in: + int fileSize = myAudioFormat.getChannels() * (int) myAudioInputStream.getFrameLength() + * myAudioFormat.getSampleSizeInBits() / 8; + if(fileSize > 0) + { + // Allocate memory for the audio data: + fullBuffer = new byte[myAudioFormat.getChannels() + * (int) myAudioInputStream.getFrameLength() + * myAudioFormat.getSampleSizeInBits() / 8]; + int read = 0, total = 0; + try + { + // Read until the end of the stream is reached: + while((read = myAudioInputStream.read(fullBuffer, total, fullBuffer.length - total)) != -1 + && total < fullBuffer.length) + { + total += read; + } + } catch (IOException e) + { + errorMessage("Exception thrown while reading from the " + + "AudioInputStream (location #1)."); + printStackTrace(e); + return null; + } + } else + { + // Total file size unknown. + + // Variables used when reading from the audio input stream: + int totalBytes = 0, bytesRead = 0, cnt = 0; + byte[] smallBuffer = null; + + // Allocate memory for a chunk of data: + smallBuffer = new byte[SoundSystemConfig.getFileChunkSize()]; + + // Read until end of file or maximum file size is reached: + while((!endOfStream(GET, XXX)) && (totalBytes < SoundSystemConfig.getMaxFileSize())) + { + bytesRead = 0; + cnt = 0; + + try + { + // Read until small buffer is filled or end of file reached: + while(bytesRead < smallBuffer.length) + { + myAudioInputStream.execute(); + if((cnt = myAudioInputStream.read(smallBuffer, bytesRead, + smallBuffer.length - bytesRead)) < 0) + { + endOfStream(SET, true); + break; + } + bytesRead += cnt; + } + } catch (IOException e) + { + errorMessage("Exception thrown while reading from the " + + "AudioInputStream (location #2)."); + printStackTrace(e); + return null; + } + + // Reverse byte order if necessary: + // if( reverseBytes ) + // reverseBytes( smallBuffer, 0, bytesRead ); + + // Keep track of the total number of bytes read: + totalBytes += bytesRead; + + // Append the small buffer to the full buffer: + fullBuffer = appendByteArrays(fullBuffer, smallBuffer, bytesRead); + } + } + + // Insert the converted data into a ByteBuffer + // byte[] data = convertAudioBytes( fullBuffer, + // myAudioFormat.getSampleSizeInBits() == 16 ); + + // Wrap the data into an SoundBuffer: + SoundBuffer soundBuffer = new SoundBuffer(fullBuffer, myAudioFormat); + + // Close the audio input stream + try + { + myAudioInputStream.close(); + } catch (IOException e) + { + } + + // Return the result: + return soundBuffer; + } + + @Override + public boolean endOfStream() + { + return endOfStream(GET, XXX); + } + + @Override + public void cleanup() + { + if(myAudioInputStream != null) + try + { + myAudioInputStream.close(); + } catch (Exception e) + { + } + } + + @Override + public AudioFormat getAudioFormat() + { + return myAudioFormat; + } + + /** + * Internal method for synchronizing access to the boolean 'initialized'. + * + * @param action + * GET or SET. + * @param value + * New value if action == SET, or XXX if action == GET. + * @return True if steam is initialized. + */ + private synchronized boolean initialized(boolean action, boolean value) + { + if(action == SET) + initialized = value; + return initialized; + } + + /** + * Internal method for synchronizing access to the boolean 'endOfStream'. + * + * @param action + * GET or SET. + * @param value + * New value if action == SET, or XXX if action == GET. + * @return True if end of stream was reached. + */ + private synchronized boolean endOfStream(boolean action, boolean value) + { + if(action == SET) + endOfStream = value; + return endOfStream; + } + + /** + * Reverse-orders all bytes contained in the specified array. + * + * @param buffer + * Array containing audio data. + */ + public static void reverseBytes(byte[] buffer) + { + reverseBytes(buffer, 0, buffer.length); + } + + /** + * Reverse-orders the specified range of bytes contained in the specified + * array. + * + * @param buffer + * Array containing audio data. + * @param offset + * Array index to begin. + * @param size + * number of bytes to reverse-order. + */ + public static void reverseBytes(byte[] buffer, int offset, int size) + { + + byte b; + for(int i = offset; i < (offset + size); i += 2) + { + b = buffer[i]; + buffer[i] = buffer[i + 1]; + buffer[i + 1] = b; + } + } + + /** + * Prints an error message. + * + * @param message + * Message to print. + */ + private void errorMessage(String message) + { + logger.errorMessage("CodecJLayerMP3", message, 0); + } + + /** + * Prints an exception's error message followed by the stack trace. + * + * @param e + * Exception containing the information to print. + */ + private void printStackTrace(Exception e) + { + logger.printStackTrace(e, 1); + } + + /** + * Creates a new array with the second array appended to the end of the + * first array. + * + * @param arrayOne + * The first array. + * @param arrayTwo + * The second array. + * @param length + * How many bytes to append from the second array. + * @return Byte array containing information from both arrays. + */ + private static byte[] appendByteArrays(byte[] arrayOne, byte[] arrayTwo, int length) + { + byte[] newArray; + if(arrayOne == null && arrayTwo == null) + { + // no data, just return + return null; + } else if(arrayOne == null) + { + // create the new array, same length as arrayTwo: + newArray = new byte[length]; + // fill the new array with the contents of arrayTwo: + System.arraycopy(arrayTwo, 0, newArray, 0, length); + arrayTwo = null; + } else if(arrayTwo == null) + { + // create the new array, same length as arrayOne: + newArray = new byte[arrayOne.length]; + // fill the new array with the contents of arrayOne: + System.arraycopy(arrayOne, 0, newArray, 0, arrayOne.length); + arrayOne = null; + } else + { + // create the new array large enough to hold both arrays: + newArray = new byte[arrayOne.length + length]; + System.arraycopy(arrayOne, 0, newArray, 0, arrayOne.length); + // fill the new array with the contents of both arrays: + System.arraycopy(arrayTwo, 0, newArray, arrayOne.length, length); + arrayOne = null; + arrayTwo = null; + } + + return newArray; + } + + private static class DMAISObuffer extends Obuffer + { + private int m_nChannels; + private byte[] m_abBuffer; + private int[] m_anBufferPointers; + private boolean m_bIsBigEndian; + + public DMAISObuffer(int nChannels) + { + m_nChannels = nChannels; + m_abBuffer = new byte[OBUFFERSIZE * nChannels]; + m_anBufferPointers = new int[nChannels]; + reset(); + } + + public void append(int nChannel, short sValue) + { + byte bFirstByte; + byte bSecondByte; + if(m_bIsBigEndian) + { + bFirstByte = (byte) ((sValue >>> 8) & 0xFF); + bSecondByte = (byte) (sValue & 0xFF); + } else + // little endian + { + bFirstByte = (byte) (sValue & 0xFF); + bSecondByte = (byte) ((sValue >>> 8) & 0xFF); + } + m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte; + m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte; + m_anBufferPointers[nChannel] += m_nChannels * 2; + } + + public void set_stop_flag() + { + } + + public void close() + { + } + + public void write_buffer(int nValue) + { + } + + public void clear_buffer() + { + } + + public void reset() + { + for(int i = 0; i < m_nChannels; i++) + { + /* + * Points to byte location, implicitly assuming 16 bit samples. + */ + m_anBufferPointers[i] = i * 2; + } + } + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/BitReserve.java b/src/lwjgl/java/javazoom/jl/decoder/BitReserve.java new file mode 100644 index 0000000..fa3deab --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/BitReserve.java @@ -0,0 +1,224 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 0.0.7 Implementation stores single bits + * as ints for better performance. mdm@techie.com. + * + * 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net + * + * Adapted from the public c code by Jeff Tsay. + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implementation of Bit Reservoir for Layer III. + *

+ * The implementation stores single bits as a word in the buffer. If + * a bit is set, the corresponding word in the buffer will be non-zero. + * If a bit is clear, the corresponding word is zero. Although this + * may seem wasteful, this can be a factor of two quicker than + * packing 8 bits to a byte and extracting. + *

+ */ + +// REVIEW: there is no range checking, so buffer underflow or overflow +// can silently occur. +final class BitReserve +{ + /** + * Size of the internal buffer to store the reserved bits. + * Must be a power of 2. And x8, as each bit is stored as a single + * entry. + */ + private static final int BUFSIZE = 4096*8; + + /** + * Mask that can be used to quickly implement the + * modulus operation on BUFSIZE. + */ + private static final int BUFSIZE_MASK = BUFSIZE-1; + + private int offset, totbit, buf_byte_idx; + private final int[] buf = new int[BUFSIZE]; + private int buf_bit_idx; + + BitReserve() + { + + offset = 0; + totbit = 0; + buf_byte_idx = 0; + } + + + /** + * Return totbit Field. + */ + public int hsstell() + { + return(totbit); + } + + /** + * Read a number bits from the bit stream. + * @param N the number of + */ + public int hgetbits(int N) + { + totbit += N; + + int val = 0; + + int pos = buf_byte_idx; + if (pos+N < BUFSIZE) + { + while (N-- > 0) + { + val <<= 1; + val |= ((buf[pos++]!=0) ? 1 : 0); + } + } + else + { + while (N-- > 0) + { + val <<= 1; + val |= ((buf[pos]!=0) ? 1 : 0); + pos = (pos+1) & BUFSIZE_MASK; + } + } + buf_byte_idx = pos; + return val; + } + + + + /** + * Read 1 bit from the bit stream. + */ +/* + public int hget1bit_old() + { + int val; + totbit++; + if (buf_bit_idx == 0) + { + buf_bit_idx = 8; + buf_byte_idx++; + } + // BUFSIZE = 4096 = 2^12, so + // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff + val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx]; + buf_bit_idx--; + val = val >>> buf_bit_idx; + return val; + } + */ + /** + * Returns next bit from reserve. + * + * @return 0 if next bit is reset, or 1 if next bit is set. + */ + public int hget1bit() + { + totbit++; + int val = buf[buf_byte_idx]; + buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK; + return val; + } + + /** + * Retrieves bits from the reserve. + */ +/* + public int readBits(int[] out, int len) + { + if (buf_bit_idx == 0) + { + buf_bit_idx = 8; + buf_byte_idx++; + current = buf[buf_byte_idx & BUFSIZE_MASK]; + } + + + + // save total number of bits returned + len = buf_bit_idx; + buf_bit_idx = 0; + + int b = current; + int count = len-1; + + while (count >= 0) + { + out[count--] = (b & 0x1); + b >>>= 1; + } + + totbit += len; + return len; + } + */ + + /** + * Write 8 bits into the bit stream. + */ + public void hputbuf(int val) + { + int ofs = offset; + buf[ofs++] = val & 0x80; + buf[ofs++] = val & 0x40; + buf[ofs++] = val & 0x20; + buf[ofs++] = val & 0x10; + buf[ofs++] = val & 0x08; + buf[ofs++] = val & 0x04; + buf[ofs++] = val & 0x02; + buf[ofs++] = val & 0x01; + + if (ofs==BUFSIZE) + offset = 0; + else + offset = ofs; + + } + + /** + * Rewind N bits in Stream. + */ + public void rewindNbits(int N) + { + totbit -= N; + buf_byte_idx -= N; + if (buf_byte_idx<0) + buf_byte_idx += BUFSIZE; + } + + /** + * Rewind N bytes in Stream. + */ + public void rewindNbytes(int N) + { + int bits = (N << 3); + totbit -= bits; + buf_byte_idx -= bits; + if (buf_byte_idx<0) + buf_byte_idx += BUFSIZE; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Bitstream.java b/src/lwjgl/java/javazoom/jl/decoder/Bitstream.java new file mode 100644 index 0000000..6286160 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Bitstream.java @@ -0,0 +1,659 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net + * + * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net + * + * 12/12/99 Based on Ibitstream. Exceptions thrown on errors, + * Temporary removed seek functionality. mdm@techie.com + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * 04/14/97 : Added function prototypes for new syncing and seeking + * mechanisms. Also made this file portable. Changes made by Jeff Tsay + * + * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; + + +/** + * The Bistream class is responsible for parsing + * an MPEG audio bitstream. + * + * REVIEW: much of the parsing currently occurs in the + * various decoders. This should be moved into this class and associated + * inner classes. + */ +public final class Bitstream implements BitstreamErrors +{ + /** + * Synchronization control constant for the initial + * synchronization to the start of a frame. + */ + static byte INITIAL_SYNC = 0; + + /** + * Synchronization control constant for non-initial frame + * synchronizations. + */ + static byte STRICT_SYNC = 1; + + // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC + /** + * Maximum size of the frame buffer. + */ + private static final int BUFFER_INT_SIZE = 433; + + /** + * The frame buffer that holds the data for the current frame. + */ + private final int[] framebuffer = new int[BUFFER_INT_SIZE]; + + /** + * Number of valid bytes in the frame buffer. + */ + private int framesize; + + /** + * The bytes read from the stream. + */ + private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4]; + + /** + * Index into framebuffer where the next bits are + * retrieved. + */ + private int wordpointer; + + /** + * Number (0-31, from MSB to LSB) of next bit for get_bits() + */ + private int bitindex; + + /** + * The current specified syncword + */ + private int syncword; + + /** + * Audio header position in stream. + */ + private int header_pos = 0; + + /** + * + */ + private boolean single_ch_mode; + //private int current_frame_number; + //private int last_frame_number; + + private final int bitmask[] = {0, // dummy + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF }; + + private final PushbackInputStream source; + + private final Header header = new Header(); + + private final byte syncbuf[] = new byte[4]; + + private Crc16[] crc = new Crc16[1]; + + private byte[] rawid3v2 = null; + + private boolean firstframe = true; + + + /** + * Construct a IBitstream that reads data from a + * given InputStream. + * + * @param in The InputStream to read from. + */ + public Bitstream(InputStream in) + { + if (in==null) throw new NullPointerException("in"); + in = new BufferedInputStream(in); + loadID3v2(in); + firstframe = true; + //source = new PushbackInputStream(in, 1024); + source = new PushbackInputStream(in, BUFFER_INT_SIZE*4); + + closeFrame(); + //current_frame_number = -1; + //last_frame_number = -1; + } + + /** + * Return position of the first audio header. + * @return size of ID3v2 tag frames. + */ + public int header_pos() + { + return header_pos; + } + + /** + * Load ID3v2 frames. + * @param in MP3 InputStream. + * @author JavaZOOM + */ + private void loadID3v2(InputStream in) + { + int size = -1; + try + { + // Read ID3v2 header (10 bytes). + in.mark(10); + size = readID3v2Header(in); + header_pos = size; + } + catch (IOException e) + {} + finally + { + try + { + // Unread ID3v2 header (10 bytes). + in.reset(); + } + catch (IOException e) + {} + } + // Load ID3v2 tags. + try + { + if (size > 0) + { + rawid3v2 = new byte[size]; + in.read(rawid3v2,0,rawid3v2.length); + } + } + catch (IOException e) + {} + } + + /** + * Parse ID3v2 tag header to find out size of ID3v2 frames. + * @param in MP3 InputStream + * @return size of ID3v2 frames + header + * @throws IOException + * @author JavaZOOM + */ + private int readID3v2Header(InputStream in) throws IOException + { + byte[] id3header = new byte[4]; + int size = -10; + in.read(id3header,0,3); + // Look for ID3v2 + if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3')) + { + in.read(id3header,0,3); + int majorVersion = id3header[0]; + int revision = id3header[1]; + in.read(id3header,0,4); + size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]); + } + return (size+10); + } + + /** + * Return raw ID3v2 frames + header. + * @return ID3v2 InputStream or null if ID3v2 frames are not available. + */ + public InputStream getRawID3v2() + { + if (rawid3v2 == null) return null; + else + { + ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2); + return bain; + } + } + + /** + * Close the Bitstream. + * @throws BitstreamException + */ + public void close() throws BitstreamException + { + try + { + source.close(); + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + } + + /** + * Reads and parses the next frame from the input source. + * + * @return the Header describing details of the frame read, + * or null if the end of the stream has been reached. + */ + public Header readFrame() throws BitstreamException + { + Header result = null; + try + { + result = readNextFrame(); + // E.B, Parse VBR (if any) first frame. + if (firstframe == true) + { + result.parseVBR(frame_bytes); + firstframe = false; + } + } + catch (BitstreamException ex) + { + if ((ex.getErrorCode()==INVALIDFRAME)) + { + // Try to skip this frame. + //System.out.println("INVALIDFRAME"); + try + { + closeFrame(); + result = readNextFrame(); + } + catch (BitstreamException e) + { + if ((e.getErrorCode()!=STREAM_EOF)) + { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(e.getErrorCode(), e); + } + } + } + else if ((ex.getErrorCode()!=STREAM_EOF)) + { + // wrap original exception so stack trace is maintained. + throw newBitstreamException(ex.getErrorCode(), ex); + } + } + return result; + } + + /** + * Read next MP3 frame. + * + * @return MP3 frame header. + * @throws BitstreamException + */ + private Header readNextFrame() throws BitstreamException + { + if (framesize == -1) + { + nextFrame(); + } + return header; + } + + + /** + * Read next MP3 frame. + * + * @throws BitstreamException + */ + private void nextFrame() throws BitstreamException + { + // entire frame is read by the header class. + header.read_header(this, crc); + } + + /** + * Unreads the bytes read from the frame. + * + * @throws BitstreamException + */ + // REVIEW: add new error codes for this. + public void unreadFrame() throws BitstreamException + { + if (wordpointer==-1 && bitindex==-1 && (framesize>0)) + { + try + { + source.unread(frame_bytes, 0, framesize); + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR); + } + } + } + + /** + * Close MP3 frame. + */ + public void closeFrame() + { + framesize = -1; + wordpointer = -1; + bitindex = -1; + } + + /** + * Determines if the next 4 bytes of the stream represent a + * frame header. + */ + public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException + { + int read = readBytes(syncbuf, 0, 4); + int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF); + + try + { + source.unread(syncbuf, 0, read); + } + catch (IOException ex) + { + } + + boolean sync = false; + switch (read) + { + case 0: + sync = true; + break; + case 4: + sync = isSyncMark(headerstring, syncmode, syncword); + break; + } + + return sync; + } + + + // REVIEW: this class should provide inner classes to + // parse the frame contents. Eventually, readBits will + // be removed. + public int readBits(int n) + { + return get_bits(n); + } + + public int readCheckedBits(int n) + { + // REVIEW: implement CRC check. + return get_bits(n); + } + + protected BitstreamException newBitstreamException(int errorcode) + { + return new BitstreamException(errorcode, null); + } + protected BitstreamException newBitstreamException(int errorcode, Throwable throwable) + { + return new BitstreamException(errorcode, throwable); + } + + /** + * Get next 32 bits from bitstream. + * They are stored in the headerstring. + * syncmod allows Synchro flag ID + * The returned value is False at the end of stream. + */ + + int syncHeader(byte syncmode) throws BitstreamException + { + boolean sync; + int headerstring; + // read additional 2 bytes + int bytesRead = readBytes(syncbuf, 0, 3); + + if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null); + + headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF); + + do + { + headerstring <<= 8; + + if (readBytes(syncbuf, 3, 1)!=1) + throw newBitstreamException(STREAM_EOF, null); + + headerstring |= (syncbuf[3] & 0x000000FF); + + sync = isSyncMark(headerstring, syncmode, syncword); + } + while (!sync); + + //current_frame_number++; + //if (last_frame_number < current_frame_number) last_frame_number = current_frame_number; + + return headerstring; + } + + public boolean isSyncMark(int headerstring, int syncmode, int word) + { + boolean sync = false; + + if (syncmode == INITIAL_SYNC) + { + //sync = ((headerstring & 0xFFF00000) == 0xFFF00000); + sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5 + } + else + { + sync = ((headerstring & 0xFFF80C00) == word) && + (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode); + } + + // filter out invalid sample rate + if (sync) + sync = (((headerstring >>> 10) & 3)!=3); + // filter out invalid layer + if (sync) + sync = (((headerstring >>> 17) & 3)!=0); + // filter out invalid version + if (sync) + sync = (((headerstring >>> 19) & 3)!=1); + + return sync; + } + + /** + * Reads the data for the next frame. The frame is not parsed + * until parse frame is called. + */ + int read_frame_data(int bytesize) throws BitstreamException + { + int numread = 0; + numread = readFully(frame_bytes, 0, bytesize); + framesize = bytesize; + wordpointer = -1; + bitindex = -1; + return numread; + } + + /** + * Parses the data previously read with read_frame_data(). + */ + void parse_frame() throws BitstreamException + { + // Convert Bytes read to int + int b=0; + byte[] byteread = frame_bytes; + int bytesize = framesize; + + // Check ID3v1 TAG (True only if last frame). + //for (int t=0;t<(byteread.length)-2;t++) + //{ + // if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G')) + // { + // System.out.println("ID3v1 detected at offset "+t); + // throw newBitstreamException(INVALIDFRAME, null); + // } + //} + + for (int k=0;k>> (32 - sum)) & bitmask[number_of_bits]; + // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits]; + if ((bitindex += number_of_bits) == 32) + { + bitindex = 0; + wordpointer++; // added by me! + } + return returnvalue; + } + + // E.B : Check that ? + //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0]; + //wordpointer++; // Added by me! + //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0]; + int Right = (framebuffer[wordpointer] & 0x0000FFFF); + wordpointer++; + int Left = (framebuffer[wordpointer] & 0xFFFF0000); + returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF); + + returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex)) + returnvalue &= bitmask[number_of_bits]; + bitindex = sum - 32; + return returnvalue; +} + + /** + * Set the word we want to sync the header to. + * In Big-Endian byte order + */ + void set_syncword(int syncword0) + { + syncword = syncword0 & 0xFFFFFF3F; + single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0); + } + /** + * Reads the exact number of bytes from the source + * input stream into a byte array. + * + * @param b The byte array to read the specified number + * of bytes into. + * @param offs The index in the array where the first byte + * read should be stored. + * @param len the number of bytes to read. + * + * @exception BitstreamException is thrown if the specified + * number of bytes could not be read from the stream. + */ + private int readFully(byte[] b, int offs, int len) + throws BitstreamException + { + int nRead = 0; + try + { + while (len > 0) + { + int bytesread = source.read(b, offs, len); + if (bytesread == -1) + { + while (len-->0) + { + b[offs++] = 0; + } + break; + //throw newBitstreamException(UNEXPECTED_EOF, new EOFException()); + } + nRead = nRead + bytesread; + offs += bytesread; + len -= bytesread; + } + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + return nRead; + } + + /** + * Similar to readFully, but doesn't throw exception when + * EOF is reached. + */ + private int readBytes(byte[] b, int offs, int len) + throws BitstreamException + { + int totalBytesRead = 0; + try + { + while (len > 0) + { + int bytesread = source.read(b, offs, len); + if (bytesread == -1) + { + break; + } + totalBytesRead += bytesread; + offs += bytesread; + len -= bytesread; + } + } + catch (IOException ex) + { + throw newBitstreamException(STREAM_ERROR, ex); + } + return totalBytesRead; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java b/src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java new file mode 100644 index 0000000..b5c3c93 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java @@ -0,0 +1,72 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 11/17/04 INVALIDFRAME code added. javalayer@javazoom.net + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * This interface describes all error codes that can be thrown + * in BistreamExceptions. + * + * @see BitstreamException + * + * @author MDM 12/12/99 + * @since 0.0.6 + */ + +public interface BitstreamErrors extends JavaLayerErrors +{ + + /** + * An undetermined error occurred. + */ + public static final int UNKNOWN_ERROR = BITSTREAM_ERROR + 0; + + /** + * The header describes an unknown sample rate. + */ + public static final int UNKNOWN_SAMPLE_RATE = BITSTREAM_ERROR + 1; + + /** + * A problem occurred reading from the stream. + */ + public static final int STREAM_ERROR = BITSTREAM_ERROR + 2; + + /** + * The end of the stream was reached prematurely. + */ + public static final int UNEXPECTED_EOF = BITSTREAM_ERROR + 3; + + /** + * The end of the stream was reached. + */ + public static final int STREAM_EOF = BITSTREAM_ERROR + 4; + + /** + * Frame data are missing. + */ + public static final int INVALIDFRAME = BITSTREAM_ERROR + 5; + + /** + * + */ + public static final int BITSTREAM_LAST = 0x1ff; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java b/src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java new file mode 100644 index 0000000..7aa0d6d --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java @@ -0,0 +1,71 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Instances of BitstreamException are thrown + * when operations on a Bitstream fail. + *

+ * The exception provides details of the exception condition + * in two ways: + *

  1. + * as an error-code describing the nature of the error + *


  2. + * as the Throwable instance, if any, that was thrown + * indicating that an exceptional condition has occurred. + *

+ * + * @since 0.0.6 + * @author MDM 12/12/99 + */ + +public class BitstreamException extends JavaLayerException + implements BitstreamErrors +{ + private int errorcode = UNKNOWN_ERROR; + + public BitstreamException(String msg, Throwable t) + { + super(msg, t); + } + + public BitstreamException(int errorcode, Throwable t) + { + this(getErrorString(errorcode), t); + this.errorcode = errorcode; + } + + public int getErrorCode() + { + return errorcode; + } + + + public static String getErrorString(int errorcode) + { + // REVIEW: use resource bundle to map error codes + // to locale-sensitive strings. + + return "Bitstream errorcode "+Integer.toHexString(errorcode); + } + + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Control.java b/src/lwjgl/java/javazoom/jl/decoder/Control.java new file mode 100644 index 0000000..080ed52 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Control.java @@ -0,0 +1,57 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + */ + +public interface Control +{ + + /** + * Starts playback of the media presented by this control. + */ + public void start(); + + /** + * Stops playback of the media presented by this control. + */ + public void stop(); + + public boolean isPlaying(); + + public void pause(); + + + public boolean isRandomAccess(); + + /** + * Retrieves the current position. + */ + public double getPosition(); + + /** + * + */ + public void setPosition(double d); + + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Crc16.java b/src/lwjgl/java/javazoom/jl/decoder/Crc16.java new file mode 100644 index 0000000..84760f2 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Crc16.java @@ -0,0 +1,70 @@ +/* + * 11/19/04 : 1.0 moved to LGPL. + * + * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net + * + * @(#) crc.h 1.5, last edit: 6/15/94 16:55:32 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ +package javazoom.jl.decoder; + +/** + * 16-Bit CRC checksum + */ +public final class Crc16 +{ + private static short polynomial=(short)0x8005; + private short crc; + + /** + * Dummy Constructor + */ + public Crc16() + { + crc = (short) 0xFFFF; + } + + /** + * Feed a bitstring to the CRC calculation (0 < length <= 32). + */ + public void add_bits (int bitstring, int length) + { + int bitmask = 1 << (length - 1); + do + if (((crc & 0x8000) == 0) ^ ((bitstring & bitmask) == 0 )) + { + crc <<= 1; + crc ^= polynomial; + } + else + crc <<= 1; + while ((bitmask >>>= 1) != 0); + } + + /** + * Return the calculated checksum. + * Erase it for next calls to add_bits(). + */ + public short checksum() + { + short sum = crc; + crc = (short) 0xFFFF; + return sum; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Decoder.java b/src/lwjgl/java/javazoom/jl/decoder/Decoder.java new file mode 100644 index 0000000..dcd893b --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Decoder.java @@ -0,0 +1,356 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The Decoder class encapsulates the details of + * decoding an MPEG audio frame. + * + * @author MDM + * @version 0.0.7 12/12/99 + * @since 0.0.5 + */ +public class Decoder implements DecoderErrors +{ + private static final Params DEFAULT_PARAMS = new Params(); + + /** + * The Bitstream from which the MPEG audio frames are read. + */ + //private Bitstream stream; + + /** + * The Obuffer instance that will receive the decoded + * PCM samples. + */ + private Obuffer output; + + /** + * Synthesis filter for the left channel. + */ + private SynthesisFilter filter1; + + /** + * Synthesis filter for the right channel. + */ + private SynthesisFilter filter2; + + /** + * The decoder used to decode layer III frames. + */ + private LayerIIIDecoder l3decoder; + private LayerIIDecoder l2decoder; + private LayerIDecoder l1decoder; + + private int outputFrequency; + private int outputChannels; + + private Equalizer equalizer = new Equalizer(); + + private Params params; + + private boolean initialized; + + + /** + * Creates a new Decoder instance with default + * parameters. + */ + + public Decoder() + { + this(null); + } + + /** + * Creates a new Decoder instance with default + * parameters. + * + * @param params The Params instance that describes + * the customizable aspects of the decoder. + */ + public Decoder(Params params0) + { + if (params0==null) + params0 = DEFAULT_PARAMS; + + params = params0; + + Equalizer eq = params.getInitialEqualizerSettings(); + if (eq!=null) + { + equalizer.setFrom(eq); + } + } + + public static Params getDefaultParams() throws CloneNotSupportedException + { + return (Params)DEFAULT_PARAMS.clone(); + } + + public void setEqualizer(Equalizer eq) + { + if (eq==null) + eq = Equalizer.PASS_THRU_EQ; + + equalizer.setFrom(eq); + + float[] factors = equalizer.getBandFactors(); + + if (filter1!=null) + filter1.setEQ(factors); + + if (filter2!=null) + filter2.setEQ(factors); + } + + /** + * Decodes one frame from an MPEG audio bitstream. + * + * @param header The header describing the frame to decode. + * @param bitstream The bitstream that provides the bits for te body of the frame. + * + * @return A SampleBuffer containing the decoded samples. + */ + public Obuffer decodeFrame(Header header, Bitstream stream) + throws DecoderException + { + if (!initialized) + { + initialize(header); + } + + int layer = header.layer(); + + output.clear_buffer(); + + FrameDecoder decoder = retrieveDecoder(header, stream, layer); + + decoder.decodeFrame(); + + output.write_buffer(1); + + return output; + } + + /** + * Changes the output buffer. This will take effect the next time + * decodeFrame() is called. + */ + public void setOutputBuffer(Obuffer out) + { + output = out; + } + + /** + * Retrieves the sample frequency of the PCM samples output + * by this decoder. This typically corresponds to the sample + * rate encoded in the MPEG audio stream. + * + * @param the sample rate (in Hz) of the samples written to the + * output buffer when decoding. + */ + public int getOutputFrequency() + { + return outputFrequency; + } + + /** + * Retrieves the number of channels of PCM samples output by + * this decoder. This usually corresponds to the number of + * channels in the MPEG audio stream, although it may differ. + * + * @return The number of output channels in the decoded samples: 1 + * for mono, or 2 for stereo. + * + */ + public int getOutputChannels() + { + return outputChannels; + } + + /** + * Retrieves the maximum number of samples that will be written to + * the output buffer when one frame is decoded. This can be used to + * help calculate the size of other buffers whose size is based upon + * the number of samples written to the output buffer. NB: this is + * an upper bound and fewer samples may actually be written, depending + * upon the sample rate and number of channels. + * + * @return The maximum number of samples that are written to the + * output buffer when decoding a single frame of MPEG audio. + */ + public int getOutputBlockSize() + { + return Obuffer.OBUFFERSIZE; + } + + + protected DecoderException newDecoderException(int errorcode) + { + return new DecoderException(errorcode, null); + } + + protected DecoderException newDecoderException(int errorcode, Throwable throwable) + { + return new DecoderException(errorcode, throwable); + } + + protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer) + throws DecoderException + { + FrameDecoder decoder = null; + + // REVIEW: allow channel output selection type + // (LEFT, RIGHT, BOTH, DOWNMIX) + switch (layer) + { + case 3: + if (l3decoder==null) + { + l3decoder = new LayerIIIDecoder(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + + decoder = l3decoder; + break; + case 2: + if (l2decoder==null) + { + l2decoder = new LayerIIDecoder(); + l2decoder.create(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + decoder = l2decoder; + break; + case 1: + if (l1decoder==null) + { + l1decoder = new LayerIDecoder(); + l1decoder.create(stream, + header, filter1, filter2, + output, OutputChannels.BOTH_CHANNELS); + } + decoder = l1decoder; + break; + } + + if (decoder==null) + { + throw newDecoderException(UNSUPPORTED_LAYER, null); + } + + return decoder; + } + + private void initialize(Header header) + throws DecoderException + { + + // REVIEW: allow customizable scale factor + float scalefactor = 32700.0f; + + int mode = header.mode(); + int layer = header.layer(); + int channels = mode==Header.SINGLE_CHANNEL ? 1 : 2; + + + // set up output buffer if not set up by client. + if (output==null) + output = new SampleBuffer(header.frequency(), channels); + + float[] factors = equalizer.getBandFactors(); + filter1 = new SynthesisFilter(0, scalefactor, factors); + + // REVIEW: allow mono output for stereo + if (channels==2) + filter2 = new SynthesisFilter(1, scalefactor, factors); + + outputChannels = channels; + outputFrequency = header.frequency(); + + initialized = true; + } + + /** + * The Params class presents the customizable + * aspects of the decoder. + *

+ * Instances of this class are not thread safe. + */ + public static class Params implements Cloneable + { + private OutputChannels outputChannels = OutputChannels.BOTH; + + private Equalizer equalizer = new Equalizer(); + + public Params() + { + } + + public Object clone() throws CloneNotSupportedException { + try + { + return super.clone(); + } + catch (CloneNotSupportedException ex) + { + throw new InternalError(this+": "+ex); + } + } + + public void setOutputChannels(OutputChannels out) + { + if (out==null) + throw new NullPointerException("out"); + + outputChannels = out; + } + + public OutputChannels getOutputChannels() + { + return outputChannels; + } + + /** + * Retrieves the equalizer settings that the decoder's equalizer + * will be initialized from. + *

+ * The Equalizer instance returned + * cannot be changed in real time to affect the + * decoder output as it is used only to initialize the decoders + * EQ settings. To affect the decoder's output in realtime, + * use the Equalizer returned from the getEqualizer() method on + * the decoder. + * + * @return The Equalizer used to initialize the + * EQ settings of the decoder. + */ + public Equalizer getInitialEqualizerSettings() + { + return equalizer; + } + + }; +} + diff --git a/src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java b/src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java new file mode 100644 index 0000000..4cbbc81 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java @@ -0,0 +1,45 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * This interface provides constants describing the error + * codes used by the Decoder to indicate errors. + * + * @author MDM + */ +public interface DecoderErrors extends JavaLayerErrors +{ + + public static final int UNKNOWN_ERROR = DECODER_ERROR + 0; + + /** + * Layer not supported by the decoder. + */ + public static final int UNSUPPORTED_LAYER = DECODER_ERROR + 1; + + /** + * Illegal allocation in subband layer. Indicates a corrupt stream. + */ + public static final int ILLEGAL_SUBBAND_ALLOCATION = DECODER_ERROR + 2; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/DecoderException.java b/src/lwjgl/java/javazoom/jl/decoder/DecoderException.java new file mode 100644 index 0000000..ce15c3d --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/DecoderException.java @@ -0,0 +1,59 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 01/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The DecoderException represents the class of + * errors that can occur when decoding MPEG audio. + * + * @author MDM + */ +public class DecoderException extends JavaLayerException + implements DecoderErrors +{ + private int errorcode = UNKNOWN_ERROR; + + public DecoderException(String msg, Throwable t) + { + super(msg, t); + } + + public DecoderException(int errorcode, Throwable t) + { + this(getErrorString(errorcode), t); + this.errorcode = errorcode; + } + + public int getErrorCode() + { + return errorcode; + } + + + public static String getErrorString(int errorcode) + { + // REVIEW: use resource file to map error codes + // to locale-sensitive strings. + + return "Decoder errorcode "+Integer.toHexString(errorcode); + } +} + diff --git a/src/lwjgl/java/javazoom/jl/decoder/Equalizer.java b/src/lwjgl/java/javazoom/jl/decoder/Equalizer.java new file mode 100644 index 0000000..9d41047 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Equalizer.java @@ -0,0 +1,227 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + + +package javazoom.jl.decoder; + +/** + * The Equalizer class can be used to specify + * equalization settings for the MPEG audio decoder. + *

+ * The equalizer consists of 32 band-pass filters. + * Each band of the equalizer can take on a fractional value between + * -1.0 and +1.0. + * At -1.0, the input signal is attenuated by 6dB, at +1.0 the signal is + * amplified by 6dB. + * + * @see Decoder + * + * @author MDM + */ +public final class Equalizer +{ + /** + * Equalizer setting to denote that a given band will not be + * present in the output signal. + */ + public static final float BAND_NOT_PRESENT = Float.NEGATIVE_INFINITY; + + public static final Equalizer PASS_THRU_EQ = new Equalizer(); + + private static final int BANDS = 32; + + private final float[] settings = new float[BANDS]; + + /** + * Creates a new Equalizer instance. + */ + public Equalizer() + { + } + +// private Equalizer(float b1, float b2, float b3, float b4, float b5, +// float b6, float b7, float b8, float b9, float b10, float b11, +// float b12, float b13, float b14, float b15, float b16, +// float b17, float b18, float b19, float b20); + + public Equalizer(float[] settings) + { + setFrom(settings); + } + + public Equalizer(EQFunction eq) + { + setFrom(eq); + } + + public void setFrom(float[] eq) + { + reset(); + int max = (eq.length > BANDS) ? BANDS : eq.length; + + for (int i=0; i=0) && (band=0) && (band 1.0f) + return 1.0f; + if (eq < -1.0f) + return -1.0f; + + return eq; + } + + /** + * Retrieves an array of floats whose values represent a + * scaling factor that can be applied to linear samples + * in each band to provide the equalization represented by + * this instance. + * + * @return an array of factors that can be applied to the + * subbands. + */ + float[] getBandFactors() + { + float[] factors = new float[BANDS]; + for (int i=0, maxCount=BANDS; i>> 19) & 1); + if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection + if (h_version == MPEG2_LSF) + h_version = MPEG25_LSF; + else + throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR); + if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) + { + throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR); + } + } + h_layer = 4 - (headerstring >>> 17) & 3; + h_protection_bit = (headerstring >>> 16) & 1; + h_bitrate_index = (headerstring >>> 12) & 0xF; + h_padding_bit = (headerstring >>> 9) & 1; + h_mode = ((headerstring >>> 6) & 3); + h_mode_extension = (headerstring >>> 4) & 3; + if (h_mode == JOINT_STEREO) + h_intensity_stereo_bound = (h_mode_extension << 2) + 4; + else + h_intensity_stereo_bound = 0; // should never be used + if (((headerstring >>> 3) & 1) == 1) + h_copyright = true; + if (((headerstring >>> 2) & 1) == 1) + h_original = true; + // calculate number of subbands: + if (h_layer == 1) + h_number_of_subbands = 32; + else + { + channel_bitrate = h_bitrate_index; + // calculate bitrate per channel: + if (h_mode != SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + if ((channel_bitrate == 1) || (channel_bitrate == 2)) + if (h_sample_frequency == THIRTYTWO) + h_number_of_subbands = 12; + else + h_number_of_subbands = 8; + else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5))) + h_number_of_subbands = 27; + else + h_number_of_subbands = 30; + } + if (h_intensity_stereo_bound > h_number_of_subbands) + h_intensity_stereo_bound = h_number_of_subbands; + // calculate framesize and nSlots + calculate_framesize(); + // read framedata: + int framesizeloaded = stream.read_frame_data(framesize); + if ((framesize >=0) && (framesizeloaded != framesize)) + { + // Data loaded does not match to expected framesize, + // it might be an ID3v1 TAG. (Fix 11/17/04). + throw stream.newBitstreamException(Bitstream.INVALIDFRAME); + } + if (stream.isSyncCurrentPosition(syncmode)) + { + if (syncmode == Bitstream.INITIAL_SYNC) + { + syncmode = Bitstream.STRICT_SYNC; + stream.set_syncword(headerstring & 0xFFF80CC0); + } + sync = true; + } + else + { + stream.unreadFrame(); + } + } + while (!sync); + stream.parse_frame(); + if (h_protection_bit == 0) + { + // frame contains a crc checksum + checksum = (short) stream.get_bits(16); + if (crc == null) + crc = new Crc16(); + crc.add_bits(headerstring, 16); + crcp[0] = crc; + } + else + crcp[0] = null; + if (h_sample_frequency == FOURTYFOUR_POINT_ONE) + { + /* + if (offset == null) + { + int max = max_number_of_frames(stream); + offset = new int[max]; + for(int i=0; i 0) && (cf == lf)) + { + offset[cf] = offset[cf-1] + h_padding_bit; + } + else + { + offset[0] = h_padding_bit; + } + */ + } + } + + /** + * Parse frame to extract optional VBR frame. + * + * @param firstframe + * @author E.B (javalayer@javazoom.net) + */ + void parseVBR(byte[] firstframe) throws BitstreamException + { + // Trying Xing header. + String xing = "Xing"; + byte tmp[] = new byte[4]; + int offset = 0; + // Compute "Xing" offset depending on MPEG version and channels. + if (h_version == MPEG1) + { + if (h_mode == SINGLE_CHANNEL) offset=21-4; + else offset=36-4; + } + else + { + if (h_mode == SINGLE_CHANNEL) offset=13-4; + else offset = 21-4; + } + try + { + System.arraycopy(firstframe, offset, tmp, 0, 4); + // Is "Xing" ? + if (xing.equals(new String(tmp))) + { + //Yes. + h_vbr = true; + h_vbr_frames = -1; + h_vbr_bytes = -1; + h_vbr_scale = -1; + h_vbr_toc = new byte[100]; + + int length = 4; + // Read flags. + byte flags[] = new byte[4]; + System.arraycopy(firstframe, offset + length, flags, 0, flags.length); + length += flags.length; + // Read number of frames (if available). + if ((flags[3] & (byte) (1 << 0)) != 0) + { + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + } + // Read size (if available). + if ((flags[3] & (byte) (1 << 1)) != 0) + { + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + } + // Read TOC (if available). + if ((flags[3] & (byte) (1 << 2)) != 0) + { + System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length); + length += h_vbr_toc.length; + } + // Read scale (if available). + if ((flags[3] & (byte) (1 << 3)) != 0) + { + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_scale = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + } + //System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); + } + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new BitstreamException("XingVBRHeader Corrupted",e); + } + + // Trying VBRI header. + String vbri = "VBRI"; + offset = 36-4; + try + { + System.arraycopy(firstframe, offset, tmp, 0, 4); + // Is "VBRI" ? + if (vbri.equals(new String(tmp))) + { + //Yes. + h_vbr = true; + h_vbr_frames = -1; + h_vbr_bytes = -1; + h_vbr_scale = -1; + h_vbr_toc = new byte[100]; + // Bytes. + int length = 4 + 6; + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + // Frames. + System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length); + h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF; + length += 4; + //System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); + // TOC + // TODO + } + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new BitstreamException("VBRIVBRHeader Corrupted",e); + } + } + + // Functions to query header contents: + /** + * Returns version. + */ + public int version() { return h_version; } + + /** + * Returns Layer ID. + */ + public int layer() { return h_layer; } + + /** + * Returns bitrate index. + */ + public int bitrate_index() { return h_bitrate_index; } + + /** + * Returns Sample Frequency. + */ + public int sample_frequency() { return h_sample_frequency; } + + /** + * Returns Frequency. + */ + public int frequency() {return frequencies[h_version][h_sample_frequency];} + + /** + * Returns Mode. + */ + public int mode() { return h_mode; } + + /** + * Returns Protection bit. + */ + public boolean checksums() + { + if (h_protection_bit == 0) return true; + else return false; + } + + /** + * Returns Copyright. + */ + public boolean copyright() { return h_copyright; } + + /** + * Returns Original. + */ + public boolean original() { return h_original; } + + /** + * Return VBR. + * + * @return true if VBR header is found + */ + public boolean vbr() { return h_vbr; } + + /** + * Return VBR scale. + * + * @return scale of -1 if not available + */ + public int vbr_scale() { return h_vbr_scale; } + + /** + * Return VBR TOC. + * + * @return vbr toc ot null if not available + */ + public byte[] vbr_toc() { return h_vbr_toc; } + + /** + * Returns Checksum flag. + * Compares computed checksum with stream checksum. + */ + public boolean checksum_ok () { return (checksum == crc.checksum()); } + + // Seeking and layer III stuff + /** + * Returns Layer III Padding bit. + */ + public boolean padding() + { + if (h_padding_bit == 0) return false; + else return true; + } + + /** + * Returns Slots. + */ + public int slots() { return nSlots; } + + /** + * Returns Mode Extension. + */ + public int mode_extension() { return h_mode_extension; } + + // E.B -> private to public + public static final int bitrates[][][] = { + {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, + + {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000, + 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0}, + {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0}, + {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000, + 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}}, + // SZD: MPEG2.5 + {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, + 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, + {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, + 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, + + }; + + // E.B -> private to public + /** + * Calculate Frame size. + * + * Calculates framesize in bytes excluding header size. + */ + public int calculate_framesize() + { + + if (h_layer == 1) + { + framesize = (12 * bitrates[h_version][0][h_bitrate_index]) / + frequencies[h_version][h_sample_frequency]; + if (h_padding_bit != 0 ) framesize++; + framesize <<= 2; // one slot is 4 bytes long + nSlots = 0; + } + else + { + framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) / + frequencies[h_version][h_sample_frequency]; + if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1; // SZD + if (h_padding_bit != 0) framesize++; + // Layer III slots + if (h_layer == 3) + { + if (h_version == MPEG1) + { + nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size + - ((h_protection_bit!=0) ? 0 : 2) // CRC size + - 4; // header size + } + else + { // MPEG-2 LSF, SZD: MPEG-2.5 LSF + nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side info size + - ((h_protection_bit!=0) ? 0 : 2) // CRC size + - 4; // header size + } + } + else + { + nSlots = 0; + } + } + framesize -= 4; // subtract header size + return framesize; + } + + /** + * Returns the maximum number of frames in the stream. + * + * @param streamsize + * @return number of frames + */ + public int max_number_of_frames(int streamsize) // E.B + { + if (h_vbr == true) return h_vbr_frames; + else + { + if ((framesize + 4 - h_padding_bit) == 0) return 0; + else return(streamsize / (framesize + 4 - h_padding_bit)); + } + } + + /** + * Returns the maximum number of frames in the stream. + * + * @param streamsize + * @return number of frames + */ + public int min_number_of_frames(int streamsize) // E.B + { + if (h_vbr == true) return h_vbr_frames; + else + { + if ((framesize + 5 - h_padding_bit) == 0) return 0; + else return(streamsize / (framesize + 5 - h_padding_bit)); + } + } + + + /** + * Returns ms/frame. + * + * @return milliseconds per frame + */ + public float ms_per_frame() // E.B + { + if (h_vbr == true) + { + double tpf = h_vbr_time_per_frame[layer()] / frequency(); + if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2; + return ((float) (tpf * 1000)); + } + else + { + float ms_per_frame_array[][] = {{8.707483f, 8.0f, 12.0f}, + {26.12245f, 24.0f, 36.0f}, + {26.12245f, 24.0f, 36.0f}}; + return(ms_per_frame_array[h_layer-1][h_sample_frequency]); + } + } + + /** + * Returns total ms. + * + * @param streamsize + * @return total milliseconds + */ + public float total_ms(int streamsize) // E.B + { + return(max_number_of_frames(streamsize) * ms_per_frame()); + } + + /** + * Returns synchronized header. + */ + public int getSyncHeader() // E.B + { + return _headerstring; + } + + // functions which return header informations as strings: + /** + * Return Layer version. + */ + public String layer_string() + { + switch (h_layer) + { + case 1: + return "I"; + case 2: + return "II"; + case 3: + return "III"; + } + return null; + } + + // E.B -> private to public + public static final String bitrate_str[][][] = { + {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", + "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}}, + + {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", + "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", + "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s", + "forbidden"}, + {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", + "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s", + "forbidden"}, + {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", + "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s", + "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", + "forbidden"}}, + // SZD: MPEG2.5 + {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", + "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", + "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}, + {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", + "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", + "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", + "forbidden"}}, + }; + + /** + * Return Bitrate. + * + * @return bitrate in bps + */ + public String bitrate_string() + { + if (h_vbr == true) + { + return Integer.toString(bitrate()/1000)+" kb/s"; + } + else return bitrate_str[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Return Bitrate. + * + * @return bitrate in bps and average bitrate for VBR header + */ + public int bitrate() + { + if (h_vbr == true) + { + return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000; + } + else return bitrates[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Return Instant Bitrate. + * Bitrate for VBR is not constant. + * + * @return bitrate in bps + */ + public int bitrate_instant() + { + return bitrates[h_version][h_layer - 1][h_bitrate_index]; + } + + /** + * Returns Frequency + * + * @return frequency string in kHz + */ + public String sample_frequency_string() + { + switch (h_sample_frequency) + { + case THIRTYTWO: + if (h_version == MPEG1) + return "32 kHz"; + else if (h_version == MPEG2_LSF) + return "16 kHz"; + else // SZD + return "8 kHz"; + case FOURTYFOUR_POINT_ONE: + if (h_version == MPEG1) + return "44.1 kHz"; + else if (h_version == MPEG2_LSF) + return "22.05 kHz"; + else // SZD + return "11.025 kHz"; + case FOURTYEIGHT: + if (h_version == MPEG1) + return "48 kHz"; + else if (h_version == MPEG2_LSF) + return "24 kHz"; + else // SZD + return "12 kHz"; + } + return(null); + } + + /** + * Returns Mode. + */ + public String mode_string() + { + switch (h_mode) + { + case STEREO: + return "Stereo"; + case JOINT_STEREO: + return "Joint stereo"; + case DUAL_CHANNEL: + return "Dual channel"; + case SINGLE_CHANNEL: + return "Single channel"; + } + return null; + } + + /** + * Returns Version. + * + * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF + */ + public String version_string() + { + switch (h_version) + { + case MPEG1: + return "MPEG-1"; + case MPEG2_LSF: + return "MPEG-2 LSF"; + case MPEG25_LSF: // SZD + return "MPEG-2.5 LSF"; + } + return(null); + } + + /** + * Returns the number of subbands in the current frame. + * + * @return number of subbands + */ + public int number_of_subbands() {return h_number_of_subbands;} + + /** + * Returns Intensity Stereo. + * (Layer II joint stereo only). + * Returns the number of subbands which are in stereo mode, + * subbands above that limit are in intensity stereo mode. + * + * @return intensity + */ + public int intensity_stereo_bound() {return h_intensity_stereo_bound;} +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java b/src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java new file mode 100644 index 0000000..5c62947 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java @@ -0,0 +1,80 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Work In Progress. + * + * An instance of InputStreamSource implements a + * Source that provides data from an InputStream + * . Seeking functionality is not supported. + * + * @author MDM + */ +public class InputStreamSource implements Source +{ + private final InputStream in; + + public InputStreamSource(InputStream in) + { + if (in==null) + throw new NullPointerException("in"); + + this.in = in; + } + + public int read(byte[] b, int offs, int len) + throws IOException + { + int read = in.read(b, offs, len); + return read; + } + + public boolean willReadBlock() + { + return true; + //boolean block = (in.available()==0); + //return block; + } + + public boolean isSeekable() + { + return false; + } + + public long tell() + { + return -1; + } + + public long seek(long to) + { + return -1; + } + + public long length() + { + return -1; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java new file mode 100644 index 0000000..d9910bc --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java @@ -0,0 +1,31 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Work in progress. + * + * API usage errors may be handled by throwing an instance of this + * class, as per JMF 2.0. + */ +public class JavaLayerError extends Error +{ +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java new file mode 100644 index 0000000..9050610 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java @@ -0,0 +1,40 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Exception error codes for components of the JavaLayer API. + */ +public interface JavaLayerErrors +{ + /** + * The first bitstream error code. See the {@link DecoderErrors DecoderErrors} + * interface for other bitstream error codes. + */ + public static final int BITSTREAM_ERROR = 0x100; + + /** + * The first decoder error code. See the {@link DecoderErrors DecoderErrors} + * interface for other decoder error codes. + */ + public static final int DECODER_ERROR = 0x200; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java new file mode 100644 index 0000000..e432a68 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java @@ -0,0 +1,78 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.PrintStream; + + +/** + * The JavaLayerException is the base class for all API-level + * exceptions thrown by JavaLayer. To facilitate conversion and + * common handling of exceptions from other domains, the class + * can delegate some functionality to a contained Throwable instance. + *

+ * + * @author MDM + */ +public class JavaLayerException extends Exception +{ + + private Throwable exception; + + + public JavaLayerException() + { + } + + public JavaLayerException(String msg) + { + super(msg); + } + + public JavaLayerException(String msg, Throwable t) + { + super(msg); + exception = t; + } + + public Throwable getException() + { + return exception; + } + + + public void printStackTrace() + { + printStackTrace(System.err); + } + + public void printStackTrace(PrintStream ps) + { + if (this.exception==null) + { + super.printStackTrace(ps); + } + else + { + exception.printStackTrace(); + } + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java new file mode 100644 index 0000000..3520594 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java @@ -0,0 +1,36 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.InputStream; + +/** + * The JavaLayerHooks class allows developers to change + * the way the JavaLayer library uses Resources. + */ + +public interface JavaLayerHook +{ + /** + * Retrieves the named resource. This allows resources to be + * obtained without specifying how they are retrieved. + */ + public InputStream getResourceAsStream(String name); +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java new file mode 100644 index 0000000..5cfbd16 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java @@ -0,0 +1,208 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial version. mdm@techie.com + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; + +/** + * The JavaLayerUtils class is not strictly part of the JavaLayer API. + * It serves to provide useful methods and system-wide hooks. + * + * @author MDM + */ +public class JavaLayerUtils +{ + private static JavaLayerHook hook = null; + + /** + * Deserializes the object contained in the given input stream. + * + * @param in The input stream to deserialize an object from. + * @param cls The expected class of the deserialized object. + */ + public static Object deserialize(InputStream in, Class cls) + throws IOException + { + if (cls==null) + throw new NullPointerException("cls"); + + Object obj = deserialize(in, cls); + if (!cls.isInstance(obj)) + { + throw new InvalidObjectException("type of deserialized instance not of required class."); + } + + return obj; + } + + /** + * Deserializes an object from the given InputStream. + * The deserialization is delegated to an + * ObjectInputStream instance. + * + * @param in The InputStream to deserialize an object + * from. + * + * @return The object deserialized from the stream. + * @exception IOException is thrown if there was a problem reading + * the underlying stream, or an object could not be deserialized + * from the stream. + * + * @see java.io.ObjectInputStream + */ + public static Object deserialize(InputStream in) + throws IOException + { + if (in==null) + throw new NullPointerException("in"); + + ObjectInputStream objIn = new ObjectInputStream(in); + + Object obj; + + try + { + obj = objIn.readObject(); + } + catch (ClassNotFoundException ex) + { + throw new InvalidClassException(ex.toString()); + } + + return obj; + } + + /** + * Deserializes an array from a given InputStream. + * + * @param in The InputStream to + * deserialize an object from. + * + * @param elemType The class denoting the type of the array + * elements. + * @param length The expected length of the array, or -1 if + * any length is expected. + */ + public static Object deserializeArray(InputStream in, Class elemType, int length) + throws IOException + { + if (elemType==null) + throw new NullPointerException("elemType"); + + if (length<-1) + throw new IllegalArgumentException("length"); + + Object obj = deserialize(in); + + Class cls = obj.getClass(); + + + if (!cls.isArray()) + throw new InvalidObjectException("object is not an array"); + + Class arrayElemType = cls.getComponentType(); + if (arrayElemType!=elemType) + throw new InvalidObjectException("unexpected array component type"); + + if (length != -1) + { + int arrayLength = Array.getLength(obj); + if (arrayLength!=length) + throw new InvalidObjectException("array length mismatch"); + } + + return obj; + } + + public static Object deserializeArrayResource(String name, Class elemType, int length) + throws IOException + { + InputStream str = getResourceAsStream(name); + if (str==null) + throw new IOException("unable to load resource '"+name+"'"); + + Object obj = deserializeArray(str, elemType, length); + + return obj; + } + + public static void serialize(OutputStream out, Object obj) + throws IOException + { + if (out==null) + throw new NullPointerException("out"); + + if (obj==null) + throw new NullPointerException("obj"); + + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(obj); + + } + + /** + * Sets the system-wide JavaLayer hook. + */ + public static synchronized void setHook(JavaLayerHook hook0) + { + hook = hook0; + } + + public static synchronized JavaLayerHook getHook() + { + return hook; + } + + /** + * Retrieves an InputStream for a named resource. + * + * @param name The name of the resource. This must be a simple + * name, and not a qualified package name. + * + * @return The InputStream for the named resource, or null if + * the resource has not been found. If a hook has been + * provided, its getResourceAsStream() method is called + * to retrieve the resource. + */ + public static synchronized InputStream getResourceAsStream(String name) + { + InputStream is = null; + + if (hook!=null) + { + is = hook.getResourceAsStream(name); + } + else + { + Class cls = JavaLayerUtils.class; + is = cls.getResourceAsStream(name); + } + + return is; + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java b/src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java new file mode 100644 index 0000000..5e3232c --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java @@ -0,0 +1,448 @@ +/* + * 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org) + * + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 Initial version. Adapted from javalayer.java + * and Subband*.java. mdm@techie.com + * + * 02/28/99 Initial version : javalayer.java by E.B + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implements decoding of MPEG Audio Layer I frames. + */ +class LayerIDecoder implements FrameDecoder +{ + protected Bitstream stream; + protected Header header; + protected SynthesisFilter filter1, filter2; + protected Obuffer buffer; + protected int which_channels; + protected int mode; + + protected int num_subbands; + protected Subband[] subbands; + protected Crc16 crc = null; // new Crc16[1] to enable CRC checking. + + public LayerIDecoder() + { + crc = new Crc16(); + } + + public void create(Bitstream stream0, Header header0, + SynthesisFilter filtera, SynthesisFilter filterb, + Obuffer buffer0, int which_ch0) + { + stream = stream0; + header = header0; + filter1 = filtera; + filter2 = filterb; + buffer = buffer0; + which_channels = which_ch0; + + } + + public void decodeFrame() throws DecoderException + { + + num_subbands = header.number_of_subbands(); + subbands = new Subband[32]; + mode = header.mode(); + + createSubbands(); + + readAllocation(); + readScaleFactorSelection(); + + if ((crc != null) || header.checksum_ok()) + { + readScaleFactors(); + + readSampleData(); + } + + } + + protected void createSubbands() + { + int i; + if (mode == Header.SINGLE_CHANNEL) + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1(i); + else if (mode == Header.JOINT_STEREO) + { + for (i = 0; i < header.intensity_stereo_bound(); ++i) + subbands[i] = new SubbandLayer1Stereo(i); + for (; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1IntensityStereo(i); + } + else + { + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer1Stereo(i); + } + } + + protected void readAllocation() throws DecoderException + { + // start to read audio data: + for (int i = 0; i < num_subbands; ++i) + subbands[i].read_allocation(stream, header, crc); + + } + + protected void readScaleFactorSelection() + { + // scale factor selection not present for layer I. + } + + protected void readScaleFactors() + { + for (int i = 0; i < num_subbands; ++i) + subbands[i].read_scalefactor(stream, header); + } + + protected void readSampleData() + { + boolean read_ready = false; + boolean write_ready = false; + int mode = header.mode(); + int i; + do + { + for (i = 0; i < num_subbands; ++i) + read_ready = subbands[i].read_sampledata(stream); + do + { + for (i = 0; i < num_subbands; ++i) + write_ready = subbands[i].put_next_sample(which_channels,filter1, filter2); + + filter1.calculate_pcm_samples(buffer); + if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL)) + filter2.calculate_pcm_samples(buffer); + } while (!write_ready); + } while (!read_ready); + + } + + /** + * Abstract base class for subband classes of layer I and II + */ + abstract static class Subband + { + /* + * Changes from version 1.1 to 1.2: + * - array size increased by one, although a scalefactor with index 63 + * is illegal (to prevent segmentation faults) + */ + // Scalefactors for layer I and II, Annex 3-B.1 in ISO/IEC DIS 11172: + public static final float scalefactors[] = + { + 2.00000000000000f, 1.58740105196820f, 1.25992104989487f, 1.00000000000000f, + 0.79370052598410f, 0.62996052494744f, 0.50000000000000f, 0.39685026299205f, + 0.31498026247372f, 0.25000000000000f, 0.19842513149602f, 0.15749013123686f, + 0.12500000000000f, 0.09921256574801f, 0.07874506561843f, 0.06250000000000f, + 0.04960628287401f, 0.03937253280921f, 0.03125000000000f, 0.02480314143700f, + 0.01968626640461f, 0.01562500000000f, 0.01240157071850f, 0.00984313320230f, + 0.00781250000000f, 0.00620078535925f, 0.00492156660115f, 0.00390625000000f, + 0.00310039267963f, 0.00246078330058f, 0.00195312500000f, 0.00155019633981f, + 0.00123039165029f, 0.00097656250000f, 0.00077509816991f, 0.00061519582514f, + 0.00048828125000f, 0.00038754908495f, 0.00030759791257f, 0.00024414062500f, + 0.00019377454248f, 0.00015379895629f, 0.00012207031250f, 0.00009688727124f, + 0.00007689947814f, 0.00006103515625f, 0.00004844363562f, 0.00003844973907f, + 0.00003051757813f, 0.00002422181781f, 0.00001922486954f, 0.00001525878906f, + 0.00001211090890f, 0.00000961243477f, 0.00000762939453f, 0.00000605545445f, + 0.00000480621738f, 0.00000381469727f, 0.00000302772723f, 0.00000240310869f, + 0.00000190734863f, 0.00000151386361f, 0.00000120155435f, 0.00000000000000f /* illegal scalefactor */ + }; + + public abstract void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException; + public abstract void read_scalefactor (Bitstream stream, Header header); + public abstract boolean read_sampledata (Bitstream stream); + public abstract boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2); + }; + + /** + * Class for layer I subbands in single channel mode. + * Used for single channel mode + * and in derived class for intensity stereo mode + */ + static class SubbandLayer1 extends Subband + { + + // Factors and offsets for sample re-quantization + public static final float table_factor[] = { + 0.0f, (1.0f/2.0f) * (4.0f/3.0f), (1.0f/4.0f) * (8.0f/7.0f), (1.0f/8.0f) * (16.0f/15.0f), + (1.0f/16.0f) * (32.0f/31.0f), (1.0f/32.0f) * (64.0f/63.0f), (1.0f/64.0f) * (128.0f/127.0f), + (1.0f/128.0f) * (256.0f/255.0f), (1.0f/256.0f) * (512.0f/511.0f), + (1.0f/512.0f) * (1024.0f/1023.0f), (1.0f/1024.0f) * (2048.0f/2047.0f), + (1.0f/2048.0f) * (4096.0f/4095.0f), (1.0f/4096.0f) * (8192.0f/8191.0f), + (1.0f/8192.0f) * (16384.0f/16383.0f), (1.0f/16384.0f) * (32768.0f/32767.0f) + }; + + public static final float table_offset[] = { + 0.0f, ((1.0f/2.0f)-1.0f) * (4.0f/3.0f), ((1.0f/4.0f)-1.0f) * (8.0f/7.0f), ((1.0f/8.0f)-1.0f) * (16.0f/15.0f), + ((1.0f/16.0f)-1.0f) * (32.0f/31.0f), ((1.0f/32.0f)-1.0f) * (64.0f/63.0f), ((1.0f/64.0f)-1.0f) * (128.0f/127.0f), + ((1.0f/128.0f)-1.0f) * (256.0f/255.0f), ((1.0f/256.0f)-1.0f) * (512.0f/511.0f), + ((1.0f/512.0f)-1.0f) * (1024.0f/1023.0f), ((1.0f/1024.0f)-1.0f) * (2048.0f/2047.0f), + ((1.0f/2048.0f)-1.0f) * (4096.0f/4095.0f), ((1.0f/4096.0f)-1.0f) * (8192.0f/8191.0f), + ((1.0f/8192.0f)-1.0f) * (16384.0f/16383.0f), ((1.0f/16384.0f)-1.0f) * (32768.0f/32767.0f) + }; + + protected int subbandnumber; + protected int samplenumber; + protected int allocation; + protected float scalefactor; + protected int samplelength; + protected float sample; + protected float factor, offset; + + /** + * Constructor. + */ + public SubbandLayer1(int subbandnumber) + { + this.subbandnumber = subbandnumber; + samplenumber = 0; + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException + { + if ((allocation = stream.get_bits (4)) == 15) + { + // CGJ: catch this condition and throw appropriate exception + throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null); + // cerr << "WARNING: stream contains an illegal allocation!\n"; + // MPEG-stream is corrupted! + } + + if (crc != null) crc.add_bits (allocation, 4); + if (allocation != 0) + { + samplelength = allocation + 1; + factor = table_factor[allocation]; + offset = table_offset[allocation]; + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)]; + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) + { + if (allocation != 0) + { + sample = (float) (stream.get_bits(samplelength)); + } + if (++samplenumber == 12) + { + samplenumber = 0; + return true; + } + return false; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if ((allocation !=0) && (channels != OutputChannels.RIGHT_CHANNEL)) + { + float scaled_sample = (sample * factor + offset) * scalefactor; + filter1.input_sample (scaled_sample, subbandnumber); + } + return true; + } + }; + + /** + * Class for layer I subbands in joint stereo mode. + */ + static class SubbandLayer1IntensityStereo extends SubbandLayer1 + { + protected float channel2_scalefactor; + + /** + * Constructor + */ + public SubbandLayer1IntensityStereo(int subbandnumber) + { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException + { + super.read_allocation (stream, header, crc); + } + + /** + * + */ + public void read_scalefactor (Bitstream stream, Header header) + { + if (allocation != 0) + { + scalefactor = scalefactors[stream.get_bits(6)]; + channel2_scalefactor = scalefactors[stream.get_bits(6)]; + } + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) + { + return super.read_sampledata (stream); + } + + /** + * + */ + public boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if (allocation !=0 ) + { + sample = sample * factor + offset; // re-quantization + if (channels == OutputChannels.BOTH_CHANNELS) + { + float sample1 = sample * scalefactor, + sample2 = sample * channel2_scalefactor; + filter1.input_sample(sample1, subbandnumber); + filter2.input_sample(sample2, subbandnumber); + } + else if (channels == OutputChannels.LEFT_CHANNEL) + { + float sample1 = sample * scalefactor; + filter1.input_sample(sample1, subbandnumber); + } + else + { + float sample2 = sample * channel2_scalefactor; + filter1.input_sample(sample2, subbandnumber); + } + } + return true; + } + }; + + /** + * Class for layer I subbands in stereo mode. + */ + static class SubbandLayer1Stereo extends SubbandLayer1 + { + protected int channel2_allocation; + protected float channel2_scalefactor; + protected int channel2_samplelength; + protected float channel2_sample; + protected float channel2_factor, channel2_offset; + + + /** + * Constructor + */ + public SubbandLayer1Stereo(int subbandnumber) + { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException + { + allocation = stream.get_bits(4); + channel2_allocation = stream.get_bits(4); + if (crc != null) + { + crc.add_bits (allocation, 4); + crc.add_bits (channel2_allocation, 4); + } + if (allocation != 0) + { + samplelength = allocation + 1; + factor = table_factor[allocation]; + offset = table_offset[allocation]; + } + if (channel2_allocation != 0) + { + channel2_samplelength = channel2_allocation + 1; + channel2_factor = table_factor[channel2_allocation]; + channel2_offset = table_offset[channel2_allocation]; + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)]; + if (channel2_allocation != 0) channel2_scalefactor = scalefactors[stream.get_bits(6)]; + } + + /** + * + */ + public boolean read_sampledata (Bitstream stream) + { + boolean returnvalue = super.read_sampledata(stream); + if (channel2_allocation != 0) + { + channel2_sample = (float) (stream.get_bits(channel2_samplelength)); + } + return(returnvalue); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + super.put_next_sample (channels, filter1, filter2); + if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) + { + float sample2 = (channel2_sample * channel2_factor + channel2_offset) * + channel2_scalefactor; + if (channels == OutputChannels.BOTH_CHANNELS) + filter2.input_sample (sample2, subbandnumber); + else + filter1.input_sample (sample2, subbandnumber); + } + return true; + } + }; + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java b/src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java new file mode 100644 index 0000000..7265b1f --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java @@ -0,0 +1,1064 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 29/05/01 Michael Scheerer, Fixed some C++ to Java porting bugs. + * + * 16/07/01 Michael Scheerer, Catched a bug in method + * read_sampledata, which causes an outOfIndexException. + * + * 12/12/99 Initial version. Adapted from javalayer.java + * and Subband*.java. mdm@techie.com + * + * 02/28/99 Initial version : javalayer.java by E.B + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Implements decoding of MPEG Audio Layer II frames. + */ +class LayerIIDecoder extends LayerIDecoder implements FrameDecoder +{ + + public LayerIIDecoder() + { + } + + + protected void createSubbands() + { + int i; + if (mode == Header.SINGLE_CHANNEL) + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2(i); + else if (mode == Header.JOINT_STEREO) + { + for (i = 0; i < header.intensity_stereo_bound(); ++i) + subbands[i] = new SubbandLayer2Stereo(i); + for (; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2IntensityStereo(i); + } + else + { + for (i = 0; i < num_subbands; ++i) + subbands[i] = new SubbandLayer2Stereo(i); + } + + } + + protected void readScaleFactorSelection() + { + for (int i = 0; i < num_subbands; ++i) + ((SubbandLayer2)subbands[i]).read_scalefactor_selection(stream, crc); + } + + + + /** + * Class for layer II subbands in single channel mode. + */ + static class SubbandLayer2 extends Subband + { + // this table contains 3 requantized samples for each legal codeword + // when grouped in 5 bits, i.e. 3 quantizationsteps per sample + public static final float grouping_5bits[] = new float[] + { + -2.0f/3.0f, -2.0f/3.0f, -2.0f/3.0f, + 0.0f, -2.0f/3.0f, -2.0f/3.0f, + 2.0f/3.0f, -2.0f/3.0f, -2.0f/3.0f, + -2.0f/3.0f, 0.0f, -2.0f/3.0f, + 0.0f, 0.0f, -2.0f/3.0f, + 2.0f/3.0f, 0.0f, -2.0f/3.0f, + -2.0f/3.0f, 2.0f/3.0f, -2.0f/3.0f, + 0.0f, 2.0f/3.0f, -2.0f/3.0f, + 2.0f/3.0f, 2.0f/3.0f, -2.0f/3.0f, + -2.0f/3.0f, -2.0f/3.0f, 0.0f, + 0.0f, -2.0f/3.0f, 0.0f, + 2.0f/3.0f, -2.0f/3.0f, 0.0f, + -2.0f/3.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 2.0f/3.0f, 0.0f, 0.0f, + -2.0f/3.0f, 2.0f/3.0f, 0.0f, + 0.0f, 2.0f/3.0f, 0.0f, + 2.0f/3.0f, 2.0f/3.0f, 0.0f, + -2.0f/3.0f, -2.0f/3.0f, 2.0f/3.0f, + 0.0f, -2.0f/3.0f, 2.0f/3.0f, + 2.0f/3.0f, -2.0f/3.0f, 2.0f/3.0f, + -2.0f/3.0f, 0.0f, 2.0f/3.0f, + 0.0f, 0.0f, 2.0f/3.0f, + 2.0f/3.0f, 0.0f, 2.0f/3.0f, + -2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, + 0.0f, 2.0f/3.0f, 2.0f/3.0f, + 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f + }; + + // this table contains 3 requantized samples for each legal codeword + // when grouped in 7 bits, i.e. 5 quantizationsteps per sample + public static final float grouping_7bits[] = new float[] + { + -0.8f, -0.8f, -0.8f, -0.4f, -0.8f, -0.8f, 0.0f, -0.8f, -0.8f, 0.4f, -0.8f, -0.8f, 0.8f, -0.8f, -0.8f, + -0.8f, -0.4f, -0.8f, -0.4f, -0.4f, -0.8f, 0.0f, -0.4f, -0.8f, 0.4f, -0.4f, -0.8f, 0.8f, -0.4f, -0.8f, + -0.8f, 0.0f, -0.8f, -0.4f, 0.0f, -0.8f, 0.0f, 0.0f, -0.8f, 0.4f, 0.0f, -0.8f, 0.8f, 0.0f, -0.8f, + -0.8f, 0.4f, -0.8f, -0.4f, 0.4f, -0.8f, 0.0f, 0.4f, -0.8f, 0.4f, 0.4f, -0.8f, 0.8f, 0.4f, -0.8f, + -0.8f, 0.8f, -0.8f, -0.4f, 0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.4f, 0.8f, -0.8f, 0.8f, 0.8f, -0.8f, + -0.8f, -0.8f, -0.4f, -0.4f, -0.8f, -0.4f, 0.0f, -0.8f, -0.4f, 0.4f, -0.8f, -0.4f, 0.8f, -0.8f, -0.4f, + -0.8f, -0.4f, -0.4f, -0.4f, -0.4f, -0.4f, 0.0f, -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.8f, -0.4f, -0.4f, + -0.8f, 0.0f, -0.4f, -0.4f, 0.0f, -0.4f, 0.0f, 0.0f, -0.4f, 0.4f, 0.0f, -0.4f, 0.8f, 0.0f, -0.4f, + -0.8f, 0.4f, -0.4f, -0.4f, 0.4f, -0.4f, 0.0f, 0.4f, -0.4f, 0.4f, 0.4f, -0.4f, 0.8f, 0.4f, -0.4f, + -0.8f, 0.8f, -0.4f, -0.4f, 0.8f, -0.4f, 0.0f, 0.8f, -0.4f, 0.4f, 0.8f, -0.4f, 0.8f, 0.8f, -0.4f, + -0.8f, -0.8f, 0.0f, -0.4f, -0.8f, 0.0f, 0.0f, -0.8f, 0.0f, 0.4f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, + -0.8f, -0.4f, 0.0f, -0.4f, -0.4f, 0.0f, 0.0f, -0.4f, 0.0f, 0.4f, -0.4f, 0.0f, 0.8f, -0.4f, 0.0f, + -0.8f, 0.0f, 0.0f, -0.4f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.4f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, + -0.8f, 0.4f, 0.0f, -0.4f, 0.4f, 0.0f, 0.0f, 0.4f, 0.0f, 0.4f, 0.4f, 0.0f, 0.8f, 0.4f, 0.0f, + -0.8f, 0.8f, 0.0f, -0.4f, 0.8f, 0.0f, 0.0f, 0.8f, 0.0f, 0.4f, 0.8f, 0.0f, 0.8f, 0.8f, 0.0f, + -0.8f, -0.8f, 0.4f, -0.4f, -0.8f, 0.4f, 0.0f, -0.8f, 0.4f, 0.4f, -0.8f, 0.4f, 0.8f, -0.8f, 0.4f, + -0.8f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.0f, -0.4f, 0.4f, 0.4f, -0.4f, 0.4f, 0.8f, -0.4f, 0.4f, + -0.8f, 0.0f, 0.4f, -0.4f, 0.0f, 0.4f, 0.0f, 0.0f, 0.4f, 0.4f, 0.0f, 0.4f, 0.8f, 0.0f, 0.4f, + -0.8f, 0.4f, 0.4f, -0.4f, 0.4f, 0.4f, 0.0f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.4f, 0.4f, + -0.8f, 0.8f, 0.4f, -0.4f, 0.8f, 0.4f, 0.0f, 0.8f, 0.4f, 0.4f, 0.8f, 0.4f, 0.8f, 0.8f, 0.4f, + -0.8f, -0.8f, 0.8f, -0.4f, -0.8f, 0.8f, 0.0f, -0.8f, 0.8f, 0.4f, -0.8f, 0.8f, 0.8f, -0.8f, 0.8f, + -0.8f, -0.4f, 0.8f, -0.4f, -0.4f, 0.8f, 0.0f, -0.4f, 0.8f, 0.4f, -0.4f, 0.8f, 0.8f, -0.4f, 0.8f, + -0.8f, 0.0f, 0.8f, -0.4f, 0.0f, 0.8f, 0.0f, 0.0f, 0.8f, 0.4f, 0.0f, 0.8f, 0.8f, 0.0f, 0.8f, + -0.8f, 0.4f, 0.8f, -0.4f, 0.4f, 0.8f, 0.0f, 0.4f, 0.8f, 0.4f, 0.4f, 0.8f, 0.8f, 0.4f, 0.8f, + -0.8f, 0.8f, 0.8f, -0.4f, 0.8f, 0.8f, 0.0f, 0.8f, 0.8f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f + }; + + // this table contains 3 requantized samples for each legal codeword + // when grouped in 10 bits, i.e. 9 quantizationsteps per sample + public static final float grouping_10bits[] = + { + -8.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 0.0f, -8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 0.0f, -6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 0.0f, -4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 0.0f, -2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 0.0f, -8.0f/9.0f, -6.0f/9.0f, 0.0f, -8.0f/9.0f, -4.0f/9.0f, 0.0f, -8.0f/9.0f, + -2.0f/9.0f, 0.0f, -8.0f/9.0f, 0.0f, 0.0f, -8.0f/9.0f, 2.0f/9.0f, 0.0f, -8.0f/9.0f, + 4.0f/9.0f, 0.0f, -8.0f/9.0f, 6.0f/9.0f, 0.0f, -8.0f/9.0f, 8.0f/9.0f, 0.0f, -8.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 0.0f, 2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 0.0f, 4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 0.0f, 6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 0.0f, 8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 0.0f, -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 0.0f, -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, + -2.0f/9.0f, 0.0f, -6.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, + 4.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 0.0f, 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 0.0f, -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 0.0f, -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, + -2.0f/9.0f, 0.0f, -4.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, + 4.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 0.0f, 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 0.0f, -8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 0.0f, -6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 0.0f, -4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 0.0f, -2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 0.0f, -2.0f/9.0f, -6.0f/9.0f, 0.0f, -2.0f/9.0f, -4.0f/9.0f, 0.0f, -2.0f/9.0f, + -2.0f/9.0f, 0.0f, -2.0f/9.0f, 0.0f, 0.0f, -2.0f/9.0f, 2.0f/9.0f, 0.0f, -2.0f/9.0f, + 4.0f/9.0f, 0.0f, -2.0f/9.0f, 6.0f/9.0f, 0.0f, -2.0f/9.0f, 8.0f/9.0f, 0.0f, -2.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 0.0f, 2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 0.0f, 4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 0.0f, 6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 0.0f, 8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 0.0f, -6.0f/9.0f, -8.0f/9.0f, 0.0f, -4.0f/9.0f, -8.0f/9.0f, 0.0f, + -2.0f/9.0f, -8.0f/9.0f, 0.0f, 0.0f, -8.0f/9.0f, 0.0f, 2.0f/9.0f, -8.0f/9.0f, 0.0f, + 4.0f/9.0f, -8.0f/9.0f, 0.0f, 6.0f/9.0f, -8.0f/9.0f, 0.0f, 8.0f/9.0f, -8.0f/9.0f, 0.0f, + -8.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, + -2.0f/9.0f, -6.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, + 4.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, + -8.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, + -2.0f/9.0f, -4.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, + 4.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, + -8.0f/9.0f, -2.0f/9.0f, 0.0f, -6.0f/9.0f, -2.0f/9.0f, 0.0f, -4.0f/9.0f, -2.0f/9.0f, 0.0f, + -2.0f/9.0f, -2.0f/9.0f, 0.0f, 0.0f, -2.0f/9.0f, 0.0f, 2.0f/9.0f, -2.0f/9.0f, 0.0f, + 4.0f/9.0f, -2.0f/9.0f, 0.0f, 6.0f/9.0f, -2.0f/9.0f, 0.0f, 8.0f/9.0f, -2.0f/9.0f, 0.0f, + -8.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 0.0f, 0.0f, + -2.0f/9.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f/9.0f, 0.0f, 0.0f, + 4.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 0.0f, 0.0f, + -8.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, + -2.0f/9.0f, 2.0f/9.0f, 0.0f, 0.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, + 4.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, + -8.0f/9.0f, 4.0f/9.0f, 0.0f, -6.0f/9.0f, 4.0f/9.0f, 0.0f, -4.0f/9.0f, 4.0f/9.0f, 0.0f, + -2.0f/9.0f, 4.0f/9.0f, 0.0f, 0.0f, 4.0f/9.0f, 0.0f, 2.0f/9.0f, 4.0f/9.0f, 0.0f, + 4.0f/9.0f, 4.0f/9.0f, 0.0f, 6.0f/9.0f, 4.0f/9.0f, 0.0f, 8.0f/9.0f, 4.0f/9.0f, 0.0f, + -8.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, + -2.0f/9.0f, 6.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, + 4.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, + -8.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, + -2.0f/9.0f, 8.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, + 4.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, + -8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 0.0f, -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 0.0f, -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, + -2.0f/9.0f, 0.0f, 2.0f/9.0f, 0.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, + 4.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 0.0f, 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 0.0f, -8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 0.0f, -6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 0.0f, -4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 0.0f, -2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 0.0f, 4.0f/9.0f, -6.0f/9.0f, 0.0f, 4.0f/9.0f, -4.0f/9.0f, 0.0f, 4.0f/9.0f, + -2.0f/9.0f, 0.0f, 4.0f/9.0f, 0.0f, 0.0f, 4.0f/9.0f, 2.0f/9.0f, 0.0f, 4.0f/9.0f, + 4.0f/9.0f, 0.0f, 4.0f/9.0f, 6.0f/9.0f, 0.0f, 4.0f/9.0f, 8.0f/9.0f, 0.0f, 4.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 0.0f, 2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 0.0f, 4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 0.0f, 6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 0.0f, 8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 0.0f, -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 0.0f, -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, + -2.0f/9.0f, 0.0f, 6.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, + 4.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 0.0f, 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, + -8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 0.0f, -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 0.0f, -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, + -2.0f/9.0f, 0.0f, 8.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, + 4.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, + -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 0.0f, 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, + -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, + -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, + 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f + }; + + // data taken from ISO/IEC DIS 11172, Annexes 3-B.2[abcd] and 3-B.4: + + // subbands 0-2 in tables 3-B.2a and 2b: (index is allocation) + public static final int table_ab1_codelength[] = + // bits per codeword + { 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + + public static final float table_ab1_groupingtables[][] = + // pointer to sample grouping table, or NULL-pointer if ungrouped + { null, grouping_5bits, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; + + public static final float table_ab1_factor[] = + // factor for requantization: (real)sample * factor - 1.0 gives requantized sample + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32.0f, 1.0f/64.0f, + 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, 1.0f/1024.0f, 1.0f/2048.0f, + 1.0f/4096.0f, 1.0f/8192.0f, 1.0f/16384.0f, 1.0f/32768.0f }; + + public static final float table_ab1_c[] = + // factor c for requantization from table 3-B.4 + { 0.0f, 1.33333333333f, 1.14285714286f, 1.06666666666f, 1.03225806452f, + 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, 1.00097751711f, + 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, 1.00003051851f, + 1.00001525902f }; + + public static final float table_ab1_d[] = + // addend d for requantization from table 3-B.4 + { 0.0f, 0.50000000000f, 0.25000000000f, 0.12500000000f, 0.06250000000f, + 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, 0.00195312500f, + 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, 0.00006103516f, + 0.00003051758f }; + + // subbands 3-... tables 3-B.2a and 2b: + public static final float[] table_ab234_groupingtables[] = + { null, grouping_5bits, grouping_7bits, null, grouping_10bits, null, null, null, null, null, null, null, null, null, null, null }; + + // subbands 3-10 in tables 3-B.2a and 2b: + public static final int table_ab2_codelength[] = + { 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }; + public static final float table_ab2_factor[] = + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, + 1.0f/32.0f, 1.0f/64.0f, 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, + 1.0f/1024.0f, 1.0f/2048.0f, 1.0f/4096.0f, 1.0f/32768.0f }; + public static final float table_ab2_c[] = + { 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, + 1.06666666666f, 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, + 1.00195694716f, 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, + 1.00001525902f }; + public static final float table_ab2_d[] = + { 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, + 0.12500000000f, 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, + 0.00390625000f, 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, + 0.00003051758f }; + + // subbands 11-22 in tables 3-B.2a and 2b: + public static final int table_ab3_codelength[] = { 0, 5, 7, 3, 10, 4, 5, 16 }; + public static final float table_ab3_factor[] = + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32768.0f }; + public static final float table_ab3_c[] = + { 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, + 1.06666666666f, 1.03225806452f, 1.00001525902f }; + public static final float table_ab3_d[] = + { 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, + 0.12500000000f, 0.06250000000f, 0.00003051758f }; + + // subbands 23-... in tables 3-B.2a and 2b: + public static final int table_ab4_codelength[] = { 0, 5, 7, 16 }; + public static final float table_ab4_factor[] = { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/32768.0f }; + public static final float table_ab4_c[] = { 0.0f, 1.33333333333f, 1.60000000000f, 1.00001525902f }; + public static final float table_ab4_d[] = { 0.0f, 0.50000000000f, 0.50000000000f, 0.00003051758f }; + + // subbands in tables 3-B.2c and 2d: + public static final int table_cd_codelength[] = + { 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + public static final float table_cd_groupingtables[][] = + { null, grouping_5bits, grouping_7bits, grouping_10bits, null, null, null, null, null, null, null, null, null, null, null, null }; + public static final float table_cd_factor[] = + { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32.0f, 1.0f/64.0f, + 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, 1.0f/1024.0f, 1.0f/2048.0f, 1.0f/4096.0f, + 1.0f/8192.0f, 1.0f/16384.0f }; + public static final float table_cd_c[] = + { 0.0f, 1.33333333333f, 1.60000000000f, 1.77777777777f, 1.06666666666f, + 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, + 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, + 1.00003051851f }; + public static final float table_cd_d[] = + { 0.0f, 0.50000000000f, 0.50000000000f, 0.50000000000f, 0.12500000000f, + 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, + 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, + 0.00006103516f }; + + + + protected int subbandnumber; + protected int allocation; + protected int scfsi; + protected float scalefactor1, scalefactor2, scalefactor3; + protected int[] codelength = {0}; + protected float groupingtable[][] = new float[2][]; + //protected float[][] groupingtable = {{0},{0}} ; + protected float[] factor = {0.0f}; + protected int groupnumber; + protected int samplenumber; + protected float[] samples = new float[3]; + protected float[] c = {0}; + protected float[] d = {0}; + /** + * Constructor + */ + public SubbandLayer2(int subbandnumber) + { + this.subbandnumber = subbandnumber; + groupnumber = samplenumber = 0; + } + + + /** + * + */ + protected int get_allocationlength (Header header) + { + if (header.version() == Header.MPEG1) + { + int channel_bitrate = header.bitrate_index(); + + // calculate bitrate per channel: + if (header.mode() != Header.SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + + if (channel_bitrate == 1 || channel_bitrate == 2) + // table 3-B.2c or 3-B.2d + if (subbandnumber <= 1) + return 4; + else + return 3; + else + // tables 3-B.2a or 3-B.2b + if (subbandnumber <= 10) + return 4; + else if (subbandnumber <= 22) + return 3; + else + return 2; + } + else + { // MPEG-2 LSF -- Jeff + + // table B.1 of ISO/IEC 13818-3 + if (subbandnumber <= 3) + return 4; + else if (subbandnumber <= 10) + return 3; + else + return 2; + } + } + + /** + * + */ + protected void prepare_sample_reading(Header header, int allocation, + //float[][] groupingtable, + int channel, + float[] factor, int[] codelength, + float[] c, float[] d) + { + int channel_bitrate = header.bitrate_index(); + // calculate bitrate per channel: + if (header.mode() != Header.SINGLE_CHANNEL) + if (channel_bitrate == 4) + channel_bitrate = 1; + else + channel_bitrate -= 4; + + if (channel_bitrate == 1 || channel_bitrate == 2) + { + // table 3-B.2c or 3-B.2d + groupingtable[channel] = table_cd_groupingtables[allocation]; + factor[0] = table_cd_factor[allocation]; + codelength[0] = table_cd_codelength[allocation]; + c[0] = table_cd_c[allocation]; + d[0] = table_cd_d[allocation]; + } + else + { + // tables 3-B.2a or 3-B.2b + if (subbandnumber <= 2) + { + groupingtable[channel] = table_ab1_groupingtables[allocation]; + factor[0] = table_ab1_factor[allocation]; + codelength[0] = table_ab1_codelength[allocation]; + c[0] = table_ab1_c[allocation]; + d[0] = table_ab1_d[allocation]; + } + else + { + groupingtable[channel] = table_ab234_groupingtables[allocation]; + if (subbandnumber <= 10) + { + factor[0] = table_ab2_factor[allocation]; + codelength[0] = table_ab2_codelength[allocation]; + c[0] = table_ab2_c[allocation]; + d[0] = table_ab2_d[allocation]; + } + else if (subbandnumber <= 22) + { + factor[0] = table_ab3_factor[allocation]; + codelength[0] = table_ab3_codelength[allocation]; + c[0] = table_ab3_c[allocation]; + d[0] = table_ab3_d[allocation]; + } + else + { + factor[0] = table_ab4_factor[allocation]; + codelength[0] = table_ab4_codelength[allocation]; + c[0] = table_ab4_c[allocation]; + d[0] = table_ab4_d[allocation]; + } + } + } + } + + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) + { + int length = get_allocationlength(header); + allocation = stream.get_bits(length); + if (crc != null) + crc.add_bits(allocation, length); + } + + /** + * + */ + public void read_scalefactor_selection (Bitstream stream, Crc16 crc) + { + if (allocation != 0) + { + scfsi = stream.get_bits(2); + if (crc != null) crc.add_bits(scfsi, 2); + } + } + + /** + * + */ + public void read_scalefactor (Bitstream stream, Header header) + { + if (allocation != 0) + { + switch (scfsi) + { + case 0: + scalefactor1 = scalefactors[stream.get_bits(6)]; + scalefactor2 = scalefactors[stream.get_bits(6)]; + scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + case 1: + scalefactor1 = scalefactor2 = scalefactors[stream.get_bits(6)]; + scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + case 2: + scalefactor1 = scalefactor2 = scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + case 3: + scalefactor1 = scalefactors[stream.get_bits(6)]; + scalefactor2 = scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + } + prepare_sample_reading(header, allocation, 0, + factor, codelength, c, d); + } + } + + /** + * + */ + public boolean read_sampledata (Bitstream stream) + { + if (allocation != 0) + if (groupingtable[0] != null) + { + int samplecode = stream.get_bits(codelength[0]); + // create requantized samples: + samplecode += samplecode << 1; + float[] target = samples; + float[] source = groupingtable[0]; + /* + int tmp = 0; + int temp = 0; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp] = source[samplecode + temp]; + */ + //Bugfix: + int tmp = 0; + int temp = samplecode; + + if(temp > source.length - 3) temp = source.length - 3; + + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + + // memcpy (samples, groupingtable + samplecode, 3 * sizeof (real)); + } + else + { + samples[0] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0); + samples[1] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0); + samples[2] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0); + } + + samplenumber = 0; + if (++groupnumber == 12) + return true; + else + return false; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL)) + { + float sample = samples[samplenumber]; + + if (groupingtable[0] == null) + sample = (sample + d[0]) * c[0]; + if (groupnumber <= 4) + sample *= scalefactor1; + else if (groupnumber <= 8) + sample *= scalefactor2; + else + sample *= scalefactor3; + filter1.input_sample(sample, subbandnumber); + } + + if (++samplenumber == 3) + return true; + else + return false; + } + }; + + /** + * Class for layer II subbands in joint stereo mode. + */ + static class SubbandLayer2IntensityStereo extends SubbandLayer2 + { + protected int channel2_scfsi; + protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3; + + /** + * Constructor + */ + public SubbandLayer2IntensityStereo (int subbandnumber) + { + super(subbandnumber); + } + + /** + * + */ + public void read_allocation(Bitstream stream, Header header, Crc16 crc) + { + super.read_allocation (stream, header, crc); + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) + { + if (allocation != 0) + { + scfsi = stream.get_bits(2); + channel2_scfsi = stream.get_bits(2); + if (crc != null) + { + crc.add_bits(scfsi, 2); + crc.add_bits(channel2_scfsi, 2); + } + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + if (allocation != 0) + { + super.read_scalefactor(stream, header); + switch (channel2_scfsi) + { + case 0: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 1: + channel2_scalefactor1 = channel2_scalefactor2 = scalefactors[stream.get_bits (6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 2: + channel2_scalefactor1 = channel2_scalefactor2 = + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 3: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = channel2_scalefactor3 = scalefactors[stream.get_bits (6)]; + break; + } + } + + } + + /** + * + */ + public boolean read_sampledata(Bitstream stream) + { + return super.read_sampledata (stream); + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + if (allocation != 0) + { + float sample = samples[samplenumber]; + + if (groupingtable[0] == null) + sample = (sample + d[0]) * c[0]; + if (channels == OutputChannels.BOTH_CHANNELS) + { + float sample2 = sample; + if (groupnumber <= 4) + { + sample *= scalefactor1; + sample2 *= channel2_scalefactor1; + } + else if (groupnumber <= 8) + { + sample *= scalefactor2; + sample2 *= channel2_scalefactor2; + } + else + { + sample *= scalefactor3; + sample2 *= channel2_scalefactor3; + } + filter1.input_sample(sample, subbandnumber); + filter2.input_sample(sample2, subbandnumber); + } + else if (channels == OutputChannels.LEFT_CHANNEL) + { + if (groupnumber <= 4) + sample *= scalefactor1; + else if (groupnumber <= 8) + sample *= scalefactor2; + else + sample *= scalefactor3; + filter1.input_sample(sample, subbandnumber); + } + else + { + if (groupnumber <= 4) + sample *= channel2_scalefactor1; + else if (groupnumber <= 8) + sample *= channel2_scalefactor2; + else + sample *= channel2_scalefactor3; + filter1.input_sample(sample, subbandnumber); + } + } + + if (++samplenumber == 3) + return true; + else + return false; + } + }; + + /** + * Class for layer II subbands in stereo mode. + */ + static class SubbandLayer2Stereo extends SubbandLayer2 + { + protected int channel2_allocation; + protected int channel2_scfsi; + protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3; + //protected boolean channel2_grouping; ???? Never used! + protected int[] channel2_codelength = {0}; + //protected float[][] channel2_groupingtable = {{0},{0}}; + protected float[] channel2_factor = {0}; + protected float[] channel2_samples; + protected float[] channel2_c = {0}; + protected float[] channel2_d = {0}; + + /** + * Constructor + */ + public SubbandLayer2Stereo(int subbandnumber) + { + super(subbandnumber); + channel2_samples = new float[3]; + } + + /** + * + */ + public void read_allocation (Bitstream stream, Header header, Crc16 crc) + { + int length = get_allocationlength(header); + allocation = stream.get_bits(length); + channel2_allocation = stream.get_bits(length); + if (crc != null) + { + crc.add_bits(allocation, length); + crc.add_bits(channel2_allocation, length); + } + } + + /** + * + */ + public void read_scalefactor_selection(Bitstream stream, Crc16 crc) + { + if (allocation != 0) + { + scfsi = stream.get_bits(2); + if (crc != null) + crc.add_bits(scfsi, 2); + } + if (channel2_allocation != 0) + { + channel2_scfsi = stream.get_bits(2); + if (crc != null) + crc.add_bits(channel2_scfsi, 2); + } + } + + /** + * + */ + public void read_scalefactor(Bitstream stream, Header header) + { + super.read_scalefactor(stream, header); + if (channel2_allocation != 0) + { + switch (channel2_scfsi) + { + case 0: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 1: + channel2_scalefactor1 = channel2_scalefactor2 = + scalefactors[stream.get_bits(6)]; + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 2: + channel2_scalefactor1 = channel2_scalefactor2 = + channel2_scalefactor3 = scalefactors[stream.get_bits(6)]; + break; + + case 3: + channel2_scalefactor1 = scalefactors[stream.get_bits(6)]; + channel2_scalefactor2 = channel2_scalefactor3 = + scalefactors[stream.get_bits(6)]; + break; + } + prepare_sample_reading(header, channel2_allocation, 1, + channel2_factor, channel2_codelength, channel2_c, + channel2_d); + } + } + + /** + * + */ + public boolean read_sampledata (Bitstream stream) + { + boolean returnvalue = super.read_sampledata(stream); + + if (channel2_allocation != 0) + if (groupingtable[1] != null) + { + int samplecode = stream.get_bits(channel2_codelength[0]); + // create requantized samples: + samplecode += samplecode << 1; + /* + float[] target = channel2_samples; + float[] source = channel2_groupingtable[0]; + int tmp = 0; + int temp = 0; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp++] = source[samplecode + temp]; + temp++; + target[tmp] = source[samplecode + temp]; + // memcpy (channel2_samples, channel2_groupingtable + samplecode, 3 * sizeof (real)); + */ + float[] target = channel2_samples; + float[] source = groupingtable[1]; + int tmp = 0; + int temp = samplecode; + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + temp++;tmp++; + target[tmp] = source[temp]; + + } + else + { + channel2_samples[0] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + channel2_samples[1] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + channel2_samples[2] = (float) ((stream.get_bits(channel2_codelength[0])) * + channel2_factor[0] - 1.0); + } + return returnvalue; + } + + /** + * + */ + public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2) + { + boolean returnvalue = super.put_next_sample(channels, filter1, filter2); + if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL)) + { + float sample = channel2_samples[samplenumber - 1]; + + if (groupingtable[1] == null) + sample = (sample + channel2_d[0]) * channel2_c[0]; + + if (groupnumber <= 4) + sample *= channel2_scalefactor1; + else if (groupnumber <= 8) + sample *= channel2_scalefactor2; + else + sample *= channel2_scalefactor3; + if (channels == OutputChannels.BOTH_CHANNELS) + filter2.input_sample(sample, subbandnumber); + else + filter1.input_sample(sample, subbandnumber); + } + return returnvalue; + } + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java b/src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java new file mode 100644 index 0000000..009e60d --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java @@ -0,0 +1,2436 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 18/06/01 Michael Scheerer, Fixed bugs which causes + * negative indexes in method huffmann_decode and in method + * dequanisize_sample. + * + * 16/07/01 Michael Scheerer, Catched a bug in method + * huffmann_decode, which causes an outOfIndexException. + * Cause : Indexnumber of 24 at SfBandIndex, + * which has only a length of 22. I have simply and dirty + * fixed the index to <= 22, because I'm not really be able + * to fix the bug. The Indexnumber is taken from the MP3 + * file and the origin Ma-Player with the same code works + * well. + * + * 02/19/99 Java Conversion by E.B, javalayer@javazoom.net + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class Implementing Layer 3 Decoding. + * + * @since 0.0 + */ +final class LayerIIIDecoder implements FrameDecoder +{ + static final double d43 = (4.0/3.0); + + public int[] scalefac_buffer; + + // MDM: removed, as this wasn't being used. + //private float CheckSumOut1d = 0.0f; + private int CheckSumHuff = 0; + private int[] is_1d; + private float[][][] ro; + private float[][][] lr; + private float[] out_1d; + private float[][] prevblck; + private float[][] k; + private int[] nonzero; + private Bitstream stream; + private Header header; + private SynthesisFilter filter1, filter2; + private Obuffer buffer; + private int which_channels; + private BitReserve br; + private III_side_info_t si; + + private temporaire2[] III_scalefac_t; + private temporaire2[] scalefac; + // private III_scalefac_t scalefac; + + private int max_gr; + private int frame_start; + private int part2_start; + private int channels; + private int first_channel; + private int last_channel; + private int sfreq; + + + /** + * Constructor. + */ + // REVIEW: these constructor arguments should be moved to the + // decodeFrame() method, where possible, so that one + public LayerIIIDecoder(Bitstream stream0, Header header0, + SynthesisFilter filtera, SynthesisFilter filterb, + Obuffer buffer0, int which_ch0) + { + huffcodetab.inithuff(); + is_1d = new int[SBLIMIT*SSLIMIT+4]; + ro = new float[2][SBLIMIT][SSLIMIT]; + lr = new float[2][SBLIMIT][SSLIMIT]; + out_1d = new float[SBLIMIT*SSLIMIT]; + prevblck = new float[2][SBLIMIT*SSLIMIT]; + k = new float[2][SBLIMIT*SSLIMIT]; + nonzero = new int[2]; + + //III_scalefact_t + III_scalefac_t = new temporaire2[2]; + III_scalefac_t[0] = new temporaire2(); + III_scalefac_t[1] = new temporaire2(); + scalefac = III_scalefac_t; + // L3TABLE INIT + + sfBandIndex = new SBI[9]; // SZD: MPEG2.5 +3 indices + int[] l0 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s0 = {0,4,8,12,18,24,32,42,56,74,100,132,174,192}; + int[] l1 = {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}; + int[] s1 = {0,4,8,12,18,26,36,48,62,80,104,136,180,192}; + int[] l2 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s2 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192}; + + int[] l3 = {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}; + int[] s3 = {0,4,8,12,16,22,30,40,52,66,84,106,136,192}; + int[] l4 = {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}; + int[] s4 = {0,4,8,12,16,22,28,38,50,64,80,100,126,192}; + int[] l5 = {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}; + int[] s5 = {0,4,8,12,16,22,30,42,58,78,104,138,180,192}; + // SZD: MPEG2.5 + int[] l6 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s6 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192}; + int[] l7 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}; + int[] s7 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192}; + int[] l8 = {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}; + int[] s8 = {0,8,16,24,36,52,72,96,124,160,162,164,166,192}; + + sfBandIndex[0]= new SBI(l0,s0); + sfBandIndex[1]= new SBI(l1,s1); + sfBandIndex[2]= new SBI(l2,s2); + + sfBandIndex[3]= new SBI(l3,s3); + sfBandIndex[4]= new SBI(l4,s4); + sfBandIndex[5]= new SBI(l5,s5); + //SZD: MPEG2.5 + sfBandIndex[6]= new SBI(l6,s6); + sfBandIndex[7]= new SBI(l7,s7); + sfBandIndex[8]= new SBI(l8,s8); + // END OF L3TABLE INIT + + if(reorder_table == null) { // SZD: generate LUT + reorder_table = new int[9][]; + for(int i = 0; i < 9; i++) + reorder_table[i] = reorder(sfBandIndex[i].s); + } + + // Sftable + int[] ll0 = {0, 6, 11, 16, 21}; + int[] ss0 = {0, 6, 12}; + sftable = new Sftable(ll0,ss0); + // END OF Sftable + + // scalefac_buffer + scalefac_buffer = new int[54]; + // END OF scalefac_buffer + + stream = stream0; + header = header0; + filter1 = filtera; + filter2 = filterb; + buffer = buffer0; + which_channels = which_ch0; + + frame_start = 0; + channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2; + max_gr = (header.version() == Header.MPEG1) ? 2 : 1; + + sfreq = header.sample_frequency() + + ((header.version() == Header.MPEG1) ? 3 : + (header.version() == Header.MPEG25_LSF) ? 6 : 0); // SZD + + if (channels == 2) + { + switch (which_channels) + { + case OutputChannels.LEFT_CHANNEL: + case OutputChannels.DOWNMIX_CHANNELS: + first_channel = last_channel = 0; + break; + + case OutputChannels.RIGHT_CHANNEL: + first_channel = last_channel = 1; + break; + + case OutputChannels.BOTH_CHANNELS: + default: + first_channel = 0; + last_channel = 1; + break; + } + } + else + { + first_channel = last_channel = 0; + } + + for(int ch=0;ch<2;ch++) + for (int j=0; j<576; j++) + prevblck[ch][j] = 0.0f; + + nonzero[0] = nonzero[1] = 576; + + br = new BitReserve(); + si = new III_side_info_t(); + } + + /** + * Notify decoder that a seek is being made. + */ + public void seek_notify() + { + frame_start = 0; + for(int ch=0;ch<2;ch++) + for (int j=0; j<576; j++) + prevblck[ch][j] = 0.0f; + br = new BitReserve(); + } + + public void decodeFrame() + { + decode(); + } + + /** + * Decode one frame, filling the buffer with the output samples. + */ + + // subband samples are buffered and passed to the + // SynthesisFilter in one go. + private float[] samples1 = new float[32]; + private float[] samples2 = new float[32]; + + public void decode() + { + int nSlots = header.slots(); + int flush_main; + int gr, ch, ss, sb, sb18; + int main_data_end; + int bytes_to_discard; + int i; + + get_side_info(); + + for (i=0; i>> 3; // of previous frame + + if ((flush_main = (br.hsstell() & 7)) != 0) { + br.hgetbits(8 - flush_main); + main_data_end++; + } + + bytes_to_discard = frame_start - main_data_end + - si.main_data_begin; + + frame_start += nSlots; + + if (bytes_to_discard < 0) + return; + + if (main_data_end > 4096) { + frame_start -= 4096; + br.rewindNbytes(4096); + } + + for (; bytes_to_discard > 0; bytes_to_discard--) + br.hgetbits(8); + + for (gr=0;gr>> 4) / 5 ; + new_slen[1] = (scalefac_comp >>> 4) % 5 ; + new_slen[2] = (scalefac_comp & 0xF) >>> 2 ; + new_slen[3] = (scalefac_comp & 3); + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 0; + + } else if (scalefac_comp < 500) { + + new_slen[0] = ((scalefac_comp - 400) >>> 2) / 5 ; + new_slen[1] = ((scalefac_comp - 400) >>> 2) % 5 ; + new_slen[2] = (scalefac_comp - 400 ) & 3 ; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 1; + + } else if (scalefac_comp < 512) { + + new_slen[0] = (scalefac_comp - 500 ) / 3 ; + new_slen[1] = (scalefac_comp - 500) % 3 ; + new_slen[2] = 0; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 1; + blocknumber = 2; + } + } + + if((((mode_ext == 1) || (mode_ext == 3)) && (ch == 1))) + { + int_scalefac_comp = scalefac_comp >>> 1; + + if (int_scalefac_comp < 180) + { + new_slen[0] = int_scalefac_comp / 36 ; + new_slen[1] = (int_scalefac_comp % 36 ) / 6 ; + new_slen[2] = (int_scalefac_comp % 36) % 6; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 3; + } else if (int_scalefac_comp < 244) { + new_slen[0] = ((int_scalefac_comp - 180 ) & 0x3F) >>> 4 ; + new_slen[1] = ((int_scalefac_comp - 180) & 0xF) >>> 2 ; + new_slen[2] = (int_scalefac_comp - 180 ) & 3 ; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 4; + } else if (int_scalefac_comp < 255) { + new_slen[0] = (int_scalefac_comp - 244 ) / 3 ; + new_slen[1] = (int_scalefac_comp - 244 ) % 3 ; + new_slen[2] = 0 ; + new_slen[3] = 0; + si.ch[ch].gr[gr].preflag = 0; + blocknumber = 5; + } + } + + for (int x=0; x<45; x++) // why 45, not 54? + scalefac_buffer[x] = 0; + + m = 0; + for (int i=0; i<4;i++) { + for (int j = 0; j < nr_of_sfb_block[blocknumber][blocktypenumber][i]; + j++) + { + scalefac_buffer[m] = (new_slen[i] == 0) ? 0 : + br.hgetbits(new_slen[i]); + m++; + + } // for (unint32 j ... + } // for (uint32 i ... + } + + /** + * + */ + private void get_LSF_scale_factors(int ch, int gr) + { + int m = 0; + int sfb, window; + gr_info_s gr_info = (si.ch[ch].gr[gr]); + + get_LSF_scale_data(ch, gr); + + if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) { + if (gr_info.mixed_block_flag != 0) { // MIXED + for (sfb = 0; sfb < 8; sfb++) + { + scalefac[ch].l[sfb] = scalefac_buffer[m]; + m++; + } + for (sfb = 3; sfb < 12; sfb++) { + for (window=0; window<3; window++) + { + scalefac[ch].s[window][sfb] = scalefac_buffer[m]; + m++; + } + } + for (window=0; window<3; window++) + scalefac[ch].s[window][12] = 0; + + } else { // SHORT + + for (sfb = 0; sfb < 12; sfb++) { + for (window=0; window<3; window++) + { + scalefac[ch].s[window][sfb] = scalefac_buffer[m]; + m++; + } + } + + for (window=0; window<3; window++) + scalefac[ch].s[window][12] = 0; + } + } else { // LONG types 0,1,3 + + for (sfb = 0; sfb < 21; sfb++) { + scalefac[ch].l[sfb] = scalefac_buffer[m]; + m++; + } + scalefac[ch].l[21] = 0; // Jeff + scalefac[ch].l[22] = 0; + } + } + + /** + * + */ + int[] x = {0}; + int[] y = {0}; + int[] v = {0}; + int[] w = {0}; + private void huffman_decode(int ch, int gr) + { + x[0] = 0; + y[0] = 0; + v[0] = 0; + w[0] = 0; + + int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length; + int num_bits; + int region1Start; + int region2Start; + int index; + + int buf, buf1; + + huffcodetab h; + + // Find region boundary for short block case + + if ( ((si.ch[ch].gr[gr].window_switching_flag) != 0) && + (si.ch[ch].gr[gr].block_type == 2) ) { + + // Region2. + //MS: Extrahandling for 8KHZ + region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case 8KHZ = 72 + region2Start = 576; // No Region2 for short block case + + } else { // Find region boundary for long block case + + buf = si.ch[ch].gr[gr].region0_count + 1; + buf1 = buf + si.ch[ch].gr[gr].region1_count + 1; + + if(buf1 > sfBandIndex[sfreq].l.length - 1) buf1 = sfBandIndex[sfreq].l.length - 1; + + region1Start = sfBandIndex[sfreq].l[buf]; + region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */ + } + + index = 0; + // Read bigvalues area + for (int i=0; i<(si.ch[ch].gr[gr].big_values<<1); i+=2) { + if (i= is_1d.length) System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length); + + is_1d[index++] = x[0]; + is_1d[index++] = y[0]; + + CheckSumHuff = CheckSumHuff + x[0] + y[0]; + // System.out.println("x = "+x[0]+" y = "+y[0]); + } + + // Read count1 area + h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select+32]; + num_bits = br.hsstell(); + + while ((num_bits < part2_3_end) && (index < 576)) { + + huffcodetab.huffman_decoder(h, x, y, v, w, br); + + is_1d[index++] = v[0]; + is_1d[index++] = w[0]; + is_1d[index++] = x[0]; + is_1d[index++] = y[0]; + CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0]; + // System.out.println("v = "+v[0]+" w = "+w[0]); + // System.out.println("x = "+x[0]+" y = "+y[0]); + num_bits = br.hsstell(); + } + + if (num_bits > part2_3_end) { + br.rewindNbits(num_bits - part2_3_end); + index-=4; + } + + num_bits = br.hsstell(); + + // Dismiss stuffing bits + if (num_bits < part2_3_end) + br.hgetbits(part2_3_end - num_bits); + + // Zero out rest + + if (index < 576) + nonzero[ch] = index; + else + nonzero[ch] = 576; + + if (index < 0) index = 0; + + // may not be necessary + for (; index<576; index++) + is_1d[index] = 0; + } + + /** + * + */ + private void i_stereo_k_values(int is_pos, int io_type, int i) + { + if (is_pos == 0) { + k[0][i] = 1.0f; + k[1][i] = 1.0f; + } else if ((is_pos & 1) != 0) { + k[0][i] = io[io_type][(is_pos + 1) >>> 1]; + k[1][i] = 1.0f; + } else { + k[0][i] = 1.0f; + k[1][i] = io[io_type][is_pos >>> 1]; + } + } + + /** + * + */ + private void dequantize_sample(float xr[][], int ch, int gr) + { + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int cb=0; + int next_cb_boundary; + int cb_begin = 0; + int cb_width = 0; + int index=0, t_index, j; + float g_gain; + float[][] xr_1d = xr; + + // choose correct scalefactor band per block type, initalize boundary + + if ((gr_info.window_switching_flag !=0 ) && (gr_info.block_type == 2) ) { + if (gr_info.mixed_block_flag != 0) + next_cb_boundary=sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3 + else { + cb_width = sfBandIndex[sfreq].s[1]; + next_cb_boundary = (cb_width << 2) - cb_width; + cb_begin = 0; + } + } else { + next_cb_boundary=sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3 + } + + // Compute overall (global) scaling. + + g_gain = (float) Math.pow(2.0 , (0.25 * (gr_info.global_gain - 210.0))); + + for (j=0; j 0) xr_1d[quotien][reste] = g_gain * t_43[abv]; + else + { + if (-abv < t_43.length) xr_1d[quotien][reste] = -g_gain * t_43[-abv]; + else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43); + } + } + else + { + if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * (float)Math.pow(abv, d43); + else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43); + } + } + } + + // apply formula per block type + for (j=0; j= 36)) )) + { + + t_index = (index - cb_begin) / cb_width; + /* xr[sb][ss] *= pow(2.0, ((-2.0 * gr_info.subblock_gain[t_index]) + -(0.5 * (1.0 + gr_info.scalefac_scale) + * scalefac[ch].s[t_index][cb]))); */ + int idx = scalefac[ch].s[t_index][cb] + << gr_info.scalefac_scale; + idx += (gr_info.subblock_gain[t_index] << 2); + + xr_1d[quotien][reste] *= two_to_negative_half_pow[idx]; + + } else { // LONG block types 0,1,3 & 1st 2 subbands of switched blocks + /* xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info.scalefac_scale) + * (scalefac[ch].l[cb] + + gr_info.preflag * pretab[cb])); */ + int idx = scalefac[ch].l[cb]; + + if (gr_info.preflag != 0) + idx += pretab[cb]; + + idx = idx << gr_info.scalefac_scale; + xr_1d[quotien][reste] *= two_to_negative_half_pow[idx]; + } + index++; + } + + for (j=nonzero[ch]; j<576; j++) + { + // Modif E.B 02/22/99 + int reste = j % SSLIMIT; + int quotien = (int) ((j-reste)/SSLIMIT); + if(reste < 0) reste = 0; + if(quotien < 0) quotien = 0; + xr_1d[quotien][reste] = 0.0f; + } + + return; + } + + /** + * + */ + private void reorder(float xr[][], int ch, int gr) + { + gr_info_s gr_info = (si.ch[ch].gr[gr]); + int freq, freq3; + int index; + int sfb, sfb_start, sfb_lines; + int src_line, des_line; + float[][] xr_1d = xr; + + if ((gr_info.window_switching_flag !=0) && (gr_info.block_type == 2)) { + + for(index=0; index<576; index++) + out_1d[index] = 0.0f; + + if (gr_info.mixed_block_flag !=0 ) { + // NO REORDER FOR LOW 2 SUBBANDS + for (index = 0; index < 36; index++) + { + // Modif E.B 02/22/99 + int reste = index % SSLIMIT; + int quotien = (int) ((index-reste)/SSLIMIT); + out_1d[index] = xr_1d[quotien][reste]; + } + // REORDERING FOR REST SWITCHED SHORT + /*for( sfb=3,sfb_start=sfBandIndex[sfreq].s[3], + sfb_lines=sfBandIndex[sfreq].s[4] - sfb_start; + sfb < 13; sfb++,sfb_start = sfBandIndex[sfreq].s[sfb], + sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start ) + {*/ + for( sfb=3; sfb < 13; sfb++) + { + //System.out.println("sfreq="+sfreq+" sfb="+sfb+" sfBandIndex="+sfBandIndex.length+" sfBandIndex[sfreq].s="+sfBandIndex[sfreq].s.length); + sfb_start = sfBandIndex[sfreq].s[sfb]; + sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start; + + int sfb_start3 = (sfb_start << 2) - sfb_start; + + for(freq=0, freq3=0; freq=3; sfb-- ) { + i = sfBandIndex[sfreq].s[sfb]; + lines = sfBandIndex[sfreq].s[sfb+1] - i; + i = (i << 2) - i + (j+1) * lines - 1; + + while (lines > 0) { + if (ro[1][i/18][i%18] != 0.0f) { + // MDM: in java, array access is very slow. + // Is quicker to compute div and mod values. + //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) { + sfbcnt = sfb; + sfb = -10; + lines = -10; + } + + lines--; + i--; + + } // while (lines > 0) + + } // for (sfb=12 ... + sfb = sfbcnt + 1; + + if (sfb > max_sfb) + max_sfb = sfb; + + while(sfb < 12) { + temp = sfBandIndex[sfreq].s[sfb]; + sb = sfBandIndex[sfreq].s[sfb+1] - temp; + i = (temp << 2) - temp + j * sb; + + for ( ; sb > 0; sb--) { + is_pos[i] = scalefac[1].s[j][sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + + i++; + } // for (; sb>0... + sfb++; + } // while (sfb < 12) + sfb = sfBandIndex[sfreq].s[10]; + sb = sfBandIndex[sfreq].s[11] - sfb; + sfb = (sfb << 2) - sfb + j * sb; + temp = sfBandIndex[sfreq].s[11]; + sb = sfBandIndex[sfreq].s[12] - temp; + i = (temp << 2) - temp + j * sb; + + for (; sb > 0; sb--) { + is_pos[i] = is_pos[sfb]; + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // for (; sb > 0 ... + } + if (max_sfb <= 3) { + i = 2; + ss = 17; + sb = -1; + while (i >= 0) { + if (ro[1][i][ss] != 0.0f) { + sb = (i<<4) + (i<<1) + ss; + i = -1; + } else { + ss--; + if (ss < 0) { + i--; + ss = 17; + } + } // if (ro ... + } // while (i>=0) + i = 0; + while (sfBandIndex[sfreq].l[i] <= sb) + i++; + sfb = i; + i = sfBandIndex[sfreq].l[i]; + for (; sfb<8; sfb++) { + sb = sfBandIndex[sfreq].l[sfb+1]-sfBandIndex[sfreq].l[sfb]; + for (; sb>0; sb--) { + is_pos[i] = scalefac[1].l[sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } // for (; sb>0 ... + } // for (; sfb<8 ... + } // for (j=0 ... + } else { // if (gr_info.mixed_block_flag) + for (int j=0; j<3; j++) { + int sfbcnt; + sfbcnt = -1; + for( sfb=12; sfb >=0; sfb-- ) + { + temp = sfBandIndex[sfreq].s[sfb]; + lines = sfBandIndex[sfreq].s[sfb+1] - temp; + i = (temp << 2) - temp + (j+1) * lines - 1; + + while (lines > 0) { + if (ro[1][i/18][i%18] != 0.0f) { + // MDM: in java, array access is very slow. + // Is quicker to compute div and mod values. + //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) { + sfbcnt = sfb; + sfb = -10; + lines = -10; + } + lines--; + i--; + } // while (lines > 0) */ + + } // for (sfb=12 ... + sfb = sfbcnt + 1; + while(sfb<12) { + temp = sfBandIndex[sfreq].s[sfb]; + sb = sfBandIndex[sfreq].s[sfb+1] - temp; + i = (temp << 2) - temp + j * sb; + for ( ; sb > 0; sb--) { + is_pos[i] = scalefac[1].s[j][sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } // for (; sb>0 ... + sfb++; + } // while (sfb<12) + + temp = sfBandIndex[sfreq].s[10]; + temp2= sfBandIndex[sfreq].s[11]; + sb = temp2 - temp; + sfb = (temp << 2) - temp + j * sb; + sb = sfBandIndex[sfreq].s[12] - temp2; + i = (temp2 << 2) - temp2 + j * sb; + + for (; sb>0; sb--) { + is_pos[i] = is_pos[sfb]; + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // for (; sb>0 ... + } // for (sfb=12 + } // for (j=0 ... + } else { // if (gr_info.window_switching_flag ... + i = 31; + ss = 17; + sb = 0; + while (i >= 0) { + if (ro[1][i][ss] != 0.0f) { + sb = (i<<4) + (i<<1) + ss; + i = -1; + } else { + ss--; + if (ss < 0) { + i--; + ss = 17; + } + } + } + i = 0; + while (sfBandIndex[sfreq].l[i] <= sb) + i++; + + sfb = i; + i = sfBandIndex[sfreq].l[i]; + for (; sfb<21; sfb++) { + sb = sfBandIndex[sfreq].l[sfb+1] - sfBandIndex[sfreq].l[sfb]; + for (; sb > 0; sb--) { + is_pos[i] = scalefac[1].l[sfb]; + if (is_pos[i] != 7) + if (lsf) + i_stereo_k_values(is_pos[i], io_type, i); + else + is_ratio[i] = TAN12[is_pos[i]]; + i++; + } + } + sfb = sfBandIndex[sfreq].l[20]; + for (sb = 576 - sfBandIndex[sfreq].l[21]; (sb > 0) && (i<576); sb--) + { + is_pos[i] = is_pos[sfb]; // error here : i >=576 + + if (lsf) { + k[0][i] = k[0][sfb]; + k[1][i] = k[1][sfb]; + } else { + is_ratio[i] = is_ratio[sfb]; + } + i++; + } // if (gr_info.mixed_block_flag) + } // if (gr_info.window_switching_flag ... + } // if (i_stereo) + + i = 0; + for(sb=0;sb 32767.0f) ? 32767 : + ((sample < -32768.0f) ? -32768 : + (short) sample)); + } + + /** + * Write the samples to the file or directly to the audio hardware. + */ + public abstract void write_buffer(int val); + public abstract void close(); + + /** + * Clears all data in the buffer (for seeking). + */ + public abstract void clear_buffer(); + + /** + * Notify the buffer that the user has stopped the stream. + */ + public abstract void set_stop_flag(); +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java b/src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java new file mode 100644 index 0000000..7197306 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java @@ -0,0 +1,143 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 12/12/99 Initial implementation. mdm@techie.com. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + + +/** + * A Type-safe representation of the the supported output channel + * constants. + * + * This class is immutable and, hence, is thread safe. + * + * @author Mat McGowan 12/12/99 + * @since 0.0.7 + */ +public class OutputChannels +{ + /** + * Flag to indicate output should include both channels. + */ + public static final int BOTH_CHANNELS = 0; + + /** + * Flag to indicate output should include the left channel only. + */ + public static final int LEFT_CHANNEL = 1; + + /** + * Flag to indicate output should include the right channel only. + */ + public static final int RIGHT_CHANNEL = 2; + + /** + * Flag to indicate output is mono. + */ + public static final int DOWNMIX_CHANNELS = 3; + + + public static final OutputChannels LEFT = new OutputChannels(LEFT_CHANNEL); + public static final OutputChannels RIGHT = new OutputChannels(RIGHT_CHANNEL); + public static final OutputChannels BOTH = new OutputChannels(BOTH_CHANNELS); + public static final OutputChannels DOWNMIX = new OutputChannels(DOWNMIX_CHANNELS); + + + private /*final*/ int outputChannels; + + /** + * Creates an OutputChannels instance + * corresponding to the given channel code. + * + * @param code one of the OutputChannels channel code constants. + * + * @throws IllegalArgumentException if code is not a valid + * channel code. + */ + public static OutputChannels fromInt(int code) + { + switch (code) + { + case LEFT_CHANNEL: + return LEFT; + case RIGHT_CHANNEL: + return RIGHT; + case BOTH_CHANNELS: + return BOTH; + case DOWNMIX_CHANNELS: + return DOWNMIX; + default: + throw new IllegalArgumentException("Invalid channel code: "+code); + } + } + + private OutputChannels(int channels) + { + outputChannels = channels; + + if (channels<0 || channels>3) + throw new IllegalArgumentException("channels"); + } + + /** + * Retrieves the code representing the desired output channels. + * Will be one of LEFT_CHANNEL, RIGHT_CHANNEL, BOTH_CHANNELS + * or DOWNMIX_CHANNELS. + * + * @return the channel code represented by this instance. + */ + public int getChannelsOutputCode() + { + return outputChannels; + } + + /** + * Retrieves the number of output channels represented + * by this channel output type. + * + * @return The number of output channels for this channel output + * type. This will be 2 for BOTH_CHANNELS only, and 1 + * for all other types. + */ + public int getChannelCount() + { + int count = (outputChannels==BOTH_CHANNELS) ? 2 : 1; + return count; + } + + + public boolean equals(Object o) + { + boolean equals = false; + + if (o instanceof OutputChannels) + { + OutputChannels oc = (OutputChannels)o; + equals = (oc.outputChannels == outputChannels); + } + + return equals; + } + + public int hashCode() + { + return outputChannels; + } + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java b/src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java new file mode 100644 index 0000000..00b9f1b --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java @@ -0,0 +1,132 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 12/12/99 Initial Version based on FileObuffer. mdm@techie.com. + * + * FileObuffer: + * 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * The SampleBuffer class implements an output buffer + * that provides storage for a fixed size block of samples. + */ +public class SampleBuffer extends Obuffer +{ + private short[] buffer; + private int[] bufferp; + private int channels; + private int frequency; + + /** + * Constructor + */ + public SampleBuffer(int sample_frequency, int number_of_channels) + { + buffer = new short[OBUFFERSIZE]; + bufferp = new int[MAXCHANNELS]; + channels = number_of_channels; + frequency = sample_frequency; + + for (int i = 0; i < number_of_channels; ++i) + bufferp[i] = (short)i; + + } + + public int getChannelCount() + { + return this.channels; + } + + public int getSampleFrequency() + { + return this.frequency; + } + + public short[] getBuffer() + { + return this.buffer; + } + + public int getBufferLength() + { + return bufferp[0]; + } + + /** + * Takes a 16 Bit PCM sample. + */ + public void append(int channel, short value) + { + buffer[bufferp[channel]] = value; + bufferp[channel] += channels; + } + + public void appendSamples(int channel, float[] f) + { + int pos = bufferp[channel]; + + short s; + float fs; + for (int i=0; i<32;) + { + fs = f[i++]; + fs = (fs>32767.0f ? 32767.0f + : (fs < -32767.0f ? -32767.0f : fs)); + + s = (short)fs; + buffer[pos] = s; + pos += channels; + } + + bufferp[channel] = pos; + } + + + /** + * Write the samples to the file (Random Access). + */ + public void write_buffer(int val) + { + + //for (int i = 0; i < channels; ++i) + // bufferp[i] = (short)i; + + } + + public void close() + {} + + /** + * + */ + public void clear_buffer() + { + for (int i = 0; i < channels; ++i) + bufferp[i] = (short)i; + } + + /** + * + */ + public void set_stop_flag() + {} +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/Source.java b/src/lwjgl/java/javazoom/jl/decoder/Source.java new file mode 100644 index 0000000..9d6a5d7 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/Source.java @@ -0,0 +1,49 @@ +/* + * 11/19/04 1.0 moved to LGPL. + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +import java.io.IOException; + +/** + * Work in progress. + * + * Class to describe a seekable data source. + * + */ +public interface Source +{ + + public static final long LENGTH_UNKNOWN = -1; + + public int read(byte[] b, int offs, int len) + throws IOException; + + + public boolean willReadBlock(); + + public boolean isSeekable(); + + public long length(); + + public long tell(); + + public long seek(long pos); + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java b/src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java new file mode 100644 index 0000000..ea6e1a7 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java @@ -0,0 +1,1815 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 04/01/00 Fixes for running under build 23xx Microsoft JVM. mdm. + * + * 19/12/99 Performance improvements to compute_pcm_samples(). + * Mat McGowan. mdm@techie.com. + * + * 16/02/99 Java Conversion by E.B , javalayer@javazoom.net + * + * @(#) synthesis_filter.h 1.8, last edit: 6/15/94 16:52:00 + * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) + * @(#) Berlin University of Technology + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ +package javazoom.jl.decoder; + +import java.io.IOException; + +/** + * A class for the synthesis filter bank. + * This class does a fast downsampling from 32, 44.1 or 48 kHz to 8 kHz, if ULAW is defined. + * Frequencies above 4 kHz are removed by ignoring higher subbands. + */ +final class SynthesisFilter +{ + private float[] v1; + private float[] v2; + private float[] actual_v; // v1 or v2 + private int actual_write_pos; // 0-15 + private float[] samples; // 32 new subband samples + private int channel; + private float scalefactor; + private float[] eq; + + /** + * Quality value for controlling CPU usage/quality tradeoff. + */ + /* + private int quality; + + private int v_inc; + + + + public static final int HIGH_QUALITY = 1; + public static final int MEDIUM_QUALITY = 2; + public static final int LOW_QUALITY = 4; + */ + + /** + * Constructor. + * + * The scalefactor scales the calculated float pcm samples to short values + * (raw pcm samples are in [-1.0, 1.0], if no violations occur). + */ + public SynthesisFilter(int channelnumber, float factor, float[] eq0) + { + if (d==null) + { + d = load_d(); + d16 = splitArray(d, 16); + } + + v1 = new float[512]; + v2 = new float[512]; + samples = new float[32]; + channel = channelnumber; + scalefactor = factor; + setEQ(eq); + //setQuality(HIGH_QUALITY); + + reset(); + } + + public void setEQ(float[] eq0) + { + this.eq = eq0; + if (eq==null) + { + eq = new float[32]; + for (int i=0; i<32; i++) + eq[i] = 1.0f; + } + if (eq.length<32) + { + throw new IllegalArgumentException("eq0"); + } + + } + + /* + private void setQuality(int quality0) + { + switch (quality0) + { + case HIGH_QUALITY: + case MEDIUM_QUALITY: + case LOW_QUALITY: + v_inc = 16 * quality0; + quality = quality0; + break; + default : + throw new IllegalArgumentException("Unknown quality value"); + } + } + + public int getQuality() + { + return quality; + } + */ + + /** + * Reset the synthesis filter. + */ + public void reset() + { + //float[] floatp; + // float[] floatp2; + + // initialize v1[] and v2[]: + //for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; ) + // *--floatp = *--floatp2 = 0.0; + for (int p=0;p<512;p++) + v1[p] = v2[p] = 0.0f; + + // initialize samples[]: + //for (floatp = samples + 32; floatp > samples; ) + // *--floatp = 0.0; + for (int p2=0;p2<32;p2++) + samples[p2] = 0.0f; + + actual_v = v1; + actual_write_pos = 15; + } + + + /** + * Inject Sample. + */ + public void input_sample(float sample, int subbandnumber) + { + samples[subbandnumber] = eq[subbandnumber]*sample; + } + + public void input_samples(float[] s) + { + for (int i=31; i>=0; i--) + { + samples[i] = s[i]*eq[i]; + } + } + + /** + * Compute new values via a fast cosine transform. + */ + private void compute_new_v() + { + // p is fully initialized from x1 + //float[] p = _p; + // pp is fully initialized from p + //float[] pp = _pp; + + //float[] new_v = _new_v; + + //float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 + //float[] p = new float[16]; + //float[] pp = new float[16]; + + /* + for (int i=31; i>=0; i--) + { + new_v[i] = 0.0f; + } + */ + + float new_v0, new_v1, new_v2, new_v3, new_v4, new_v5, new_v6, new_v7, new_v8, new_v9; + float new_v10, new_v11, new_v12, new_v13, new_v14, new_v15, new_v16, new_v17, new_v18, new_v19; + float new_v20, new_v21, new_v22, new_v23, new_v24, new_v25, new_v26, new_v27, new_v28, new_v29; + float new_v30, new_v31; + + new_v0 = new_v1 = new_v2 = new_v3 = new_v4 = new_v5 = new_v6 = new_v7 = new_v8 = new_v9 = + new_v10 = new_v11 = new_v12 = new_v13 = new_v14 = new_v15 = new_v16 = new_v17 = new_v18 = new_v19 = + new_v20 = new_v21 = new_v22 = new_v23 = new_v24 = new_v25 = new_v26 = new_v27 = new_v28 = new_v29 = + new_v30 = new_v31 = 0.0f; + + +// float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 +// float[] p = new float[16]; +// float[] pp = new float[16]; + + float[] s = samples; + + float s0 = s[0]; + float s1 = s[1]; + float s2 = s[2]; + float s3 = s[3]; + float s4 = s[4]; + float s5 = s[5]; + float s6 = s[6]; + float s7 = s[7]; + float s8 = s[8]; + float s9 = s[9]; + float s10 = s[10]; + float s11 = s[11]; + float s12 = s[12]; + float s13 = s[13]; + float s14 = s[14]; + float s15 = s[15]; + float s16 = s[16]; + float s17 = s[17]; + float s18 = s[18]; + float s19 = s[19]; + float s20 = s[20]; + float s21 = s[21]; + float s22 = s[22]; + float s23 = s[23]; + float s24 = s[24]; + float s25 = s[25]; + float s26 = s[26]; + float s27 = s[27]; + float s28 = s[28]; + float s29 = s[29]; + float s30 = s[30]; + float s31 = s[31]; + + float p0 = s0 + s31; + float p1 = s1 + s30; + float p2 = s2 + s29; + float p3 = s3 + s28; + float p4 = s4 + s27; + float p5 = s5 + s26; + float p6 = s6 + s25; + float p7 = s7 + s24; + float p8 = s8 + s23; + float p9 = s9 + s22; + float p10 = s10 + s21; + float p11 = s11 + s20; + float p12 = s12 + s19; + float p13 = s13 + s18; + float p14 = s14 + s17; + float p15 = s15 + s16; + + float pp0 = p0 + p15; + float pp1 = p1 + p14; + float pp2 = p2 + p13; + float pp3 = p3 + p12; + float pp4 = p4 + p11; + float pp5 = p5 + p10; + float pp6 = p6 + p9; + float pp7 = p7 + p8; + float pp8 = (p0 - p15) * cos1_32; + float pp9 = (p1 - p14) * cos3_32; + float pp10 = (p2 - p13) * cos5_32; + float pp11 = (p3 - p12) * cos7_32; + float pp12 = (p4 - p11) * cos9_32; + float pp13 = (p5 - p10) * cos11_32; + float pp14 = (p6 - p9) * cos13_32; + float pp15 = (p7 - p8) * cos15_32; + + p0 = pp0 + pp7; + p1 = pp1 + pp6; + p2 = pp2 + pp5; + p3 = pp3 + pp4; + p4 = (pp0 - pp7) * cos1_16; + p5 = (pp1 - pp6) * cos3_16; + p6 = (pp2 - pp5) * cos5_16; + p7 = (pp3 - pp4) * cos7_16; + p8 = pp8 + pp15; + p9 = pp9 + pp14; + p10 = pp10 + pp13; + p11 = pp11 + pp12; + p12 = (pp8 - pp15) * cos1_16; + p13 = (pp9 - pp14) * cos3_16; + p14 = (pp10 - pp13) * cos5_16; + p15 = (pp11 - pp12) * cos7_16; + + + pp0 = p0 + p3; + pp1 = p1 + p2; + pp2 = (p0 - p3) * cos1_8; + pp3 = (p1 - p2) * cos3_8; + pp4 = p4 + p7; + pp5 = p5 + p6; + pp6 = (p4 - p7) * cos1_8; + pp7 = (p5 - p6) * cos3_8; + pp8 = p8 + p11; + pp9 = p9 + p10; + pp10 = (p8 - p11) * cos1_8; + pp11 = (p9 - p10) * cos3_8; + pp12 = p12 + p15; + pp13 = p13 + p14; + pp14 = (p12 - p15) * cos1_8; + pp15 = (p13 - p14) * cos3_8; + + p0 = pp0 + pp1; + p1 = (pp0 - pp1) * cos1_4; + p2 = pp2 + pp3; + p3 = (pp2 - pp3) * cos1_4; + p4 = pp4 + pp5; + p5 = (pp4 - pp5) * cos1_4; + p6 = pp6 + pp7; + p7 = (pp6 - pp7) * cos1_4; + p8 = pp8 + pp9; + p9 = (pp8 - pp9) * cos1_4; + p10 = pp10 + pp11; + p11 = (pp10 - pp11) * cos1_4; + p12 = pp12 + pp13; + p13 = (pp12 - pp13) * cos1_4; + p14 = pp14 + pp15; + p15 = (pp14 - pp15) * cos1_4; + + // this is pretty insane coding + float tmp1; + new_v19/*36-17*/ = -(new_v4 = (new_v12 = p7) + p5) - p6; + new_v27/*44-17*/ = -p6 - p7 - p4; + new_v6 = (new_v10 = (new_v14 = p15) + p11) + p13; + new_v17/*34-17*/ = -(new_v2 = p15 + p13 + p9) - p14; + new_v21/*38-17*/ = (tmp1 = -p14 - p15 - p10 - p11) - p13; + new_v29/*46-17*/ = -p14 - p15 - p12 - p8; + new_v25/*42-17*/ = tmp1 - p12; + new_v31/*48-17*/ = -p0; + new_v0 = p1; + new_v23/*40-17*/ = -(new_v8 = p3) - p2; + + p0 = (s0 - s31) * cos1_64; + p1 = (s1 - s30) * cos3_64; + p2 = (s2 - s29) * cos5_64; + p3 = (s3 - s28) * cos7_64; + p4 = (s4 - s27) * cos9_64; + p5 = (s5 - s26) * cos11_64; + p6 = (s6 - s25) * cos13_64; + p7 = (s7 - s24) * cos15_64; + p8 = (s8 - s23) * cos17_64; + p9 = (s9 - s22) * cos19_64; + p10 = (s10 - s21) * cos21_64; + p11 = (s11 - s20) * cos23_64; + p12 = (s12 - s19) * cos25_64; + p13 = (s13 - s18) * cos27_64; + p14 = (s14 - s17) * cos29_64; + p15 = (s15 - s16) * cos31_64; + + + pp0 = p0 + p15; + pp1 = p1 + p14; + pp2 = p2 + p13; + pp3 = p3 + p12; + pp4 = p4 + p11; + pp5 = p5 + p10; + pp6 = p6 + p9; + pp7 = p7 + p8; + pp8 = (p0 - p15) * cos1_32; + pp9 = (p1 - p14) * cos3_32; + pp10 = (p2 - p13) * cos5_32; + pp11 = (p3 - p12) * cos7_32; + pp12 = (p4 - p11) * cos9_32; + pp13 = (p5 - p10) * cos11_32; + pp14 = (p6 - p9) * cos13_32; + pp15 = (p7 - p8) * cos15_32; + + + p0 = pp0 + pp7; + p1 = pp1 + pp6; + p2 = pp2 + pp5; + p3 = pp3 + pp4; + p4 = (pp0 - pp7) * cos1_16; + p5 = (pp1 - pp6) * cos3_16; + p6 = (pp2 - pp5) * cos5_16; + p7 = (pp3 - pp4) * cos7_16; + p8 = pp8 + pp15; + p9 = pp9 + pp14; + p10 = pp10 + pp13; + p11 = pp11 + pp12; + p12 = (pp8 - pp15) * cos1_16; + p13 = (pp9 - pp14) * cos3_16; + p14 = (pp10 - pp13) * cos5_16; + p15 = (pp11 - pp12) * cos7_16; + + + pp0 = p0 + p3; + pp1 = p1 + p2; + pp2 = (p0 - p3) * cos1_8; + pp3 = (p1 - p2) * cos3_8; + pp4 = p4 + p7; + pp5 = p5 + p6; + pp6 = (p4 - p7) * cos1_8; + pp7 = (p5 - p6) * cos3_8; + pp8 = p8 + p11; + pp9 = p9 + p10; + pp10 = (p8 - p11) * cos1_8; + pp11 = (p9 - p10) * cos3_8; + pp12 = p12 + p15; + pp13 = p13 + p14; + pp14 = (p12 - p15) * cos1_8; + pp15 = (p13 - p14) * cos3_8; + + + p0 = pp0 + pp1; + p1 = (pp0 - pp1) * cos1_4; + p2 = pp2 + pp3; + p3 = (pp2 - pp3) * cos1_4; + p4 = pp4 + pp5; + p5 = (pp4 - pp5) * cos1_4; + p6 = pp6 + pp7; + p7 = (pp6 - pp7) * cos1_4; + p8 = pp8 + pp9; + p9 = (pp8 - pp9) * cos1_4; + p10 = pp10 + pp11; + p11 = (pp10 - pp11) * cos1_4; + p12 = pp12 + pp13; + p13 = (pp12 - pp13) * cos1_4; + p14 = pp14 + pp15; + p15 = (pp14 - pp15) * cos1_4; + + + // manually doing something that a compiler should handle sucks + // coding like this is hard to read + float tmp2; + new_v5 = (new_v11 = (new_v13 = (new_v15 = p15) + p7) + p11) + + p5 + p13; + new_v7 = (new_v9 = p15 + p11 + p3) + p13; + new_v16/*33-17*/ = -(new_v1 = (tmp1 = p13 + p15 + p9) + p1) - p14; + new_v18/*35-17*/ = -(new_v3 = tmp1 + p5 + p7) - p6 - p14; + + new_v22/*39-17*/ = (tmp1 = -p10 - p11 - p14 - p15) + - p13 - p2 - p3; + new_v20/*37-17*/ = tmp1 - p13 - p5 - p6 - p7; + new_v24/*41-17*/ = tmp1 - p12 - p2 - p3; + new_v26/*43-17*/ = tmp1 - p12 - (tmp2 = p4 + p6 + p7); + new_v30/*47-17*/ = (tmp1 = -p8 - p12 - p14 - p15) - p0; + new_v28/*45-17*/ = tmp1 - tmp2; + + // insert V[0-15] (== new_v[0-15]) into actual v: + // float[] x2 = actual_v + actual_write_pos; + float dest[] = actual_v; + + int pos = actual_write_pos; + + dest[0 + pos] = new_v0; + dest[16 + pos] = new_v1; + dest[32 + pos] = new_v2; + dest[48 + pos] = new_v3; + dest[64 + pos] = new_v4; + dest[80 + pos] = new_v5; + dest[96 + pos] = new_v6; + dest[112 + pos] = new_v7; + dest[128 + pos] = new_v8; + dest[144 + pos] = new_v9; + dest[160 + pos] = new_v10; + dest[176 + pos] = new_v11; + dest[192 + pos] = new_v12; + dest[208 + pos] = new_v13; + dest[224 + pos] = new_v14; + dest[240 + pos] = new_v15; + + // V[16] is always 0.0: + dest[256 + pos] = 0.0f; + + // insert V[17-31] (== -new_v[15-1]) into actual v: + dest[272 + pos] = -new_v15; + dest[288 + pos] = -new_v14; + dest[304 + pos] = -new_v13; + dest[320 + pos] = -new_v12; + dest[336 + pos] = -new_v11; + dest[352 + pos] = -new_v10; + dest[368 + pos] = -new_v9; + dest[384 + pos] = -new_v8; + dest[400 + pos] = -new_v7; + dest[416 + pos] = -new_v6; + dest[432 + pos] = -new_v5; + dest[448 + pos] = -new_v4; + dest[464 + pos] = -new_v3; + dest[480 + pos] = -new_v2; + dest[496 + pos] = -new_v1; + + // insert V[32] (== -new_v[0]) into other v: + dest = (actual_v==v1) ? v2 : v1; + + dest[0 + pos] = -new_v0; + // insert V[33-48] (== new_v[16-31]) into other v: + dest[16 + pos] = new_v16; + dest[32 + pos] = new_v17; + dest[48 + pos] = new_v18; + dest[64 + pos] = new_v19; + dest[80 + pos] = new_v20; + dest[96 + pos] = new_v21; + dest[112 + pos] = new_v22; + dest[128 + pos] = new_v23; + dest[144 + pos] = new_v24; + dest[160 + pos] = new_v25; + dest[176 + pos] = new_v26; + dest[192 + pos] = new_v27; + dest[208 + pos] = new_v28; + dest[224 + pos] = new_v29; + dest[240 + pos] = new_v30; + dest[256 + pos] = new_v31; + + // insert V[49-63] (== new_v[30-16]) into other v: + dest[272 + pos] = new_v30; + dest[288 + pos] = new_v29; + dest[304 + pos] = new_v28; + dest[320 + pos] = new_v27; + dest[336 + pos] = new_v26; + dest[352 + pos] = new_v25; + dest[368 + pos] = new_v24; + dest[384 + pos] = new_v23; + dest[400 + pos] = new_v22; + dest[416 + pos] = new_v21; + dest[432 + pos] = new_v20; + dest[448 + pos] = new_v19; + dest[464 + pos] = new_v18; + dest[480 + pos] = new_v17; + dest[496 + pos] = new_v16; +/* + } + else + { + v1[0 + actual_write_pos] = -new_v0; + // insert V[33-48] (== new_v[16-31]) into other v: + v1[16 + actual_write_pos] = new_v16; + v1[32 + actual_write_pos] = new_v17; + v1[48 + actual_write_pos] = new_v18; + v1[64 + actual_write_pos] = new_v19; + v1[80 + actual_write_pos] = new_v20; + v1[96 + actual_write_pos] = new_v21; + v1[112 + actual_write_pos] = new_v22; + v1[128 + actual_write_pos] = new_v23; + v1[144 + actual_write_pos] = new_v24; + v1[160 + actual_write_pos] = new_v25; + v1[176 + actual_write_pos] = new_v26; + v1[192 + actual_write_pos] = new_v27; + v1[208 + actual_write_pos] = new_v28; + v1[224 + actual_write_pos] = new_v29; + v1[240 + actual_write_pos] = new_v30; + v1[256 + actual_write_pos] = new_v31; + + // insert V[49-63] (== new_v[30-16]) into other v: + v1[272 + actual_write_pos] = new_v30; + v1[288 + actual_write_pos] = new_v29; + v1[304 + actual_write_pos] = new_v28; + v1[320 + actual_write_pos] = new_v27; + v1[336 + actual_write_pos] = new_v26; + v1[352 + actual_write_pos] = new_v25; + v1[368 + actual_write_pos] = new_v24; + v1[384 + actual_write_pos] = new_v23; + v1[400 + actual_write_pos] = new_v22; + v1[416 + actual_write_pos] = new_v21; + v1[432 + actual_write_pos] = new_v20; + v1[448 + actual_write_pos] = new_v19; + v1[464 + actual_write_pos] = new_v18; + v1[480 + actual_write_pos] = new_v17; + v1[496 + actual_write_pos] = new_v16; + } +*/ + } + + /** + * Compute new values via a fast cosine transform. + */ + private void compute_new_v_old() + { + // p is fully initialized from x1 + //float[] p = _p; + // pp is fully initialized from p + //float[] pp = _pp; + + //float[] new_v = _new_v; + + float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 + float[] p = new float[16]; + float[] pp = new float[16]; + + + for (int i=31; i>=0; i--) + { + new_v[i] = 0.0f; + } + +// float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3 +// float[] p = new float[16]; +// float[] pp = new float[16]; + + float[] x1 = samples; + + p[0] = x1[0] + x1[31]; + p[1] = x1[1] + x1[30]; + p[2] = x1[2] + x1[29]; + p[3] = x1[3] + x1[28]; + p[4] = x1[4] + x1[27]; + p[5] = x1[5] + x1[26]; + p[6] = x1[6] + x1[25]; + p[7] = x1[7] + x1[24]; + p[8] = x1[8] + x1[23]; + p[9] = x1[9] + x1[22]; + p[10] = x1[10] + x1[21]; + p[11] = x1[11] + x1[20]; + p[12] = x1[12] + x1[19]; + p[13] = x1[13] + x1[18]; + p[14] = x1[14] + x1[17]; + p[15] = x1[15] + x1[16]; + + pp[0] = p[0] + p[15]; + pp[1] = p[1] + p[14]; + pp[2] = p[2] + p[13]; + pp[3] = p[3] + p[12]; + pp[4] = p[4] + p[11]; + pp[5] = p[5] + p[10]; + pp[6] = p[6] + p[9]; + pp[7] = p[7] + p[8]; + pp[8] = (p[0] - p[15]) * cos1_32; + pp[9] = (p[1] - p[14]) * cos3_32; + pp[10] = (p[2] - p[13]) * cos5_32; + pp[11] = (p[3] - p[12]) * cos7_32; + pp[12] = (p[4] - p[11]) * cos9_32; + pp[13] = (p[5] - p[10]) * cos11_32; + pp[14] = (p[6] - p[9]) * cos13_32; + pp[15] = (p[7] - p[8]) * cos15_32; + + p[0] = pp[0] + pp[7]; + p[1] = pp[1] + pp[6]; + p[2] = pp[2] + pp[5]; + p[3] = pp[3] + pp[4]; + p[4] = (pp[0] - pp[7]) * cos1_16; + p[5] = (pp[1] - pp[6]) * cos3_16; + p[6] = (pp[2] - pp[5]) * cos5_16; + p[7] = (pp[3] - pp[4]) * cos7_16; + p[8] = pp[8] + pp[15]; + p[9] = pp[9] + pp[14]; + p[10] = pp[10] + pp[13]; + p[11] = pp[11] + pp[12]; + p[12] = (pp[8] - pp[15]) * cos1_16; + p[13] = (pp[9] - pp[14]) * cos3_16; + p[14] = (pp[10] - pp[13]) * cos5_16; + p[15] = (pp[11] - pp[12]) * cos7_16; + + + pp[0] = p[0] + p[3]; + pp[1] = p[1] + p[2]; + pp[2] = (p[0] - p[3]) * cos1_8; + pp[3] = (p[1] - p[2]) * cos3_8; + pp[4] = p[4] + p[7]; + pp[5] = p[5] + p[6]; + pp[6] = (p[4] - p[7]) * cos1_8; + pp[7] = (p[5] - p[6]) * cos3_8; + pp[8] = p[8] + p[11]; + pp[9] = p[9] + p[10]; + pp[10] = (p[8] - p[11]) * cos1_8; + pp[11] = (p[9] - p[10]) * cos3_8; + pp[12] = p[12] + p[15]; + pp[13] = p[13] + p[14]; + pp[14] = (p[12] - p[15]) * cos1_8; + pp[15] = (p[13] - p[14]) * cos3_8; + + p[0] = pp[0] + pp[1]; + p[1] = (pp[0] - pp[1]) * cos1_4; + p[2] = pp[2] + pp[3]; + p[3] = (pp[2] - pp[3]) * cos1_4; + p[4] = pp[4] + pp[5]; + p[5] = (pp[4] - pp[5]) * cos1_4; + p[6] = pp[6] + pp[7]; + p[7] = (pp[6] - pp[7]) * cos1_4; + p[8] = pp[8] + pp[9]; + p[9] = (pp[8] - pp[9]) * cos1_4; + p[10] = pp[10] + pp[11]; + p[11] = (pp[10] - pp[11]) * cos1_4; + p[12] = pp[12] + pp[13]; + p[13] = (pp[12] - pp[13]) * cos1_4; + p[14] = pp[14] + pp[15]; + p[15] = (pp[14] - pp[15]) * cos1_4; + + // this is pretty insane coding + float tmp1; + new_v[36-17] = -(new_v[4] = (new_v[12] = p[7]) + p[5]) - p[6]; + new_v[44-17] = -p[6] - p[7] - p[4]; + new_v[6] = (new_v[10] = (new_v[14] = p[15]) + p[11]) + p[13]; + new_v[34-17] = -(new_v[2] = p[15] + p[13] + p[9]) - p[14]; + new_v[38-17] = (tmp1 = -p[14] - p[15] - p[10] - p[11]) - p[13]; + new_v[46-17] = -p[14] - p[15] - p[12] - p[8]; + new_v[42-17] = tmp1 - p[12]; + new_v[48-17] = -p[0]; + new_v[0] = p[1]; + new_v[40-17] = -(new_v[8] = p[3]) - p[2]; + + p[0] = (x1[0] - x1[31]) * cos1_64; + p[1] = (x1[1] - x1[30]) * cos3_64; + p[2] = (x1[2] - x1[29]) * cos5_64; + p[3] = (x1[3] - x1[28]) * cos7_64; + p[4] = (x1[4] - x1[27]) * cos9_64; + p[5] = (x1[5] - x1[26]) * cos11_64; + p[6] = (x1[6] - x1[25]) * cos13_64; + p[7] = (x1[7] - x1[24]) * cos15_64; + p[8] = (x1[8] - x1[23]) * cos17_64; + p[9] = (x1[9] - x1[22]) * cos19_64; + p[10] = (x1[10] - x1[21]) * cos21_64; + p[11] = (x1[11] - x1[20]) * cos23_64; + p[12] = (x1[12] - x1[19]) * cos25_64; + p[13] = (x1[13] - x1[18]) * cos27_64; + p[14] = (x1[14] - x1[17]) * cos29_64; + p[15] = (x1[15] - x1[16]) * cos31_64; + + + pp[0] = p[0] + p[15]; + pp[1] = p[1] + p[14]; + pp[2] = p[2] + p[13]; + pp[3] = p[3] + p[12]; + pp[4] = p[4] + p[11]; + pp[5] = p[5] + p[10]; + pp[6] = p[6] + p[9]; + pp[7] = p[7] + p[8]; + pp[8] = (p[0] - p[15]) * cos1_32; + pp[9] = (p[1] - p[14]) * cos3_32; + pp[10] = (p[2] - p[13]) * cos5_32; + pp[11] = (p[3] - p[12]) * cos7_32; + pp[12] = (p[4] - p[11]) * cos9_32; + pp[13] = (p[5] - p[10]) * cos11_32; + pp[14] = (p[6] - p[9]) * cos13_32; + pp[15] = (p[7] - p[8]) * cos15_32; + + + p[0] = pp[0] + pp[7]; + p[1] = pp[1] + pp[6]; + p[2] = pp[2] + pp[5]; + p[3] = pp[3] + pp[4]; + p[4] = (pp[0] - pp[7]) * cos1_16; + p[5] = (pp[1] - pp[6]) * cos3_16; + p[6] = (pp[2] - pp[5]) * cos5_16; + p[7] = (pp[3] - pp[4]) * cos7_16; + p[8] = pp[8] + pp[15]; + p[9] = pp[9] + pp[14]; + p[10] = pp[10] + pp[13]; + p[11] = pp[11] + pp[12]; + p[12] = (pp[8] - pp[15]) * cos1_16; + p[13] = (pp[9] - pp[14]) * cos3_16; + p[14] = (pp[10] - pp[13]) * cos5_16; + p[15] = (pp[11] - pp[12]) * cos7_16; + + + pp[0] = p[0] + p[3]; + pp[1] = p[1] + p[2]; + pp[2] = (p[0] - p[3]) * cos1_8; + pp[3] = (p[1] - p[2]) * cos3_8; + pp[4] = p[4] + p[7]; + pp[5] = p[5] + p[6]; + pp[6] = (p[4] - p[7]) * cos1_8; + pp[7] = (p[5] - p[6]) * cos3_8; + pp[8] = p[8] + p[11]; + pp[9] = p[9] + p[10]; + pp[10] = (p[8] - p[11]) * cos1_8; + pp[11] = (p[9] - p[10]) * cos3_8; + pp[12] = p[12] + p[15]; + pp[13] = p[13] + p[14]; + pp[14] = (p[12] - p[15]) * cos1_8; + pp[15] = (p[13] - p[14]) * cos3_8; + + + p[0] = pp[0] + pp[1]; + p[1] = (pp[0] - pp[1]) * cos1_4; + p[2] = pp[2] + pp[3]; + p[3] = (pp[2] - pp[3]) * cos1_4; + p[4] = pp[4] + pp[5]; + p[5] = (pp[4] - pp[5]) * cos1_4; + p[6] = pp[6] + pp[7]; + p[7] = (pp[6] - pp[7]) * cos1_4; + p[8] = pp[8] + pp[9]; + p[9] = (pp[8] - pp[9]) * cos1_4; + p[10] = pp[10] + pp[11]; + p[11] = (pp[10] - pp[11]) * cos1_4; + p[12] = pp[12] + pp[13]; + p[13] = (pp[12] - pp[13]) * cos1_4; + p[14] = pp[14] + pp[15]; + p[15] = (pp[14] - pp[15]) * cos1_4; + + + // manually doing something that a compiler should handle sucks + // coding like this is hard to read + float tmp2; + new_v[5] = (new_v[11] = (new_v[13] = (new_v[15] = p[15]) + p[7]) + p[11]) + + p[5] + p[13]; + new_v[7] = (new_v[9] = p[15] + p[11] + p[3]) + p[13]; + new_v[33-17] = -(new_v[1] = (tmp1 = p[13] + p[15] + p[9]) + p[1]) - p[14]; + new_v[35-17] = -(new_v[3] = tmp1 + p[5] + p[7]) - p[6] - p[14]; + + new_v[39-17] = (tmp1 = -p[10] - p[11] - p[14] - p[15]) + - p[13] - p[2] - p[3]; + new_v[37-17] = tmp1 - p[13] - p[5] - p[6] - p[7]; + new_v[41-17] = tmp1 - p[12] - p[2] - p[3]; + new_v[43-17] = tmp1 - p[12] - (tmp2 = p[4] + p[6] + p[7]); + new_v[47-17] = (tmp1 = -p[8] - p[12] - p[14] - p[15]) - p[0]; + new_v[45-17] = tmp1 - tmp2; + + // insert V[0-15] (== new_v[0-15]) into actual v: + x1 = new_v; + // float[] x2 = actual_v + actual_write_pos; + float[] dest = actual_v; + + dest[0 + actual_write_pos] = x1[0]; + dest[16 + actual_write_pos] = x1[1]; + dest[32 + actual_write_pos] = x1[2]; + dest[48 + actual_write_pos] = x1[3]; + dest[64 + actual_write_pos] = x1[4]; + dest[80 + actual_write_pos] = x1[5]; + dest[96 + actual_write_pos] = x1[6]; + dest[112 + actual_write_pos] = x1[7]; + dest[128 + actual_write_pos] = x1[8]; + dest[144 + actual_write_pos] = x1[9]; + dest[160 + actual_write_pos] = x1[10]; + dest[176 + actual_write_pos] = x1[11]; + dest[192 + actual_write_pos] = x1[12]; + dest[208 + actual_write_pos] = x1[13]; + dest[224 + actual_write_pos] = x1[14]; + dest[240 + actual_write_pos] = x1[15]; + + // V[16] is always 0.0: + dest[256 + actual_write_pos] = 0.0f; + + // insert V[17-31] (== -new_v[15-1]) into actual v: + dest[272 + actual_write_pos] = -x1[15]; + dest[288 + actual_write_pos] = -x1[14]; + dest[304 + actual_write_pos] = -x1[13]; + dest[320 + actual_write_pos] = -x1[12]; + dest[336 + actual_write_pos] = -x1[11]; + dest[352 + actual_write_pos] = -x1[10]; + dest[368 + actual_write_pos] = -x1[9]; + dest[384 + actual_write_pos] = -x1[8]; + dest[400 + actual_write_pos] = -x1[7]; + dest[416 + actual_write_pos] = -x1[6]; + dest[432 + actual_write_pos] = -x1[5]; + dest[448 + actual_write_pos] = -x1[4]; + dest[464 + actual_write_pos] = -x1[3]; + dest[480 + actual_write_pos] = -x1[2]; + dest[496 + actual_write_pos] = -x1[1]; + + // insert V[32] (== -new_v[0]) into other v: + + } + + /** + * Compute PCM Samples. + */ + + private float[] _tmpOut = new float[32]; + + + private void compute_pcm_samples0(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + float pcm_sample; + final float[] dp = d16[i]; + pcm_sample = (float)(((vp[0 + dvp] * dp[0]) + + (vp[15 + dvp] * dp[1]) + + (vp[14 + dvp] * dp[2]) + + (vp[13 + dvp] * dp[3]) + + (vp[12 + dvp] * dp[4]) + + (vp[11 + dvp] * dp[5]) + + (vp[10 + dvp] * dp[6]) + + (vp[9 + dvp] * dp[7]) + + (vp[8 + dvp] * dp[8]) + + (vp[7 + dvp] * dp[9]) + + (vp[6 + dvp] * dp[10]) + + (vp[5 + dvp] * dp[11]) + + (vp[4 + dvp] * dp[12]) + + (vp[3 + dvp] * dp[13]) + + (vp[2 + dvp] * dp[14]) + + (vp[1 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples1(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[1 + dvp] * dp[0]) + + (vp[0 + dvp] * dp[1]) + + (vp[15 + dvp] * dp[2]) + + (vp[14 + dvp] * dp[3]) + + (vp[13 + dvp] * dp[4]) + + (vp[12 + dvp] * dp[5]) + + (vp[11 + dvp] * dp[6]) + + (vp[10 + dvp] * dp[7]) + + (vp[9 + dvp] * dp[8]) + + (vp[8 + dvp] * dp[9]) + + (vp[7 + dvp] * dp[10]) + + (vp[6 + dvp] * dp[11]) + + (vp[5 + dvp] * dp[12]) + + (vp[4 + dvp] * dp[13]) + + (vp[3 + dvp] * dp[14]) + + (vp[2 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples2(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[2 + dvp] * dp[0]) + + (vp[1 + dvp] * dp[1]) + + (vp[0 + dvp] * dp[2]) + + (vp[15 + dvp] * dp[3]) + + (vp[14 + dvp] * dp[4]) + + (vp[13 + dvp] * dp[5]) + + (vp[12 + dvp] * dp[6]) + + (vp[11 + dvp] * dp[7]) + + (vp[10 + dvp] * dp[8]) + + (vp[9 + dvp] * dp[9]) + + (vp[8 + dvp] * dp[10]) + + (vp[7 + dvp] * dp[11]) + + (vp[6 + dvp] * dp[12]) + + (vp[5 + dvp] * dp[13]) + + (vp[4 + dvp] * dp[14]) + + (vp[3 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples3(Obuffer buffer) + { + final float[] vp = actual_v; + + int idx = 0; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[3 + dvp] * dp[0]) + + (vp[2 + dvp] * dp[1]) + + (vp[1 + dvp] * dp[2]) + + (vp[0 + dvp] * dp[3]) + + (vp[15 + dvp] * dp[4]) + + (vp[14 + dvp] * dp[5]) + + (vp[13 + dvp] * dp[6]) + + (vp[12 + dvp] * dp[7]) + + (vp[11 + dvp] * dp[8]) + + (vp[10 + dvp] * dp[9]) + + (vp[9 + dvp] * dp[10]) + + (vp[8 + dvp] * dp[11]) + + (vp[7 + dvp] * dp[12]) + + (vp[6 + dvp] * dp[13]) + + (vp[5 + dvp] * dp[14]) + + (vp[4 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples4(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[4 + dvp] * dp[0]) + + (vp[3 + dvp] * dp[1]) + + (vp[2 + dvp] * dp[2]) + + (vp[1 + dvp] * dp[3]) + + (vp[0 + dvp] * dp[4]) + + (vp[15 + dvp] * dp[5]) + + (vp[14 + dvp] * dp[6]) + + (vp[13 + dvp] * dp[7]) + + (vp[12 + dvp] * dp[8]) + + (vp[11 + dvp] * dp[9]) + + (vp[10 + dvp] * dp[10]) + + (vp[9 + dvp] * dp[11]) + + (vp[8 + dvp] * dp[12]) + + (vp[7 + dvp] * dp[13]) + + (vp[6 + dvp] * dp[14]) + + (vp[5 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples5(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[5 + dvp] * dp[0]) + + (vp[4 + dvp] * dp[1]) + + (vp[3 + dvp] * dp[2]) + + (vp[2 + dvp] * dp[3]) + + (vp[1 + dvp] * dp[4]) + + (vp[0 + dvp] * dp[5]) + + (vp[15 + dvp] * dp[6]) + + (vp[14 + dvp] * dp[7]) + + (vp[13 + dvp] * dp[8]) + + (vp[12 + dvp] * dp[9]) + + (vp[11 + dvp] * dp[10]) + + (vp[10 + dvp] * dp[11]) + + (vp[9 + dvp] * dp[12]) + + (vp[8 + dvp] * dp[13]) + + (vp[7 + dvp] * dp[14]) + + (vp[6 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples6(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[6 + dvp] * dp[0]) + + (vp[5 + dvp] * dp[1]) + + (vp[4 + dvp] * dp[2]) + + (vp[3 + dvp] * dp[3]) + + (vp[2 + dvp] * dp[4]) + + (vp[1 + dvp] * dp[5]) + + (vp[0 + dvp] * dp[6]) + + (vp[15 + dvp] * dp[7]) + + (vp[14 + dvp] * dp[8]) + + (vp[13 + dvp] * dp[9]) + + (vp[12 + dvp] * dp[10]) + + (vp[11 + dvp] * dp[11]) + + (vp[10 + dvp] * dp[12]) + + (vp[9 + dvp] * dp[13]) + + (vp[8 + dvp] * dp[14]) + + (vp[7 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples7(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[7 + dvp] * dp[0]) + + (vp[6 + dvp] * dp[1]) + + (vp[5 + dvp] * dp[2]) + + (vp[4 + dvp] * dp[3]) + + (vp[3 + dvp] * dp[4]) + + (vp[2 + dvp] * dp[5]) + + (vp[1 + dvp] * dp[6]) + + (vp[0 + dvp] * dp[7]) + + (vp[15 + dvp] * dp[8]) + + (vp[14 + dvp] * dp[9]) + + (vp[13 + dvp] * dp[10]) + + (vp[12 + dvp] * dp[11]) + + (vp[11 + dvp] * dp[12]) + + (vp[10 + dvp] * dp[13]) + + (vp[9 + dvp] * dp[14]) + + (vp[8 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples8(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[8 + dvp] * dp[0]) + + (vp[7 + dvp] * dp[1]) + + (vp[6 + dvp] * dp[2]) + + (vp[5 + dvp] * dp[3]) + + (vp[4 + dvp] * dp[4]) + + (vp[3 + dvp] * dp[5]) + + (vp[2 + dvp] * dp[6]) + + (vp[1 + dvp] * dp[7]) + + (vp[0 + dvp] * dp[8]) + + (vp[15 + dvp] * dp[9]) + + (vp[14 + dvp] * dp[10]) + + (vp[13 + dvp] * dp[11]) + + (vp[12 + dvp] * dp[12]) + + (vp[11 + dvp] * dp[13]) + + (vp[10 + dvp] * dp[14]) + + (vp[9 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples9(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[9 + dvp] * dp[0]) + + (vp[8 + dvp] * dp[1]) + + (vp[7 + dvp] * dp[2]) + + (vp[6 + dvp] * dp[3]) + + (vp[5 + dvp] * dp[4]) + + (vp[4 + dvp] * dp[5]) + + (vp[3 + dvp] * dp[6]) + + (vp[2 + dvp] * dp[7]) + + (vp[1 + dvp] * dp[8]) + + (vp[0 + dvp] * dp[9]) + + (vp[15 + dvp] * dp[10]) + + (vp[14 + dvp] * dp[11]) + + (vp[13 + dvp] * dp[12]) + + (vp[12 + dvp] * dp[13]) + + (vp[11 + dvp] * dp[14]) + + (vp[10 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + + private void compute_pcm_samples10(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[10 + dvp] * dp[0]) + + (vp[9 + dvp] * dp[1]) + + (vp[8 + dvp] * dp[2]) + + (vp[7 + dvp] * dp[3]) + + (vp[6 + dvp] * dp[4]) + + (vp[5 + dvp] * dp[5]) + + (vp[4 + dvp] * dp[6]) + + (vp[3 + dvp] * dp[7]) + + (vp[2 + dvp] * dp[8]) + + (vp[1 + dvp] * dp[9]) + + (vp[0 + dvp] * dp[10]) + + (vp[15 + dvp] * dp[11]) + + (vp[14 + dvp] * dp[12]) + + (vp[13 + dvp] * dp[13]) + + (vp[12 + dvp] * dp[14]) + + (vp[11 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples11(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[11 + dvp] * dp[0]) + + (vp[10 + dvp] * dp[1]) + + (vp[9 + dvp] * dp[2]) + + (vp[8 + dvp] * dp[3]) + + (vp[7 + dvp] * dp[4]) + + (vp[6 + dvp] * dp[5]) + + (vp[5 + dvp] * dp[6]) + + (vp[4 + dvp] * dp[7]) + + (vp[3 + dvp] * dp[8]) + + (vp[2 + dvp] * dp[9]) + + (vp[1 + dvp] * dp[10]) + + (vp[0 + dvp] * dp[11]) + + (vp[15 + dvp] * dp[12]) + + (vp[14 + dvp] * dp[13]) + + (vp[13 + dvp] * dp[14]) + + (vp[12 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples12(Obuffer buffer) + { + final float[] vp = actual_v; + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[12 + dvp] * dp[0]) + + (vp[11 + dvp] * dp[1]) + + (vp[10 + dvp] * dp[2]) + + (vp[9 + dvp] * dp[3]) + + (vp[8 + dvp] * dp[4]) + + (vp[7 + dvp] * dp[5]) + + (vp[6 + dvp] * dp[6]) + + (vp[5 + dvp] * dp[7]) + + (vp[4 + dvp] * dp[8]) + + (vp[3 + dvp] * dp[9]) + + (vp[2 + dvp] * dp[10]) + + (vp[1 + dvp] * dp[11]) + + (vp[0 + dvp] * dp[12]) + + (vp[15 + dvp] * dp[13]) + + (vp[14 + dvp] * dp[14]) + + (vp[13 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples13(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[13 + dvp] * dp[0]) + + (vp[12 + dvp] * dp[1]) + + (vp[11 + dvp] * dp[2]) + + (vp[10 + dvp] * dp[3]) + + (vp[9 + dvp] * dp[4]) + + (vp[8 + dvp] * dp[5]) + + (vp[7 + dvp] * dp[6]) + + (vp[6 + dvp] * dp[7]) + + (vp[5 + dvp] * dp[8]) + + (vp[4 + dvp] * dp[9]) + + (vp[3 + dvp] * dp[10]) + + (vp[2 + dvp] * dp[11]) + + (vp[1 + dvp] * dp[12]) + + (vp[0 + dvp] * dp[13]) + + (vp[15 + dvp] * dp[14]) + + (vp[14 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples14(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + final float[] dp = d16[i]; + float pcm_sample; + + pcm_sample = (float)(((vp[14 + dvp] * dp[0]) + + (vp[13 + dvp] * dp[1]) + + (vp[12 + dvp] * dp[2]) + + (vp[11 + dvp] * dp[3]) + + (vp[10 + dvp] * dp[4]) + + (vp[9 + dvp] * dp[5]) + + (vp[8 + dvp] * dp[6]) + + (vp[7 + dvp] * dp[7]) + + (vp[6 + dvp] * dp[8]) + + (vp[5 + dvp] * dp[9]) + + (vp[4 + dvp] * dp[10]) + + (vp[3 + dvp] * dp[11]) + + (vp[2 + dvp] * dp[12]) + + (vp[1 + dvp] * dp[13]) + + (vp[0 + dvp] * dp[14]) + + (vp[15 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + + dvp += 16; + } // for + } + private void compute_pcm_samples15(Obuffer buffer) + { + final float[] vp = actual_v; + + //int inc = v_inc; + final float[] tmpOut = _tmpOut; + int dvp =0; + + // fat chance of having this loop unroll + for( int i=0; i<32; i++) + { + float pcm_sample; + final float dp[] = d16[i]; + pcm_sample = (float)(((vp[15 + dvp] * dp[0]) + + (vp[14 + dvp] * dp[1]) + + (vp[13 + dvp] * dp[2]) + + (vp[12 + dvp] * dp[3]) + + (vp[11 + dvp] * dp[4]) + + (vp[10 + dvp] * dp[5]) + + (vp[9 + dvp] * dp[6]) + + (vp[8 + dvp] * dp[7]) + + (vp[7 + dvp] * dp[8]) + + (vp[6 + dvp] * dp[9]) + + (vp[5 + dvp] * dp[10]) + + (vp[4 + dvp] * dp[11]) + + (vp[3 + dvp] * dp[12]) + + (vp[2 + dvp] * dp[13]) + + (vp[1 + dvp] * dp[14]) + + (vp[0 + dvp] * dp[15]) + ) * scalefactor); + + tmpOut[i] = pcm_sample; + dvp += 16; + } // for + } + +private void compute_pcm_samples(Obuffer buffer) +{ + + switch (actual_write_pos) + { + case 0: + compute_pcm_samples0(buffer); + break; + case 1: + compute_pcm_samples1(buffer); + break; + case 2: + compute_pcm_samples2(buffer); + break; + case 3: + compute_pcm_samples3(buffer); + break; + case 4: + compute_pcm_samples4(buffer); + break; + case 5: + compute_pcm_samples5(buffer); + break; + case 6: + compute_pcm_samples6(buffer); + break; + case 7: + compute_pcm_samples7(buffer); + break; + case 8: + compute_pcm_samples8(buffer); + break; + case 9: + compute_pcm_samples9(buffer); + break; + case 10: + compute_pcm_samples10(buffer); + break; + case 11: + compute_pcm_samples11(buffer); + break; + case 12: + compute_pcm_samples12(buffer); + break; + case 13: + compute_pcm_samples13(buffer); + break; + case 14: + compute_pcm_samples14(buffer); + break; + case 15: + compute_pcm_samples15(buffer); + break; + } + + if (buffer!=null) + { + buffer.appendSamples(channel, _tmpOut); + } + +/* + // MDM: I was considering putting in quality control for + // low-spec CPUs, but the performance gain (about 10-15%) + // did not justify the considerable drop in audio quality. + switch (inc) + { + case 16: + buffer.appendSamples(channel, tmpOut); + break; + case 32: + for (int i=0; i<16; i++) + { + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + } + break; + case 64: + for (int i=0; i<8; i++) + { + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + buffer.append(channel, (short)tmpOut[i]); + } + break; + + } +*/ + } + + /** + * Calculate 32 PCM samples and put the into the Obuffer-object. + */ + + public void calculate_pcm_samples(Obuffer buffer) + { + compute_new_v(); + compute_pcm_samples(buffer); + + actual_write_pos = (actual_write_pos + 1) & 0xf; + actual_v = (actual_v == v1) ? v2 : v1; + + // initialize samples[]: + //for (register float *floatp = samples + 32; floatp > samples; ) + // *--floatp = 0.0f; + + // MDM: this may not be necessary. The Layer III decoder always + // outputs 32 subband samples, but I haven't checked layer I & II. + for (int p=0;p<32;p++) + samples[p] = 0.0f; + } + + + private static final double MY_PI = 3.14159265358979323846; + private static final float cos1_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 64.0))); + private static final float cos3_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 64.0))); + private static final float cos5_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 64.0))); + private static final float cos7_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 64.0))); + private static final float cos9_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 64.0))); + private static final float cos11_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 64.0))); + private static final float cos13_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 64.0))); + private static final float cos15_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 64.0))); + private static final float cos17_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 17.0 / 64.0))); + private static final float cos19_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 19.0 / 64.0))); + private static final float cos21_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 21.0 / 64.0))); + private static final float cos23_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 23.0 / 64.0))); + private static final float cos25_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 25.0 / 64.0))); + private static final float cos27_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 27.0 / 64.0))); + private static final float cos29_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 29.0 / 64.0))); + private static final float cos31_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 31.0 / 64.0))); + private static final float cos1_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 32.0))); + private static final float cos3_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 32.0))); + private static final float cos5_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 32.0))); + private static final float cos7_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 32.0))); + private static final float cos9_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 32.0))); + private static final float cos11_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 32.0))); + private static final float cos13_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 32.0))); + private static final float cos15_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 32.0))); + private static final float cos1_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 16.0))); + private static final float cos3_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 16.0))); + private static final float cos5_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 16.0))); + private static final float cos7_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 16.0))); + private static final float cos1_8 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 8.0))); + private static final float cos3_8 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 8.0))); + private static final float cos1_4 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 4.0))); + + // Note: These values are not in the same order + // as in Annex 3-B.3 of the ISO/IEC DIS 11172-3 + // private float d[] = {0.000000000, -4.000442505}; + + private static float d[] = null; + + /** + * d[] split into subarrays of length 16. This provides for + * more faster access by allowing a block of 16 to be addressed + * with constant offset. + **/ + private static float d16[][] = null; + + /** + * Loads the data for the d[] from the resource SFd.ser. + * @return the loaded values for d[]. + */ + static private float[] load_d() + { + try + { + Class elemType = Float.TYPE; + Object o = JavaLayerUtils.deserializeArrayResource("sfd.ser", elemType, 512); + return (float[])o; + } + catch (IOException ex) + { + throw new ExceptionInInitializerError(ex); + } + } + + /** + * Converts a 1D array into a number of smaller arrays. This is used + * to achieve offset + constant indexing into an array. Each sub-array + * represents a block of values of the original array. + * @param array The array to split up into blocks. + * @param blockSize The size of the blocks to split the array + * into. This must be an exact divisor of + * the length of the array, or some data + * will be lost from the main array. + * + * @return An array of arrays in which each element in the returned + * array will be of length blockSize. + */ + static private float[][] splitArray(final float[] array, final int blockSize) + { + int size = array.length / blockSize; + float[][] split = new float[size][]; + for (int i=0; i array.length) + { + len = array.length-offs; + } + + if (len < 0) + len = 0; + + float[] subarray = new float[len]; + System.arraycopy(array, offs + 0, subarray, 0, len); + + return subarray; + } + + // The original data for d[]. This data is loaded from a file + // to reduce the overall package size and to improve performance. +/* + static final float d_data[] = { + 0.000000000f, -0.000442505f, 0.003250122f, -0.007003784f, + 0.031082153f, -0.078628540f, 0.100311279f, -0.572036743f, + 1.144989014f, 0.572036743f, 0.100311279f, 0.078628540f, + 0.031082153f, 0.007003784f, 0.003250122f, 0.000442505f, + -0.000015259f, -0.000473022f, 0.003326416f, -0.007919312f, + 0.030517578f, -0.084182739f, 0.090927124f, -0.600219727f, + 1.144287109f, 0.543823242f, 0.108856201f, 0.073059082f, + 0.031478882f, 0.006118774f, 0.003173828f, 0.000396729f, + -0.000015259f, -0.000534058f, 0.003387451f, -0.008865356f, + 0.029785156f, -0.089706421f, 0.080688477f, -0.628295898f, + 1.142211914f, 0.515609741f, 0.116577148f, 0.067520142f, + 0.031738281f, 0.005294800f, 0.003082275f, 0.000366211f, + -0.000015259f, -0.000579834f, 0.003433228f, -0.009841919f, + 0.028884888f, -0.095169067f, 0.069595337f, -0.656219482f, + 1.138763428f, 0.487472534f, 0.123474121f, 0.061996460f, + 0.031845093f, 0.004486084f, 0.002990723f, 0.000320435f, + -0.000015259f, -0.000625610f, 0.003463745f, -0.010848999f, + 0.027801514f, -0.100540161f, 0.057617188f, -0.683914185f, + 1.133926392f, 0.459472656f, 0.129577637f, 0.056533813f, + 0.031814575f, 0.003723145f, 0.002899170f, 0.000289917f, + -0.000015259f, -0.000686646f, 0.003479004f, -0.011886597f, + 0.026535034f, -0.105819702f, 0.044784546f, -0.711318970f, + 1.127746582f, 0.431655884f, 0.134887695f, 0.051132202f, + 0.031661987f, 0.003005981f, 0.002792358f, 0.000259399f, + -0.000015259f, -0.000747681f, 0.003479004f, -0.012939453f, + 0.025085449f, -0.110946655f, 0.031082153f, -0.738372803f, + 1.120223999f, 0.404083252f, 0.139450073f, 0.045837402f, + 0.031387329f, 0.002334595f, 0.002685547f, 0.000244141f, + -0.000030518f, -0.000808716f, 0.003463745f, -0.014022827f, + 0.023422241f, -0.115921021f, 0.016510010f, -0.765029907f, + 1.111373901f, 0.376800537f, 0.143264771f, 0.040634155f, + 0.031005859f, 0.001693726f, 0.002578735f, 0.000213623f, + -0.000030518f, -0.000885010f, 0.003417969f, -0.015121460f, + 0.021575928f, -0.120697021f, 0.001068115f, -0.791213989f, + 1.101211548f, 0.349868774f, 0.146362305f, 0.035552979f, + 0.030532837f, 0.001098633f, 0.002456665f, 0.000198364f, + -0.000030518f, -0.000961304f, 0.003372192f, -0.016235352f, + 0.019531250f, -0.125259399f, -0.015228271f, -0.816864014f, + 1.089782715f, 0.323318481f, 0.148773193f, 0.030609131f, + 0.029937744f, 0.000549316f, 0.002349854f, 0.000167847f, + -0.000030518f, -0.001037598f, 0.003280640f, -0.017349243f, + 0.017257690f, -0.129562378f, -0.032379150f, -0.841949463f, + 1.077117920f, 0.297210693f, 0.150497437f, 0.025817871f, + 0.029281616f, 0.000030518f, 0.002243042f, 0.000152588f, + -0.000045776f, -0.001113892f, 0.003173828f, -0.018463135f, + 0.014801025f, -0.133590698f, -0.050354004f, -0.866363525f, + 1.063217163f, 0.271591187f, 0.151596069f, 0.021179199f, + 0.028533936f, -0.000442505f, 0.002120972f, 0.000137329f, + -0.000045776f, -0.001205444f, 0.003051758f, -0.019577026f, + 0.012115479f, -0.137298584f, -0.069168091f, -0.890090942f, + 1.048156738f, 0.246505737f, 0.152069092f, 0.016708374f, + 0.027725220f, -0.000869751f, 0.002014160f, 0.000122070f, + -0.000061035f, -0.001296997f, 0.002883911f, -0.020690918f, + 0.009231567f, -0.140670776f, -0.088775635f, -0.913055420f, + 1.031936646f, 0.221984863f, 0.151962280f, 0.012420654f, + 0.026840210f, -0.001266479f, 0.001907349f, 0.000106812f, + -0.000061035f, -0.001388550f, 0.002700806f, -0.021789551f, + 0.006134033f, -0.143676758f, -0.109161377f, -0.935195923f, + 1.014617920f, 0.198059082f, 0.151306152f, 0.008316040f, + 0.025909424f, -0.001617432f, 0.001785278f, 0.000106812f, + -0.000076294f, -0.001480103f, 0.002487183f, -0.022857666f, + 0.002822876f, -0.146255493f, -0.130310059f, -0.956481934f, + 0.996246338f, 0.174789429f, 0.150115967f, 0.004394531f, + 0.024932861f, -0.001937866f, 0.001693726f, 0.000091553f, + -0.000076294f, -0.001586914f, 0.002227783f, -0.023910522f, + -0.000686646f, -0.148422241f, -0.152206421f, -0.976852417f, + 0.976852417f, 0.152206421f, 0.148422241f, 0.000686646f, + 0.023910522f, -0.002227783f, 0.001586914f, 0.000076294f, + -0.000091553f, -0.001693726f, 0.001937866f, -0.024932861f, + -0.004394531f, -0.150115967f, -0.174789429f, -0.996246338f, + 0.956481934f, 0.130310059f, 0.146255493f, -0.002822876f, + 0.022857666f, -0.002487183f, 0.001480103f, 0.000076294f, + -0.000106812f, -0.001785278f, 0.001617432f, -0.025909424f, + -0.008316040f, -0.151306152f, -0.198059082f, -1.014617920f, + 0.935195923f, 0.109161377f, 0.143676758f, -0.006134033f, + 0.021789551f, -0.002700806f, 0.001388550f, 0.000061035f, + -0.000106812f, -0.001907349f, 0.001266479f, -0.026840210f, + -0.012420654f, -0.151962280f, -0.221984863f, -1.031936646f, + 0.913055420f, 0.088775635f, 0.140670776f, -0.009231567f, + 0.020690918f, -0.002883911f, 0.001296997f, 0.000061035f, + -0.000122070f, -0.002014160f, 0.000869751f, -0.027725220f, + -0.016708374f, -0.152069092f, -0.246505737f, -1.048156738f, + 0.890090942f, 0.069168091f, 0.137298584f, -0.012115479f, + 0.019577026f, -0.003051758f, 0.001205444f, 0.000045776f, + -0.000137329f, -0.002120972f, 0.000442505f, -0.028533936f, + -0.021179199f, -0.151596069f, -0.271591187f, -1.063217163f, + 0.866363525f, 0.050354004f, 0.133590698f, -0.014801025f, + 0.018463135f, -0.003173828f, 0.001113892f, 0.000045776f, + -0.000152588f, -0.002243042f, -0.000030518f, -0.029281616f, + -0.025817871f, -0.150497437f, -0.297210693f, -1.077117920f, + 0.841949463f, 0.032379150f, 0.129562378f, -0.017257690f, + 0.017349243f, -0.003280640f, 0.001037598f, 0.000030518f, + -0.000167847f, -0.002349854f, -0.000549316f, -0.029937744f, + -0.030609131f, -0.148773193f, -0.323318481f, -1.089782715f, + 0.816864014f, 0.015228271f, 0.125259399f, -0.019531250f, + 0.016235352f, -0.003372192f, 0.000961304f, 0.000030518f, + -0.000198364f, -0.002456665f, -0.001098633f, -0.030532837f, + -0.035552979f, -0.146362305f, -0.349868774f, -1.101211548f, + 0.791213989f, -0.001068115f, 0.120697021f, -0.021575928f, + 0.015121460f, -0.003417969f, 0.000885010f, 0.000030518f, + -0.000213623f, -0.002578735f, -0.001693726f, -0.031005859f, + -0.040634155f, -0.143264771f, -0.376800537f, -1.111373901f, + 0.765029907f, -0.016510010f, 0.115921021f, -0.023422241f, + 0.014022827f, -0.003463745f, 0.000808716f, 0.000030518f, + -0.000244141f, -0.002685547f, -0.002334595f, -0.031387329f, + -0.045837402f, -0.139450073f, -0.404083252f, -1.120223999f, + 0.738372803f, -0.031082153f, 0.110946655f, -0.025085449f, + 0.012939453f, -0.003479004f, 0.000747681f, 0.000015259f, + -0.000259399f, -0.002792358f, -0.003005981f, -0.031661987f, + -0.051132202f, -0.134887695f, -0.431655884f, -1.127746582f, + 0.711318970f, -0.044784546f, 0.105819702f, -0.026535034f, + 0.011886597f, -0.003479004f, 0.000686646f, 0.000015259f, + -0.000289917f, -0.002899170f, -0.003723145f, -0.031814575f, + -0.056533813f, -0.129577637f, -0.459472656f, -1.133926392f, + 0.683914185f, -0.057617188f, 0.100540161f, -0.027801514f, + 0.010848999f, -0.003463745f, 0.000625610f, 0.000015259f, + -0.000320435f, -0.002990723f, -0.004486084f, -0.031845093f, + -0.061996460f, -0.123474121f, -0.487472534f, -1.138763428f, + 0.656219482f, -0.069595337f, 0.095169067f, -0.028884888f, + 0.009841919f, -0.003433228f, 0.000579834f, 0.000015259f, + -0.000366211f, -0.003082275f, -0.005294800f, -0.031738281f, + -0.067520142f, -0.116577148f, -0.515609741f, -1.142211914f, + 0.628295898f, -0.080688477f, 0.089706421f, -0.029785156f, + 0.008865356f, -0.003387451f, 0.000534058f, 0.000015259f, + -0.000396729f, -0.003173828f, -0.006118774f, -0.031478882f, + -0.073059082f, -0.108856201f, -0.543823242f, -1.144287109f, + 0.600219727f, -0.090927124f, 0.084182739f, -0.030517578f, + 0.007919312f, -0.003326416f, 0.000473022f, 0.000015259f + }; + */ + +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/au2lin.ser b/src/lwjgl/java/javazoom/jl/decoder/au2lin.ser new file mode 100644 index 0000000..0b20bc8 Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/au2lin.ser differ diff --git a/src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java b/src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java new file mode 100644 index 0000000..3d80f17 --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java @@ -0,0 +1,600 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 16/11/99 Renamed class, added javadoc, and changed table + * name from String to 3 chars. mdm@techie.com + * 02/15/99 Java Conversion by E.B, javalayer@javazoom.net + * + * 04/19/97 : Adapted from the ISO MPEG Audio Subgroup Software Simulation + * Group's public c source for its MPEG audio decoder. Miscellaneous + * changes by Jeff Tsay (ctsay@pasteur.eecs.berkeley.edu). + *----------------------------------------------------------------------- + * Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved + * MPEG/audio coding/decoding software, work in progress + * NOT for public distribution until verified and approved by the + * MPEG/audio committee. For further information, please contact + * Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com + * + * VERSION 4.1 + * changes made since last update: + * date programmers comment + * 27.2.92 F.O.Witte (ITT Intermetall) + * 8/24/93 M. Iwadare Changed for 1 pass decoding. + * 7/14/94 J. Koller useless 'typedef' before huffcodetab removed + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.decoder; + +/** + * Class that implements a Huffman decoder. + */ +final class huffcodetab +{ + private static final int MXOFF=250; + private static final int HTN=34; + + private char tablename0 = ' '; /* string, containing table_description */ + private char tablename1 = ' '; /* string, containing table_description */ + private char tablename2 = ' '; /* string, containing table_description */ + + private int xlen; /* max. x-index+ */ + private int ylen; /* max. y-index+ */ + private int linbits; /* number of linbits */ + private int linmax; /* max number to be stored in linbits */ + private int ref; /* a positive value indicates a reference */ + private int[] table=null; /* pointer to array[xlen][ylen] */ + private int[] hlen=null; /* pointer to array[xlen][ylen] */ + private int[][] val=null; /* decoder tree */ + private int treelen; /* length of decoder tree */ + + private static int ValTab0[][] = { + {0,0} // dummy + }; + + private static int ValTab1[][] = { + {2,1},{0,0},{2,1},{0,16},{2,1},{0,1},{0,17}, + }; + + private static int ValTab2[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1}, + {0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34}, + }; + + private static int ValTab3[][] = { + {4,1},{2,1},{0,0},{0,1},{2,1},{0,17},{2,1},{0,16},{4,1},{2,1}, + {0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34}, + }; + + private static int ValTab4[][] = {{0,0}}; // dummy + + private static int ValTab5[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{8,1},{4,1}, + {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1},{0,34}, + {0,48},{2,1},{0,3},{0,19},{2,1},{0,49},{2,1},{0,50},{2,1},{0,35}, + {0,51}, + }; + + private static int ValTab6[][] = { + {6,1},{4,1},{2,1},{0,0},{0,16},{0,17},{6,1},{2,1},{0,1},{2,1}, + {0,32},{0,33},{6,1},{2,1},{0,18},{2,1},{0,2},{0,34},{4,1},{2,1}, + {0,49},{0,19},{4,1},{2,1},{0,48},{0,50},{2,1},{0,35},{2,1},{0,3}, + {0,51}, + }; + + private static int ValTab7[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{0,33},{18,1},{6,1},{2,1},{0,18},{2,1},{0,34}, + {0,48},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,3},{0,50},{2,1}, + {0,35},{0,4},{10,1},{4,1},{2,1},{0,64},{0,65},{2,1},{0,20},{2,1}, + {0,66},{0,36},{12,1},{6,1},{4,1},{2,1},{0,51},{0,67},{0,80},{4,1}, + {2,1},{0,52},{0,5},{0,81},{6,1},{2,1},{0,21},{2,1},{0,82},{0,37}, + {4,1},{2,1},{0,68},{0,53},{4,1},{2,1},{0,83},{0,84},{2,1},{0,69}, + {0,85}, + }; + + private static int ValTab8[][] = { + {6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1}, + {0,33},{0,18},{14,1},{4,1},{2,1},{0,32},{0,2},{2,1},{0,34},{4,1}, + {2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{14,1},{8,1},{4,1},{2,1}, + {0,50},{0,35},{2,1},{0,64},{0,4},{2,1},{0,65},{2,1},{0,20},{0,66}, + {12,1},{6,1},{2,1},{0,36},{2,1},{0,51},{0,80},{4,1},{2,1},{0,67}, + {0,52},{0,81},{6,1},{2,1},{0,21},{2,1},{0,5},{0,82},{6,1},{2,1}, + {0,37},{2,1},{0,68},{0,53},{2,1},{0,83},{2,1},{0,69},{2,1},{0,84}, + {0,85}, + }; + + private static int ValTab9[][] = { + {8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{10,1},{4,1}, + {2,1},{0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},{12,1},{6,1}, + {4,1},{2,1},{0,48},{0,3},{0,49},{2,1},{0,19},{2,1},{0,50},{0,35}, + {12,1},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,64},{0,51},{2,1}, + {0,66},{0,36},{10,1},{6,1},{4,1},{2,1},{0,4},{0,80},{0,67},{2,1}, + {0,52},{0,81},{8,1},{4,1},{2,1},{0,21},{0,82},{2,1},{0,37},{0,68}, + {6,1},{4,1},{2,1},{0,5},{0,84},{0,83},{2,1},{0,53},{2,1},{0,69}, + {0,85}, + }; + + private static int ValTab10[][] = { + {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{10,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{28,1},{8,1},{4,1},{2,1}, + {0,34},{0,48},{2,1},{0,49},{0,19},{8,1},{4,1},{2,1},{0,3},{0,50}, + {2,1},{0,35},{0,64},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,4}, + {0,51},{2,1},{0,66},{0,36},{28,1},{10,1},{6,1},{4,1},{2,1},{0,80}, + {0,5},{0,96},{2,1},{0,97},{0,22},{12,1},{6,1},{4,1},{2,1},{0,67}, + {0,52},{0,81},{2,1},{0,21},{2,1},{0,82},{0,37},{4,1},{2,1},{0,38}, + {0,54},{0,113},{20,1},{8,1},{2,1},{0,23},{4,1},{2,1},{0,68},{0,83}, + {0,6},{6,1},{4,1},{2,1},{0,53},{0,69},{0,98},{2,1},{0,112},{2,1}, + {0,7},{0,100},{14,1},{4,1},{2,1},{0,114},{0,39},{6,1},{2,1},{0,99}, + {2,1},{0,84},{0,85},{2,1},{0,70},{0,115},{8,1},{4,1},{2,1},{0,55}, + {0,101},{2,1},{0,86},{0,116},{6,1},{2,1},{0,71},{2,1},{0,102},{0,117}, + {4,1},{2,1},{0,87},{0,118},{2,1},{0,103},{0,119}, + }; + + private static int ValTab11[][] = { + {6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{0,18},{24,1},{8,1},{2,1},{0,33},{2,1},{0,34}, + {2,1},{0,48},{0,3},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,50}, + {0,35},{4,1},{2,1},{0,64},{0,4},{2,1},{0,65},{0,20},{30,1},{16,1}, + {10,1},{4,1},{2,1},{0,66},{0,36},{4,1},{2,1},{0,51},{0,67},{0,80}, + {4,1},{2,1},{0,52},{0,81},{0,97},{6,1},{2,1},{0,22},{2,1},{0,6}, + {0,38},{2,1},{0,98},{2,1},{0,21},{2,1},{0,5},{0,82},{16,1},{10,1}, + {6,1},{4,1},{2,1},{0,37},{0,68},{0,96},{2,1},{0,99},{0,54},{4,1}, + {2,1},{0,112},{0,23},{0,113},{16,1},{6,1},{4,1},{2,1},{0,7},{0,100}, + {0,114},{2,1},{0,39},{4,1},{2,1},{0,83},{0,53},{2,1},{0,84},{0,69}, + {10,1},{4,1},{2,1},{0,70},{0,115},{2,1},{0,55},{2,1},{0,101},{0,86}, + {10,1},{6,1},{4,1},{2,1},{0,85},{0,87},{0,116},{2,1},{0,71},{0,102}, + {4,1},{2,1},{0,117},{0,118},{2,1},{0,103},{0,119}, + }; + + private static int ValTab12[][] = { + {12,1},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{2,1},{0,0},{2,1}, + {0,32},{0,2},{16,1},{4,1},{2,1},{0,33},{0,18},{4,1},{2,1},{0,34}, + {0,49},{2,1},{0,19},{2,1},{0,48},{2,1},{0,3},{0,64},{26,1},{8,1}, + {4,1},{2,1},{0,50},{0,35},{2,1},{0,65},{0,51},{10,1},{4,1},{2,1}, + {0,20},{0,66},{2,1},{0,36},{2,1},{0,4},{0,80},{4,1},{2,1},{0,67}, + {0,52},{2,1},{0,81},{0,21},{28,1},{14,1},{8,1},{4,1},{2,1},{0,82}, + {0,37},{2,1},{0,83},{0,53},{4,1},{2,1},{0,96},{0,22},{0,97},{4,1}, + {2,1},{0,98},{0,38},{6,1},{4,1},{2,1},{0,5},{0,6},{0,68},{2,1}, + {0,84},{0,69},{18,1},{10,1},{4,1},{2,1},{0,99},{0,54},{4,1},{2,1}, + {0,112},{0,7},{0,113},{4,1},{2,1},{0,23},{0,100},{2,1},{0,70},{0,114}, + {10,1},{6,1},{2,1},{0,39},{2,1},{0,85},{0,115},{2,1},{0,55},{0,86}, + {8,1},{4,1},{2,1},{0,101},{0,116},{2,1},{0,71},{0,102},{4,1},{2,1}, + {0,117},{0,87},{2,1},{0,118},{2,1},{0,103},{0,119}, + }; + + private static int ValTab13[][] = { + {2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{28,1},{8,1}, + {4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1}, + {0,34},{0,48},{2,1},{0,3},{0,49},{6,1},{2,1},{0,19},{2,1},{0,50}, + {0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{70,1},{28,1},{14,1},{6,1}, + {2,1},{0,20},{2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1}, + {0,67},{0,52},{4,1},{2,1},{0,81},{0,21},{4,1},{2,1},{0,5},{0,82}, + {2,1},{0,37},{2,1},{0,68},{0,83},{14,1},{8,1},{4,1},{2,1},{0,96}, + {0,6},{2,1},{0,97},{0,22},{4,1},{2,1},{0,128},{0,8},{0,129},{16,1}, + {8,1},{4,1},{2,1},{0,53},{0,98},{2,1},{0,38},{0,84},{4,1},{2,1}, + {0,69},{0,99},{2,1},{0,54},{0,112},{6,1},{4,1},{2,1},{0,7},{0,85}, + {0,113},{2,1},{0,23},{2,1},{0,39},{0,55},{72,1},{24,1},{12,1},{4,1}, + {2,1},{0,24},{0,130},{2,1},{0,40},{4,1},{2,1},{0,100},{0,70},{0,114}, + {8,1},{4,1},{2,1},{0,132},{0,72},{2,1},{0,144},{0,9},{2,1},{0,145}, + {0,25},{24,1},{14,1},{8,1},{4,1},{2,1},{0,115},{0,101},{2,1},{0,86}, + {0,116},{4,1},{2,1},{0,71},{0,102},{0,131},{6,1},{2,1},{0,56},{2,1}, + {0,117},{0,87},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,103}, + {0,133},{2,1},{0,88},{0,57},{2,1},{0,147},{2,1},{0,73},{0,134},{6,1}, + {2,1},{0,160},{2,1},{0,104},{0,10},{2,1},{0,161},{0,26},{68,1},{24,1}, + {12,1},{4,1},{2,1},{0,162},{0,42},{4,1},{2,1},{0,149},{0,89},{2,1}, + {0,163},{0,58},{8,1},{4,1},{2,1},{0,74},{0,150},{2,1},{0,176},{0,11}, + {2,1},{0,177},{0,27},{20,1},{8,1},{2,1},{0,178},{4,1},{2,1},{0,118}, + {0,119},{0,148},{6,1},{4,1},{2,1},{0,135},{0,120},{0,164},{4,1},{2,1}, + {0,105},{0,165},{0,43},{12,1},{6,1},{4,1},{2,1},{0,90},{0,136},{0,179}, + {2,1},{0,59},{2,1},{0,121},{0,166},{6,1},{4,1},{2,1},{0,106},{0,180}, + {0,192},{4,1},{2,1},{0,12},{0,152},{0,193},{60,1},{22,1},{10,1},{6,1}, + {2,1},{0,28},{2,1},{0,137},{0,181},{2,1},{0,91},{0,194},{4,1},{2,1}, + {0,44},{0,60},{4,1},{2,1},{0,182},{0,107},{2,1},{0,196},{0,76},{16,1}, + {8,1},{4,1},{2,1},{0,168},{0,138},{2,1},{0,208},{0,13},{2,1},{0,209}, + {2,1},{0,75},{2,1},{0,151},{0,167},{12,1},{6,1},{2,1},{0,195},{2,1}, + {0,122},{0,153},{4,1},{2,1},{0,197},{0,92},{0,183},{4,1},{2,1},{0,29}, + {0,210},{2,1},{0,45},{2,1},{0,123},{0,211},{52,1},{28,1},{12,1},{4,1}, + {2,1},{0,61},{0,198},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212}, + {8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1}, + {0,124},{0,213},{2,1},{0,93},{0,224},{10,1},{4,1},{2,1},{0,225},{0,30}, + {4,1},{2,1},{0,14},{0,46},{0,226},{8,1},{4,1},{2,1},{0,227},{0,109}, + {2,1},{0,140},{0,228},{4,1},{2,1},{0,229},{0,186},{0,240},{38,1},{16,1}, + {4,1},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1},{0,170},{0,155},{0,185}, + {2,1},{0,62},{2,1},{0,214},{0,200},{12,1},{6,1},{2,1},{0,78},{2,1}, + {0,215},{0,125},{2,1},{0,171},{2,1},{0,94},{0,201},{6,1},{2,1},{0,15}, + {2,1},{0,156},{0,110},{2,1},{0,242},{0,47},{32,1},{16,1},{6,1},{4,1}, + {2,1},{0,216},{0,141},{0,63},{6,1},{2,1},{0,243},{2,1},{0,230},{0,202}, + {2,1},{0,244},{0,79},{8,1},{4,1},{2,1},{0,187},{0,172},{2,1},{0,231}, + {0,245},{4,1},{2,1},{0,217},{0,157},{2,1},{0,95},{0,232},{30,1},{12,1}, + {6,1},{2,1},{0,111},{2,1},{0,246},{0,203},{4,1},{2,1},{0,188},{0,173}, + {0,218},{8,1},{2,1},{0,247},{4,1},{2,1},{0,126},{0,127},{0,142},{6,1}, + {4,1},{2,1},{0,158},{0,174},{0,204},{2,1},{0,248},{0,143},{18,1},{8,1}, + {4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{4,1},{2,1},{0,159}, + {0,235},{2,1},{0,190},{2,1},{0,205},{0,250},{14,1},{4,1},{2,1},{0,221}, + {0,236},{6,1},{4,1},{2,1},{0,233},{0,175},{0,220},{2,1},{0,206},{0,251}, + {8,1},{4,1},{2,1},{0,191},{0,222},{2,1},{0,207},{0,238},{4,1},{2,1}, + {0,223},{0,239},{2,1},{0,255},{2,1},{0,237},{2,1},{0,253},{2,1},{0,252}, + {0,254}, + }; + + private static int ValTab14[][] = { + {0,0} // dummy + }; + + private static int ValTab15[][] = { + {16,1},{6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1}, + {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{50,1},{16,1},{6,1},{2,1}, + {0,34},{2,1},{0,48},{0,49},{6,1},{2,1},{0,19},{2,1},{0,3},{0,64}, + {2,1},{0,50},{0,35},{14,1},{6,1},{4,1},{2,1},{0,4},{0,20},{0,65}, + {4,1},{2,1},{0,51},{0,66},{2,1},{0,36},{0,67},{10,1},{6,1},{2,1}, + {0,52},{2,1},{0,80},{0,5},{2,1},{0,81},{0,21},{4,1},{2,1},{0,82}, + {0,37},{4,1},{2,1},{0,68},{0,83},{0,97},{90,1},{36,1},{18,1},{10,1}, + {6,1},{2,1},{0,53},{2,1},{0,96},{0,6},{2,1},{0,22},{0,98},{4,1}, + {2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{10,1},{6,1},{2,1},{0,54}, + {2,1},{0,112},{0,7},{2,1},{0,113},{0,85},{4,1},{2,1},{0,23},{0,100}, + {2,1},{0,114},{0,39},{24,1},{16,1},{8,1},{4,1},{2,1},{0,70},{0,115}, + {2,1},{0,55},{0,101},{4,1},{2,1},{0,86},{0,128},{2,1},{0,8},{0,116}, + {4,1},{2,1},{0,129},{0,24},{2,1},{0,130},{0,40},{16,1},{8,1},{4,1}, + {2,1},{0,71},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117},{0,87}, + {2,1},{0,132},{0,72},{6,1},{4,1},{2,1},{0,144},{0,25},{0,145},{4,1}, + {2,1},{0,146},{0,118},{2,1},{0,103},{0,41},{92,1},{36,1},{18,1},{10,1}, + {4,1},{2,1},{0,133},{0,88},{4,1},{2,1},{0,9},{0,119},{0,147},{4,1}, + {2,1},{0,57},{0,148},{2,1},{0,73},{0,134},{10,1},{6,1},{2,1},{0,104}, + {2,1},{0,160},{0,10},{2,1},{0,161},{0,26},{4,1},{2,1},{0,162},{0,42}, + {2,1},{0,149},{0,89},{26,1},{14,1},{6,1},{2,1},{0,163},{2,1},{0,58}, + {0,135},{4,1},{2,1},{0,120},{0,164},{2,1},{0,74},{0,150},{6,1},{4,1}, + {2,1},{0,105},{0,176},{0,177},{4,1},{2,1},{0,27},{0,165},{0,178},{14,1}, + {8,1},{4,1},{2,1},{0,90},{0,43},{2,1},{0,136},{0,151},{2,1},{0,179}, + {2,1},{0,121},{0,59},{8,1},{4,1},{2,1},{0,106},{0,180},{2,1},{0,75}, + {0,193},{4,1},{2,1},{0,152},{0,137},{2,1},{0,28},{0,181},{80,1},{34,1}, + {16,1},{6,1},{4,1},{2,1},{0,91},{0,44},{0,194},{6,1},{4,1},{2,1}, + {0,11},{0,192},{0,166},{2,1},{0,167},{0,122},{10,1},{4,1},{2,1},{0,195}, + {0,60},{4,1},{2,1},{0,12},{0,153},{0,182},{4,1},{2,1},{0,107},{0,196}, + {2,1},{0,76},{0,168},{20,1},{10,1},{4,1},{2,1},{0,138},{0,197},{4,1}, + {2,1},{0,208},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1},{0,29}, + {2,1},{0,13},{0,45},{12,1},{4,1},{2,1},{0,210},{0,211},{4,1},{2,1}, + {0,61},{0,198},{2,1},{0,108},{0,169},{6,1},{4,1},{2,1},{0,154},{0,184}, + {0,212},{4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{68,1},{34,1}, + {18,1},{10,1},{4,1},{2,1},{0,213},{0,93},{4,1},{2,1},{0,224},{0,14}, + {0,225},{4,1},{2,1},{0,30},{0,226},{2,1},{0,170},{0,46},{8,1},{4,1}, + {2,1},{0,185},{0,155},{2,1},{0,227},{0,214},{4,1},{2,1},{0,109},{0,62}, + {2,1},{0,200},{0,140},{16,1},{8,1},{4,1},{2,1},{0,228},{0,78},{2,1}, + {0,215},{0,125},{4,1},{2,1},{0,229},{0,186},{2,1},{0,171},{0,94},{8,1}, + {4,1},{2,1},{0,201},{0,156},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1}, + {0,240},{0,110},{0,242},{2,1},{0,47},{0,230},{38,1},{18,1},{8,1},{4,1}, + {2,1},{0,216},{0,243},{2,1},{0,63},{0,244},{6,1},{2,1},{0,79},{2,1}, + {0,141},{0,217},{2,1},{0,187},{0,202},{8,1},{4,1},{2,1},{0,172},{0,231}, + {2,1},{0,126},{0,245},{8,1},{4,1},{2,1},{0,157},{0,95},{2,1},{0,232}, + {0,142},{2,1},{0,246},{0,203},{34,1},{18,1},{10,1},{6,1},{4,1},{2,1}, + {0,15},{0,174},{0,111},{2,1},{0,188},{0,218},{4,1},{2,1},{0,173},{0,247}, + {2,1},{0,127},{0,233},{8,1},{4,1},{2,1},{0,158},{0,204},{2,1},{0,248}, + {0,143},{4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{16,1},{8,1}, + {4,1},{2,1},{0,159},{0,220},{2,1},{0,205},{0,235},{4,1},{2,1},{0,190}, + {0,250},{2,1},{0,175},{0,221},{14,1},{6,1},{4,1},{2,1},{0,236},{0,206}, + {0,251},{4,1},{2,1},{0,191},{0,237},{2,1},{0,222},{0,252},{6,1},{4,1}, + {2,1},{0,207},{0,253},{0,238},{4,1},{2,1},{0,223},{0,254},{2,1},{0,239}, + {0,255}, + }; + + private static int ValTab16[][] = { + {2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{42,1},{8,1}, + {4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{10,1},{6,1},{2,1}, + {0,34},{2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{10,1},{4,1},{2,1}, + {0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{6,1},{2,1},{0,20}, + {2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1},{0,67},{0,52}, + {138,1},{40,1},{16,1},{6,1},{4,1},{2,1},{0,5},{0,21},{0,81},{4,1}, + {2,1},{0,82},{0,37},{4,1},{2,1},{0,68},{0,53},{0,83},{10,1},{6,1}, + {4,1},{2,1},{0,96},{0,6},{0,97},{2,1},{0,22},{0,98},{8,1},{4,1}, + {2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{4,1},{2,1},{0,54},{0,112}, + {0,113},{40,1},{18,1},{8,1},{2,1},{0,23},{2,1},{0,7},{2,1},{0,85}, + {0,100},{4,1},{2,1},{0,114},{0,39},{4,1},{2,1},{0,70},{0,101},{0,115}, + {10,1},{6,1},{2,1},{0,55},{2,1},{0,86},{0,8},{2,1},{0,128},{0,129}, + {6,1},{2,1},{0,24},{2,1},{0,116},{0,71},{2,1},{0,130},{2,1},{0,40}, + {0,102},{24,1},{14,1},{8,1},{4,1},{2,1},{0,131},{0,56},{2,1},{0,117}, + {0,132},{4,1},{2,1},{0,72},{0,144},{0,145},{6,1},{2,1},{0,25},{2,1}, + {0,9},{0,118},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,133}, + {0,88},{2,1},{0,147},{0,57},{4,1},{2,1},{0,160},{0,10},{0,26},{8,1}, + {2,1},{0,162},{2,1},{0,103},{2,1},{0,87},{0,73},{6,1},{2,1},{0,148}, + {2,1},{0,119},{0,134},{2,1},{0,161},{2,1},{0,104},{0,149},{220,1},{126,1}, + {50,1},{26,1},{12,1},{6,1},{2,1},{0,42},{2,1},{0,89},{0,58},{2,1}, + {0,163},{2,1},{0,135},{0,120},{8,1},{4,1},{2,1},{0,164},{0,74},{2,1}, + {0,150},{0,105},{4,1},{2,1},{0,176},{0,11},{0,177},{10,1},{4,1},{2,1}, + {0,27},{0,178},{2,1},{0,43},{2,1},{0,165},{0,90},{6,1},{2,1},{0,179}, + {2,1},{0,166},{0,106},{4,1},{2,1},{0,180},{0,75},{2,1},{0,12},{0,193}, + {30,1},{14,1},{6,1},{4,1},{2,1},{0,181},{0,194},{0,44},{4,1},{2,1}, + {0,167},{0,195},{2,1},{0,107},{0,196},{8,1},{2,1},{0,29},{4,1},{2,1}, + {0,136},{0,151},{0,59},{4,1},{2,1},{0,209},{0,210},{2,1},{0,45},{0,211}, + {18,1},{6,1},{4,1},{2,1},{0,30},{0,46},{0,226},{6,1},{4,1},{2,1}, + {0,121},{0,152},{0,192},{2,1},{0,28},{2,1},{0,137},{0,91},{14,1},{6,1}, + {2,1},{0,60},{2,1},{0,122},{0,182},{4,1},{2,1},{0,76},{0,153},{2,1}, + {0,168},{0,138},{6,1},{2,1},{0,13},{2,1},{0,197},{0,92},{4,1},{2,1}, + {0,61},{0,198},{2,1},{0,108},{0,154},{88,1},{86,1},{36,1},{16,1},{8,1}, + {4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{4,1},{2,1},{0,213}, + {0,93},{2,1},{0,224},{0,14},{8,1},{2,1},{0,227},{4,1},{2,1},{0,208}, + {0,183},{0,123},{6,1},{4,1},{2,1},{0,169},{0,184},{0,212},{2,1},{0,225}, + {2,1},{0,170},{0,185},{24,1},{10,1},{6,1},{4,1},{2,1},{0,155},{0,214}, + {0,109},{2,1},{0,62},{0,200},{6,1},{4,1},{2,1},{0,140},{0,228},{0,78}, + {4,1},{2,1},{0,215},{0,229},{2,1},{0,186},{0,171},{12,1},{4,1},{2,1}, + {0,156},{0,230},{4,1},{2,1},{0,110},{0,216},{2,1},{0,141},{0,187},{8,1}, + {4,1},{2,1},{0,231},{0,157},{2,1},{0,232},{0,142},{4,1},{2,1},{0,203}, + {0,188},{0,158},{0,241},{2,1},{0,31},{2,1},{0,15},{0,47},{66,1},{56,1}, + {2,1},{0,242},{52,1},{50,1},{20,1},{8,1},{2,1},{0,189},{2,1},{0,94}, + {2,1},{0,125},{0,201},{6,1},{2,1},{0,202},{2,1},{0,172},{0,126},{4,1}, + {2,1},{0,218},{0,173},{0,204},{10,1},{6,1},{2,1},{0,174},{2,1},{0,219}, + {0,220},{2,1},{0,205},{0,190},{6,1},{4,1},{2,1},{0,235},{0,237},{0,238}, + {6,1},{4,1},{2,1},{0,217},{0,234},{0,233},{2,1},{0,222},{4,1},{2,1}, + {0,221},{0,236},{0,206},{0,63},{0,240},{4,1},{2,1},{0,243},{0,244},{2,1}, + {0,79},{2,1},{0,245},{0,95},{10,1},{2,1},{0,255},{4,1},{2,1},{0,246}, + {0,111},{2,1},{0,247},{0,127},{12,1},{6,1},{2,1},{0,143},{2,1},{0,248}, + {0,249},{4,1},{2,1},{0,159},{0,250},{0,175},{8,1},{4,1},{2,1},{0,251}, + {0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1},{0,254}, + {0,239}, + }; + + private static int ValTab24[][] = { + {60,1},{8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{14,1}, + {6,1},{4,1},{2,1},{0,32},{0,2},{0,33},{2,1},{0,18},{2,1},{0,34}, + {2,1},{0,48},{0,3},{14,1},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1}, + {0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{8,1},{4,1},{2,1}, + {0,20},{0,51},{2,1},{0,66},{0,36},{6,1},{4,1},{2,1},{0,67},{0,52}, + {0,81},{6,1},{4,1},{2,1},{0,80},{0,5},{0,21},{2,1},{0,82},{0,37}, + {250,1},{98,1},{34,1},{18,1},{10,1},{4,1},{2,1},{0,68},{0,83},{2,1}, + {0,53},{2,1},{0,96},{0,6},{4,1},{2,1},{0,97},{0,22},{2,1},{0,98}, + {0,38},{8,1},{4,1},{2,1},{0,84},{0,69},{2,1},{0,99},{0,54},{4,1}, + {2,1},{0,113},{0,85},{2,1},{0,100},{0,70},{32,1},{14,1},{6,1},{2,1}, + {0,114},{2,1},{0,39},{0,55},{2,1},{0,115},{4,1},{2,1},{0,112},{0,7}, + {0,23},{10,1},{4,1},{2,1},{0,101},{0,86},{4,1},{2,1},{0,128},{0,8}, + {0,129},{4,1},{2,1},{0,116},{0,71},{2,1},{0,24},{0,130},{16,1},{8,1}, + {4,1},{2,1},{0,40},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117}, + {0,87},{2,1},{0,132},{0,72},{8,1},{4,1},{2,1},{0,145},{0,25},{2,1}, + {0,146},{0,118},{4,1},{2,1},{0,103},{0,41},{2,1},{0,133},{0,88},{92,1}, + {34,1},{16,1},{8,1},{4,1},{2,1},{0,147},{0,57},{2,1},{0,148},{0,73}, + {4,1},{2,1},{0,119},{0,134},{2,1},{0,104},{0,161},{8,1},{4,1},{2,1}, + {0,162},{0,42},{2,1},{0,149},{0,89},{4,1},{2,1},{0,163},{0,58},{2,1}, + {0,135},{2,1},{0,120},{0,74},{22,1},{12,1},{4,1},{2,1},{0,164},{0,150}, + {4,1},{2,1},{0,105},{0,177},{2,1},{0,27},{0,165},{6,1},{2,1},{0,178}, + {2,1},{0,90},{0,43},{2,1},{0,136},{0,179},{16,1},{10,1},{6,1},{2,1}, + {0,144},{2,1},{0,9},{0,160},{2,1},{0,151},{0,121},{4,1},{2,1},{0,166}, + {0,106},{0,180},{12,1},{6,1},{2,1},{0,26},{2,1},{0,10},{0,176},{2,1}, + {0,59},{2,1},{0,11},{0,192},{4,1},{2,1},{0,75},{0,193},{2,1},{0,152}, + {0,137},{67,1},{34,1},{16,1},{8,1},{4,1},{2,1},{0,28},{0,181},{2,1}, + {0,91},{0,194},{4,1},{2,1},{0,44},{0,167},{2,1},{0,122},{0,195},{10,1}, + {6,1},{2,1},{0,60},{2,1},{0,12},{0,208},{2,1},{0,182},{0,107},{4,1}, + {2,1},{0,196},{0,76},{2,1},{0,153},{0,168},{16,1},{8,1},{4,1},{2,1}, + {0,138},{0,197},{2,1},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1}, + {0,29},{0,210},{9,1},{4,1},{2,1},{0,45},{0,211},{2,1},{0,61},{0,198}, + {85,250},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212},{32,1},{16,1}, + {8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1}, + {0,124},{0,213},{2,1},{0,93},{0,225},{8,1},{4,1},{2,1},{0,30},{0,226}, + {2,1},{0,170},{0,185},{4,1},{2,1},{0,155},{0,227},{2,1},{0,214},{0,109}, + {20,1},{10,1},{6,1},{2,1},{0,62},{2,1},{0,46},{0,78},{2,1},{0,200}, + {0,140},{4,1},{2,1},{0,228},{0,215},{4,1},{2,1},{0,125},{0,171},{0,229}, + {10,1},{4,1},{2,1},{0,186},{0,94},{2,1},{0,201},{2,1},{0,156},{0,110}, + {8,1},{2,1},{0,230},{2,1},{0,13},{2,1},{0,224},{0,14},{4,1},{2,1}, + {0,216},{0,141},{2,1},{0,187},{0,202},{74,1},{2,1},{0,255},{64,1},{58,1}, + {32,1},{16,1},{8,1},{4,1},{2,1},{0,172},{0,231},{2,1},{0,126},{0,217}, + {4,1},{2,1},{0,157},{0,232},{2,1},{0,142},{0,203},{8,1},{4,1},{2,1}, + {0,188},{0,218},{2,1},{0,173},{0,233},{4,1},{2,1},{0,158},{0,204},{2,1}, + {0,219},{0,189},{16,1},{8,1},{4,1},{2,1},{0,234},{0,174},{2,1},{0,220}, + {0,205},{4,1},{2,1},{0,235},{0,190},{2,1},{0,221},{0,236},{8,1},{4,1}, + {2,1},{0,206},{0,237},{2,1},{0,222},{0,238},{0,15},{4,1},{2,1},{0,240}, + {0,31},{0,241},{4,1},{2,1},{0,242},{0,47},{2,1},{0,243},{0,63},{18,1}, + {8,1},{4,1},{2,1},{0,244},{0,79},{2,1},{0,245},{0,95},{4,1},{2,1}, + {0,246},{0,111},{2,1},{0,247},{2,1},{0,127},{0,143},{10,1},{4,1},{2,1}, + {0,248},{0,249},{4,1},{2,1},{0,159},{0,175},{0,250},{8,1},{4,1},{2,1}, + {0,251},{0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1}, + {0,254},{0,239}, + }; + + private static int ValTab32[][] = { + {2,1},{0,0},{8,1},{4,1},{2,1},{0,8},{0,4},{2,1},{0,1},{0,2}, + {8,1},{4,1},{2,1},{0,12},{0,10},{2,1},{0,3},{0,6},{6,1},{2,1}, + {0,9},{2,1},{0,5},{0,7},{4,1},{2,1},{0,14},{0,13},{2,1},{0,15}, + {0,11}, + }; + + private static int ValTab33[][] = { + {16,1},{8,1},{4,1},{2,1},{0,0},{0,1},{2,1},{0,2},{0,3},{4,1}, + {2,1},{0,4},{0,5},{2,1},{0,6},{0,7},{8,1},{4,1},{2,1},{0,8}, + {0,9},{2,1},{0,10},{0,11},{4,1},{2,1},{0,12},{0,13},{2,1},{0,14}, + {0,15}, + }; + + + public static huffcodetab[] ht = null; /* Simulate extern struct */ + + private static int[] bitbuf = new int[32]; + + /** + * Big Constructor : Computes all Huffman Tables. + */ + private huffcodetab(String S,int XLEN, int YLEN, int LINBITS, int LINMAX, int REF, + int[] TABLE, int[] HLEN, int[][] VAL, int TREELEN) + { + tablename0 = S.charAt(0); + tablename1 = S.charAt(1); + tablename2 = S.charAt(2); + xlen = XLEN; + ylen = YLEN; + linbits = LINBITS; + linmax = LINMAX; + ref = REF; + table = TABLE; + hlen = HLEN; + val = VAL; + treelen = TREELEN; + } + + + + /** + * Do the Huffman decoding. + * note! for counta,countb -the 4 bit value is returned in y, + * discard x. + */ + public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br) + { + // array of all huffcodtable headers + // 0..31 Huffman code table 0..31 + // 32,33 count1-tables + + int dmask = 1 << ((4 * 8) - 1); + int hs = 4 * 8; + int level; + int point = 0; + int error = 1; + level = dmask; + + if (h.val == null) return 2; + + /* table 0 needs no bits */ + if ( h.treelen == 0) + { + x[0] = y[0] = 0; + return 0; + } + + /* Lookup in Huffman table. */ + + /*int bitsAvailable = 0; + int bitIndex = 0; + + int bits[] = bitbuf;*/ + do + { + if (h.val[point][0]==0) + { /*end of tree*/ + x[0] = h.val[point][1] >>> 4; + y[0] = h.val[point][1] & 0xf; + error = 0; + break; + } + + // hget1bit() is called thousands of times, and so needs to be + // ultra fast. + /* + if (bitIndex==bitsAvailable) + { + bitsAvailable = br.readBits(bits, 32); + bitIndex = 0; + } + */ + //if (bits[bitIndex++]!=0) + if (br.hget1bit()!=0) + { + while (h.val[point][1] >= MXOFF) point += h.val[point][1]; + point += h.val[point][1]; + } + else + { + while (h.val[point][0] >= MXOFF) point += h.val[point][0]; + point += h.val[point][0]; + } + level >>>= 1; + // MDM: ht[0] is always 0; + } while ((level !=0 ) || (point < 0 /*ht[0].treelen*/) ); + + // put back any bits not consumed + /* + int unread = (bitsAvailable-bitIndex); + if (unread>0) + br.rewindNbits(unread); + */ + /* Process sign encodings for quadruples tables. */ + // System.out.println(h.tablename); + if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3')) + { + v[0] = (y[0]>>3) & 1; + w[0] = (y[0]>>2) & 1; + x[0] = (y[0]>>1) & 1; + y[0] = y[0] & 1; + + /* v, w, x and y are reversed in the bitstream. + switch them around to make test bistream work. */ + + if (v[0]!=0) + if (br.hget1bit() != 0) v[0] = -v[0]; + if (w[0]!=0) + if (br.hget1bit() != 0) w[0] = -w[0]; + if (x[0]!=0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (y[0]!=0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + else + { + // Process sign and escape encodings for dual tables. + // x and y are reversed in the test bitstream. + // Reverse x and y here to make test bitstream work. + + if (h.linbits != 0) + if ((h.xlen-1) == x[0]) + x[0] += br.hgetbits(h.linbits); + if (x[0] != 0) + if (br.hget1bit() != 0) x[0] = -x[0]; + if (h.linbits != 0) + if ((h.ylen-1) == y[0]) + y[0] += br.hgetbits(h.linbits); + if (y[0] != 0) + if (br.hget1bit() != 0) y[0] = -y[0]; + } + return error; + } + + public static void inithuff() + { + + if (ht!=null) + return; + + ht = new huffcodetab[HTN]; + ht[0] = new huffcodetab("0 ",0,0,0,0,-1,null,null,ValTab0,0); + ht[1] = new huffcodetab("1 ",2,2,0,0,-1,null,null,ValTab1,7); + ht[2] = new huffcodetab("2 ",3,3,0,0,-1,null,null,ValTab2,17); + ht[3] = new huffcodetab("3 ",3,3,0,0,-1,null,null,ValTab3,17); + ht[4] = new huffcodetab("4 ",0,0,0,0,-1,null,null,ValTab4,0); + ht[5] = new huffcodetab("5 ",4,4,0,0,-1,null,null,ValTab5,31); + ht[6] = new huffcodetab("6 ",4,4,0,0,-1,null,null,ValTab6,31); + ht[7] = new huffcodetab("7 ",6,6,0,0,-1,null,null,ValTab7,71); + ht[8] = new huffcodetab("8 ",6,6,0,0,-1,null,null,ValTab8,71); + ht[9] = new huffcodetab("9 ",6,6,0,0,-1,null,null,ValTab9,71); + ht[10] = new huffcodetab("10 ",8,8,0,0,-1,null,null,ValTab10,127); + ht[11] = new huffcodetab("11 ",8,8,0,0,-1,null,null,ValTab11,127); + ht[12] = new huffcodetab("12 ",8,8,0,0,-1,null,null,ValTab12,127); + ht[13] = new huffcodetab("13 ",16,16,0,0,-1,null,null,ValTab13,511); + ht[14] = new huffcodetab("14 ",0,0,0,0,-1,null,null,ValTab14,0); + ht[15] = new huffcodetab("15 ",16,16,0,0,-1,null,null,ValTab15,511); + ht[16] = new huffcodetab("16 ",16,16,1,1,-1,null,null,ValTab16,511); + ht[17] = new huffcodetab("17 ",16,16,2,3,16,null,null,ValTab16,511); + ht[18] = new huffcodetab("18 ",16,16,3,7,16,null,null,ValTab16,511); + ht[19] = new huffcodetab("19 ",16,16,4,15,16,null,null,ValTab16,511); + ht[20] = new huffcodetab("20 ",16,16,6,63,16,null,null,ValTab16,511); + ht[21] = new huffcodetab("21 ",16,16,8,255,16,null,null,ValTab16,511); + ht[22] = new huffcodetab("22 ",16,16,10,1023,16,null,null,ValTab16,511); + ht[23] = new huffcodetab("23 ",16,16,13,8191,16,null,null,ValTab16,511); + ht[24] = new huffcodetab("24 ",16,16,4,15,-1,null,null,ValTab24,512); + ht[25] = new huffcodetab("25 ",16,16,5,31,24,null,null,ValTab24,512); + ht[26] = new huffcodetab("26 ",16,16,6,63,24,null,null,ValTab24,512); + ht[27] = new huffcodetab("27 ",16,16,7,127,24,null,null,ValTab24,512); + ht[28] = new huffcodetab("28 ",16,16,8,255,24,null,null,ValTab24,512); + ht[29] = new huffcodetab("29 ",16,16,9,511,24,null,null,ValTab24,512); + ht[30] = new huffcodetab("30 ",16,16,11,2047,24,null,null,ValTab24,512); + ht[31] = new huffcodetab("31 ",16,16,13,8191,24,null,null,ValTab24,512); + ht[32] = new huffcodetab("32 ",1,16,0,0,-1,null,null,ValTab32,31); + ht[33] = new huffcodetab("33 ",1,16,0,0,-1,null,null,ValTab33,31); + } +} diff --git a/src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser b/src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser new file mode 100644 index 0000000..da216fc Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser differ diff --git a/src/lwjgl/java/javazoom/jl/decoder/lin2au.ser b/src/lwjgl/java/javazoom/jl/decoder/lin2au.ser new file mode 100644 index 0000000..ec1c83d Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/lin2au.ser differ diff --git a/src/lwjgl/java/javazoom/jl/decoder/readme.txt b/src/lwjgl/java/javazoom/jl/decoder/readme.txt new file mode 100644 index 0000000..7a765ec --- /dev/null +++ b/src/lwjgl/java/javazoom/jl/decoder/readme.txt @@ -0,0 +1,15 @@ + +TODO: + + +Implement high-level Player and Converter classes. + +Add MP1 and MP2 support and test. + +Add option to run each "stage" on own thread. +E.g. read & parse input, decode subbands, subband synthesis, audio output. + +Retrofit seek support (temporarily removed when reworking classes.) + + +Document and give example code. \ No newline at end of file diff --git a/src/lwjgl/java/javazoom/jl/decoder/sfd.ser b/src/lwjgl/java/javazoom/jl/decoder/sfd.ser new file mode 100644 index 0000000..440c7c6 Binary files /dev/null and b/src/lwjgl/java/javazoom/jl/decoder/sfd.ser differ diff --git a/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java b/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java new file mode 100644 index 0000000..b908f49 --- /dev/null +++ b/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java @@ -0,0 +1,265 @@ +/* + * DecodedMpegAudioInputStream. + * + * JavaZOOM : mp3spi@javazoom.net + * http://www.javazoom.net + * + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + *----------------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *------------------------------------------------------------------------ + */ + +package javazoom.mp3spi; + +import java.io.IOException; +import java.io.InputStream; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +import tritonus.TAsynchronousFilteredAudioInputStream; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.BitstreamException; +import javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.DecoderException; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.Obuffer; + +/** + * Main decoder. + */ +public class DecodedMpegAudioInputStream extends TAsynchronousFilteredAudioInputStream +{ + private InputStream m_encodedStream; + private Bitstream m_bitstream; + private Decoder m_decoder; + private Header m_header; + private DMAISObuffer m_oBuffer; + + // Bytes info. + private long byteslength = -1; + private long currentByte = 0; + // Frame info. + private int frameslength = -1; + private long currentFrame = 0; + private int currentFramesize = 0; + + public DecodedMpegAudioInputStream(AudioFormat outputFormat, + AudioInputStream bufferedInputStream) + { + super(outputFormat, -1); + + try + { + // Try to find out inputstream length to allow skip. + byteslength = bufferedInputStream.available(); + } catch (IOException e) + { + byteslength = -1; + } + m_encodedStream = bufferedInputStream; + m_bitstream = new Bitstream(bufferedInputStream); + m_decoder = new Decoder(null); + // m_equalizer = new Equalizer(); + // m_equalizer_values = new float[32]; + // for (int b=0;b 0)) + frameslength = m_header.max_number_of_frames((int) byteslength); + } catch (BitstreamException e) + { + + byteslength = -1; + } + } + + public void execute()// if( reverseBytes ) + // reverseBytes( smallBuffer, 0, bytesRead ); + { + + try + { + // Following line hangs when FrameSize is available in AudioFormat. + Header header = null; + if(m_header == null) + header = m_bitstream.readFrame(); + else header = m_header; + + if(header == null) + { + + getCircularBuffer().close(); + return; + } + currentFrame++; + currentFramesize = header.calculate_framesize(); + currentByte = currentByte + currentFramesize; + // Obuffer decoderOutput = + m_decoder.decodeFrame(header, m_bitstream); + m_bitstream.closeFrame(); + getCircularBuffer().write(m_oBuffer.getBuffer(), 0, m_oBuffer.getCurrentBufferSize()); + m_oBuffer.reset(); + if(m_header != null) + m_header = null; + } catch (BitstreamException e) + { + + } catch (DecoderException e) + { + + } + + } + + public long skip(long bytes) + { + if((byteslength > 0) && (frameslength > 0)) + { + float ratio = bytes * 1.0f / byteslength * 1.0f; + long bytesread = skipFrames((long) (ratio * frameslength)); + currentByte = currentByte + bytesread; + m_header = null; + return bytesread; + } else return -1; + } + + /** + * Skip frames. You don't need to call it severals times, it will exactly + * skip given frames number. + * + * @param frames + * @return bytes length skipped matching to frames skipped. + */ + public long skipFrames(long frames) + { + + int framesRead = 0; + int bytesReads = 0; + try + { + for(int i = 0; i < frames; i++) + { + Header header = m_bitstream.readFrame(); + if(header != null) + { + int fsize = header.calculate_framesize(); + bytesReads = bytesReads + fsize; + } + m_bitstream.closeFrame(); + framesRead++; + } + } catch (BitstreamException e) + { + + } + + currentFrame = currentFrame + framesRead; + return bytesReads; + } + + private boolean isBigEndian() + { + return getFormat().isBigEndian(); + } + + public void close() throws IOException + { + super.close(); + m_encodedStream.close(); + } + + private class DMAISObuffer extends Obuffer + { + private int m_nChannels; + private byte[] m_abBuffer; + private int[] m_anBufferPointers; + private boolean m_bIsBigEndian; + + public DMAISObuffer(int nChannels) + { + m_nChannels = nChannels; + m_abBuffer = new byte[OBUFFERSIZE * nChannels]; + m_anBufferPointers = new int[nChannels]; + reset(); + m_bIsBigEndian = DecodedMpegAudioInputStream.this.isBigEndian(); + } + + public void append(int nChannel, short sValue) + { + byte bFirstByte; + byte bSecondByte; + if(m_bIsBigEndian) + { + bFirstByte = (byte) ((sValue >>> 8) & 0xFF); + bSecondByte = (byte) (sValue & 0xFF); + } else + // little endian + { + bFirstByte = (byte) (sValue & 0xFF); + bSecondByte = (byte) ((sValue >>> 8) & 0xFF); + } + m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte; + m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte; + m_anBufferPointers[nChannel] += m_nChannels * 2; + } + + public void set_stop_flag() + { + } + + public void close() + { + } + + public void write_buffer(int nValue) + { + } + + public void clear_buffer() + { + } + + public byte[] getBuffer() + { + return m_abBuffer; + } + + public int getCurrentBufferSize() + { + return m_anBufferPointers[0]; + } + + public void reset() + { + for(int i = 0; i < m_nChannels; i++) + { + /* + * Points to byte location, implicitely assuming 16 bit samples. + */ + m_anBufferPointers[i] = i * 2; + } + } + } +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/MinecraftMain.java b/src/lwjgl/java/net/lax1dude/eaglercraft/MinecraftMain.java new file mode 100644 index 0000000..8864d17 --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/MinecraftMain.java @@ -0,0 +1,27 @@ +package net.lax1dude.eaglercraft; + +import javax.swing.JOptionPane; + +import net.minecraft.client.Minecraft; + +public class MinecraftMain { + + public static void main(String[] par0ArrayOfStr) { + + JOptionPane.showMessageDialog(null, "launch renderdoc (optionally) and press ok to continue", "eaglercraft", JOptionPane.PLAIN_MESSAGE); + /* + EaglerAdapter.initializeContext(); + LocalStorageManager.loadStorage(); + + byte[] b = EaglerAdapter.loadLocalStorage("forced"); + if(b != null) { + ServerList.loadDefaultServers(Base64.encodeBase64String(b)); + } + if(par0ArrayOfStr.length > 0) { + EaglerAdapter.setServerToJoinOnLaunch(par0ArrayOfStr[0]); + } + */ + Minecraft.startMainThread(null, null, null); + + } +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/EaglerAdapterImpl2.java b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/EaglerAdapterImpl2.java new file mode 100644 index 0000000..4ae8c8c --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/EaglerAdapterImpl2.java @@ -0,0 +1,1451 @@ +package net.lax1dude.eaglercraft.adapter; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.HeadlessException; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.charset.Charset; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.filechooser.FileFilter; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import org.json.JSONObject; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.openal.AL; +import org.lwjgl.opengl.ARBDebugOutput; +import org.lwjgl.opengl.ARBDebugOutputCallback; +import org.lwjgl.opengl.ARBOcclusionQuery2; +import org.lwjgl.opengl.ContextAttribs; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.DisplayMode; +import org.lwjgl.opengl.EXTTextureFilterAnisotropic; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.PixelFormat; +import org.lwjgl.util.glu.GLU; + +import de.cuina.fireandfuel.CodecJLayerMP3; +import net.lax1dude.eaglercraft.AssetRepository; +import net.lax1dude.eaglercraft.EarlyLoadScreen; +import net.lax1dude.eaglercraft.ServerQuery; +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.ProgramGL; +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.RateLimit; +import net.lax1dude.eaglercraft.adapter.lwjgl.GameWindowListener; +import net.minecraft.src.MathHelper; +import paulscode.sound.SoundSystem; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.libraries.LibraryLWJGLOpenAL; + +public class EaglerAdapterImpl2 { + + public static final boolean _wisWebGL() { + return false; + } + public static final boolean _wisAnisotropicPatched() { + return true; + } + public static final String _wgetShaderHeader() { + return "#version 150"; + } + + public static final InputStream loadResource(String path) { + byte[] file = loadResourceBytes(path); + if (file != null) { + return new ByteArrayInputStream(file); + } else { + return null; + } + } + + public static final boolean isSSLPage() { + return true; + } + + public static final String[] getIdentifier() { + return new String[0]; + } + + private static final boolean useEPKTest = false; + + public static final byte[] loadResourceBytes(String path) { + if(useEPKTest) { + return AssetRepository.getResource(path); + }else { + try { + InputStream stream; + try { + stream = new FileInputStream(new File("resources", path)); + } catch (FileNotFoundException e) { + return null; + } + byte[] targetArray = new byte[stream.available()]; + stream.read(targetArray); + stream.close(); + return targetArray; + } catch (IOException e) { + return null; + } + } + } + + public static final String fileContents(String path) { + byte[] contents = loadResourceBytes(path); + if(contents == null) { + return null; + }else { + return new String(contents, Charset.forName("UTF-8")); + } + } + + public static final String[] fileContentsLines(String path) { + String contents = fileContents(path); + if(contents == null) { + return null; + }else { + return contents.replace("\r\n", "\n").split("[\r\n]"); + } + } + + public static final void setDebugVar(String v, String s) { + + } + + public static final int _wGL_TEXTURE_2D = GL11.GL_TEXTURE_2D; + public static final int _wGL_DEPTH_TEST = GL11.GL_DEPTH_TEST; + public static final int _wGL_LEQUAL = GL11.GL_LEQUAL; + public static final int _wGL_GEQUAL = GL11.GL_GEQUAL; + public static final int _wGL_GREATER = GL11.GL_GREATER; + public static final int _wGL_LESS = GL11.GL_LESS; + public static final int _wGL_BACK = GL11.GL_BACK; + public static final int _wGL_FRONT = GL11.GL_FRONT; + public static final int _wGL_FRONT_AND_BACK = GL11.GL_FRONT_AND_BACK; + public static final int _wGL_COLOR_BUFFER_BIT = GL11.GL_COLOR_BUFFER_BIT; + public static final int _wGL_DEPTH_BUFFER_BIT = GL11.GL_DEPTH_BUFFER_BIT; + public static final int _wGL_BLEND = GL11.GL_BLEND; + public static final int _wGL_RGBA = GL11.GL_RGBA; + public static final int _wGL_RGB = GL11.GL_RGB; + public static final int _wGL_RGB8 = GL11.GL_RGB8; + public static final int _wGL_RGBA8 = GL11.GL_RGBA8; + public static final int _wGL_UNSIGNED_BYTE = GL11.GL_UNSIGNED_BYTE; + public static final int _wGL_UNSIGNED_SHORT = GL11.GL_UNSIGNED_SHORT; + public static final int _wGL_TEXTURE_WIDTH = GL11.GL_TEXTURE_WIDTH; + public static final int _wGL_SRC_ALPHA = GL11.GL_SRC_ALPHA; + public static final int _wGL_ONE_MINUS_SRC_ALPHA = GL11.GL_ONE_MINUS_SRC_ALPHA; + public static final int _wGL_ONE_MINUS_DST_COLOR = GL11.GL_ONE_MINUS_DST_COLOR; + public static final int _wGL_ONE_MINUS_SRC_COLOR = GL11.GL_ONE_MINUS_SRC_COLOR; + public static final int _wGL_ZERO = GL11.GL_ZERO; + public static final int _wGL_CULL_FACE = GL11.GL_CULL_FACE; + public static final int _wGL_TEXTURE_MIN_FILTER = GL11.GL_TEXTURE_MIN_FILTER; + public static final int _wGL_TEXTURE_MAG_FILTER = GL11.GL_TEXTURE_MAG_FILTER; + public static final int _wGL_LINEAR = GL11.GL_LINEAR; + public static final int _wGL_NEAREST_MIPMAP_LINEAR = GL11.GL_NEAREST_MIPMAP_LINEAR; + public static final int _wGL_LINEAR_MIPMAP_LINEAR = GL11.GL_LINEAR_MIPMAP_LINEAR; + public static final int _wGL_LINEAR_MIPMAP_NEAREST = GL11.GL_LINEAR_MIPMAP_NEAREST; + public static final int _wGL_NEAREST_MIPMAP_NEAREST = GL11.GL_NEAREST_MIPMAP_NEAREST; + public static final int _wGL_EQUAL = GL11.GL_EQUAL; + public static final int _wGL_SRC_COLOR = GL11.GL_SRC_COLOR; + public static final int _wGL_ONE = GL11.GL_ONE; + public static final int _wGL_NEAREST = GL11.GL_NEAREST; + public static final int _wGL_CLAMP = GL12.GL_CLAMP_TO_EDGE; + public static final int _wGL_TEXTURE_WRAP_S = GL11.GL_TEXTURE_WRAP_S; + public static final int _wGL_TEXTURE_WRAP_T = GL11.GL_TEXTURE_WRAP_T; + public static final int _wGL_TEXTURE_MAX_LEVEL = GL12.GL_TEXTURE_MAX_LEVEL; + public static final int _wGL_REPEAT = GL11.GL_REPEAT; + public static final int _wGL_DST_COLOR = GL11.GL_DST_COLOR; + public static final int _wGL_DST_ALPHA = GL11.GL_DST_ALPHA; + public static final int _wGL_FLOAT = GL11.GL_FLOAT; + public static final int _wGL_SHORT = GL11.GL_SHORT; + public static final int _wGL_TRIANGLES = GL11.GL_TRIANGLES; + public static final int _wGL_TRIANGLE_STRIP = GL11.GL_TRIANGLE_STRIP; + public static final int _wGL_TRIANGLE_FAN = GL11.GL_TRIANGLE_FAN; + public static final int _wGL_LINE_STRIP = GL11.GL_LINE_STRIP; + public static final int _wGL_LINES = GL11.GL_LINES; + public static final int _wGL_PACK_ALIGNMENT = GL11.GL_PACK_ALIGNMENT; + public static final int _wGL_UNPACK_ALIGNMENT = GL11.GL_UNPACK_ALIGNMENT; + public static final int _wGL_TEXTURE0 = GL13.GL_TEXTURE0; + public static final int _wGL_TEXTURE1 = GL13.GL_TEXTURE1; + public static final int _wGL_TEXTURE2 = GL13.GL_TEXTURE2; + public static final int _wGL_TEXTURE3 = GL13.GL_TEXTURE3; + public static final int _wGL_VIEWPORT = GL11.GL_VIEWPORT; + public static final int _wGL_VERTEX_SHADER = GL20.GL_VERTEX_SHADER; + public static final int _wGL_FRAGMENT_SHADER = GL20.GL_FRAGMENT_SHADER; + public static final int _wGL_ARRAY_BUFFER = GL15.GL_ARRAY_BUFFER; + public static final int _wGL_ELEMENT_ARRAY_BUFFER = GL15.GL_ELEMENT_ARRAY_BUFFER; + public static final int _wGL_STATIC_DRAW = GL15.GL_STATIC_DRAW; + public static final int _wGL_DYNAMIC_DRAW = GL15.GL_DYNAMIC_DRAW; + public static final int _wGL_INVALID_ENUM = GL11.GL_INVALID_ENUM; + public static final int _wGL_INVALID_VALUE= GL11.GL_INVALID_VALUE; + public static final int _wGL_INVALID_OPERATION = GL11.GL_INVALID_OPERATION; + public static final int _wGL_OUT_OF_MEMORY = GL11.GL_OUT_OF_MEMORY; + public static final int _wGL_CONTEXT_LOST_WEBGL = -1; + public static final int _wGL_FRAMEBUFFER_COMPLETE = GL30.GL_FRAMEBUFFER_COMPLETE; + public static final int _wGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL30.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + public static final int _wGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL30.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + public static final int _wGL_COLOR_ATTACHMENT0 = GL30.GL_COLOR_ATTACHMENT0; + public static final int _wGL_DEPTH_STENCIL_ATTACHMENT = GL30.GL_DEPTH_STENCIL_ATTACHMENT; + public static final int _wGL_DEPTH_ATTACHMENT = GL30.GL_DEPTH_ATTACHMENT; + public static final int _wGL_DEPTH_COMPONENT32F = GL30.GL_DEPTH_COMPONENT32F; + public static final int _wGL_DEPTH_STENCIL = GL30.GL_DEPTH_STENCIL; + public static final int _wGL_DEPTH24_STENCIL8 = GL30.GL_DEPTH24_STENCIL8; + public static final int _wGL_UNSIGNED_INT_24_8 = GL30.GL_UNSIGNED_INT_24_8; + public static final int _wGL_UNSIGNED_INT = GL11.GL_UNSIGNED_INT; + public static int _wGL_ANY_SAMPLES_PASSED = -1; + public static final int _wGL_QUERY_RESULT = GL15.GL_QUERY_RESULT; + public static final int _wGL_QUERY_RESULT_AVAILABLE = GL15.GL_QUERY_RESULT_AVAILABLE; + public static int _wGL_TEXTURE_MAX_ANISOTROPY = -1; + public static final int _wGL_R8 = GL30.GL_R8; + public static final int _wGL_R32UI = GL30.GL_R32UI; + public static final int _wGL_RED = GL11.GL_RED; + public static final int _wGL_RENDERBUFFER = GL30.GL_RENDERBUFFER; + public static final int _wGL_MULTISAMPLE = GL13.GL_MULTISAMPLE; + public static final int _wGL_LINE_SMOOTH = GL11.GL_LINE_SMOOTH; + public static final int _wGL_DRAW_FRAMEBUFFER = GL30.GL_DRAW_FRAMEBUFFER; + public static final int _wGL_READ_FRAMEBUFFER = GL30.GL_READ_FRAMEBUFFER; + public static final int _wGL_FRAMEBUFFER = GL30.GL_FRAMEBUFFER; + public static final int _wGL_POLYGON_OFFSET_FILL = GL11.GL_POLYGON_OFFSET_FILL; + + public static final class TextureGL { + protected final int obj; + public int w = -1; + public int h = -1; + public boolean nearest = true; + public boolean anisotropic = false; + protected TextureGL(int obj) { + this.obj = obj; + } + } + public static final class BufferGL { + protected final int obj; + protected BufferGL(int obj) { + this.obj = obj; + } + } + public static final class ShaderGL { + protected final int obj; + protected ShaderGL(int obj) { + this.obj = obj; + } + } + public static final class ProgramGL { + protected final int obj; + protected ProgramGL(int obj) { + this.obj = obj; + } + } + public static final class UniformGL { + protected final int obj; + protected UniformGL(int obj) { + this.obj = obj; + } + } + public static final class BufferArrayGL { + protected final int obj; + public boolean isQuadBufferBound; + protected BufferArrayGL(int obj) { + this.obj = obj; + this.isQuadBufferBound = false; + } + } + public static final class FramebufferGL { + protected final int obj; + protected FramebufferGL(int obj) { + this.obj = obj; + } + } + public static final class RenderbufferGL { + protected final int obj; + protected RenderbufferGL(int obj) { + this.obj = obj; + } + } + public static final class QueryGL { + protected final int obj; + protected QueryGL(int obj) { + this.obj = obj; + } + } + + public static final void _wglEnable(int p1) { + GL11.glEnable(p1); + } + public static final void _wglClearDepth(float p1) { + GL11.glClearDepth(p1); + } + public static final void _wglDepthFunc(int p1) { + GL11.glDepthFunc(p1); + } + public static final void _wglCullFace(int p1) { + GL11.glCullFace(p1); + } + private static final int[] viewport = new int[4]; + public static final void _wglViewport(int p1, int p2, int p3, int p4) { + viewport[0] = p1; viewport[1] = p2; + viewport[2] = p3; viewport[3] = p4; + GL11.glViewport(p1, p2, p3, p4); + } + public static final void _wglClear(int p1) { + GL11.glClear(p1); + } + public static final void _wglClearColor(float p1, float p2, float p3, float p4) { + GL11.glClearColor(p1, p2, p3, p4); + } + public static final void _wglDisable(int p1) { + GL11.glDisable(p1); + } + public static final int _wglGetError() { + return GL11.glGetError(); + } + public static final void _wglFlush() { + + } + public static final void _wglTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + GL11.glTexImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + + public static final void _wglBlendFunc(int p1, int p2) { + GL11.glBlendFunc(p1, p2); + } + public static final void _wglDepthMask(boolean p1) { + GL11.glDepthMask(p1); + } + public static final void _wglColorMask(boolean p1, boolean p2, boolean p3, boolean p4) { + GL11.glColorMask(p1, p2, p3, p4); + } + public static final void _wglBindTexture(int p1, TextureGL p2) { + GL11.glBindTexture(p1, p2 == null ? 0 : p2.obj); + } + public static final void _wglCopyTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) { + GL11.glCopyTexSubImage2D(p1, p2, p3, p4, p5, p6, p7, p8); + } + public static final void _wglTexParameteri(int p1, int p2, int p3) { + GL11.glTexParameteri(p1, p2, p3); + } + public static final void _wglTexParameterf(int p1, int p2, int p3) { + GL11.glTexParameterf(p1, p2, p3); + } + public static final void _wglTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + GL11.glTexImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + public static final void _wglTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + GL11.glTexSubImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + public static final void _wglDeleteTextures(TextureGL p1) { + GL11.glDeleteTextures(p1.obj); + } + public static final void _wglDrawArrays(int p1, int p2, int p3) { + GL11.glDrawArrays(p1, p2, p3); + } + public static final void _wglDrawElements(int p1, int p2, int p3, int p4) { + GL11.glDrawElements(p1, p2, p3, p4); + } + public static final TextureGL _wglGenTextures() { + return new TextureGL(GL11.glGenTextures()); + } + public static final void _wglTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + GL11.glTexSubImage2D(p1, p2, p3, p4, p5, p6, p7, p8, p9); + } + public static final void _wglTexImage3D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, ByteBuffer p10) { + GL12.glTexImage3D(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + public static final void _wglTexParameterf(int p1, int p2, float p3) { + GL11.glTexParameterf(p1, p2, p3); + } + public static final void _wglActiveTexture(int p1) { + GL13.glActiveTexture(p1); + } + public static final String _wgluErrorString(int p1) { + return GLU.gluErrorString(p1); + } + public static final ProgramGL _wglCreateProgram() { + return new ProgramGL(GL20.glCreateProgram()); + } + public static final ShaderGL _wglCreateShader(int p1) { + return new ShaderGL(GL20.glCreateShader(p1)); + } + public static final void _wglAttachShader(ProgramGL p1, ShaderGL p2) { + GL20.glAttachShader(p1.obj, p2.obj); + } + public static final void _wglDetachShader(ProgramGL p1, ShaderGL p2) { + GL20.glDetachShader(p1.obj, p2.obj); + } + public static final void _wglCompileShader(ShaderGL p1) { + GL20.glCompileShader(p1.obj); + } + public static final void _wglLinkProgram(ProgramGL p1) { + GL20.glLinkProgram(p1.obj); + } + public static final void _wglShaderSource(ShaderGL p1, String p2) { + GL20.glShaderSource(p1.obj, p2); + } + public static final String _wglGetShaderInfoLog(ShaderGL p1) { + return GL20.glGetShaderInfoLog(p1.obj, 8192); + } + public static final String _wglGetProgramInfoLog(ProgramGL p1) { + return GL20.glGetProgramInfoLog(p1.obj, 8192); + } + public static final boolean _wglGetShaderCompiled(ShaderGL p1) { + return GL20.glGetShaderi(p1.obj, GL20.GL_COMPILE_STATUS) == GL11.GL_TRUE; + } + public static final boolean _wglGetProgramLinked(ProgramGL p1) { + return GL20.glGetProgrami(p1.obj, GL20.GL_LINK_STATUS) == GL11.GL_TRUE; + } + public static final void _wglDeleteShader(ShaderGL p1) { + GL20.glDeleteShader(p1.obj); + } + public static final void _wglDeleteProgram(ProgramGL p1) { + GL20.glDeleteProgram(p1.obj); + } + public static final BufferArrayGL _wglCreateVertexArray() { + return new BufferArrayGL(GL30.glGenVertexArrays()); + } + public static final void _wglDeleteVertexArray(BufferArrayGL p1) { + GL30.glDeleteVertexArrays(p1.obj); + } + public static final void _wglBindVertexArray(BufferArrayGL p1) { + GL30.glBindVertexArray(p1 == null ? 0 : p1.obj); + } + public static final BufferGL _wglCreateBuffer() { + return new BufferGL(GL15.glGenBuffers()); + } + public static final void _wglDeleteBuffer(BufferGL p1) { + GL15.glDeleteBuffers(p1.obj); + } + public static final void _wglBindBuffer(int p1, BufferGL p2) { + GL15.glBindBuffer(p1, p2 == null ? 0 : p2.obj); + } + public static final void _wglBufferData(int p1, Object p2, int p3) { + GL15.glBufferData(p1, (IntBuffer)p2, p3); + } + public static final void _wglBufferSubData(int p1, int p2, Object p3) { + GL15.glBufferSubData(p1, p2, (IntBuffer)p3); + } + public static final void _wglBufferData0(int p1, IntBuffer p2, int p3) { + GL15.glBufferData(p1, p2, p3); + } + public static final void _wglBufferSubData0(int p1, int p2, IntBuffer p3) { + GL15.glBufferSubData(p1, p2, p3); + } + public static final void _wglBindAttribLocation(int p1, int p2, String p3) { + GL20.glBindAttribLocation(p1, p2, p3); + } + public static final void _wglEnableVertexAttribArray(int p1) { + GL20.glEnableVertexAttribArray(p1); + } + public static final void _wglDisableVertexAttribArray(int p1) { + GL20.glDisableVertexAttribArray(p1); + } + public static final UniformGL _wglGetUniformLocation(ProgramGL p1, String p2) { + int u = GL20.glGetUniformLocation(p1.obj, p2); + return u == -1 ? null : new UniformGL(u); + } + public static final void _wglBindAttributeLocation(ProgramGL p1, int p2, String p3) { + GL20.glBindAttribLocation(p1.obj, p2, p3); + } + public static final void _wglUniform1f(UniformGL p1, float p2) { + if(p1 != null) GL20.glUniform1f(p1.obj, p2); + } + public static final void _wglUniform2f(UniformGL p1, float p2, float p3) { + if(p1 != null) GL20.glUniform2f(p1.obj, p2, p3); + } + public static final void _wglUniform3f(UniformGL p1, float p2, float p3, float p4) { + if(p1 != null) GL20.glUniform3f(p1.obj, p2, p3, p4); + } + public static final void _wglUniform4f(UniformGL p1, float p2, float p3, float p4, float p5) { + if(p1 != null) GL20.glUniform4f(p1.obj, p2, p3, p4, p5); + } + public static final void _wglUniform1i(UniformGL p1, int p2) { + if(p1 != null) GL20.glUniform1i(p1.obj, p2); + } + public static final void _wglUniform2i(UniformGL p1, int p2, int p3) { + if(p1 != null) GL20.glUniform2i(p1.obj, p2, p3); + } + public static final void _wglUniform3i(UniformGL p1, int p2, int p3, int p4) { + if(p1 != null) GL20.glUniform3i(p1.obj, p2, p3, p4); + } + public static final void _wglUniform4i(UniformGL p1, int p2, int p3, int p4, int p5) { + if(p1 != null) GL20.glUniform4i(p1.obj, p2, p3, p4, p5); + } + private static final FloatBuffer matUpload = ByteBuffer.allocateDirect(16 << 2).order(ByteOrder.nativeOrder()).asFloatBuffer(); + public static final void _wglUniformMat2fv(UniformGL p1, float[] mat) { + matUpload.clear(); + matUpload.put(mat); + matUpload.flip(); + if(p1 != null) GL20.glUniformMatrix2(p1.obj, false, matUpload); + } + public static final void _wglUniformMat3fv(UniformGL p1, float[] mat) { + matUpload.clear(); + matUpload.put(mat); + matUpload.flip(); + if(p1 != null) GL20.glUniformMatrix3(p1.obj, false, matUpload); + } + public static final void _wglUniformMat4fv(UniformGL p1, float[] mat) { + matUpload.clear(); + matUpload.put(mat); + matUpload.flip(); + if(p1 != null) GL20.glUniformMatrix4(p1.obj, false, matUpload); + } + private static int currentProgram = 0; + public static final void _wglUseProgram(ProgramGL p1) { + int i = p1 == null ? 0 : p1.obj; + if(i != currentProgram) { + currentProgram = i; + GL20.glUseProgram(i); + } + } + public static final void _wglGetParameter(int p1, int size, int[] p3) { + if(p1 == _wGL_VIEWPORT) { + p3[0] = viewport[0]; p3[1] = viewport[1]; + p3[2] = viewport[2]; p3[3] = viewport[3]; + } + } + public static final void _wglPolygonOffset(float p1, float p2) { + GL11.glPolygonOffset(p1, p2); + } + public static final void _wglVertexAttribPointer(int p1, int p2, int p3, boolean p4, int p5, int p6) { + GL20.glVertexAttribPointer(p1, p2, p3, p4, p5, p6); + } + public static final void _wglBindFramebuffer(int p1, FramebufferGL p2) { + GL30.glBindFramebuffer(p1, p2 == null ? 0 : p2.obj); + } + public static final void _wglDrawBuffer(int p1) { + GL11.glDrawBuffer(p1); + } + public static final void _wglBlitFramebuffer(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10) { + GL30.glBlitFramebuffer(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + public static final FramebufferGL _wglCreateFramebuffer() { + return new FramebufferGL(GL30.glGenFramebuffers()); + } + public static final void _wglDeleteFramebuffer(FramebufferGL p1) { + GL30.glDeleteFramebuffers(p1.obj); + } + public static final void _wglFramebufferTexture2D(int p1, TextureGL p2) { + GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, p1, GL11.GL_TEXTURE_2D, p2.obj, 0); + } + public static final RenderbufferGL _wglCreateRenderBuffer() { + return new RenderbufferGL(GL30.glGenRenderbuffers()); + } + public static final void _wglDeleteRenderbuffer(RenderbufferGL p1) { + GL30.glDeleteRenderbuffers(p1.obj); + } + public static final void _wglBindRenderbuffer(RenderbufferGL p1) { + GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, p1 == null ? 0 : p1.obj); + } + public static final void _wglRenderbufferStorage(int p1, int p2, int p3) { + GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, p1, p2, p3); + } + public static final void _wglRenderbufferStorageMultisample(int p1, int p2, int p3, int p4) { + GL30.glRenderbufferStorageMultisample(GL30.GL_RENDERBUFFER, p1, p2, p3, p4); + } + public static final void _wglFramebufferRenderbuffer(int p1, RenderbufferGL p2) { + GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, p1, GL30.GL_RENDERBUFFER, p2.obj); + } + public static final QueryGL _wglCreateQuery() { + return new QueryGL(GL15.glGenQueries()); + } + public static final void _wglBeginQuery(int p1, QueryGL p2) { + GL15.glBeginQuery(p1, p2.obj); + } + public static final void _wglEndQuery(int p1) { + GL15.glEndQuery(p1); + } + public static final void _wglDeleteQuery(QueryGL p1) { + GL15.glDeleteQueries(p1.obj); + } + public static final int _wglGetQueryObjecti(QueryGL p1, int p2) { + return GL15.glGetQueryObjecti(p1.obj, p2); + } + public static final void _wglLineWidth(float p1) { + GL11.glLineWidth(p1); + } + public static final int _wglGetTexParameteri(int p1) { + return GL11.glGetTexParameteri(GL11.GL_TEXTURE_2D, p1); + } + public static final float _wglGetTexParameterf(int p1) { + return GL11.glGetTexParameterf(GL11.GL_TEXTURE_2D, p1); + } + public static final int _wglGetAttribLocation(ProgramGL p1, String p2) { + return GL20.glGetAttribLocation(p1.obj, p2); + } + + + // ======================================================================================= + // ======================================================================================= + // ======================================================================================= + // ======================================================================================= + // ======================================================================================= + + private static Canvas daCanvas = null; + private static Frame eagler = null; + private static SoundSystem ss = null; + public static final void initializeContext() { + daCanvas = new Canvas(); + eagler = new Frame(); + eagler.setTitle("eaglercraft desktop runtime"); + eagler.setBackground(Color.BLACK); + JPanel var16 = new JPanel(); + eagler.setLayout(new BorderLayout()); + var16.setPreferredSize(new Dimension(854, 480)); + eagler.add(var16, "Center"); + eagler.pack(); + eagler.setLocationRelativeTo((Component) null); + eagler.setVisible(true); + eagler.addWindowListener(new GameWindowListener()); + eagler.removeAll(); + eagler.setLayout(new BorderLayout()); + eagler.add(daCanvas, "Center"); + eagler.validate(); + eagler.setVisible(true); + + try { + ContextAttribs contextAtrributes = new ContextAttribs(3, 2).withForwardCompatible(true).withProfileCore(true).withDebug(true); + Display.setParent(daCanvas); + Display.create((new PixelFormat()).withDepthBits(24), contextAtrributes); + } catch (LWJGLException var5) { + var5.printStackTrace(); + + try { + Thread.sleep(1000L); + } catch (InterruptedException var4) { + ; + } + + try { + Display.create(); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + + //if(!_wisWebGL()) { + // GL30.glBindVertexArray(GL30.glGenVertexArrays()); + //} + + EarlyLoadScreen.paintScreen(); + + try { + Mouse.create(); + Keyboard.create(); + } catch (LWJGLException var5) { + var5.printStackTrace(); + } + + if(useEPKTest) { + try { + InputStream stream = new FileInputStream(new File("out.epk")); + byte[] targetArray = new byte[stream.available()]; + stream.read(targetArray); + stream.close(); + AssetRepository.install(targetArray); + } catch(IOException e) { + e.printStackTrace(); + } + } + + Display.setTitle("eaglercraft desktop runtime"); + System.out.println("LWJGL Version: " + Sys.getVersion()); + + _wGL_ANY_SAMPLES_PASSED = ARBOcclusionQuery2.GL_ANY_SAMPLES_PASSED; + _wGL_TEXTURE_MAX_ANISOTROPY = EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT; + + GL11.glEnable(ARBDebugOutput.GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + ARBDebugOutput.glDebugMessageCallbackARB(new ARBDebugOutputCallback(new ARBDebugOutputCallback.Handler() { + + @Override + public void handleMessage(int arg0, int arg1, int arg2, int arg3, String arg4) { + if(arg3 == ARBDebugOutput.GL_DEBUG_SEVERITY_MEDIUM_ARB || arg3 == ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB) { + StringBuilder b = new StringBuilder(); + b.append("[KHR DEBUG #"); b.append(arg2); b.append("] "); + switch(arg0) { + case ARBDebugOutput.GL_DEBUG_SOURCE_API_ARB: b.append("[API - "); break; + case ARBDebugOutput.GL_DEBUG_SOURCE_APPLICATION_ARB: b.append("[APPLICATION - "); break; + default: + case ARBDebugOutput.GL_DEBUG_SOURCE_OTHER_ARB: b.append("[OTHER - "); break; + case ARBDebugOutput.GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: b.append("[SHADER COMPILER - "); break; + case ARBDebugOutput.GL_DEBUG_SOURCE_THIRD_PARTY_ARB: b.append("[THIRD PARTY - "); break; + } + switch(arg1) { + case ARBDebugOutput.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: b.append("DEPRECATED BEHAVIOR] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_ERROR_ARB: b.append("ERROR] "); break; + default: + case ARBDebugOutput.GL_DEBUG_TYPE_OTHER_ARB: b.append("OTHER] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_PERFORMANCE_ARB: b.append("PERFORMANCE] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_PORTABILITY_ARB: b.append("PORTABILITY] "); break; + case ARBDebugOutput.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: b.append("UNDEFINED BEHAVIOR] "); break; + } + switch(arg3) { + default: + case ARBDebugOutput.GL_DEBUG_SEVERITY_LOW_ARB: b.append("[LOW Severity] "); break; + case ARBDebugOutput.GL_DEBUG_SEVERITY_MEDIUM_ARB: b.append("[MEDIUM Severity] "); break; + case ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB: b.append("[SEVERE] "); break; + } + b.append(arg4); + System.err.println(b.toString()); + if(arg3 == ARBDebugOutput.GL_DEBUG_SEVERITY_HIGH_ARB) { + throw new RuntimeException("GL_DEBUG_SEVERITY_HIGH_ARB was thrown"); + } + } + } + + })); + + try { + SoundSystemConfig.addLibrary(LibraryLWJGLOpenAL.class); + SoundSystemConfig.setCodec("mp3", CodecJLayerMP3.class); + ss = new SoundSystem(); + }catch(Throwable t) { + t.printStackTrace(); + } + } + public static final void destroyContext() { + Display.destroy(); + Keyboard.destroy(); + Mouse.destroy(); + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + eagler.dispose(); + } + }); + if(ss != null) { + ss.cleanup(); + } + AL.destroy(); + } + public static final boolean isWindows() { + return System.getProperty("os.name").toLowerCase().contains("windows"); + } + public static final boolean mouseNext() { + return Mouse.next(); + } + public static final int mouseGetEventButton() { + return Mouse.getEventButton(); + } + public static final boolean mouseGetEventButtonState() { + return Mouse.getEventButtonState(); + } + public static final boolean mouseIsButtonDown(int p1) { + return Mouse.isButtonDown(p1); + } + public static final int mouseGetEventDWheel() { + return Mouse.getDWheel(); + } + public static final void mouseSetCursorPosition(int x, int y) { + Mouse.setCursorPosition(x, y); + } + public static final void mouseSetGrabbed(boolean grabbed) { + Mouse.setGrabbed(grabbed); + } + public static final int mouseGetDX() { + return Mouse.getDX(); + } + public static final int mouseGetDY() { + return Mouse.getDY(); + } + public static final int mouseGetX() { + return Mouse.getX(); + } + public static final int mouseGetY() { + return Mouse.getY(); + } + public static final int mouseGetEventX() { + return Mouse.getEventX(); + } + public static final int mouseGetEventY() { + return Mouse.getEventY(); + } + public static final boolean keysNext() { + return Keyboard.next(); + } + public static final int getEventKey() { + return Keyboard.getEventKey(); + } + public static final char getEventChar() { + return Keyboard.getEventCharacter(); + } + public static final boolean getEventKeyState() { + return Keyboard.getEventKeyState(); + } + public static final boolean isKeyDown(int p1) { + return Keyboard.isKeyDown(p1); + } + public static final String getKeyName(int p1) { + return Keyboard.getKeyName(p1); + } + public static final void setFullscreen(boolean p1) { + try { + Display.setFullscreen(p1); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + public static final boolean shouldShutdown() { + return Display.isCloseRequested(); + } + public static final void updateDisplay() { + Display.update(); + } + public static final void setVSyncEnabled(boolean p1) { + Display.setVSyncEnabled(p1); + } + public static final void enableRepeatEvents(boolean b) { + Keyboard.enableRepeatEvents(b); + } + public static final boolean isFocused() { + return Display.isActive(); + } + public static final int getScreenWidth() { + return Display.getDisplayMode().getWidth(); + } + public static final int getScreenHeight() { + return Display.getDisplayMode().getHeight(); + } + public static final int getCanvasWidth() { + return daCanvas.getWidth(); + } + public static final int getCanvasHeight() { + return daCanvas.getHeight(); + } + public static final void setDisplaySize(int x, int y) { + try { + Display.setDisplayMode(new DisplayMode(x, y)); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + public static final void syncDisplay(int performanceToFps) { + Display.sync(performanceToFps); + } + + private static final Set rateLimitedAddresses = new HashSet(); + private static final Set blockedAddresses = new HashSet(); + + private static WebSocketClient clientSocket = null; + private static final Object socketSync = new Object(); + + private static LinkedList readPackets = new LinkedList(); + + private static class EaglerSocketClient extends WebSocketClient { + + private Exception currentException = null; + private boolean wasAbleToConnect = false; + private String serverUriString; + private boolean socketIsAlive = false; + + public EaglerSocketClient(URI serverUri, String str) throws IOException, InterruptedException { + super(serverUri); + this.setTcpNoDelay(true); + this.setConnectionLostTimeout(5); + System.out.println("[ws] connecting to "+serverUri.toString()); + rateLimitStatus = null; + if(!this.connectBlocking(5, TimeUnit.SECONDS)) { + synchronized(socketSync) { + if(rateLimitStatus == null) { + if(blockedAddresses.contains(str)) { + rateLimitStatus = RateLimit.BLOCKED; + }else if(rateLimitedAddresses.contains(str)) { + rateLimitStatus = RateLimit.FAILED_POSSIBLY_LOCKED; + }else { + rateLimitStatus = RateLimit.FAILED; + } + } + } + throw new IOException("could not connect socket", currentException); + } + serverUriString = str; + } + + @Override + public void onClose(int arg0, String arg1, boolean arg2) { + synchronized(socketSync) { + readPackets.clear(); + System.out.println("[ws] disconnecting - " + currentException); + currentException = null; + if(!wasAbleToConnect && rateLimitStatus == null) { + if(blockedAddresses.contains(serverUriString)) { + rateLimitStatus = RateLimit.LOCKED; + }else if(rateLimitedAddresses.contains(serverUriString)) { + rateLimitStatus = RateLimit.FAILED_POSSIBLY_LOCKED; + }else { + rateLimitStatus = RateLimit.FAILED; + } + }else if(!socketIsAlive && (blockedAddresses.contains(serverUriString) || rateLimitedAddresses.contains(serverUriString))) { + rateLimitStatus = RateLimit.LOCKED; + } + } + } + + @Override + public void onError(Exception arg0) { + currentException = arg0; + } + + @Override + public void onMessage(String arg0) { + wasAbleToConnect = true; + synchronized(socketSync) { + if(arg0.equalsIgnoreCase("BLOCKED")) { + rateLimitedAddresses.add(serverUriString); + if(rateLimitStatus == null) { + rateLimitStatus = RateLimit.BLOCKED; + } + }else if(arg0.equalsIgnoreCase("LOCKED")) { + blockedAddresses.add(serverUriString); + rateLimitedAddresses.add(serverUriString); + if(rateLimitStatus == null) { + rateLimitStatus = RateLimit.NOW_LOCKED; + } + } + } + this.close(); + currentException = null; + } + + @Override + public void onMessage(ByteBuffer arg0) { + wasAbleToConnect = true; + synchronized(socketSync) { + readPackets.add(arg0.array()); + } + currentException = null; + } + + @Override + public void onOpen(ServerHandshake arg0) { + System.out.println("[ws] connected."); + } + + } + + public static final boolean startConnection(String uri) { + if(clientSocket != null) { + clientSocket.close(); + } + rateLimitStatus = null; + try { + clientSocket = new EaglerSocketClient(new URI(uri), uri); + return true; + }catch(InterruptedException e) { + clientSocket = null; + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + public static final void endConnection() { + synchronized(socketSync) { + if(clientSocket.isOpen()) { + clientSocket.close(); + } + clientSocket = null; + readPackets.clear(); + } + } + public static final boolean connectionOpen() { + return clientSocket != null && clientSocket.isOpen(); + } + public static final void writePacket(byte[] packet) { + if(clientSocket != null && clientSocket.isOpen()) { + clientSocket.send(ByteBuffer.wrap(packet)); + } + } + public static final byte[] readPacket() { + synchronized(socketSync) { + if(!readPackets.isEmpty()) { + return readPackets.remove(0); + } + } + return null; + } + private static RateLimit rateLimitStatus = null; + public static enum RateLimit { + NONE, FAILED, BLOCKED, FAILED_POSSIBLY_LOCKED, LOCKED, NOW_LOCKED; + } + public static final RateLimit getRateLimitStatus() { + RateLimit l = rateLimitStatus; + rateLimitStatus = null; + return l; + } + public static final void logRateLimit(String addr, RateLimit l) { + synchronized(socketSync) { + if(l == RateLimit.LOCKED) { + blockedAddresses.add(addr); + }else { + rateLimitedAddresses.add(addr); + } + } + } + public static final RateLimit checkRateLimitHistory(String addr) { + synchronized(socketSync) { + if(blockedAddresses.contains(addr)) { + return RateLimit.LOCKED; + }else if(rateLimitedAddresses.contains(addr)) { + return RateLimit.BLOCKED; + }else { + return RateLimit.NONE; + } + } + } + public static final byte[] loadLocalStorage(String key) { + try { + File f = new File("_eagstorage."+key+".dat"); + byte[] b = new byte[(int)f.length()]; + FileInputStream s = new FileInputStream(f); + s.read(b); + s.close(); + return b; + } catch (IOException e) { + return null; + } + } + public static final void saveLocalStorage(String key, byte[] data) { + try { + FileOutputStream f = new FileOutputStream(new File("_eagstorage."+key+".dat")); + f.write(data); + f.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + public static final void openLink(String url) { + try { + Class var3 = Class.forName("java.awt.Desktop"); + Object var4 = var3.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]); + var3.getMethod("browse", new Class[] { URI.class }).invoke(var4, new Object[] { new URI(url) }); + } catch (Throwable var5) { + var5.printStackTrace(); + } + } + private static volatile boolean fileChooserOpen = false; + private static volatile byte[] fileChooserFile = null; + private static volatile String fileChooserName = null; + public static final void openFileChooser(final String ext, final String mime) { + EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + if(!fileChooserOpen) { + fileChooserOpen = true; + try { + JFileChooser yee = new JFileChooser(new File(System.getProperty("user.home"))); + yee.setDialogTitle("select a file"); + yee.setFileSelectionMode(JFileChooser.FILES_ONLY); + yee.setMultiSelectionEnabled(false); + yee.setFileFilter(new FileFilter() { + + @Override + public String getDescription() { + return ext+" files"; + } + + @Override + public boolean accept(File f) { + return f.isDirectory() || f.getName().endsWith("."+ext); + } + }); + if(yee.showOpenDialog(eagler) == JFileChooser.APPROVE_OPTION) { + File f = yee.getSelectedFile(); + fileChooserName = f.getName(); + try { + byte[] b = new byte[(int)f.length()]; + FileInputStream s = new FileInputStream(f); + s.read(b); + s.close(); + fileChooserFile = b; + } catch (IOException e) { + fileChooserFile = new byte[0]; + } + }else { + fileChooserFile = new byte[0]; + } + }catch(Throwable t) { + fileChooserFile = new byte[0]; + } + fileChooserOpen = false; + } + } + + }); + } + public static final byte[] getFileChooserResult() { + byte[] b = fileChooserFile; + fileChooserFile = null; + return b; + } + public static final String getFileChooserResultName() { + String s = fileChooserName; + fileChooserName = null; + return s; + } + public static final void setListenerPos(float x, float y, float z, float vx, float vy, float vz, float pitch, float yaw) { + float var11 = MathHelper.cos(-yaw * 0.017453292F - (float) Math.PI); + float var12 = MathHelper.sin(-yaw * 0.017453292F - (float) Math.PI); + float var13 = -var12; + float var14 = -MathHelper.sin(-pitch * 0.017453292F - (float) Math.PI); + float var15 = -var11; + float var16 = 0.0F; + float var17 = 1.0F; + float var18 = 0.0F; + ss.setListenerPosition(x, y, z); + ss.setListenerOrientation(var13, var14, var15, var16, var17, var18); + ss.setListenerVelocity(vx, vy, vz); + } + public static final void setPlaybackOffsetDelay(float f) { + // nah + } + private static int playbackId = 0; + public static final int beginPlayback(String fileName, float x, float y, float z, float volume, float pitch) { + int id = ++playbackId; + URL loc = null; + if((loc = getResourceURL(fileName)) != null) { + String name = "sound_"+id; + float var8 = 16.0F; + if (volume > 1.0F) { + var8 *= volume; + } + ss.newSource(false, name, loc, fileName, false, x, y, z, 2, var8); + ss.setTemporary(name, true); + ss.setPitch(name, pitch); + ss.setVolume(name, volume); + ss.play(name); + }else { + System.err.println("unknown sound event "+fileName); + } + return id; + } + public static final int beginPlaybackStatic(String fileName, float volume, float pitch) { + int id = ++playbackId; + URL loc = null; + if((loc = getResourceURL(fileName)) != null) { + String name = "sound_"+id; + ss.newSource(false, name, loc, fileName, false, 0f, 0f, 0f, 0, 0f); + ss.setTemporary(name, true); + ss.setPitch(name, pitch); + ss.setVolume(name, volume); + ss.play(name); + }else { + System.err.println("unknown sound event "+fileName); + } + return id; + } + private static URL getResourceURL(String path) { + try { + File f = new File("resources", path); + if(f.exists()) { + return f.toURI().toURL(); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + public static final void setPitch(int id, float pitch) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.setPitch(name, pitch); + } + } + public static final void setVolume(int id, float volume) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.setVolume(name, volume); + } + } + public static final void moveSound(int id, float x, float y, float z, float vx, float vy, float vz) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.setPosition(name, x, y, z); + ss.setVelocity(name, vx, vy, vz); + } + } + public static final void endSound(int id) { + String name = "sound_"+id; + if(ss.playing(name)) { + ss.stop(name); + } + } + public static final boolean isPlaying(int id) { + return ss.playing("sound_"+id); + } + public static final void openConsole() { + EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + JOptionPane.showMessageDialog(eagler, "not supported in lwjgl runtime", "eaglercraft", JOptionPane.ERROR_MESSAGE); + } + + }); + } + private static boolean connected = false; + public static final void voiceConnect(String channel) { + connected = true; + } + public static final void voiceVolume(float volume) { + + } + public static final boolean voiceActive() { + return connected; + } + public static final boolean voiceRelayed() { + return connected; + } + public static final String[] voiceUsers() { + return new String[0]; + } + public static final String[] voiceUsersTalking() { + return new String[0]; + } + public static final void voiceEnd() { + connected = false; + } + public static final void doJavascriptCoroutines() { + + } + public static final long maxMemory() { + return Runtime.getRuntime().maxMemory(); + } + public static final long totalMemory() { + return Runtime.getRuntime().totalMemory(); + } + public static final long freeMemory() { + return Runtime.getRuntime().freeMemory(); + } + public static final void exit() { + Runtime.getRuntime().halt(0); + } + public static final int _wArrayByteLength(Object obj) { + return ((IntBuffer)obj).remaining() * 4; + } + public static final Object _wCreateLowLevelIntBuffer(int len) { + return ByteBuffer.allocateDirect(len*4).order(ByteOrder.nativeOrder()).asIntBuffer(); + } + + private static final IntBuffer appendbuffer = (IntBuffer) _wCreateLowLevelIntBuffer(525000); + + public static final void _wAppendLowLevelBuffer(Object arr) { + if(appendbuffer.limit() != appendbuffer.capacity()) appendbuffer.clear(); + IntBuffer a = (IntBuffer)arr; + if(appendbuffer.remaining() >= a.remaining()) { + appendbuffer.put(a); + } + } + + public static final Object _wGetLowLevelBuffersAppended() { + appendbuffer.flip(); + return appendbuffer; + } + + public static final String getUserAgent() { + return System.getProperty("os.name"); + } + + public static final String getClipboard() { + try { + return (String)Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor); + } catch (HeadlessException | UnsupportedFlavorException | IOException e) { + return null; + } + } + + public static final void setClipboard(String str) { + StringSelection selection = new StringSelection(str); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(selection, selection); + } + + public static final void saveScreenshot() { + + } + + private static class ServerQueryImpl extends WebSocketClient implements ServerQuery { + + private final LinkedList queryResponses = new LinkedList(); + private final LinkedList queryResponsesBytes = new LinkedList(); + private final String type; + private boolean open; + private boolean alive; + private String serverUri; + + private ServerQueryImpl(String type, URI serverUri, String serverUriString) throws IOException { + super(serverUri); + this.serverUri = serverUriString; + this.type = type; + this.open = true; + this.alive = false; + this.setConnectionLostTimeout(5); + this.setTcpNoDelay(true); + this.connect(); + } + + @Override + public int responseAvailable() { + synchronized(queryResponses) { + return queryResponses.size(); + } + } + + @Override + public int responseBinaryAvailable() { + synchronized(queryResponsesBytes) { + return queryResponsesBytes.size(); + } + } + + @Override + public QueryResponse getResponse() { + synchronized(queryResponses) { + return queryResponses.size() > 0 ? queryResponses.remove(0) : null; + } + } + + @Override + public byte[] getBinaryResponse() { + synchronized(queryResponsesBytes) { + return queryResponsesBytes.size() > 0 ? queryResponsesBytes.remove(0) : null; + } + } + + @Override + public void onClose(int arg0, String arg1, boolean arg2) { + open = false; + if(!alive) { + synchronized(socketSync) { + if(EaglerAdapterImpl2.blockedAddresses.contains(serverUri)) { + queryResponses.add(new QueryResponse(true)); + }else if(EaglerAdapterImpl2.rateLimitedAddresses.contains(serverUri)) { + queryResponses.add(new QueryResponse(false)); + } + } + } + } + + @Override + public void onError(Exception arg0) { + System.err.println("WebSocket query error: " + arg0.toString()); + open = false; + this.close(); + } + + @Override + public void onMessage(String arg0) { + this.alive = true; + synchronized(queryResponses) { + if(arg0.equalsIgnoreCase("BLOCKED")) { + synchronized(socketSync) { + EaglerAdapterImpl2.rateLimitedAddresses.add(serverUri); + queryResponses.add(new QueryResponse(false)); + } + this.close(); + return; + }else if(arg0.equalsIgnoreCase("LOCKED")) { + synchronized(socketSync) { + EaglerAdapterImpl2.blockedAddresses.add(serverUri); + queryResponses.add(new QueryResponse(true)); + } + this.close(); + return; + }else { + try { + QueryResponse q = new QueryResponse(new JSONObject(arg0)); + if(q.rateLimitStatus != null) { + synchronized(socketSync) { + if(q.rateLimitStatus == RateLimit.BLOCKED) { + EaglerAdapterImpl2.rateLimitedAddresses.add(serverUri); + }else if(q.rateLimitStatus == RateLimit.LOCKED) { + EaglerAdapterImpl2.blockedAddresses.add(serverUri); + } + } + this.close(); + } + queryResponses.add(q); + }catch(Throwable t) { + System.err.println("Query response parse error: " + t.toString()); + } + } + } + } + + @Override + public void onMessage(ByteBuffer arg0) { + this.alive = true; + synchronized(queryResponsesBytes) { + byte[] pkt = new byte[arg0.limit()]; + arg0.get(pkt); + queryResponsesBytes.add(pkt); + } + } + + @Override + public void onOpen(ServerHandshake arg0) { + send("Accept: " + type); + } + + @Override + public boolean isQueryOpen() { + return open; + } + + } + + public static final ServerQuery openQuery(String type, String uri) { + try { + return new ServerQueryImpl(type, new URI(uri), uri); + }catch(Throwable t) { + System.err.println("WebSocket query error: " + t.toString()); + return null; + } + } + + private static String serverToJoinOnLaunch = null; + + public static final void setServerToJoinOnLaunch(String s) { + serverToJoinOnLaunch = s; + } + + public static final String getServerToJoinOnLaunch() { + return serverToJoinOnLaunch; + } + +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/Tessellator.java b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/Tessellator.java new file mode 100644 index 0000000..f65c4e7 --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/Tessellator.java @@ -0,0 +1,384 @@ +package net.lax1dude.eaglercraft.adapter; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.src.MathHelper; + +public class Tessellator { + + /** The byte buffer used for GL allocation. */ + private ByteBuffer byteBuffer; + private IntBuffer intBuffer; + + /** Raw integer array. */ + private int[] rawBuffer; + + /** + * The number of vertices to be drawn in the next draw call. Reset to 0 between + * draw calls. + */ + private int vertexCount = 0; + + /** The first coordinate to be used for the texture. */ + private double textureU; + + /** The second coordinate to be used for the texture. */ + private double textureV; + private int brightness; + + /** The color (RGBA) value to be used for the following draw call. */ + private int color; + + /** + * Whether the current draw object for this tessellator has color values. + */ + private boolean hasColor = false; + + /** + * Whether the current draw object for this tessellator has texture coordinates. + */ + private boolean hasTexture = false; + private boolean hasBrightness = false; + + /** + * Whether the current draw object for this tessellator has normal values. + */ + private boolean hasNormals = false; + + /** The index into the raw buffer to be used for the next data. */ + private int rawBufferIndex = 0; + + /** + * The number of vertices manually added to the given draw call. This differs + * from vertexCount because it adds extra vertices when converting quads to + * triangles. + */ + private int addedVertices = 0; + + /** Disables all color information for the following draw call. */ + private boolean isColorDisabled = false; + + /** The draw mode currently being used by the tessellator. */ + private int drawMode; + + /** + * An offset to be applied along the x-axis for all vertices in this draw call. + */ + private double xOffset; + + /** + * An offset to be applied along the y-axis for all vertices in this draw call. + */ + private double yOffset; + + /** + * An offset to be applied along the z-axis for all vertices in this draw call. + */ + private double zOffset; + + /** The normal to be applied to the face being drawn. */ + private int normal; + + /** The static instance of the Tessellator. */ + public static final Tessellator instance = new Tessellator(525000); + + /** Whether this tessellator is currently in draw mode. */ + private boolean isDrawing = false; + + /** Whether we are currently using VBO or not. */ + private boolean useVBO = false; + + /** The size of the buffers used (in integers). */ + private int bufferSize; + + private Tessellator(int par1) { + this.bufferSize = par1; + this.byteBuffer = ByteBuffer.allocateDirect(par1 * 4).order(ByteOrder.nativeOrder()); + this.intBuffer = this.byteBuffer.asIntBuffer(); + this.rawBuffer = new int[par1]; + this.useVBO = false;// tryVBO && GLContext.getCapabilities().GL_ARB_vertex_buffer_object; + + //if (this.useVBO) { + //this.vertexBuffers = GLAllocation.createDirectIntBuffer(this.vboCount); + //ARBVertexBufferObject.glGenBuffersARB(this.vertexBuffers); + //} + } + + /** + * Draws the data set up in this tessellator and resets the state to prepare for + * new drawing. + */ + public int draw() { + if (!this.isDrawing) { + return 0; + } else { + this.isDrawing = false; + + if (this.vertexCount > 0) { + IntBuffer up = null; + this.intBuffer.clear(); + this.intBuffer.put(rawBuffer, 0, this.rawBufferIndex); + this.intBuffer.flip(); + up = this.intBuffer; + + if (this.hasTexture) { + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + } + + if (this.hasColor) { + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_COLOR_ARRAY); + } + + if (this.hasNormals) { + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_NORMAL_ARRAY); + } + + if (this.hasBrightness) { + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE1); + EaglerAdapter.glEnableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE0); + } + + EaglerAdapter.glDrawArrays(this.drawMode, 0, this.vertexCount, up); + + if (this.hasTexture) { + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + } + + if (this.hasColor) { + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_COLOR_ARRAY); + } + + if (this.hasNormals) { + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_NORMAL_ARRAY); + } + + if (this.hasBrightness) { + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE1); + EaglerAdapter.glDisableVertexAttrib(EaglerAdapter.GL_TEXTURE_COORD_ARRAY); + EaglerAdapter.glClientActiveTexture(EaglerAdapter.GL_TEXTURE0); + } + } + + int var1 = this.rawBufferIndex * 4; + this.reset(); + return var1; + } + } + + /** + * Clears the tessellator state in preparation for new drawing. + */ + private void reset() { + this.vertexCount = 0; + this.rawBufferIndex = 0; + this.addedVertices = 0; + } + + /** + * Sets draw mode in the tessellator to draw quads. + */ + public void startDrawingQuads() { + this.startDrawing(EaglerAdapter.GL_QUADS); + } + + /** + * Resets tessellator state and prepares for drawing (with the specified draw + * mode). + */ + public void startDrawing(int par1) { + if (this.isDrawing) { + this.draw(); + } + this.isDrawing = true; + this.reset(); + this.drawMode = par1; + this.hasNormals = false; + this.hasColor = false; + this.hasTexture = false; + this.hasBrightness = false; + this.isColorDisabled = false; + } + + /** + * Sets the texture coordinates. + */ + public void setTextureUV(double par1, double par3) { + this.hasTexture = true; + this.textureU = par1; + this.textureV = par3; + } + + public void setBrightness(int par1) { + this.hasBrightness = true; + this.brightness = par1; + } + + /** + * Sets the RGB values as specified, converting from floats between 0 and 1 to + * integers from 0-255. + */ + public void setColorOpaque_F(float par1, float par2, float par3) { + this.setColorOpaque((int) (par1 * 255.0F), (int) (par2 * 255.0F), (int) (par3 * 255.0F)); + } + + /** + * Sets the RGBA values for the color, converting from floats between 0 and 1 to + * integers from 0-255. + */ + public void setColorRGBA_F(float par1, float par2, float par3, float par4) { + this.setColorRGBA((int) (par1 * 255.0F), (int) (par2 * 255.0F), (int) (par3 * 255.0F), (int) (par4 * 255.0F)); + } + + /** + * Sets the RGB values as specified, and sets alpha to opaque. + */ + public void setColorOpaque(int par1, int par2, int par3) { + this.setColorRGBA(par1, par2, par3, 255); + } + + /** + * Sets the RGBA values for the color. Also clamps them to 0-255. + */ + public void setColorRGBA(int par1, int par2, int par3, int par4) { + if (!this.isColorDisabled) { + if (par1 > 255) { + par1 = 255; + } + + if (par2 > 255) { + par2 = 255; + } + + if (par3 > 255) { + par3 = 255; + } + + if (par4 > 255) { + par4 = 255; + } + + if (par1 < 0) { + par1 = 0; + } + + if (par2 < 0) { + par2 = 0; + } + + if (par3 < 0) { + par3 = 0; + } + + if (par4 < 0) { + par4 = 0; + } + + this.hasColor = true; + this.color = par4 << 24 | par3 << 16 | par2 << 8 | par1; + } + } + + /** + * Adds a vertex specifying both x,y,z and the texture u,v for it. + */ + public void addVertexWithUV(double par1, double par3, double par5, double par7, double par9) { + this.setTextureUV(par7, par9); + this.addVertex(par1, par3, par5); + } + + /** + * Adds a vertex with the specified x,y,z to the current draw call. It will + * trigger a draw() if the buffer gets full. + */ + public void addVertex(double par1, double par3, double par5) { + if(this.addedVertices > 65534) return; + ++this.addedVertices; + + this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float) (par1 + this.xOffset)); + this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float) (par3 + this.yOffset)); + this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float) (par5 + this.zOffset)); + + if (this.hasTexture) { + this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float) this.textureU); + this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float) this.textureV); + } + + if (this.hasColor) { + this.rawBuffer[this.rawBufferIndex + 5] = this.color; + } + + if (this.hasNormals) { + this.rawBuffer[this.rawBufferIndex + 6] = this.normal; + } + + if (this.hasBrightness) { + this.rawBuffer[this.rawBufferIndex + 7] = this.brightness; + } + + this.rawBufferIndex += 8; + ++this.vertexCount; + } + + /** + * Sets the color to the given opaque value (stored as byte values packed in an + * integer). + */ + public void setColorOpaque_I(int par1) { + int var2 = par1 >> 16 & 255; + int var3 = par1 >> 8 & 255; + int var4 = par1 & 255; + this.setColorOpaque(var2, var3, var4); + } + + /** + * Sets the color to the given color (packed as bytes in integer) and alpha + * values. + */ + public void setColorRGBA_I(int par1, int par2) { + int var3 = par1 >> 16 & 255; + int var4 = par1 >> 8 & 255; + int var5 = par1 & 255; + this.setColorRGBA(var3, var4, var5, par2); + } + + /** + * Disables colors for the current draw call. + */ + public void disableColor() { + this.isColorDisabled = true; + } + + /** + * Sets the normal for the current draw call. + */ + public void setNormal(float par1, float par2, float par3) { + this.hasNormals = true; + float len = (float) Math.sqrt(par1 * par1 + par2 * par2 + par3 * par3); + int var4 = (int)((par1 / len) * 127.0F) + 127; + int var5 = (int)((par2 / len) * 127.0F) + 127; + int var6 = (int)((par3 / len) * 127.0F) + 127; + this.normal = var4 & 255 | (var5 & 255) << 8 | (var6 & 255) << 16; + } + + /** + * Sets the translation for all vertices in the current draw call. + */ + public void setTranslation(double par1, double par3, double par5) { + this.xOffset = par1; + this.yOffset = par3; + this.zOffset = par5; + } + + /** + * Offsets the translation for all vertices in the current draw call. + */ + public void addTranslation(float par1, float par2, float par3) { + this.xOffset += (double) par1; + this.yOffset += (double) par2; + this.zOffset += (double) par3; + } +} diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/lwjgl/GameWindowListener.java b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/lwjgl/GameWindowListener.java new file mode 100644 index 0000000..6356c79 --- /dev/null +++ b/src/lwjgl/java/net/lax1dude/eaglercraft/adapter/lwjgl/GameWindowListener.java @@ -0,0 +1,12 @@ +package net.lax1dude.eaglercraft.adapter.lwjgl; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import net.minecraft.client.Minecraft; + +public final class GameWindowListener extends WindowAdapter { + public void windowClosing(WindowEvent par1WindowEvent) { + Minecraft.getMinecraft().shutdown(); + } +} diff --git a/src/lwjgl/java/paulscode/sound/Channel.java b/src/lwjgl/java/paulscode/sound/Channel.java new file mode 100644 index 0000000..af0efa4 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Channel.java @@ -0,0 +1,270 @@ +package paulscode.sound; + +import java.util.LinkedList; +import javax.sound.sampled.AudioFormat; + +/** + * The Channel class is the base class which can be extended for + * library-specific channels. It is also used in the "no-sound" library. + * A channel is a reserved sound-card voice through which sources are played + * back. Channels can be either streaming channels or normal (non-streaming) + * ones. For consistant naming conventions, each sub-class should have the + * name prefix "Channel". + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Channel +{ +/** + * The library class associated with this type of channel. + */ + protected Class libraryType = Library.class; + +/** + * Global identifier for the type of channel (normal or streaming). Possible + * values for this varriable can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + */ + public int channelType; + +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Whatever source is attached to this channel. + */ + public Source attachedSource = null; + +/** + * Cumulative counter of the buffers played then unqued. + */ + public int buffersUnqueued = 0; + +/** + * Constructor: Takes channelType identifier as a paramater. Possible values + * for channel type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel (normal or streaming). + */ + public Channel( int type ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + channelType = type; + } + +/** + * Shuts the channel down and removes references to all instantiated objects. + */ + public void cleanup() + { + logger = null; + } + +/** + * Queues up the initial byte[] buffers of data to be streamed. + * @param bufferList List of the first buffers to be played for a streaming source. + * @return False if an error occurred or if end of stream was reached. + */ + public boolean preLoadBuffers( LinkedList bufferList ) + { + return true; + } + +/** + * Queues up a byte[] buffer of data to be streamed. + * @param buffer The next buffer to be played for a streaming source. + * @return False if an error occurred or if the channel is shutting down. + */ + public boolean queueBuffer( byte[] buffer ) + { + return false; + } + +/** + * Feeds raw data to the stream. + * @param buffer Buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed. + */ + public int feedRawAudioData( byte[] buffer ) + { + return 1; + } + +/** + * Returns the number of queued byte[] buffers that have finished playing. + * @return Number of buffers processed. + */ + public int buffersProcessed() + { + return 0; + } + +/** + * Calculates the number of milliseconds since the channel began playing. + * @return Milliseconds, or -1 if unable to calculate. + */ + public float millisecondsPlayed() + { + return -1; + } +/** + * Plays the next queued byte[] buffer. This method is run from the seperate + * {@link paulscode.sound.StreamThread StreamThread}. + * @return False when no more buffers are left to process. + */ + public boolean processBuffer() + { + return false; + } + +/** + * Sets the channel up to receive the specified audio format. + */ + public void setAudioFormat( AudioFormat audioFormat ) + {} + +/** + * Dequeues all previously queued data. + */ + public void flush() + {} + +/** + * Stops the channel, dequeues any queued data, and closes the channel. + */ + public void close() + {} + +/** + * Plays the currently attached normal source, opens this channel up for + * streaming, or resumes playback if this channel was paused. + */ + public void play() + {} + +/** + * Temporarily stops playback for this channel. + */ + public void pause() + {} + +/** + * Stops playback for this channel and rewinds the attached source to the + * beginning. + */ + public void stop() + {} + +/** + * Rewinds the attached source to the beginning. Stops the source if it was + * paused. + */ + public void rewind() + {} + +/** + * Used to determine if a channel is actively playing a source. This method + * will return false if the channel is paused or stopped and when no data is + * queued to be streamed. + * @return True if this channel is playing a source. + */ + public boolean playing() + { + return false; + } + +/** + * Returns the name of the class. + * @return "Channel" + library title. + */ + public String getClassName() + { + String libTitle = SoundSystemConfig.getLibraryTitle( libraryType ); + + if( libTitle.equals( "No Sound" ) ) + return "Channel"; + else + return "Channel" + libTitle; + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, getClassName(), message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( getClassName(), message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/CommandObject.java b/src/lwjgl/java/paulscode/sound/CommandObject.java new file mode 100644 index 0000000..11107af --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/CommandObject.java @@ -0,0 +1,603 @@ +package paulscode.sound; + +/** + * The CommandObject class is used to store arguments in the SoundSystem's + * Command Queue. Queued CommandObjects are then processed by the + * {@link paulscode.sound.CommandThread CommandThread}. Commands are queued + * and executed in the background, so it is unlikely that the user will ever + * need to use this class. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class CommandObject +{ +/** + * Global identifier for the command to initialize the current sound library. + */ + public static final int INITIALIZE = 1; +/** + * Global identifier for the command to pre-load a sound file. + */ + public static final int LOAD_SOUND = 2; +/** + * Global identifier for the command to pre-load a sound file. + */ + public static final int LOAD_DATA = 3; +/** + * Global identifier for the command to remove a sound file from memory. + */ + public static final int UNLOAD_SOUND = 4; +/** + * Global identifier for the command to queue a sound file. + */ + public static final int QUEUE_SOUND = 5; +/** + * Global identifier for the command to dequeue a sound file. + */ + public static final int DEQUEUE_SOUND = 6; +/** + * Global identifier for the command to fade-out transition a source. + */ + public static final int FADE_OUT = 7; +/** + * Global identifier for the command to fade-out/in transition a source. + */ + public static final int FADE_OUT_IN = 8; +/** + * Global identifier for the command to check volume levels of fading sources. + */ + public static final int CHECK_FADE_VOLUMES = 9; +/** + * Global identifier for the command to create a new source. + */ + public static final int NEW_SOURCE = 10; +/** + * Global identifier for the command to create a new raw data stream. + */ + public static final int RAW_DATA_STREAM = 11; +/** + * Global identifier for the command to create a source and immediately play it. + */ + public static final int QUICK_PLAY = 12; +/** + * Global identifier for the command to set a source's position in 3D space. + */ + public static final int SET_POSITION = 13; +/** + * Global identifier for the command to change a source's volume. + */ + public static final int SET_VOLUME = 14; +/** + * Global identifier for the command to change a source's pitch. + */ + public static final int SET_PITCH = 15; +/** + * Global identifier for the command to change a source's priority. + */ + public static final int SET_PRIORITY = 16; +/** + * Global identifier for the command to tell a source whether or not to loop. + */ + public static final int SET_LOOPING = 17; +/** + * Global identifier for the command to set a source's attenuation model. + */ + public static final int SET_ATTENUATION = 18; +/** + * Global identifier for the command to set a source's fade distance or rolloff + * factor. + */ + public static final int SET_DIST_OR_ROLL = 19; +/** + * Global identifier for the command to change the Doppler factor. + */ + public static final int CHANGE_DOPPLER_FACTOR = 20; +/** + * Global identifier for the command to change the Doppler velocity. + */ + public static final int CHANGE_DOPPLER_VELOCITY = 21; +/** + * Global identifier for the command to set a source's velocity. + */ + public static final int SET_VELOCITY = 22; +/** + * Global identifier for the command to set a source's velocity. + */ + public static final int SET_LISTENER_VELOCITY = 23; +/** + * Global identifier for the command to play a source. + */ + public static final int PLAY = 24; +/** + * Global identifier for the command to play a source. + */ + public static final int FEED_RAW_AUDIO_DATA = 25; +/** + * Global identifier for the command to pause a source. + */ + public static final int PAUSE = 26; +/** + * Global identifier for the command to stop a source. + */ + public static final int STOP = 27; +/** + * Global identifier for the command to rewind a source. + */ + public static final int REWIND = 28; +/** + * Global identifier for the command to flush all queued data. + */ + public static final int FLUSH = 29; +/** + * Global identifier for the command to cull a source. + */ + public static final int CULL = 30; +/** + * Global identifier for the command to activate a source. + */ + public static final int ACTIVATE = 31; +/** + * Global identifier for the command to set a source as permanant or temporary. + */ + public static final int SET_TEMPORARY = 32; +/** + * Global identifier for the command to delete a source. + */ + public static final int REMOVE_SOURCE = 33; +/** + * Global identifier for the command to move the listner. + */ + public static final int MOVE_LISTENER = 34; +/** + * Global identifier for the command to set the listener's position. + */ + public static final int SET_LISTENER_POSITION = 35; +/** + * Global identifier for the command to turn the listener. + */ + public static final int TURN_LISTENER = 36; +/** + * Global identifier for the command to set the listener's turn angle. + */ + public static final int SET_LISTENER_ANGLE = 37; +/** + * Global identifier for the command to change the listener's orientation. + */ + public static final int SET_LISTENER_ORIENTATION = 38; +/** + * Global identifier for the command to change the master volume. + */ + public static final int SET_MASTER_VOLUME = 39; +/** + * Global identifier for the command to create a new library. + */ + public static final int NEW_LIBRARY = 40; + +/** + * Any buffer required for a command. + */ + public byte[] buffer; +/** + * Any int arguments required for a command. + */ + public int[] intArgs; +/** + * Any float arguments required for a command. + */ + public float[] floatArgs; +/** + * Any long arguments required for a command. + */ + public long[] longArgs; +/** + * Any boolean arguments required for a command. + */ + public boolean[] boolArgs; +/** + * Any String arguments required for a command. + */ + public String[] stringArgs; + +/** + * Any Class arguments required for a command. + */ + public Class[] classArgs; + +/** + * Any Object arguments required for a command. + */ + public Object[] objectArgs; + +/** + * Which command to execute. + */ + public int Command; + +/** + * Constructor used to create a command which doesn't require any arguments. + * @param cmd Which command to execute. + */ + public CommandObject( int cmd ) + { + Command = cmd; + } +/** + * Constructor used to create a command which requires one integer argument. + * @param cmd Which command to execute. + * @param i The integer argument needed to execute this command. + */ + public CommandObject( int cmd, int i ) + { + Command = cmd; + intArgs = new int[1]; + intArgs[0] = i; + } +/** + * Constructor used to create a command which requires one Library Class + * argument. + * @param cmd Which command to execute. + * @param c The Library Class argument needed to execute this command. + */ + public CommandObject( int cmd, Class c ) + { + Command = cmd; + classArgs = new Class[1]; + classArgs[0] = c; + } +/** + * Constructor used to create a command which requires one float argument. + * @param cmd Which command to execute. + * @param f The float argument needed to execute this command. + */ + public CommandObject( int cmd, float f ) + { + Command = cmd; + floatArgs = new float[1]; + floatArgs[0] = f; + } +/** + * Constructor used to create a command which requires one String argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + */ + public CommandObject( int cmd, String s ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires one Object argument. + * @param cmd Which command to execute. + * @param o The Object argument needed to execute this command. + */ + public CommandObject( int cmd, Object o ) + { + Command = cmd; + objectArgs = new Object[1]; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires one String argument and + * one Object argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + */ + public CommandObject( int cmd, String s, Object o ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + objectArgs = new Object[1]; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires one String argument and + * one byte buffer argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param buff The byte buffer argument needed to execute this command. + */ + public CommandObject( int cmd, String s, byte[] buff ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + buffer = buff; + } +/** + * Constructor used to create a command which requires one String argument, one + * Object argument, and one long argument. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param l The long argument needed to execute this command. + */ + public CommandObject( int cmd, String s, Object o, long l ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + objectArgs = new Object[1]; + objectArgs[0] = o; + longArgs = new long[1]; + longArgs[0] = l; + } +/** + * Constructor used to create a command which requires one String argument, one + * Object argument, and two long arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param l1 The first long argument needed to execute this command. + * @param l2 The second long argument needed to execute this command. + */ + public CommandObject( int cmd, String s, Object o, long l1, long l2 ) + { + Command = cmd; + stringArgs = new String[1]; + stringArgs[0] = s; + objectArgs = new Object[1]; + objectArgs[0] = o; + longArgs = new long[2]; + longArgs[0] = l1; + longArgs[1] = l2; + } +/** + * Constructor used to create a command which requires two String arguments. + * @param cmd Which command to execute. + * @param s1 The first String argument needed to execute this command. + * @param s2 The second String argument needed to execute this command. + */ + public CommandObject( int cmd, String s1, String s2 ) + { + Command = cmd; + stringArgs = new String[2]; + stringArgs[0] = s1; + stringArgs[1] = s2; + } +/** + * Constructor used to create a command which requires a String and an int as + * arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param i The integer argument needed to execute this command. + */ + public CommandObject( int cmd, String s, int i ) + { + Command = cmd; + intArgs = new int[1]; + stringArgs = new String[1]; + intArgs[0] = i; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires a String and a float as + * arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param f The float argument needed to execute this command. + */ + public CommandObject( int cmd, String s, float f ) + { + Command = cmd; + floatArgs = new float[1]; + stringArgs = new String[1]; + floatArgs[0] = f; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires a String and a boolean + * as arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param b The boolean argument needed to execute this command. + */ + public CommandObject( int cmd, String s, boolean b ) + { + Command = cmd; + boolArgs = new boolean[1]; + stringArgs = new String[1]; + boolArgs[0] = b; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires three float arguments. + * @param cmd Which command to execute. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + */ + public CommandObject( int cmd, float f1, float f2, float f3 ) + { + Command = cmd; + floatArgs = new float[3]; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + } +/** + * Constructor used to create a command which a String and three float + * arguments. + * @param cmd Which command to execute. + * @param s The String argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + */ + public CommandObject( int cmd, String s, float f1, float f2, float f3 ) + { + Command = cmd; + floatArgs = new float[3]; + stringArgs = new String[1]; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + stringArgs[0] = s; + } +/** + * Constructor used to create a command which requires six float arguments. + * @param cmd Which command to execute. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + * @param f5 The fifth float argument needed to execute this command. + * @param f6 The sixth float argument needed to execute this command. + */ + public CommandObject( int cmd, float f1, float f2, float f3, float f4, + float f5, float f6 ) + { + Command = cmd; + floatArgs = new float[6]; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + floatArgs[4] = f5; + floatArgs[5] = f6; + } +/** + * Constructor used to create a command which requires several arguments. + * @param cmd Which command to execute. + * @param b1 The first boolean argument needed to execute this command. + * @param b2 The second boolean argument needed to execute this command. + * @param b3 The third boolean argument needed to execute this command. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param i The integer argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + */ + public CommandObject( int cmd, + boolean b1, boolean b2, boolean b3, + String s, Object o, + float f1, float f2, float f3, + int i, float f4 ) + { + Command = cmd; + intArgs = new int[1]; + floatArgs = new float[4]; + boolArgs = new boolean[3]; + stringArgs = new String[1]; + objectArgs = new Object[1]; + intArgs[0] = i; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + boolArgs[0] = b1; + boolArgs[1] = b2; + boolArgs[2] = b3; + stringArgs[0] = s; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires several arguments. + * @param cmd Which command to execute. + * @param b1 The first boolean argument needed to execute this command. + * @param b2 The second boolean argument needed to execute this command. + * @param b3 The third boolean argument needed to execute this command. + * @param s The String argument needed to execute this command. + * @param o The Object argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param i The integer argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + * @param b4 The fourth boolean argument needed to execute this command. + */ + public CommandObject( int cmd, + boolean b1, boolean b2, boolean b3, + String s, + Object o, + float f1, float f2, float f3, + int i, float f4, boolean b4 ) + { + Command = cmd; + intArgs = new int[1]; + floatArgs = new float[4]; + boolArgs = new boolean[4]; + stringArgs = new String[1]; + objectArgs = new Object[1]; + intArgs[0] = i; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + boolArgs[0] = b1; + boolArgs[1] = b2; + boolArgs[2] = b3; + boolArgs[3] = b4; + stringArgs[0] = s; + objectArgs[0] = o; + } +/** + * Constructor used to create a command which requires several arguments. + * @param cmd Which command to execute. + * @param o The Object argument needed to execute this command. + * @param b The first boolean argument needed to execute this command. + * @param s The String argument needed to execute this command. + * @param f1 The first float argument needed to execute this command. + * @param f2 The second float argument needed to execute this command. + * @param f3 The third float argument needed to execute this command. + * @param i The integer argument needed to execute this command. + * @param f4 The fourth float argument needed to execute this command. + */ + public CommandObject( int cmd, + Object o, + boolean b, + String s, + float f1, float f2, float f3, + int i, + float f4 ) + { + Command = cmd; + intArgs = new int[1]; + floatArgs = new float[4]; + boolArgs = new boolean[1]; + stringArgs = new String[1]; + objectArgs = new Object[1]; + intArgs[0] = i; + floatArgs[0] = f1; + floatArgs[1] = f2; + floatArgs[2] = f3; + floatArgs[3] = f4; + boolArgs[0] = b; + stringArgs[0] = s; + objectArgs[0] = o; + } +} diff --git a/src/lwjgl/java/paulscode/sound/CommandThread.java b/src/lwjgl/java/paulscode/sound/CommandThread.java new file mode 100644 index 0000000..982e6fa --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/CommandThread.java @@ -0,0 +1,176 @@ +package paulscode.sound; + +/** + * The CommandThread class is designed to move all command processing into a + * single thread to be run in the background and avoid conflicts between + * threads. Commands are processed in the order that they were queued. The + * arguements for each command are stored in a + * {@link paulscode.sound.CommandObject CommandObject}. The Command Queue is + * located in the {@link paulscode.sound.SoundSystem SoundSystem} class. + * Calling kill() stops the thread, and this should be immediatly followed + * by a call to interrupt() to wake up the thread so it may end. This class + * also checks for temporary sources that are finished playing, and removes + * them. + * + * NOTE: The command thread is created automatically by the sound system, so it + * is unlikely that the user would ever need to use this class. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class CommandThread extends SimpleThread +{ +/** + * Processes status messages, warnings, and error messages. + */ + protected SoundSystemLogger logger; + +/** + * Handle to the Sound System. This is where the Command Queue is located. + */ + private SoundSystem soundSystem; + +/** + * Name of this class. + */ + protected String className = "CommandThread"; + +/** + * Constructor: Takes a handle to the SoundSystem object as a parameter. + * @param s Handle to the SoundSystem. +*/ + public CommandThread( SoundSystem s ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + soundSystem = s; + } + +/** + * Shuts the thread down and removes references to all instantiated objects. + * NOTE: Method alive() will return false when cleanup() has finished. + */ + @Override + protected void cleanup() + { + kill(); + + logger = null; + soundSystem = null; + + super.cleanup(); // Important! + } + +/** + * The main loop for processing commands. The Command Thread starts out + * asleep, and it sleeps again after it finishes processing commands, so it + * must be interrupted when commands are queued for processing. + */ + @Override + public void run() + { + long previousTime = System.currentTimeMillis(); + long currentTime = previousTime; + + if( soundSystem == null ) + { + errorMessage( "SoundSystem was null in method run().", 0 ); + cleanup(); + return; + } + + // Start out asleep: + snooze( 3600000 ); + + while( !dying() ) + { + // Perform user-specific source management: + soundSystem.ManageSources(); + + // Process all queued commands: + soundSystem.CommandQueue( null ); + + // Remove temporary sources every ten seconds: + currentTime = System.currentTimeMillis(); + if( (!dying()) && ((currentTime - previousTime) > 10000) ) + { + previousTime = currentTime; + soundSystem.removeTemporarySources(); + } + + // Wait for more commands: + if( !dying() ) + snooze( 3600000 ); + } + + cleanup(); // Important! + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message, int indent ) + { + logger.message( message, indent ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message, int indent ) + { + logger.importantMessage( message, indent ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, className, message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message, int indent ) + { + logger.errorMessage( className, message, indent ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/FilenameURL.java b/src/lwjgl/java/paulscode/sound/FilenameURL.java new file mode 100644 index 0000000..96b48dc --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/FilenameURL.java @@ -0,0 +1,153 @@ +package paulscode.sound; + +import java.net.URL; + +/** + * The FilenameURL class is designed to associate a String filename/identifier + * with a URL. Handles either case where user supplies a String path or user + * supplies a URL instance. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class FilenameURL +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Filename or identifier for the file. + */ + private String filename = null; + +/** + * URL interface to the file. + */ + private URL url = null; + +/** + * Constructor: Saves handles to the url and identifier. The identifier should + * look like a filename, and it must have the correct extension so SoundSystem + * knows what format to use for the file referenced by the URL instance. + * @param url URL interface to a file. + * @param identifier Identifier (filename) for the file. + */ + public FilenameURL( URL url, String identifier ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + filename = identifier; + this.url = url; + } + +/** + * Constructor: Saves a handle to the filename (used later to generate a URL + * instance). The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL names. + * @param filename Name of the file. + */ + public FilenameURL( String filename ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + this.filename = filename; + url = null; + } + +/** + * Returns the filename/identifier. + * @return Filename or identifier for the file. + */ + public String getFilename() + { + return filename; + } + +/** + * Returns the URL interface to the file. If a URL was not originally specified + * in the constructor, then the first time this method is called it creates a + * URL instance using the previously specified filename. + * @return URL interface to the file. + */ + public URL getURL() + { + if( url == null ) + { + // Check if the file is online or inside the JAR: + if( filename.matches( SoundSystemConfig.PREFIX_URL ) ) + { + // Online + try + { + url = new URL( filename ); + } + catch( Exception e ) + { + errorMessage( "Unable to access online URL in " + + "method 'getURL'" ); + printStackTrace( e ); + return null; + } + } + else + { + // Inside the JAR + url = getClass().getClassLoader().getResource( + SoundSystemConfig.getSoundFilesPackage() + filename ); + } + } + return url; + } + +/** + * Prints an error message. + * @param message Message to print. + */ + private void errorMessage( String message ) + { + logger.errorMessage( "MidiChannel", message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + private void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/ICodec.java b/src/lwjgl/java/paulscode/sound/ICodec.java new file mode 100644 index 0000000..9385445 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/ICodec.java @@ -0,0 +1,119 @@ +package paulscode.sound; + +import java.net.URL; +import javax.sound.sampled.AudioFormat; + +/** + * The ICodec interface provides a common interface for SoundSystem to use + * for accessing external codec libraries. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public interface ICodec +{ +/** + * Should tell derived classes when they may need to reverse the byte order of + * the data before returning it in the read() and readAll() methods. The + * reason for the reversBytOrder method is because some external codec + * libraries produce audio data in a format that some external audio libraries + * require to be reversed. Derivatives of the Library and Source classes for + * audio libraries which require this type of data to be reversed should call + * the reverseByteOrder() method for all instances of ICodec that they use. + * Derivatives of the ICodec interface for codec libraries which which produce + * this type of data should use the reverseByteOrder() method to know when the + * data needs to be reversed before returning it in the read() and readAll() + * methods. If a particular codec library does not produce this type of data, + * its derived ICodec class may disregard any calls to the reverseByteOrder() + * method. + * @param b True if the calling audio library requires byte-reversal by some codec libraries. + */ + public void reverseByteOrder( boolean b ); + +/** + * Should make any preperations required before reading from the audio stream. + * If another stream is already opened, it should be closed and a new audio + * stream opened in its place. This method is used internally by SoundSystem + * not only to initialize a stream, but also to rewind streams and to switch + * stream sources on the fly. + * @return False if an error occurred or if end of stream was reached. + */ + public boolean initialize( URL url ); + +/** + * Should return false if the stream is busy initializing. To prevent bad + * data from being returned by this method, derived classes should internally + * synchronize with any elements used by both the initialized() and initialize() + * methods. + * @return True if steam is initialized. + */ + public boolean initialized(); + +/** + * Should read in one stream buffer worth of audio data. See + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about accessing and changing default settings. + * @return The audio data wrapped into a SoundBuffer context. + */ + public SoundBuffer read(); + +/** + * Should read in all the audio data from the stream (up to the default + * "maximum file size". See + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about accessing and changing default settings. + * @return the audio data wrapped into a SoundBuffer context. + */ + public SoundBuffer readAll(); + +/** + * Should return false if there is still more data available to be read in. To + * prevent bad data from being returned by this method, derived classes should + * internally synchronize with any elements used in both the endOfStream() and + * the read() or readAll() methods. + * @return True if end of stream was reached. + */ + public boolean endOfStream(); + +/** + * Should close any open streams and remove references to all instantiated + * objects. + */ + public void cleanup(); + +/** + * Should return the audio format of the data being returned by the read() and + * readAll() methods. + * @return Information wrapped into an AudioFormat context. + */ + public AudioFormat getAudioFormat(); +} diff --git a/src/lwjgl/java/paulscode/sound/IStreamListener.java b/src/lwjgl/java/paulscode/sound/IStreamListener.java new file mode 100644 index 0000000..6f767f4 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/IStreamListener.java @@ -0,0 +1,11 @@ +package paulscode.sound; + +public interface IStreamListener +{ + /** + * Notifies implementation that an End Of Stream was reached. + * @param sourcename String identifier of the source which reached the EOS. + * @param queueSize Number of items left the the stream's play queue, or zero if none. + */ + public void endOfStream( String sourcename, int queueSize ); +} diff --git a/src/lwjgl/java/paulscode/sound/Library.java b/src/lwjgl/java/paulscode/sound/Library.java new file mode 100644 index 0000000..79011db --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Library.java @@ -0,0 +1,1615 @@ +package paulscode.sound; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import javax.sound.sampled.AudioFormat; + +/** + * The Library class is the class from which all library types are extended. + * It provides generic methods for interfacing with the audio libraries + * supported by the SoundSystem. Specific libraries should extend this class + * and override the necessary methods. For consistant naming conventions, each + * sub-class should have the name prefix "Library". + * + * This class may also be used as the "No Sound Library" (i.e. silent mode) if + * no other audio libraries are supported by the host machine, or to mute all + * sound. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Library +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Position and orientation of the listener. + */ + protected ListenerData listener; + +/** + * Map containing sound file data for easy lookup by filename / identifier. + */ + protected HashMap bufferMap = null; + +/** + * Map containing all created sources for easy look-up by name. + */ + protected HashMap sourceMap; // (name, source data) pairs + +/** + * Interface through which MIDI files can be played. + */ + private MidiChannel midiChannel; + +/** + * Array containing maximum number of non-streaming audio channels. + */ + protected List streamingChannels; + +/** + * Array containing maximum number of non-streaming audio channels. + */ + protected List normalChannels; + +/** + * Source name last played on each streaming channel. + */ + private String[] streamingChannelSourceNames; + +/** + * Source name last played on each non-streaming channel. + */ + private String[] normalChannelSourceNames; + +/** + * Increments through the steaming channel list as new sources are played. + */ + private int nextStreamingChannel = 0; + +/** + * Increments through the non-steaming channel list as new sources are played. + */ + private int nextNormalChannel = 0; + +/** + * Handles processing for all streaming sources. + */ + protected StreamThread streamThread; + +/** + * Whether or not the library requires reversal of audio data byte order. + */ + protected boolean reverseByteOrder = false; + +/** + * Constructor: Instantiates the source map and listener information. NOTES: + * The 'super()' method should be at the top of constructors for all extended + * classes. The varriable 'libraryType' should be given a new value in the + * constructors for all extended classes. + */ + public Library() throws SoundSystemException + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // instantiate the buffer map: + bufferMap = new HashMap(); + + // instantiate the source map: + sourceMap = new HashMap(); + + listener = new ListenerData( 0.0f, 0.0f, 0.0f, // position + 0.0f, 0.0f, -1.0f, // look-at direction + 0.0f, 1.0f, 0.0f, // up direction + 0.0f ); // angle + + streamingChannels = new LinkedList(); + normalChannels = new LinkedList(); + streamingChannelSourceNames = new String[ + SoundSystemConfig.getNumberStreamingChannels() ]; + normalChannelSourceNames = new String[ + SoundSystemConfig.getNumberNormalChannels() ]; + + streamThread = new StreamThread(); + streamThread.start(); + } + + +/* ########################################################################## */ +/* BEGIN OVERRIDE METHODS */ +/* */ +/* The following methods should be overrided as required */ +/* ########################################################################## */ + +/** + * Stops all sources, shuts down sound library, and removes references to all + * instantiated objects. + */ + public void cleanup() + { + streamThread.kill(); + streamThread.interrupt(); + + // wait up to 5 seconds for stream thread to end: + for( int i = 0; i < 50; i++ ) + { + if( !streamThread.alive() ) + break; + try + { + Thread.sleep(100); + } + catch(Exception e) + {} + } + + if( streamThread.alive() ) + { + errorMessage( "Stream thread did not die!" ); + message( "Ignoring errors... continuing clean-up." ); + } + + if( midiChannel != null ) + { + midiChannel.cleanup(); + midiChannel = null; + } + + Channel channel = null; + if( streamingChannels != null ) + { + while( !streamingChannels.isEmpty() ) + { + channel = streamingChannels.remove(0); + channel.close(); + channel.cleanup(); + channel = null; + } + streamingChannels.clear(); + streamingChannels = null; + } + if( normalChannels != null ) + { + while( !normalChannels.isEmpty() ) + { + channel = normalChannels.remove(0); + channel.close(); + channel.cleanup(); + channel = null; + } + normalChannels.clear(); + normalChannels = null; + } + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and cleanup all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.cleanup(); + } + sourceMap.clear(); + sourceMap = null; + + listener = null; + streamThread = null; + } + +/** + * Initializes the sound library. + */ + public void init() throws SoundSystemException + { + Channel channel = null; + + // create the streaming channels: + for( int x = 0; x < SoundSystemConfig.getNumberStreamingChannels(); x++ ) + { + channel = createChannel( SoundSystemConfig.TYPE_STREAMING ); + if( channel == null ) + break; + streamingChannels.add( channel ); + } + // create the non-streaming channels: + for( int x = 0; x < SoundSystemConfig.getNumberNormalChannels(); x++ ) + { + channel = createChannel( SoundSystemConfig.TYPE_NORMAL ); + if( channel == null ) + break; + normalChannels.add( channel ); + } + } + +/** + * Checks if the no-sound library type is compatible. + * @return True or false. + */ + public static boolean libraryCompatible() + { + return true; // the no-sound library is always compatible. + } + +/** + * Creates a new channel of the specified type (normal or streaming). Possible + * values for channel type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel. + * @return The new channel. + */ + protected Channel createChannel( int type ) + { + return new Channel( type ); + } + +/** + * Pre-loads a sound into memory. + * @param filenameURL Filename/URL of the sound file to load. + * @return True if the sound loaded properly. + */ + public boolean loadSound( FilenameURL filenameURL ) + { + return true; + } + +/** + * Saves the specified sample data, under the specified identifier. This + * identifier can be later used in place of 'filename' parameters to reference + * the sample data. + * @param buffer the sample data and audio format to save. + * @param identifier What to call the sample. + * @return True if there weren't any problems. + */ + public boolean loadSound( SoundBuffer buffer, String identifier ) + { + return true; + } + +/** + * Returns the filenames of all previously loaded sounds. + * @return LinkedList of String filenames. + */ + public LinkedList getAllLoadedFilenames() + { + LinkedList filenames = new LinkedList(); + Set keys = bufferMap.keySet(); + Iterator iter = keys.iterator(); + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + filenames.add( iter.next() ); + } + + return filenames; + } + +/** + * Returns the sourcenames of all sources. + * @return LinkedList of String sourcenames. + */ + public LinkedList getAllSourcenames() + { + LinkedList sourcenames = new LinkedList(); + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + + if( midiChannel != null ) + sourcenames.add( midiChannel.getSourcename() ); + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcenames.add( iter.next() ); + } + + return sourcenames; + } + +/** + * Removes a pre-loaded sound from memory. This is a good method to use for + * freeing up memory after a large sound file is no longer needed. NOTE: the + * source will remain in memory after this method has been called, for as long + * as the sound is attached to an existing source. + * @param filename Filename/identifier of the sound file to unload. + */ + public void unloadSound( String filename ) + { + bufferMap.remove( filename ); + } + +/** + * Opens a direct line for streaming audio data. + * @param audioFormat Format that the data will be in. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param posX X position for this source. + * @param posY Y position for this source. + * @param posZ Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void rawDataStream( AudioFormat audioFormat, boolean priority, + String sourcename, float posX, float posY, + float posZ, int attModel, float distOrRoll ) + { + sourceMap.put( sourcename, + new Source( audioFormat, priority, sourcename, posX, + posY, posZ, attModel, distOrRoll ) ); + } + +/** + * Creates a new source using the specified information. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param posX X position for this source. + * @param posY Y position for this source. + * @param posZ Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newSource( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, + float posX, float posY, float posZ, int attModel, + float distOrRoll ) + { + sourceMap.put( sourcename, + new Source( priority, toStream, toLoop, sourcename, + filenameURL, null, posX, posY, posZ, + attModel, distOrRoll, false ) ); + } + +/** + * Creates and immediately plays a new source that will be removed when it + * finishes playing. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL The filename/URL of the sound file to play at this source. + * @param posX X position for this source. + * @param posY Y position for this source. + * @param posZ Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void quickPlay( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, + float posX, float posY, float posZ, int attModel, + float distOrRoll, boolean tmp ) + { + sourceMap.put( sourcename, + new Source( priority, toStream, toLoop, sourcename, + filenameURL, null, posX, posY, posZ, + attModel, distOrRoll, tmp ) ); + } + +/** + * + * Defines whether or not the source should be removed after it finishes + * playing. + * @param sourcename The source's name. + * @param temporary True or False. + */ + public void setTemporary( String sourcename, boolean temporary ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setTemporary( temporary ); + } + +/** + * Changes the specified source's position. + * @param sourcename The source's name. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + public void setPosition( String sourcename, float x, float y, float z ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setPosition( x, y, z ); + } + +/** + * Sets the specified source's priority factor. A priority source will not be + * overriden if there are too many sources playing at once. + * @param sourcename The source's name. + * @param pri True or False. + */ + public void setPriority( String sourcename, boolean pri ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setPriority( pri ); + } + +/** + * Sets the specified source's looping parameter. If parameter lp is false, + * the source will play once and stop. + * @param sourcename The source's name. + * @param lp True or False. + */ + public void setLooping( String sourcename, boolean lp ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setLooping( lp ); + } + +/** + * Sets the specified source's attenuation model. + * @param sourcename The source's name. + * @param model Attenuation model to use. + */ + public void setAttenuation( String sourcename, int model ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setAttenuation( model ); + } + +/** + * Sets the specified source's fade distance or rolloff factor. + * @param sourcename The source's name. + * @param dr Fade distance or rolloff factor. + */ + public void setDistOrRoll( String sourcename, float dr) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setDistOrRoll( dr ); + } + +/** + * Sets the specified source's velocity, for use in Doppler effect. + * @param sourcename The source's name. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setVelocity( String sourcename, float x, float y, float z ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.setVelocity( x, y, z ); + } + +/** + * Sets the listener's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setListenerVelocity( float x, float y, float z ) + { + listener.setVelocity( x, y, z ); + } + +/** + * Notifies the underlying library that the Doppler parameters have changed. + */ + public void dopplerChanged() + {} + +/** + * Returns the number of miliseconds since the specified source began playing. + * @return miliseconds, or -1 if not playing or unable to calculate + */ + public float millisecondsPlayed( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method " + + "'millisecondsPlayed'" ); + return -1; + } + + if( midiSourcename( sourcename ) ) + { + errorMessage( "Unable to calculate milliseconds for MIDI source." ); + return -1; + } + else + { + Source source = sourceMap.get( sourcename ); + if( source == null ) + { + errorMessage( "Source '" + sourcename + "' not found in " + + "method 'millisecondsPlayed'" ); + } + return source.millisecondsPlayed(); + } + } +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. + * @param sourcename Name of the streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example). + */ + public int feedRawAudioData( String sourcename, byte[] buffer ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method " + + "'feedRawAudioData'" ); + return -1; + } + + if( midiSourcename( sourcename ) ) + { + errorMessage( "Raw audio data can not be fed to the " + + "MIDI channel." ); + return -1; + } + else + { + Source source = sourceMap.get( sourcename ); + if( source == null ) + { + errorMessage( "Source '" + sourcename + "' not found in " + + "method 'feedRawAudioData'" ); + } + return feedRawAudioData( source, buffer ); + } + } + +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. + * @param source Streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example). + */ + public int feedRawAudioData( Source source, byte[] buffer ) + { + if( source == null ) + { + errorMessage( "Source parameter null in method " + + "'feedRawAudioData'" ); + return -1; + } + if( !source.toStream ) + { + errorMessage( "Only a streaming source may be specified in " + + "method 'feedRawAudioData'" ); + return -1; + } + if( !source.rawDataStream ) + { + errorMessage( "Streaming source already associated with a " + + "file or URL in method'feedRawAudioData'" ); + return -1; + } + + if( !source.playing() || source.channel == null ) + { + Channel channel; + if( source.channel != null && ( source.channel.attachedSource == + source ) ) + channel = source.channel; + else + channel = getNextChannel( source ); + + int processed = source.feedRawAudioData( channel, buffer ); + channel.attachedSource = source; + streamThread.watch( source ); + streamThread.interrupt(); + return processed; + } + + return( source.feedRawAudioData( source.channel, buffer ) ); + } + +/** + * Looks up the specified source and plays it. + * @param sourcename Name of the source to play. + */ + public void play( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method 'play'" ); + return; + } + + if( midiSourcename( sourcename ) ) + { + midiChannel.play(); + } + else + { + Source source = sourceMap.get( sourcename ); + if( source == null ) + { + errorMessage( "Source '" + sourcename + "' not found in " + + "method 'play'" ); + } + play( source ); + } + } + +/** + * Plays the specified source. + * @param source The source to play. + */ + public void play( Source source ) + { + if( source == null ) + return; + + // raw data streams will automatically play when data is sent to them, + // so no need to do anything here. + if( source.rawDataStream ) + return; + + if( !source.active() ) + return; + + if( !source.playing() ) + { + Channel channel = getNextChannel( source ); + + if( source != null && channel != null ) + { + if( source.channel != null && + source.channel.attachedSource != source ) + source.channel = null; + channel.attachedSource = source; + source.play( channel ); + if( source.toStream ) + { + streamThread.watch( source ); + streamThread.interrupt(); + } + } + } + } + +/** + * Stops the specified source. + * @param sourcename The source's name. + */ + public void stop( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method 'stop'" ); + return; + } + if( midiSourcename( sourcename ) ) + { + midiChannel.stop(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.stop(); + } + } + +/** + * Pauses the specified source. + * @param sourcename The source's name. + */ + public void pause( String sourcename ) + { + if( sourcename == null || sourcename.equals( "" ) ) + { + errorMessage( "Sourcename not specified in method 'stop'" ); + return; + } + if( midiSourcename( sourcename ) ) + { + midiChannel.pause(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.pause(); + } + } + +/** + * Rewinds the specified source. + * @param sourcename The source's name. + */ + public void rewind( String sourcename ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.rewind(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.rewind(); + } + } + +/** + * Clears all previously queued data from a stream. + * @param sourcename The source's name. + */ + public void flush( String sourcename ) + { + if( midiSourcename( sourcename ) ) + errorMessage( "You can not flush the MIDI channel" ); + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.flush(); + } + } + +/** + * Culls the specified source. A culled source will not play until it has been + * activated again. + * @param sourcename The source's name. + */ + public void cull( String sourcename ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.cull(); + } + +/** + * Activates a previously culled source, so it can be played again. + * @param sourcename The source's name. + */ + public void activate( String sourcename ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + { + mySource.activate(); + if( mySource.toPlay ) + play( mySource ); + } + } + +/** + * Sets the overall volume to the specified value, affecting all sources. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + public void setMasterVolume( float value ) + { + SoundSystemConfig.setMasterGain( value ); + if( midiChannel != null ) + midiChannel.resetGain(); + } + +/** + * Manually sets the specified source's volume. + * @param sourcename The source's name. + * @param value A float value ( 0.0f - 1.0f ). + */ + public void setVolume( String sourcename, float value ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.setVolume( value ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + { + float newVolume = value; + if( newVolume < 0.0f ) + newVolume = 0.0f; + else if( newVolume > 1.0f ) + newVolume = 1.0f; + + mySource.sourceVolume = newVolume; + mySource.positionChanged(); + } + } + } + +/** + * Returns the current volume of the specified source, or zero if the specified + * source was not found. + * @param sourcename Source to read volume from. + * @return Float value representing the source volume (0.0f - 1.0f). + */ + public float getVolume( String sourcename ) + { + if( midiSourcename( sourcename ) ) + { + return midiChannel.getVolume(); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + return mySource.sourceVolume; + else + return 0.0f; + } + } + +/** + * Manually sets the specified source's pitch. + * @param sourcename The source's name. + * @param value A float value ( 0.5f - 2.0f ). + */ + public void setPitch( String sourcename, float value ) + { + if( !midiSourcename( sourcename ) ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + { + float newPitch = value; + if( newPitch < 0.5f ) + newPitch = 0.5f; + else if( newPitch > 2.0f ) + newPitch = 2.0f; + + mySource.setPitch( newPitch ); + mySource.positionChanged(); + } + } + } + +/** + * Returns the pitch of the specified source. + * @param sourcename The source's name. + * @return Float value representing the source pitch (0.5f - 2.0f). + */ + public float getPitch( String sourcename ) + { + if( !midiSourcename( sourcename ) ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + return mySource.getPitch(); + } + return 1.0f; + } + +/** + * Moves the listener relative to the current position. + * @param x X offset. + * @param y Y offset. + * @param z Z offset. + */ + public void moveListener( float x, float y, float z ) + { + setListenerPosition( listener.position.x + x, listener.position.y + y, + listener.position.z + z ); + } + +/** + * Changes the listener's position. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + public void setListenerPosition( float x, float y, float z ) + { + // update listener's position + listener.setPosition( x, y, z ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Turn the listener 'angle' radians counterclockwise around the y-Axis, + * relative to the current angle. + * @param angle Angle in radians. + */ + public void turnListener( float angle ) + { + setListenerAngle( listener.angle + angle ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Changes the listeners orientation to the specified 'angle' radians + * counterclockwise around the y-Axis. + * @param angle Angle in radians. + */ + public void setListenerAngle( float angle ) + { + listener.setAngle( angle ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Changes the listeners orientation using the specified coordinates. + * @param lookX X element of the look-at direction. + * @param lookY Y element of the look-at direction. + * @param lookZ Z element of the look-at direction. + * @param upX X element of the up direction. + * @param upY Y element of the up direction. + * @param upZ Z element of the up direction. + */ + public void setListenerOrientation( float lookX, float lookY, float lookZ, + float upX, float upY, float upZ ) + { + listener.setOrientation( lookX, lookY, lookZ, upX, upY, upZ ); + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and update the volume of all sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + source.positionChanged(); + } + } + +/** + * Changes the listeners position and orientation using the specified listener + * data. + * @param l Listener data to use. + */ + public void setListenerData( ListenerData l ) + { + listener.setData( l ); + } + +/** + * Creates sources based on the source map provided. + * @param srcMap Sources to copy. + */ + public void copySources( HashMap srcMap ) + { + if( srcMap == null ) + return; + Set keys = srcMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source srcData; + + // remove any existing sources before starting: + sourceMap.clear(); + + // loop through and copy all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + srcData = srcMap.get( sourcename ); + if( srcData != null ) + { + loadSound( srcData.filenameURL ); + sourceMap.put( sourcename, new Source( srcData, null ) ); + } + } + } + +/** + * Stops and deletes the specified source. + * @param sourcename The source's name. + */ + public void removeSource( String sourcename ) + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) { + // if this is a streaming source just mark it removed - https://github.com/MinecraftForge/MinecraftForge/pull/4765 + if ( mySource.toStream ) + mySource.removed = true; + else + mySource.cleanup(); // end the source, free memory + } + sourceMap.remove( sourcename ); + } + +/** + * Searches for and removes all temporary sources that have finished playing. + */ + public void removeTemporarySources() + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source srcData; + + // loop through and cleanup all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + srcData = sourceMap.get( sourcename ); + if( (srcData != null) && (srcData.temporary) + && (!srcData.playing()) ) + { + srcData.cleanup(); // end the source, free memory + iter.remove(); + } + } + } + +/* ########################################################################## */ +/* END OVERRIDE METHODS */ +/* ########################################################################## */ + +/** + * Returns a handle to the next available channel. If the specified + * source is a normal source, a normal channel is returned, and if it is a + * streaming source, then a streaming channel is returned. If all channels of + * the required type are currently playing, then the next channel playing a + * non-priority source is returned. If no channels are available (i.e. they + * are all playing priority sources) then getNextChannel returns null. + * @param source Source to find a channel for. + * @return The next available channel, or null. + */ + private Channel getNextChannel( Source source ) + { + if( source == null ) + return null; + + String sourcename = source.sourcename; + if( sourcename == null ) + return null; + + int x; + int channels; + int nextChannel; + List channelList; + String[] sourceNames; + String name; + + if( source.toStream ) + { + nextChannel = nextStreamingChannel; + channelList = streamingChannels; + sourceNames = streamingChannelSourceNames; + } + else + { + nextChannel = nextNormalChannel; + channelList = normalChannels; + sourceNames = normalChannelSourceNames; + } + + channels = channelList.size(); + + // Check if this source is already on a channel: + for( x = 0; x < channels; x++ ) + { + if( sourcename.equals( sourceNames[x] ) ) + return channelList.get( x ); + } + + int n = nextChannel; + Source src; + // Play on the next new or non-playing channel: + for( x = 0; x < channels; x++ ) + { + name = sourceNames[n]; + if( name == null ) + src = null; + else + src = sourceMap.get( name ); + + if( src == null || !src.playing() ) + { + if( source.toStream ) + { + nextStreamingChannel = n + 1; + if( nextStreamingChannel >= channels ) + nextStreamingChannel = 0; + } + else + { + nextNormalChannel = n + 1; + if( nextNormalChannel >= channels ) + nextNormalChannel = 0; + } + sourceNames[n] = sourcename; + return channelList.get( n ); + } + n++; + if( n >= channels ) + n = 0; + } + + n = nextChannel; + // Play on the next non-priority channel: + for( x = 0; x < channels; x++ ) + { + name = sourceNames[n]; + if( name == null ) + src = null; + else + src = sourceMap.get( name ); + + if( src == null || !src.playing() || !src.priority ) + { + if( source.toStream ) + { + nextStreamingChannel = n + 1; + if( nextStreamingChannel >= channels ) + nextStreamingChannel = 0; + } + else + { + nextNormalChannel = n + 1; + if( nextNormalChannel >= channels ) + nextNormalChannel = 0; + } + sourceNames[n] = sourcename; + return channelList.get( n ); + } + n++; + if( n >= channels ) + n = 0; + } + + return null; + } + +/** + * Plays all sources whose 'toPlay' varriable is true but are not currently + * playing (such as sources which were culled while looping and then + * reactivated). + */ + public void replaySources() + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // loop through and cleanup all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + { + if( source.toPlay && !source.playing() ) + { + play( sourcename ); + source.toPlay = false; + } + } + } + } + +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. This + * method has no effect on non-streaming sources. + * @param sourcename Source identifier. + * @param filenameURL Filename/URL of the sound file to play next. + */ + public void queueSound( String sourcename, FilenameURL filenameURL ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.queueSound( filenameURL ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.queueSound( filenameURL ); + } + } + +/** + * Removes the first occurrence of the specified filename from the specified + * source's list of sounds to play when previous playback ends. This method + * has no effect on non-streaming sources. + * @param sourcename Source identifier. + * @param filename Filename/identifier of the sound file to remove from the queue. + */ + public void dequeueSound( String sourcename, String filename ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.dequeueSound( filename ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.dequeueSound( filename ); + } + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. If the filenameURL parameter is null or empty, the + * specified source will simply fade out and stop. The miliseconds parameter + * must be non-negative or zero. This method will remove anything that is + * currently in the specified source's list of queued sounds that would have + * played next when the current sound finished playing. This method may only + * be used for streaming and MIDI sources. + * @param sourcename Name of the source to fade out. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( String sourcename, FilenameURL filenameURL, + long milis ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.fadeOut( filenameURL, milis ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.fadeOut( filenameURL, milis ); + } + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified file. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The filenameURL parameter may not be null or empty. The + * miliseconds parameters must be non-negative or zero. This method will + * remove anything that is currently in the specified source's list of queued + * sounds that would have played next when the current sound finished playing. + * This method may only be used for streaming and MIDI sources. + * @param sourcename Name of the source to fade out/in. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( String sourcename, FilenameURL filenameURL, + long milisOut, long milisIn ) + { + if( midiSourcename( sourcename ) ) + { + midiChannel.fadeOutIn( filenameURL, milisOut, milisIn ); + } + else + { + Source mySource = sourceMap.get( sourcename ); + if( mySource != null ) + mySource.fadeOutIn( filenameURL, milisOut, milisIn ); + } + } + +/** + * Makes sure the current volume levels of streaming sources and MIDI are + * correct. This method is designed to help reduce the "jerky" fading behavior + * that happens when using some library and codec pluggins (such as + * LibraryJavaSound and CodecJOrbis). This method has no effect on normal + * "non-streaming" sources. It would normally be called somewhere in the main + * "game loop". IMPORTANT: To optimize frame-rates, do not call this method + * for every frame. It is better to just call this method at some acceptable + * "granularity" (play around with different granularities to find what sounds + * acceptable for a particular situation). + */ + public void checkFadeVolumes() + { + if( midiChannel != null ) + midiChannel.resetGain(); + Channel c; + Source s; + for( int x = 0; x < streamingChannels.size(); x++ ) + { + c = streamingChannels.get( x ); + if( c != null ) + { + s = c.attachedSource; + if( s != null ) + s.checkFadeOut(); + } + } + c = null; + s = null; + } + +/** + * Loads the specified MIDI file, and saves the source information about it. + * @param toLoop Midi file should loop or play once. + * @param sourcename Source identifier. + * @param filenameURL Filename/URL of the MIDI file to load. + */ + public void loadMidi( boolean toLoop, String sourcename, + FilenameURL filenameURL ) + { + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'loadMidi'." ); + return; + } + + if( !filenameURL.getFilename().matches( + SoundSystemConfig.EXTENSION_MIDI ) ) + { + errorMessage( "Filename/identifier doesn't end in '.mid' or" + + "'.midi' in method loadMidi." ); + return; + } + + if( midiChannel == null ) + { + midiChannel = new MidiChannel( toLoop, sourcename, filenameURL ); + } + else + { + midiChannel.switchSource( toLoop, sourcename, filenameURL ); + } + } + +/** + * Unloads the current Midi file. + */ + public void unloadMidi() + { + if( midiChannel != null ) + midiChannel.cleanup(); + midiChannel = null; + } + +/** + * Checks if the sourcename matches the midi source. + * @param sourcename Source identifier. + * @return True if sourcename and midi sourcename match. + */ + public boolean midiSourcename( String sourcename ) + { + if( midiChannel == null || sourcename == null ) + return false; + + if( midiChannel.getSourcename() == null || sourcename.equals( "" ) ) + return false; + + if( sourcename.equals( midiChannel.getSourcename() ) ) + return true; + + return false; + } + +/** + * + * Returns the Source object identified by the specified name. + * @param sourcename The source's name. + * @return The source, or null if not found. + */ + public Source getSource( String sourcename ) + { + return sourceMap.get( sourcename ); + } + +/** + * + * Returns a handle to the MIDI channel, or null if one does not exist. + * @return The MIDI channel. + */ + public MidiChannel getMidiChannel() + { + return midiChannel; + } + +/** + * + * Specifies the MIDI channel to use. + * @param c New MIDI channel. + */ + public void setMidiChannel( MidiChannel c ) + { + if( midiChannel != null && midiChannel != c ) + midiChannel.cleanup(); + + midiChannel = c; + } + +/** + * Tells all the sources that the listener has moved. + */ + public void listenerMoved() + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source srcData; + + // loop through and copy all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + srcData = sourceMap.get( sourcename ); + if( srcData != null ) + { + srcData.listenerMoved(); + } + } + } + +/** + * Returns the sources map. + * @return Map of all sources. + */ + public HashMap getSources() + { + return sourceMap; + } + +/** + * Returns information about the listener. + * @return A ListenerData object. + */ + public ListenerData getListenerData() + { + return listener; + } + +/** + * Indicates whether or not this library requires some codecs to reverse-order + * the audio data they generate. + * @return True if audio data should be reverse-ordered. + */ + public boolean reverseByteOrder() + { + return reverseByteOrder; + } +/** + * Returns the short title of this library type. + * @return A short title. + */ + public static String getTitle() + { + return "No Sound"; + } + +/** + * Returns a longer description of this library type. + * @return A longer description. + */ + public static String getDescription() + { + return "Silent Mode"; + } + +/** + * Returns the name of the class. + * @return "Library" + library title. + */ + public String getClassName() + { + return "Library"; + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, getClassName(), message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( getClassName(), message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/ListenerData.java b/src/lwjgl/java/paulscode/sound/ListenerData.java new file mode 100644 index 0000000..af24b3c --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/ListenerData.java @@ -0,0 +1,282 @@ +package paulscode.sound; + +/** + * The listenerData class is used to store information about the + * listener's position and orientation. A ListenerData object can be obtained + * using SoundSystem's getListenerData() method. See + * {@link paulscode.sound.Vector3D Vector3D} for more information about 3D + * coordinates and vectors. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class ListenerData +{ +/** + * Listener's position in 3D space + */ + public Vector3D position; +/** + * A normalized vector indicating the direction the listener is facing + */ + public Vector3D lookAt; +/** + * A normalized vector indicating the up direction + */ + public Vector3D up; +/** + * Listener's velocity in world-space + */ + public Vector3D velocity; + +/** + * Used for easy rotation along the x/z plane (for use in a first-person + * shooter type of application). + */ + public float angle = 0.0f; + +/** + * Constructor: Set this listener data to the origin facing along the z-axis + */ + public ListenerData() + { + position = new Vector3D( 0.0f, 0.0f, 0.0f ); + lookAt = new Vector3D( 0.0f, 0.0f, -1.0f ); + up = new Vector3D( 0.0f, 1.0f, 0.0f ); + velocity = new Vector3D( 0.0f, 0.0f, 0.0f ); + angle = 0.0f; + } + +/** + * Constructor: Set this listener data to the specified values for position and + * orientation. + * @param pX Listener's X coordinate. + * @param pY Listener's Y coordinate. + * @param pZ Listener's Z coordinate. + * @param lX X element of the look-at direction. + * @param lY Y element of the look-at direction. + * @param lZ Z element of the look-at direction. + * @param uX X element of the up direction. + * @param uY Y element of the up direction. + * @param uZ Z element of the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public ListenerData( float pX, float pY, float pZ, float lX, float lY, + float lZ, float uX, float uY, float uZ, float a ) + { + position = new Vector3D( pX, pY, pZ ); + lookAt = new Vector3D( lX, lY, lZ ); + up = new Vector3D( uX, uY, uZ ); + velocity = new Vector3D( 0.0f, 0.0f, 0.0f ); + angle = a; + } + +/** + * Constructor: Set this listener data to the specified values for position and + * orientation. + * @param p Position of the listener in 3D space. + * @param l Normalized vector indicating the direction which the listener is facing. + * @param u Normalized vector indicating the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public ListenerData( Vector3D p, Vector3D l, Vector3D u, float a ) + { + position = p.clone(); + lookAt = l.clone(); + up = u.clone(); + velocity = new Vector3D( 0.0f, 0.0f, 0.0f ); + angle = a; + } + +/** + * Change this listener data using the specified coordinates for position and + * orientation. + * @param pX Listener's X coordinate. + * @param pY Listener's Y coordinate. + * @param pZ Listener's Z coordinate. + * @param lX X element of the look-at direction. + * @param lY Y element of the look-at direction. + * @param lZ Z element of the look-at direction. + * @param uX X element of the up direction. + * @param uY Y element of the up direction. + * @param uZ Z element of the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public void setData( float pX, float pY, float pZ, float lX, float lY, + float lZ, float uX, float uY, float uZ, float a ) + { + position.x = pX; + position.y = pY; + position.z = pZ; + lookAt.x = lX; + lookAt.y = lY; + lookAt.z = lZ; + up.x = uX; + up.y = uY; + up.z = uZ; + angle = a; + } + +/** + * Change this listener data using the specified 3D vectors for position and + * orientation. + * @param p Position of the listener in 3D space. + * @param l Normalized vector indicating the direction which the listener is facing. + * @param u Normalized vector indicating the up direction. + * @param a Angle in radians that the listener is turned counterclockwise around the y-axis. + */ + public void setData( Vector3D p, Vector3D l, Vector3D u, float a ) + { + position.x = p.x; + position.y = p.y; + position.z = p.z; + lookAt.x = l.x; + lookAt.y = l.y; + lookAt.z = l.z; + up.x = u.x; + up.y = u.y; + up.z = u.z; + angle = a; + } + +/** + * Change this listener data to match the specified listener data. + * @param l Listener data to use. + */ + public void setData( ListenerData l ) + { + position.x = l.position.x; + position.y = l.position.y; + position.z = l.position.z; + lookAt.x = l.lookAt.x; + lookAt.y = l.lookAt.y; + lookAt.z = l.lookAt.z; + up.x = l.up.x; + up.y = l.up.y; + up.z = l.up.z; + angle = l.angle; + } + +/** + * Change this listener's position using the specified coordinates. + * @param x Listener's X coordinate. + * @param y Listener's Y coordinate. + * @param z Listener's Z coordinate. + */ + public void setPosition( float x, float y, float z ) + { + position.x = x; + position.y = y; + position.z = z; + } + +/** + * Change this listener's position using the specified vector. + * @param p New position. + */ + public void setPosition( Vector3D p ) + { + position.x = p.x; + position.y = p.y; + position.z = p.z; + } + +/** + * Changes the listeners orientation using the specified coordinates. + * @param lX X element of the look-at direction. + * @param lY Y element of the look-at direction. + * @param lZ Z element of the look-at direction. + * @param uX X element of the up direction. + * @param uY Y element of the up direction. + * @param uZ Z element of the up direction. + */ + public void setOrientation( float lX, float lY, float lZ, + float uX, float uY, float uZ ) + { + lookAt.x = lX; + lookAt.y = lY; + lookAt.z = lZ; + up.x = uX; + up.y = uY; + up.z = uZ; + } + +/** + * Changes the listeners orientation using the specified vectors. + * @param l Normalized vector representing the look-at direction. + * @param u Normalized vector representing the up direction. + */ + public void setOrientation( Vector3D l, Vector3D u ) + { + lookAt.x = l.x; + lookAt.y = l.y; + lookAt.z = l.z; + up.x = u.x; + up.y = u.y; + up.z = u.z; + } + +/** + * Change this listener's velocity in world-space. + * @param v New velocity. + */ + public void setVelocity( Vector3D v ) + { + velocity.x = v.x; + velocity.y = v.y; + velocity.z = v.z; + } + +/** + * Change this listener's velocity in world-space. + * @param x New velocity along world x-axis. + * @param y New velocity along world y-axis. + * @param z New velocity along world z-axis. + */ + public void setVelocity( float x, float y, float z ) + { + velocity.x = x; + velocity.y = y; + velocity.z = z; + } + +/** + * Sets the listener's angle counterclockwise around the y-axis. + * @param a Angle in radians. + */ + public void setAngle( float a ) + { + angle = a; + lookAt.x = -1.0f * (float) Math.sin( angle ); + lookAt.z = -1.0f * (float) Math.cos( angle ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/MidiChannel.java b/src/lwjgl/java/paulscode/sound/MidiChannel.java new file mode 100644 index 0000000..aedf033 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/MidiChannel.java @@ -0,0 +1,1601 @@ +package paulscode.sound; + +import java.io.IOException; +import java.net.URL; +import java.util.LinkedList; +import java.util.ListIterator; + +import javax.sound.midi.InvalidMidiDataException; +import javax.sound.midi.MetaEventListener; +import javax.sound.midi.MetaMessage; +import javax.sound.midi.MidiDevice; +import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequence; +import javax.sound.midi.Sequencer; +import javax.sound.midi.ShortMessage; +import javax.sound.midi.Synthesizer; + +/** + * The MidiChannel class provides an interface for playing MIDI files, using + * the JavaSound API. For more information about the JavaSound API, visit + * http://java.sun.com/products/java-media/sound/ + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class MidiChannel implements MetaEventListener +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * Filename/URL to the file: + */ + private FilenameURL filenameURL; + +/** + * Unique source identifier for this MIDI source. + */ + private String sourcename; + +/** + * Global identifier for the MIDI "change volume" event. + */ + private static final int CHANGE_VOLUME = 7; + +/** + * Global identifier for the MIDI "end of track" event. + */ + private static final int END_OF_TRACK = 47; + +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; + +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Runs the assigned sequence, passing information on to the synthesizer for + * playback. + */ + private Sequencer sequencer = null; + +/** + * Converts MIDI events into audio. + */ + private Synthesizer synthesizer = null; + +/** + * Converts MIDI events into audio if there is no default Synthesizer. + */ + private MidiDevice synthDevice = null; + +/** + * Sequence of MIDI events defining sound. + */ + private Sequence sequence = null; + +/** + * Should playback loop or play only once. + */ + private boolean toLoop = true; + +/** + * Playback volume, float value (0.0f - 1.0f). + */ + private float gain = 1.0f; + +/** + * True while sequencer is busy being set up. + */ + private boolean loading = true; + +/** + * The list of MIDI files to play when the current sequence finishes. + */ + private LinkedList sequenceQueue = null; + +/** + * Ensures that only one thread accesses the sequenceQueue at a time. + */ + private final Object sequenceQueueLock = new Object(); + +/** + * Specifies the gain factor used for the fade-out effect, or -1 when + * playback is not currently fading out. + */ + protected float fadeOutGain = -1.0f; + +/** + * Specifies the gain factor used for the fade-in effect, or 1 when + * playback is not currently fading in. + */ + protected float fadeInGain = 1.0f; + +/** + * Specifies the number of miliseconds it should take to fade out. + */ + protected long fadeOutMilis = 0; + +/** + * Specifies the number of miliseconds it should take to fade in. + */ + protected long fadeInMilis = 0; + +/** + * System time in miliseconds when the last fade in/out volume check occurred. + */ + protected long lastFadeCheck = 0; + +/** + * Used for fading in and out effects. + */ + private FadeThread fadeThread = null; + +/** + * Constructor: Defines the basic source information. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param filename Name of the MIDI file to play. + */ + public MidiChannel( boolean toLoop, String sourcename, String filename ) + { + // let others know we are busy loading: + loading( SET, true ); + + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // save information about the source: + filenameURL( SET, new FilenameURL( filename ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + // initialize the MIDI channel: + init(); + + // finished loading: + loading( SET, false ); + } + +/** + * Constructor: Defines the basic source information. The fourth parameter, + * 'identifier' should look like a filename, and it must have the correct + * extension (.mid or .midi). + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param midiFile URL to the MIDI file to play. + * @param identifier Filename/identifier for the MIDI file. + */ + public MidiChannel( boolean toLoop, String sourcename, URL midiFile, + String identifier ) + { + // let others know we are busy loading + loading( SET, true ); + + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // save information about the source: + filenameURL( SET, new FilenameURL( midiFile, identifier ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + // initialize the MIDI channel: + init(); + + // finished loading: + loading( SET, false ); + } + +/** + * Constructor: Defines the basic source information. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param midiFilenameURL Filename/URL to the MIDI file to play. + */ + public MidiChannel( boolean toLoop, String sourcename, + FilenameURL midiFilenameURL ) + { + // let others know we are busy loading + loading( SET, true ); + + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + // save information about the source: + filenameURL( SET, midiFilenameURL ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + // initialize the MIDI channel: + init(); + + // finished loading: + loading( SET, false ); + } + +/** + * Initializes the sequencer, loads the sequence, and sets up the synthesizer. + */ + private void init() + { + // Load a sequencer: + getSequencer(); + + // Load the sequence to play: + setSequence( filenameURL( GET, null).getURL() ); + + // Load a synthesizer to play the sequence on: + getSynthesizer(); + + // Ensure the initial volume is correct: + // (TODO: doesn't always work??) + resetGain(); + } + +/** + * Shuts the channel down and removes references to all instantiated objects. + */ + public void cleanup() + { + loading( SET, true ); + setLooping( true ); + + if( sequencer != null ) + { + try + { + sequencer.stop(); + sequencer.close(); + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ) + {} + } + + logger = null; + sequencer = null; + synthesizer = null; + sequence = null; + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + sequenceQueue.clear(); + sequenceQueue = null; + } + + // End the fade effects thread if it exists: + if( fadeThread != null ) + { + boolean killException = false; + try + { + fadeThread.kill(); // end the fade effects thread. + fadeThread.interrupt(); // wake the thread up so it can end. + } + catch( Exception e ) + { + killException = true; + } + + if( !killException ) + { + // wait up to 5 seconds for fade effects thread to end: + for( int i = 0; i < 50; i++ ) + { + if( !fadeThread.alive() ) + break; + try{Thread.sleep( 100 );}catch(InterruptedException e){} + } + } + + // Let user know if there was a problem ending the fade thread + if( killException || fadeThread.alive() ) + { + errorMessage( "MIDI fade effects thread did not die!" ); + message( "Ignoring errors... continuing clean-up." ); + } + } + + fadeThread = null; + + loading( SET, false ); + } + +/** + * Queues up the next MIDI sequence to play when the previous sequence ends. + * @param filenameURL MIDI sequence to play next. + */ + public void queueSound( FilenameURL filenameURL ) + { + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'queueSound'" ); + return; + } + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue == null ) + sequenceQueue = new LinkedList(); + sequenceQueue.add( filenameURL ); + } + } + +/** + * Removes the first occurrence of the specified filename/identifier from the + * list of MIDI sequences to play when the previous sequence ends. + * @param filename Filename or identifier of a MIDI sequence to remove from the + * queue. + */ + public void dequeueSound( String filename ) + { + if( filename == null || filename.equals( "" ) ) + { + errorMessage( "Filename not specified in method 'dequeueSound'" ); + return; + } + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + { + ListIterator i = sequenceQueue.listIterator(); + while( i.hasNext() ) + { + if( i.next().getFilename().equals( filename ) ) + { + i.remove(); + break; + } + } + } + } + } + +/** + * Fades out the volume of whatever sequence is currently playing, then + * begins playing the specified MIDI file at the previously assigned + * volume level. If the filenameURL parameter is null or empty, playback will + * simply fade out and stop. The miliseconds parameter must be non-negative or + * zero. This method will remove anything that is currently in the list of + * queued MIDI sequences that would have played next when current playback + * finished. + * @param filenameURL MIDI file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( FilenameURL filenameURL, long milis ) + { + if( milis < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOut'." ); + return; + } + + fadeOutMilis = milis; + fadeInMilis = 0; + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + sequenceQueue.clear(); + + if( filenameURL != null ) + { + if( sequenceQueue == null ) + sequenceQueue = new LinkedList(); + sequenceQueue.add( filenameURL ); + } + } + if( fadeThread == null ) + { + fadeThread = new FadeThread(); + fadeThread.start(); + } + fadeThread.interrupt(); + } + +/** + * Fades out the volume of whatever sequence is currently playing, then + * fades the volume back in playing the specified MIDI file. Final volume + * after fade-in completes will be equal to the previously assigned volume + * level. The filenameURL parameter may not be null or empty. The miliseconds + * parameters must be non-negative or zero. This method will remove anything + * that is currently in the list of queued MIDI sequences that would have + * played next when current playback finished. + * @param filenameURL MIDI file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( FilenameURL filenameURL, long milisOut, + long milisIn ) + { + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'fadeOutIn'." ); + return; + } + if( milisOut < 0 || milisIn < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOutIn'." ); + return; + } + + fadeOutMilis = milisOut; + fadeInMilis = milisIn; + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( sequenceQueueLock ) + { + if( sequenceQueue == null ) + sequenceQueue = new LinkedList(); + sequenceQueue.clear(); + sequenceQueue.add( filenameURL ); + } + if( fadeThread == null ) + { + fadeThread = new FadeThread(); + fadeThread.start(); + } + fadeThread.interrupt(); + } + +/** + * Resets this source's volume if it is fading out or in. Returns true if this + * source is currently in the process of fading out. When fade-out completes, + * this method transitions the source to the next sound in the sound sequence + * queue if there is one. This method has no effect on non-streaming sources. + * @return True if this source is in the process of fading out. + */ + private synchronized boolean checkFadeOut() + { + if( fadeOutGain == -1.0f && fadeInGain == 1.0f ) + return false; + + long currentTime = System.currentTimeMillis(); + long milisPast = currentTime - lastFadeCheck; + lastFadeCheck = currentTime; + + if( fadeOutGain >= 0.0f ) + { + if( fadeOutMilis == 0 ) + { + fadeOutGain = 0.0f; + fadeInGain = 0.0f; + if( !incrementSequence() ) + stop(); + rewind(); + resetGain(); + return false; + } + else + { + float fadeOutReduction = ((float)milisPast) / ((float)fadeOutMilis); + + fadeOutGain -= fadeOutReduction; + if( fadeOutGain <= 0.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 0.0f; + if( !incrementSequence() ) + stop(); + rewind(); + resetGain(); + return false; + } + } + resetGain(); + return true; + } + + if( fadeInGain < 1.0f ) + { + fadeOutGain = -1.0f; + if( fadeInMilis == 0 ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + else + { + float fadeInIncrease = ((float)milisPast) / ((float)fadeInMilis); + fadeInGain += fadeInIncrease; + if( fadeInGain >= 1.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + } + resetGain(); + } + + return false; + } + +/** + * Removes the next sequence from the queue and assigns it to the sequencer. + * @return True if there was something in the queue. + */ + private boolean incrementSequence() + { + synchronized( sequenceQueueLock ) + { + // Is there a queue, and if so, is there anything in it: + if( sequenceQueue != null && sequenceQueue.size() > 0 ) + { + // grab the next filename/URL from the queue: + filenameURL( SET, sequenceQueue.remove( 0 ) ); + + // Let everyone know we are busy loading: + loading( SET, true ); + + // Check if we have a sequencer: + if( sequencer == null ) + { + // nope, try and get one now: + getSequencer(); + } + else + { + // We have a sequencer. Stop it now: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // Stop listening for a moment: + sequencer.removeMetaEventListener( this ); + // wait a bit for the sequencer to shut down and rewind: + try{ Thread.sleep( 100 ); }catch( InterruptedException e ){} + } + // We need to have a sequencer at this point: + if( sequencer == null ) + { + errorMessage( "Unable to set the sequence in method " + + "'incrementSequence', because there wasn't " + + "a sequencer to use." ); + + // Finished loading: + loading( SET, false ); + + // failure: + return false; + } + // set the new sequence to be played: + setSequence( filenameURL( GET, null ).getURL() ); + // start playing again: + sequencer.start(); + // make sure we play at the correct volume: + // (TODO: This doesn't always work??) + resetGain(); + // start listening for end of track event again: + sequencer.addMetaEventListener( this ); + + // Finished loading: + loading( SET, false ); + + // We successfully moved to the next sequence: + return true; + } + } + + // Nothing left to load + return false; + } + +/** + * Plays the MIDI file from the beginning, or from where it left off if it was + * paused. + */ + public void play() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + // start playing: + sequencer.start(); + // event will be sent when end of track is reached: + sequencer.addMetaEventListener( this ); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'play'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Stops playback and rewinds to the beginning. + */ + public void stop() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + // stop playback: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // No need to listen any more: + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'stop'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Temporarily stops playback without rewinding. + */ + public void pause() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + //stop playback. Will resume from this location next play. + sequencer.stop(); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'pause'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Returns playback to the beginning. + */ + public void rewind() + { + if( !loading() ) + { + // Make sure there is a sequencer: + if( sequencer == null ) + return; + + try + { + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + } + catch( Exception e ) + { + errorMessage( "Exception in method 'rewind'" ); + printStackTrace( e ); + SoundSystemException sse = new SoundSystemException( + e.getMessage() ); + SoundSystem.setException( sse ); + } + } + } + +/** + * Changes the volume of MIDI playback. + * @param value Float value (0.0f - 1.0f). + */ + public void setVolume( float value ) + { + gain = value; + resetGain(); + } + +/** + * Returns the current volume for the MIDI source. + * @return Float value (0.0f - 1.0f). + */ + public float getVolume() + { + return gain; + } + +/** + * Changes the basic information about the MIDI source. This method removes + * any queued filenames/URLs from the list of MIDI sequences that would have + * played after the current sequence ended. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param filename Name of the MIDI file to play. + */ + public void switchSource( boolean toLoop, String sourcename, + String filename ) + { + // Let everyone know we are busy loading: + loading( SET, true ); + + // save information about the source: + filenameURL( SET, new FilenameURL( filename ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + reset(); + + // Finished loading: + loading( SET, false ); + } + +/** + * Changes the basic information about the MIDI source. This method removes + * any queued filenames/URLs from the list of MIDI sequences that would have + * played after the current sequence ended. The fourth parameter, + * 'identifier' should look like a filename, and it must have the correct + * extension (.mid or .midi). + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param midiFile URL to the MIDI file to play. + * @param identifier Filename/identifier for the MIDI file. + */ + public void switchSource( boolean toLoop, String sourcename, URL midiFile, + String identifier ) + { + // Let everyone know we are busy loading: + loading( SET, true ); + + // save information about the source: + filenameURL( SET, new FilenameURL( midiFile, identifier ) ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + reset(); + + // Finished loading: + loading( SET, false ); + } + +/** + * Changes the basic information about the MIDI source. This method removes + * any queued filenames/URLs from the list of MIDI sequences that would have + * played after the current sequence ended. + * @param toLoop Should playback loop or play only once? + * @param sourcename Unique identifier for this source. + * @param filenameURL Filename/URL of the MIDI file to play. + */ + public void switchSource( boolean toLoop, String sourcename, + FilenameURL filenameURL ) + { + // Let everyone know we are busy loading: + loading( SET, true ); + + // save information about the source: + filenameURL( SET, filenameURL ); + sourcename( SET, sourcename ); + setLooping( toLoop ); + + reset(); + + // Finished loading: + loading( SET, false ); + } + +/** + * Stops and rewinds the sequencer, and resets the sequence. + */ + private void reset() + { + synchronized( sequenceQueueLock ) + { + if( sequenceQueue != null ) + sequenceQueue.clear(); + } + + // Check if we have a sequencer: + if( sequencer == null ) + { + // nope, try and get one now: + getSequencer(); + } + else + { + // We have a sequencer. Stop it now: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // Stop listening for a moment: + sequencer.removeMetaEventListener( this ); + // wait a bit for the sequencer to shut down and rewind: + try{ Thread.sleep( 100 ); }catch( InterruptedException e ){} + } + // We need to have a sequencer at this point: + if( sequencer == null ) + { + errorMessage( "Unable to set the sequence in method " + + "'reset', because there wasn't " + + "a sequencer to use." ); + return; + } + + // set the new sequence to be played: + setSequence( filenameURL( GET, null ).getURL() ); + // start playing again: + sequencer.start(); + // make sure we play at the correct volume: + // (TODO: This doesn't always work??) + resetGain(); + // start listening for end of track event again: + sequencer.addMetaEventListener( this ); + } + +/** + * Sets the value of boolean 'toLoop'. + * @param value True or False. + */ + public void setLooping( boolean value ) + { + toLoop( SET, value ); + } + +/** + * Returns the value of boolean 'toLoop'. + * @return True while looping. + */ + public boolean getLooping() + { + return toLoop( GET, XXX ); + } + +/** + * Sets or returns the value of boolean 'toLoop'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True while looping. + */ + private synchronized boolean toLoop( boolean action, boolean value ) + { + if( action == SET ) + toLoop = value; + return toLoop; + } + +/** + * Check if a MIDI file is in the process of loading. + */ + public boolean loading() + { + return( loading( GET, XXX ) ); + } + +/** + * Sets or returns the value of boolean 'loading'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True while a MIDI file is in the process of loading. + */ + private synchronized boolean loading( boolean action, boolean value ) + { + if( action == SET ) + loading = value; + return loading; + } + +/** + * Defines the unique identifier for this source + * @param value New source name. + */ + public void setSourcename( String value ) + { + sourcename( SET, value ); + } + +/** + * Returns the unique identifier for this source. + * @return The source's name. + */ + public String getSourcename() + { + return sourcename( GET, null ); + } + +/** + * Sets or returns the value of String 'sourcename'. + * @param action GET or SET. + * @param value New value if action == SET, or null if action == GET. + * @return The source's name. + */ + private synchronized String sourcename( boolean action, String value ) + { + if( action == SET ) + sourcename = value; + return sourcename; + } + +/** + * Defines which MIDI file to play. + * @param value Path to the MIDI file. + */ + public void setFilenameURL( FilenameURL value ) + { + filenameURL( SET, value ); + } + +/** + * Returns the filename/identifier of the MIDI file being played. + * @return Filename of identifier of the MIDI file. + */ + public String getFilename() + { + return filenameURL( GET, null ).getFilename(); + } + +/** + * Returns the MIDI file being played. + * @return Filename/URL of the MIDI file. + */ + public FilenameURL getFilenameURL() + { + return filenameURL( GET, null ); + } + +/** + * Sets or returns the value of filenameURL. + * @param action GET or SET. + * @param value New value if action == SET, or null if action == GET. + * @return Path to the MIDI file. + */ + private synchronized FilenameURL filenameURL( boolean action, + FilenameURL value ) + { + if( action == SET ) + filenameURL = value; + return filenameURL; + } + +/** + * Called when MIDI events occur. + * @param message Meta mssage describing the MIDI event. + */ + public void meta( MetaMessage message ) + { + if( message.getType() == END_OF_TRACK ) + { + // Generate an EOS event: + SoundSystemConfig.notifyEOS( sourcename, sequenceQueue.size() ); + + // check if we should loop or not: + if( toLoop ) + { + // looping + // Check if playback is in the process of fading out. + if( !checkFadeOut() ) + { + // Not fading out, progress to the next MIDI sequence if + // any are queued. + if( !incrementSequence() ) + { + try + { + // Rewind to the beginning. + sequencer.setMicrosecondPosition( 0 ); + sequencer.start(); + // Make sure playback volume is correct. + resetGain(); + } + catch( Exception e ){} + } + } + else if( sequencer != null ) + { + try + { + // Rewind to the beginning. + sequencer.setMicrosecondPosition( 0 ); + sequencer.start(); + // Make sure playback volume is correct. + resetGain(); + } + catch( Exception e ){} + } + } + else + { + //non-looping + if( !checkFadeOut() ) + { + if( !incrementSequence() ) + { + try + { + // stop playback: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // stop looping: + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ){} + } + } + else + { + try + { + // stop playback: + sequencer.stop(); + // rewind to the beginning: + sequencer.setMicrosecondPosition( 0 ); + // stop looping: + sequencer.removeMetaEventListener( this ); + } + catch( Exception e ){} + } + } + } + } + +/** + * Resets playback volume to the correct level. + */ + public void resetGain() + { + // make sure the value for gain is valid (between 0 and 1) + if( gain < 0.0f ) + gain = 0.0f; + if( gain > 1.0f ) + gain = 1.0f; + + int midiVolume = (int) ( gain * SoundSystemConfig.getMasterGain() + * (float) Math.abs( fadeOutGain ) * fadeInGain + * 127.0f ); + if( synthesizer != null ) + { + javax.sound.midi.MidiChannel[] channels = synthesizer.getChannels(); + for( int c = 0; channels != null && c < channels.length; c++ ) + { + channels[c].controlChange( CHANGE_VOLUME, midiVolume ); + } + } + else if( synthDevice != null ) + { + try + { + ShortMessage volumeMessage = new ShortMessage(); + for( int i = 0; i < 16; i++ ) + { + volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, i, + CHANGE_VOLUME, midiVolume ); + synthDevice.getReceiver().send( volumeMessage, -1 ); + } + } + catch( Exception e ) + { + errorMessage( "Error resetting gain on MIDI device" ); + printStackTrace( e ); + } + } + else if( sequencer != null && sequencer instanceof Synthesizer ) + { + synthesizer = (Synthesizer) sequencer; + javax.sound.midi.MidiChannel[] channels = synthesizer.getChannels(); + for( int c = 0; channels != null && c < channels.length; c++ ) + { + channels[c].controlChange( CHANGE_VOLUME, midiVolume ); + } + } + else + { + try + { + Receiver receiver = MidiSystem.getReceiver(); + ShortMessage volumeMessage= new ShortMessage(); + for( int c = 0; c < 16; c++ ) + { + volumeMessage.setMessage( ShortMessage.CONTROL_CHANGE, c, + CHANGE_VOLUME, midiVolume ); + receiver.send( volumeMessage, -1 ); + } + } + catch( Exception e ) + { + errorMessage( "Error resetting gain on default receiver" ); + printStackTrace( e ); + } + } + } + +/** + * Attempts to load the default sequencer. If it fails, then other common + * sequencers are tried. If none can be loaded, then variable 'sequencer' + * remains null. + */ + private void getSequencer() + { + try + { + sequencer = MidiSystem.getSequencer(); + if( sequencer != null ) + { + try + { + sequencer.getTransmitter(); + } + catch( MidiUnavailableException mue ) + { + message( "Unable to get a transmitter from the " + + "default MIDI sequencer" ); + } + sequencer.open(); + } + } + catch( MidiUnavailableException mue ) + { + message( "Unable to open the default MIDI sequencer" ); + sequencer = null; + } + catch( Exception e ) + { + if( e instanceof InterruptedException ) + { + message( "Caught InterruptedException while attempting to " + + "open the default MIDI sequencer. Trying again." ); + sequencer = null; + } + try + { + sequencer = MidiSystem.getSequencer(); + if( sequencer != null ) + { + try + { + sequencer.getTransmitter(); + } + catch( MidiUnavailableException mue ) + { + message( "Unable to get a transmitter from the " + + "default MIDI sequencer" ); + } + sequencer.open(); + } + } + catch( MidiUnavailableException mue ) + { + message( "Unable to open the default MIDI sequencer" ); + sequencer = null; + } + catch( Exception e2 ) + { + message( "Unknown error opening the default MIDI sequencer" ); + sequencer = null; + } + } + + if( sequencer == null ) + sequencer = openSequencer( "Real Time Sequencer" ); + if( sequencer == null ) + sequencer = openSequencer( "Java Sound Sequencer"); + if( sequencer == null ) + { + errorMessage( "Failed to find an available MIDI sequencer" ); + return; + } + } + +/** + * Loads the MIDI sequence form the specified URL, and sets the sequence. If + * variable 'sequencer' is null or an error occurs, then variable 'sequence' + * remains null. + * @param midiSource URL to a MIDI file. + */ + private void setSequence( URL midiSource ) + { + if( sequencer == null ) + { + errorMessage( "Unable to update the sequence in method " + + "'setSequence', because variable 'sequencer' " + + "is null" ); + return; + } + + if( midiSource == null ) + { + errorMessage( "Unable to load Midi file in method 'setSequence'." ); + return; + } + + try + { + sequence = MidiSystem.getSequence( midiSource ); + } + catch( IOException ioe ) + { + errorMessage( "Input failed while reading from MIDI file in " + + "method 'setSequence'." ); + printStackTrace( ioe ); + return; + } + catch( InvalidMidiDataException imde ) + { + errorMessage( "Invalid MIDI data encountered, or not a MIDI " + + "file in method 'setSequence' (1)." ); + printStackTrace( imde ); + return; + } + if( sequence == null ) + { + errorMessage( "MidiSystem 'getSequence' method returned null " + + "in method 'setSequence'." ); + } + else + { + try + { + sequencer.setSequence( sequence ); + } + catch( InvalidMidiDataException imde ) + { + errorMessage( "Invalid MIDI data encountered, or not a MIDI " + + "file in method 'setSequence' (2)." ); + printStackTrace( imde ); + return; + } + catch( Exception e ) + { + errorMessage( "Problem setting sequence from MIDI file in " + + "method 'setSequence'." ); + printStackTrace( e ); + return; + } + } + } + +/** + * First attempts to load the specified "override MIDI synthesizer" if one was + * defined. If none was defined or unable to use it, then attempts to load the + * default synthesizer. If that fails, then other common synthesizers are + * attempted. If none can be loaded, then MIDI is not possible on this system. + */ + private void getSynthesizer() + { + if( sequencer == null ) + { + errorMessage( "Unable to load a Synthesizer in method " + + "'getSynthesizer', because variable 'sequencer' " + + "is null" ); + return; + } + + // Check if an alternate MIDI synthesizer was specified to use + String overrideMIDISynthesizer = + SoundSystemConfig.getOverrideMIDISynthesizer(); + if( overrideMIDISynthesizer != null + && !overrideMIDISynthesizer.equals( "" ) ) + { + // Try and open the specified device: + synthDevice = openMidiDevice( overrideMIDISynthesizer ); + // See if we got it: + if( synthDevice != null ) + { + // Got it, try and link it to the sequencer: + try + { + sequencer.getTransmitter().setReceiver( + synthDevice.getReceiver() ); + // Success! + return; + } + catch( MidiUnavailableException mue ) + { + // Problem linking the two, let the user know + errorMessage( "Unable to link sequencer transmitter " + + "with receiver for MIDI device '" + + overrideMIDISynthesizer + "'" ); + } + } + } + + // No alternate MIDI synthesizer was specified, or unable to use it. + + // If the squencer were also a synthesizer, that would make things easy: + if( sequencer instanceof Synthesizer ) + { + synthesizer = (Synthesizer) sequencer; + } + else + { + // Try getting the default synthesizer first: + try + { + synthesizer = MidiSystem.getSynthesizer(); + synthesizer.open(); + } + catch( MidiUnavailableException mue ) + { + message( "Unable to open the default synthesizer" ); + synthesizer = null; + } + + // See if we were sucessful: + if( synthesizer == null ) + { + // Try for the common MIDI synthesizers: + synthDevice = openMidiDevice( "Java Sound Synthesizer" ); + if( synthDevice == null ) + synthDevice = openMidiDevice( "Microsoft GS Wavetable" ); + if( synthDevice == null ) + synthDevice = openMidiDevice( "Gervill" ); + if( synthDevice == null ) + { + // Still nothing, MIDI is not going to work + errorMessage( "Failed to find an available MIDI " + + "synthesizer" ); + return; + } + } + + // Are we using the default synthesizer or something else? + if( synthesizer == null ) + { + // Link the sequencer and synthesizer: + try + { + sequencer.getTransmitter().setReceiver( + synthDevice.getReceiver() ); + } + catch( MidiUnavailableException mue ) + { + errorMessage( "Unable to link sequencer transmitter " + + "with MIDI device receiver" ); + } + } + else + { + // Bug-fix for multiple-receivers playing simultaneously + if( synthesizer.getDefaultSoundbank() == null ) + { + // Link the sequencer to the default receiver: + try + { + sequencer.getTransmitter().setReceiver( + MidiSystem.getReceiver() ); + } + catch( MidiUnavailableException mue ) + { + errorMessage( "Unable to link sequencer transmitter " + + "with default receiver" ); + } + } + else + { + // Link the sequencer to the default synthesizer: + try + { + sequencer.getTransmitter().setReceiver( + synthesizer.getReceiver() ); + } + catch( MidiUnavailableException mue ) + { + errorMessage( "Unable to link sequencer transmitter " + + "with synthesizer receiver" ); + } + } + // End bug-fix + } + } + } + +/** + * Attempts to open the Sequencer with a name containing the specified string. + * @param containsString Part or all of a Sequencer's name. + * @return Handle to the Sequencer, or null if not found or error. + */ + private Sequencer openSequencer( String containsString ) + { + Sequencer s = null; + s = (Sequencer) openMidiDevice( containsString ); + if( s == null ) + return null; + try + { + s.getTransmitter(); + } + catch( MidiUnavailableException mue ) + { + message( " Unable to get a transmitter from this sequencer" ); + s = null; + return null; + } + + return s; + } + +/** + * Attempts to open the MIDI device with a name containing the specified + * string. + * @param containsString Part or all of a MIDI device's name. + * @return Handle to the MIDI device, or null if not found or error. + */ + private MidiDevice openMidiDevice( String containsString ) + { + message( "Searching for MIDI device with name containing '" + + containsString + "'" ); + MidiDevice device = null; + MidiDevice.Info[] midiDevices = MidiSystem.getMidiDeviceInfo(); + for( int i = 0; i < midiDevices.length; i++ ) + { + device = null; + try + { + device = MidiSystem.getMidiDevice( midiDevices[i] ); + } + catch( MidiUnavailableException e ) + { + message( " Problem in method 'getMidiDevice': " + + "MIDIUnavailableException was thrown" ); + device = null; + } + if( device != null && midiDevices[i].getName().contains( + containsString ) ) + { + message( " Found MIDI device named '" + + midiDevices[i].getName() + "'" ); + if( device instanceof Synthesizer ) + message( " *this is a Synthesizer instance" ); + if( device instanceof Sequencer ) + message( " *this is a Sequencer instance" ); + try + { + device.open(); + } + catch( MidiUnavailableException mue ) + { + message( " Unable to open this MIDI device" ); + device = null; + } + return device; + } + } + message( " MIDI device not found" ); + return null; + } + +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, "MidiChannel", message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( "MidiChannel", message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } + +/** + * The FadeThread class handles sequence changing, timing, and volume change + * messages in the background. + */ + private class FadeThread extends SimpleThread + { + @Override +/** + * Runs in the background, timing fade in and fade out, changing the sequence, + * and issuing the appropriate volume change messages. + */ + public void run() + { + while( !dying() ) + { + // if not currently fading in or out, put the thread to sleep + if( fadeOutGain == -1.0f && fadeInGain == 1.0f ) + snooze( 3600000 ); + checkFadeOut(); + // only update every 50 miliseconds (no need to peg the cpu) + snooze( 50 ); + } + // Important! + cleanup(); + } + } + +} + diff --git a/src/lwjgl/java/paulscode/sound/SimpleThread.java b/src/lwjgl/java/paulscode/sound/SimpleThread.java new file mode 100644 index 0000000..8bd65fa --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SimpleThread.java @@ -0,0 +1,200 @@ +package paulscode.sound; + + +/** + * The SimpleThread class is the template used to create all thread classes + * used by in the SoundSystem library. It provides methods for common actions + * like sleeping, killing, and checking liveness. NOTE: super.cleanup() must + * be called at the bottom of overriden cleanup() methods, and cleanup() + * must be called at the bottom of the run() method for all extended classes. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SimpleThread extends Thread +{ +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; + +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * True when thread is running. + */ + private boolean alive = true; + +/** + * True when thread should end. + */ + private boolean kill = false; + +/** + * Removes all references to instantiated objects, and changes the thread's + * state to "not alive". Method alive() returns false when this method has + * completed. NOTE: super.cleanup() must be called at the bottom of overriden + * cleanup() methods, and cleanup() must be called at the bottom of the run() + * method for all extended classes. + */ + protected void cleanup() + { + kill( SET, true ); // tread needs to shut down + alive( SET, false ); // thread has ended + } + +/** + * Executes the thread's main loop. NOTES: Extended classes should check + * method dying() often to know when the user wants the thread to shut down. + * Method cleanup() must be called at the bottom of the run() method for all + * extended classes. + */ + @Override + public void run() + { + /* How the run() method should be set up: */ + + + // Do your stuff here. Remember to check dying() often to know when + // the user wants the thread to shut down. + + // MUST call cleanup() at the bottom of Overridden run() method!!!!! + cleanup(); // clears memory and sets status to dead. + } + +/** + * Calls the rerun() method on a seperate thread, which calls run() when the + * previous thread finishes. + */ + public void restart() + { + new Thread() + { + @Override + public void run() + { + rerun(); + } + }.start(); + } + +/** + * Kills the previous thread, waits for it to die, then calls run(). + */ + private void rerun() + { + kill( SET, true ); + while( alive( GET, XXX ) ) + { + snooze( 100 ); + } + alive( SET, true ); + kill( SET, false ); + run(); + } + +/** + * Returns false when the cleanup() method has finished. This method should be + * used to know when the thread has been safely shut down. + * @return True while the thread is alive. + */ + public boolean alive() + { + return alive( GET, XXX ); + } + +/** + * Causes method dying() to return true, letting the thread know it needs to + * shut down. + */ + public void kill() + { + kill( SET, true ); + } + +/** + * Returns true when the thread is supposed to shut down. + * @return True if the thread should die. + */ + protected boolean dying() + { + return kill( GET, XXX ); + } + +/** + * Sets or returns the value of boolean 'alive'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True while the thread is alive. + */ + private synchronized boolean alive( boolean action, boolean value ) + { + if( action == SET ) + alive = value; + return alive; + } + +/** + * Sets or returns the value of boolean 'kill'. + * @param action GET or SET. + * @param value New value if action == SET, or XXX if action == GET. + * @return True if the thread should die. + */ + private synchronized boolean kill( boolean action, boolean value ) + { + if( action == SET ) + kill = value; + return kill; + } + +/** + * Sleeps for the specified number of milliseconds. + */ + protected void snooze( long milliseconds ) + { + try + { + Thread.sleep( milliseconds ); + } + catch( InterruptedException e ){} + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundBuffer.java b/src/lwjgl/java/paulscode/sound/SoundBuffer.java new file mode 100644 index 0000000..b258502 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundBuffer.java @@ -0,0 +1,91 @@ +package paulscode.sound; + +import javax.sound.sampled.AudioFormat; + +/** + * The SoundBuffer class is used to wrap audio data along with the format in + * which the data is stored. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundBuffer +{ +/** + * The actual audio data. + */ + public byte[] audioData; +/** + * The audio format in which the data is stored. + */ + public AudioFormat audioFormat; + +/** + * Constructor: Wraps the specified data with the specified audio format. + * + * @param audioData The actual audio data. + * @param audioFormat The audio format in which the data is stored. + */ + public SoundBuffer( byte[] audioData, AudioFormat audioFormat ) + { + this.audioData = audioData; + this.audioFormat = audioFormat; + } + +/** + * Removes handles to all instantiated objects. + */ + public void cleanup() + { + audioData = null; + audioFormat = null; + } + +/** + * Trims down the size of the audio data if it is larger than the specified + * maximum length. + * + * @param maxLength Maximum size this buffer may be. + */ + public void trimData( int maxLength ) + { + if( audioData == null || maxLength == 0 ) + audioData = null; + else if( audioData.length > maxLength ) + { + byte[] trimmedArray = new byte[maxLength]; + System.arraycopy( audioData, 0, trimmedArray, 0, + maxLength ); + audioData = trimmedArray; + } + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystem.java b/src/lwjgl/java/paulscode/sound/SoundSystem.java new file mode 100644 index 0000000..0f25617 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystem.java @@ -0,0 +1,2895 @@ +package paulscode.sound; + +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Random; +import java.util.Set; +import javax.sound.sampled.AudioFormat; + +/** + * The SoundSystem class is the core class for the SoundSystem library. It is + * capable of interfacing with external sound library and codec library + * pluggins. This core class is stripped down to give it a smaller memory + * footprint and to make it more customizable. This library was created to + * provide a simple, common interface to a variety of 3rd-party sound and codec + * libraries, and to simplify switching between them on the fly. If no + * external pluggins are loaded, this core class by itself is only capable of + * playing MIDI files. Specific implementations (such as SoundSystemJPCT) will + * extend this core class. They will automatically link with popular + * external pluggins and provide extra methods for ease of use. + * There should be only one instance of this class in any program! The + * SoundSystem can be constructed by defining which sound library to use, or by + * allowing SoundSystem to perform its own library compatibility checking. See + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for information + * about changing default settings and linking with external pluggins. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystem +{ +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Processes status messages, warnings, and error messages. + */ + protected SoundSystemLogger logger; + +/** + * Handle to the active sound library. + */ + protected Library soundLibrary; + +/** + * List of queued commands to perform. + */ + protected List commandQueue; + +/** + * Used internally by SoundSystem to keep track of play/pause/stop/rewind + * commands. This prevents source management (culling and activating) from + * being adversely affected by the quickPlay, quickStream, and backgroundMusic + * methods. + */ + private List sourcePlayList; + +/** + * Processes queued commands in the background. + */ + protected CommandThread commandThread; + +/** + * Generates random numbers. + */ + public Random randomNumberGenerator; + +/** + * Name of this class. + */ + protected String className = "SoundSystem"; + +/** + * Indicates the currently loaded sound-library, or null if none. + */ + private static Class currentLibrary = null; + +/** + * Becomes true when the sound library has been initialized. + */ + private static boolean initialized = false; + +/** + * Indicates the last exception that was thrown. + */ + private static SoundSystemException lastException = null; + +/** + * Constructor: Create the sound system using the default library. If the + * default library is not compatible, another library type will be loaded + * instead, in the order of library preference. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about sound library types. + */ + public SoundSystem() + { + // create the message logger: + logger = SoundSystemConfig.getLogger(); + // if the user didn't create one, then do it now: + if( logger == null ) + { + logger = new SoundSystemLogger(); + SoundSystemConfig.setLogger( logger ); + } + + linkDefaultLibrariesAndCodecs(); + + LinkedList libraries = SoundSystemConfig.getLibraries(); + + if( libraries != null ) + { + ListIterator i = libraries.listIterator(); + Class c; + while( i.hasNext() ) + { + c = i.next(); + try + { + init( c ); + return; + } + catch( SoundSystemException sse ) + { + logger.printExceptionMessage( sse, 1 ); + } + } + } + try + { + init( Library.class ); + return; + } + catch( SoundSystemException sse ) + { + logger.printExceptionMessage( sse, 1 ); + } + } + +/** + * Constructor: Create the sound system using the specified library. + * @param libraryClass Library to use. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + public SoundSystem( Class libraryClass ) throws SoundSystemException + { + // create the message logger: + logger = SoundSystemConfig.getLogger(); + // if the user didn't create one, then do it now: + if( logger == null ) + { + logger = new SoundSystemLogger(); + SoundSystemConfig.setLogger( logger ); + } + linkDefaultLibrariesAndCodecs(); + + init( libraryClass ); + } + +/** + * Links with any default libraries or codecs should be made in this method. + * This method is empty in the core SoundSystem class, and should be overriden + * by classes which extend SoundSystem. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about linking with sound libraries and codecs. + */ + protected void linkDefaultLibrariesAndCodecs() + { + } + +/** + * Loads the message logger, initializes the specified sound library, and + * starts the command thread. Also instantiates the random number generator + * and the command queue. + * @param libraryClass Library to initialize. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + protected void init( Class libraryClass ) throws SoundSystemException + { + message( "", 0 ); + message( "Starting up " + className + " version "+ SoundSystem.class.getPackage().getImplementationVersion()+"...", 0 ); + + // create the random number generator: + randomNumberGenerator = new Random(); + // create the command queue: + commandQueue = new LinkedList(); + // create the working source playlist: + sourcePlayList = new LinkedList(); + + // Instantiate and start the Command Processer thread: + commandThread = new CommandThread( this ); // Gets a SoundSystem handle + commandThread.start(); + + snooze( 200 ); + + newLibrary( libraryClass ); + message( "", 0 ); + } + +/** + * Ends the command thread, shuts down the sound system, and removes references + * to all instantiated objects. + */ + public void cleanup() + { + boolean killException = false; + message( "", 0 ); + message( className + " shutting down...", 0 ); + + // End the command thread: + try + { + commandThread.kill(); // end the command processor loop. + commandThread.interrupt(); // wake the thread up so it can end. + } + catch( Exception e ) + { + killException = true; + } + + if( !killException ) + { + // wait up to 5 seconds for command thread to end: + for( int i = 0; i < 50; i++ ) + { + if( !commandThread.alive() ) + break; + snooze( 100 ); + } + } + + // Let user know if there was a problem ending the command thread + if( killException || commandThread.alive() ) + { + errorMessage( "Command thread did not die!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + initialized( SET, false ); + currentLibrary( SET, null ); + try + { + // Stop all sources and shut down the sound library: + if( soundLibrary != null ) + soundLibrary.cleanup(); + } + catch( Exception e ) + { + errorMessage( "Problem during Library.cleanup()!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + try + { + // remove any queued commands: + if( commandQueue != null ) + commandQueue.clear(); + } + catch( Exception e ) + { + errorMessage( "Unable to clear the command queue!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + try + { + // empty the source management list: + if( sourcePlayList != null ) + sourcePlayList.clear(); + } + catch( Exception e ) + { + errorMessage( "Unable to clear the source management list!", 0 ); + message( "Ignoring errors... continuing clean-up.", 0 ); + } + + // Remove references to all instantiated objects: + randomNumberGenerator = null; + soundLibrary = null; + commandQueue = null; + sourcePlayList = null; + commandThread = null; + + importantMessage( "Author: Paul Lamb, www.paulscode.com", 1 ); + message( "", 0 ); + } + +/** + * Wakes up the Command Thread to process commands. This method should be + * used if there is a need to call methods 'ManageSources' and 'CommandQueue' + * externally. In most cases, this method will not be needed, since + * SoundSystem automatically wakes the Command Thread every time commands are + * placed into either the ManageSources queue or CommandQueue to be processed. + */ + public void interruptCommandThread() + { + if( commandThread == null ) + { + errorMessage( "Command Thread null in method " + + "'interruptCommandThread'", 0 ); + return; + } + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Pre-loads a sound into memory. The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL's. If the file + * is located within the compiled JAR, the package in which sound files are + * located may be set by calling SoundSystemConfig.setSoundFilesPackage(). + * @param filename Filename of the sound file to load. + */ + public void loadSound( String filename ) + { + // Queue a command to load the sound file: + CommandQueue( new CommandObject( CommandObject.LOAD_SOUND, + new FilenameURL( filename ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Pre-loads a sound specified by the given URL into memory. The second + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. + * @param url URL handle to the sound file to load. + * @param identifier Filename/identifier of the file referenced by the URL. + */ + public void loadSound( URL url, String identifier ) + { + // Queue a command to load the sound file from a URL: + CommandQueue( new CommandObject( CommandObject.LOAD_SOUND, + new FilenameURL( url, identifier ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Saves raw PCM audio data in the specified audio format, under the specified + * identifier. This identifier can be later used in place of 'filename' + * parameters to reference the sample data. + * @param data The sample data + * @param format Format the sample data is stored in + * @param identifier What to call the sample. + */ + public void loadSound( byte[] data, AudioFormat format, String identifier ) + { + // Queue a command to load the sound file from a URL: + CommandQueue( new CommandObject( CommandObject.LOAD_DATA, + identifier, + new SoundBuffer( data, format ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + + +/** + * Removes a pre-loaded sound from memory. This is a good method to use for + * freeing up memory after a large sound file is no longer needed. NOTE: the + * source will remain in memory after calling this method as long as the + * sound is attached to an existing source. When calling this method, calls + * should also be made to method removeSource( String ) for all sources which + * this sound is bound to. + * @param filename Filename/identifier of the sound file to unload. + */ + public void unloadSound( String filename ) + { + // Queue a command to unload the sound file: + CommandQueue( new CommandObject( CommandObject.UNLOAD_SOUND, filename ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. The file + * may either be located within the JAR or at an online location. If the file + * is online, filename must begin with "http://", since that is how SoundSystem + * recognizes URL paths. If the file is located within the compiled JAR, the + * package in which sound files are located may be set by calling + * SoundSystemConfig.setSoundFilesPackage(). This method has no effect on + * non-streaming sources. + * @param sourcename Source identifier. + * @param filename Name of the sound file to play next. + */ + public void queueSound( String sourcename, String filename ) + { + // Queue a command to queue the sound: + CommandQueue( new CommandObject( CommandObject.QUEUE_SOUND, sourcename, + new FilenameURL( filename ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. The third + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. This method has no effect on non-streaming + * sources. + * @param sourcename Source identifier. + * @param url URL handle to the sound file to load. + * @param identifier Filename/identifier of the file referenced by the URL. + */ + public void queueSound( String sourcename, URL url, String identifier ) + { + // Queue a command to queue the sound: + CommandQueue( new CommandObject( CommandObject.QUEUE_SOUND, sourcename, + new FilenameURL( url, identifier ) ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Removes the first occurrence of the specified filename/identifier from the + * specified source's list of sounds to play when previous playback ends. This + * method has no effect on non-streaming sources. + * @param sourcename Source identifier. + * @param filename Filename/identifier of the sound file to play next. + */ + public void dequeueSound( String sourcename, String filename ) + { + // Queue a command to dequeue the sound: + CommandQueue( new CommandObject( CommandObject.DEQUEUE_SOUND, + sourcename, filename ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. The file may either be located within the JAR or at + * an online location. If the file is online, filename must begin with + * "http://", since that is how SoundSystem recognizes URL paths. If the file + * is located within the compiled JAR, the package in which sound files are + * located may be set by calling SoundSystemConfig.setSoundFilesPackage(). If + * the filename parameter is null or empty, the specified source will simply + * fade out and stop. The miliseconds parameter must be non-negative or zero. + * This method will remove anything that is currently in the specified source's + * list of queued sounds that would have played next when the current sound + * finished playing. This method may only be used for streaming and MIDI + * sources. + * @param sourcename Name of the source to fade out. + * @param filename Name of a sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( String sourcename, String filename, long milis ) + { + FilenameURL fu = null; + if( filename != null ) + fu = new FilenameURL( filename ); + // Queue a command to fade out: + CommandQueue( new CommandObject( CommandObject.FADE_OUT, sourcename, fu, + milis ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. If the url parameter is null or empty, the + * specified source will simply fade out and stop. The third + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. The miliseconds parameter must be + * non-negative or zero. This method will remove anything that is currently in + * the specified source's list of queued sounds that would have played next + * when the current sound finished playing. This method may only be used for + * streaming and MIDI sources. + * @param sourcename Name of the source to fade out. + * @param url URL handle to the sound file to play next, or null for none. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( String sourcename, URL url, String identifier, + long milis ) + { + FilenameURL fu = null; + if( url != null && identifier != null ) + fu = new FilenameURL( url, identifier ); + // Queue a command to fade out: + CommandQueue( new CommandObject( CommandObject.FADE_OUT, sourcename, fu, + milis ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified filename. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The filename parameter may not be null or empty. The file + * may either be located within the JAR or at an online location. If the file + * is online, filename must begin with "http://", since that is how + * SoundSystem recognizes URL paths. If the file is located within the + * compiled JAR, the package in which sound files are located may be set by + * calling SoundSystemConfig.setSoundFilesPackage(). The miliseconds + * parameters must be non-negative or zero. This method will remove anything + * that is currently in the specified source's list of queued sounds that would + * have played next when the current sound finished playing. This method may + * only be used for streaming and MIDI sources. + * @param sourcename Name of the source to fade out/in. + * @param filename Name of a sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( String sourcename, String filename, long milisOut, + long milisIn ) + { + // Queue a command to load the sound file: + CommandQueue( new CommandObject( CommandObject.FADE_OUT_IN, + sourcename, + new FilenameURL( filename ), milisOut, + milisIn ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified file. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The url parameter may not be null or empty. The third + * parameter 'identifier' should look like a filename, and it must have the + * correct extension so SoundSystem knows what codec to use for the file + * referenced by the URL instance. The miliseconds parameters must be + * non-negative or zero. This method will remove anything that is currently + * in the specified source's list of queued sounds that would have played next + * when the current sound finished playing. This method may only be used for + * streaming and MIDI sources. + * @param sourcename Name of the source to fade out/in. + * @param url URL handle to the sound file to play next. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( String sourcename, URL url, String identifier, + long milisOut, long milisIn ) + { + // Queue a command to load the sound file: + CommandQueue( new CommandObject( CommandObject.FADE_OUT_IN, + sourcename, + new FilenameURL( url, identifier ), + milisOut, milisIn ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Makes sure the current volume levels of streaming sources and MIDI are + * correct. This method is designed to help reduce the "jerky" fading behavior + * that happens when using some library and codec pluggins (such as + * LibraryJavaSound and CodecJOrbis). This method has no effect on normal + * "non-streaming" sources. It would normally be called somewhere in the main + * "game loop". IMPORTANT: To optimize frame-rates, do not call this method + * for every frame. It is better to just call this method at some acceptable + * "granularity" (play around with different granularities to find what sounds + * acceptable for a particular situation). + */ + public void checkFadeVolumes() + { + // Queue a command to load check fading source volumes: + CommandQueue( new CommandObject( CommandObject.CHECK_FADE_VOLUMES ) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + } + +/** + * Creates a new permanant, streaming, priority source with zero attenuation. + * The file may either be located within the JAR or at an online location. If + * the file is online, filename must begin with "http://", since that is how + * SoundSystem recognizes URL paths. If the file is located within the + * compiled JAR, the package in which sound files are located may be set by + * calling SoundSystemConfig.setSoundFilesPackage(). + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filename Filename of the sound file to stream at this source. + * @param toLoop Should this source loop, or play only once. + */ + public void backgroundMusic( String sourcename, String filename, + boolean toLoop ) + { + // Queue a command to quick stream a new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, true, + true, toLoop, sourcename, + new FilenameURL( filename ), 0, 0, 0, + SoundSystemConfig.ATTENUATION_NONE, 0, false ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + + commandThread.interrupt(); + } + +/** + * Creates a new permanant, streaming, priority source with zero attenuation. + * The third parameter 'identifier' should look like a filename, and it must + * have the correct extension so SoundSystem knows what codec to use for the + * file referenced by the URL instance. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + */ + public void backgroundMusic( String sourcename, URL url, String identifier, + boolean toLoop ) + { + // Queue a command to quick stream a new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, true, + true, toLoop, sourcename, + new FilenameURL( url, identifier ), + 0, 0, 0, + SoundSystemConfig.ATTENUATION_NONE, + 0, false ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + + commandThread.interrupt(); + } + +/** + * Creates a new non-streaming source. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation, fade distance, and rolloff factor. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filename Filename/identifier of the sound file to play at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newSource( boolean priority, String sourcename, String filename, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + false, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a new non-streaming source. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation, fade distance, and rolloff factor. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newSource( boolean priority, String sourcename, URL url, + String identifier, boolean toLoop, float x, float y, + float z, int attmodel, float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + false, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, + attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a new streaming source. The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL paths. If the + * file is located within the compiled JAR, the package in which sound files + * are located may be set by calling SoundSystemConfig.setSoundFilesPackage(). + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filename The filename of the sound file to play at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newStreamingSource( boolean priority, String sourcename, + String filename, boolean toLoop, float x, + float y, float z, int attmodel, + float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + true, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a new streaming source. The fourth parameter 'identifier' should + * look like a filename, and it must have the correct extension so SoundSystem + * knows what codec to use for the file referenced by the URL instance. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void newStreamingSource( boolean priority, String sourcename, + URL url, String identifier, boolean toLoop, + float x, float y, float z, int attmodel, + float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.NEW_SOURCE, priority, + true, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, attmodel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Opens a direct line for streaming audio data. This method creates a new + * streaming source to play the data at. The resulting streaming source can be + * manipulated the same as any other streaming source. Raw data can be sent to + * the new streaming source using the feedRawAudioData() method. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + public void rawDataStream( AudioFormat audioFormat, boolean priority, + String sourcename, float x, float y, float z, + int attModel, float distOrRoll ) + { + CommandQueue( new CommandObject( CommandObject.RAW_DATA_STREAM, + audioFormat, priority, sourcename, x, + y, z, attModel, distOrRoll ) ); + commandThread.interrupt(); + } + +/** + * Creates a temporary source and plays it. After the source finishes playing, + * it is removed. Returns a randomly generated name for the new source. NOTE: + * to make a source created by this method permanant, call the setActive() + * method using the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param filename Filename/identifier of the sound file to play at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickPlay( boolean priority, String filename, boolean toLoop, + float x, float y, float z, int attmodel, + float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick play this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + false, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll, true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } + +/** + * Creates a temporary source and plays it. After the source finishes playing, + * it is removed. Returns a randomly generated name for the new source. NOTE: + * to make a source created by this method permanant, call the setActive() + * method using the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickPlay( boolean priority, URL url, String identifier, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick play this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + false, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, attmodel, distOrRoll, + true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } + +/** + * Creates a temporary source and streams it. After the source finishes + * playing, it is removed. The file may either be located within the + * JAR or at an online location. If the file is online, filename must begin + * with "http://", since that is how SoundSystem recognizes URL paths. If the + * file is located within the compiled JAR, the package in which sound files + * are located may be set by calling SoundSystemConfig.setSoundFilesPackage(). + * Returns a randomly generated name for the new source. NOTE: to make a + * source created by this method permanant, call the setActive() method using + * the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param filename Filename of the sound file to stream at this source. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickStream( boolean priority, String filename, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick stream this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + true, toLoop, sourcename, + new FilenameURL( filename ), x, y, z, + attmodel, distOrRoll, true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } +/** + * Creates a temporary source and streams it. After the source finishes + * playing, it is removed. The third parameter 'identifier' should + * look like a filename, and it must have the correct extension so SoundSystem + * knows what codec to use for the file referenced by the URL instance. + * Returns a randomly generated name for the new source. NOTE: to make a + * source created by this method permanant, call the setActive() method using + * the return value for sourcename. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param url URL handle to the sound file to stream at this source. + * @param identifier Filename/identifier of the file referenced by the URL. + * @param toLoop Should this source loop, or play only once. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attmodel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @return The new sorce's name. + */ + public String quickStream( boolean priority, URL url, String identifier, + boolean toLoop, float x, float y, float z, + int attmodel, float distOrRoll ) + { + //generate a random name for this source: + String sourcename = "Source_" + + randomNumberGenerator.nextInt() + + "_" + randomNumberGenerator.nextInt(); + + // Queue a command to quick stream this new source: + CommandQueue( new CommandObject( CommandObject.QUICK_PLAY, priority, + true, toLoop, sourcename, + new FilenameURL( url, identifier ), + x, y, z, attmodel, distOrRoll, + true ) ); + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + // Wake the command thread to process commands: + commandThread.interrupt(); + + // return the new source name. + return sourcename; + } + +/** + * Move a source to the specified location. + * @param sourcename Identifier for the source. + * @param x destination X coordinate. + * @param y destination Y coordinate. + * @param z destination Z coordinate. + */ + public void setPosition( String sourcename, float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_POSITION, + sourcename, x, y, z ) ); + commandThread.interrupt(); + } +/** + * Manually sets the specified source's volume. + * @param sourcename Source to move. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + public void setVolume( String sourcename, float value ) + { + CommandQueue( new CommandObject( CommandObject.SET_VOLUME, + sourcename, value ) ); + commandThread.interrupt(); + } + +/** + * Returns the current volume of the specified source, or zero if the specified + * source was not found. + * @param sourcename Source to read volume from. + * @return Float value representing the source volume (0.0f - 1.0f). + */ + public float getVolume( String sourcename ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary != null ) + return soundLibrary.getVolume( sourcename ); + else + return 0.0f; + } + } + +/** + * Manually sets the specified source's pitch. + * @param sourcename The source's name. + * @param value A float value ( 0.5f - 2.0f ). + */ + public void setPitch( String sourcename, float value ) + { + CommandQueue( new CommandObject( CommandObject.SET_PITCH, + sourcename, value ) ); + commandThread.interrupt(); + } + +/** + * Returns the pitch of the specified source. + * @param sourcename The source's name. + * @return Float value representing the source pitch (0.5f - 2.0f). + */ + public float getPitch( String sourcename ) + { + if( soundLibrary != null ) + return soundLibrary.getPitch( sourcename ); + else + return 1.0f; + } + +/** + * Set a source's priority factor. A priority source will not be overriden when + * too many sources are playing at once. + * @param sourcename Identifier for the source. + * @param pri Setting this to true makes this source a priority source. + */ + public void setPriority( String sourcename, boolean pri ) + { + CommandQueue( new CommandObject( CommandObject.SET_PRIORITY, + sourcename, pri ) ); + commandThread.interrupt(); + } +/** + * Changes a source to looping or non-looping. + * @param sourcename Identifier for the source. + * @param lp This source should loop. + */ + public void setLooping( String sourcename, boolean lp ) + { + CommandQueue( new CommandObject( CommandObject.SET_LOOPING, + sourcename, lp ) ); + commandThread.interrupt(); + } +/** + * Changes a source's attenuation model. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation. + * @param sourcename Identifier for the source. + * @param model Attenuation model to use. + */ + public void setAttenuation( String sourcename, int model ) + { + CommandQueue( new CommandObject( CommandObject.SET_ATTENUATION, + sourcename, model ) ); + commandThread.interrupt(); + } +/** + * Changes a source's fade distance or rolloff factor. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about fade distance and rolloff. + * @param sourcename Identifier for the source. + * @param dr Either the fading distance or rolloff factor, depending on the attenuation model used. + */ + public void setDistOrRoll( String sourcename, float dr) + { + CommandQueue( new CommandObject( CommandObject.SET_DIST_OR_ROLL, + sourcename, dr ) ); + commandThread.interrupt(); + } + +/** + * Changes the Doppler factor, for determining Doppler effect scale. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerFactor New value for Doppler factor. + */ + public void changeDopplerFactor( float dopplerFactor) + { + CommandQueue( new CommandObject( CommandObject.CHANGE_DOPPLER_FACTOR, + dopplerFactor ) ); + commandThread.interrupt(); + } + +/** + * Changes the Doppler velocity, for use in Doppler effect. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerVelocity New value for Doppler velocity. + */ + public void changeDopplerVelocity( float dopplerVelocity ) + { + CommandQueue( new CommandObject( CommandObject.CHANGE_DOPPLER_VELOCITY, + dopplerVelocity ) ); + commandThread.interrupt(); + } + +/** + * Sets the specified source's velocity, for use in Doppler effect. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param sourcename The source's name. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setVelocity( String sourcename, float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_VELOCITY, + sourcename, x, y, z ) ); + commandThread.interrupt(); + } + +/** + * Sets the listener's velocity, for use in Doppler effect. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setListenerVelocity( float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_VELOCITY, + x, y, z ) ); + commandThread.interrupt(); + } + +/** + * Returns the number of miliseconds since the specified source began playing. + * @return miliseconds, or -1 if not playing or unable to calculate + */ + public float millisecondsPlayed( String sourcename ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + return soundLibrary.millisecondsPlayed( sourcename ); + } + } + +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. Only use this for streaming sources created with the + * rawDataStream() method. NOTE: Be carefull how much data you send to a + * source to stream. The data will be processed at playback speed, so if you + * queue up 1 hour worth of data, it will take 1 hour to play (not to mention + * hogging a ton of memory). To clear out all queued data from the source, use + * the flush() method. Also note: if there is a break in the data stream, + * you will hear clicks and studders, so ensure that the data flow is steady. + * @param sourcename Name of the streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + */ + public void feedRawAudioData( String sourcename, byte[] buffer ) + { + CommandQueue( new CommandObject( CommandObject.FEED_RAW_AUDIO_DATA, + sourcename, buffer ) ); + commandThread.interrupt(); + } +/** + * Plays the specified source. + * @param sourcename Identifier for the source. + */ + public void play( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.PLAY, sourcename) ); + commandThread.interrupt(); + } +/** + * Pauses the specified source. + * @param sourcename Identifier for the source. + */ + public void pause( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.PAUSE, sourcename) ); + commandThread.interrupt(); + } +/** + * Stops the specified source. + * @param sourcename Identifier for the source. + */ + public void stop( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.STOP, sourcename) ); + commandThread.interrupt(); + } +/** + * Rewinds the specified source. + * @param sourcename Identifier for the source. + */ + public void rewind( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.REWIND, sourcename) ); + commandThread.interrupt(); + } +/** + * Flushes all previously queued audio data from a streaming source. + * @param sourcename Identifier for the source. + */ + public void flush( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.FLUSH, sourcename) ); + commandThread.interrupt(); + } + +/** + * Culls the specified source. A culled source can not be played until it has + * been activated again. + * @param sourcename Identifier for the source. + */ + public void cull( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.CULL, sourcename) ); + commandThread.interrupt(); + } + +/** + * Activates the specified source after it was culled, so it can be played + * again. + * @param sourcename Identifier for the source. + */ + public void activate( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.ACTIVATE, sourcename) ); + commandThread.interrupt(); + } + +/** + * Sets a flag for a source indicating whether it should be used or if it + * should be removed after it finishes playing. One possible use for this + * method is to make temporary sources that were created with quickPlay() + * permanant. Another use could be to have a source automatically removed + * after it finishes playing. NOTE: Setting a source to temporary does not + * stop it, and setting a source to permanant does not play it. It is also + * important to note that a looping temporary source will not be removed as + * long as it keeps playing. + * @param sourcename Identifier for the source. + * @param temporary True = temporary, False = permanant. + */ + public void setTemporary( String sourcename, boolean temporary ) + { + CommandQueue( new CommandObject( CommandObject.SET_TEMPORARY, + sourcename, temporary ) ); + commandThread.interrupt(); + } + +/** + * Removes the specified source and clears up any memory it used. + * @param sourcename Identifier for the source. + */ + public void removeSource( String sourcename ) + { + CommandQueue( new CommandObject( CommandObject.REMOVE_SOURCE, + sourcename ) ); + commandThread.interrupt(); + } +/** + * Moves the listener relative to the current location. + * @param x X offset. + * @param y Y offset. + * @param z Z offset. + */ + public void moveListener( float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.MOVE_LISTENER, + x, y, z ) ); + commandThread.interrupt(); + } +/** + * Moves the listener to the specified location. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + public void setListenerPosition( float x, float y, float z ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_POSITION, + x, y, z ) ); + commandThread.interrupt(); + } +/** + * Turns the listener counterclockwise by "angle" radians around the y-axis, + * relative to the current angle. + * @param angle radian offset. + */ + public void turnListener( float angle ) + { + CommandQueue( new CommandObject( CommandObject.TURN_LISTENER, + angle ) ); + commandThread.interrupt(); + } +/** + * Sets the listener's angle in radians around the y-axis. + * @param angle radians. + */ + public void setListenerAngle( float angle ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_ANGLE, + angle ) ); + commandThread.interrupt(); + } +/** + * Sets the listener's orientation. + * @param lookX X coordinate of the (normalized) look-at vector. + * @param lookY Y coordinate of the (normalized) look-at vector. + * @param lookZ Z coordinate of the (normalized) look-at vector. + * @param upX X coordinate of the (normalized) up-direction vector. + * @param upY Y coordinate of the (normalized) up-direction vector. + * @param upZ Z coordinate of the (normalized) up-direction vector. + */ + public void setListenerOrientation( float lookX, float lookY, float lookZ, + float upX, float upY, float upZ ) + { + CommandQueue( new CommandObject( CommandObject.SET_LISTENER_ORIENTATION, + lookX, lookY, lookZ, upX, upY, upZ ) ); + commandThread.interrupt(); + } + +/** + * Sets the overall volume, affecting all sources. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + public void setMasterVolume( float value ) + { + CommandQueue( new CommandObject( CommandObject.SET_MASTER_VOLUME, + value ) ); + commandThread.interrupt(); + } + +/** + * Returns the overall volume, affecting all sources. + * @return Float value representing the master volume (0.0f - 1.0f). + */ + public float getMasterVolume() + { + return SoundSystemConfig.getMasterGain(); + } + +/** + * Method for obtaining information about the listener's position and + * orientation. + * @return a {@link paulscode.sound.ListenerData ListenerData} object. + */ + public ListenerData getListenerData() + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + return soundLibrary.getListenerData(); + } + } +/** + * Switches to the specified library, and preserves all sources. + * @param libraryClass Library to use. + * @return True if switch was successful. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + public boolean switchLibrary( Class libraryClass ) + throws SoundSystemException + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + initialized( SET, false ); + + HashMap sourceMap = null; + ListenerData listenerData = null; + + boolean wasMidiChannel = false; + MidiChannel midiChannel = null; + FilenameURL midiFilenameURL = null; + String midiSourcename = ""; + boolean midiToLoop = true; + + if( soundLibrary != null ) + { + currentLibrary( SET, null ); + sourceMap = copySources( soundLibrary.getSources() ); + listenerData = soundLibrary.getListenerData(); + midiChannel = soundLibrary.getMidiChannel(); + if( midiChannel != null ) + { + wasMidiChannel = true; + midiToLoop = midiChannel.getLooping(); + midiSourcename = midiChannel.getSourcename(); + midiFilenameURL = midiChannel.getFilenameURL(); + } + + soundLibrary.cleanup(); + soundLibrary = null; + } + message( "", 0 ); + message( "Switching to " + + SoundSystemConfig.getLibraryTitle( libraryClass ), 0 ); + message( "(" + SoundSystemConfig.getLibraryDescription( libraryClass ) + + ")", 1 ); + + try + { + soundLibrary = (Library) libraryClass.newInstance(); + } + catch( InstantiationException ie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( IllegalAccessException iae ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( ExceptionInInitializerError eiie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( SecurityException se ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + + if( errorCheck( soundLibrary == null, "Library null after " + + "initialization in method 'switchLibrary'", 1 ) ) + { + SoundSystemException sse = new SoundSystemException( + className + " did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ); + lastException( SET, sse ); + initialized( SET, true ); + throw sse; + } + + try + { + soundLibrary.init(); + } + catch( SoundSystemException sse ) + { + lastException( SET, sse ); + initialized( SET, true ); + throw sse; + } + + soundLibrary.setListenerData( listenerData ); + if( wasMidiChannel ) + { + if( midiChannel != null ) + midiChannel.cleanup(); + midiChannel = new MidiChannel( midiToLoop, midiSourcename, + midiFilenameURL ); + soundLibrary.setMidiChannel( midiChannel ); + } + soundLibrary.copySources( sourceMap ); + + message( "", 0 ); + + lastException( SET, null ); + initialized( SET, true ); + + return true; + } + } + +/** + * Switches to the specified library, loosing all sources. + * @param libraryClass Library to use. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + public boolean newLibrary( Class libraryClass ) + throws SoundSystemException + { + initialized( SET, false ); + + CommandQueue( new CommandObject( CommandObject.NEW_LIBRARY, + libraryClass ) ); + commandThread.interrupt(); + + for( int x = 0; (!initialized( GET, XXX )) && (x < 100); x++ ) + { + snooze( 400 ); + commandThread.interrupt(); + } + + if( !initialized( GET, XXX ) ) + { + SoundSystemException sse = new SoundSystemException( + className + + " did not load after 30 seconds.", + SoundSystemException.LIBRARY_NULL ); + lastException( SET, sse ); + throw sse; + } + else + { + SoundSystemException sse = lastException( GET, null ); + if( sse != null ) + throw sse; + } + return true; + } + +/** + * Switches to the specified library, loosing all sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the newLibrary() method instead. + * @param libraryClass Library to use. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for + * information about chosing a sound library. + */ + private void CommandNewLibrary( Class libraryClass ) + { + initialized( SET, false ); + + String headerMessage = "Initializing "; + if( soundLibrary != null ) + { + currentLibrary( SET, null ); + // we are switching libraries + headerMessage = "Switching to "; + soundLibrary.cleanup(); + soundLibrary = null; + } + message( headerMessage + + SoundSystemConfig.getLibraryTitle( libraryClass ), 0 ); + message( "(" + SoundSystemConfig.getLibraryDescription( libraryClass ) + + ")", 1 ); + + try + { + soundLibrary = (Library) libraryClass.newInstance(); + } + catch( InstantiationException ie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( IllegalAccessException iae ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( ExceptionInInitializerError eiie ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + catch( SecurityException se ) + { + errorMessage( "The specified library did not load properly", 1 ); + } + + if( errorCheck( soundLibrary == null, "Library null after " + + "initialization in method 'newLibrary'", 1 ) ) + { + lastException( SET, new SoundSystemException( + className + " did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ) ); + importantMessage( "Switching to silent mode", 1 ); + + try + { + soundLibrary = new Library(); + } + catch( SoundSystemException sse ) + { + lastException( SET, new SoundSystemException( + "Silent mode did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ) ); + initialized( SET, true ); + return; + } + } + + try + { + soundLibrary.init(); + } + catch( SoundSystemException sse ) + { + lastException( SET, sse ); + initialized( SET, true ); + return; + } + + lastException( SET, null ); + initialized( SET, true ); + + return; + } +/** + * Calls the library's initialize() method. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly. + */ + private void CommandInitialize() + { + try + { + if( errorCheck( soundLibrary == null, "Library null after " + + "initialization in method 'CommandInitialize'", + 1 ) ) + { + SoundSystemException sse = new SoundSystemException( + className + " did not load properly. " + + "Library was null after initialization.", + SoundSystemException.LIBRARY_NULL ); + lastException( SET, sse ); + throw sse; + } + soundLibrary.init(); + } + catch( SoundSystemException sse ) + { + lastException( SET, sse ); + initialized( SET, true ); + } + } +/** + * Loads sample data from a sound file or URL into memory. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the loadSound() method instead. + * @param filenameURL Filename/URL of the sound file to load. + */ + private void CommandLoadSound( FilenameURL filenameURL ) + { + if( soundLibrary != null ) + soundLibrary.loadSound( filenameURL ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandLoadSound'", 0 ); + } +/** + * Saves the specified sample data, under the specified identifier. This + * identifier can be later used in place of 'filename' parameters to reference + * the sample data. This method is used internally by SoundSystem for thread + * synchronization, and it can not be called directly - please use the + * loadSound() method instead. + * @param buffer the sample data and audio format to save. + * @param identifier What to call the sample. + */ + private void CommandLoadSound( SoundBuffer buffer, String identifier ) + { + if( soundLibrary != null ) + soundLibrary.loadSound( buffer, identifier ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandLoadSound'", 0 ); + } +/** + * Removes previously loaded sampled data from memory. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the unloadSound() method instead. + * @param filename Filename or string identifyer of sound to unload. + */ + private void CommandUnloadSound( String filename ) + { + if( soundLibrary != null ) + soundLibrary.unloadSound( filename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandLoadSound'", 0 ); + } +/** + * If the specified source is a streaming source or MIDI source, this method + * queues up the next sound to play when the previous playback ends. This + * method has no effect on non-streaming sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the queueSound() method instead. + * @param sourcename Source identifier. + * @param filenameURL Filename/URL of the sound file to play next. + */ + private void CommandQueueSound( String sourcename, + FilenameURL filenameURL ) + { + if( soundLibrary != null ) + soundLibrary.queueSound( sourcename, filenameURL ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandQueueSound'", 0 ); + } +/** + * Removes the first occurrence of the specified filename/identifier from the + * specified source's list of sounds to play when previous playback ends. This + * method has no effect on non-streaming sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the dequeueSound() method instead. + * @param sourcename Source identifier. + * @param filename Filename/identifier of the sound file to remove from the queue. + */ + private void CommandDequeueSound( String sourcename, String filename ) + { + if( soundLibrary != null ) + soundLibrary.dequeueSound( sourcename, filename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandDequeueSound'", 0 ); + } +/** + * Fades out the volume of whatever the specified source is currently playing, + * then begins playing the specified file at the source's previously + * assigned volume level. If the filenameURL parameter is null or empty, the + * specified source will simply fade out and stop. The miliseconds parameter + * must be non-negative or zero. This method will remove anything that is + * currently in the specified source's list of queued sounds that would have + * played next when the current sound finished playing. This method may only + * be used for streaming and MIDI sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the fadeOut() method instead. + * @param sourcename Name of the source to fade out. + * @param filenameURL Filename/URL of a sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + private void CommandFadeOut( String sourcename, FilenameURL filenameURL, + long milis ) + { + if( soundLibrary != null ) + soundLibrary.fadeOut( sourcename, filenameURL, milis ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFadeOut'", 0 ); + } +/** + * Fades out the volume of whatever the specified source is currently playing, + * then fades the volume back in playing the specified file. Final volume + * after fade-in completes will be equal to the source's previously assigned + * volume level. The filenameURL parameter may not be null or empty. The + * miliseconds parameters must be non-negative or zero. This method will + * remove anything that is currently in the specified source's list of queued + * sounds that would have played next when the current sound finished playing. + * This method may only be used for streaming and MIDI sources. This method is + * used internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the fadeOutIn() method instead. + * @param sourcename Name of the source to fade out/in. + * @param filenameURL Filename/URL of a sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + private void CommandFadeOutIn( String sourcename, FilenameURL filenameURL, + long milisOut, long milisIn ) + { + if( soundLibrary != null ) + soundLibrary.fadeOutIn( sourcename, filenameURL, milisOut, + milisIn ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFadeOutIn'", 0 ); + } +/** + * Makes sure the current volume levels of streaming sources and MIDI are + * correct. This method is designed to help reduce the "jerky" fading behavior + * that happens when using some library and codec pluggins (such as + * LibraryJavaSound and CodecJOrbis). This method has no effect on normal + * "non-streaming" sources. It would normally be called somewhere in the main + * "game loop". IMPORTANT: To optimize frame-rates, do not call this method + * for every frame. It is better to just call this method at some acceptable + * "granularity" (play around with different granularities to find what sounds + * acceptable for a particular situation). This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the checkFadeVolumes() method instead. + */ + private void CommandCheckFadeVolumes() + { + if( soundLibrary != null ) + soundLibrary.checkFadeVolumes(); + else + errorMessage( "Variable 'soundLibrary' null in method " + + "'CommandCheckFadeVolumes'", 0 ); + } +/** + * Loads a sound file into memory. This method is used internally by + * SoundSystem for thread synchronization, and it can not be called directly - + * please use the newSource() method instead. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Whether or not to stream the source. + * @param toLoop Whether or not to loop the source. + * @param sourcename A unique identifier for the source. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distORroll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + private void CommandNewSource( boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, float x, + float y, float z, int attModel, + float distORroll ) + { + if( soundLibrary != null ) + { + if( filenameURL.getFilename().matches( + SoundSystemConfig.EXTENSION_MIDI ) + && !SoundSystemConfig.midiCodec() ) + { + soundLibrary.loadMidi( toLoop, sourcename, filenameURL ); + } + else + { + soundLibrary.newSource( priority, toStream, toLoop, sourcename, + filenameURL, x, y, z, attModel, + distORroll ); + } + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandNewSource'", 0 ); + } +/** + * Opens a direct line for streaming audio data. This method is used + * internally by SoundSystem, and it can not be called directly - please use + * the rawDataStream() method instead. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + private void CommandRawDataStream( AudioFormat audioFormat, + boolean priority, String sourcename, + float x, float y, float z, + int attModel, float distOrRoll ) + { + if( soundLibrary != null ) + soundLibrary.rawDataStream( audioFormat, priority, sourcename, + x, y, z, attModel, distOrRoll ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandRawDataStream'", 0 ); + } +/** + * Creates a temporary source and either plays or streams it. After the source + * finishes playing, it is removed. This method is used internally by + * SoundSystem for thread synchronization, and it can not be called directly - + * please use the quickPlay() method instead. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Whether or not to stream the source. + * @param toLoop Whether or not to loop the source. + * @param sourcename A unique identifier for the source. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distORroll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @param temporary Whether or not the source should be removed after it finishes playing. + */ + private void CommandQuickPlay( boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, float x, float y, + float z, int attModel, float distORroll, + boolean temporary ) + { + if( soundLibrary != null ) + { + if( filenameURL.getFilename().matches( SoundSystemConfig.EXTENSION_MIDI ) && + !SoundSystemConfig.midiCodec() ) + { + soundLibrary.loadMidi( toLoop, sourcename, filenameURL ); + } + else + { + soundLibrary.quickPlay( priority, toStream, toLoop, sourcename, + filenameURL, x, y, z, attModel, + distORroll, temporary ); + } + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandQuickPlay'", 0 ); + } +/** + * Moves a source to the specified coordinates. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setPosition() method instead. + * @param sourcename Source to move. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + private void CommandSetPosition( String sourcename, float x, float y, + float z) + { + if( soundLibrary != null ) + soundLibrary.setPosition( sourcename, x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandMoveSource'", 0 ); + } +/** + * Manually sets the specified source's volume. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setVolume() method instead. + * @param sourcename Source to change the volume of. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + private void CommandSetVolume( String sourcename, float value ) + { + if( soundLibrary != null ) + soundLibrary.setVolume( sourcename, value ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetVolume'", 0 ); + } +/** + * Manually sets the specified source's pitch. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setPitch() method instead. + * @param sourcename Source to change the pitch of. + * @param value New pitch, float value ( 0.5f - 2.0f ). + */ + private void CommandSetPitch( String sourcename, float value ) + { + if( soundLibrary != null ) + soundLibrary.setPitch( sourcename, value ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetPitch'", 0 ); + } +/** + * Set a source's priority factor. A priority source will not be overriden when + * too many sources are playing at once. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setPriority() method instead. + * @param sourcename Identifier for the source. + * @param pri Setting this to true makes this source a priority source. + */ + private void CommandSetPriority( String sourcename, boolean pri ) + { + if( soundLibrary != null ) + soundLibrary.setPriority( sourcename, pri ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetPriority'", 0 ); + } +/** + * Changes a source to looping or non-looping. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setLooping() method instead. + * @param sourcename Identifier for the source. + * @param lp This source should loop. + */ + private void CommandSetLooping( String sourcename, boolean lp ) + { + if( soundLibrary != null ) + soundLibrary.setLooping( sourcename, lp ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetLooping'", 0 ); + } +/** + * Changes a source's attenuation model. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setAttenuation() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Attenuation. + * @param sourcename Identifier for the source. + * @param model Attenuation model to use. + */ + private void CommandSetAttenuation( String sourcename, int model ) + { + if( soundLibrary != null ) + soundLibrary.setAttenuation( sourcename, model ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetAttenuation'", + 0 ); + } +/** + * Changes a source's fade distance or rolloff factor. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about fade distance and rolloff. + * @param sourcename Identifier for the source. + * @param dr Either the fading distance or rolloff factor, depending on the attenuation model used. + */ + private void CommandSetDistOrRoll( String sourcename, float dr ) + { + if( soundLibrary != null ) + soundLibrary.setDistOrRoll( sourcename, dr ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetDistOrRoll'", + 0 ); + } +/** + * Changes the Doppler factor. This method is used internally by SoundSystem + * for thread synchronization, and it can not be called directly - please use + * the setDopplerFactor() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerFactor New Doppler factor, for determining Doppler effect scale. + */ + private void CommandChangeDopplerFactor( float dopplerFactor ) + { + if( soundLibrary != null ) + { + SoundSystemConfig.setDopplerFactor( dopplerFactor ); + soundLibrary.dopplerChanged(); + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetDopplerFactor'", + 0 ); + } +/** + * Changes the Doppler velocity. This method is used internally by SoundSystem + * for thread synchronization, and it can not be called directly - please use + * the setDopplerVelocity() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param dopplerVelocity New Doppler velocity, for use in Doppler effect. + */ + private void CommandChangeDopplerVelocity( float dopplerVelocity ) + { + if( soundLibrary != null ) + { + SoundSystemConfig.setDopplerVelocity( dopplerVelocity ); + soundLibrary.dopplerChanged(); + } + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetDopplerFactor'", + 0 ); + } +/** + * Changes a source's velocity, for use in Doppler effect. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setVelocity() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param sourcename Identifier for the source. + * @param x Source's velocity along the world x-axis. + * @param y Source's velocity along the world y-axis. + * @param z Source's velocity along the world z-axis. + */ + private void CommandSetVelocity( String sourcename, float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.setVelocity( sourcename, x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandVelocity'", + 0 ); + } +/** + * Changes the listener's velocity, for use in Doppler effect. This method is + * used internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerVelocity() method instead. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about Doppler effect. + * @param x Velocity along the world x-axis. + * @param y Velocity along the world y-axis. + * @param z Velocity along the world z-axis. + */ + private void CommandSetListenerVelocity( float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.setListenerVelocity( x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerVelocity'", + 0 ); + } +/** + * Plays the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the play() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandPlay( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.play( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandPlay'", 0 ); + } +/** + * Feeds raw data through the specified source. The source must be a + * streaming source and it can not be already associated with a file or URL to + * stream from. This method is used internally by SoundSystem for thread + * synchronization, and it can not be called directly - please use the + * feedRawAudioData() method instead. + * @param sourcename Name of the streaming source to play from. + * @param buffer Byte buffer containing raw audio data to stream. + */ + private void CommandFeedRawAudioData( String sourcename, byte[] buffer ) + { + if( soundLibrary != null ) + soundLibrary.feedRawAudioData( sourcename, buffer ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFeedRawAudioData'", 0 ); + } +/** + * Pauses the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the pause() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandPause( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.pause( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandPause'", 0 ); + } +/** + * Stops the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the stop() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandStop( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.stop( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandStop'", 0 ); + } +/** + * Rewinds the specified source. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the rewind() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandRewind( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.rewind( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandRewind'", 0 ); + } +/** + * Flushes all previously queued audio data from a streaming source. This + * method is used internally by SoundSystem for thread synchronization, and it + * can not be called directly - please use the flush() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandFlush( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.flush( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandFlush'", 0 ); + } +/** + * Sets a flag for a source indicating whether it should be used or if it + * should be removed after it finishes playing. One possible use for this + * method is to make temporary sources that were created with quickPlay() + * permanant. Another use could be to have a source automatically removed + * after it finishes playing. NOTE: Setting a source to inactive does not stop + * it, and setting a source to active does not play it. It is also important + * to note that a looping inactive source will not be removed as long as + * it keeps playing. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setTemporary() method instead. + * @param sourcename Identifier for the source. + * @param temporary True or False. + */ + private void CommandSetTemporary( String sourcename, boolean temporary ) + { + if( soundLibrary != null ) + soundLibrary.setTemporary( sourcename, temporary ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetActive'", 0 ); + } +/** + * Removes the specified source and clears up any memory it used. This method + * is used internally by SoundSystem for thread synchronization, and it can not + * be called directly - please use the removeSource() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandRemoveSource( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.removeSource( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandRemoveSource'", 0 ); + } +/** + * Moves the listener relative to the current location. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the moveListener() method instead. + * @param x X offset. + * @param y Y offset. + * @param z Z offset. + */ + private void CommandMoveListener( float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.moveListener( x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandMoveListener'", 0 ); + } + /** + * Moves the listener to the specified location. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerPosition() method instead. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + private void CommandSetListenerPosition( float x, float y, float z ) + { + if( soundLibrary != null ) + soundLibrary.setListenerPosition( x, y, z ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerPosition'", + 0 ); + } +/** + * Turns the listener counterclockwise by "angle" radians around the y-axis, + * relative to the current angle. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the turnListener() method instead. + * @param angle radian offset. + */ + private void CommandTurnListener( float angle ) + { + if( soundLibrary != null ) + soundLibrary.turnListener( angle ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandTurnListener'", + 0 ); + } +/** + * Sets the listener's angle in radians around the y-axis. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerAngle() method instead. + * @param angle radians. + */ + private void CommandSetListenerAngle( float angle ) + { + if( soundLibrary != null ) + soundLibrary.setListenerAngle( angle ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerAngle'", + 0 ); + } +/** + * Sets the listener's orientation. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setListenerOrientation() method instead. + * @param lookX X coordinate of the (normalized) look-at vector. + * @param lookY Y coordinate of the (normalized) look-at vector. + * @param lookZ Z coordinate of the (normalized) look-at vector. + * @param upX X coordinate of the (normalized) look-at vector. + * @param upY Y coordinate of the (normalized) look-at vector. + * @param upZ Z coordinate of the (normalized) look-at vector. + */ + private void CommandSetListenerOrientation( float lookX, float lookY, + float lookZ, float upX, + float upY, float upZ ) + { + if( soundLibrary != null ) + soundLibrary.setListenerOrientation( lookX, lookY, lookZ, upX, upY, + upZ ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetListenerOrientation'", + 0 ); + } +/** + * Culls the specified source. A culled source can not be played until it has + * been activated again. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the cull() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandCull( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.cull( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandCull'", 0 ); + } +/** + * Activates a previously culled source, so it can be played again. This + * method is used internally by SoundSystem for thread synchronization, and it + * can not be called directly - please use the activate() method instead. + * @param sourcename Identifier for the source. + */ + private void CommandActivate( String sourcename ) + { + if( soundLibrary != null ) + soundLibrary.activate( sourcename ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandActivate'", + 0 ); + } +/** + * Sets the overall volume, affecting all sources. This method is used + * internally by SoundSystem for thread synchronization, and it can not be + * called directly - please use the setMasterVolume() method instead. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + private void CommandSetMasterVolume( float value ) + { + if( soundLibrary != null ) + soundLibrary.setMasterVolume( value ); + else + errorMessage( + "Variable 'soundLibrary' null in method 'CommandSetMasterVolume'", + 0 ); + } + +/** + * This method can be overridden by extended classes to be used for source + * management (culling and activating sources based on established rules). One + * possible use for this method is sorting sources by distance, culling the + * furthest, and activating the closest. + * This method is automatically called on the CommandThread before processing + * queued commands, so you do not need to call it anywhere else. Note: use + * methods cull() and activate() here, NOT CommandCull() and CommandActivate() + * (thread safety issue). + * IMPORTANT: Always use synchronized( SoundSystemConfig.THREAD_SYNC ) when + * manually manipulating sources from outside the Command Thread! + */ + protected void ManageSources() + { + // OVERRIDDEN METHODS MUST USE THIS: + + /******* + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + // TODO: Sort the sources, cull and activate, etc. + } + ********/ + } + +/** + * Queues a command. + * If newCommand is null, all commands are dequeued and executed. + * This is automatically used by the sound system, so it is not + * likely that a user would ever need to use this method. + * See {@link paulscode.sound.CommandObject CommandObject} for more information + * about commands. + * @param newCommand Command to queue, or null to execute commands. + * @return True if more commands exist, false if queue is empty. + */ + public boolean CommandQueue( CommandObject newCommand ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( newCommand == null ) + { + // New command is null - that means execute all queued commands. + boolean activations = false; + CommandObject commandObject; + + // Loop through the command queue: + while( commandQueue != null && commandQueue.size() > 0 ) + { + // Grab the oldest command in the queue: + commandObject = commandQueue.remove( 0 ); + // See what it is, and execute the proper Command method: + if( commandObject != null ) + { + switch( commandObject.Command ) + { + case CommandObject.INITIALIZE: + CommandInitialize(); + break; + case CommandObject.LOAD_SOUND: + CommandLoadSound( + (FilenameURL) commandObject.objectArgs[0] ); + break; + case CommandObject.LOAD_DATA: + CommandLoadSound( + (SoundBuffer) commandObject.objectArgs[0], + commandObject.stringArgs[0] ); + break; + case CommandObject.UNLOAD_SOUND: + CommandUnloadSound( commandObject.stringArgs[0] ); + break; + case CommandObject.QUEUE_SOUND: + CommandQueueSound( commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0] ); + break; + case CommandObject.DEQUEUE_SOUND: + CommandDequeueSound( commandObject.stringArgs[0], + commandObject.stringArgs[1] ); + break; + case CommandObject.FADE_OUT: + CommandFadeOut( commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.longArgs[0] ); + break; + case CommandObject.FADE_OUT_IN: + CommandFadeOutIn( commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.longArgs[0], + commandObject.longArgs[1] ); + break; + case CommandObject.CHECK_FADE_VOLUMES: + CommandCheckFadeVolumes(); + break; + case CommandObject.NEW_SOURCE: + CommandNewSource( commandObject.boolArgs[0], + commandObject.boolArgs[1], + commandObject.boolArgs[2], + commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.intArgs[0], + commandObject.floatArgs[3] ); + break; + case CommandObject.RAW_DATA_STREAM: + CommandRawDataStream( + (AudioFormat) commandObject.objectArgs[0], + commandObject.boolArgs[0], + commandObject.stringArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.intArgs[0], + commandObject.floatArgs[3] ); + break; + case CommandObject.QUICK_PLAY: + CommandQuickPlay( commandObject.boolArgs[0], + commandObject.boolArgs[1], + commandObject.boolArgs[2], + commandObject.stringArgs[0], + (FilenameURL) commandObject.objectArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.intArgs[0], + commandObject.floatArgs[3], + commandObject.boolArgs[3] ); + break; + case CommandObject.SET_POSITION: + CommandSetPosition( commandObject.stringArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2] ); + break; + case CommandObject.SET_VOLUME: + CommandSetVolume( commandObject.stringArgs[0], + commandObject.floatArgs[0] ); + break; + case CommandObject.SET_PITCH: + CommandSetPitch( commandObject.stringArgs[0], + commandObject.floatArgs[0] ); + break; + case CommandObject.SET_PRIORITY: + CommandSetPriority( commandObject.stringArgs[0], + commandObject.boolArgs[0] ); + break; + case CommandObject.SET_LOOPING: + CommandSetLooping( commandObject.stringArgs[0], + commandObject.boolArgs[0] ); + break; + case CommandObject.SET_ATTENUATION: + CommandSetAttenuation( commandObject.stringArgs[0], + commandObject.intArgs[0] ); + break; + case CommandObject.SET_DIST_OR_ROLL: + CommandSetDistOrRoll( commandObject.stringArgs[0], + commandObject.floatArgs[0] ); + break; + case CommandObject.CHANGE_DOPPLER_FACTOR: + CommandChangeDopplerFactor( + commandObject.floatArgs[0] ); + break; + case CommandObject.CHANGE_DOPPLER_VELOCITY: + CommandChangeDopplerVelocity( + commandObject.floatArgs[0] ); + break; + case CommandObject.SET_VELOCITY: + CommandSetVelocity( commandObject.stringArgs[0], + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2] + ); + break; + case CommandObject.SET_LISTENER_VELOCITY: + CommandSetListenerVelocity( + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2] + ); + break; + // Methods related to playing sources must be processed + // after cull/activate commands in order for source + // management to work properly, so save them for + // later: + //------------------------------------------------------ + case CommandObject.PLAY: + sourcePlayList.add( commandObject ); + break; + case CommandObject.FEED_RAW_AUDIO_DATA: + sourcePlayList.add( commandObject ); + break; + //------------------------------------------------------ + case CommandObject.PAUSE: + CommandPause( commandObject.stringArgs[0] ); + break; + case CommandObject.STOP: + CommandStop( commandObject.stringArgs[0] ); + break; + case CommandObject.REWIND: + CommandRewind( commandObject.stringArgs[0] ); + break; + case CommandObject.FLUSH: + CommandFlush( commandObject.stringArgs[0] ); + break; + case CommandObject.CULL: + CommandCull( commandObject.stringArgs[0] ); + break; + case CommandObject.ACTIVATE: + activations = true; + CommandActivate( commandObject.stringArgs[0] ); + break; + case CommandObject.SET_TEMPORARY: + CommandSetTemporary( commandObject.stringArgs[0], + commandObject.boolArgs[0] ); + break; + case CommandObject.REMOVE_SOURCE: + CommandRemoveSource( commandObject.stringArgs[0] ); + break; + case CommandObject.MOVE_LISTENER: + CommandMoveListener( commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2]); + break; + case CommandObject.SET_LISTENER_POSITION: + CommandSetListenerPosition( + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2]); + break; + case CommandObject.TURN_LISTENER: + CommandTurnListener( commandObject.floatArgs[0] ); + break; + case CommandObject.SET_LISTENER_ANGLE: + CommandSetListenerAngle( + commandObject.floatArgs[0]); + break; + case CommandObject.SET_LISTENER_ORIENTATION: + CommandSetListenerOrientation( + commandObject.floatArgs[0], + commandObject.floatArgs[1], + commandObject.floatArgs[2], + commandObject.floatArgs[3], + commandObject.floatArgs[4], + commandObject.floatArgs[5]); + break; + case CommandObject.SET_MASTER_VOLUME: + CommandSetMasterVolume( + commandObject.floatArgs[0] ); + break; + case CommandObject.NEW_LIBRARY: + CommandNewLibrary( commandObject.classArgs[0] ); + break; + // If we don't recognize the command, just skip it: + default: + break; + } + } + } + + // If any sources were reactivated, check if they need to be + // replayed: + if( activations ) + soundLibrary.replaySources(); + + // Now that we have the correct sources culled and activated, we + // can start playing sources. Loop through the playlist and + // execute the commands: + while( sourcePlayList != null && sourcePlayList.size() > 0 ) + { + // Grab the oldest command in the queue: + commandObject = sourcePlayList.remove( 0 ); + if( commandObject != null ) + { + // See what it is, and execute the proper Command method: + switch( commandObject.Command ) + { + case CommandObject.PLAY: + CommandPlay( commandObject.stringArgs[0] ); + break; + case CommandObject.FEED_RAW_AUDIO_DATA: + CommandFeedRawAudioData( + commandObject.stringArgs[0], + commandObject.buffer ); + break; + } + } + } + + return( commandQueue != null && commandQueue.size() > 0 ); + } + else + { + // make sure the commandQueue exists: + if( commandQueue == null ) + return false; + // queue a new command + commandQueue.add( newCommand ); + // Of course there is something in the list now, since we just + // added it: + return true; + } + } + } + +/** + * Searches for and removes any temporary sources that have finished + * playing. This method is used internally by SoundSystem, and it is + * unlikely that the user will ever need to use it. + */ + public void removeTemporarySources() + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary != null ) + soundLibrary.removeTemporarySources(); + } + } + +/** + * Returns true if the specified source is playing. + * @param sourcename Unique identifier of the source to check. + * @return True or false. + */ + public boolean playing( String sourcename ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary == null ) + return false; + + Source src = soundLibrary.getSources().get( sourcename ); + + if( src == null ) + return false; + + return src.playing(); + } + } + +/** + * Returns true if anything is currently playing. + * @return True or false. + */ + public boolean playing() + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( soundLibrary == null ) + return false; + + HashMap sourceMap = soundLibrary.getSources(); + if( sourceMap == null ) + return false; + + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + if( source.playing() ) + return true; + } + + return false; + } + } + +/** + * Copies and returns the peripheral information from a map of sources. This + * method is used internally by SoundSystem, and it is unlikely that the user + * will ever need to use it. + * @param sourceMap Sources to copy. + * @return New map of sources. + */ + private HashMap copySources( HashMap sourceMap ) + { + Set keys = sourceMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // New map of generic source data: + HashMap returnMap = new HashMap(); + + + // loop through and store information from all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = sourceMap.get( sourcename ); + if( source != null ) + returnMap.put( sourcename, new Source( source, null ) ); + } + return returnMap; + } + +/** + * Checks if the specified library type is compatible. + * @param libraryClass Libary type to check. + * @return True or false. + */ + public static boolean libraryCompatible( Class libraryClass ) + { + // create the message logger: + SoundSystemLogger logger = SoundSystemConfig.getLogger(); + // if the user didn't create one, then do it now: + if( logger == null ) + { + logger = new SoundSystemLogger(); + SoundSystemConfig.setLogger( logger ); + } + logger.message( "", 0 ); + logger.message( "Checking if " + + SoundSystemConfig.getLibraryTitle( libraryClass ) + + " is compatible...", 0 ); + + boolean comp = SoundSystemConfig.libraryCompatible( libraryClass ); + + if( comp ) + logger.message( "...yes", 1 ); + else + logger.message( "...no", 1 ); + + return comp; + } + +/** + * Returns the currently loaded library, or -1 if none. + * @return Global library identifier + */ + public static Class currentLibrary() + { + return( currentLibrary( GET, null ) ); + } + +/** + * Returns false if a sound library is busy initializing. + * @return True or false. + */ + public static boolean initialized() + { + return( initialized( GET, XXX ) ); + } + +/** + * Returns the last SoundSystemException thrown, or null if none. + * @return The last exception. + */ + public static SoundSystemException getLastException() + { + return( lastException( GET, null ) ); + } + +/** + * Stores a SoundSystemException which can be retreived later with the + * 'getLastException' method. + * @param e Exception to store. + */ + public static void setException( SoundSystemException e ) + { + lastException( SET, e ); + } + +/** + * Sets or returns the value of boolean 'initialized'. + * @param action Action to perform (GET or SET). + * @param value New value if action is SET, otherwise XXX. + * @return value of boolean 'initialized'. + */ + private static boolean initialized( boolean action, boolean value ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( action == SET ) + initialized = value; + return initialized; + } + } + +/** + * Sets or returns the value of boolean 'initialized'. + * @param action Action to perform (GET or SET). + * @param value New value if action is SET, otherwise XXX. + * @return value of boolean 'initialized'. + */ + private static Class currentLibrary( boolean action, + Class value ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( action == SET ) + currentLibrary = value; + return currentLibrary; + } + } + +/** + * Sets or returns the error code for the last error that occurred. If no + * errors have occurred, returns SoundSystem.ERROR_NONE + * @param action Action to perform (GET or SET). + * @param e New exception if action is SET, otherwise XXX. + * @return Last SoundSystemException thrown. + */ + private static SoundSystemException lastException( boolean action, + SoundSystemException e ) + { + synchronized( SoundSystemConfig.THREAD_SYNC ) + { + if( action == SET ) + lastException = e; + return lastException; + } + } + +/** + * Sleeps for the specified number of milliseconds. + */ + protected static void snooze( long milliseconds ) + { + try + { + Thread.sleep( milliseconds ); + } + catch( InterruptedException e ){} + } + +/** + * Prints a message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + protected void message( String message, int indent ) + { + logger.message( message, indent ); + } + +/** + * Prints an important message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + protected void importantMessage( String message, int indent ) + { + logger.importantMessage( message, indent ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @param indent Number of tabs to indent the message. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message, int indent ) + { + return logger.errorCheck( error, className, message, indent ); + } + +/** + * Prints an error message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + protected void errorMessage( String message, int indent ) + { + logger.errorMessage( className, message, indent ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystemConfig.java b/src/lwjgl/java/paulscode/sound/SoundSystemConfig.java new file mode 100644 index 0000000..d5efbc0 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystemConfig.java @@ -0,0 +1,1074 @@ +package paulscode.sound; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Locale; +import java.util.ListIterator; +import java.util.LinkedList; + +/** + * The SoundSystemConfig class is used to access global sound system settings, + * and to link with external pluggins. All members of this class are static. + * SoundSystemConfig is sort of a "catch all" configuration class, so if you + * are not sure where to find something in the SoundSystem library, this is + * probably a good place to start. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystemConfig +{ +// GLOBAL THREAD SYNCHRONIZATION +/** + * Lock object used to synchronize the three threads used by SoundSystem. + * Synchronize on this anytime you manually manipulate a Source's properties. + */ + public static final Object THREAD_SYNC = new Object(); +// END GLOBAL THREAD SYNCHRONIZATION + +// GLOBAL IDENTIFIERS + +/** + * A normal (non-streaming) source. Also used to define a Channel type as + * normal. + */ + public static final int TYPE_NORMAL = 0; +/** + * A streaming source. Also used to define a Channel type as streaming. + */ + public static final int TYPE_STREAMING = 1; + +/** + * Global identifier for no attenuation. Attenuation is how a source's volume + * fades with distance. When there is no attenuation, a source's volume + * remains constaint regardles of distance. + */ + public static final int ATTENUATION_NONE = 0; // no attenuation +/** + * Global identifier for rolloff attenuation. Rolloff attenuation is a + * realistic attenuation model, which uses a rolloff factor to determine how + * quickly a source fades with distance. A smaller rolloff factor will fade at + * a further distance, and a rolloff factor of 0 will never fade. NOTE: In + * OpenAL, rolloff attenuation only works for monotone sounds. + */ + public static final int ATTENUATION_ROLLOFF = 1; // logrithmic attenuation +/** + * Global identifier for linear attenuation. Linear attenuation is less + * realistic than rolloff attenuation, but it allows the user to specify a + * maximum "fade distance" where a source's volume becomes zero. + */ + public static final int ATTENUATION_LINEAR = 2; // linear attenuation + +/** + * A Regular expression for determining if a file's extension is MIDI. + */ + public static String EXTENSION_MIDI = ".*[mM][iI][dD][iI]?$"; + +/** + * A Regular expression for determining if a path is an online URL. + */ + public static String PREFIX_URL = "^[hH][tT][tT][pP]://.*"; + +// END GLOBAL IDENTIFIERS + + +// PRIVATE STATIC VARIABLES + +/** + * Handle to the message logger. The default logger can be changed by + * overridding the {@link paulscode.sound.SoundSystemLogger SoundSystemLogger} + * class and calling the setLogger() method (must be done BEFORE instantiating + * the SoundSystem class!) + */ + private static SoundSystemLogger logger = null; + +/** + * List of library types in their order of priority. + */ + private static LinkedList libraries; + +/** + * List of codecs and the file formats they are associated with. + */ + private static LinkedList codecs = null; + +/** + * List of stream listeners. + */ + private static LinkedList streamListeners = null; +/** + * For synchronizing access to the streamListeners list. + */ + private static final Object streamListenersLock = new Object(); + +/** + * Maximum number of normal (non-streaming) channels that can be created. + * NOTE: JavaSound may require the total number of channels (non-streaming + + * streaming) to be 32. + */ + private static int numberNormalChannels = 28; +/** + * Maximum number of streaming channels that can be created. + * NOTE: JavaSound may require the total number of channels (non-streaming + + * streaming) to be 32. + */ + private static int numberStreamingChannels = 4; +/** + * Overall volume, affecting all sources. Float value (0.0f - 1.0f). + */ + private static float masterGain = 1.0f; +/** + * Attenuation model to use if not specified. Attenuation is how a source's + * volume fades with distance. + */ + private static int defaultAttenuationModel = ATTENUATION_ROLLOFF; +/** + * Default value to use for the rolloff factor if not specified. + */ + private static float defaultRolloffFactor = 0.03f; +/** + * Value to use for the doppler factor, for determining Doppler scale. + */ + private static float dopplerFactor = 0.0f; +/** + * Value to use for the doppler velocity. + */ + private static float dopplerVelocity = 1.0f; +/** + * Default value to use for fade distance if not specified. + */ + private static float defaultFadeDistance = 1000.0f; +/** + * Package where the sound files are located (must be followed by '/'). + */ + private static String soundFilesPackage = "Sounds/"; + +/** + * Number of bytes to load at a time when streaming. + */ + private static int streamingBufferSize = 131072; +/** + * Number of buffers used for each streaming sorce. Slow codecs may require + * this number to be greater than 2 to prevent audio skipping during playback. + */ + private static int numberStreamingBuffers = 3; +/** + * Enables a transition-speed optimization by assuming all sounds in each + * streaming source's queue will have exactly the same format once decoded + * (including channels, sample rate, and sample size). This is an advanced + * setting which should only be changed by experienced developers. + */ + private static boolean streamQueueFormatsMatch = false; +/** + * The maximum number of bytes to read in for (non-streaming) files. + * Increase this value if non-streaming sounds are getting cut off. + * Decrease this value if large sound files are causing lag during load time. + */ + private static int maxFileSize = 268435456; +/** + * Size of each chunk to read at a time for loading (non-streaming) files. + * Increase if loading sound files is causing significant lag. + */ + private static int fileChunkSize = 1048576; + +/** + * Indicates whether or not there is a codec for reading from MIDI files. If + * there is no codec for MIDI, then SoundSystem uses javax.sound.midi. + */ + private static boolean midiCodec = false; + +/** + * MIDI device to try using as the Synthesizer. May be the full name or part + * of the name. If this String is empty, the default Synthesizer will be used, + * or one of the common alternate synthesizers if the default Synthesizer is + * unavailable. + */ + private static String overrideMIDISynthesizer = ""; + +// END PRIVATE STATIC VARIABLES + +// THESE TWO METHODS PROVIDE INFORMATION ABOUT THE INDIVIDUAL SOUND LIBRARIES + +/** + * Adds an entry to the list of library types. This method has no effect if + * the specified library type is already in the list of libraries. + * NOTE: The parameterless constructor of the SoundSystem class will try to + * load libraries in the order that they were entered into the list. + * @param libraryClass Derivitive of class 'Library'. +*/ + public static void addLibrary( Class libraryClass ) + throws SoundSystemException + { + if( libraryClass == null ) + throw new SoundSystemException( + "Parameter null in method 'addLibrary'", + SoundSystemException.NULL_PARAMETER ); + if( !Library.class.isAssignableFrom( libraryClass ) ) + throw new SoundSystemException( "The specified class does not " + + "extend class 'Library' in method 'addLibrary'" ); + + if( libraries == null ) + libraries = new LinkedList(); + + if( !libraries.contains( libraryClass ) ) + libraries.add( libraryClass ); + } + +/** + * Removes the specified library from the list of library types. + * @param libraryClass Derivitive of class 'Library'. +*/ + public static void removeLibrary( Class libraryClass ) + throws SoundSystemException + { + if( libraries == null || libraryClass == null ) + return; + + libraries.remove( libraryClass ); + } + +/** + * Returns the list of library types. + * @return LinkedList of classes derived from 'Library', or null if none were specified. +*/ + public static LinkedList getLibraries() + { + return libraries; + } + +/** + * Checks if the specified library class is compatible on the user's machine. + * @param libraryClass Library type to check. + * @return True or false. +*/ + public static boolean libraryCompatible( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'librayCompatible'" ); + return false; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'libraryCompatible'" ); + return false; + } + + Object o = runMethod( libraryClass, "libraryCompatible", + new Class[0], new Object[0] ); + + if( o == null ) + { + errorMessage( "Method 'Library.libraryCompatible' returned " + + "'null' in method 'libraryCompatible'" ); + return false; + } + + return( ( (Boolean) o ).booleanValue() ); + } + +/** + * Return the short title of the specified library, or null if error. + * @param libraryClass Derivitive of class 'Library'. + * @return String containing the library title. +*/ + public static String getLibraryTitle( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'getLibrayTitle'" ); + return null; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'getLibraryTitle'" ); + return null; + } + + Object o = runMethod( libraryClass, "getTitle", new Class[0], + new Object[0] ); + if( o == null ) + { + errorMessage( "Method 'Library.getTitle' returned " + + "'null' in method 'getLibraryTitle'" ); + return null; + } + + return( (String) o ); + } + +/** + * Return the longer description of the specified library, or null if error. + * @param libraryClass Derivitive of class 'Library'. + * @return String containing the library title. +*/ + public static String getLibraryDescription( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'getLibrayDescription'" ); + return null; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'getLibraryDescription'" ); + return null; + } + + Object o = runMethod( libraryClass, "getDescription", + new Class[0], new Object[0] ); + if( o == null ) + { + errorMessage( "Method 'Library.getDescription' returned " + + "'null' in method 'getLibraryDescription'" ); + return null; + } + + return( (String) o ); + } + +/** + * Return whether or not requires reversal of audio data byte-order. + * @param libraryClass Derivitive of class 'Library'. + * @return True if byte-order reversal is required. +*/ + public static boolean reverseByteOrder( Class libraryClass ) + { + if( libraryClass == null ) + { + errorMessage( "Parameter 'libraryClass' null in method" + + "'reverseByteOrder'" ); + return false; + } + if( !Library.class.isAssignableFrom( libraryClass ) ) + { + errorMessage( "The specified class does not extend class " + + "'Library' in method 'reverseByteOrder'" ); + return false; + } + + Object o = runMethod( libraryClass, "reversByteOrder", + new Class[0], new Object[0] ); + if( o == null ) + { + errorMessage( "Method 'Library.reverseByteOrder' returned " + + "'null' in method 'getLibraryDescription'" ); + return false; + } + + return( ((Boolean) o).booleanValue() ); + } + +// END LIBRARY INFORMATION + +// Use the following methods to interface the private variables above: + +// STATIC NONSYNCHRONIZED INTERFACE METHODS +/** + * Changes the message logger to use for handling status messages, warnings, + * and error messages. This method should only be called BEFORE instantiating + * the SoundSystem class! If this method is called after the SoundSystem has + * been created, there will be handles floating around to two different + * loggers, and the results will be undesirable. This method can be used to + * change how messages are handled. First, the + * {@link paulscode.sound.SoundSystemLogger SoundSystemLogger} class should be + * extended and methods overriden to change how messages are handled. Then, + * the overridden class should be instantiated, and a call made to + * SoundSystemConfig.setLogger() before creating the SoundSystem object. + * If an alternate logger is not set by the user before the SoundSystem is + * instantiated, then an instance of the base SoundSystemLogger class will be + * used by default. + * @param l Handle to a message logger. + */ + public static void setLogger( SoundSystemLogger l ) + { + logger = l; + } +/** + * Returns a handle to the message logger. + * @return The current message logger. + */ + public static SoundSystemLogger getLogger() + { + return logger; + } + +// STATIC SYNCHRONIZED INTERFACE METHODS + +/** + * Sets the maximum number of normal (non-streaming) channels that can be + * created. Streaming channels are created first, so the higher the maximum + * number of streaming channels is set, the fewer non-streaming channels will + * be available. If unable to create the number of channels specified, + * SoundSystem will create as many as possible. + * NOTE: Some sound library pluggins may require the total number of channels + * (non-streaming + streaming) to be 32. + * @param number How many normal audio channels. + */ + public static synchronized void setNumberNormalChannels( int number ) + { + numberNormalChannels = number; + } + +/** + * Returns the maximum number of normal (non-streaming) channels that can be + * created. + * @return Maximum non-streaming channels. + */ + public static synchronized int getNumberNormalChannels() + { + return numberNormalChannels; + } + +/** + * Sets the maximum number of streaming channels that can be created. + * Streaming channels are created first, so the higher the maximum number of + * streaming channels is set, the fewer non-streaming channels will + * be available. If unable to create the number of channels specified, + * SoundSystem will create as many as possible. + * NOTE: Some sound library pluggins may require the total number of channels + * (non-streaming + streaming) to be 32. + * @param number How many streaming audio channels. + */ + public static synchronized void setNumberStreamingChannels( int number ) + { + numberStreamingChannels = number; + } + +/** + * Returns the maximum number of streaming channels that can be created. + * @return Maximum streaming channels. + */ + public static synchronized int getNumberStreamingChannels() + { + return numberStreamingChannels; + } + +/** + * Sets the varriable used for overall volume, affecting all sources. + * @param value Float value (0.0f - 1.0f). + */ + public static synchronized void setMasterGain( float value ) + { + masterGain = value; + } + +/** + * Returns the value for the overall volume. + * @return A float value (0.0f - 1.0f). + */ + public static synchronized float getMasterGain() + { + return masterGain; + } + +/** + * Sets the default attenuation model to use when one is not specified. + * Attenuation is how a source's volume fades with distance. + * @param model A global attenuation model identifier. + */ + public static synchronized void setDefaultAttenuation( int model ) + { + defaultAttenuationModel = model; + } +/** + * Returns the default attenuation model used when one is not specified. + * @return A global attenuation model identifier + */ + public static synchronized int getDefaultAttenuation() + { + return defaultAttenuationModel; + } +/** + * Sets the default rolloff factor to use when one is not specified. + * @param rolloff Rolloff factor. + */ + public static synchronized void setDefaultRolloff( float rolloff ) + { + defaultRolloffFactor = rolloff; + } +/** + * Returns the doppler factor, for determining Doppler Effect scale. + * @return Doppler factor + */ + public static synchronized float getDopplerFactor() + { + return dopplerFactor; + } +/** + * Sets the doppler factor, for determining Doppler Effect scale. Use this + * method BEFORE instantiating the SoundSystem. To change the Doppler factor + * after the SoundSystem is instantiated, use the + * SoundSystem.changeDopplerFactor method instead. + * @param factor Doppler factor. + */ + public static synchronized void setDopplerFactor( float factor ) + { + dopplerFactor = factor; + } +/** + * Returns the Doppler Velocity, for use in Doppler Effect. + * @return Doppler velocity. + */ + public static synchronized float getDopplerVelocity() + { + return dopplerVelocity; + } +/** + * Sets the Doppler velocity, for use in Doppler Effect. Use this method + * BEFORE instantiating the SoundSystem. To change the Doppler velocity after + * the SoundSystem is instantiated, use the SoundSystem.changeDopplerVelocity + * method instead. + * @param velocity Doppler velocity. + */ + public static synchronized void setDopplerVelocity( float velocity ) + { + dopplerVelocity = velocity; + } +/** + * Returns the default rolloff factor used when one is not specified. + * @return Default rolloff factor + */ + public static synchronized float getDefaultRolloff() + { + return defaultRolloffFactor; + } +/** + * Sets the default fade distance to use when one is not specified. + * @param distance Fade Distance. + */ + public static synchronized void setDefaultFadeDistance( float distance ) + { + defaultFadeDistance = distance; + } +/** + * Returns the default fade distance used when one is not specified. + * @return Default fade distance + */ + public static synchronized float getDefaultFadeDistance() + { + return defaultFadeDistance; + } +/** + * Sets the package where sound files are located. + * @param location Path to the sound files location (must be followed by '/'). + */ + public static synchronized void setSoundFilesPackage( String location ) + { + soundFilesPackage = location; + } +/** + * Returns the package where sound files are located. + * @return Path to the sound files location + */ + public static synchronized String getSoundFilesPackage() + { + return soundFilesPackage; + } +/** + * Sets the number of bytes to load at a time when streaming. + * @param size Size in bytes. + */ + public static synchronized void setStreamingBufferSize( int size ) + { + streamingBufferSize = size; + } +/** + * Returns the number of bytes to load at a time when streaming. + * @return Size in bytes. + */ + public static synchronized int getStreamingBufferSize() + { + return streamingBufferSize; + } +/** + * Sets the number of buffers used for each streaming sorce. + * Slow codecs may require this number to be greater than 2 to prevent audio + * skipping during playback. + * @param num How many buffers. + */ + public static synchronized void setNumberStreamingBuffers( int num ) + { + numberStreamingBuffers = num; + } +/** + * Returns the number of buffers used for each streaming sorce. + * @return How many buffers. + */ + public static synchronized int getNumberStreamingBuffers() + { + return numberStreamingBuffers; + } + +/** + * Enables a transition-speed optimization by assuming all sounds in each + * streaming source's queue will have exactly the same format once decoded + * (including channels, sample rate, and sample size). This is an advanced + * setting which should only be changed by experienced developers. + * @param val False by default. + */ + public static synchronized void setStreamQueueFormatsMatch( boolean val ) + { + streamQueueFormatsMatch = val; + } + +/** + * Returns whether or not all sounds in each streaming source's queue will be + * handled as if they have exactly the same format once decoded (including + * channels, sample rate, and sample size). This is an advanced setting which + * should only be changed by experienced developers. + * @return Normally false. + */ + public static synchronized boolean getStreamQueueFormatsMatch() + { + return streamQueueFormatsMatch; + } + +/** + * Sets the maximum number of bytes to read in for (non-streaming) files. + * Increase this value if non-streaming sounds are getting cut off. + * Decrease this value if large sound files are causing lag during load time. + * @param size Size in bytes. + */ + public static synchronized void setMaxFileSize( int size ) + { + maxFileSize = size; + } +/** + * Returns the maximum number of bytes to read in for (non-streaming) files. + * @return Size in bytes. + */ + public static synchronized int getMaxFileSize() + { + return maxFileSize; + } +/** + * Sets the size of each chunk to read at a time for loading (non-streaming) + * files. Increase if loading sound files is causing significant lag. + * @param size Size in bytes. + */ + public static synchronized void setFileChunkSize( int size ) + { + fileChunkSize = size; + } +/** + * Returns the size of each chunk to read at a time for loading (non-streaming) + * files. + * @return Size in bytes. + */ + public static synchronized int getFileChunkSize() + { + return fileChunkSize; + } +/** + * Returns the name of the MIDI synthesizer to use instead of the default, or + * empty string if none was specified. + * @return All or part of a MIDI device name, or empty string for not specified. + */ + public static synchronized String getOverrideMIDISynthesizer() + { + return overrideMIDISynthesizer; + } +/** + * Sets the name of the MIDI synthesizer to use instead of the default. If + * 'name' is an empty string, the default Synthesizer will be used, or one of + * the common alternate synthesizers if the default Synthesizer is unavailable. + * @param name All or part of the MIDI device name. + */ + public static synchronized void setOverrideMIDISynthesizer( String name ) + { + overrideMIDISynthesizer = name; + } +/** + * Uses the specified file extension to associate a particular file format + * with the codec used to read audio data from it. + * @param extension File extension to be associated with the specified codec. + * @param iCodecClass Codec type to use for files with the specified extension. + */ + public static synchronized void setCodec( String extension, + Class iCodecClass ) + throws SoundSystemException + { + if( extension == null ) + throw new SoundSystemException( "Parameter 'extension' null in " + + "method 'setCodec'.", + SoundSystemException.NULL_PARAMETER ); + if( iCodecClass == null ) + throw new SoundSystemException( "Parameter 'iCodecClass' null in " + + "method 'setCodec'.", + SoundSystemException.NULL_PARAMETER ); + if( !ICodec.class.isAssignableFrom( iCodecClass ) ) + throw new SoundSystemException( "The specified class does " + + "not implement interface 'ICodec' in method 'setCodec'", + SoundSystemException.CLASS_TYPE_MISMATCH ); + + if( codecs == null ) + codecs = new LinkedList(); + + ListIterator i = codecs.listIterator(); + Codec codec; + + while( i.hasNext() ) + { + codec = i.next(); + if( extension.matches( codec.extensionRegX ) ) + i.remove(); + } + codecs.add( new Codec( extension, iCodecClass ) ); + + // Let SoundSystem know if this is a MIDI codec, so it won't use + // javax.sound.midi anymore: + if( extension.matches( EXTENSION_MIDI ) ) + midiCodec = true; + } +/** + * Returns the codec that can be used to read audio data from the specified + * file. + * @param filename File to get a codec for. + * @return Codec to use for reading audio data. + */ + public static synchronized ICodec getCodec( String filename ) + { + if( codecs == null ) + return null; + + ListIterator i = codecs.listIterator(); + Codec codec; + + while( i.hasNext() ) + { + codec = i.next(); + if( filename.matches( codec.extensionRegX ) ) + return codec.getInstance(); + } + + return null; + } + +/** + * Indicates whether or not there is a codec for reading from MIDI files. If + * there is no codec for MIDI, then SoundSystem uses javax.sound.midi. + * @return True if there the user defined a MIDI codec. + */ + public static boolean midiCodec() + { + return midiCodec; + } + +/** + * Adds an entry to the list of stream listeners. If the instance is already + * in the list, the command is ignored. + * @param streamListener Implementation of interface 'IStreamListener'. +*/ + public static void addStreamListener( IStreamListener streamListener ) + { + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + streamListeners = new LinkedList(); + + if( !streamListeners.contains( streamListener ) ) + streamListeners.add( streamListener ); + } + } + +/** + * Removes an entry from the list of stream listeners. + * @param streamListener Implementation of interface 'IStreamListener'. +*/ + public static void removeStreamListener( IStreamListener streamListener ) + { + + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + streamListeners = new LinkedList(); + + if( streamListeners.contains( streamListener ) ) + streamListeners.remove( streamListener ); + } + } + +/** + * Notifies all stream listeners that an End Of Stream was reached. If there + * are no listeners, the command is ignored. + * @param sourcename String identifier of the source which reached the EOS. + * @param queueSize Number of items left the the stream's play queue, or zero if none. +*/ + public static void notifyEOS( String sourcename, int queueSize ) + { + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + return; + } + final String srcName = sourcename; + final int qSize = queueSize; + + new Thread() + { + @Override + public void run() + { + synchronized( streamListenersLock ) + { + if( streamListeners == null ) + return; + ListIterator i = streamListeners.listIterator(); + IStreamListener streamListener; + while( i.hasNext() ) + { + streamListener = i.next(); + if( streamListener == null ) + i.remove(); + else + streamListener.endOfStream( srcName, qSize ); + } + } + } + }.start(); + } + +// END STATIC SYNCHRONIZED INTERFACE METHODS + + +// PRIVATE INTERNAL METHODS + +/** + * Display the specified error message using the current logger. + * @param message Error message to display. +*/ + private static void errorMessage( String message ) + { + if( logger != null ) + logger.errorMessage( "SoundSystemConfig", message, 0 ); + } + + // We don't know what Class parameter 'c' is, so we will ignore the + // warning message "unchecked call to getMethod". + @SuppressWarnings("unchecked") +/** + * Returns the results of calling the specified method from the specified + * class using the specified parameters. + * @param c Class to call the method on. + * @param method Name of the method. + * @param paramTypes Data types of the parameters being passed to the method. + * @param params Actual parameters to pass to the method. + * @return Specified method's return value, or null if error or void. +*/ + private static Object runMethod( Class c, String method, Class[] paramTypes, + Object[] params ) + { + Method m = null; + try + { + m = c.getMethod( method, paramTypes ); // <--- generates a warning + } + catch( NoSuchMethodException nsme ) + { + errorMessage( "NoSuchMethodException thrown when attempting " + + "to call method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( SecurityException se ) + { + errorMessage( "Access denied when attempting to call method '" + + method + "' in method 'runMethod'" ); + return null; + } + catch( NullPointerException npe ) + { + errorMessage( "NullPointerException thrown when attempting " + + "to call method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + if( m == null ) + { + errorMessage( "Method '" + method + "' not found for the class " + + "specified in method 'runMethod'" ); + return null; + } + + Object o = null; + try + { + o = m.invoke( null, params ); + } + catch( IllegalAccessException iae ) + { + errorMessage( "IllegalAccessException thrown when attempting " + + "to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( IllegalArgumentException iae ) + { + errorMessage( "IllegalArgumentException thrown when attempting " + + "to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( InvocationTargetException ite ) + { + errorMessage( "InvocationTargetException thrown while attempting " + + "to invoke method 'Library.getTitle' in " + + "method 'getLibraryTitle'" ); + return null; + } + catch( NullPointerException npe ) + { + errorMessage( "NullPointerException thrown when attempting " + + "to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + catch( ExceptionInInitializerError eiie ) + { + errorMessage( "ExceptionInInitializerError thrown when " + + "attempting to invoke method '" + method + "' in " + + "method 'runMethod'" ); + return null; + } + + return( o ); + } + +// END PRIVATE INTERNAL METHODS + + +// PRIVATE INTERNAL CLASSES + +/** + * The Codec class is used to associate individual file formats with the + * codecs used to load audio data from them. + * + * Author: Paul Lamb + */ + private static class Codec + { +/** + * A regular expression used to match a file's extension. This is used to + * determine the file format. + */ + public String extensionRegX; +/** + * Codec used to load audio data from this file format. + */ + public Class iCodecClass; +/** + * Constructor: Converts the specified extension string into a regular + * expression, and associates that with the specified codec. + * @param extension File extension to be associated with the specified codec. + * @param iCodec Codec to use for files with the specified extension. + */ + public Codec( String extension, Class iCodecClass ) + { + extensionRegX = ""; + // Make sure an extension was specified: + if( extension != null && extension.length() > 0 ) + { + // We are only interested in the file extension. The filename + // can begin with whatever: + extensionRegX = ".*"; + String c; + for( int x = 0; x < extension.length(); x++ ) + { + // Each character could be either upper or lower case: + c = extension.substring( x, x + 1 ); + extensionRegX += "[" + c.toLowerCase( Locale.ENGLISH ) + + c.toUpperCase( Locale.ENGLISH ) + "]"; + } + // The extension will be at the end of the filename: + extensionRegX += "$"; + } + // remember the codec to use for this format: + this.iCodecClass = iCodecClass; + } + + public ICodec getInstance() + { + if( iCodecClass == null ) + return null; + + Object o = null; + try + { + o = iCodecClass.newInstance(); + } + catch( InstantiationException ie ) + { + instantiationErrorMessage(); + return null; + } + catch( IllegalAccessException iae ) + { + instantiationErrorMessage(); + return null; + } + catch( ExceptionInInitializerError eiie ) + { + instantiationErrorMessage(); + return null; + } + catch( SecurityException se ) + { + instantiationErrorMessage(); + return null; + } + + + if( o == null ) + { + instantiationErrorMessage(); + return null; + } + + return (ICodec) o; + } + + private void instantiationErrorMessage() + { + errorMessage( "Unrecognized ICodec implementation in method " + + "'getInstance'. Ensure that the implementing " + + "class has one public, parameterless constructor." ); + } + } +// END PRIVATE INTERNAL CLASSES +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystemException.java b/src/lwjgl/java/paulscode/sound/SoundSystemException.java new file mode 100644 index 0000000..d0a0101 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystemException.java @@ -0,0 +1,94 @@ +package paulscode.sound; + +/** + * The SoundSystemException class is used to provide information about serious + * errors. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystemException extends Exception +{ +/** + * Global identifier for no problem. + */ + public static final int ERROR_NONE = 0; +/** + * Global identifier for a generic exception. + */ + public static final int UNKNOWN_ERROR = 1; +/** + * Global identifier for a null parameter. + */ + public static final int NULL_PARAMETER = 2; +/** + * Global identifier for a class type mismatch. + */ + public static final int CLASS_TYPE_MISMATCH = 3; +/** + * Global identifier for the sound library does not exist. + */ + public static final int LIBRARY_NULL = 4; +/** + * Global identifier for the sound library does not exist. + */ + public static final int LIBRARY_TYPE = 5; + +/** + * Holds a global identifier indicating the type of exception. + */ + private int myType = UNKNOWN_ERROR; + +/** + * Constructor: Generic exception. Specify the error message. + */ + public SoundSystemException( String message ) + { + super( message ); + } + +/** + * Constructor: Specify the error message and type of exception. + * @param message Description of the problem. + * @param type Global identifier for type of exception. + */ + public SoundSystemException( String message, int type ) + { + super( message ); + myType = type; + } + + public int getType() + { + return myType; + } +} diff --git a/src/lwjgl/java/paulscode/sound/SoundSystemLogger.java b/src/lwjgl/java/paulscode/sound/SoundSystemLogger.java new file mode 100644 index 0000000..7230a13 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/SoundSystemLogger.java @@ -0,0 +1,173 @@ +package paulscode.sound; + +/** + * The SoundSystemLogger class handles all status messages, warnings, and error + * messages for the SoundSystem library. This class can be extended and + * methods overriden to change how messages are handled. To do this, the + * overridden class should be instantiated, and a call should be made to method + * SoundSystemConfig.setLogger() BEFORE creating the SoundSystem object. If + * the setLogger() method is called after the SoundSystem has been created, + * there will be handles floating around to two different message loggers, and + * the results will be undesirable. + * See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more + * information about changing default settings. If an alternate logger is not + * set by the user, then an instance of this base class will be automatically + * created by default when the SoundSystem class is instantiated. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SoundSystemLogger +{ +/** + * Prints a message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + public void message( String message, int indent ) + { + String messageText; + // Determine how many spaces to indent: + String spacer = ""; + for( int x = 0; x < indent; x++ ) + { + spacer += " "; + } + // indent the message: + messageText = spacer + message; + + // Print the message: + System.out.println( messageText ); + } + +/** + * Prints an important message. + * @param message Message to print. + * @param indent Number of tabs to indent the message. + */ + public void importantMessage( String message, int indent ) + { + String messageText; + // Determine how many spaces to indent: + String spacer = ""; + for( int x = 0; x < indent; x++ ) + { + spacer += " "; + } + // indent the message: + messageText = spacer + message; + + // Print the message: + System.out.println( messageText ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param classname Name of the class checking for an error. + * @param message Message to print if error is true. + * @param indent Number of tabs to indent the message. + * @return True if error is true. + */ + public boolean errorCheck( boolean error, String classname, String message, + int indent ) + { + if( error ) + errorMessage( classname, message, indent ); + return error; + } + +/** + * Prints the classname which generated the error, followed by the error + * message. + * @param classname Name of the class which generated the error. + * @param message The actual error message. + * @param indent Number of tabs to indent the message. +*/ + public void errorMessage( String classname, String message, int indent ) + { + String headerLine, messageText; + // Determine how many spaces to indent: + String spacer = ""; + for( int x = 0; x < indent; x++ ) + { + spacer += " "; + } + // indent the header: + headerLine = spacer + "Error in class '" + classname + "'"; + // indent the message one more than the header: + messageText = " " + spacer + message; + + // Print the error message: + System.out.println( headerLine ); + System.out.println( messageText ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + * @param indent Number of tabs to indent the message and stack trace. + */ + public void printStackTrace( Exception e, int indent ) + { + printExceptionMessage( e, indent ); + importantMessage( "STACK TRACE:", indent ); + if( e == null ) + return; + + StackTraceElement[] stack = e.getStackTrace(); + if( stack == null ) + return; + + StackTraceElement line; + for( int x = 0; x < stack.length; x++ ) + { + line = stack[x]; + if( line != null ) + message( line.toString(), indent + 1 ); + } + } + +/** + * Prints an exception's error message. + * @param e Exception containing the message to print. + * @param indent Number of tabs to indent the message. + */ + public void printExceptionMessage( Exception e, int indent ) + { + importantMessage( "ERROR MESSAGE:", indent ); + if( e.getMessage() == null ) + message( "(none)", indent + 1 ); + else + message( e.getMessage(), indent + 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/Source.java b/src/lwjgl/java/paulscode/sound/Source.java new file mode 100644 index 0000000..00c0a0a --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Source.java @@ -0,0 +1,1344 @@ +package paulscode.sound; + +import java.net.URL; +import java.util.LinkedList; +import java.util.ListIterator; +import javax.sound.sampled.AudioFormat; + +/** + * The Source class is used to store information about a source. + * Source objects are stored in a map in the Library class. The + * information they contain is used to create library-specific sources. + * This is the template class which is extended for each specific library. + * This class is also used by the "No Sound" library to represent a mute + * source. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Source +{ +/** + * The library class associated with this type of channel. + */ + protected Class libraryType = Library.class; + +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; + +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; + +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * True if this source is being directly fed with raw audio data. + */ + public boolean rawDataStream = false; + +/** + * Format the raw data will be in if this is a Raw Data Stream source. + */ + public AudioFormat rawDataFormat = null; + +/** + * Determines whether a source should be removed after it finishes playing. + */ + public boolean temporary = false; + +/** + * Determines whether or not this is a priority source. Priority sources will + * not be overwritten by other sources when there are no available channels. + */ + public boolean priority = false; + +/** + * Whether or not this source should be streamed. + */ + public boolean toStream = false; + +/** + * Whether this source should loop or only play once. + */ + public boolean toLoop = false; + +/** + * Whether this source needs to be played (for example if it was playing and + * looping when it got culled). + */ + public boolean toPlay = false; + +/** + * Unique name for this source. More than one source can not have the same + * sourcename. + */ + public String sourcename = ""; + +/** + * The audio file which this source should play. + */ + public FilenameURL filenameURL = null; + +/** + * This source's position in 3D space. + */ + public Vector3D position; + +/** + * Attenuation model to use for this source. + */ + public int attModel = 0; + +/** + * Either fade distance or rolloff factor, depending on the value of attModel. + */ + public float distOrRoll = 0.0f; + +/** + * Source's velocity in world-space, for use in Doppler effect. + */ + public Vector3D velocity; + +/** + * This source's volume (a float between 0.0 - 1.0). This value is used + * internally for attenuation, and should not be used to manually change a + * source's volume. + */ + public float gain = 1.0f; + +/** + * This value should be used to manually increase or decrease source volume. + */ + public float sourceVolume = 1.0f; + + /** + * Indicates to the streaming thread that this source is removed and needs cleanup. + * @see https://github.com/MinecraftForge/MinecraftForge/pull/4765 + */ + public boolean removed = false; + +/** + * This value represents the source's pitch (float value between 0.5f - 2.0f). + */ + protected float pitch = 1.0f; + +/** + * This source's distance from the listener. + */ + public float distanceFromListener = 0.0f; + +/** + * Channel to play this source on. + */ + public Channel channel = null; + +/** + * Holds the data used by normal sources. + */ + public SoundBuffer soundBuffer = null; + +/** + * False when this source gets culled. + */ + private boolean active = true; + +/** + * Whether or not this source has been stopped. + */ + private boolean stopped = true; + +/** + * Whether or not this source has been paused. + */ + private boolean paused = false; + +/** + * Codec used to read data for streaming sources. + */ + protected ICodec codec = null; + +/** + * Codec used to read in some initial data from the next sound in the queue. + */ + protected ICodec nextCodec = null; + +/** + * List of buffers to hold some initial data from the next sound in the queue. + */ + protected LinkedList nextBuffers = null; + + +/** + * The list of files to stream when the current stream finishes. + */ + protected LinkedList soundSequenceQueue = null; + +/** + * Ensures that only one thread accesses the soundSequenceQueue at a time. + */ + protected final Object soundSequenceLock = new Object(); + +/** + * Used by streaming sources to indicate whether or not the initial + * stream-buffers still need to be queued. + */ + public boolean preLoad = false; + +/** + * Specifies the gain factor used for the fade-out effect, or -1 when + * source is not currently fading out. + */ + protected float fadeOutGain = -1.0f; + +/** + * Specifies the gain factor used for the fade-in effect, or 1 when + * source is not currently fading in. + */ + protected float fadeInGain = 1.0f; + +/** + * Specifies the number of miliseconds it should take to fade out. + */ + protected long fadeOutMilis = 0; + +/** + * Specifies the number of miliseconds it should take to fade in. + */ + protected long fadeInMilis = 0; + +/** + * System time in miliseconds when the last fade in/out volume check occurred. + */ + protected long lastFadeCheck = 0; + +/** + * Constructor: Creates a new source using the specified parameters. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL The filename/URL of the sound file to play at this source. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public Source( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, + SoundBuffer soundBuffer, float x, float y, float z, + int attModel, float distOrRoll, boolean temporary ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + this.priority = priority; + this.toStream = toStream; + this.toLoop = toLoop; + this.sourcename = sourcename; + this.filenameURL = filenameURL; + this.soundBuffer = soundBuffer; + position = new Vector3D( x, y, z ); + this.attModel = attModel; + this.distOrRoll = distOrRoll; + this.velocity = new Vector3D( 0, 0, 0 ); + this.temporary = temporary; + + if( toStream && filenameURL != null ) + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + } + +/** + * Constructor: Creates a new source matching the specified one. + * @param old Source to copy information from. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + */ + public Source( Source old, SoundBuffer soundBuffer ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + priority = old.priority; + toStream = old.toStream; + toLoop = old.toLoop; + sourcename = old.sourcename; + filenameURL = old.filenameURL; + position = old.position.clone(); + attModel = old.attModel; + distOrRoll = old.distOrRoll; + velocity = old.velocity.clone(); + temporary = old.temporary; + + sourceVolume = old.sourceVolume; + + rawDataStream = old.rawDataStream; + rawDataFormat = old.rawDataFormat; + + this.soundBuffer = soundBuffer; + + if( toStream && filenameURL != null ) + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + } + +/** + * Constructor: Creates a new streaming source that will be directly fed with + * raw audio data. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + */ + public Source( AudioFormat audioFormat, boolean priority, String sourcename, + float x, float y, float z, int attModel, float distOrRoll ) + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + this.priority = priority; + this.toStream = true; + this.toLoop = false; + this.sourcename = sourcename; + this.filenameURL = null; + this.soundBuffer = null; + position = new Vector3D( x, y, z ); + this.attModel = attModel; + this.distOrRoll = distOrRoll; + this.velocity = new Vector3D( 0, 0, 0 ); + this.temporary = false; + + rawDataStream = true; + rawDataFormat = audioFormat; + } +/* Override methods */ + +/** + * Shuts the source down and removes references to all instantiated objects. + */ + public void cleanup() + { + if( codec != null ) + codec.cleanup(); + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null ) + soundSequenceQueue.clear(); + soundSequenceQueue = null; + } + + sourcename = null; + filenameURL = null; + position = null; + soundBuffer = null; + codec = null; + } + +/** + * If this is a streaming source, queues up the next sound to play when + * the previous stream ends. This method has no effect on non-streaming + * sources. + * @param filenameURL The filename/URL of the sound file to stream next. + */ + public void queueSound( FilenameURL filenameURL ) + { + if( !toStream ) + { + errorMessage( "Method 'queueSound' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( filenameURL == null ) + { + errorMessage( "File not specified in method 'queueSound'" ); + return; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue == null ) + soundSequenceQueue = new LinkedList(); + soundSequenceQueue.add( filenameURL ); + } + } + +/** + * Removes the first occurrence of the specified filename from the list of + * sounds to play when the previous stream ends. This method has no effect + * on non-streaming sources. + * @param filename Filename/identifier of a sound file to remove from the queue. + */ + public void dequeueSound( String filename ) + { + if( !toStream ) + { + errorMessage( "Method 'dequeueSound' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( filename == null || filename.equals( "" ) ) + { + errorMessage( "Filename not specified in method 'dequeueSound'" ); + return; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null ) + { + ListIterator i = soundSequenceQueue.listIterator(); + while( i.hasNext() ) + { + if( i.next().getFilename().equals( filename ) ) + { + i.remove(); + break; + } + } + } + } + } + +/** + * Fades out the volume of whatever this source is currently playing, then + * begins playing the specified filename at the source's previously assigned + * volume level. If the filename parameter is null or empty, the source will + * simply fade out and stop. The miliseconds parameter must be non-negative or + * zero. This method will remove anything that is currently in the list of + * queued sounds that would have played next when the current sound finished + * playing. This method has no effect on non-streaming sources. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milis Number of miliseconds the fadeout should take. + */ + public void fadeOut( FilenameURL filenameURL, long milis ) + { + if( !toStream ) + { + errorMessage( "Method 'fadeOut' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( milis < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOut'." ); + return; + } + + fadeOutMilis = milis; + fadeInMilis = 0; + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null ) + soundSequenceQueue.clear(); + + if( filenameURL != null ) + { + if( soundSequenceQueue == null ) + soundSequenceQueue = new LinkedList(); + soundSequenceQueue.add( filenameURL ); + } + } + } + +/** + * Fades out the volume of whatever this source is currently playing, then + * fades the volume back in playing the specified file. Final volume after + * fade-in completes will be equal to the source's previously assigned volume + * level. The filenameURL parameter may not be null or empty. The miliseconds + * parameters must be non-negative or zero. This method will remove anything + * that is currently in the list of queued sounds that would have played next + * when the current sound finished playing. This method has no effect on + * non-streaming sources. + * @param filenameURL Filename/URL of the sound file to play next, or null for none. + * @param milisOut Number of miliseconds the fadeout should take. + * @param milisIn Number of miliseconds the fadein should take. + */ + public void fadeOutIn( FilenameURL filenameURL, long milisOut, long milisIn ) + { + if( !toStream ) + { + errorMessage( "Method 'fadeOutIn' may only be used for " + + "streaming and MIDI sources." ); + return; + } + if( filenameURL == null ) + { + errorMessage( "Filename/URL not specified in method 'fadeOutIn'." ); + return; + } + if( milisOut < 0 || milisIn < 0 ) + { + errorMessage( "Miliseconds may not be negative in method " + + "'fadeOutIn'." ); + return; + } + + fadeOutMilis = milisOut; + fadeInMilis = milisIn; + + fadeOutGain = 1.0f; + lastFadeCheck = System.currentTimeMillis(); + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue == null ) + soundSequenceQueue = new LinkedList(); + soundSequenceQueue.clear(); + soundSequenceQueue.add( filenameURL ); + } + } + +/** + * Resets this source's volume if it is fading out or in. Returns true if this + * source is currently in the process of fading out. When fade-out completes, + * this method transitions the source to the next sound in the sound sequence + * queue if there is one. This method has no effect on non-streaming sources. + * @return True if this source is in the process of fading out. + */ + public boolean checkFadeOut() + { + if( !toStream ) + return false; + + if( fadeOutGain == -1.0f && fadeInGain == 1.0f ) + return false; + + long currentTime = System.currentTimeMillis(); + long milisPast = currentTime - lastFadeCheck; + lastFadeCheck = currentTime; + + if( fadeOutGain >= 0.0f ) + { + if( fadeOutMilis == 0 ) + { + fadeOutGain = -1.0f; + fadeInGain = 0.0f; + if( !incrementSoundSequence() ) + { + stop(); + } + positionChanged(); + preLoad = true; + return false; + } + else + { + float fadeOutReduction = ((float)milisPast) / ((float)fadeOutMilis); + fadeOutGain -= fadeOutReduction; + if( fadeOutGain <= 0.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 0.0f; + if( !incrementSoundSequence() ) + stop(); + positionChanged(); + preLoad = true; + return false; + } + } + positionChanged(); + return true; + } + + if( fadeInGain < 1.0f ) + { + fadeOutGain = -1.0f; + if( fadeInMilis == 0 ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + else + { + float fadeInIncrease = ((float)milisPast) / ((float)fadeInMilis); + fadeInGain += fadeInIncrease; + if( fadeInGain >= 1.0f ) + { + fadeOutGain = -1.0f; + fadeInGain = 1.0f; + } + } + positionChanged(); + return true; + } + return false; + } + +/** + * Removes the next filename/URL from the sound sequence queue and assigns it to + * this source. This method has no effect on non-streaming sources. This + * method is used internally by SoundSystem, and it is unlikely that the user + * will ever need to use it. + * @return True if there was something in the queue. + */ + public boolean incrementSoundSequence() + { + if( !toStream ) + { + errorMessage( "Method 'incrementSoundSequence' may only be used " + + "for streaming and MIDI sources." ); + return false; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 ) + { + filenameURL = soundSequenceQueue.remove( 0 ); + if( codec != null ) + codec.cleanup(); + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + return true; + } + } + return false; + } + +/** + * Reads in initial buffers of data from the next sound in the sound sequence + * queue, to reduce lag when the transition occurrs. This method has no effect + * on non-streaming sources. This method is used internally by SoundSystem, and + * it is unlikely that the user will ever need to use it. + * @return False if there is nothing in the queue to read from. + */ + public boolean readBuffersFromNextSoundInSequence() + { + if( !toStream ) + { + errorMessage( "Method 'readBuffersFromNextSoundInSequence' may " + + "only be used for streaming sources." ); + return false; + } + + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 ) + { + if( nextCodec != null ) + nextCodec.cleanup(); + nextCodec = SoundSystemConfig.getCodec( + soundSequenceQueue.get( 0 ).getFilename() ); + nextCodec.initialize( soundSequenceQueue.get( 0 ).getURL() ); + + SoundBuffer buffer = null; + for( int i = 0; + i < SoundSystemConfig.getNumberStreamingBuffers() + && !nextCodec.endOfStream(); + i++ ) + { + buffer = nextCodec.read(); + if( buffer != null ) + { + if( nextBuffers == null ) + nextBuffers = new LinkedList(); + nextBuffers.add( buffer ); + } + } + return true; + } + } + return false; + } + + +/** + * Returns the size of the sound sequence queue (if this is a streaming source). + * @return Number of sounds left in the queue, or zero if none. + */ + public int getSoundSequenceQueueSize() + { + if( soundSequenceQueue == null ) + return 0; + return soundSequenceQueue.size(); + } + +/** + * Sets whether or not this source should be removed when it finishes playing. + * @param tmp True or false. + */ + public void setTemporary( boolean tmp ) + { + temporary = tmp; + } + +/** + * Called every time the listener's position or orientation changes. + */ + public void listenerMoved() + {} + +/** + * Moves the source to the specified position. + * @param x X coordinate to move to. + * @param y Y coordinate to move to. + * @param z Z coordinate to move to. + */ + public void setPosition( float x, float y, float z ) + { + position.x = x; + position.y = y; + position.z = z; + } + +/** + * Called every time the source changes position. + */ + public void positionChanged() + {} + +/** + * Sets whether or not this source is a priority source. A priority source + * will not be overritten by another source if there are no channels available + * to play on. + * @param pri True or false. + */ + public void setPriority( boolean pri ) + { + priority = pri; + } + +/** + * Sets whether this source should loop or only play once. + * @param lp True or false. + */ + public void setLooping( boolean lp ) + { + toLoop = lp; + } + +/** + * Sets this source's attenuation model. + * @param model Attenuation model to use. + */ + public void setAttenuation( int model ) + { + attModel = model; + } + +/** + * Sets this source's fade distance or rolloff factor, depending on the + * attenuation model. + * @param dr New value for fade distance or rolloff factor. + */ + public void setDistOrRoll( float dr) + { + distOrRoll = dr; + } + +/** + * Sets this source's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + public void setVelocity( float x, float y, float z ) + { + this.velocity.x = x; + this.velocity.y = y; + this.velocity.z = z; + } + +/** + * Returns the source's distance from the listener. + * @return How far away the source is. + */ + public float getDistanceFromListener() + { + return distanceFromListener; + } + +/** + * Manually sets the specified source's pitch. + * @param value A float value ( 0.5f - 2.0f ). + */ + public void setPitch( float value ) + { + float newPitch = value; + if( newPitch < 0.5f ) + newPitch = 0.5f; + else if( newPitch > 2.0f ) + newPitch = 2.0f; + pitch = newPitch; + } + +/** + * Returns the pitch of the specified source. + * @return Float value representing the source pitch (0.5f - 2.0f). + */ + public float getPitch() + { + return pitch; + } + +/** + * Indicates whether or not this source's associated library requires some + * codecs to reverse-order the audio data they generate. + * @return True if audio data should be reverse-ordered. + */ + public boolean reverseByteOrder() + { + return SoundSystemConfig.reverseByteOrder( libraryType ); + } + +/** + * Changes the sources peripheral information to match the supplied parameters. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public void changeSource( boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, SoundBuffer soundBuffer, + float x, float y, float z, int attModel, + float distOrRoll, boolean temporary ) + { + this.priority = priority; + this.toStream = toStream; + this.toLoop = toLoop; + this.sourcename = sourcename; + this.filenameURL = filenameURL; + this.soundBuffer = soundBuffer; + position.x = x; + position.y = y; + position.z = z; + this.attModel = attModel; + this.distOrRoll = distOrRoll; + this.temporary = temporary; + } + +/** + * Feeds raw data to the specified channel. + * @param buffer Byte buffer containing raw audio data to stream. + * @param c Channel to stream on. + * @return Number of prior buffers that have been processed, or -1 if unable to queue the buffer (if the source was culled, for example). + */ + public int feedRawAudioData( Channel c, byte[] buffer ) + { + if( !active( GET, XXX) ) + { + toPlay = true; + return -1; + } + if( channel != c ) + { + channel = c; + channel.close(); + channel.setAudioFormat( rawDataFormat ); + positionChanged(); + } + + // change the state of this source to not stopped and not paused: + stopped( SET, false ); + paused( SET, false ); + + return channel.feedRawAudioData( buffer ); + } + +/** + * Plays the source on the specified channel. + * @param c Channel to play on. + */ + public void play( Channel c ) + { + if( !active( GET, XXX) ) + { + if( toLoop ) + toPlay = true; + return; + } + if( channel != c ) + { + channel = c; + channel.close(); + } + // change the state of this source to not stopped and not paused: + stopped( SET, false ); + paused( SET, false ); + } +/* END Override methods */ + +/** + * Streams the source on its current channel + * @return False when stream has finished playing. + */ + public boolean stream() + { + if( channel == null ) + return false; + + if( preLoad ) + { + if( rawDataStream ) + preLoad = false; + else + return preLoad(); + } + + if( rawDataStream ) + { + if( stopped() || paused() ) + return true; + if( channel.buffersProcessed() > 0 ) + channel.processBuffer(); + return true; + } + else + { + if( codec == null ) + return false; + if( stopped() ) + return false; + if( paused() ) + return true; + + int processed = channel.buffersProcessed(); + + SoundBuffer buffer = null; + for( int i = 0; i < processed; i++ ) + { + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + return true; + } + else if( codec.endOfStream() ) + { + synchronized( soundSequenceLock ) + { + if( SoundSystemConfig.getStreamQueueFormatsMatch() ) + { + if( soundSequenceQueue != null && + soundSequenceQueue.size() > 0 ) + { + if( codec != null ) + codec.cleanup(); + filenameURL = soundSequenceQueue.remove( 0 ); + codec = SoundSystemConfig.getCodec( + filenameURL.getFilename() ); + codec.initialize( filenameURL.getURL() ); + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + return true; + } + } + else if( toLoop ) + { + codec.initialize( filenameURL.getURL() ); + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + return true; + } + } + } + } + } +/* + if( codec.endOfStream() ) + { + synchronized( soundSequenceLock ) + { + if( SoundSystemConfig.getStreamQueueFormatsMatch() ) + { + if( soundSequenceQueue != null && + soundSequenceQueue.size() > 0 ) + { + if( codec != null ) + codec.cleanup(); + filenameURL = soundSequenceQueue.remove( 0 ); + codec = SoundSystemConfig.getCodec( + filenameURL.getFilename() ); + codec.initialize( filenameURL.getURL() ); + return true; + } + else if( toLoop ) + { + codec.initialize( filenameURL.getURL() ); + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + } + } + } + } + return false; + } +*/ + } + } + return false; + } + +/** + * Queues up the initial stream-buffers for the stream. + * @return False if the end of the stream was reached. + */ + public boolean preLoad() + { + if( channel == null ) + return false; + + if( codec == null ) + return false; + + SoundBuffer buffer = null; + + boolean noNextBuffers = false; + synchronized( soundSequenceLock ) + { + if( nextBuffers == null || nextBuffers.isEmpty() ) + noNextBuffers = true; + } + + if( nextCodec != null && !noNextBuffers ) + { + codec = nextCodec; + nextCodec = null; + synchronized( soundSequenceLock ) + { + while( !nextBuffers.isEmpty() ) + { + buffer = nextBuffers.remove( 0 ); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + } + } + } + } + else + { + nextCodec = null; + URL url = filenameURL.getURL(); + + codec.initialize( url ); + for( int i = 0; i < SoundSystemConfig.getNumberStreamingBuffers(); + i++ ) + { + buffer = codec.read(); + if( buffer != null ) + { + if( buffer.audioData != null ) + channel.queueBuffer( buffer.audioData ); + buffer.cleanup(); + buffer = null; + } + } + } + + return true; + } + +/** + * Pauses the source. + */ + public void pause() + { + toPlay = false; + paused( SET, true ); + if( channel != null ) + channel.pause(); + else + errorMessage( "Channel null in method 'pause'" ); + } + +/** + * Stops the source. + */ + public void stop() + { + toPlay = false; + stopped( SET, true ); + paused( SET, false ); + if( channel != null ) + channel.stop(); + else + errorMessage( "Channel null in method 'stop'" ); + } + +/** + * Rewinds the source. If the source was paused, then it is stopped. + */ + public void rewind() + { + if( paused( GET, XXX ) ) + { + stop(); + } + if( channel != null ) + { + boolean rePlay = playing(); + channel.rewind(); + if( toStream && rePlay ) + { + stop(); + play( channel ); + } + } + else + errorMessage( "Channel null in method 'rewind'" ); + } + +/** + * Dequeues any previously queued data. + */ + public void flush() + { + if( channel != null ) + channel.flush(); + else + errorMessage( "Channel null in method 'flush'" ); + } + +/** + * Stops and flushes the source, and prevents it from being played again until + * the activate() is called. + */ + public void cull() + { + if( !active( GET, XXX ) ) + return; + if( playing() && toLoop ) + toPlay = true; + if( rawDataStream ) + toPlay = true; + active( SET, false ); + if( channel != null ) + channel.close(); + channel = null; + } + +/** + * Allows a previously culled source to be played again. + */ + public void activate() + { + active( SET, true ); + } + +/** + * Returns false if the source has been culled. + * @return True or False + */ + public boolean active() + { + return active( GET, XXX ); + } + +/** + * Returns true if the source is playing. + * @return True or False + */ + public boolean playing() + { + if( channel == null || channel.attachedSource != this ) + return false; + else if( paused() || stopped() ) + return false; + else + return channel.playing(); + } + +/** + * Returns true if the source has been stopped. + * @return True or False + */ + public boolean stopped() + { + return stopped( GET, XXX ); + } + +/** + * Returns true if the source has been paused. + * @return True or False + */ + public boolean paused() + { + return paused( GET, XXX ); + } + +/** + * Returns the number of miliseconds since the source began playing. + * @return miliseconds, or -1 if not playing or unable to calculate + */ + public float millisecondsPlayed() + { + if( channel == null ) + return( -1 ); + else + return channel.millisecondsPlayed(); + } + +/** + * Sets or returns whether or not the source has been culled. + * @return True or False + */ + private synchronized boolean active( boolean action, boolean value ) + { + if( action == SET ) + active = value; + return active; + } + +/** + * Sets or returns whether or not the source has been stopped. + * @return True or False + */ + private synchronized boolean stopped( boolean action, boolean value ) + { + if( action == SET ) + stopped = value; + return stopped; + } + +/** + * Sets or returns whether or not the source has been paused. + * @return True or False + */ + private synchronized boolean paused( boolean action, boolean value ) + { + if( action == SET ) + paused = value; + return paused; + } + +/** + * Returns the name of the class. + * @return SoundLibraryXXXX. + */ + public String getClassName() + { + String libTitle = SoundSystemConfig.getLibraryTitle( libraryType ); + + if( libTitle.equals( "No Sound" ) ) + return "Source"; + else + return "Source" + libTitle; + } +/** + * Prints a message. + * @param message Message to print. + */ + protected void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + protected void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + protected boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, getClassName(), message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + protected void errorMessage( String message ) + { + logger.errorMessage( getClassName(), message, 0 ); + } + +/** + * Prints an exception's error message followed by the stack trace. + * @param e Exception containing the information to print. + */ + protected void printStackTrace( Exception e ) + { + logger.printStackTrace( e, 1 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/StreamThread.java b/src/lwjgl/java/paulscode/sound/StreamThread.java new file mode 100644 index 0000000..ab237be --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/StreamThread.java @@ -0,0 +1,303 @@ +package paulscode.sound; + +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +/** + * The StreamThread class is used to process all streaming sources. This + * thread starts out asleep, and it sleeps when all streaming sources are + * finished playing, so it is necessary to call interrupt() after adding new + * streaming sources to the list. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ * + */ +public class StreamThread extends SimpleThread +{ +/** + * Processes status messages, warnings, and error messages. + */ + private SoundSystemLogger logger; + +/** + * List of sources that are currently streaming. + */ + private List streamingSources; + +/** + * Used to synchronize access to the streaming sources list. + */ + private final Object listLock = new Object(); + +/** + * Constructor: Grabs a handle to the message logger and instantiates the + * streaming sources list. + */ + public StreamThread() + { + // grab a handle to the message logger: + logger = SoundSystemConfig.getLogger(); + + streamingSources = new LinkedList(); + } + +/** + * Removes all references to instantiated objects, and changes the thread's + * state to "not alive". Method alive() returns false when the cleanup() + * method has completed. + */ + @Override + protected void cleanup() + { + kill(); + super.cleanup(); // Important!! + } + +/** + * The main loop for processing commands. The thread sleeps when it finishes + * processing commands, and it must be interrupted to process more. + */ + @Override + public void run() + { + ListIterator iter; + Source src; + + // Start out asleep: + snooze( 3600000 ); + + while( !dying() ) + { + while( !dying() && !streamingSources.isEmpty() ) + { + // Make sure noone else is accessing the list of sources: + synchronized( listLock ) + { + iter = streamingSources.listIterator(); + while( !dying() && iter.hasNext() ) + { + src = iter.next(); + // If this is a removed source, we cleanup here and then let normal cleanup run - https://github.com/MinecraftForge/MinecraftForge/pull/4765 + if (src!=null && src.removed) + { + src.cleanup(); + src = null; + } + if( src == null ) + { + iter.remove(); + } + else if( src.stopped() ) + { + if( !src.rawDataStream ) + iter.remove(); + } + else if( !src.active() ) + { + if( src.toLoop || src.rawDataStream ) + src.toPlay = true; + iter.remove(); + } + else if( !src.paused() ) + { + src.checkFadeOut(); + if( (!src.stream()) && (!src.rawDataStream) ) + { + if( src.channel == null + || !src.channel.processBuffer() ) + { + if( src.nextCodec == null ) + { + src.readBuffersFromNextSoundInSequence(); + } +/* + if( src.getSoundSequenceQueueSize() > 0 ) + { + src.incrementSoundSequence(); + } + + // check if this is a looping source + else*/ if( src.toLoop ) + { + // wait for stream to finish playing + if( !src.playing() ) + { + // Generate an EOS event: + SoundSystemConfig.notifyEOS( + src.sourcename, + src.getSoundSequenceQueueSize() + ); + // Check if the source is currently + // in the process of fading out. + if( src.checkFadeOut() ) + { + // Source is fading out. + // Keep looping until it + // finishes. + src.preLoad = true; + } + else + { + // Source is not fading out. + // If there is another sound in + // the sequence, switch to it + // before replaying. + src.incrementSoundSequence(); + src.preLoad = true; // replay + } + } + } + else + { + // wait for stream to finish playing + if( !src.playing() ) + { + // Generate an EOS event: + SoundSystemConfig.notifyEOS( + src.sourcename, + src.getSoundSequenceQueueSize() + ); + // Check if the source is currently + // in the process of fading out + if( !src.checkFadeOut() ) + { + // Source is not fading out. + // Play anything else that is + // in the sound sequence queue. + if( + src.incrementSoundSequence() ) + src.preLoad = true; + else + iter.remove(); // finished + } + } + } + } + } + } + } + } + if( !dying() && !streamingSources.isEmpty() ) + snooze( 20 ); // sleep a bit so we don't peg the cpu + } + if( !dying() && streamingSources.isEmpty() ) + snooze( 3600000 ); // sleep until there is more to do. + } + + cleanup(); // Important!! + } + +/** + * Adds a new streaming source to the list. If another source in the list is + * already playing on the same channel, it is stopped and removed from the + * list. + * @param source New source to stream. + */ + public void watch( Source source ) + { + // make sure the source exists: + if( source == null ) + return; + + // make sure we aren't already watching this source: + if( streamingSources.contains( source ) ) + return; + + ListIterator iter; + Source src; + + // Make sure noone else is accessing the list of sources: + synchronized( listLock ) + { + // Any currently watched source which is null or playing on the + // same channel as the new source should be stopped and removed + // from the list. + iter = streamingSources.listIterator(); + while( iter.hasNext() ) + { + src = iter.next(); + if( src == null ) + { + iter.remove(); + } + else if( source.channel == src.channel ) + { + src.stop(); + iter.remove(); + } + } + + // Add the new source to the list: + streamingSources.add( source ); + } + } + +/** + * Prints a message. + * @param message Message to print. + */ + private void message( String message ) + { + logger.message( message, 0 ); + } + +/** + * Prints an important message. + * @param message Message to print. + */ + private void importantMessage( String message ) + { + logger.importantMessage( message, 0 ); + } + +/** + * Prints the specified message if error is true. + * @param error True or False. + * @param message Message to print if error is true. + * @return True if error is true. + */ + private boolean errorCheck( boolean error, String message ) + { + return logger.errorCheck( error, "StreamThread", message, 0 ); + } + +/** + * Prints an error message. + * @param message Message to print. + */ + private void errorMessage( String message ) + { + logger.errorMessage( "StreamThread", message, 0 ); + } +} diff --git a/src/lwjgl/java/paulscode/sound/Vector3D.java b/src/lwjgl/java/paulscode/sound/Vector3D.java new file mode 100644 index 0000000..5c38676 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/Vector3D.java @@ -0,0 +1,210 @@ +package paulscode.sound; + +/** + * The Vector3D class contains methods to simplify common 3D vector functions, + * such as cross and dot product, normalize, etc. + *

+ * SoundSystem License:

+ * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 2) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 3) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 4) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 5) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 6) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class Vector3D +{ + +/** + * The vector's X coordinate. + */ + public float x; + +/** + * The vector's Y coordinate. + */ + public float y; + +/** + * The vector's Z coordinate. + */ + public float z; + +/** + * Constructor: Places the vector at the origin. + */ + public Vector3D() + { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } + +/** + * Constructor: Places the vector at the specified 3D coordinates. + * @param nx X coordinate for the new vector. + * @param ny Y coordinate for the new vector. + * @param nz Z coordinate for the new vector. + */ + public Vector3D( float nx, float ny, float nz ) + { + x = nx; + y = ny; + z = nz; + } + +/** + * Returns a new instance containing the same information as this one. + * @return A new Vector3D. + */ + @Override + public Vector3D clone() + { + return new Vector3D( x, y, z ); + } + +/** + * Returns a vector containing the cross-product: A cross B. + * @param A First vector in the cross product. + * @param B Second vector in the cross product. + * @return A new Vector3D. + */ + public Vector3D cross( Vector3D A, Vector3D B ) + { + return new Vector3D( + A.y * B.z - B.y * A.z, + A.z * B.x - B.z * A.x, + A.x * B.y - B.x * A.y ); + } + +/** + * Returns a vector containing the cross-product: (this) cross B. + * @param B Second vector in the cross product. + * @return A new Vector3D. + */ + public Vector3D cross( Vector3D B ) + { + return new Vector3D( + y * B.z - B.y * z, + z * B.x - B.z * x, + x * B.y - B.x * y ); + + } + +/** + * Returns the dot-product result of: A dot B. + * @param A First vector in the dot product. + * @param B Second vector in the dot product. + * @return Dot product. + */ + public float dot( Vector3D A, Vector3D B ) + { + return( (A.x * B.x) + (A.y * B.y) + (A.z * B.z) ); + } + +/** + * Returns the dot-product result of: (this) dot B. + * @param B Second vector in the dot product. + * @return Dot product. + */ + public float dot( Vector3D B ) + { + return( (x * B.x) + (y * B.y) + (z * B.z) ); + } + +/** + * Returns the vector represented by: A + B. + * @param A First vector. + * @param B Vector to add to A. + * @return A new Vector3D. + */ + public Vector3D add( Vector3D A, Vector3D B ) + { + return new Vector3D( A.x + B.x, A.y + B.y, A.z + B.z ); + } + +/** + * Returns the vector represented by: (this) + B. + * @param B Vector to add to this one. + * @return A new Vector3D. + */ + public Vector3D add( Vector3D B ) + { + return new Vector3D( x + B.x, y + B.y, z + B.z ); + } + +/** + * Returns the vector represented by: A - B. + * @param A First vector. + * @param B Vector to subtract from A. + * @return A new Vector3D. + */ + public Vector3D subtract( Vector3D A, Vector3D B ) + { + return new Vector3D( A.x - B.x, A.y - B.y, A.z - B.z ); + } + +/** + * Returns the vector represented by: (this) - B. + * @param B Vector to subtract from this one. + * @return A new Vector3D. + */ + public Vector3D subtract( Vector3D B ) + { + return new Vector3D( x - B.x, y - B.y, z - B.z ); + } + +/** + * Returns the length of this vector. + * @return Length. + */ + public float length() + { + return (float) Math.sqrt( x * x + y * y + z * z ); + } + +/** + * Changes the length of this vector to 1.0. + */ + public void normalize() + { + double t = Math.sqrt( x*x + y*y + z*z ); + x = (float) (x / t); + y = (float) (y / t); + z = (float) (z / t); + } + +/** + * Returns a string depicting this vector. + * @return "Vector3D (x, y, z)". + */ + @Override + public String toString() + { + return "Vector3D (" + x + ", " + y + ", " + z + ")"; + } +} diff --git a/src/lwjgl/java/paulscode/sound/libraries/ChannelLWJGLOpenAL.java b/src/lwjgl/java/paulscode/sound/libraries/ChannelLWJGLOpenAL.java new file mode 100644 index 0000000..637d146 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/libraries/ChannelLWJGLOpenAL.java @@ -0,0 +1,696 @@ +package paulscode.sound.libraries; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.LinkedList; +import javax.sound.sampled.AudioFormat; + +// From the lwjgl library, http://www.lwjgl.org +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; +import org.lwjgl.openal.AL11; + +import paulscode.sound.Channel; +import paulscode.sound.SoundSystemConfig; + +/** + * The ChannelLWJGLOpenAL class is used to reserve a sound-card voice using the + * lwjgl binding of OpenAL. Channels can be either normal or streaming + * channels. + *

+ * This software is based on or using the LWJGL Lightweight Java Gaming + * Library available from + * http://www.lwjgl.org/. + *


+ * LWJGL License: + *
+ * Copyright (c) 2002-2008 Lightweight Java Game Library Project + * All rights reserved. + *
+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + *
+ * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + *
+ * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + *
+ * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *


+ * SoundSystem LibraryLWJGLOpenAL License:

+ * + * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You must abide by the conditions of the aforementioned LWJGL License. + *
+ * 2) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 3) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 4) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 5) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 6) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 7) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class ChannelLWJGLOpenAL extends Channel +{ +/** + * OpenAL's IntBuffer identifier for this channel. + */ + public IntBuffer ALSource; + +/** + * OpenAL data format to use when playing back the assigned source. + */ + public int ALformat; // OpenAL data format + +/** + * Sample rate (speed) to use for play-back. + */ + public int sampleRate; // sample rate + +/** + * Miliseconds of buffers previously played (streaming sources). + */ + public float millisPreviouslyPlayed = 0; + +/** + * Constructor: takes channelType identifier and a handle to the OpenAL + * IntBuffer identifier to use for this channel. Possible values for channel + * type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel (normal or streaming). + * @param src Handle to the OpenAL source identifier. + */ + public ChannelLWJGLOpenAL( int type, IntBuffer src ) + { + super( type ); + libraryType = LibraryLWJGLOpenAL.class; + ALSource = src; + } + +/** + * Empties the streamBuffers list, stops and deletes the ALSource, shuts the + * channel down, and removes references to all instantiated objects. + */ + @Override + public void cleanup() + { + if( ALSource != null ) + { + try + { + // Stop playing the source: + AL10.alSourceStop( ALSource ); + AL10.alGetError(); + } + catch( Exception e ) + {} + try + { + // Delete the source: + AL10.alDeleteSources( ALSource ); + AL10.alGetError(); + } + catch( Exception e ) + {} + ALSource.clear(); + } + ALSource = null; + + super.cleanup(); + } + +/** + * Attaches an OpenAL sound-buffer identifier for the sound data to be played + * back for a normal source. + * @param buf Intbuffer identifier for the sound data to play. + * @return False if an error occurred. + */ + public boolean attachBuffer( IntBuffer buf ) + { + // A sound buffer can only be attached to a normal source: + if( errorCheck( channelType != SoundSystemConfig.TYPE_NORMAL, + "Sound buffers may only be attached to normal " + + "sources." ) ) + return false; + + // send the sound buffer to the channel: + AL10.alSourcei( ALSource.get( 0 ), AL10.AL_BUFFER, + buf.get(0) ); + + + // save the format for later, for determining milliseconds played + if( attachedSource != null && attachedSource.soundBuffer != null && + attachedSource.soundBuffer.audioFormat != null ) + setAudioFormat( attachedSource.soundBuffer.audioFormat ); + + // Check for errors and return: + return checkALError(); + } +/** + * Sets the channel up to receive the specified audio format. + * @param audioFormat Format to use when playing the stream data. + */ + @Override + public void setAudioFormat( AudioFormat audioFormat ) + { + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'setAudioFormat'" ); + return; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'setAudioFormat'" ); + return; + } + } + else + { + errorMessage( "Audio data neither mono nor stereo in " + + "method 'setAudioFormat'" ); + return; + } + ALformat = soundFormat; + sampleRate = (int) audioFormat.getSampleRate(); + } +/** + * Sets the channel up to receive the specified OpenAL audio format and sample + * rate. + * @param format Format to use. + * @param rate Sample rate (speed) to use. + */ + public void setFormat( int format, int rate ) + { + ALformat = format; + sampleRate = rate; + } + +/** + * Queues up the initial byte[] buffers of data to be streamed. + * @param bufferList List of the first buffers to be played for a streaming source. + * @return False if problem occurred or if end of stream was reached. + */ + @Override + public boolean preLoadBuffers( LinkedList bufferList ) + { + // Stream buffers can only be queued for streaming sources: + if( errorCheck( channelType != SoundSystemConfig.TYPE_STREAMING, + "Buffers may only be queued for streaming sources." ) ) + return false; + + if( errorCheck( bufferList == null, + "Buffer List null in method 'preLoadBuffers'" ) ) + return false; + + IntBuffer streamBuffers; + + // Remember if the channel was playing: + boolean playing = playing(); + // stop the channel if it is playing: + if( playing ) + { + AL10.alSourceStop( ALSource.get( 0 ) ); + checkALError(); + } + // Clear out any previously queued buffers: + int processed = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_PROCESSED ); + if( processed > 0 ) + { + streamBuffers = BufferUtils.createIntBuffer( processed ); + AL10.alGenBuffers( streamBuffers ); + if( errorCheck( checkALError(), + "Error clearing stream buffers in method 'preLoadBuffers'" ) ) + return false; + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), streamBuffers ); + if( errorCheck( checkALError(), + "Error unqueuing stream buffers in method 'preLoadBuffers'" ) ) + return false; + } + + // restart the channel if it was previously playing: + if( playing ) + { + AL10.alSourcePlay( ALSource.get( 0 ) ); + checkALError(); + } + + streamBuffers = BufferUtils.createIntBuffer( bufferList.size() ); + AL10.alGenBuffers( streamBuffers ); + if( errorCheck( checkALError(), + "Error generating stream buffers in method 'preLoadBuffers'" ) ) + return false; + + ByteBuffer byteBuffer = null; + for( int i = 0; i < bufferList.size(); i++ ) + { + //byteBuffer = ByteBuffer.wrap( bufferList.get(i), 0, + // bufferList.get(i).length ); + byteBuffer = (ByteBuffer) BufferUtils.createByteBuffer( + bufferList.get(i).length ).put( bufferList.get( i ) ).flip(); + + try + { + AL10.alBufferData( streamBuffers.get(i), ALformat, byteBuffer, + sampleRate ); + } + catch( Exception e ) + { + errorMessage( "Error creating buffers in method " + + "'preLoadBuffers'" ); + printStackTrace( e ); + return false; + } + if( errorCheck( checkALError(), + "Error creating buffers in method 'preLoadBuffers'" ) ) + return false; + + } + + try + { + AL10.alSourceQueueBuffers( ALSource.get( 0 ), streamBuffers ); + } + catch( Exception e ) + { + errorMessage( "Error queuing buffers in method 'preLoadBuffers'" ); + printStackTrace( e ); + return false; + } + if( errorCheck( checkALError(), + "Error queuing buffers in method 'preLoadBuffers'" ) ) + return false; + + AL10.alSourcePlay( ALSource.get( 0 ) ); + if( errorCheck( checkALError(), + "Error playing source in method 'preLoadBuffers'" ) ) + return false; + + // Success: + return true; + } + +/** + * Queues up a byte[] buffer of data to be streamed. + * @param buffer The next buffer to be played for a streaming source. + * @return False if an error occurred or if the channel is shutting down. + */ + @Override + public boolean queueBuffer( byte[] buffer ) + { + // Stream buffers can only be queued for streaming sources: + if( errorCheck( channelType != SoundSystemConfig.TYPE_STREAMING, + "Buffers may only be queued for streaming sources." ) ) + return false; + + //ByteBuffer byteBuffer = ByteBuffer.wrap( buffer, 0, buffer.length ); + ByteBuffer byteBuffer = (ByteBuffer) BufferUtils.createByteBuffer( + buffer.length ).put( buffer ).flip(); + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), intBuffer ); + if( checkALError() ) + return false; + + if( AL10.alIsBuffer( intBuffer.get( 0 ) ) ) + millisPreviouslyPlayed += millisInBuffer( intBuffer.get( 0 ) ); + checkALError(); + + AL10.alBufferData( intBuffer.get(0), ALformat, byteBuffer, sampleRate ); + if( checkALError() ) + return false; + + AL10.alSourceQueueBuffers( ALSource.get( 0 ), intBuffer ); + if( checkALError() ) + return false; + + return true; + } + +/** + * Feeds raw data to the stream. + * @param buffer Buffer containing raw audio data to stream. + * @return Number of prior buffers that have been processed., or -1 if error. + */ + @Override + public int feedRawAudioData( byte[] buffer ) + { + // Stream buffers can only be queued for streaming sources: + if( errorCheck( channelType != SoundSystemConfig.TYPE_STREAMING, + "Raw audio data can only be fed to streaming sources." ) ) + return -1; + + //ByteBuffer byteBuffer = ByteBuffer.wrap( buffer, 0, buffer.length ); + ByteBuffer byteBuffer = (ByteBuffer) BufferUtils.createByteBuffer( + buffer.length ).put( buffer ).flip(); + + IntBuffer intBuffer; + + // Clear out any previously queued buffers: + int processed = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_PROCESSED ); + if( processed > 0 ) + { + intBuffer = BufferUtils.createIntBuffer( processed ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( checkALError(), + "Error clearing stream buffers in method 'feedRawAudioData'" ) ) + return -1; + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), intBuffer ); + if( errorCheck( checkALError(), + "Error unqueuing stream buffers in method 'feedRawAudioData'" ) ) + return -1; + int i; + intBuffer.rewind(); + while( intBuffer.hasRemaining() ) + { + i = intBuffer.get(); + if( AL10.alIsBuffer( i ) ) + { + millisPreviouslyPlayed += millisInBuffer( i ); + } + checkALError(); + } + AL10.alDeleteBuffers( intBuffer ); + checkALError(); + } + intBuffer = BufferUtils.createIntBuffer( 1 ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( checkALError(), + "Error generating stream buffers in method 'preLoadBuffers'" ) ) + return -1; + + AL10.alBufferData( intBuffer.get(0), ALformat, byteBuffer, sampleRate ); + if( checkALError() ) + return -1; + + AL10.alSourceQueueBuffers( ALSource.get( 0 ), intBuffer ); + if( checkALError() ) + return -1; + + if( attachedSource != null && attachedSource.channel == this && + attachedSource.active() ) + { + // restart the channel if it was previously playing: + if( !playing() ) + { + AL10.alSourcePlay( ALSource.get( 0 ) ); + checkALError(); + } + } + + return processed; + } + +/** + * Returns the number of milliseconds of audio contained in specified buffer. + * @return milliseconds, or 0 if unable to calculate. + */ + public float millisInBuffer( int alBufferi ) + { + return( ( (float) AL10.alGetBufferi( alBufferi, AL10.AL_SIZE ) / + (float) AL10.alGetBufferi( alBufferi, AL10.AL_CHANNELS ) / + ( (float) AL10.alGetBufferi( alBufferi, AL10.AL_BITS ) / 8.0f ) / + (float) sampleRate ) * 1000 ); + } + +/** + * Calculates the number of milliseconds since the channel began playing. + * @return Milliseconds, or -1 if unable to calculate. + */ + @Override + public float millisecondsPlayed() + { + // get number of samples played in current buffer + float offset = (float)AL10.alGetSourcei( ALSource.get( 0 ), + AL11.AL_BYTE_OFFSET ); + + float bytesPerFrame = 1f; + switch( ALformat ) + { + case AL10.AL_FORMAT_MONO8 : + bytesPerFrame = 1f; + break; + case AL10.AL_FORMAT_MONO16 : + bytesPerFrame = 2f; + break; + case AL10.AL_FORMAT_STEREO8 : + bytesPerFrame = 2f; + break; + case AL10.AL_FORMAT_STEREO16 : + bytesPerFrame = 4f; + break; + default : + break; + } + + offset = ( ( (float) offset / bytesPerFrame ) / (float) sampleRate ) + * 1000; + + // add the milliseconds from stream-buffers that played previously + if( channelType == SoundSystemConfig.TYPE_STREAMING ) + offset += millisPreviouslyPlayed; + + // Return millis played: + return( offset ); + } + +/** + * Returns the number of queued byte[] buffers that have finished playing. + * @return Number of buffers processed. + */ + @Override + public int buffersProcessed() + { + // Only streaming sources process buffers: + if( channelType != SoundSystemConfig.TYPE_STREAMING ) + return 0; + + // determine how many have been processed: + int processed = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_PROCESSED ); + + // Check for errors: + if( checkALError() ) + return 0; + + // Return how many were processed: + return processed; + } + +/** + * Dequeues all previously queued data. + */ + @Override + public void flush() + { + // Only a streaming source can be flushed, because only streaming + // sources have queued buffers: + if( channelType != SoundSystemConfig.TYPE_STREAMING ) + return; + + // determine how many buffers have been queued: + int queued = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_BUFFERS_QUEUED ); + // Check for errors: + if( checkALError() ) + return; + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + while( queued > 0 ) + { + try + { + AL10.alSourceUnqueueBuffers( ALSource.get( 0 ), intBuffer ); + } + catch( Exception e ) + { + return; + } + if( checkALError() ) + return; + queued--; + } + millisPreviouslyPlayed = 0; + } + +/** + * Stops the channel, dequeues any queued data, and closes the channel. + */ + @Override + public void close() + { + try + { + AL10.alSourceStop( ALSource.get( 0 ) ); + AL10.alGetError(); + } + catch( Exception e ) + {} + + if( channelType == SoundSystemConfig.TYPE_STREAMING ) + flush(); + } + +/** + * Plays the currently attached normal source, opens this channel up for + * streaming, or resumes playback if this channel was paused. + */ + @Override + public void play() + { + AL10.alSourcePlay( ALSource.get( 0 ) ); + checkALError(); + } + +/** + * Temporarily stops playback for this channel. + */ + @Override + public void pause() + { + AL10.alSourcePause( ALSource.get( 0 ) ); + checkALError(); + } + +/** + * Stops playback for this channel and rewinds the attached source to the + * beginning. + */ + @Override + public void stop() + { + AL10.alSourceStop( ALSource.get( 0 ) ); + if( !checkALError() ) + millisPreviouslyPlayed = 0; + } + +/** + * Rewinds the attached source to the beginning. Stops the source if it was + * paused. + */ + @Override + public void rewind() + { + // rewinding for streaming sources is handled elsewhere + if( channelType == SoundSystemConfig.TYPE_STREAMING ) + return; + + AL10.alSourceRewind( ALSource.get( 0 ) ); + if( !checkALError() ) + millisPreviouslyPlayed = 0; + } + + +/** + * Used to determine if a channel is actively playing a source. This method + * will return false if the channel is paused or stopped and when no data is + * queued to be streamed. + * @return True if this channel is playing a source. + */ + @Override + public boolean playing() + { + int state = AL10.alGetSourcei( ALSource.get( 0 ), + AL10.AL_SOURCE_STATE ); + if( checkALError() ) + return false; + + return( state == AL10.AL_PLAYING ); + } + +/** + * Checks for OpenAL errors, and prints a message if there is an error. + * @return True if there was an error, False if not. + */ + private boolean checkALError() + { + switch( AL10.alGetError() ) + { + case AL10.AL_NO_ERROR: + return false; + case AL10.AL_INVALID_NAME: + errorMessage( "Invalid name parameter." ); + return true; + case AL10.AL_INVALID_ENUM: + errorMessage( "Invalid parameter." ); + return true; + case AL10.AL_INVALID_VALUE: + errorMessage( "Invalid enumerated parameter value." ); + return true; + case AL10.AL_INVALID_OPERATION: + errorMessage( "Illegal call." ); + return true; + case AL10.AL_OUT_OF_MEMORY: + errorMessage( "Unable to allocate memory." ); + return true; + default: + errorMessage( "An unrecognized error occurred." ); + return true; + } + } +} diff --git a/src/lwjgl/java/paulscode/sound/libraries/LibraryLWJGLOpenAL.java b/src/lwjgl/java/paulscode/sound/libraries/LibraryLWJGLOpenAL.java new file mode 100644 index 0000000..1b1b939 --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/libraries/LibraryLWJGLOpenAL.java @@ -0,0 +1,1126 @@ +package paulscode.sound.libraries; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.FloatBuffer; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; +import javax.sound.sampled.AudioFormat; + +// From the lwjgl library, http://www.lwjgl.org +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.openal.AL; +import org.lwjgl.openal.AL10; + +import paulscode.sound.Channel; +import paulscode.sound.FilenameURL; +import paulscode.sound.ICodec; +import paulscode.sound.Library; +import paulscode.sound.ListenerData; +import paulscode.sound.SoundBuffer; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.SoundSystemException; +import paulscode.sound.Source; + +/** + * The LibraryLWJGLOpenAL class interfaces the lwjgl binding of OpenAL. + *

+ * This software is based on or using the LWJGL Lightweight Java Gaming + * Library available from + * http://www.lwjgl.org/. + *


+ * LWJGL License: + *
+ * Copyright (c) 2002-2008 Lightweight Java Game Library Project + * All rights reserved. + *
+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + *
+ * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + *
+ * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + *
+ * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *


+ * SoundSystem LibraryLWJGLOpenAL License:

+ * + * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You must abide by the conditions of the aforementioned LWJGL License. + *
+ * 2) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 3) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 4) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 5) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 6) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 7) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class LibraryLWJGLOpenAL extends Library +{ +/** + * Used to return a current value from one of the synchronized + * boolean-interface methods. + */ + private static final boolean GET = false; +/** + * Used to set the value in one of the synchronized boolean-interface methods. + */ + private static final boolean SET = true; +/** + * Used when a parameter for one of the synchronized boolean-interface methods + * is not aplicable. + */ + private static final boolean XXX = false; + +/** + * Position of the listener in 3D space. + */ + private FloatBuffer listenerPositionAL = null; +/** + * Information about the listener's orientation. + */ + private FloatBuffer listenerOrientation = null; +/** + * Velocity of the listener. + */ + private FloatBuffer listenerVelocity = null; +/** + * Map containing OpenAL identifiers for sound buffers. + */ + private HashMap ALBufferMap = null; + +/** + * Whether or not the AL_PITCH control is supported. + */ + private static boolean alPitchSupported = true; + +/** + * Constructor: Instantiates the source map, buffer map and listener + * information. Also sets the library type to + * SoundSystemConfig.LIBRARY_OPENAL + */ + public LibraryLWJGLOpenAL() throws SoundSystemException + { + super(); + ALBufferMap = new HashMap(); + reverseByteOrder = true; + } + +/** + * Initializes OpenAL, creates the listener, and grabs up audio channels. + */ + @Override + public void init() throws SoundSystemException + { + boolean errors = false; // set to 'true' if error(s) occur: + + try + { + // Try and create the sound system: + AL.create(); + errors = checkALError(); + } + catch( LWJGLException e ) + { + // There was an exception + errorMessage( "Unable to initialize OpenAL. Probable cause: " + + "OpenAL not supported." ); + printStackTrace( e ); + throw new LibraryLWJGLOpenAL.Exception( e.getMessage(), + LibraryLWJGLOpenAL.Exception.CREATE ); + } + + // Let user know if the library loaded properly + if( errors ) + importantMessage( "OpenAL did not initialize properly!" ); + else + message( "OpenAL initialized." ); + + // Listener is at the origin, facing along the z axis, no velocity: + listenerPositionAL = BufferUtils.createFloatBuffer( 3 ).put( + new float[] { listener.position.x, + listener.position.y, + listener.position.z } ); + listenerOrientation = BufferUtils.createFloatBuffer( 6 ).put ( + new float[] { listener.lookAt.x, listener.lookAt.y, + listener.lookAt.z, listener.up.x, listener.up.y, + listener.up.z } ); + listenerVelocity = BufferUtils.createFloatBuffer( 3 ).put ( + new float[] { 0.0f, 0.0f, 0.0f } ); + + // Flip the buffers, so they can be used: + listenerPositionAL.flip(); + listenerOrientation.flip(); + listenerVelocity.flip(); + + // Pass the buffers to the sound system, and check for potential errors: + AL10.alListener( AL10.AL_POSITION, listenerPositionAL ); + errors = checkALError() || errors; + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + errors = checkALError() || errors; + AL10.alListener( AL10.AL_VELOCITY, listenerVelocity ); + errors = checkALError() || errors; + + AL10.alDopplerFactor( SoundSystemConfig.getDopplerFactor() ); + errors = checkALError() || errors; + + AL10.alDopplerVelocity( SoundSystemConfig.getDopplerVelocity() ); + errors = checkALError() || errors; + + // Let user know what caused the above error messages: + if( errors ) + { + importantMessage( "OpenAL did not initialize properly!" ); + throw new LibraryLWJGLOpenAL.Exception( "Problem encountered " + + "while loading OpenAL or " + + "creating the listener. " + + "Probable cause: OpenAL not " + + "supported", + LibraryLWJGLOpenAL.Exception.CREATE ); + } + + super.init(); + + // Check if we can use the AL_PITCH control: + ChannelLWJGLOpenAL channel = (ChannelLWJGLOpenAL) + normalChannels.get( 1 ); + try + { + AL10.alSourcef( channel.ALSource.get( 0 ), + AL10.AL_PITCH, 1.0f ); + if( checkALError() ) + { + alPitchSupported( SET, false ); + throw new LibraryLWJGLOpenAL.Exception( "OpenAL: AL_PITCH not " + + "supported.", LibraryLWJGLOpenAL.Exception.NO_AL_PITCH ); + } + else + { + alPitchSupported( SET, true ); + } + } + catch( java.lang.Exception e ) + { + alPitchSupported( SET, false ); + throw new LibraryLWJGLOpenAL.Exception( "OpenAL: AL_PITCH not " + + "supported.", LibraryLWJGLOpenAL.Exception.NO_AL_PITCH ); + } + } + +/** + * Checks if the OpenAL library type is compatible. + * @return True or false. + */ + public static boolean libraryCompatible() + { + if( AL.isCreated() ) + return true; + + try + { + AL.create(); + } + catch( java.lang.Exception e ) + { + return false; + } + + try + { + AL.destroy(); + } + catch( java.lang.Exception e ) + {} + + return true; + } + +/** + * Creates a new channel of the specified type (normal or streaming). Possible + * values for channel type can be found in the + * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class. + * @param type Type of channel. + */ + @Override + protected Channel createChannel( int type ) + { + ChannelLWJGLOpenAL channel; + IntBuffer ALSource; + + ALSource = BufferUtils.createIntBuffer( 1 ); + try + { + AL10.alGenSources( ALSource ); + } + catch( java.lang.Exception e ) + { + AL10.alGetError(); + return null; // no more voices left + } + + if( AL10.alGetError() != AL10.AL_NO_ERROR ) + return null; + + channel = new ChannelLWJGLOpenAL( type, ALSource ); + return channel; + } + + /** + * Stops all sources, shuts down OpenAL, and removes references to all + * instantiated objects. + */ + @Override + public void cleanup() + { + super.cleanup(); + + Set keys = bufferMap.keySet(); + Iterator iter = keys.iterator(); + String filename; + IntBuffer buffer; + + // loop through and clear all sound buffers: + while( iter.hasNext() ) + { + filename = iter.next(); + buffer = ALBufferMap.get( filename ); + if( buffer != null ) + { + AL10.alDeleteBuffers( buffer ); + checkALError(); + buffer.clear(); + } + } + + bufferMap.clear(); + AL.destroy(); + + bufferMap = null; + listenerPositionAL = null; + listenerOrientation = null; + listenerVelocity = null; + } + +/** + * Pre-loads a sound into memory. + * @param filenameURL Filename/URL of the sound file to load. + * @return True if the sound loaded properly. + */ + @Override + public boolean loadSound( FilenameURL filenameURL ) + { + // Make sure the buffer map exists: + if( bufferMap == null ) + { + bufferMap = new HashMap(); + importantMessage( "Buffer Map was null in method 'loadSound'" ); + } + // Make sure the OpenAL buffer map exists: + if( ALBufferMap == null ) + { + ALBufferMap = new HashMap(); + importantMessage( "Open AL Buffer Map was null in method" + + "'loadSound'" ); + } + + // make sure they gave us a filename: + if( errorCheck( filenameURL == null, + "Filename/URL not specified in method 'loadSound'" ) ) + return false; + + // check if it is already loaded: + if( bufferMap.get( filenameURL.getFilename() ) != null ) + return true; + + ICodec codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + if( errorCheck( codec == null, "No codec found for file '" + + filenameURL.getFilename() + + "' in method 'loadSound'" ) ) + return false; + codec.reverseByteOrder( true ); + + URL url = filenameURL.getURL(); + if( errorCheck( url == null, "Unable to open file '" + + filenameURL.getFilename() + + "' in method 'loadSound'" ) ) + return false; + + codec.initialize( url ); + SoundBuffer buffer = codec.readAll(); + codec.cleanup(); + codec = null; + if( errorCheck( buffer == null, + "Sound buffer null in method 'loadSound'" ) ) + return false; + + bufferMap.put( filenameURL.getFilename(), buffer ); + + AudioFormat audioFormat = buffer.audioFormat; + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else + { + errorMessage( "File neither mono nor stereo in method " + + "'loadSound'" ); + return false; + } + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alGenBuffers error when loading " + + filenameURL.getFilename() ) ) + return false; + +// AL10.alBufferData( intBuffer.get( 0 ), soundFormat, +// ByteBuffer.wrap( buffer.audioData ), +// (int) audioFormat.getSampleRate() ); + AL10.alBufferData( intBuffer.get( 0 ), soundFormat, + (ByteBuffer) BufferUtils.createByteBuffer( + buffer.audioData.length ).put( + buffer.audioData ).flip(), + (int) audioFormat.getSampleRate() ); + + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alBufferData error when loading " + + filenameURL.getFilename() ) ) + + + if( errorCheck( intBuffer == null, + "Sound buffer was not created for " + + filenameURL.getFilename() ) ) + return false; + + ALBufferMap.put( filenameURL.getFilename(), intBuffer ); + + return true; + } + +/** + * Saves the specified sample data, under the specified identifier. This + * identifier can be later used in place of 'filename' parameters to reference + * the sample data. + * @param buffer the sample data and audio format to save. + * @param identifier What to call the sample. + * @return True if there weren't any problems. + */ + @Override + public boolean loadSound( SoundBuffer buffer, String identifier ) + { + // Make sure the buffer map exists: + if( bufferMap == null ) + { + bufferMap = new HashMap(); + importantMessage( "Buffer Map was null in method 'loadSound'" ); + } + // Make sure the OpenAL buffer map exists: + if( ALBufferMap == null ) + { + ALBufferMap = new HashMap(); + importantMessage( "Open AL Buffer Map was null in method" + + "'loadSound'" ); + } + + // make sure they gave us an identifier: + if( errorCheck( identifier == null, + "Identifier not specified in method 'loadSound'" ) ) + return false; + + // check if it is already loaded: + if( bufferMap.get( identifier ) != null ) + return true; + + if( errorCheck( buffer == null, + "Sound buffer null in method 'loadSound'" ) ) + return false; + + bufferMap.put( identifier, buffer ); + + AudioFormat audioFormat = buffer.audioFormat; + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method 'loadSound'" ); + return false; + } + } + else + { + errorMessage( "File neither mono nor stereo in method " + + "'loadSound'" ); + return false; + } + + IntBuffer intBuffer = BufferUtils.createIntBuffer( 1 ); + AL10.alGenBuffers( intBuffer ); + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alGenBuffers error when saving " + + identifier ) ) + return false; + +// AL10.alBufferData( intBuffer.get( 0 ), soundFormat, +// ByteBuffer.wrap( buffer.audioData ), +// (int) audioFormat.getSampleRate() ); + AL10.alBufferData( intBuffer.get( 0 ), soundFormat, + (ByteBuffer) BufferUtils.createByteBuffer( + buffer.audioData.length ).put( + buffer.audioData ).flip(), + (int) audioFormat.getSampleRate() ); + + if( errorCheck( AL10.alGetError() != AL10.AL_NO_ERROR, + "alBufferData error when saving " + + identifier ) ) + + + if( errorCheck( intBuffer == null, + "Sound buffer was not created for " + + identifier ) ) + return false; + + ALBufferMap.put( identifier, intBuffer ); + + return true; + } + +/** + * Removes a pre-loaded sound from memory. This is a good method to use for + * freeing up memory after a large sound file is no longer needed. NOTE: the + * source will remain in memory after this method has been called, for as long + * as the sound is attached to an existing source. + * @param filename Filename/identifier of the sound file to unload. + */ + @Override + public void unloadSound( String filename ) + { + ALBufferMap.remove( filename ); + super.unloadSound( filename ); + } + + /** + * Sets the overall volume to the specified value, affecting all sources. + * @param value New volume, float value ( 0.0f - 1.0f ). + */ + @Override + public void setMasterVolume( float value ) + { + super.setMasterVolume( value ); + + AL10.alListenerf( AL10.AL_GAIN, value ); + checkALError(); + } + +/** + * Creates a new source and places it into the source map. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + @Override + public void newSource( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, float x, + float y, float z, int attModel, float distOrRoll ) + { + IntBuffer myBuffer = null; + if( !toStream ) + { + // Grab the sound buffer for this file: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + + // if not found, try loading it: + if( myBuffer == null ) + { + if( !loadSound( filenameURL ) ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because an error occurred while loading " + + filenameURL.getFilename() ); + return; + } + } + + // try and grab the sound buffer again: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( myBuffer == null ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because a sound buffer was not found for " + + filenameURL.getFilename() ); + return; + } + } + SoundBuffer buffer = null; + + if( !toStream ) + { + // Grab the audio data for this file: + buffer = bufferMap.get( filenameURL.getFilename() ); + // if not found, try loading it: + if( buffer == null ) + { + if( !loadSound( filenameURL ) ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because an error occurred while loading " + + filenameURL.getFilename() ); + return; + } + } + // try and grab the sound buffer again: + buffer = bufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( buffer == null ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because audio data was not found for " + + filenameURL.getFilename() ); + return; + } + } + + sourceMap.put( sourcename, + new SourceLWJGLOpenAL( listenerPositionAL, myBuffer, + priority, toStream, toLoop, + sourcename, filenameURL, buffer, x, + y, z, attModel, distOrRoll, + false ) ); + } + + /** + * Opens a direct line for streaming audio data. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + */ + @Override + public void rawDataStream( AudioFormat audioFormat, boolean priority, + String sourcename, float x, float y, + float z, int attModel, float distOrRoll ) + { + sourceMap.put( sourcename, + new SourceLWJGLOpenAL( listenerPositionAL, audioFormat, + priority, sourcename, x, y, z, + attModel, distOrRoll ) ); + } + +/** + * Creates and immediately plays a new source. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will load the sound in pieces rather than all at once. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of "attmodel". + * @param temporary Whether or not this source should be removed after it finishes playing. + */ + @Override + public void quickPlay( boolean priority, boolean toStream, boolean toLoop, + String sourcename, FilenameURL filenameURL, float x, + float y, float z, int attModel, float distOrRoll, + boolean temporary ) + { + IntBuffer myBuffer = null; + if( !toStream ) + { + // Grab the sound buffer for this file: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + // if not found, try loading it: + if( myBuffer == null ) + loadSound( filenameURL ); + // try and grab the sound buffer again: + myBuffer = ALBufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( myBuffer == null ) + { + errorMessage( "Sound buffer was not created for " + + filenameURL.getFilename() ); + return; + } + } + + SoundBuffer buffer = null; + + if( !toStream ) + { + // Grab the sound buffer for this file: + buffer = bufferMap.get( filenameURL.getFilename() ); + // if not found, try loading it: + if( buffer == null ) + { + if( !loadSound( filenameURL ) ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because an error occurred while loading " + + filenameURL.getFilename() ); + return; + } + } + // try and grab the sound buffer again: + buffer = bufferMap.get( filenameURL.getFilename() ); + // see if it was there this time: + if( buffer == null ) + { + errorMessage( "Source '" + sourcename + "' was not created " + + "because audio data was not found for " + + filenameURL.getFilename() ); + return; + } + } + SourceLWJGLOpenAL s = new SourceLWJGLOpenAL( listenerPositionAL, + myBuffer, priority, + toStream, toLoop, + sourcename, filenameURL, + buffer, x, y, z, + attModel, distOrRoll, + false ); + + sourceMap.put( sourcename, s ); + play( s ); + if( temporary ) + s.setTemporary( true ); +} + +/** + * Creates sources based on the source map provided. + * @param srcMap Sources to copy. + */ + @Override + public void copySources( HashMap srcMap ) + { + if( srcMap == null ) + return; + Set keys = srcMap.keySet(); + Iterator iter = keys.iterator(); + String sourcename; + Source source; + + // Make sure the buffer map exists: + if( bufferMap == null ) + { + bufferMap = new HashMap(); + importantMessage( "Buffer Map was null in method 'copySources'" ); + } + // Make sure the OpenAL buffer map exists: + if( ALBufferMap == null ) + { + ALBufferMap = new HashMap(); + importantMessage( "Open AL Buffer Map was null in method" + + "'copySources'" ); + } + + // remove any existing sources before starting: + sourceMap.clear(); + + SoundBuffer buffer; + // loop through and copy all the sources: + while( iter.hasNext() ) + { + sourcename = iter.next(); + source = srcMap.get( sourcename ); + if( source != null ) + { + buffer = null; + if( !source.toStream ) + { + loadSound( source.filenameURL ); + buffer = bufferMap.get( source.filenameURL.getFilename() ); + } + if( source.toStream || buffer != null ) + sourceMap.put( sourcename, new SourceLWJGLOpenAL( + listenerPositionAL, + ALBufferMap.get( + source.filenameURL.getFilename() ), + source, buffer ) ); + } + } + } + +/** + * Changes the listener's position. + * @param x Destination X coordinate. + * @param y Destination Y coordinate. + * @param z Destination Z coordinate. + */ + @Override + public void setListenerPosition( float x, float y, float z ) + { + super.setListenerPosition( x, y, z ); + + listenerPositionAL.put( 0, x ); + listenerPositionAL.put( 1, y ); + listenerPositionAL.put( 2, z ); + + // Update OpenAL listener position: + AL10.alListener( AL10.AL_POSITION, listenerPositionAL ); + // Check for errors: + checkALError(); + } + +/** + * Changes the listeners orientation to the specified 'angle' radians + * counterclockwise around the y-Axis. + * @param angle Radians. + */ + @Override + public void setListenerAngle( float angle ) + { + super.setListenerAngle( angle ); + + listenerOrientation.put( 0, listener.lookAt.x ); + listenerOrientation.put( 2, listener.lookAt.z ); + + // Update OpenAL listener orientation: + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + // Check for errors: + checkALError(); + } + +/** + * Changes the listeners orientation using the specified coordinates. + * @param lookX X element of the look-at direction. + * @param lookY Y element of the look-at direction. + * @param lookZ Z element of the look-at direction. + * @param upX X element of the up direction. + * @param upY Y element of the up direction. + * @param upZ Z element of the up direction. + */ + @Override + public void setListenerOrientation( float lookX, float lookY, float lookZ, + float upX, float upY, float upZ ) + { + super.setListenerOrientation( lookX, lookY, lookZ, upX, upY, upZ ); + listenerOrientation.put( 0, lookX ); + listenerOrientation.put( 1, lookY ); + listenerOrientation.put( 2, lookZ ); + listenerOrientation.put( 3, upX ); + listenerOrientation.put( 4, upY ); + listenerOrientation.put( 5, upZ ); + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + checkALError(); + } + +/** + * Changes the listeners position and orientation using the specified listener + * data. + * @param l Listener data to use. + */ + @Override + public void setListenerData( ListenerData l ) + { + super.setListenerData( l ); + + listenerPositionAL.put( 0, l.position.x ); + listenerPositionAL.put( 1, l.position.y ); + listenerPositionAL.put( 2, l.position.z ); + AL10.alListener( AL10.AL_POSITION, listenerPositionAL ); + checkALError(); + + listenerOrientation.put( 0, l.lookAt.x ); + listenerOrientation.put( 1, l.lookAt.y ); + listenerOrientation.put( 2, l.lookAt.z ); + listenerOrientation.put( 3, l.up.x ); + listenerOrientation.put( 4, l.up.y ); + listenerOrientation.put( 5, l.up.z ); + AL10.alListener( AL10.AL_ORIENTATION, listenerOrientation ); + checkALError(); + + listenerVelocity.put( 0, l.velocity.x ); + listenerVelocity.put( 1, l.velocity.y ); + listenerVelocity.put( 2, l.velocity.z ); + AL10.alListener( AL10.AL_VELOCITY, listenerVelocity ); + checkALError(); + } + +/** + * Sets the listener's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + @Override + public void setListenerVelocity( float x, float y, float z ) + { + super.setListenerVelocity( x, y, z ); + + listenerVelocity.put( 0, listener.velocity.x ); + listenerVelocity.put( 1, listener.velocity.y ); + listenerVelocity.put( 2, listener.velocity.z ); + AL10.alListener( AL10.AL_VELOCITY, listenerVelocity ); + } + +/** + * The Doppler parameters have changed. + */ + @Override + public void dopplerChanged() + { + super.dopplerChanged(); + + AL10.alDopplerFactor( SoundSystemConfig.getDopplerFactor() ); + checkALError(); + AL10.alDopplerVelocity( SoundSystemConfig.getDopplerVelocity() ); + checkALError(); + } + +/** + * Checks for OpenAL errors, and prints a message if there is an error. + * @return True if there was an error, False if not. + */ + private boolean checkALError() + { + switch( AL10.alGetError() ) + { + case AL10.AL_NO_ERROR: + return false; + case AL10.AL_INVALID_NAME: + errorMessage( "Invalid name parameter." ); + return true; + case AL10.AL_INVALID_ENUM: + errorMessage( "Invalid parameter." ); + return true; + case AL10.AL_INVALID_VALUE: + errorMessage( "Invalid enumerated parameter value." ); + return true; + case AL10.AL_INVALID_OPERATION: + errorMessage( "Illegal call." ); + return true; + case AL10.AL_OUT_OF_MEMORY: + errorMessage( "Unable to allocate memory." ); + return true; + default: + errorMessage( "An unrecognized error occurred." ); + return true; + } + } + +/** + * Whether or not the AL_PITCH control is supported. + * @return True if AL_PITCH is supported. + */ + public static boolean alPitchSupported() + { + return alPitchSupported( GET, XXX ); + } +/** + * Sets or returns the value of boolean 'alPitchSupported'. + * @param action Action to perform (GET or SET). + * @param value New value if action is SET, otherwise XXX. + * @return value of boolean 'alPitchSupported'. + */ + private static synchronized boolean alPitchSupported( boolean action, + boolean value ) + { + if( action == SET ) + alPitchSupported = value; + return alPitchSupported; + } + +/** + * Returns the short title of this library type. + * @return A short title. + */ + public static String getTitle() + { + return "LWJGL OpenAL"; + } + +/** + * Returns a longer description of this library type. + * @return A longer description. + */ + public static String getDescription() + { + return "The LWJGL binding of OpenAL. For more information, see " + + "http://www.lwjgl.org"; + } + +/** + * Returns the name of the class. + * @return "Library" + library title. + */ + @Override + public String getClassName() + { + return "LibraryLWJGLOpenAL"; + } + +/** + * The LibraryLWJGLOpenAL.Exception class provides library-specific error + * information. + */ + public static class Exception extends SoundSystemException + { + private static final long serialVersionUID = -7502452059037798035L; + /** + * Global identifier for an exception during AL.create(). Probably + * means that OpenAL is not supported. + */ + public static final int CREATE = 101; + /** + * Global identifier for an invalid name parameter in OpenAL. + */ + public static final int INVALID_NAME = 102; + /** + * Global identifier for an invalid parameter in OpenAL. + */ + public static final int INVALID_ENUM = 103; + /** + * Global identifier for an invalid enumerated parameter value in OpenAL. + */ + public static final int INVALID_VALUE = 104; + /** + * Global identifier for an illegal call in OpenAL. + */ + public static final int INVALID_OPERATION = 105; + /** + * Global identifier for OpenAL out of memory. + */ + public static final int OUT_OF_MEMORY = 106; + /** + * Global identifier for an exception while creating the OpenAL Listener. + */ + public static final int LISTENER = 107; + /** + * Global identifier for OpenAL AL_PITCH not supported. + */ + public static final int NO_AL_PITCH = 108; + + /** + * Constructor: Generates a standard "unknown error" exception with the + * specified message. + * @param message A brief description of the problem that occurred. + */ + public Exception( String message ) + { + super( message ); + } + + /** + * Constructor: Generates an exception of the specified type, with the + * specified message. + * @param message A brief description of the problem that occurred. + * @param type Identifier indicating they type of error. + */ + public Exception( String message, int type ) + { + super( message, type ); + } + } +} diff --git a/src/lwjgl/java/paulscode/sound/libraries/SourceLWJGLOpenAL.java b/src/lwjgl/java/paulscode/sound/libraries/SourceLWJGLOpenAL.java new file mode 100644 index 0000000..f22d74a --- /dev/null +++ b/src/lwjgl/java/paulscode/sound/libraries/SourceLWJGLOpenAL.java @@ -0,0 +1,801 @@ +package paulscode.sound.libraries; + +import java.nio.IntBuffer; +import java.nio.FloatBuffer; +import java.util.LinkedList; +import javax.sound.sampled.AudioFormat; + +// From the lwjgl library, http://www.lwjgl.org +import org.lwjgl.BufferUtils; +import org.lwjgl.openal.AL10; + +import paulscode.sound.Channel; +import paulscode.sound.FilenameURL; +import paulscode.sound.Source; +import paulscode.sound.SoundBuffer; +import paulscode.sound.SoundSystemConfig; + +/** + * The SourceLWJGLOpenAL class provides an interface to the lwjgl binding of OpenAL. + *

+ * This software is based on or using the LWJGL Lightweight Java Gaming + * Library available from + * http://www.lwjgl.org/. + *


+ * LWJGL License: + *
+ * Copyright (c) 2002-2008 Lightweight Java Game Library Project + * All rights reserved. + *
+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + *
+ * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + *
+ * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + *
+ * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *


+ * SoundSystem LibraryLWJGLOpenAL License:

+ * + * You are free to use this library for any purpose, commercial or otherwise. + * You may modify this library or source code, and distribute it any way you + * like, provided the following conditions are met: + *
+ * 1) You must abide by the conditions of the aforementioned LWJGL License. + *
+ * 2) You may not falsely claim to be the author of this library or any + * unmodified portion of it. + *
+ * 3) You may not copyright this library or a modified version of it and then + * sue me for copyright infringement. + *
+ * 4) If you modify the source code, you must clearly document the changes + * made before redistributing the modified source code, so other users know + * it is not the original code. + *
+ * 5) You are not required to give me credit for this library in any derived + * work, but if you do, you must also mention my website: + * http://www.paulscode.com + *
+ * 6) I the author will not be responsible for any damages (physical, + * financial, or otherwise) caused by the use if this library or any part + * of it. + *
+ * 7) I the author do not guarantee, warrant, or make any representations, + * either expressed or implied, regarding the use of this library or any + * part of it. + *

+ * Author: Paul Lamb + *
+ * http://www.paulscode.com + *
+ */ +public class SourceLWJGLOpenAL extends Source +{ +/** + * The source's basic Channel type-cast to a ChannelLWJGLOpenAL. + */ + private ChannelLWJGLOpenAL channelOpenAL = (ChannelLWJGLOpenAL) channel; + +/** + * OpenAL IntBuffer sound-buffer identifier for this source if it is a normal + * source. + */ + private IntBuffer myBuffer; + +/** + * FloatBuffer containing the listener's 3D coordinates. + */ + private FloatBuffer listenerPosition; + +/** + * FloatBuffer containing the source's 3D coordinates. + */ + private FloatBuffer sourcePosition; + +/** + * FloatBuffer containing the source's velocity vector. + */ + private FloatBuffer sourceVelocity; + +/** + * Constructor: Creates a new source using the specified parameters. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param myBuffer OpenAL IntBuffer sound-buffer identifier to use for a new normal source. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public SourceLWJGLOpenAL( FloatBuffer listenerPosition, IntBuffer myBuffer, + boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, SoundBuffer soundBuffer, + float x, float y, float z, int attModel, + float distOrRoll, boolean temporary ) + { + super( priority, toStream, toLoop, sourcename, filenameURL, soundBuffer, + x, y, z, attModel, distOrRoll, temporary ); + if( codec != null ) + codec.reverseByteOrder( true ); + this.listenerPosition = listenerPosition; + this.myBuffer = myBuffer; + libraryType = LibraryLWJGLOpenAL.class; + pitch = 1.0f; + resetALInformation(); + } + +/** + * Constructor: Creates a new source matching the specified source. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param myBuffer OpenAL IntBuffer sound-buffer identifier to use for a new normal source. + * @param old Source to copy information from. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + */ + public SourceLWJGLOpenAL( FloatBuffer listenerPosition, IntBuffer myBuffer, + Source old, SoundBuffer soundBuffer ) + { + super( old, soundBuffer ); + if( codec != null ) + codec.reverseByteOrder( true ); + this.listenerPosition = listenerPosition; + this.myBuffer = myBuffer; + libraryType = LibraryLWJGLOpenAL.class; + pitch = 1.0f; + resetALInformation(); + } + + /** + * Constructor: Creates a new streaming source that will be directly fed with + * raw audio data. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param audioFormat Format that the data will be in. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + */ + public SourceLWJGLOpenAL( FloatBuffer listenerPosition, + AudioFormat audioFormat, boolean priority, + String sourcename, float x, float y, float z, + int attModel, float distOrRoll ) + { + super( audioFormat, priority, sourcename, x, y, z, attModel, + distOrRoll ); + this.listenerPosition = listenerPosition; + libraryType = LibraryLWJGLOpenAL.class; + pitch = 1.0f; + resetALInformation(); + } + +/** + * Shuts the source down and removes references to all instantiated objects. + */ + @Override + public void cleanup() + { + + super.cleanup(); + } + +/** + * Changes the peripheral information about the source using the specified + * parameters. + * @param listenerPosition FloatBuffer containing the listener's 3D coordinates. + * @param myBuffer OpenAL IntBuffer sound-buffer identifier to use for a new normal source. + * @param priority Setting this to true will prevent other sounds from overriding this one. + * @param toStream Setting this to true will create a streaming source. + * @param toLoop Should this source loop, or play only once. + * @param sourcename A unique identifier for this source. Two sources may not use the same sourcename. + * @param filenameURL Filename/URL of the sound file to play at this source. + * @param soundBuffer Buffer containing audio data, or null if not loaded yet. + * @param x X position for this source. + * @param y Y position for this source. + * @param z Z position for this source. + * @param attModel Attenuation model to use. + * @param distOrRoll Either the fading distance or rolloff factor, depending on the value of 'att'. + * @param temporary Whether or not to remove this source after it finishes playing. + */ + public void changeSource( FloatBuffer listenerPosition, IntBuffer myBuffer, + boolean priority, boolean toStream, + boolean toLoop, String sourcename, + FilenameURL filenameURL, SoundBuffer soundBuffer, + float x, float y, float z, int attModel, + float distOrRoll, boolean temporary ) + { + super.changeSource( priority, toStream, toLoop, sourcename, + filenameURL, soundBuffer, x, y, z, attModel, + distOrRoll, temporary ); + this.listenerPosition = listenerPosition; + this.myBuffer = myBuffer; + pitch = 1.0f; + resetALInformation(); + } + +/** + * Removes the next filename from the sound sequence queue and assigns it to + * this source. This method has no effect on non-streaming sources. This + * method is used internally by SoundSystem, and it is unlikely that the user + * will ever need to use it. + * @return True if there was something in the queue. + */ + @Override + public boolean incrementSoundSequence() + { + if( !toStream ) + { + errorMessage( "Method 'incrementSoundSequence' may only be used " + + "for streaming sources." ); + return false; + } + synchronized( soundSequenceLock ) + { + if( soundSequenceQueue != null && soundSequenceQueue.size() > 0 ) + { + filenameURL = soundSequenceQueue.remove( 0 ); + if( codec != null ) + codec.cleanup(); + codec = SoundSystemConfig.getCodec( filenameURL.getFilename() ); + if( codec != null ) + { + codec.reverseByteOrder( true ); + if( codec.getAudioFormat() == null ) + codec.initialize( filenameURL.getURL() ); + + AudioFormat audioFormat = codec.getAudioFormat(); + + if( audioFormat == null ) + { + errorMessage( "Audio Format null in method " + + "'incrementSoundSequence'" ); + return false; + } + + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'incrementSoundSequence'" ); + return false; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method " + + "'incrementSoundSequence'" ); + return false; + } + } + else + { + errorMessage( "Audio data neither mono nor stereo in " + + "method 'incrementSoundSequence'" ); + return false; + } + + // Let the channel know what format and sample rate to use: + channelOpenAL.setFormat( soundFormat, + (int) audioFormat.getSampleRate() ); + preLoad = true; + } + return true; + } + } + return false; + } + +/** + * Called every time the listener's position or orientation changes. + */ + @Override + public void listenerMoved() + { + positionChanged(); + } + +/** + * Moves the source to the specified position. + * @param x X coordinate to move to. + * @param y Y coordinate to move to. + * @param z Z coordinate to move to. + */ + @Override + public void setPosition( float x, float y, float z ) + { + super.setPosition( x, y, z ); + + // Make sure OpenAL information has been created + if( sourcePosition == null ) + resetALInformation(); + else + positionChanged(); + + // put the new position information into the buffer: + sourcePosition.put( 0, x ); + sourcePosition.put( 1, y ); + sourcePosition.put( 2, z ); + + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + // move the source: + AL10.alSource( channelOpenAL.ALSource.get( 0 ), AL10.AL_POSITION, + sourcePosition ); + checkALError(); + } + } + +/** + * Recalculates the distance from the listner and the gain. + */ + @Override + public void positionChanged() + { + calculateDistance(); + calculateGain(); + + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_GAIN, (gain * sourceVolume + * (float) Math.abs( fadeOutGain ) + * fadeInGain) ); + checkALError(); + } + checkPitch(); + } + +/** + * Checks the source's pitch. + */ + private void checkPitch() + { + if( channel != null && channel.attachedSource == this && + LibraryLWJGLOpenAL.alPitchSupported() && channelOpenAL != null && + channelOpenAL.ALSource != null ) + { + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_PITCH, pitch ); + checkALError(); + } + } + +/** + * Sets whether this source should loop or only play once. + * @param lp True or false. + */ + @Override + public void setLooping( boolean lp ) + { + super.setLooping( lp ); + + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + if( lp ) + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_TRUE ); + else + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_FALSE ); + checkALError(); + } + } + +/** + * Sets this source's attenuation model. + * @param model Attenuation model to use. + */ + @Override + public void setAttenuation( int model ) + { + super.setAttenuation( model ); + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + // attenuation changed, so update the rolloff factor accordingly + if( model == SoundSystemConfig.ATTENUATION_ROLLOFF ) + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, distOrRoll ); + else + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, 0.0f ); + checkALError(); + } + } + +/** + * Sets this source's fade distance or rolloff factor, depending on the + * attenuation model. + * @param dr New value for fade distance or rolloff factor. + */ + @Override + public void setDistOrRoll( float dr) + { + super.setDistOrRoll( dr ); + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + // if we are using rolloff attenuation, then dr is a rolloff factor: + if( attModel == SoundSystemConfig.ATTENUATION_ROLLOFF ) + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, dr ); + else + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, 0.0f ); + checkALError(); + } + } + +/** + * Sets this source's velocity, for use in Doppler effect. + * @param x Velocity along world x-axis. + * @param y Velocity along world y-axis. + * @param z Velocity along world z-axis. + */ + @Override + public void setVelocity( float x, float y, float z ) + { + super.setVelocity( x, y, z ); + + sourceVelocity = BufferUtils.createFloatBuffer( 3 ).put( new float[] + { x, y, z } ); + sourceVelocity.flip(); + // make sure we are assigned to a channel: + if( channel != null && channel.attachedSource == this && + channelOpenAL != null && channelOpenAL.ALSource != null ) + { + AL10.alSource( channelOpenAL.ALSource.get( 0 ), + AL10.AL_VELOCITY, sourceVelocity ); + checkALError(); + } + } + +/** + * Manually sets this source's pitch. + * @param value A float value ( 0.5f - 2.0f ). + */ + @Override + public void setPitch( float value ) + { + super.setPitch( value ); + checkPitch(); + } + +/** + * Plays the source on the specified channel. + * @param c Channel to play on. + */ + @Override + public void play( Channel c ) + { + if( !active() ) + { + if( toLoop ) + toPlay = true; + return; + } + + if( c == null ) + { + errorMessage( "Unable to play source, because channel was null" ); + return; + } + + boolean newChannel = (channel != c); + if( channel != null && channel.attachedSource != this ) + newChannel = true; + + boolean wasPaused = paused(); + + super.play( c ); + + channelOpenAL = (ChannelLWJGLOpenAL) channel; + + // Make sure the channel exists: + // check if we are already on this channel: + if( newChannel ) + { + setPosition( position.x, position.y, position.z ); + checkPitch(); + + // Send the source's attributes to the channel: + if( channelOpenAL != null && channelOpenAL.ALSource != null ) + { + if( LibraryLWJGLOpenAL.alPitchSupported() ) + { + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_PITCH, pitch ); + checkALError(); + } + AL10.alSource( channelOpenAL.ALSource.get( 0 ), + AL10.AL_POSITION, sourcePosition ); + checkALError(); + + AL10.alSource( channelOpenAL.ALSource.get( 0 ), + AL10.AL_VELOCITY, sourceVelocity ); + + checkALError(); + + if( attModel == SoundSystemConfig.ATTENUATION_ROLLOFF ) + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, distOrRoll ); + else + AL10.alSourcef( channelOpenAL.ALSource.get( 0 ), + AL10.AL_ROLLOFF_FACTOR, 0.0f ); + checkALError(); + + if( toLoop && (!toStream) ) + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_TRUE ); + else + AL10.alSourcei( channelOpenAL.ALSource.get( 0 ), + AL10.AL_LOOPING, AL10.AL_FALSE ); + checkALError(); + } + if( !toStream ) + { + // This is not a streaming source, so make sure there is + // a sound buffer loaded to play: + if( myBuffer == null ) + { + errorMessage( "No sound buffer to play" ); + return; + } + + channelOpenAL.attachBuffer( myBuffer ); + } + } + + // See if we are already playing: + if( !playing() ) + { + if( toStream && !wasPaused ) + { + if( codec == null ) + { + errorMessage( "Decoder null in method 'play'" ); + return; + } + if( codec.getAudioFormat() == null ) + codec.initialize( filenameURL.getURL() ); + + AudioFormat audioFormat = codec.getAudioFormat(); + + if( audioFormat == null ) + { + errorMessage( "Audio Format null in method 'play'" ); + return; + } + + int soundFormat = 0; + if( audioFormat.getChannels() == 1 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_MONO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_MONO16; + } + else + { + errorMessage( "Illegal sample size in method 'play'" ); + return; + } + } + else if( audioFormat.getChannels() == 2 ) + { + if( audioFormat.getSampleSizeInBits() == 8 ) + { + soundFormat = AL10.AL_FORMAT_STEREO8; + } + else if( audioFormat.getSampleSizeInBits() == 16 ) + { + soundFormat = AL10.AL_FORMAT_STEREO16; + } + else + { + errorMessage( "Illegal sample size in method 'play'" ); + return; + } + } + else + { + errorMessage( "Audio data neither mono nor stereo in " + + "method 'play'" ); + return; + } + + // Let the channel know what format and sample rate to use: + channelOpenAL.setFormat( soundFormat, + (int) audioFormat.getSampleRate() ); + preLoad = true; + } + channel.play(); + if( pitch != 1.0f ) + checkPitch(); + } + } + +/** + * Queues up the initial stream-buffers for the stream. + * @return False if the end of the stream was reached. + */ + @Override + public boolean preLoad() + { + if( codec == null ) + return false; + + codec.initialize( filenameURL.getURL() ); + LinkedList preLoadBuffers = new LinkedList(); + for( int i = 0; i < SoundSystemConfig.getNumberStreamingBuffers(); i++ ) + { + soundBuffer = codec.read(); + + if( soundBuffer == null || soundBuffer.audioData == null ) + break; + + preLoadBuffers.add( soundBuffer.audioData ); + } + positionChanged(); + + channel.preLoadBuffers( preLoadBuffers ); + + preLoad = false; + return true; + } + +/** + * Resets all the information OpenAL uses to play this source. + */ + private void resetALInformation() + { + // Create buffers for the source's position and velocity + sourcePosition = BufferUtils.createFloatBuffer( 3 ).put( + new float[] { position.x, position.y, position.z } ); + sourceVelocity = BufferUtils.createFloatBuffer( 3 ).put( + new float[] { velocity.x, velocity.y, velocity.z } ); + + // flip the buffers, so they can be used: + sourcePosition.flip(); + sourceVelocity.flip(); + + positionChanged(); + } + +/** + * Calculates this source's distance from the listener. + */ + private void calculateDistance() + { + if( listenerPosition != null ) + { + // Calculate the source's distance from the listener: + double dX = position.x - listenerPosition.get( 0 ); + double dY = position.y - listenerPosition.get( 1 ); + double dZ = position.z - listenerPosition.get( 2 ); + distanceFromListener = (float) Math.sqrt( dX*dX + dY*dY + dZ*dZ ); + } + } + +/** + * If using linear attenuation, calculates the gain for this source based on + * its distance from the listener. + */ + private void calculateGain() + { + // If using linear attenuation, calculate the source's gain: + if( attModel == SoundSystemConfig.ATTENUATION_LINEAR ) + { + if( distanceFromListener <= 0 ) + { + gain = 1.0f; + } + else if( distanceFromListener >= distOrRoll ) + { + gain = 0.0f; + } + else + { + gain = 1.0f - (distanceFromListener / distOrRoll); + } + if( gain > 1.0f ) + gain = 1.0f; + if( gain < 0.0f ) + gain = 0.0f; + } + else + { + gain = 1.0f; + } + } + +/** + * Checks for OpenAL errors, and prints a message if there is an error. + * @return True if there was an error, False if not. + */ + private boolean checkALError() + { + switch( AL10.alGetError() ) + { + case AL10.AL_NO_ERROR: + return false; + case AL10.AL_INVALID_NAME: + errorMessage( "Invalid name parameter." ); + return true; + case AL10.AL_INVALID_ENUM: + errorMessage( "Invalid parameter." ); + return true; + case AL10.AL_INVALID_VALUE: + errorMessage( "Invalid enumerated parameter value." ); + return true; + case AL10.AL_INVALID_OPERATION: + errorMessage( "Illegal call." ); + return true; + case AL10.AL_OUT_OF_MEMORY: + errorMessage( "Unable to allocate memory." ); + return true; + default: + errorMessage( "An unrecognized error occurred." ); + return true; + } + } +} diff --git a/src/lwjgl/java/tritonus/TAsynchronousFilteredAudioInputStream.java b/src/lwjgl/java/tritonus/TAsynchronousFilteredAudioInputStream.java new file mode 100644 index 0000000..1719269 --- /dev/null +++ b/src/lwjgl/java/tritonus/TAsynchronousFilteredAudioInputStream.java @@ -0,0 +1,200 @@ +/* + * TAsynchronousFilteredAudioInputStream.java + * + * This file is part of Tritonus: http://www.tritonus.org/ + */ + +/* + * Copyright (c) 1999, 2000 by Matthias Pfisterer + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +package tritonus; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.sound.sampled.AudioFormat; + +/** + * Base class for asynchronous converters. This class serves as base class for + * converters that do not have a fixed ratio between the size of a block of + * input data and the size of a block of output data. These types of converters + * therefore need an internal buffer, which is realized in this class. + * + * @author Matthias Pfisterer + */ +public abstract class TAsynchronousFilteredAudioInputStream extends TAudioInputStream implements + TCircularBuffer.Trigger +{ + private static final int DEFAULT_BUFFER_SIZE = 327670; + private static final int DEFAULT_MIN_AVAILABLE = 4096; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + private TCircularBuffer m_circularBuffer; + private int m_nMinAvailable; + private byte[] m_abSingleByte; + + /** + * Constructor. This constructor uses the default buffer size and the + * default min available amount. + * + * @param lLength + * length of this stream in frames. May be + * AudioSystem.NOT_SPECIFIED. + */ + public TAsynchronousFilteredAudioInputStream(AudioFormat outputFormat, long lLength) + { + this(outputFormat, lLength, DEFAULT_BUFFER_SIZE, DEFAULT_MIN_AVAILABLE); + } + + /** + * Constructor. With this constructor, the buffer size and the minimum + * available amount can be specified as parameters. + * + * @param lLength + * length of this stream in frames. May be + * AudioSystem.NOT_SPECIFIED. + * @param nBufferSize + * size of the circular buffer in bytes. + */ + public TAsynchronousFilteredAudioInputStream(AudioFormat outputFormat, long lLength, + int nBufferSize, int nMinAvailable) + { + /* + * The usage of a ByteArrayInputStream is a hack. (the infamous + * "JavaOne hack", because I did it on June 6th 2000 in San Francisco, + * only hours before a JavaOne session where I wanted to show mp3 + * playback with Java Sound.) It is necessary because in the FCS version + * of the Sun jdk1.3, the constructor of AudioInputStream throws an + * exception if its first argument is null. So we have to pass a dummy + * non-null value. + */ + super(new ByteArrayInputStream(EMPTY_BYTE_ARRAY), outputFormat, lLength); + + m_circularBuffer = new TCircularBuffer(nBufferSize, false, // blocking + // read + true, // blocking write + this); // trigger + m_nMinAvailable = nMinAvailable; + + } + + /** + * Returns the circular buffer. + */ + protected TCircularBuffer getCircularBuffer() + { + return m_circularBuffer; + } + + /** + * Check if writing more data to the circular buffer is recommended. This + * checks the available write space in the circular buffer against the + * minimum available property. If the available write space is greater than + * the minimum available property, more writing is encouraged, so this method + * returns true. Note that this is only a hint to subclasses. However, it is + * an important hint. + * + * @return true if more writing to the circular buffer is recommended. + * Otherwise, false is returned. + */ + protected boolean writeMore() + { + return getCircularBuffer().availableWrite() > m_nMinAvailable; + } + + public int read() throws IOException + { + // if (TDebug.TraceAudioConverter) { + // TDebug.out("TAsynchronousFilteredAudioInputStream.read(): begin"); } + int nByte = -1; + if(m_abSingleByte == null) + { + m_abSingleByte = new byte[1]; + } + int nReturn = read(m_abSingleByte); + if(nReturn == -1) + { + nByte = -1; + } else + { + // $$fb 2001-04-14 nobody really knows that... + nByte = m_abSingleByte[0] & 0xFF; + } + // if (TDebug.TraceAudioConverter) { + // TDebug.out("TAsynchronousFilteredAudioInputStream.read(): end"); } + return nByte; + } + + public int read(byte[] abData) throws IOException + { + + int nRead = read(abData, 0, abData.length); + + return nRead; + } + + public int read(byte[] abData, int nOffset, int nLength) throws IOException + { + + int nRead = m_circularBuffer.read(abData, nOffset, nLength); + + return nRead; + } + + public long skip(long lSkip) throws IOException + { + // TODO: this is quite inefficient + for(long lSkipped = 0; lSkipped < lSkip; lSkipped++) + { + int nReturn = read(); + if(nReturn == -1) + { + return lSkipped; + } + } + return lSkip; + } + + public int available() throws IOException + { + return m_circularBuffer.availableRead(); + } + + public void close() throws IOException + { + m_circularBuffer.close(); + } + + public boolean markSupported() + { + return false; + } + + public void mark(int nReadLimit) + { + } + + public void reset() throws IOException + { + throw new IOException("mark not supported"); + } +} + +/*** TAsynchronousFilteredAudioInputStream.java ***/ diff --git a/src/lwjgl/java/tritonus/TAudioInputStream.java b/src/lwjgl/java/tritonus/TAudioInputStream.java new file mode 100644 index 0000000..50a3246 --- /dev/null +++ b/src/lwjgl/java/tritonus/TAudioInputStream.java @@ -0,0 +1,106 @@ +/* + * TAudioInputStream.java + * + * This file is part of Tritonus: http://www.tritonus.org/ + */ + +/* + * Copyright (c) 2003 by Matthias Pfisterer + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package tritonus; + +import java.io.InputStream; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; + +/** + * AudioInputStream base class. This class implements "dynamic" properties. + * "Dynamic" properties are properties that may change during the life time of + * the objects. This is typically used to pass information like the current + * frame number, volume of subbands and similar values. "Dynamic" properties are + * different from properties in AudioFormat and AudioFileFormat, which are + * considered "static", as they aren't allowed to change after creating of the + * object, thereby maintaining the immutable character of these classes. + */ + +public class TAudioInputStream extends AudioInputStream +{ + private Map m_properties; + private Map m_unmodifiableProperties; + + /** + * Constructor without properties. Creates an empty properties map. + */ + public TAudioInputStream(InputStream inputStream, AudioFormat audioFormat, long lLengthInFrames) + { + super(inputStream, audioFormat, lLengthInFrames); + initMaps(new HashMap()); + } + + /** + * Constructor with properties. The passed properties map is not copied. + * This allows subclasses to change values in the map after creation, and + * the changes are reflected in the map the application program can obtain. + */ + public TAudioInputStream(InputStream inputStream, AudioFormat audioFormat, + long lLengthInFrames, Map properties) + { + super(inputStream, audioFormat, lLengthInFrames); + initMaps(properties); + } + + private void initMaps(Map properties) + { + /* + * Here, we make a shallow copy of the map. It's unclear if this is + * sufficient (of if a deep copy should be made). + */ + m_properties = properties; + m_unmodifiableProperties = Collections.unmodifiableMap(m_properties); + } + + /** + * Obtain a Map containing the properties. This method returns a Map that + * cannot be modified by the application program, but reflects changes to + * the map made by the implementation. + * + * @return a map containing the properties. + */ + public Map properties() + { + return m_unmodifiableProperties; + } + + /** + * Set a property. Unlike in AudioFormat and AudioFileFormat, this method + * may be used anywhere by subclasses - it is not restricted to be used in + * the constructor. + */ + protected void setProperty(String key, Object value) + { + m_properties.put(key, value); + } +} + +/*** TAudioInputStream.java ***/ diff --git a/src/lwjgl/java/tritonus/TCircularBuffer.java b/src/lwjgl/java/tritonus/TCircularBuffer.java new file mode 100644 index 0000000..de04edf --- /dev/null +++ b/src/lwjgl/java/tritonus/TCircularBuffer.java @@ -0,0 +1,201 @@ +/* + * TCircularBuffer.java + * + * This file is part of Tritonus: http://www.tritonus.org/ + */ + +/* + * Copyright (c) 1999 by Matthias Pfisterer + * Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +package tritonus; + +public class TCircularBuffer +{ + private boolean m_bBlockingRead; + private boolean m_bBlockingWrite; + private byte[] m_abData; + private int m_nSize; + private long m_lReadPos; + private long m_lWritePos; + private Trigger m_trigger; + private boolean m_bOpen; + + public TCircularBuffer(int nSize, boolean bBlockingRead, boolean bBlockingWrite, Trigger trigger) + { + m_bBlockingRead = bBlockingRead; + m_bBlockingWrite = bBlockingWrite; + m_nSize = nSize; + m_abData = new byte[m_nSize]; + m_lReadPos = 0; + m_lWritePos = 0; + m_trigger = trigger; + m_bOpen = true; + } + + public void close() + { + m_bOpen = false; + // TODO: call notify() ? + } + + private boolean isOpen() + { + return m_bOpen; + } + + public int availableRead() + { + return (int) (m_lWritePos - m_lReadPos); + } + + public int availableWrite() + { + return m_nSize - availableRead(); + } + + private int getReadPos() + { + return (int) (m_lReadPos % m_nSize); + } + + private int getWritePos() + { + return (int) (m_lWritePos % m_nSize); + } + + public int read(byte[] abData) + { + return read(abData, 0, abData.length); + } + + public int read(byte[] abData, int nOffset, int nLength) + { + + if(!isOpen()) + { + if(availableRead() > 0) + { + nLength = Math.min(nLength, availableRead()); + + } else + { + + return -1; + } + } + synchronized(this) + { + if(m_trigger != null && availableRead() < nLength) + { + + m_trigger.execute(); + } + if(!m_bBlockingRead) + { + nLength = Math.min(availableRead(), nLength); + } + int nRemainingBytes = nLength; + while(nRemainingBytes > 0) + { + while(availableRead() == 0) + { + try + { + wait(); + } catch (InterruptedException e) + { + + } + } + int nAvailable = Math.min(availableRead(), nRemainingBytes); + while(nAvailable > 0) + { + int nToRead = Math.min(nAvailable, m_nSize - getReadPos()); + System.arraycopy(m_abData, getReadPos(), abData, nOffset, nToRead); + m_lReadPos += nToRead; + nOffset += nToRead; + nAvailable -= nToRead; + nRemainingBytes -= nToRead; + } + notifyAll(); + } + + return nLength; + } + } + + public int write(byte[] abData) + { + return write(abData, 0, abData.length); + } + + public int write(byte[] abData, int nOffset, int nLength) + { + + synchronized(this) + { + + if(!m_bBlockingWrite) + { + nLength = Math.min(availableWrite(), nLength); + } + int nRemainingBytes = nLength; + while(nRemainingBytes > 0) + { + while(availableWrite() == 0) + { + try + { + wait(); + } catch (InterruptedException e) + { + + } + } + int nAvailable = Math.min(availableWrite(), nRemainingBytes); + while(nAvailable > 0) + { + int nToWrite = Math.min(nAvailable, m_nSize - getWritePos()); + // TDebug.out("src buf size= " + abData.length + + // ", offset = " + nOffset + ", dst buf size=" + + // m_abData.length + " write pos=" + getWritePos() + " len=" + // + nToWrite); + System.arraycopy(abData, nOffset, m_abData, getWritePos(), nToWrite); + m_lWritePos += nToWrite; + nOffset += nToWrite; + nAvailable -= nToWrite; + nRemainingBytes -= nToWrite; + } + notifyAll(); + } + + return nLength; + } + } + + public static interface Trigger + { + public void execute(); + } + +} + +/*** TCircularBuffer.java ***/ + diff --git a/src/main/java/com/baislsl/png/chunk/Chunk.java b/src/main/java/com/baislsl/png/chunk/Chunk.java new file mode 100644 index 0000000..1a50dd0 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/Chunk.java @@ -0,0 +1,62 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.util.ByteHandler; + +/** + * Created by baislsl on 17-7-9. + */ +public class Chunk { + protected long length; + protected ChunkType type; + protected byte[] data; + protected byte[] crc = new byte[4]; + + public byte[] dump() { + byte[] output = new byte[4 + 4 + data.length + 4]; + Byte[] lengthBytes = new Byte[4]; + for (int i = 0; i < 4; i++) { + output[3 - i] = (byte) (length & 0xff); + } + String typeName = type.name().toUpperCase(); + for (int i = 0; i < 4; i++) { + output[4 + i] = (byte) typeName.charAt(i); + } + System.arraycopy(data, 0, output, 8, data.length); + System.arraycopy(crc, 0, output, output.length - crc.length, crc.length); + return output; + } + + protected Chunk(byte[] length, byte[] type, byte[] data, byte[] crc) { + this.length = ByteHandler.byteToLong(length); + this.data = data; + this.crc = crc; + + for (ChunkType chunkType : ChunkType.values()) { + if (chunkType.name().equals(ByteHandler.byteToString(type))) { + this.type = chunkType; + break; + } + } + + } + + public long dataLength() { + return data.length; + } + + public long getLength() { + return length; + } + + public ChunkType getType() { + return type; + } + + public byte[] getData() { + return data; + } + + public byte[] getCrc() { + return crc; + } +} diff --git a/src/main/java/com/baislsl/png/chunk/ChunkType.java b/src/main/java/com/baislsl/png/chunk/ChunkType.java new file mode 100644 index 0000000..91a3181 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/ChunkType.java @@ -0,0 +1,44 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; +import com.baislsl.png.decode.PNG; + +/** + * Created by baislsl on 17-7-9. + */ +public enum ChunkType { + + IHDR { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setIhdr(new IHDR(length, type, data, crc)); + } + }, + tRNS { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setTrns(new tRNS(length, type, data, crc)); + } + }, + PLTE { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setPlte(new PLTE(length, type, data, crc)); + } + }, + IDAT { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.add(new IDAT(length, type, data, crc)); + } + }, + IEND { + @Override + public void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + png.setIend(new IEND(length, type, data, crc)); + } + }; + + public abstract void apply(PNG png, byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException; + +} diff --git a/src/main/java/com/baislsl/png/chunk/IDAT.java b/src/main/java/com/baislsl/png/chunk/IDAT.java new file mode 100644 index 0000000..f8d93d5 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/IDAT.java @@ -0,0 +1,11 @@ +package com.baislsl.png.chunk; + +/** + * Created by baislsl on 17-7-10. + */ +public class IDAT extends Chunk { + + public IDAT(byte[] length, byte[] type, byte[] data, byte[] crc) { + super(length, type, data, crc); + } +} diff --git a/src/main/java/com/baislsl/png/chunk/IEND.java b/src/main/java/com/baislsl/png/chunk/IEND.java new file mode 100644 index 0000000..6132e60 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/IEND.java @@ -0,0 +1,10 @@ +package com.baislsl.png.chunk; + +/** + * Created by baislsl on 17-7-9. + */ +public class IEND extends Chunk { + public IEND(byte[] length, byte[] type, byte[] data, byte[] crc) { + super(length, type, data, crc); + } +} diff --git a/src/main/java/com/baislsl/png/chunk/IHDR.java b/src/main/java/com/baislsl/png/chunk/IHDR.java new file mode 100644 index 0000000..1c4e7d5 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/IHDR.java @@ -0,0 +1,119 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; +import com.baislsl.png.util.ByteHandler; + +/** + * Created by baislsl on 17-7-9. + */ +public class IHDR extends Chunk { + private long width, height; + private int bitDepth, colorType, compressionMethod, filterMethod, interlaceMethod; + + final private static int[] colorTypeValid = { 0, 2, 3, 4, 6 }; + final private static int[][] mapColorBitDepth = { { 1, 2, 4, 8, 16 }, // color type = 0 + {}, { 8, 16 }, // color type = 2 + { 1, 2, 4, 8 }, // color type = 3 + { 8, 16 }, // color type = 4 + {}, { 8, 16 } // color type = 6 + }; + + // the number of bytes per complete pixel, rounding up to one + public int getBpp() { + if (colorType == 2) { // Each pixel is an R,G,B triple. + return 3; + } else if (colorType == 6) { // Each pixel is an R,G,B triple, followed by an alpha sample. + return 4; + } else if (colorType == 3) { // palette index, roll up to 1 + return 1; + } else { + // LOG.error("Error when find bpp"); + return 0; + } + } + + public IHDR(byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + super(length, type, data, crc); + build(); + checkLegal(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("width="); + sb.append(width); + sb.append("height="); + sb.append(height); + sb.append("bitDepth="); + sb.append(bitDepth); + sb.append("colorType="); + sb.append(colorType); + sb.append("compressionMethod="); + sb.append(compressionMethod); + sb.append("filterMethod="); + sb.append(filterMethod); + sb.append("interlaceMethod="); + sb.append(interlaceMethod); + return sb.toString(); + } + + private void build() { + this.width = ByteHandler.byteToLong(data); + this.height = ByteHandler.byteToLong(data, 4); + this.bitDepth = ((int) data[8]) & 0xFF; + this.colorType = ((int) data[9]) & 0xFF; + this.compressionMethod = ((int) data[10]) & 0xFF; + this.filterMethod = ((int) data[11]) & 0xFF; + this.interlaceMethod = ((int) data[12]) & 0xFF; + } + + private void checkLegal() throws DecodeException { + boolean legal = false; + for (int c : colorTypeValid) { + if (c == colorType) { + legal = true; + break; + } + } + if (!legal) { + throw new DecodeException("Initialize IHDR : color type not legal to be " + colorType); + } + for (int b : mapColorBitDepth[colorType]) { + if (b == bitDepth) { + return; + } + } + throw new DecodeException( + "Initialzie IHDR : bit depth " + bitDepth + " not valid matching color type " + colorType); + } + + public long getWidth() { + return this.width; + } + + public long getHeight() { + return this.height; + } + + public int getBitDepth() { + return bitDepth; + } + + public int getColorType() { + return colorType; + } + + public int getCompressionMethod() { + return compressionMethod; + } + + public int getFilterMethod() { + return filterMethod; + } + + public int getInterlaceMethod() { + return interlaceMethod; + } + +} diff --git a/src/main/java/com/baislsl/png/chunk/PLTE.java b/src/main/java/com/baislsl/png/chunk/PLTE.java new file mode 100644 index 0000000..cb6a489 --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/PLTE.java @@ -0,0 +1,35 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; + +/** + * Created by baislsl on 17-7-9. + */ +public class PLTE extends Chunk { + private int[] color; + + public PLTE(byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + super(length, type, data, crc); + build(); + } + + private void build() throws DecodeException { + if (this.length % 3 != 0) + throw new DecodeException("PLTE length can not be divide by 3"); + int size = (int) length / 3; + color = new int[size]; + for (int i = 0; i < size; i++) { + color[i] = (((int) data[i * 3]) & 0xFF) << 16 | (((int) data[i * 3 + 1]) & 0xFF) << 8 + | (((int) data[i * 3 + 2]) & 0xFF) | 0xFF000000; + } + } + + public int getColor(int i) { + return color[i]; + } + + public int getPaletteSize() { + return color.length; + } + +} diff --git a/src/main/java/com/baislsl/png/chunk/tRNS.java b/src/main/java/com/baislsl/png/chunk/tRNS.java new file mode 100644 index 0000000..bfca19d --- /dev/null +++ b/src/main/java/com/baislsl/png/chunk/tRNS.java @@ -0,0 +1,18 @@ +package com.baislsl.png.chunk; + +import com.baislsl.png.decode.DecodeException; + +/** + * Created by baislsl on 17-7-9. + */ +public class tRNS extends Chunk { + + public tRNS(byte[] length, byte[] type, byte[] data, byte[] crc) throws DecodeException { + super(length, type, data, crc); + } + + public int getAlpha() { + return (int)data[0] & 0xFF; + } + +} diff --git a/src/main/java/com/baislsl/png/decode/DecodeException.java b/src/main/java/com/baislsl/png/decode/DecodeException.java new file mode 100644 index 0000000..63f287b --- /dev/null +++ b/src/main/java/com/baislsl/png/decode/DecodeException.java @@ -0,0 +1,22 @@ +package com.baislsl.png.decode; + +/** + * Created by baislsl on 17-7-9. + */ +public class DecodeException extends Exception { + + public DecodeException() { + } + + public DecodeException(String message) { + super(message); + } + + public DecodeException(String message, Throwable cause) { + super(message, cause); + } + + public DecodeException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/baislsl/png/decode/Decoder.java b/src/main/java/com/baislsl/png/decode/Decoder.java new file mode 100644 index 0000000..bcb3552 --- /dev/null +++ b/src/main/java/com/baislsl/png/decode/Decoder.java @@ -0,0 +1,96 @@ +package com.baislsl.png.decode; + +import com.baislsl.png.chunk.ChunkType; +import com.baislsl.png.util.CRC; +import com.baislsl.png.util.ByteHandler; + +import java.io.IOException; +import java.io.InputStream; + +import static com.baislsl.png.util.ByteHandler.byteToLong; + +/** + * Created by baislsl on 17-7-9. + */ +public class Decoder { + // private final static Logger LOG = LoggerFactory.getLogger(Decoder.class); + private final InputStream in; + + private final static char[] head = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; + + public Decoder(InputStream in) { + this.in = in; + } + + private void readHeader() throws DecodeException, IOException { + byte[] header = readBytes(8); + for (int i = 0; i < 8; i++) { + if ((header[i] & 0xff) != (int) head[i]) + throw new DecodeException("It seems that this is not a PNG files"); + } + // LOG.info(ByteHandler.byteToString(header)); + } + + private boolean readChunk(PNG png, String chunkName, byte[] length, byte[] type, byte[] data, byte[] crc) + throws IOException, DecodeException { + for (ChunkType chunkType : ChunkType.values()) { + if (chunkType.name().equalsIgnoreCase(chunkName)) { + chunkType.apply(png, length, type, data, crc); + return true; + } + } + return false; + } + + private boolean checkCrc(byte[] data, long crcNumber) { + return crcNumber == CRC.crc(data, data.length); + } + + private boolean checkCrc(byte[] type, byte[] data, byte[] crc) { + long crcNumber = byteToLong(crc); + byte[] crcData = new byte[4 + data.length]; + System.arraycopy(type, 0, crcData, 0, 4); + System.arraycopy(data, 0, crcData, 4, data.length); + + return checkCrc(crcData, crcNumber); + } + + public PNG readInPNG() throws IOException, DecodeException { + PNG png = new PNG(); + readHeader(); + + String chunkName; + do { + byte[] length = readBytes(4); + long size = byteToLong(length); + byte[] type = readBytes(4); + chunkName = ByteHandler.byteToString(type).toUpperCase(); + if ("IEND".equals(chunkName)) { + break; + } + byte[] data = readBytes((int) size); + byte[] crc = readBytes(4); + // LOG.info(ByteHandler.byteToString(type)); + + boolean found = readChunk(png, chunkName, length, type, data, crc); + if (!found) { + // LOG.info("Not support chunk name {}", chunkName); + } + + boolean crcMatch = checkCrc(type, data, crc); + if (!crcMatch) { + throw new DecodeException("Error data stream for incorrect crc"); + } + } while (!"IEND".equals(chunkName)); + return png; + } + + private byte[] readBytes(int size) throws IOException { + byte[] result = new byte[size]; + int ret = in.read(result, 0, size); + if (ret == -1) + return null; + return result; + } + +} diff --git a/src/main/java/com/baislsl/png/decode/IDATManager.java b/src/main/java/com/baislsl/png/decode/IDATManager.java new file mode 100644 index 0000000..a62ac41 --- /dev/null +++ b/src/main/java/com/baislsl/png/decode/IDATManager.java @@ -0,0 +1,23 @@ +package com.baislsl.png.decode; + +import com.baislsl.png.chunk.IDAT; + +import java.util.ArrayList; + +public class IDATManager extends ArrayList { + + public byte[] getIDATData() { + int dataSize = 0; + for (IDAT idat : this) { + dataSize += idat.dataLength(); + } + byte[] data = new byte[dataSize]; + int curPos = 0; + for (IDAT idat : this) { + System.arraycopy(idat.getData(), 0, data, curPos, (int) idat.dataLength()); + curPos += idat.dataLength(); + } + return data; + } + +} diff --git a/src/main/java/com/baislsl/png/decode/PNG.java b/src/main/java/com/baislsl/png/decode/PNG.java new file mode 100644 index 0000000..aca2767 --- /dev/null +++ b/src/main/java/com/baislsl/png/decode/PNG.java @@ -0,0 +1,132 @@ +package com.baislsl.png.decode; + +import com.baislsl.png.chunk.*; +import com.baislsl.png.util.ReverseFilter; + +import net.lax1dude.eaglercraft.EaglerInflater; + +import java.io.IOException; + +/** + * Created by baislsl on 17-7-9. + */ +public class PNG { + // private final static Logger LOG = LoggerFactory.getLogger(PNG.class); + public IHDR ihdr; + public IDATManager idats = new IDATManager(); + public PLTE plte; + public tRNS trns; + public IEND iend; + + public PNG() { + } + + public boolean isAlpha() { + return this.trns != null || ihdr.getBpp() == 4; + } + + public int[] getColor() throws DecodeException { + byte[] rawData = idats.getIDATData(); + byte[] uncompressData = applyLZ77(rawData); + byte[][] transferData = applyReverseFilter(uncompressData); + int[] colors = applyColorTransfer(transferData); + return colors; + } + + private int[] applyColorTransfer(byte[][] data) throws DecodeException { + int bpp = ihdr.getBpp(); + int width = (int) ihdr.getWidth(); + int height = (int) ihdr.getHeight(); + int colorType = ihdr.getColorType(); + int bitDepth = ihdr.getBitDepth(); + int[] colors = new int[width * height]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int idx = i * width + j; + switch (colorType) { + case 2: + if (bitDepth == 8) { // bpp = 3 + colors[idx] = ((int) data[i][bpp * j] & 0xff) << 16 | ((int) data[i][bpp * j + 1] & 0xff) << 8 + | ((int) data[i][bpp * j + 2] & 0xff); + } else { + throw new DecodeException("not supported"); + } + break; + case 6: + if (bitDepth == 8) { // bpp = 4 + colors[idx] = ((int) data[i][bpp * j] & 0xff) << 16 | ((int) data[i][bpp * j + 1] & 0xff) << 8 + | ((int) data[i][bpp * j + 2] & 0xff) | ((int) data[i][bpp * j + 3] & 0xff) << 24; + } else { + throw new DecodeException("not supported"); + } + break; + case 3: + int gap = 8 / bitDepth; + int a = (1 << bitDepth) - 1; + int b = gap - (j % gap) - 1; + int pi = (data[i][j / gap] >> (b * bitDepth)) & a; + if (trns != null && trns.getAlpha() == pi) { + colors[idx] = 0; + }else { + colors[idx] = plte.getColor(pi); + } + break; + default: + throw new DecodeException("Do not support color type " + colorType); + } + } + } + + return colors; + } + + private byte[] applyLZ77(byte[] data) throws DecodeException { + byte[] result; + try { + result = EaglerInflater.uncompress(data); + } catch (IOException e) { + // LOG.error("LZ77 decode error", e); + throw new DecodeException(e); + } + // LOG.info("Size after decode={}", result.length); + return result; + } + + private byte[][] applyReverseFilter(byte[] data) { + int width = (int) ihdr.getWidth(), height = (int) ihdr.getHeight(); + return ReverseFilter.apply(data, width, height, ihdr.getBpp()); + } + + public void setIdats(IDATManager idats) { + this.idats = idats; + } + + public void setIhdr(IHDR ihdr) { + this.ihdr = ihdr; + } + + public void setPlte(PLTE plte) { + this.plte = plte; + } + + public void setTrns(tRNS trns) { + this.trns = trns; + } + + public void setIend(IEND iend) { + this.iend = iend; + } + + public void add(IDAT idat) throws DecodeException { + idats.add(idat); + } + + public long getWidth() { + return ihdr.getWidth(); + } + + public long getHeight() { + return ihdr.getHeight(); + } + +} diff --git a/src/main/java/com/baislsl/png/util/ByteHandler.java b/src/main/java/com/baislsl/png/util/ByteHandler.java new file mode 100644 index 0000000..8e07d1d --- /dev/null +++ b/src/main/java/com/baislsl/png/util/ByteHandler.java @@ -0,0 +1,32 @@ +package com.baislsl.png.util; + +/** + * Created by baislsl on 17-7-10. + */ +public class ByteHandler { + + public static long byteToLong(byte[] data, int offset, int size) { + long result = 0; + for (int i = 0; i < size; i++) { + result <<= 8; + result |= ((long) data[offset + i] & 0xff); + } + return result; + } + + public static long byteToLong(byte[] data, int offset) { + return byteToLong(data, offset, 4); + } + + public static long byteToLong(byte[] data) { + return byteToLong(data, 0, 4); + } + + public static String byteToString(byte[] data) { + StringBuilder str = new StringBuilder(); + for (byte b : data) { + str.append((char) (0x0ff & b)); + } + return str.toString(); + } +} diff --git a/src/main/java/com/baislsl/png/util/CRC.java b/src/main/java/com/baislsl/png/util/CRC.java new file mode 100644 index 0000000..1d95c27 --- /dev/null +++ b/src/main/java/com/baislsl/png/util/CRC.java @@ -0,0 +1,35 @@ +package com.baislsl.png.util; + +/** + * Created by baislsl on 17-7-9. + */ +public class CRC { + private final static long[] crcTable = new long[256]; + + static { + for (int i = 0; i < 256; i++) { + long c = i; + for (int k = 0; k < 8; k++) { + if ((c & 1) != 0) { + c = 0xedb88320L ^ (c >> 1); + } else { + c >>= 1; + } + } + crcTable[i] = c; + } + } + + private static long updateCrc(long crc, byte[] buf, int size) { + long ans = crc; + for (int i = 0; i < size; i++) { + ans = crcTable[(int) ((ans ^ buf[i]) & 0xff)] ^ (ans >> 8); + } + return ans; + } + + public static long crc(byte[] buf, int size) { + return updateCrc(0xffffffffL, buf, size) ^ 0xffffffffL; + } + +} diff --git a/src/main/java/com/baislsl/png/util/ReverseFilter.java b/src/main/java/com/baislsl/png/util/ReverseFilter.java new file mode 100644 index 0000000..9016fdc --- /dev/null +++ b/src/main/java/com/baislsl/png/util/ReverseFilter.java @@ -0,0 +1,64 @@ +package com.baislsl.png.util; + +public class ReverseFilter { + private ReverseFilter() { + } + + private static int paethPredictor(int a, int b, int c) { + int p = a + b - c; + int pa = Math.abs(p - a), pb = Math.abs(p - b), pc = Math.abs(p - c); + if (pa <= pb && pa <= pc) + return a; + if (pb <= pc) + return b; + return c; + } + + // apply reverse Filter Algorithms to byte data + // bpp = 3 + public static byte[][] apply(byte[] data, int width, int height, int bpp) { + int[] filterType = new int[height]; + int[][] blocks = new int[height][width * bpp]; + int dataIndex = 0; + for (int i = 0; i < height; i++) { + filterType[i] = (int) (data[dataIndex++]) & 0xFF; + for (int j = 0; j < width * bpp; j++) { + blocks[i][j] = (int) (data[dataIndex++]) & 0xFF; + } + } + for (int i = 0; i < height; i++) { + for (int j = 0; j < width * bpp; j++) { + int prior = (i == 0) ? 0 : blocks[i - 1][j]; + int rawBpp = (j < bpp) ? 0 : blocks[i][j - bpp]; + int bppPrior = (i == 0 || j < bpp) ? 0 : blocks[i - 1][j - bpp]; + switch (filterType[i]) { + case 0: // none + break; + case 1: // sub + blocks[i][j] = blocks[i][j] + rawBpp; + break; + case 2: // up + blocks[i][j] = blocks[i][j] + prior; + break; + case 3: // average + blocks[i][j] = blocks[i][j] + (rawBpp + prior) / 2; + break; + case 4: // paeth + blocks[i][j] = blocks[i][j] + paethPredictor(rawBpp, prior, bppPrior); + break; + default: + } + blocks[i][j] &= 0xff; + } + } + + byte[][] result = new byte[height][width * bpp]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width * bpp; j++) { + result[i][j] = (byte) blocks[i][j]; + } + } + return result; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/AssetRepository.java b/src/main/java/net/lax1dude/eaglercraft/AssetRepository.java new file mode 100644 index 0000000..c9234b4 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/AssetRepository.java @@ -0,0 +1,48 @@ +package net.lax1dude.eaglercraft; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.HashMap; + +import com.jcraft.jzlib.InflaterInputStream; + +public class AssetRepository { + + private static final HashMap filePool = new HashMap(); + + public static final void install(byte[] pkg) throws IOException { + ByteArrayInputStream in2 = new ByteArrayInputStream(pkg); + DataInputStream in = new DataInputStream(in2); + byte[] header = new byte[8]; + in.read(header); + if(!"EAGPKG!!".equals(new String(header, Charset.forName("UTF-8")))) throw new IOException("invalid epk file"); + in.readUTF(); + in = new DataInputStream(new InflaterInputStream(in2)); + String s = null; + SHA1Digest dg = new SHA1Digest(); + while("".equals(s = in.readUTF())) { + String path = in.readUTF(); + byte[] digest = new byte[20]; + byte[] digest2 = new byte[20]; + in.read(digest); + int len = in.readInt(); + byte[] file = new byte[len]; + in.read(file); + if(filePool.containsKey(path)) continue; + dg.update(file, 0, len); dg.doFinal(digest2, 0); + if(!Arrays.equals(digest, digest2)) throw new IOException("invalid file hash for "+path); + filePool.put(path, file); + if(!"".equals(in.readUTF())) throw new IOException("invalid epk file"); + } + if(in.available() > 0 || !" end".equals(s)) throw new IOException("invalid epk file"); + } + + public static final byte[] getResource(String path) { + if(path.startsWith("/")) path = path.substring(1); + return filePool.get(path); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/Base64.java b/src/main/java/net/lax1dude/eaglercraft/Base64.java new file mode 100644 index 0000000..db4cf64 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/Base64.java @@ -0,0 +1,845 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.lax1dude.eaglercraft; + +import java.math.BigInteger; +import java.nio.charset.Charset; + +/** + * Provides Base64 encoding and decoding as defined by RFC 2045. + * + *

+ * This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose + * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein. + *

+ *

+ * The class can be parameterized in the following manner with various constructors: + *

+ *
    + *
  • URL-safe mode: Default off.
  • + *
  • Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of + * 4 in the encoded data. + *
  • Line separator: Default is CRLF ("\r\n")
  • + *
+ *

+ * The URL-safe parameter is only applied to encode operations. Decoding seamlessly handles both modes. + *

+ *

+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only + * encode/decode character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, + * UTF-8, etc). + *

+ *

+ * This class is thread-safe. + *

+ * + * @see RFC 2045 + * @since 1.0 + */ +public class Base64 extends BaseNCodec { + + /** + * BASE32 characters are 6 bits in length. + * They are formed by taking a block of 3 octets to form a 24-bit string, + * which is converted into 4 BASE64 characters. + */ + private static final int BITS_PER_ENCODED_BYTE = 6; + private static final int BYTES_PER_UNENCODED_BLOCK = 3; + private static final int BYTES_PER_ENCODED_BLOCK = 4; + + /** + * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" + * equivalents as specified in Table 1 of RFC 2045. + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] STANDARD_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + /** + * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / + * changed to - and _ to make the encoded Base64 results more URL-SAFE. + * This table is only used when the Base64's mode is set to URL-SAFE. + */ + private static final byte[] URL_SAFE_ENCODE_TABLE = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' + }; + + /** + * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified + * in Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 + * alphabet but fall within the bounds of the array are translated to -1. + * + * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both + * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit). + * + * Thanks to "commons" project in ws.apache.org for this code. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + */ + private static final byte[] DECODE_TABLE = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, // 20-2f + - / + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 30-3f 0-9 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 40-4f A-O + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, // 50-5f P-Z _ + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 60-6f a-o + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 // 70-7a p-z + }; + + /** + * Base64 uses 6-bit fields. + */ + /** Mask used to extract 6 bits, used when encoding */ + private static final int MASK_6BITS = 0x3f; + /** Mask used to extract 4 bits, used when decoding final trailing character. */ + private static final int MASK_4BITS = 0xf; + /** Mask used to extract 2 bits, used when decoding final trailing character. */ + private static final int MASK_2BITS = 0x3; + + // The static final fields above are used for the original static byte[] methods on Base64. + // The private member fields below are used with the new streaming approach, which requires + // some state be preserved between calls of encode() and decode(). + + /** + * Decodes Base64 data into octets. + *

+ * Note: this method seamlessly handles data encoded in URL-safe or normal mode. + *

+ * + * @param base64Data + * Byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decodeBase64(final byte[] base64Data) { + return new Base64().decode(base64Data); + } + + /** + * Decodes a Base64 String into octets. + *

+ * Note: this method seamlessly handles data encoded in URL-safe or normal mode. + *

+ * + * @param base64String + * String containing Base64 data + * @return Array containing decoded data. + * @since 1.4 + */ + public static byte[] decodeBase64(final String base64String) { + return new Base64().decode(base64String); + } + + // Implementation of integer encoding used for crypto + /** + * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature. + * + * @param pArray + * a byte array containing base64 character data + * @return A BigInteger + * @since 1.4 + */ + public static BigInteger decodeInteger(final byte[] pArray) { + return new BigInteger(1, decodeBase64(pArray)); + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + */ + public static byte[] encodeBase64(final byte[] binaryData) { + return encodeBase64(binaryData, false); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if {@code true} this encoder will chunk the base64 output into 76 character blocks + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked) { + return encodeBase64(binaryData, isChunked, false); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if {@code true} this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if {@code true} this encoder will emit - and _ instead of the usual + and / characters. + * Note: no padding is added when encoding using the URL-safe alphabet. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} + * @since 1.4 + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) { + return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE); + } + + /** + * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. + * + * @param binaryData + * Array containing binary data to encode. + * @param isChunked + * if {@code true} this encoder will chunk the base64 output into 76 character blocks + * @param urlSafe + * if {@code true} this encoder will emit - and _ instead of the usual + and / characters. + * Note: no padding is added when encoding using the URL-safe alphabet. + * @param maxResultSize + * The maximum result size to accept. + * @return Base64-encoded data. + * @throws IllegalArgumentException + * Thrown when the input array needs an output array bigger than maxResultSize + * @since 1.4 + */ + public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, + final boolean urlSafe, final int maxResultSize) { + if (binaryData == null || binaryData.length == 0) { + return binaryData; + } + + // Create this so can use the super-class method + // Also ensures that the same roundings are performed by the ctor and the code + final Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe); + final long len = b64.getEncodedLength(binaryData); + if (len > maxResultSize) { + throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + + len + + ") than the specified maximum size of " + + maxResultSize); + } + + return b64.encode(binaryData); + } + + /** + * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks + * + * @param binaryData + * binary data to encode + * @return Base64 characters chunked in 76 character blocks + */ + public static byte[] encodeBase64Chunked(final byte[] binaryData) { + return encodeBase64(binaryData, true); + } + + /** + * Encodes binary data using the base64 algorithm but does not chunk the output. + * + * NOTE: We changed the behavior of this method from multi-line chunking (commons-codec-1.4) to + * single-line non-chunking (commons-codec-1.5). + * + * @param binaryData + * binary data to encode + * @return String containing Base64 characters. + * @since 1.4 (NOTE: 1.4 chunked the output, whereas 1.5 does not). + */ + public static String encodeBase64String(final byte[] binaryData) { + return new String(encodeBase64(binaryData, false), Charset.forName("UTF-8")); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * Note: no padding is added. + * @param binaryData + * binary data to encode + * @return byte[] containing Base64 characters in their UTF-8 representation. + * @since 1.4 + */ + public static byte[] encodeBase64URLSafe(final byte[] binaryData) { + return encodeBase64(binaryData, false, true); + } + + /** + * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The + * url-safe variation emits - and _ instead of + and / characters. + * Note: no padding is added. + * @param binaryData + * binary data to encode + * @return String containing Base64 characters + * @since 1.4 + */ + public static String encodeBase64URLSafeString(final byte[] binaryData) { + return new String(encodeBase64(binaryData, false, true), Charset.forName("UTF-8")); + } + + /** + * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature. + * + * @param bigInteger + * a BigInteger + * @return A byte array containing base64 character data + * @throws NullPointerException + * if null is passed in + * @since 1.4 + */ + public static byte[] encodeInteger(final BigInteger bigInteger) { + return encodeBase64(toIntegerBytes(bigInteger), false); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return {@code true} if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * {@code false}, otherwise + * @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0. + */ + @Deprecated + public static boolean isArrayByteBase64(final byte[] arrayOctet) { + return isBase64(arrayOctet); + } + + /** + * Returns whether or not the {@code octet} is in the base 64 alphabet. + * + * @param octet + * The value to test + * @return {@code true} if the value is defined in the the base 64 alphabet, {@code false} otherwise. + * @since 1.4 + */ + public static boolean isBase64(final byte octet) { + return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1); + } + + /** + * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param arrayOctet + * byte array to test + * @return {@code true} if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; + * {@code false}, otherwise + * @since 1.5 + */ + public static boolean isBase64(final byte[] arrayOctet) { + for (int i = 0; i < arrayOctet.length; i++) { + if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { + return false; + } + } + return true; + } + + /** + * Tests a given String to see if it contains only valid characters within the Base64 alphabet. Currently the + * method treats whitespace as valid. + * + * @param base64 + * String to test + * @return {@code true} if all characters in the String are valid characters in the Base64 alphabet or if + * the String is empty; {@code false}, otherwise + * @since 1.5 + */ + public static boolean isBase64(final String base64) { + return isBase64(base64.getBytes(Charset.forName("UTF-8"))); + } + + /** + * Returns a byte-array representation of a {@code BigInteger} without sign bit. + * + * @param bigInt + * {@code BigInteger} to be converted + * @return a byte array representation of the BigInteger parameter + */ + static byte[] toIntegerBytes(final BigInteger bigInt) { + int bitlen = bigInt.bitLength(); + // round bitlen + bitlen = ((bitlen + 7) >> 3) << 3; + final byte[] bigBytes = bigInt.toByteArray(); + + if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { + return bigBytes; + } + // set up params for copying everything but sign bit + int startSrc = 0; + int len = bigBytes.length; + + // if bigInt is exactly byte-aligned, just skip signbit in copy + if ((bigInt.bitLength() % 8) == 0) { + startSrc = 1; + len--; + } + final int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec + final byte[] resizedBytes = new byte[bitlen / 8]; + System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); + return resizedBytes; + } + + /** + * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able + * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch + * between the two modes. + */ + private final byte[] encodeTable; + + // Only one decode table currently; keep for consistency with Base32 code + private final byte[] decodeTable = DECODE_TABLE; + + /** + * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. + */ + private final byte[] lineSeparator; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * {@code decodeSize = 3 + lineSeparator.length;} + */ + private final int decodeSize; + + /** + * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. + * {@code encodeSize = 4 + lineSeparator.length;} + */ + private final int encodeSize; + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ */ + public Base64() { + this(0); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode. + *

+ * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. + *

+ * + *

+ * When decoding all variants are supported. + *

+ * + * @param urlSafe + * if {@code true}, URL-safe encoding is used. In most cases this should be set to + * {@code false}. + * @since 1.4 + */ + public Base64(final boolean urlSafe) { + this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @since 1.4 + */ + public Base64(final int lineLength) { + this(lineLength, CHUNK_SEPARATOR); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @throws IllegalArgumentException + * Thrown when the provided lineSeparator included some base64 characters. + * @since 1.4 + */ + public Base64(final int lineLength, final byte[] lineSeparator) { + this(lineLength, lineSeparator, false); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param urlSafe + * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode + * operations. Decoding seamlessly handles both modes. + * Note: no padding is added when using the URL-safe alphabet. + * @throws IllegalArgumentException + * Thrown when the {@code lineSeparator} contains Base64 characters. + * @since 1.4 + */ + public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe) { + this(lineLength, lineSeparator, urlSafe, CodecPolicy.LENIANT); + } + + /** + * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. + *

+ * When encoding the line length and line separator are given in the constructor, and the encoding table is + * STANDARD_ENCODE_TABLE. + *

+ *

+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. + *

+ *

+ * When decoding all variants are supported. + *

+ * + * @param lineLength + * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of + * 4). If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when + * decoding. + * @param lineSeparator + * Each line of encoded data will end with this sequence of bytes. + * @param urlSafe + * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode + * operations. Decoding seamlessly handles both modes. + * Note: no padding is added when using the URL-safe alphabet. + * @param decodingPolicy The decoding policy. + * @throws IllegalArgumentException + * Thrown when the {@code lineSeparator} contains Base64 characters. + * @since 1.15 + */ + public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe, final CodecPolicy decodingPolicy) { + super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, + lineLength, + lineSeparator == null ? 0 : lineSeparator.length, + PAD_DEFAULT, + decodingPolicy); + // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0 + // @see test case Base64Test.testConstructors() + if (lineSeparator != null) { + if (containsAlphabetOrPad(lineSeparator)) { + final String sep = new String(lineSeparator, Charset.forName("UTF-8")); + throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]"); + } + if (lineLength > 0){ // null line-sep forces no chunking rather than throwing IAE + this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length; + this.lineSeparator = new byte[lineSeparator.length]; + System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + } else { + this.encodeSize = BYTES_PER_ENCODED_BLOCK; + this.lineSeparator = null; + } + this.decodeSize = this.encodeSize - 1; + this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE; + } + + // Implementation of the Encoder Interface + + /** + *

+ * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once + * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" + * call is not necessary when decoding, but it doesn't hurt, either. + *

+ *

+ * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are + * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, + * garbage-out philosophy: it will not check the provided data for validity. + *

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of ascii data to base64 decode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for decoding. + * @param context + * the context to be used + */ + @Override + void decode(final byte[] in, int inPos, final int inAvail, final Context context) { + if (context.eof) { + return; + } + if (inAvail < 0) { + context.eof = true; + } + for (int i = 0; i < inAvail; i++) { + final byte[] buffer = ensureBufferSize(decodeSize, context); + final byte b = in[inPos++]; + if (b == pad) { + // We're done. + context.eof = true; + break; + } + if (b >= 0 && b < DECODE_TABLE.length) { + final int result = DECODE_TABLE[b]; + if (result >= 0) { + context.modulus = (context.modulus+1) % BYTES_PER_ENCODED_BLOCK; + context.ibitWorkArea = (context.ibitWorkArea << BITS_PER_ENCODED_BYTE) + result; + if (context.modulus == 0) { + buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 16) & MASK_8BITS); + buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS); + buffer[context.pos++] = (byte) (context.ibitWorkArea & MASK_8BITS); + } + } + } + } + + // Two forms of EOF as far as base64 decoder is concerned: actual + // EOF (-1) and first time '=' character is encountered in stream. + // This approach makes the '=' padding characters completely optional. + if (context.eof && context.modulus != 0) { + final byte[] buffer = ensureBufferSize(decodeSize, context); + + // We have some spare bits remaining + // Output all whole multiples of 8 bits and ignore the rest + switch (context.modulus) { +// case 0 : // impossible, as excluded above + case 1 : // 6 bits - either ignore entirely, or raise an exception + validateTrailingCharacter(); + break; + case 2 : // 12 bits = 8 + 4 + validateCharacter(MASK_4BITS, context); + context.ibitWorkArea = context.ibitWorkArea >> 4; // dump the extra 4 bits + buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS); + break; + case 3 : // 18 bits = 8 + 8 + 2 + validateCharacter(MASK_2BITS, context); + context.ibitWorkArea = context.ibitWorkArea >> 2; // dump 2 bits + buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS); + buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS); + break; + default: + throw new IllegalStateException("Impossible modulus " + context.modulus); + } + } + } + + /** + *

+ * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with + * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, to flush last + * remaining bytes (if not multiple of 3). + *

+ *

Note: no padding is added when encoding using the URL-safe alphabet.

+ *

+ * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. + * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ + *

+ * + * @param in + * byte[] array of binary data to base64 encode. + * @param inPos + * Position to start reading data from. + * @param inAvail + * Amount of bytes available from input for encoding. + * @param context + * the context to be used + */ + @Override + void encode(final byte[] in, int inPos, final int inAvail, final Context context) { + if (context.eof) { + return; + } + // inAvail < 0 is how we're informed of EOF in the underlying data we're + // encoding. + if (inAvail < 0) { + context.eof = true; + if (0 == context.modulus && lineLength == 0) { + return; // no leftovers to process and not using chunking + } + final byte[] buffer = ensureBufferSize(encodeSize, context); + final int savedPos = context.pos; + switch (context.modulus) { // 0-2 + case 0 : // nothing to do here + break; + case 1 : // 8 bits = 6 + 2 + // top 6 bits: + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 2) & MASK_6BITS]; + // remaining 2: + buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 4) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[context.pos++] = pad; + buffer[context.pos++] = pad; + } + break; + + case 2 : // 16 bits = 6 + 6 + 4 + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 10) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 4) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 2) & MASK_6BITS]; + // URL-SAFE skips the padding to further reduce size. + if (encodeTable == STANDARD_ENCODE_TABLE) { + buffer[context.pos++] = pad; + } + break; + default: + throw new IllegalStateException("Impossible modulus " + context.modulus); + } + context.currentLinePos += context.pos - savedPos; // keep track of current line position + // if currentPos == 0 we are at the start of a line, so don't add CRLF + if (lineLength > 0 && context.currentLinePos > 0) { + System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length); + context.pos += lineSeparator.length; + } + } else { + for (int i = 0; i < inAvail; i++) { + final byte[] buffer = ensureBufferSize(encodeSize, context); + context.modulus = (context.modulus+1) % BYTES_PER_UNENCODED_BLOCK; + int b = in[inPos++]; + if (b < 0) { + b += 256; + } + context.ibitWorkArea = (context.ibitWorkArea << 8) + b; // BITS_PER_BYTE + if (0 == context.modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 18) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 12) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 6) & MASK_6BITS]; + buffer[context.pos++] = encodeTable[context.ibitWorkArea & MASK_6BITS]; + context.currentLinePos += BYTES_PER_ENCODED_BLOCK; + if (lineLength > 0 && lineLength <= context.currentLinePos) { + System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length); + context.pos += lineSeparator.length; + context.currentLinePos = 0; + } + } + } + } + } + + /** + * Returns whether or not the {@code octet} is in the Base64 alphabet. + * + * @param octet + * The value to test + * @return {@code true} if the value is defined in the the Base64 alphabet {@code false} otherwise. + */ + @Override + protected boolean isInAlphabet(final byte octet) { + return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1; + } + + /** + * Returns our current encode mode. True if we're URL-SAFE, false otherwise. + * + * @return true if we're in URL-SAFE mode, false otherwise. + * @since 1.4 + */ + public boolean isUrlSafe() { + return this.encodeTable == URL_SAFE_ENCODE_TABLE; + } + + /** + * Validates whether decoding the final trailing character is possible in the context + * of the set of possible base 64 values. + * + *

The character is valid if the lower bits within the provided mask are zero. This + * is used to test the final trailing base-64 digit is zero in the bits that will be discarded. + * + * @param emptyBitsMask The mask of the lower bits that should be empty + * @param context the context to be used + * + * @throws IllegalArgumentException if the bits being checked contain any non-zero value + */ + private void validateCharacter(final int emptyBitsMask, final Context context) { + if (isStrictDecoding() && (context.ibitWorkArea & emptyBitsMask) != 0) { + throw new IllegalArgumentException( + "Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. " + + "Expected the discarded bits from the character to be zero."); + } + } + + /** + * Validates whether decoding allows an entire final trailing character that cannot be + * used for a complete byte. + * + * @throws IllegalArgumentException if strict decoding is enabled + */ + private void validateTrailingCharacter() { + if (isStrictDecoding()) { + throw new IllegalArgumentException( + "Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. " + + "Decoding requires at least two trailing 6-bit characters to create bytes."); + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/BaseNCodec.java b/src/main/java/net/lax1dude/eaglercraft/BaseNCodec.java new file mode 100644 index 0000000..9db8103 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/BaseNCodec.java @@ -0,0 +1,674 @@ +package net.lax1dude.eaglercraft; + +import java.nio.charset.Charset; +import java.util.Arrays; + +import net.lax1dude.eaglercraft.BaseNCodec.CodecPolicy; + +public abstract class BaseNCodec { + + static enum CodecPolicy { + STRICT,LENIANT; + } + + /** + * Holds thread context so classes can be thread-safe. + * + * This class is not itself thread-safe; each thread must allocate its own copy. + * + * @since 1.7 + */ + static class Context { + + /** + * Place holder for the bytes we're dealing with for our based logic. + * Bitwise operations store and extract the encoding or decoding from this variable. + */ + int ibitWorkArea; + + /** + * Place holder for the bytes we're dealing with for our based logic. + * Bitwise operations store and extract the encoding or decoding from this variable. + */ + long lbitWorkArea; + + /** + * Buffer for streaming. + */ + byte[] buffer; + + /** + * Position where next character should be written in the buffer. + */ + int pos; + + /** + * Position where next character should be read from the buffer. + */ + int readPos; + + /** + * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless, + * and must be thrown away. + */ + boolean eof; + + /** + * Variable tracks how many characters have been written to the current line. Only used when encoding. We use + * it to make sure each encoded line never goes beyond lineLength (if lineLength > 0). + */ + int currentLinePos; + + /** + * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding. This + * variable helps track that. + */ + int modulus; + + Context() { + } + + /** + * Returns a String useful for debugging (especially within a debugger.) + * + * @return a String useful for debugging. + */ + @SuppressWarnings("boxing") // OK to ignore boxing here + @Override + public String toString() { + return String.format("%s[buffer=%s, currentLinePos=%s, eof=%s, ibitWorkArea=%s, lbitWorkArea=%s, " + + "modulus=%s, pos=%s, readPos=%s]", this.getClass().getSimpleName(), Arrays.toString(buffer), + currentLinePos, eof, ibitWorkArea, lbitWorkArea, modulus, pos, readPos); + } + } + + /** + * EOF + * + * @since 1.7 + */ + static final int EOF = -1; + + /** + * MIME chunk size per RFC 2045 section 6.8. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 2045 section 6.8 + */ + public static final int MIME_CHUNK_SIZE = 76; + + /** + * PEM chunk size per RFC 1421 section 4.3.2.4. + * + *

+ * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any + * equal signs. + *

+ * + * @see RFC 1421 section 4.3.2.4 + */ + public static final int PEM_CHUNK_SIZE = 64; + + private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2; + + /** + * Defines the default buffer size - currently {@value} + * - must be large enough for at least one encoded block+separator + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * The maximum size buffer to allocate. + * + *

This is set to the same size used in the JDK {@code java.util.ArrayList}:

+ *
+ * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit. + *
+ */ + private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + + /** Mask used to extract 8 bits, used in decoding bytes */ + protected static final int MASK_8BITS = 0xff; + + /** + * Byte used to pad output. + */ + protected static final byte PAD_DEFAULT = '='; // Allow static access to default + + /** + * Chunk separator per RFC 2045 section 2.1. + * + * @see RFC 2045 section 2.1 + */ + static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; + + /** + * Compares two {@code int} values numerically treating the values + * as unsigned. Taken from JDK 1.8. + * + *

TODO: Replace with JDK 1.8 Integer::compareUnsigned(int, int).

+ * + * @param x the first {@code int} to compare + * @param y the second {@code int} to compare + * @return the value {@code 0} if {@code x == y}; a value less + * than {@code 0} if {@code x < y} as unsigned values; and + * a value greater than {@code 0} if {@code x > y} as + * unsigned values + */ + private static int compareUnsigned(final int xx, final int yy) { + int x = xx + Integer.MIN_VALUE; + int y = yy + Integer.MIN_VALUE; + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } + + /** + * Create a positive capacity at least as large the minimum required capacity. + * If the minimum capacity is negative then this throws an OutOfMemoryError as no array + * can be allocated. + * + * @param minCapacity the minimum capacity + * @return the capacity + * @throws OutOfMemoryError if the {@code minCapacity} is negative + */ + private static int createPositiveCapacity(final int minCapacity) { + if (minCapacity < 0) { + // overflow + throw new OutOfMemoryError("Unable to allocate array size: " + (minCapacity & 0xffffffffL)); + } + // This is called when we require buffer expansion to a very big array. + // Use the conservative maximum buffer size if possible, otherwise the biggest required. + // + // Note: In this situation JDK 1.8 java.util.ArrayList returns Integer.MAX_VALUE. + // This excludes some VMs that can exceed MAX_BUFFER_SIZE but not allocate a full + // Integer.MAX_VALUE length array. + // The result is that we may have to allocate an array of this size more than once if + // the capacity must be expanded again. + return (minCapacity > MAX_BUFFER_SIZE) ? + minCapacity : + MAX_BUFFER_SIZE; + } + + /** + * Gets a copy of the chunk separator per RFC 2045 section 2.1. + * + * @return the chunk separator + * @see RFC 2045 section 2.1 + * @since 1.15 + */ + public static byte[] getChunkSeparator() { + return CHUNK_SEPARATOR.clone(); + } + + /** + * Checks if a byte value is whitespace or not. + * Whitespace is taken to mean: space, tab, CR, LF + * @param byteToCheck + * the byte to check + * @return true if byte is whitespace, false otherwise + */ + protected static boolean isWhiteSpace(final byte byteToCheck) { + switch (byteToCheck) { + case ' ' : + case '\n' : + case '\r' : + case '\t' : + return true; + default : + return false; + } + } + + /** + * Increases our buffer by the {@link #DEFAULT_BUFFER_RESIZE_FACTOR}. + * @param context the context to be used + * @param minCapacity the minimum required capacity + * @return the resized byte[] buffer + * @throws OutOfMemoryError if the {@code minCapacity} is negative + */ + private static byte[] resizeBuffer(final Context context, final int minCapacity) { + // Overflow-conscious code treats the min and new capacity as unsigned. + final int oldCapacity = context.buffer.length; + int newCapacity = oldCapacity * DEFAULT_BUFFER_RESIZE_FACTOR; + if (compareUnsigned(newCapacity, minCapacity) < 0) { + newCapacity = minCapacity; + } + if (compareUnsigned(newCapacity, MAX_BUFFER_SIZE) > 0) { + newCapacity = createPositiveCapacity(minCapacity); + } + + final byte[] b = new byte[newCapacity]; + System.arraycopy(context.buffer, 0, b, 0, context.buffer.length); + context.buffer = b; + return b; + } + + /** + * @deprecated Use {@link #pad}. Will be removed in 2.0. + */ + @Deprecated + protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later + + protected final byte pad; // instance variable just in case it needs to vary later + + /** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */ + private final int unencodedBlockSize; + + /** Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32 */ + private final int encodedBlockSize; + + /** + * Chunksize for encoding. Not used when decoding. + * A value of zero or less implies no chunking of the encoded data. + * Rounded down to nearest multiple of encodedBlockSize. + */ + protected final int lineLength; + + /** + * Size of chunk separator. Not used unless {@link #lineLength} > 0. + */ + private final int chunkSeparatorLength; + + /** + * Defines the decoding behavior when the input bytes contain leftover trailing bits that + * cannot be created by a valid encoding. These can be bits that are unused from the final + * character or entire characters. The default mode is lenient decoding. Set this to + * {@code true} to enable strict decoding. + *
    + *
  • Lenient: Any trailing bits are composed into 8-bit bytes where possible. + * The remainder are discarded. + *
  • Strict: The decoding will raise an {@link IllegalArgumentException} if trailing bits + * are not part of a valid encoding. Any unused bits from the final character must + * be zero. Impossible counts of entire final characters are not allowed. + *
+ * + *

When strict decoding is enabled it is expected that the decoded bytes will be re-encoded + * to a byte array that matches the original, i.e. no changes occur on the final + * character. This requires that the input bytes use the same padding and alphabet + * as the encoder. + */ + private final CodecPolicy decodingPolicy; + + /** + * Note {@code lineLength} is rounded down to the nearest multiple of the encoded block size. + * If {@code chunkSeparatorLength} is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length {@code lineLength} + * @param chunkSeparatorLength the chunk separator length, if relevant + */ + protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, + final int lineLength, final int chunkSeparatorLength) { + this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, PAD_DEFAULT); + } + + /** + * Note {@code lineLength} is rounded down to the nearest multiple of the encoded block size. + * If {@code chunkSeparatorLength} is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length {@code lineLength} + * @param chunkSeparatorLength the chunk separator length, if relevant + * @param pad byte used as padding byte. + */ + protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, + final int lineLength, final int chunkSeparatorLength, final byte pad) { + this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, pad, CodecPolicy.LENIANT); + } + + /** + * Note {@code lineLength} is rounded down to the nearest multiple of the encoded block size. + * If {@code chunkSeparatorLength} is zero, then chunking is disabled. + * @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3) + * @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4) + * @param lineLength if > 0, use chunking with a length {@code lineLength} + * @param chunkSeparatorLength the chunk separator length, if relevant + * @param pad byte used as padding byte. + * @param decodingPolicy Decoding policy. + * @since 1.15 + */ + protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, + final int lineLength, final int chunkSeparatorLength, final byte pad, final CodecPolicy decodingPolicy) { + this.unencodedBlockSize = unencodedBlockSize; + this.encodedBlockSize = encodedBlockSize; + final boolean useChunking = lineLength > 0 && chunkSeparatorLength > 0; + this.lineLength = useChunking ? (lineLength / encodedBlockSize) * encodedBlockSize : 0; + this.chunkSeparatorLength = chunkSeparatorLength; + this.pad = pad; + this.decodingPolicy = decodingPolicy; + } + + /** + * Returns the amount of buffered data available for reading. + * + * @param context the context to be used + * @return The amount of buffered data available for reading. + */ + int available(final Context context) { // package protected for access from I/O streams + return context.buffer != null ? context.pos - context.readPos : 0; + } + + /** + * Tests a given byte array to see if it contains any characters within the alphabet or PAD. + * + * Intended for use in checking line-ending arrays + * + * @param arrayOctet + * byte array to test + * @return {@code true} if any byte is a valid character in the alphabet or PAD; {@code false} otherwise + */ + protected boolean containsAlphabetOrPad(final byte[] arrayOctet) { + if (arrayOctet == null) { + return false; + } + for (final byte element : arrayOctet) { + if (pad == element || isInAlphabet(element)) { + return true; + } + } + return false; + } + + /** + * Decodes a byte[] containing characters in the Base-N alphabet. + * + * @param pArray + * A byte array containing Base-N character data + * @return a byte array containing binary data + */ + public byte[] decode(final byte[] pArray) { + if (pArray == null || pArray.length == 0) { + return pArray; + } + final Context context = new Context(); + decode(pArray, 0, pArray.length, context); + decode(pArray, 0, EOF, context); // Notify decoder of EOF. + final byte[] result = new byte[context.pos]; + readResults(result, 0, result.length, context); + return result; + } + + // package protected for access from I/O streams + abstract void decode(byte[] pArray, int i, int length, Context context); + + /** + * Decodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of + * the Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String. + * + * @param obj + * Object to decode + * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String + * supplied. + * @throws DecoderException + * if the parameter supplied is not of type byte[] + */ + public Object decode(final Object obj) { + if (obj instanceof byte[]) { + return decode((byte[]) obj); + } else if (obj instanceof String) { + return decode((String) obj); + } else { + return null; + } + } + + /** + * Decodes a String containing characters in the Base-N alphabet. + * + * @param pArray + * A String containing Base-N character data + * @return a byte array containing binary data + */ + public byte[] decode(final String pArray) { + return decode(pArray.getBytes(Charset.forName("UTF-8"))); + } + + /** + * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet. + * + * @param pArray + * a byte array containing binary data + * @return A byte array containing only the base N alphabetic character data + */ + public byte[] encode(final byte[] pArray) { + if (pArray == null || pArray.length == 0) { + return pArray; + } + return encode(pArray, 0, pArray.length); + } + + /** + * Encodes a byte[] containing binary data, into a byte[] containing + * characters in the alphabet. + * + * @param pArray + * a byte array containing binary data + * @param offset + * initial offset of the subarray. + * @param length + * length of the subarray. + * @return A byte array containing only the base N alphabetic character data + * @since 1.11 + */ + public byte[] encode(final byte[] pArray, final int offset, final int length) { + if (pArray == null || pArray.length == 0) { + return pArray; + } + final Context context = new Context(); + encode(pArray, offset, length, context); + encode(pArray, offset, EOF, context); // Notify encoder of EOF. + final byte[] buf = new byte[context.pos - context.readPos]; + readResults(buf, 0, buf.length, context); + return buf; + } + + // package protected for access from I/O streams + abstract void encode(byte[] pArray, int i, int length, Context context); + + /** + * Encodes an Object using the Base-N algorithm. This method is provided in order to satisfy the requirements of + * the Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[]. + * + * @param obj + * Object to encode + * @return An object (of type byte[]) containing the Base-N encoded data which corresponds to the byte[] supplied. + * @throws EncoderException + * if the parameter supplied is not of type byte[] + */ + public Object encode(final Object obj) { + return encode((byte[]) obj); + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the appropriate alphabet. + * Uses UTF8 encoding. + * + * @param pArray a byte array containing binary data + * @return String containing only character data in the appropriate alphabet. + * @since 1.5 + * This is a duplicate of {@link #encodeToString(byte[])}; it was merged during refactoring. + */ + public String encodeAsString(final byte[] pArray){ + return new String(encode(pArray), Charset.forName("UTF-8")); + } + + /** + * Encodes a byte[] containing binary data, into a String containing characters in the Base-N alphabet. + * Uses UTF8 encoding. + * + * @param pArray + * a byte array containing binary data + * @return A String containing only Base-N character data + */ + public String encodeToString(final byte[] pArray) { + return new String(encode(pArray), Charset.forName("UTF-8")); + } + + /** + * Ensure that the buffer has room for {@code size} bytes + * + * @param size minimum spare space required + * @param context the context to be used + * @return the buffer + */ + protected byte[] ensureBufferSize(final int size, final Context context){ + if (context.buffer == null) { + context.buffer = new byte[Math.max(size, getDefaultBufferSize())]; + context.pos = 0; + context.readPos = 0; + + // Overflow-conscious: + // x + y > z == x + y - z > 0 + } else if (context.pos + size - context.buffer.length > 0) { + return resizeBuffer(context, context.pos + size); + } + return context.buffer; + } + + /** + * Returns the decoding behavior policy. + * + *

+ * The default is lenient. If the decoding policy is strict, then decoding will raise an + * {@link IllegalArgumentException} if trailing bits are not part of a valid encoding. Decoding will compose + * trailing bits into 8-bit bytes and discard the remainder. + *

+ * + * @return true if using strict decoding + * @since 1.15 + */ + public CodecPolicy getCodecPolicy() { + return decodingPolicy; + } + + /** + * Get the default buffer size. Can be overridden. + * + * @return the default buffer size. + */ + protected int getDefaultBufferSize() { + return DEFAULT_BUFFER_SIZE; + } + + /** + * Calculates the amount of space needed to encode the supplied array. + * + * @param pArray byte[] array which will later be encoded + * + * @return amount of space needed to encoded the supplied array. + * Returns a long since a max-len array will require > Integer.MAX_VALUE + */ + public long getEncodedLength(final byte[] pArray) { + // Calculate non-chunked size - rounded up to allow for padding + // cast to long is needed to avoid possibility of overflow + long len = ((pArray.length + unencodedBlockSize-1) / unencodedBlockSize) * (long) encodedBlockSize; + if (lineLength > 0) { // We're using chunking + // Round up to nearest multiple + len += ((len + lineLength-1) / lineLength) * chunkSeparatorLength; + } + return len; + } + + /** + * Returns true if this object has buffered data for reading. + * + * @param context the context to be used + * @return true if there is data still available for reading. + */ + boolean hasData(final Context context) { // package protected for access from I/O streams + return context.buffer != null; + } + + /** + * Returns whether or not the {@code octet} is in the current alphabet. + * Does not allow whitespace or pad. + * + * @param value The value to test + * + * @return {@code true} if the value is defined in the current alphabet, {@code false} otherwise. + */ + protected abstract boolean isInAlphabet(byte value); + + /** + * Tests a given byte array to see if it contains only valid characters within the alphabet. + * The method optionally treats whitespace and pad as valid. + * + * @param arrayOctet byte array to test + * @param allowWSPad if {@code true}, then whitespace and PAD are also allowed + * + * @return {@code true} if all bytes are valid characters in the alphabet or if the byte array is empty; + * {@code false}, otherwise + */ + public boolean isInAlphabet(final byte[] arrayOctet, final boolean allowWSPad) { + for (final byte octet : arrayOctet) { + if (!isInAlphabet(octet) && + (!allowWSPad || (octet != pad) && !isWhiteSpace(octet))) { + return false; + } + } + return true; + } + + /** + * Tests a given String to see if it contains only valid characters within the alphabet. + * The method treats whitespace and PAD as valid. + * + * @param basen String to test + * @return {@code true} if all characters in the String are valid characters in the alphabet or if + * the String is empty; {@code false}, otherwise + * @see #isInAlphabet(byte[], boolean) + */ + public boolean isInAlphabet(final String basen) { + return isInAlphabet(basen.getBytes(Charset.forName("UTF-8")), true); + } + + /** + * Returns true if decoding behavior is strict. Decoding will raise an {@link IllegalArgumentException} if trailing + * bits are not part of a valid encoding. + * + *

+ * The default is false for lenient decoding. Decoding will compose trailing bits into 8-bit bytes and discard the + * remainder. + *

+ * + * @return true if using strict decoding + * @since 1.15 + */ + public boolean isStrictDecoding() { + return decodingPolicy == CodecPolicy.STRICT; + } + + /** + * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail + * bytes. Returns how many bytes were actually extracted. + *

+ * Package protected for access from I/O streams. + * + * @param b + * byte[] array to extract the buffered data into. + * @param bPos + * position in byte[] array to start extraction at. + * @param bAvail + * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available). + * @param context + * the context to be used + * @return The number of bytes successfully extracted into the provided byte[] array. + */ + int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) { + if (context.buffer != null) { + final int len = Math.min(available(context), bAvail); + System.arraycopy(context.buffer, context.readPos, b, bPos, len); + context.readPos += len; + if (context.readPos >= context.pos) { + context.buffer = null; // so hasData() will return false, and this method can return -1 + } + return len; + } + return context.eof ? EOF : 0; + } +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/ConfigConstants.java b/src/main/java/net/lax1dude/eaglercraft/ConfigConstants.java new file mode 100644 index 0000000..84e1fcc --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/ConfigConstants.java @@ -0,0 +1,14 @@ +package net.lax1dude.eaglercraft; + +public class ConfigConstants { + + public static boolean profanity = false; + + public static final String version = "22w15d"; + public static final String mainMenuString = "eaglercraft " + version; + + public static final String forkMe = "https://github.com/LAX1DUDE/eaglercraft"; + + public static final boolean html5build = true; + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/DefaultSkinRenderer.java b/src/main/java/net/lax1dude/eaglercraft/DefaultSkinRenderer.java new file mode 100644 index 0000000..9db0d93 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/DefaultSkinRenderer.java @@ -0,0 +1,438 @@ +package net.lax1dude.eaglercraft; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.EntityClientPlayerMP; +import net.minecraft.src.EntityOtherPlayerMP; +import net.minecraft.src.EntityPlayer; +import net.minecraft.src.ModelBiped; +import net.minecraft.src.ModelBlaze; +import net.minecraft.src.ModelEnderman; +import net.minecraft.src.ModelSkeleton; +import net.minecraft.src.ModelVillager; +import net.minecraft.src.ModelZombie; +import net.minecraft.src.OpenGlHelper; +import net.minecraft.src.Packet250CustomPayload; +import net.minecraft.src.RenderEnderman; +import net.minecraft.src.RenderHelper; +import net.minecraft.src.RenderManager; + +public class DefaultSkinRenderer { + + public static final TextureLocation[] defaultVanillaSkins = new TextureLocation[] { + new TextureLocation("/skins/01.default_steve.png"), + new TextureLocation("/skins/02.default_alex.png"), + new TextureLocation("/skins/03.tennis_steve.png"), + new TextureLocation("/skins/04.tennis_alex.png"), + new TextureLocation("/skins/05.tuxedo_steve.png"), + new TextureLocation("/skins/06.tuxedo_alex.png"), + new TextureLocation("/skins/07.athlete_steve.png"), + new TextureLocation("/skins/08.athlete_alex.png"), + new TextureLocation("/skins/09.cyclist_steve.png"), + new TextureLocation("/skins/10.cyclist_alex.png"), + new TextureLocation("/skins/11.boxer_steve.png"), + new TextureLocation("/skins/12.boxer_alex.png"), + new TextureLocation("/skins/13.prisoner_steve.png"), + new TextureLocation("/skins/14.prisoner_alex.png"), + new TextureLocation("/skins/15.scottish_steve.png"), + new TextureLocation("/skins/16.scottish_alex.png"), + new TextureLocation("/skins/17.dev_steve.png"), + new TextureLocation("/skins/18.dev_alex.png"), + new TextureLocation("/skins/19.herobrine.png"), + new TextureLocation("/mob/enderman.png"), + new TextureLocation("/mob/skeleton.png"), + new TextureLocation("/mob/fire.png"), + new TextureLocation("/skins/20.barney.png"), + new TextureLocation("/skins/21.slime.png"), + new TextureLocation("/skins/22.noob.png"), + new TextureLocation("/skins/23.trump.png"), + new TextureLocation("/skins/24.notch.png"), + new TextureLocation("/skins/25.creeper.png"), + new TextureLocation("/skins/26.zombie.png"), + new TextureLocation("/skins/27.pig.png"), + new TextureLocation("/skins/28.squid.png"), + new TextureLocation("/skins/29.mooshroom.png"), + new TextureLocation("/mob/villager/villager.png"), + new TextureLocation("/skins/30.longarms.png"), + new TextureLocation("/skins/31.laxdude.png") + }; + + public static final boolean[] defaultVanillaSkinClassicOrSlimVariants = new boolean[] { + false, true, + false, true, + false, true, + false, true, + false, true, + false, true, + false, true, + false, true, + false, true + }; + + private static final HashMap skinCookies = new HashMap(); + private static final HashMap skinGLUnits = new HashMap(); + private static final HashMap skinGLTimeout = new HashMap(); + + private static long lastClean = 0l; + + public static void deleteOldSkins() { + if(System.currentTimeMillis() - lastClean > 60000l) { + lastClean = System.currentTimeMillis(); + Iterator> itr = skinGLTimeout.entrySet().iterator(); + while(itr.hasNext()) { + Entry ee = itr.next(); + if(System.currentTimeMillis() - ee.getValue() > 80000l) { + itr.remove(); + if(skinGLUnits.containsKey(ee.getKey())) { + Minecraft.getMinecraft().renderEngine.deleteTexture(skinGLUnits.remove(ee.getKey())); + } + } + } + Iterator> itr2 = skinCookies.entrySet().iterator(); + while(itr2.hasNext()) { + Entry e = itr2.next(); + if(e.getValue().isDead) { + itr2.remove(); + } + } + } + } + + public static boolean bindSyncedSkin(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + return false; + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(((int)pp.skinPacket[0] & 0xFF) != 4) { + if(!skinGLUnits.containsKey(pp)) { + byte[] skinToLoad = new byte[pp.skinPacket.length - 1]; + System.arraycopy(pp.skinPacket, 1, skinToLoad, 0, skinToLoad.length); + int w, h; + + switch((int)pp.skinPacket[0] & 0xFF) { + default: + case 0: + w = 64; + h = 32; + break; + case 1: + case 5: + w = 64; + h = 64; + break; + case 2: + w = 128; + h = 64; + break; + case 3: + case 6: + w = 128; + h = 128; + break; + } + + if(skinToLoad.length / 4 == w * h) { + skinGLUnits.put(pp, Minecraft.getMinecraft().renderEngine.setupTextureRaw(skinToLoad, w, h)); + } + } + skinGLTimeout.put(pp, System.currentTimeMillis()); + Integer i = skinGLUnits.get(pp); + if(i != null && i.intValue() > 0) { + Minecraft.getMinecraft().renderEngine.bindTexture(i.intValue()); + }else { + defaultVanillaSkins[0].bindTexture(); + } + }else { + if(((int)pp.skinPacket[1] & 0xFF) < defaultVanillaSkins.length) { + defaultVanillaSkins[(int)pp.skinPacket[1] & 0xFF].bindTexture(); + } + } + return true; + }else { + if(!skinCookies.containsValue(pp)) { + int cookie = (int)(System.nanoTime() % 65536); + skinCookies.put(cookie, pp); + byte[] n = pp.username.getBytes(); + byte[] pkt = new byte[n.length + 2]; + System.arraycopy(n, 0, pkt, 2, n.length); + pkt[0] = (byte)(cookie & 0xFF); + pkt[1] = (byte)((cookie >> 8) & 0xFF); + //Minecraft.getMinecraft().addToSendQueue(new Packet250CustomPayload("EAG|FetchSkin", pkt)); //TODO: add + } + } + return false; + }else { + return false; + } + } + + public static void skinResponse(byte[] data) { + int cookie = ((int)data[0] & 0xFF) | (((int)data[1] & 0xFF) << 8); + if(skinCookies.containsKey(cookie) && (data.length > 3)) { + EntityOtherPlayerMP p = skinCookies.remove(cookie); + byte[] packet = new byte[data.length - 2]; + System.arraycopy(data, 2, packet, 0, packet.length); + p.skinPacket = packet; + } + } + + public static boolean isNewSkin(int id) { + return !(id == 0 || id == 2 || id == 4 || id == 6 || id == 8 || id == 10 || id == 12 || id == 14 || id == 18 || id == 28); + } + + public static boolean isAlexSkin(int id) { + return id < defaultVanillaSkinClassicOrSlimVariants.length && defaultVanillaSkinClassicOrSlimVariants[id]; + } + + public static boolean isStandardModel(int id) { + return !isZombieModel(id) && !(id == 19 || id == 20 || id == 21 || id == 32 || id == 33 || id == 34); + } + + public static boolean isZombieModel(int id) { + return id == 18 || id == 28; + } + + public static boolean isPlayerNewSkin(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId <= -1) { + int type = EaglerProfile.getSkinSize(EaglerProfile.skins.get(EaglerProfile.customSkinId).data.length); + return (type == 1 || type == 3); + }else { + return isNewSkin(EaglerProfile.presetSkinId); + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] != (byte)4) { + return (pp.skinPacket[0] == (byte)1) || (pp.skinPacket[0] == (byte)3) || (pp.skinPacket[0] == (byte)5) || (pp.skinPacket[0] == (byte)6); + }else { + return isNewSkin((int)pp.skinPacket[1] & 0xFF); + } + } + } + return false; + } + + public static boolean isPlayerNewSkinSlim(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId == -1) { + return EaglerProfile.skins.get(EaglerProfile.customSkinId).slim; + }else { + return isAlexSkin(EaglerProfile.presetSkinId); + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] != (byte)4) { + return (pp.skinPacket[0] == (byte)5) || (pp.skinPacket[0] == (byte)6); + }else { + return isAlexSkin((int)pp.skinPacket[1] & 0xFF); + } + } + } + return false; + } + + public static boolean isPlayerStandard(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId == -1) { + return true; + }else { + return isStandardModel(EaglerProfile.presetSkinId); + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] != (byte)4) { + return true; + }else { + return isStandardModel((int)pp.skinPacket[1] & 0xFF); + } + } + } + return true; + } + + public static int getPlayerRenderer(EntityPlayer p) { + if(p instanceof EntityClientPlayerMP) { + if(EaglerProfile.presetSkinId == -1) { + return 0; + }else { + return EaglerProfile.presetSkinId; + } + }else if(p instanceof EntityOtherPlayerMP) { + EntityOtherPlayerMP pp = (EntityOtherPlayerMP) p; + if(pp.skinPacket != null) { + if(pp.skinPacket[0] != (byte)4) { + return 0; + }else { + return (int)pp.skinPacket[1] & 0xFF; + } + } + } + return 0; + } + + public static ModelBiped oldSkinRenderer = null; + public static ModelBipedNewSkins newSkinRenderer = null; + public static ModelBipedNewSkins newSkinRendererSlim = null; + public static ModelZombie zombieRenderer = null; + public static ModelVillager villagerRenderer = null; + public static ModelEnderman endermanRenderer = null; + public static ModelBlaze blazeRenderer = null; + public static ModelSkeleton skeletonRenderer = null; + + public static void renderPlayerPreview(int x, int y, int mx, int my, int id2) { + int id = id2 - EaglerProfile.skins.size(); + + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) x, (float) (y - 80), 100.0F); + EaglerAdapter.glScalef(50.0f, 50.0f, 50.0f); + EaglerAdapter.glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glScalef(1.0F, -1.0F, 1.0F); + RenderHelper.enableGUIStandardItemLighting(); + EaglerAdapter.glTranslatef(0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f); + EaglerAdapter.glRotatef(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f); + EaglerAdapter.glTranslatef(0.0F, -1.0F, 0.0F); + + if(id < 0) { + Minecraft.getMinecraft().renderEngine.bindTexture(EaglerProfile.skins.get(id2).glTex); + }else { + defaultVanillaSkins[id].bindTexture(); + } + + if(isStandardModel(id) || id < 0) { + if(oldSkinRenderer == null) oldSkinRenderer = new ModelBiped(0.0F, 0.0F, 64, 32); + if(newSkinRenderer == null) newSkinRenderer = new ModelBipedNewSkins(0.0F, false); + if(newSkinRendererSlim == null) newSkinRendererSlim = new ModelBipedNewSkins(0.0F, true); + oldSkinRenderer.isChild = false; + newSkinRenderer.isChild = false; + newSkinRendererSlim.isChild = false; + boolean isNew = isNewSkin(id); + if(id < 0) { + int type = EaglerProfile.getSkinSize(EaglerProfile.skins.get(id2).data.length); + isNew = (type == 1 || type == 3); + } + if(isNew) { + if((id < 0 && EaglerProfile.skins.get(id2).slim) || (id >= 0 && isAlexSkin(id))) { + newSkinRendererSlim.blockTransparentSkin = true; + newSkinRendererSlim.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + newSkinRendererSlim.blockTransparentSkin = false; + }else { + newSkinRenderer.blockTransparentSkin = true; + newSkinRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + newSkinRenderer.blockTransparentSkin = false; + } + }else { + oldSkinRenderer.blockTransparentSkin = true; + oldSkinRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + oldSkinRenderer.blockTransparentSkin = false; + } + }else if(isZombieModel(id)) { + if(zombieRenderer == null) zombieRenderer = new ModelZombie(0.0F, true); + zombieRenderer.isChild = false; + zombieRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else if(id == 32) { + if(villagerRenderer == null) villagerRenderer = new ModelVillager(0.0F); + villagerRenderer.isChild = false; + villagerRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else if(id == 19) { + if(endermanRenderer == null) endermanRenderer = new ModelEnderman(); + endermanRenderer.isChild = false; + endermanRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + EaglerAdapter.glColor4f(1.4f, 1.4f, 1.4f, 1.0f); + //EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + //EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + //EaglerAdapter.glBlendFunc(EaglerAdapter.GL_ONE, EaglerAdapter.GL_ONE); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + RenderEnderman.tex_eyes.bindTexture(); + endermanRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + }else if(id == 20) { + if(skeletonRenderer == null) skeletonRenderer = new ModelSkeleton(0.0F); + skeletonRenderer.isChild = false; + skeletonRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + }else if(id == 21) { + if(blazeRenderer == null) blazeRenderer = new ModelBlaze(); + blazeRenderer.isChild = false; + EaglerAdapter.glColor4f(1.5f, 1.5f, 1.5f, 1.0f); + blazeRenderer.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + } + + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + } + + public static void renderAlexOrSteve(int x, int y, int mx, int my, boolean alex) { + ModelBipedNewSkins bp; + if(alex) { + if(newSkinRendererSlim == null) { + newSkinRendererSlim = new ModelBipedNewSkins(0.0F, true); + } + bp = newSkinRendererSlim; + }else { + if(newSkinRenderer == null) { + newSkinRenderer = new ModelBipedNewSkins(0.0F, false); + } + bp = newSkinRenderer; + } + + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef((float) x, (float) (y - 80), 100.0F); + EaglerAdapter.glScalef(50.0f, 50.0f, 50.0f); + EaglerAdapter.glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + EaglerAdapter.glEnable(EaglerAdapter.GL_RESCALE_NORMAL); + EaglerAdapter.glScalef(1.0F, -1.0F, 1.0F); + RenderHelper.enableGUIStandardItemLighting(); + EaglerAdapter.glTranslatef(0.0F, 1.0F, 0.0F); + EaglerAdapter.glRotatef(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f); + EaglerAdapter.glRotatef(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f); + EaglerAdapter.glTranslatef(0.0F, -1.0F, 0.0F); + + bp.isChild = false; + bp.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625F); + + EaglerAdapter.glPopMatrix(); + EaglerAdapter.glDisable(EaglerAdapter.GL_RESCALE_NORMAL); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + } + + public static boolean isPlayerPreviewNew(int id2) { + int id = id2 - EaglerProfile.skins.size(); + if(id < 0) { + return EaglerProfile.skins.get(id2).data.length == EaglerProfile.SKIN_DATA_SIZE[1] || EaglerProfile.skins.get(id2).data.length == EaglerProfile.SKIN_DATA_SIZE[3]; + }else { + return false; + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerAdapter.java b/src/main/java/net/lax1dude/eaglercraft/EaglerAdapter.java new file mode 100644 index 0000000..19d57f6 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerAdapter.java @@ -0,0 +1,7 @@ +package net.lax1dude.eaglercraft; + +import net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30; + +public class EaglerAdapter extends EaglerAdapterGL30 { + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerImage.java b/src/main/java/net/lax1dude/eaglercraft/EaglerImage.java new file mode 100644 index 0000000..26d5f6b --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerImage.java @@ -0,0 +1,60 @@ +package net.lax1dude.eaglercraft; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import com.baislsl.png.decode.DecodeException; +import com.baislsl.png.decode.Decoder; +import com.baislsl.png.decode.PNG; + +public class EaglerImage { + + public final int[] data; + public final int w; + public final int h; + public final boolean alpha; + + public EaglerImage(int pw, int ph, boolean palpha) { + this.w = pw; + this.h = ph; + this.alpha = palpha; + this.data = new int[pw * ph]; + } + + public EaglerImage(int[] pdata, int pw, int ph, boolean palpha) { + if(pdata.length != pw*ph) { + throw new IllegalArgumentException("array size does not equal image size"); + } + this.w = pw; + this.h = ph; + this.alpha = palpha; + if(!palpha) { + for(int i = 0; i < pdata.length; ++i) { + pdata[i] = pdata[i] | 0xFF000000; + } + } + this.data = pdata; + } + + public static final EaglerImage loadImage(byte[] file) { + try { + PNG p = (new Decoder(new ByteArrayInputStream(file))).readInPNG(); + return new EaglerImage(p.getColor(), (int)p.getWidth(), (int)p.getHeight(), p.isAlpha()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } catch (DecodeException e) { + e.printStackTrace(); + return null; + } + } + + public EaglerImage getSubImage(int x, int y, int pw, int ph) { + int[] img = new int[pw * ph]; + for(int i = 0; i < ph; ++i) { + System.arraycopy(data, (i + y) * this.w + x, img, i * pw, pw); + } + return new EaglerImage(img, pw, ph, alpha); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerInflater.java b/src/main/java/net/lax1dude/eaglercraft/EaglerInflater.java new file mode 100644 index 0000000..4601d78 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerInflater.java @@ -0,0 +1,25 @@ +package net.lax1dude.eaglercraft; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import com.jcraft.jzlib.InflaterInputStream; + +public class EaglerInflater { + + public static byte[] uncompress(byte[] input) throws IOException { + return getBytesFromInputStream(new InflaterInputStream(new ByteArrayInputStream(input))); + } + + public static byte[] getBytesFromInputStream(InputStream is) throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[0xFFFF]; + for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { + os.write(buffer, 0, len); + } + return os.toByteArray(); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglerProfile.java b/src/main/java/net/lax1dude/eaglercraft/EaglerProfile.java new file mode 100644 index 0000000..9e49226 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglerProfile.java @@ -0,0 +1,210 @@ +package net.lax1dude.eaglercraft; + +import java.util.ArrayList; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.NBTBase; +import net.minecraft.src.NBTTagByteArray; +import net.minecraft.src.NBTTagCompound; + +public class EaglerProfile { + + public static class EaglerProfileSkin { + public String name; + public byte[] data; + public boolean slim; + public int glTex; + public EaglerProfileSkin(String name, byte[] data, boolean slim, int glTex) { + this.name = name; + this.data = data; + this.slim = slim; + this.glTex = glTex; + } + } + + public static String username; + public static int presetSkinId; + public static int customSkinId; + + public static String myChannel; + + public static final int[] SKIN_DATA_SIZE = new int[] { 64*32*4, 64*64*4, 128*64*4, 128*128*4, 2, 64*64*4, 128*128*4 }; + public static ArrayList skins = new ArrayList(); + + public static final EaglercraftRandom rand; + + public static int getSkinSize(int len) { + for(int i = 0; i < SKIN_DATA_SIZE.length; ++i) { + if(len == SKIN_DATA_SIZE[i]) { + return i; + } + } + return -1; + } + + public static byte[] getSkinPacket() { + if(presetSkinId == -1) { + byte[] d = skins.get(customSkinId).data; + byte[] d2 = new byte[1 + d.length]; + d2[0] = (byte) getSkinSize(d.length); + if(d2[0] == (byte)1 && skins.get(customSkinId).slim) { + d2[0] = (byte)5; + } + if(d2[0] == (byte)3 && skins.get(customSkinId).slim) { + d2[0] = (byte)6; + } + System.arraycopy(d, 0, d2, 1, d.length); + return d2; + }else { + return new byte[] { (byte)4, (byte)presetSkinId }; + } + } + + public static String[] concatArrays(String[] a, String[] b) { + String[] r = new String[a.length + b.length]; + System.arraycopy(a, 0, r, 0, a.length); + System.arraycopy(b, 0, r, a.length, b.length); + return r; + } + + public static int addSkin(String name, byte[] data, boolean slim) { + int i = -1; + for(int j = 0, l = skins.size(); j < l; ++j) { + if(skins.get(j).name.equalsIgnoreCase(name)) { + i = j; + break; + } + } + int t = getSkinSize(data.length); + + if(t == -1) { + return -1; + } + + int w, h; + + switch(t) { + default: + case 0: + w = 64; + h = 32; + break; + case 1: + case 5: + w = 64; + h = 64; + break; + case 2: + w = 128; + h = 64; + break; + case 3: + case 6: + w = 128; + h = 128; + break; + } + + int im = Minecraft.getMinecraft().renderEngine.setupTextureRaw(data, w, h); + if(i == -1) { + i = skins.size(); + skins.add(new EaglerProfileSkin(name, data, slim, im)); + }else { + skins.get(i).glTex = im; + skins.get(i).data = data; + skins.get(i).slim = slim; + } + return i; + + } + + static { + String[] usernameDefaultWords = ConfigConstants.profanity ? new String[] { + "Eagler", + "Eagler", + "Bitch", + "Cock", + "Milf", + "Milf", + "Yeer", + "Groon", + "Eag", + "Deevis", + "Chode", + "Deev", + "Deev", + "Fucker", + "Fucking", + "Dumpster", + "Dumpster", + "Cum", + "Chad", + "Egg", + "Fudgler", + "Fudgli", + "Yee", + "Yee", + "Yee", + "Yeet", + "Flumpter", + "Darvy", + "Darver", + "Darver", + "Fuck", + "Fuck", + "Frick", + "Eagler", + "Vigg", + "Vigg", + "Cunt", + "Darvig" + } : new String[] { + "Yeeish", + "Yeeish", + "Yee", + "Yee", + "Yeer", + "Yeeler", + "Eagler", + "Eagl", + "Darver", + "Darvler", + "Vool", + "Vigg", + "Vigg", + "Deev", + "Yigg", + "Yeeg" + }; + + rand = new EaglercraftRandom(); + + do { + username = usernameDefaultWords[rand.nextInt(usernameDefaultWords.length)] + usernameDefaultWords[rand.nextInt(usernameDefaultWords.length)] + (10 + rand.nextInt(90)); + }while(username.length() > 16); + + presetSkinId = rand.nextInt(GuiScreenEditProfile.defaultOptions.length); + myChannel = username + "_" + (100 + rand.nextInt(900)); + customSkinId = -1; + } + + public static void loadFromStorage() { + if(!LocalStorageManager.profileSettingsStorage.hasNoTags()) { + presetSkinId = LocalStorageManager.profileSettingsStorage.getInteger("ps"); + customSkinId = LocalStorageManager.profileSettingsStorage.getInteger("cs"); + username = LocalStorageManager.profileSettingsStorage.getString("name"); + myChannel = username + "_" + (100 + rand.nextInt(900)); + NBTTagCompound n = LocalStorageManager.profileSettingsStorage.getCompoundTag("skins"); + for(Object s : NBTTagCompound.getTagMap(n).keySet()) { + String s2 = (String)s; + NBTBase k = n.getTag(s2); + if(k.getId() == (byte)7) { + addSkin(s2, ((NBTTagByteArray)k).byteArray, false); + }else if(k.getId() == (byte)10) { + addSkin(s2, ((NBTTagCompound)k).getByteArray("data"), ((NBTTagCompound)k).getBoolean("slim")); + } + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EaglercraftRandom.java b/src/main/java/net/lax1dude/eaglercraft/EaglercraftRandom.java new file mode 100644 index 0000000..72b0f8c --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EaglercraftRandom.java @@ -0,0 +1,84 @@ +package net.lax1dude.eaglercraft; + +public class EaglercraftRandom { + + private static final long multiplier = 0x5DEECE66DL; + private static final long addend = 0xBL; + private static final long mask = (1L << 48) - 1; + + private static final double DOUBLE_UNIT = 0x1.0p-53; + private long seed = 69; + + public EaglercraftRandom() { + this(System.nanoTime()); + } + + public EaglercraftRandom(long seed) { + setSeed(seed); + } + + public void setSeed(long yeed) { + seed = yeed; + } + + protected int next(int bits) { + seed = (seed * multiplier + addend) & mask; + return (int)(seed >>> (48 - bits)); + } + + public void nextBytes(byte[] bytes) { + for (int i = 0, len = bytes.length; i < len; ) + for (int rnd = nextInt(), + n = Math.min(len - i, Integer.SIZE/Byte.SIZE); + n-- > 0; rnd >>= Byte.SIZE) + bytes[i++] = (byte)rnd; + } + public int nextInt() { + return next(32); + } + public int nextInt(int bound) { + int r = next(31); + int m = bound - 1; + if ((bound & m) == 0) // i.e., bound is a power of 2 + r = (int)((bound * (long)r) >> 31); + else { + for (int u = r; + u - (r = u % bound) + m < 0; + u = next(31)) + ; + } + return r; + } + public long nextLong() { + return ((long)(next(32)) << 32) + next(32); + } + public boolean nextBoolean() { + return next(1) != 0; + } + public float nextFloat() { + return next(24) / ((float)(1 << 24)); + } + public double nextDouble() { + return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT; + } + private double nextNextGaussian; + private boolean haveNextNextGaussian = false; + public double nextGaussian() { + // See Knuth, ACP, Section 3.4.1 Algorithm C. + if (haveNextNextGaussian) { + haveNextNextGaussian = false; + return nextNextGaussian; + } else { + double v1, v2, s; + do { + v1 = 2 * nextDouble() - 1; // between -1 and 1 + v2 = 2 * nextDouble() - 1; // between -1 and 1 + s = v1 * v1 + v2 * v2; + } while (s >= 1 || s == 0); + double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s); + nextNextGaussian = v2 * multiplier; + haveNextNextGaussian = true; + return v1 * multiplier; + } + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/EarlyLoadScreen.java b/src/main/java/net/lax1dude/eaglercraft/EarlyLoadScreen.java new file mode 100644 index 0000000..c77067e --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/EarlyLoadScreen.java @@ -0,0 +1,171 @@ +package net.lax1dude.eaglercraft; + +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.*; + +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.BufferArrayGL; +import net.minecraft.src.GLAllocation; + +public class EarlyLoadScreen { + + public static final String loadScreen = "iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHAAAWonpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHja7ZpZjmO3lkX/OYoaAnseDoctUDOo4dfaVGRUOm0Dfnh+QH04w5YUiite8jS7IeXO//z3df/Fv9KruVya1V6r51/uucfBC/Off+M9Bp/f4/u3vv7E7795333/IfJW4jl9frX6df2P98P3AJ+nwavy00D2NVKYv/1Dz1/j2y8Dfd0oaUaRF/troP41UIqfP4SvAcZnWb52az8vYZ7P8/6xEvv87/SQ2hv7e5Bff8+N6O3CmynGk0LyPMaUPxNI+j+4NPhDfI+NC3nkdUz1Pf6ICQH5ozj5n2blfs3K96vwJ+//kpRUP+873vhtMOv38x++H8ofB9+9EP9057S+7/yb9/0J9dfl/Pj/3m3u3vNZ3ciVkNavRX1HRy+4cBLy9D5W+Wn8X3jd3k/nxxzVu8jOpmQnPyv0EEnLDTnsMMIN5z2vsJhijieSkhjjIlF6z0hRjyt5R56yfsKNLfW0k5GtRXoT78bvuYR33/5ut4Jx4x24MgYGU9aj08Pf8fOnA92rkg/B23esmFdUoTINZU6PXEVCwv1RR+UF+MfPr/+U10QGywuzscDh52eIWcJXbamO0kt04sLC86ctQttfAxAi7l2YTEhkwNeQSqjBtxhbCMTRyM9gIKNp4iQFoZS4mWXMKVWSY1H35jMtvGtjiZ+3wSwSUWijRmp6GuQqA2zUT8tGDY2SSi6l1NKKlV5GTTXXUmttVeA3Wmq5lVZba9Z6G5YsW7FqzcxZt9FjT4AjiNlbt977GNx0MPLg04MLxphxpplnmXW2abPPsSiflVdZdbVlbvU1dtxpgxO77rZt9z1OOJTSyaecetqx08+4lNpNN99y623Xbr/jO2vBfdL6u5+/nrXwI2vxZUoXtu+s8dHWfgwRBCdFOSNjMQcy3pQBCjoqZ95CztEpdcqZ75GuKJFZFiVnB2WMDOYTYrnhO3f/l7nf5M3l/G/lLf7InFPq/o7MOaXuTzL3+7z9Qdb2eKyZ3MuQ2lBB9Yn246IRjf/gpL/+7P7VD/wz0D8D/UcGGmGsOoOrnSbvPdWR2jqg9giht+pTsnBmhgWOjUXF72Zz5nZD3XPtdHqAuCu9bv5kW66m1Fe7MZUptVdCLuHruRnoVQGUWcYMfPbQoLumE3Mfe8Nx3IXZCNiuK3TtysBoR0C2yQjlpi525CPF78xYZfQ+9xzAglr/pAmC9XXLuMixX2Nk4/DjgQqgRC+Zdt0n5Hhjnmg4oDE3JpO2cc88Aa6wI8C10y3bbTTevDvFMyIIU0EV8LQiFEC7AibuVQo3QN4SqhmvggY+Ed94egGZEC5AmENOpFXH8j38Pkp63j3mbCNVnqtn4ikWu9nHuR5ipcB4qbiTwbvB5XmPuTqKpfDU+AUwPhcenqUx55ljY/UkchHmNTMpWL5s2MJA3uNOAIIRbZeL6tqs5voC4ufpLzGqqCEIft0OClsrxLkHcrHQ2RV8v2HP3GfbjhvYmYnQ3lGXeVvn9NSOR3bFdgoTP5MgdU9qmQChuExixlxifHFMkl/XUVVzhXYJwY4jxDkIO3DP7KxDN0Th+rWanbZnbDeN0+et7e5cxpnL2652Y3QzzNozayMzKdTFJef2IRIdixo626c8N5REZrn2sQcPp+wOvXV9IvQV3F1nMHU+Mu5Z/cZ9S2EOe+2R/Wnh1JQvFXiNxbUhQksEdu/a01WVqdxbcw2yvtXO2Cez6Bh2uaeskPhgup1L7okUDfHMbSV+pXRKsB4D/5GLkdukQF3x13ciMDPB7HtO2rG1GAYVWwqPuZMxGvJAl5eugQDbYjwEAHnY8xBy6eze774Tbp2+hVV1y7NmuSU1ap9uueh1ownyzkdlQDtOwYARS7QFeCDTeRw5457BmDakSZ+0TAs0Rjq2DNWY90KF4A+pDcI6VpvjkkPKuDC9nMY6FpoLNc1NUzL7imaHaXs55V7xL5pmjLaYSSoLFOkxMpV+G51J++IV70pjt9kaeBRVAHNda2F0EiT1Y1WtlZh3JHUM301tRzkDRvP0fkhKPjuiGcZC32V1v5c0qkr1vHlQcRdVocQSqrwj7bWYbQpojzFRdylNnzbqzVYDG1DLnrC6s08Evga1ULWgXHqYa9FpM1rPgTcx82tIwF3QI90L0gBX1IGBcpav5einI56x9RWzlxVaB7dDPyoQC6FmiCkqKty85jHujYLa5wTyTWou1dUaHXH3caBl5DPMK81KW5KyUAdlG+hLWk8KkDSFfUdp6uZFwqj8ib9DnWXU4EyrRaQfZWqHi5CCpVGPxM9WGY8n+qAP020gIXZs0E/JgM30UISumRPiYGoW3WEBh/wPCdmyV+c5nk0SoQXKdtqY4BuGL+9ZFByaK94WACrQ3M5uaeGS0NmrpU1m9iWLYrfCp0kcBAX8jJJRrgeoIz+EBewZ2CAC0lUIEBZZMxrFsYQwQdIyWVDmuo5HrCVS53RtuhjEo5UAD7OuG2svjaAV468Y0r1SrMxkusGquZAFcyWpjrCYtV1YOs2J4PTtotZHRelPim7CSiQ341aBOw9D7bNw2A5sv/lrFJXmT+OoChK1po6JCaShhsrpum4m8kIzwxeQB+yX3PbUIqBJAfVIdVicPvOZ9PK9BA1oayODNoXPH06C//DWlBCrBC9viA4oGpck9mEso5NIPAXdKW1xZ4W/4Ut+JQIUXqBZG1Ba6RTNbGEarxUtrRlpPnm/t+mTQT4pSz6kLqb+I1VtUGqwIZD0BHSOBP+tDE8empoSnduBK6JVaLy2PCUSNlPhZYct/d4kxkNldKIM/4AGjtgsduClnbB2If9tA/6UiNEFcyNfRqfxI+gaFg5BWqGBep4ygVcn4AM0TngQ5q2gCRBJGGpJtAD6yEMvlZqCZu48lecBSs9F5gJVixaibehDD6ENzZhZVn8TpelDHFuxXt5BXEZS0ToT6hGwUecgWyveGIzcUoYA7lr4da81QWTMTFh6tz9cTRY2WWPuVvagQAoloEaPoDBgzBqZNCaqL/wvPMLHE6VI2ahJCHDDynWRNEXpatvoqppYy0z25bDaRjIuOApcuUsMZBDiRVKAHxA4spBfKrWK6dKSdnWTijt+1b4hLVIu/oM9Z8a+4dMusBMTSeuyYKBIQp+CWdJORdt5n2fAHwhAxM08xHqVbm/kPq6SiRkhRuqowsCadYjL8hsya/QUJheIXVhXsnPqdaiLmPxBkET/qOvOTehf56FgFsoVwChIy/wqLV+pRMpnI9xypHspVPSpQ8lSAVssH+YlU+i53aUUMpzlRSGL6oFXq8UTSDiMBrnCp4gqUY9WVrd7VIjSPWikS4k1hDJr0HwANoOtG5pt1Ga+rkNKhdkID+CSbHYVKQQgzIZexiApbVFlXIAu3RHKRPFpobRU5toD74Fs4F1WHhP5eUop2UbcoR0cMkFSBk0MwFH8/bShyfZ4pjTBLPtK41DfT05QlhYECKWQiUJaUO7jWQiUGy83zQOz+YcCTbyxeBhEC7XDpMLUToH0G2W6IGYKCmiRvkzMGw1JvsWVkDq5gU2mbgnvIwr6pgyT9hpFOeQfjgQ8SWLF828UFSrLoOZWiqNRzdYAGPlosgmrQ4qweaHyYJ4rwn0gDG8EvbpDeomhBR8GslDMgcoGvcqphA3FRXWghwhJ4ENG8OmQwOdwL74ZaplZ05iIZUibBu83pThOg0LJ2lT77TIlFkvdRIDa3XAIEACOxEv38euVoCvUEryBWOC31xqHHjzhXIccQmJeaGogsTFTQDi9AjpD2doGpw4REgaW0H2gFVAMdRSBmzFVbNIIzBg1gge4wBRwvheoRX8sgAlQHiigm5SXpnRS84+KFiImAriSH0h71Nw+m8qOHYjTA63dN0DCXV+nIVaHntERr9LjKNqcEQFPYRgYjMrCVlXGXQ55PeRosSNv6wnoWkX+8PUN0QPDCkaFCnrDR0yXiJJb3mPaTBIKXXMgNAlZMDLNXDp/WNrrrBGBlJgrSo0EIdlTEqzS28Do0ekEtjY1IBuneHJw/QgLwtOz/qN6znosdxG11CNca/NCTrgG3e3pAzqSZTbF4Bh3WViI4+nsc4mDl+HpIK8kUJMeQz5CT9yTGxBi8Pq1ENDCmslWb7mSuyTuh7mxITUg0IDGcPZCu5KsjTfliqv6xuiwXsCK+cBbcAt2Vjus2mTr9Gry2KwOguO5D8R5cQ1NxQBnUI+vNUTHcHpltbjkBnmj4PBKyASKEnkMcFJ82Zl0Kr6gcglBx5GmvsTBAKdQZDH/TolTwmNQzAli7NKcHtkNheKoyMXNjopQY+F4kXryUtinQWNkKhChADyJOx9ivqo6GbMH3mDqKFW0K3o3ILmpo0jsE3lInRFyMSB6gYG0jOlQqh/IC+fGHOAOBEBLIyONYtHqZ4qdm+fiCAIxQpGcZyIOUn2peJc1wbjB5moLlk8ecCHQ3gG3ESVgSgbt8PZqRPfk04XmoH7/oihR/I5sqFXuiRUAK3opgC3tC0UizydyrsjHJZGOzj9cEGnNCdSiTm2g1KjEHToDYNjVtGgC7Cl2bKFDKTk+BYJD7R1yXJKF8pkOYERfAfwEep5z354RdsOehIEABkL50G6wC3gTgpS8PAvzNHgSvOxcFxxYXIJESmGxYbSD+wJ+6S7iXHPWtkylxc/SlsIWYiDUBwnuWDApE+Qlje56yFTGFQVRUUQYxRCHhOAiIrzDRUvuhfnge5rPqoe9tF2EI5DXgNn6diAK1EYmfIWDAw4iFfi4IvatM0d4DXuBwKcD2sHxoLJQ4iQB+iHPJiHYpnfadgEAQF7rYBSmr1L9irBU/00ZvwsdIFVgMaMFznrbBpH+lu8LPpoRVqcZAhfobOIjMFnwJMUUYgXrUTxWcYpDch5I7fhEXrSqfO6E6KEXnklwr14JH+oApQYDglgIVoCRXiTQseIwjo7gkrQWN0dk2MCfSIIDwyAr9FExxytDwFVSFEKQDadcqFWZHeIDLEGrSNaoAAmTSRckTinkhP6mhsFtbBbVXCTCrFVPtCHpTi4MHYNZMCKj1iH9MR9FAdr4dVNz2c5puYibw8PGhJ42jFzVBhdsyJxo26MNI3yFxkg6KCBlLL6SIcQP09zaTWQty2UdeIDpSLvzbpHi1PbY0t4etEMyWVvSAQb5v03DAwa2CyqYcK+LX+H2rhPS4qljjEIYR6c66NAkqVoLfgfeBhwAZB1g2CaXh/YlPDoaQbaQNmxjaY4lyLs1+SFPxVb5VmRul5NlBZOR4SrAPkhnFlAgyVB7yWt0KEPeDCS50ID8RMdRoqaJi4eAzdy145GmkEhE9MwiZoub31TO6lOmkrYndGX66VBgfstfRBQEkk42DeqEIaFXEXeuGH58PJqt142sDTcnbDs5Pn5olyBqa1LGD0MbMAkZ0RICXin7jV9G/UOMD8FWUWui0aHS9LbHwPyq06UM/EB9IK5jqdgmYat2vJA6TXU1m5gkkd0cvY65MBIFcRSLBydYEXGT8+zlar8Esabtw9ze1iRmM442QgCZrqFNJZEAbml27PBE3pwhapCVZpoJVmsmjINahztTUI/SQNUj8HDJeBmsDSoBAgbG4BhcEDzaqPYAoCHcADGEOBnW1nSl/485X7gdqRoCACwXvU+PgsVVuUX0z5rLMrQXUp/mloYfI5+tDStoGTQroDKyppIRorcKfoweD2FhjqlOrG+ReeD+XfSDaOb2Vzfbm+IgqSQR74smQrnrVFRMQ7iRCaS7Ju3FQh6Fe+Op4rgfS1akd0gACWm42adKjtemedSK3OthXlQz1HKuXd8Uod09BlGN/7actf8EXMLGZ4eD9KSx6G2xLt4fRLfh3h78G+rfe/5PDzQ7qh/Zj+FFEtVN/iDQUgEO2g2HhkwqKCx0A8WXAsof1NH+Trl0JOQN9aH0e6CKAG8kRJiUBEnFaOhUHnoi2zWli5NvyF7ShxtBsOPhBVCDFOxOUaMOB3rkgMX1MLhgdt352d1gsPRRRNCH3Ix/+3agcHFYsJUhDfwKLOCl1/DE2rGBuZCCE2I72hPQ4WwXop9VqzjXZOhim1hr4BwYwQjImnXtaqEYZBk7zNAjv2t3H9rvhv86tBtsTmMgzoySoE2w2EA3PdvctB48lm0AY6IvyCPNV25eewWz5Lc5B7JReQBdwdtEL/1DT8BnOrIAJSOVTcHCmtryn4glbwG+A5/gSpw8uI+bpLci3jNnOhbiRKz3Z7IyUrH6DNZvlL+ggklstPe4URArNYXAhHXQuwIfrHZVTMhke7gJ8Zj2GwkuJEm/N3e4DRYQ7qwbJOjauj6QSQLjHyXqQPzUGHFwkublFPK6KpIdZqbE8MgxILTwEg1qRulrx6RhZhEBrSEH/SZxj1p1qIY0wUwVlL7nxtQcEHCr9oNELjm5MbTXnDfNiJDQmTrxnga4XPhTOyhLWiGcnqW0iUmWutJHAFc/HxhhcQE2KbhgZhcZd/MiRBuqgaqJJbOeHhuwb8loGR3VIKoD9A2yrbcvQjVQx9c920l5nIKAifdt8tBPaPSgMyAmiBZG3NELqFgULZKROSHskM/RI/LJLLSAYqOq9SUK7GBf320HRL5TUGhxosuzTh/gvnPpnGKqHcQYmD/Jxb9yTnvQ5IJZ6h3ORZTDIxgxHIl2sZAH0cGHsCfWiDUi2OiKj4ixTdIWnkAbHxAQikPb/9uqGDfOqDMbunoYNYUJdcg1/CKBGoVbAq0F1w8YSLMjUSV1aBSibPydN9DHqAmEAj2orR3URaG+vfM6cNJesYnUdMq0tPeN9kboVnFrx/6PjHhcOtQraiCMGlpEdSG9ijCMyYlAisefgl0T3tQ2TN06D0WHaaPY6HXA8erQU67FSyzR9qoDElFtLQSlOewdYRF2aRN/JKNmdVdKaGJ0aBPEVcGSgS+pZpTtQnDQUmgdaI8lIsNgEnfoIB1rYX6I+r6Yg4Mo0BlN3tr5XxM13SuYC4PDT75hyYRKd5j2RQzjUi057ZTv5nXkh/JB9qKVpY6hdn3ThFEfoyNypMBxoagi7TJp/4XMw4ZQHWLYyQLpS3B4odU/h0tqyqbdY9RZbNqxnPrKjpBsy9Qtqgm2pBJieRt62OHtpg4+tOtNO1HZdSaAH9uQkRhwimpI3/O7Oap6EDtbEBwqqyeQuA1EYLkTfaSiCJ1OZjFkeOsk4UoYb0xn0GY2AjZ4WRlcwXg7+okQP6+rr95tQo2seWLtVpT1AGqHPANq/RNIfdGHoIHICGAIkgr2b3MIEJrqfQwDmHwrCtBl8Z+EIVKAnOmALzJTmTT4BGH0pPoE+fRNQJ0ulFdkyzN3w6no1JbZY/woCHQzfnRDOkGWgcRPRO9lSQtIpof62zlROKfO23TGgIaClHUzCJDKhodRZ5MYoK5hQeZ+SoVILwV8tKuGaH6VFielODLOtWpfCZSi3oxC0/cPweyuA5h66EUwSbuiLF0nD+DkFQi9Y0iAtS/tdt1IOxn1drAwOtXvb1+8TwdPlSFeGBlfCQdK6mlvBIPMGjt1SFyL9u6STtjHHPcllkCnghkSGM+KFdV3D7QlSjkO4J7SRcuSXj6d3jbK8zcJdXP0aTlc4HVL4sMqOF/WjdZ3rYGqgAgsPiGEjPZBGeNQnhfQLkXGaEHoyPbZX62hsZ/mJANIengXyTNc1tcsoH4dsxZWRZR0FIICCDTIX/9mjPubvqPzz0D/3wdKgFB3/wtcE3QksSKtewAAAYRpQ0NQSUNDIHByb2ZpbGUAAHicfZE9SMNAHMVfU6UiFaF2EHHIUF20ICriKFUsgoXSVmjVweTSL2jSkKS4OAquBQc/FqsOLs66OrgKguAHiJubk6KLlPi/pNAixoPjfry797h7BwiNClPNrglA1SwjFY+J2dyqGHhFECEAYwhJzNQT6cUMPMfXPXx8vYvyLO9zf44+JW8ywCcSzzHdsIg3iGc2LZ3zPnGYlSSF+Jx43KALEj9yXXb5jXPRYYFnho1Map44TCwWO1juYFYyVOJp4oiiapQvZF1WOG9xVis11ronf2Ewr62kuU5zGHEsIYEkRMiooYwKLERp1UgxkaL9mId/yPEnySWTqwxGjgVUoUJy/OB/8LtbszA16SYFY0D3i21/jACBXaBZt+3vY9tungD+Z+BKa/urDWD2k/R6W4scAf3bwMV1W5P3gMsdYPBJlwzJkfw0hUIBeD+jb8oBA7dA75rbW2sfpw9AhrpavgEODoHRImWve7y7p7O3f8+0+vsBcEhypl5zelkAAA0YaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOmVlODc0NzUwLWYyMTgtNGZhYi04ZmVkLTk3YjdiNTRlMTRmOSIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2ZjJlY2IyYi1lZDdlLTRiNDktYTlkZS03YmRlNTNlOWVjZDciCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpjNDQ3M2M4Yy02MmJhLTQyYjctYWQ0Yi02MjE4ODNiOTM5NDgiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJXaW5kb3dzIgogICBHSU1QOlRpbWVTdGFtcD0iMTYzOTc5MDc4MDQ5ODI0MSIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjI0IgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAgMi4xMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjYxMDQ5ZjkxLTE0N2ItNDJjNy1hYzRhLWMyNmU0ZDIzZmEwNSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0xMi0xN1QxNzoyNjoyMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4gG/WSAAAABmJLR0QAnQCdAJ2roJyEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QwSARoUHogWFQAAB8dJREFUeNrt3Wtu4yAUQGG36hadRbqLzPxixDCAwYbESb4jVWqbGGPMubz8+Lrf7/cF+FC+FQEIABAAIABAAIAAAAEAAgAEAAgAEAAgAEAAgAAAAQACAAQACAAQACAAQACAAAABAAIABAAIABAAIABAAIAAAAEAAgAEAAgAEAAgAEAAgAAAAQACAAQACAAQACAAQACAAAABAAIABAAIABAAIAAIABAAIABAAIAAAAEAAgAEAAgAEAAgAEAAgADAa/OjCN6L39/f4v/WdV3WdVVIBHjfyn+73arfIYAu0FujghPgoyv/tm3L/X4ngi7Q47sfcf9bf7tcTr3lkpYrAV5kAEqAf/n6+vr7+/1+7x7XhPIcWa66QJMqP9plONrKEoAAHzfGGd2qEkDlfxjbtmV/bxnYzxLgZ1ZlyFWKnj5cvH2pgp3tE7bktbbf2vZH0m1p6mcNrvckHrHPdV2b+/4jtmviPoht2+7rut6XZdn9Wde1mk5LGml627ZNyWsp70fzuZev1rT2jjd3fLX97+3vXfkZFT3iFcg0SqURLXy/pxncS+/393fZtm03UuVWS+P0c9H3EbM5t9utOI2ay1Mov1F5W9f1pbpyoUxOt4gjIn9LZGqNSGl6pahVipa9kbE1D6V0S61J2KalZYq3H3W8vS1AqWx6WtZcnlvLYC+dUpmfTftnRORqiZa5CNMScWrpldIsbdMa3dO0w3a5fmg6HhjZ32853tERNR6kjmhd0pY6bclz+6hd0Dd84uGMPS3RdK+fmbO7te+Zi4q1POSiYi2yt6bdm49amdQiWs9+elqA9Ltno2qtdVzX9e9PLn+946qnjgF6LWyJYGf7dLX0j0bpWdOdI9I7m0Y89ghlP3JckUb78L9SzyEeF+a+k7ZST5sGPVuZWueL33mufmYZtnZ54so/o9xrXcQrDMy/r1gJrsroytnS151RhmEmbHblz5VdOtuVW5NJ5ZxZV4a2AHs3YzxTmtrA+BkXrZWOYXYZ5qaB4ynF2ZW/duy5aeCQr1mB8vJXg8aR4Gwh9MwaPbN78oiyvEIgSMcIj2h1p48BRmW45fa+UQLcbrfdhaeRi06jxz+9+aqVw6yuUG4xc9u2/1qfNNiF7tmM+nBqGnQ5sAh1dHp1SRaWwn5Ki0OjL4PYO64j06BH8n62DJeGSzlGncNa2Yd9x/8rTY3G57p32r2pHl9NgLNz9a2VaE+CnlXQVxEgzdOR1eKRVw2kK8apBOk5yEnwtHWAGQOT0krt6K5HmIkopf0pd3Jt2/bfjSmzB8R7U6Xp73E+wt9xns/m9Xt0Bb761GNp4Wf0ItCrTAvn+vylqcrZ57I1qF7ilsjWmZMrnfx04eeZlb02LfvofMw4l5UxZ5MEtcH4ZQWYMY/de2nDXvR/ZmVrib4z7ns9GsyeUT49U95DHv8yclDTM5DKXSbbOjDcm8nJDV6P3MCyNF7WfGZGpXQcLdseuUR7xjEcGaDvXVi4dwn6qHwtM2YbSlOX6YlpFSBOJ92+Nt2Xpn9EgOXEHVXp8bfce9BSfvExH5G8VLl6g8rZ6dC9qdJHsMyY3jpzElrSirfdq0AjWoHlxA06LdOcR9YmcuV39pbK2vYjK2Q41tnRvYWv+8C7jUuXLaQ3r7fctlgbtKbb58Ydpe+WLrTq7bvv9ZvjfLcOutNtj5Rh63H1bj/jQsDa4PthExT3DyOOci0rvLNWIPFGN8W/Culj9lrmpa8yY4Q5fH9i5e9tYj3olgBvIcDMPi0IcOnKP3KVmjzvw0eMAXIVNtwD0DIjMuNxIbgGQ6dBX2kMcEQiYwECvMU4oKdLpOIT4KMGx/r5BAA+Bi/IAAEAAgAEAAgAEAAgAEAAgAAAAQACAAQACAAQACAAQACAAAABAAIABACuzSUejPUujy0Mzx2a9bLpUrl5gsULtwDx8/rDT+sDrKa9Pfwi++spt0869rdrAR4ZNd/lGMILJp7xXl8CPKlLUYp2cWTatu3v97Zty74PII1kacXNPUY93m9pf7n04meQhu/En599OXju3bq1/LR+FvKQfj899r00CXBgHBA/tDb+f/z28PRk5frCofLFUTKNlqFpDyctFqYkQel1RaWuSLxdvL90X719+pqcpQcClz5LW5I4iNSOvZYmAU4OhOMKk5MjlqJUQeJ00hOV7rM2iN3b354EaaTNRfvWrkxuH7lta2nl3p3WIlpPmgQY0H+OI2Vv01qK4ld4EXXcIvS+eyD32PZQOUN5xemGcqt91iJC7fzU0iTAgHFA+P1s4cbdqNx44NGt3pknT7e0Nrfb7Z9yq312NC+1NPda1qOffcQYII0oIdKUmu/Wk5eLoGkfPdd6lPZXer1pb3em5/u5gfvejFB6XC1C7R37XppagAMChMFXejLTQWyuAu5Fi7jJLg0+cwPs2v5yszAtFTrtArV0IWpdlHignxtj1D7LzWa1HHstzVfA49Gf3L3LTUO+w5qIFgDNEuzNIEEL8JbkuhxWdAkAPAyXQ4MAAAEAAgAEAAgAEAAgAEAAgAAAAQACAAQACAAQACAAQACAAAABAAIABAAIABAAIABAAIAAAAEAAgAEAAgAEAAgAEAAgAAAAQACAAQACAAQACAAQACAAAABAAIABAAIABAAIABAAIAAAAGAZVn+ANVuB8euXCQKAAAAAElFTkSuQmCC"; + public static final String enableScreen = "iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAC4jAAAuIwF4pT92AAAEAklEQVR42u2dvXbjIBBG7T0+xw+gTp06v//LmE6dO/VR5a3wGZNh+BGSFeveJgkIBrDy8TGKds8/Pz/PExyW8/P55AY4MP9YgmNzmeeZVUABAA8AKADgAQAFADwAoACABwAUAPAAgAIAHgBQAMADAAoAeABAAY7LOI7fpQDX65VPtZCt18w5d7rdbigAbOgBxnE8DcPwJnnDMCTrNJlsUVcizTnj9HWxeVvINfN9y361OdTEk30551ZZt3PsvYDYxOSChoPQ6sJ21mRLBm61jY0lpy61gDKWNdfcNcv5wErWLbfPF88I9/s9WtayzopXS85YtPqcMeT23SqedV1pucal1V4iTUooV/IaWSfbWHU5JmkvpmzrsayaB9DqfJnVTpMff72sc869/WzVlcjjOI7mOOVYfBzfT05exLfT5pqae008a71Ly6tPASV79CfPylvFjpm+teLH+tXiF5nA2LOAUMpCibckWpPBUOJT20btFuDjyK8p+S45Z4fX+ti+LDb3pef62PosWbfkDbBW8mFPhB/gt8Vr7gG+kZK9+C/GM2+ArffnnKRHbT5gSdJoK0+ydrziGyCW115LolLxnHOr59q3lt89b6U8Czg4pgdI5bUtKY3VzfOclGBtTLVSmmqn1cdyC7Iud+5791KX1MLJDz3Mg2s59pK6sM/asdTmLrRx5pzjS+e+awWw9lstVeuv1/a10rqwT8sn5LQr8RzaMVfmKrR2qfnFjs57/puLS0nyoTZp0fL8XGq+ap8v4AES+3Msx74kN2/tmblewWoXPl9o+RykZH5/5hTQYv+y+vj084XcPHpJbHmt1s7yGbV1q+UBnHO/gnoZje2RmuzK/Vr2F3sWEF6TGkvutqH5CG08qTmk5u77tLyK5Qtq62rgxRA8AO8FHBkygQeHLQAFADwAoACABwAUAPAAgAIAHgBQAMADAAoAeABAAQAPACgA4AEABQA8AKAAgAcAFAC+3gNM03Tqum7VQSyN4dtvMdZDKcBWC9oqhr8JoIEHeDwep77vf5VJfL0vl9fLa/u+f+vPfx9eszSGNXZo5AH6vlcXW36gsqykrzViwAIPYL3r3nXd63v5m6i9J2+VaT8viWGNHZQbYE97+KdjHPIGKH0XPSyL7eXSjPk2YZlsN03Tq21OjLAs598ZggIT2MpMbW3IMICFN0Dsv4xpfUbfAvIAK9wAcOAtAMgDwJHzAIACAB4AUADAAwAKAHgAQAEADwAoAOABAAUAPACgAIAHABQA8ACAAgAeAFAAwAMACgB4AEABAA8AKADgAQAFADwAoACABwAUAPAAgAIAHgBQAMADAAoAeABAAQAPACgA4AEABQA8AKAAgAcAFADwANCe/0of1jQ8XY5YAAAAAElFTkSuQmCC"; + + private static BufferGL vbo = null; + private static ProgramGL program = null; + + public static void paintScreen() { + + TextureGL tex = _wglGenTextures(); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + EaglerImage img = EaglerImage.loadImage(Base64.decodeBase64(loadScreen)); + IntBuffer upload = GLAllocation.createDirectIntBuffer(192*192); + upload.put(img.data); + upload.flip(); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGBA, 192, 192, 0, _wGL_RGBA, _wGL_UNSIGNED_BYTE, upload); + + upload.clear(); + upload.put(Float.floatToIntBits(0.0f)); upload.put(Float.floatToIntBits(0.0f)); + upload.put(Float.floatToIntBits(0.0f)); upload.put(Float.floatToIntBits(1.0f)); + upload.put(Float.floatToIntBits(1.0f)); upload.put(Float.floatToIntBits(0.0f)); + upload.put(Float.floatToIntBits(1.0f)); upload.put(Float.floatToIntBits(0.0f)); + upload.put(Float.floatToIntBits(0.0f)); upload.put(Float.floatToIntBits(1.0f)); + upload.put(Float.floatToIntBits(1.0f)); upload.put(Float.floatToIntBits(1.0f)); + upload.flip(); + + vbo = _wglCreateBuffer(); + _wglBindBuffer(_wGL_ARRAY_BUFFER, vbo); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + + ShaderGL vert = _wglCreateShader(_wGL_VERTEX_SHADER); + _wglShaderSource(vert, _wgetShaderHeader()+"\nprecision lowp float; in vec2 a_pos; out vec2 v_pos; void main() { gl_Position = vec4(((v_pos = a_pos) - 0.5) * vec2(2.0, -2.0), 0.0, 1.0); }"); + _wglCompileShader(vert); + + ShaderGL frag = _wglCreateShader(_wGL_FRAGMENT_SHADER); + _wglShaderSource(frag, _wgetShaderHeader()+"\nprecision lowp float; in vec2 v_pos; out vec4 fragColor; uniform sampler2D tex; uniform vec2 aspect; void main() { fragColor = vec4(texture(tex, clamp(v_pos * aspect - ((aspect - 1.0) * 0.5), 0.02, 0.98)).rgb, 1.0); }"); + _wglCompileShader(frag); + + program = _wglCreateProgram(); + + _wglAttachShader(program, vert); + _wglAttachShader(program, frag); + _wglBindAttributeLocation(program, 0, "a_pos"); + _wglLinkProgram(program); + _wglDetachShader(program, vert); + _wglDetachShader(program, frag); + _wglDeleteShader(vert); + _wglDeleteShader(frag); + + try { + Thread.sleep(50l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + _wglUseProgram(program); + _wglUniform1i(_wglGetUniformLocation(program, "tex"), 0); + + int width = getCanvasWidth(); + int height = getCanvasHeight(); + float x, y; + if(width > height) { + x = (float)width / (float)height; + y = 1.0f; + }else { + x = 1.0f; + y = (float)height / (float)width; + } + + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + + _wglViewport(0, 0, width, height); + _wglClearColor(1.0f, 1.0f, 1.0f, 1.0f); + _wglClear(_wGL_COLOR_BUFFER_BIT | _wGL_DEPTH_BUFFER_BIT); + + _wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y); + + BufferArrayGL vao = _wglCreateVertexArray(); + _wglBindVertexArray(vao); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglDisableVertexAttribArray(0); + _wglFlush(); + updateDisplay(); + + _wglUseProgram(null); + _wglBindBuffer(_wGL_ARRAY_BUFFER, null); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglDeleteTextures(tex); + _wglDeleteVertexArray(vao); + } + + public static void paintEnable() { + + TextureGL tex = _wglGenTextures(); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + EaglerImage img = EaglerImage.loadImage(Base64.decodeBase64(enableScreen)); + IntBuffer upload = GLAllocation.createDirectIntBuffer(128*128); + upload.put(img.data); + upload.flip(); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGBA, 128, 128, 0, _wGL_RGBA, _wGL_UNSIGNED_BYTE, upload); + + try { + Thread.sleep(50l); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + _wglUseProgram(program); + + int width = getCanvasWidth(); + int height = getCanvasHeight(); + float x, y; + if(width > height) { + x = (float)width / (float)height; + y = 1.0f; + }else { + x = 1.0f; + y = (float)height / (float)width; + } + + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, tex); + + _wglViewport(0, 0, width, height); + _wglClearColor(1.0f, 1.0f, 1.0f, 1.0f); + _wglClear(_wGL_COLOR_BUFFER_BIT | _wGL_DEPTH_BUFFER_BIT); + + _wglUniform2f(_wglGetUniformLocation(program, "aspect"), x, y); + + BufferArrayGL vao = _wglCreateVertexArray(); + _wglBindVertexArray(vao); + _wglBindBuffer(_wGL_ARRAY_BUFFER, vbo); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglDisableVertexAttribArray(0); + _wglFlush(); + updateDisplay(); + + _wglUseProgram(null); + _wglBindBuffer(_wGL_ARRAY_BUFFER, null); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglDeleteTextures(tex); + _wglDeleteVertexArray(vao); + + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/GeneralDigest.java b/src/main/java/net/lax1dude/eaglercraft/GeneralDigest.java new file mode 100644 index 0000000..0ebbb07 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GeneralDigest.java @@ -0,0 +1,124 @@ +package net.lax1dude.eaglercraft; + +/** + * base implementation of MD4 family style digest as outlined in + * "Handbook of Applied Cryptography", pages 344 - 347. + */ +public abstract class GeneralDigest { + private byte[] xBuf; + private int xBufOff; + + private long byteCount; + + /** + * Standard constructor + */ + protected GeneralDigest() + { + xBuf = new byte[4]; + xBufOff = 0; + } + + /** + * Copy constructor. We are using copy constructors in place + * of the Object.clone() interface as this interface is not + * supported by J2ME. + */ + protected GeneralDigest(GeneralDigest t) + { + xBuf = new byte[t.xBuf.length]; + System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); + + xBufOff = t.xBufOff; + byteCount = t.byteCount; + } + + public void update( + byte in) + { + xBuf[xBufOff++] = in; + + if (xBufOff == xBuf.length) + { + processWord(xBuf, 0); + xBufOff = 0; + } + + byteCount++; + } + + public void update( + byte[] in, + int inOff, + int len) + { + // + // fill the current word + // + while ((xBufOff != 0) && (len > 0)) + { + update(in[inOff]); + + inOff++; + len--; + } + + // + // process whole words. + // + while (len > xBuf.length) + { + processWord(in, inOff); + + inOff += xBuf.length; + len -= xBuf.length; + byteCount += xBuf.length; + } + + // + // load in the remainder. + // + while (len > 0) + { + update(in[inOff]); + + inOff++; + len--; + } + } + + public void finish() + { + long bitLength = (byteCount << 3); + + // + // add the pad bytes. + // + update((byte)128); + + while (xBufOff != 0) + { + update((byte)0); + } + + processLength(bitLength); + + processBlock(); + } + + public void reset() + { + byteCount = 0; + + xBufOff = 0; + for ( int i = 0; i < xBuf.length; i++ ) { + xBuf[i] = 0; + } + } + + protected abstract void processWord(byte[] in, int inOff); + + protected abstract void processLength(long bitLength); + + protected abstract void processBlock(); +} diff --git a/src/main/java/net/lax1dude/eaglercraft/GuiScreenEditProfile.java b/src/main/java/net/lax1dude/eaglercraft/GuiScreenEditProfile.java new file mode 100644 index 0000000..c1402f8 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GuiScreenEditProfile.java @@ -0,0 +1,463 @@ +package net.lax1dude.eaglercraft; + +import net.lax1dude.eaglercraft.EaglerProfile.EaglerProfileSkin; +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.GuiTextField; +import net.minecraft.src.NBTTagCompound; +import net.minecraft.src.StringTranslate; + +public class GuiScreenEditProfile extends GuiScreen { + + private GuiScreen parent; + private GuiTextField username; + + private boolean dropDownOpen = false; + private String[] dropDownOptions; + private int slotsVisible = 0; + private int selectedSlot = 0; + private int scrollPos = -1; + private int skinsHeight = 0; + private boolean dragging = false; + private int mousex = 0; + private int mousey = 0; + + private boolean newSkinWaitSteveOrAlex = false; + + private static final TextureLocation gui = new TextureLocation("/gui/gui.png"); + + public static final String[] defaultOptions = new String[] { + "Default Steve", + "Default Alex", + "Tennis Steve", + "Tennis Alex", + "Tuxedo Steve", + "Tuxedo Alex", + "Athlete Steve", + "Athlete Alex", + "Cyclist Steve", + "Cyclist Alex", + "Boxer Steve", + "Boxer Alex", + "Prisoner Steve", + "Prisoner Alex", + "Scottish Steve", + "Scottish Alex", + "Developer Steve", + "Developer Alex", + "Herobrine", + "Enderman", + "Skeleton", + "Blaze", + "Barney", + "Slime", + "Noob", + "Trump", + "Notch", + "Creeper", + "Zombie", + "Pig", + "Squid", + "Mooshroom", + "Villager" + }; + + protected String screenTitle = "Edit Profile"; + + public GuiScreenEditProfile(GuiScreen parent) { + this.parent = parent; + reconcatDD(); + } + + private void reconcatDD() { + String[] n = new String[EaglerProfile.skins.size()]; + for(int i = 0; i < n.length; ++i) { + n[i] = EaglerProfile.skins.get(i).name; + } + + this.dropDownOptions = EaglerProfile.concatArrays(n, defaultOptions); + } + + private GuiButton button0, button1, button2, button10, button11, button12; + + public void initGui() { + super.initGui(); + EaglerAdapter.enableRepeatEvents(true); + StringTranslate var1 = StringTranslate.getInstance(); + this.screenTitle = var1.translateKey("profile.title"); + this.username = new GuiTextField(this.fontRenderer, this.width / 2 - 20 + 1, this.height / 6 + 24 + 1, 138, 20); + this.username.setFocused(true); + this.username.setText(EaglerProfile.username); + selectedSlot = EaglerProfile.presetSkinId == -1 ? EaglerProfile.customSkinId : (EaglerProfile.presetSkinId + EaglerProfile.skins.size()); + //this.buttonList.add(new GuiButton(0, this.width / 2 - 100, 140, "eeeee")); + this.buttonList.add(button0 = new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done"))); + this.buttonList.add(button1 = new GuiButton(2, this.width / 2 - 21, this.height / 6 + 110, 71, 20, var1.translateKey("profile.addSkin"))); + this.buttonList.add(button2 = new GuiButton(3, this.width / 2 - 21 + 71, this.height / 6 + 110, 72, 20, var1.translateKey("profile.clearSkin"))); + //this.buttonList.add(new GuiButton(200, this.width / 2, this.height / 6 + 72, 150, 20, var1.translateKey("gui.done"))); + } + + public void drawScreen(int mx, int my, float par3) { + StringTranslate var1 = StringTranslate.getInstance(); + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 15, 16777215); + this.drawString(this.fontRenderer, var1.translateKey("profile.screenname"), this.width / 2 - 20, this.height / 6 + 8, 10526880); + this.drawString(this.fontRenderer, var1.translateKey("profile.playerSkin"), this.width / 2 - 20, this.height / 6 + 66, 10526880); + + mousex = mx; + mousey = my; + + int skinX = this.width / 2 - 120; + int skinY = this.height / 6 + 8; + int skinWidth = 80; + int skinHeight = 130; + + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336); + drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xff000015); + + this.username.drawTextBox(); + if(dropDownOpen || newSkinWaitSteveOrAlex) { + super.drawScreen(0, 0, par3); + }else { + super.drawScreen(mx, my, par3); + } + + skinX = this.width / 2 - 20; + skinY = this.height / 6 + 82; + skinWidth = 140; + skinHeight = 22; + + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336); + drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 21, skinY + skinHeight - 1, -16777216); + drawRect(skinX + skinWidth - 20, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216); + + EaglerAdapter.glColor4f(1f, 1f, 1f, 1f); + gui.bindTexture(); + drawTexturedModalRect(skinX + skinWidth - 18, skinY + 3, 0, 240, 16, 16); + + this.fontRenderer.drawStringWithShadow(dropDownOptions[selectedSlot], skinX + 5, skinY + 7, 14737632); + + skinX = this.width / 2 - 20; + skinY = this.height / 6 + 103; + skinWidth = 140; + skinHeight = (this.height - skinY - 10); + slotsVisible = (skinHeight / 10); + if(slotsVisible > dropDownOptions.length) slotsVisible = dropDownOptions.length; + skinHeight = slotsVisible * 10 + 7; + skinsHeight = skinHeight; + if(scrollPos == -1) { + scrollPos = selectedSlot - 2; + } + if(scrollPos > (dropDownOptions.length - slotsVisible)) { + scrollPos = (dropDownOptions.length - slotsVisible); + } + if(scrollPos < 0) { + scrollPos = 0; + } + if(dropDownOpen) { + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336); + drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216); + for(int i = 0; i < slotsVisible; i++) { + if(i + scrollPos < dropDownOptions.length) { + if(selectedSlot == i + scrollPos) { + drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x77ffffff); + }else if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i*10 + 5) && my < (skinY + i*10 + 15)) { + drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x55ffffff); + } + this.fontRenderer.drawStringWithShadow(dropDownOptions[i + scrollPos], skinX + 5, skinY + 5 + i*10, 14737632); + } + } + int scrollerSize = skinHeight * slotsVisible / dropDownOptions.length; + int scrollerPos = skinHeight * scrollPos / dropDownOptions.length; + drawRect(skinX + skinWidth - 4, skinY + scrollerPos + 1, skinX + skinWidth - 1, skinY + scrollerPos + scrollerSize, 0xff888888); + } + + int xx = this.width / 2 - 80; + int yy = this.height / 6 + 130; + + if(newSkinWaitSteveOrAlex && selectedSlot < EaglerProfile.skins.size()) { + skinWidth = 70; + skinHeight = 120; + + EaglerProfile.EaglerProfileSkin eee = EaglerProfile.skins.get(selectedSlot); + + EaglerAdapter.glClear(EaglerAdapter.GL_DEPTH_BUFFER_BIT); + + skinX = this.width / 2 - 90; + skinY = this.height / 4; + xx = skinX + 35; + yy = skinY + 117; + + boolean mouseOver = mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight; + int cc = mouseOver ? 0xFFDDDD99 : 0xFF555555; + + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + drawRect(0, 0, width, height, 0xbb000000); + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xbb000000); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + + drawRect(skinX, skinY, skinX + 1, skinY + skinHeight, cc); + drawRect(skinX, skinY, skinX + skinWidth, skinY + 1, cc); + drawRect(skinX + skinWidth - 1, skinY, skinX + skinWidth, skinY + skinHeight, cc); + drawRect(skinX, skinY + skinHeight - 1, skinX + skinWidth, skinY + skinHeight, cc); + + if(mouseOver) { + drawCenteredString(fontRenderer, "Steve", skinX + skinWidth / 2, skinY + skinHeight + 6, cc); + } + + this.mc.renderEngine.bindTexture(eee.glTex); + DefaultSkinRenderer.renderAlexOrSteve(xx, yy, mx, my, false); + + skinX = this.width / 2 + 20; + skinY = this.height / 4; + xx = skinX + 35; + yy = skinY + 117; + + mouseOver = mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight; + cc = mouseOver ? 0xFFDDDD99 : 0xFF555555; + + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xbb000000); + EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND); + + drawRect(skinX, skinY, skinX + 1, skinY + skinHeight, cc); + drawRect(skinX, skinY, skinX + skinWidth, skinY + 1, cc); + drawRect(skinX + skinWidth - 1, skinY, skinX + skinWidth, skinY + skinHeight, cc); + drawRect(skinX, skinY + skinHeight - 1, skinX + skinWidth, skinY + skinHeight, cc); + + if(mouseOver) { + drawCenteredString(fontRenderer, "Alex", skinX + skinWidth / 2, skinY + skinHeight + 8, cc); + } + + this.mc.renderEngine.bindTexture(eee.glTex); + DefaultSkinRenderer.renderAlexOrSteve(xx, yy, mx, my, true); + }else { + skinX = this.width / 2 - 120; + skinY = this.height / 6 + 8; + skinWidth = 80; + skinHeight = 130; + if(DefaultSkinRenderer.isPlayerPreviewNew(selectedSlot)) { + int w = fontRenderer.getStringWidth("1.8") + 4; + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glScalef(0.75f, 0.75f, 0.75f); + drawString(fontRenderer, "1.8", (int)((skinX + skinWidth) / 0.75f) - w, (int)((skinY + skinHeight) / 0.75f) - 12, 0xFFBBBB66); + EaglerAdapter.glPopMatrix(); + } + DefaultSkinRenderer.renderPlayerPreview(xx, yy, newSkinWaitSteveOrAlex ? width / 2 : mx, newSkinWaitSteveOrAlex ? height / 2 : my, selectedSlot); + } + + } + + public void handleMouseInput() { + super.handleMouseInput(); + if(dropDownOpen) { + int var1 = EaglerAdapter.mouseGetEventDWheel(); + if(var1 < 0) { + scrollPos += 3; + } + if(var1 > 0) { + scrollPos -= 3; + } + } + } + + private void save() { + EaglerProfile.username = this.username.getText().length() == 0 ? "null" : this.username.getText(); + EaglerProfile.presetSkinId = selectedSlot - EaglerProfile.skins.size(); + if(EaglerProfile.presetSkinId < 0) { + EaglerProfile.presetSkinId = -1; + EaglerProfile.customSkinId = selectedSlot; + }else { + EaglerProfile.customSkinId = -1; + } + + LocalStorageManager.profileSettingsStorage.setInteger("ps", EaglerProfile.presetSkinId); + LocalStorageManager.profileSettingsStorage.setInteger("cs", EaglerProfile.customSkinId); + LocalStorageManager.profileSettingsStorage.setString("name", EaglerProfile.username); + + NBTTagCompound skins = new NBTTagCompound(); + for(int i = 0, l = EaglerProfile.skins.size(); i < l; i++) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setByteArray("data", EaglerProfile.skins.get(i).data); + nbt.setBoolean("slim", EaglerProfile.skins.get(i).slim); + skins.setTag(EaglerProfile.skins.get(i).name, nbt); + } + LocalStorageManager.profileSettingsStorage.setCompoundTag("skins", skins); + + LocalStorageManager.saveStorageP(); + } + + protected void actionPerformed(GuiButton par1GuiButton) { + if(!dropDownOpen) { + if(par1GuiButton.id == 200) { + save(); + this.mc.displayGuiScreen((GuiScreen) parent); + }else if(par1GuiButton.id == 2) { + EaglerAdapter.openFileChooser("png", "image/png"); + }else if(par1GuiButton.id == 3) { + for(EaglerProfileSkin i : EaglerProfile.skins) { + this.mc.renderEngine.deleteTexture(i.glTex); + } + EaglerProfile.skins.clear(); + this.dropDownOptions = defaultOptions; + this.selectedSlot = 0; + save(); + } + } + } + + public void updateScreen() { + this.username.updateCursorCounter(); + + if(dropDownOpen) { + if(EaglerAdapter.mouseIsButtonDown(0)) { + int skinX = this.width / 2 - 20; + int skinY = this.height / 6 + 103; + int skinWidth = 140; + if(mousex >= (skinX + skinWidth - 10) && mousex < (skinX + skinWidth) && mousey >= skinY && mousey < (skinY + skinsHeight)) { + dragging = true; + } + if(dragging) { + int scrollerSize = skinsHeight * slotsVisible / dropDownOptions.length; + scrollPos = (mousey - skinY - (scrollerSize / 2)) * dropDownOptions.length / skinsHeight; + } + }else { + dragging = false; + } + }else { + dragging = false; + } + + byte[] b; + if((b = EaglerAdapter.getFileChooserResult()) != null && b.length > 0) { + EaglerImage img = EaglerImage.loadImage(b); + if(!((img.w == 64 && img.h == 32) || (img.w == 64 && img.h == 64) || (img.w == 128 && img.h == 64) || (img.w == 128 && img.h == 128))) return; + byte[] rawSkin = new byte[img.data.length * 4]; + for(int i = 0; i < img.data.length; i++) { + int i2 = i * 4; int i3 = img.data[i]; + rawSkin[i2] = (byte)(i3); + rawSkin[i2 + 1] = (byte)(i3 >> 8); + rawSkin[i2 + 2] = (byte)(i3 >> 16); + rawSkin[i2 + 3] = (byte)(i3 >> 24); + } + String name = EaglerAdapter.getFileChooserResultName(); + if(name.length() > 32) { + name = name.substring(0, 32); + } + if((img.w == 64 && img.h == 64) || (img.w == 128 && img.h == 128)) { + newSkinWaitSteveOrAlex = true; + } + int k; + if((k = EaglerProfile.addSkin(name, rawSkin, false)) != -1) { + selectedSlot = k; + reconcatDD(); + save(); + } + } + } + + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + + protected void keyTyped(char par1, int par2) { + this.username.textboxKeyTyped(par1, par2); + + String text = username.getText(); + if(text.length() > 16) text = text.substring(0, 16); + text = text.replaceAll("[^A-Za-z0-9\\-_]", "_"); + this.username.setText(text); + + if(par2 == 200 && selectedSlot > 0) { + --selectedSlot; + scrollPos = selectedSlot - 2; + } + if(par2 == 208 && selectedSlot < (dropDownOptions.length - 1)) { + ++selectedSlot; + scrollPos = selectedSlot - 2; + } + } + + protected void mouseClicked(int par1, int par2, int par3) { + if(newSkinWaitSteveOrAlex) { + int skinX = this.width / 2 - 90; + int skinY = this.height / 4; + int skinWidth = 70; + int skinHeight = 120; + if(par1 >= skinX && par2 >= skinY && par1 < skinX + skinWidth && par2 < skinY + skinHeight) { + if(selectedSlot < EaglerProfile.skins.size()) { + newSkinWaitSteveOrAlex = false; + EaglerProfile.skins.get(selectedSlot).slim = false; + save(); + } + return; + } + skinX = this.width / 2 + 20; + skinY = this.height / 4; + if(par1 >= skinX && par2 >= skinY && par1 < skinX + skinWidth && par2 < skinY + skinHeight) { + if(selectedSlot < EaglerProfile.skins.size()) { + EaglerProfile.skins.get(selectedSlot).slim = true; + newSkinWaitSteveOrAlex = false; + save(); + } + } + return; + }else if(selectedSlot < EaglerProfile.skins.size()) { + int skinX = this.width / 2 - 120; + int skinY = this.height / 6 + 8; + int skinWidth = 80; + int skinHeight = 130; + if(par1 >= skinX && par2 >= skinY && par1 < skinX + skinWidth && par2 < skinY + skinHeight) { + if(selectedSlot < EaglerProfile.skins.size()) { + int type = EaglerProfile.getSkinSize(EaglerProfile.skins.get(selectedSlot).data.length); + if(type == 1 || type == 3) { + newSkinWaitSteveOrAlex = true; + return; + } + } + } + } + super.mouseClicked(par1, par2, par3); + this.username.mouseClicked(par1, par2, par3); + + if (par3 == 0) { + int skinX = this.width / 2 + 140 - 40; + int skinY = this.height / 6 + 82; + + if(par1 >= skinX && par1 < (skinX + 20) && par2 >= skinY && par2 < (skinY + 22)) { + dropDownOpen = !dropDownOpen; + } + + skinX = this.width / 2 - 20; + skinY = this.height / 6 + 82; + int skinWidth = 140; + int skinHeight = skinsHeight; + + if(!(par1 >= skinX && par1 < (skinX + skinWidth) && par2 >= skinY && par2 < (skinY + skinHeight + 22))) { + dropDownOpen = false; + dragging = false; + } + + skinY += 21; + + if(dropDownOpen && !dragging) { + for(int i = 0; i < slotsVisible; i++) { + if(i + scrollPos < dropDownOptions.length) { + if(selectedSlot != i + scrollPos) { + if(par1 >= skinX && par1 < (skinX + skinWidth - 10) && par2 >= (skinY + i*10 + 5) && par2 < (skinY + i*10 + 15) && selectedSlot != i + scrollPos) { + selectedSlot = i + scrollPos; + dropDownOpen = false; + dragging = false; + } + } + } + } + } + + } + } + + + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/GuiScreenVoiceChannel.java b/src/main/java/net/lax1dude/eaglercraft/GuiScreenVoiceChannel.java new file mode 100644 index 0000000..b326740 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/GuiScreenVoiceChannel.java @@ -0,0 +1,243 @@ +package net.lax1dude.eaglercraft; + +import java.util.Arrays; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiIngameMenu; +import net.minecraft.src.GuiMainMenu; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.GuiSlider2; +import net.minecraft.src.GuiTextField; +import net.minecraft.src.ScaledResolution; +import net.minecraft.src.StringTranslate; + +public class GuiScreenVoiceChannel extends GuiScreen { + + public GuiScreenVoiceChannel(GuiScreen parent) { + this.parent = parent; + } + + protected String screenTitle = "Voice Channel"; + private GuiScreen parent; + private GuiTextField channel; + + private GuiButton done; + private GuiButton connect; + private GuiButton disconnect; + private GuiSlider2 slider; + + public void initGui() { + StringTranslate var1 = StringTranslate.getInstance(); + this.screenTitle = var1.translateKey("voice.title"); + this.channel = new GuiTextField(this.fontRenderer, this.width / 2 - 98, this.height / 6 + 24, 195, 20); + this.channel.setText(EaglerProfile.myChannel); + EaglerAdapter.enableRepeatEvents(true); + this.buttonList.add(done = new GuiButton(200, this.width / 2 - 100, this.height / 6 + 148, var1.translateKey("gui.done"))); + this.buttonList.add(connect = new GuiButton(1, this.width / 2 - 100, this.height / 6 + 52, 99, 20, var1.translateKey("voice.connect"))); + this.buttonList.add(disconnect = new GuiButton(2, this.width / 2 + 1, this.height / 6 + 52, 99, 20, var1.translateKey("voice.disconnect"))); + this.buttonList.add(slider = new GuiSlider2(3, this.width / 2 - 100, this.height / 6 + 103, 200, 20, 0.5f, 2.0f)); + } + + public void onGuiClosed() { + EaglerAdapter.enableRepeatEvents(false); + } + + public void drawScreen(int mx, int my, float par3) { + this.drawDefaultBackground(); + StringTranslate var1 = StringTranslate.getInstance(); + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 15, 16777215); + this.drawString(this.fontRenderer, var1.translateKey("voice.addr"), this.width / 2 - 98, this.height / 6 + 8, 10526880); + if(voiceRelayed) { + this.drawCenteredString(this.fontRenderer, var1.translateKey("voice.warning1"), this.width / 2, this.height / 6 + 125, 0xffcccc); + this.drawCenteredString(this.fontRenderer, var1.translateKey("voice.warning2"), this.width / 2, this.height / 6 + 136, 0xffcccc); + this.drawCenteredString(this.fontRenderer, var1.translateKey("voice.warning3"), this.width / 2, this.height / 6 + 147, 0xffcccc); + this.drawString(this.fontRenderer, var1.translateKey("voice.volume"), this.width / 2 - 98, this.height / 6 + 81, 10526880); + slider.yPosition = this.height / 6 + 95; + done.yPosition = this.height / 6 + 168; + }else { + this.drawString(this.fontRenderer, var1.translateKey("voice.volume"), this.width / 2 - 98, this.height / 6 + 89, 10526880); + slider.yPosition = this.height / 6 + 103; + done.yPosition = this.height / 6 + 148; + } + super.drawScreen(mx, my, par3); + this.channel.drawTextBox(); + } + + protected void actionPerformed(GuiButton par1GuiButton) { + if(par1GuiButton.id == 200) { + this.mc.displayGuiScreen(parent); + }else if(par1GuiButton.id == 1) { + EaglerAdapter.voiceConnect(channel.getText()); + }else if(par1GuiButton.id == 2) { + EaglerAdapter.voiceEnd(); + } + } + + public void updateScreen() { + this.channel.updateCursorCounter(); + this.connect.enabled = !voiceActive; + this.disconnect.enabled = voiceActive; + this.channel.setEnabled(!voiceActive); + this.slider.enabled = voiceActive; + } + + protected void keyTyped(char par1, int par2) { + this.channel.textboxKeyTyped(par1, par2); + } + + protected void mouseClicked(int par1, int par2, int par3) { + super.mouseClicked(par1, par2, par3); + this.channel.mouseClicked(par1, par2, par3); + } + + public boolean doesGuiPauseGame() { + return false; + } + + private static final TextureLocation tex_gui = new TextureLocation("/gui/gui.png"); + + private static String[] connectedUsers = new String[0]; + private static String[] talkingUsers = new String[0]; + private static boolean voiceActive = false; + private static boolean voiceRelayed = false; + + public static void tickVoiceConnection() { + voiceActive = EaglerAdapter.voiceActive(); + if(voiceActive) { + voiceRelayed = EaglerAdapter.voiceRelayed(); + connectedUsers = EaglerAdapter.voiceUsers(); + talkingUsers = EaglerAdapter.voiceUsersTalking(); + Arrays.sort(talkingUsers); + Arrays.sort(connectedUsers); + }else { + voiceRelayed = false; + } + } + + public static long fadeInTimer = 0l; + + public static void drawOverlay() { + Minecraft mc = Minecraft.getMinecraft(); + if(System.currentTimeMillis() - fadeInTimer < 1500l) { + ScaledResolution res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); + EaglerAdapter.glDisable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST); + EaglerAdapter.glDisable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(false); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + float i = (float)(System.currentTimeMillis() - fadeInTimer) / 600f; + i = 1.0f / (i + 1.0f); + i = i * i * 1.08f - 0.08f; + if(i < 0.0f) i = 0.0f; + drawRect(0, 0, res.getScaledWidth(), res.getScaledHeight(), ((int)(i * 255f) << 24) | 0xffffff); + EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST); + if(System.currentTimeMillis() - fadeInTimer < 130l) { + mc.showWarningText(); + } + EaglerAdapter.glEnable(EaglerAdapter.GL_DEPTH_TEST); + EaglerAdapter.glDepthMask(true); + } + boolean titleScreen = (mc.currentScreen != null && (mc.currentScreen instanceof GuiMainMenu)); + if(voiceActive && !(titleScreen && ((GuiMainMenu)mc.currentScreen).showAck) && !mc.gameSettings.showDebugInfo) { + ScaledResolution res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); + int width = res.getScaledWidth(); int height = res.getScaledHeight(); + if(titleScreen) { + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(0f, 12f, 0f); + } + + EaglerAdapter.glDisable(EaglerAdapter.GL_LIGHTING); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + String line1 = "voice connected"; + String line2 = "" + connectedUsers.length + " users listening"; + int ll1 = mc.fontRenderer.getStringWidth(line1); + int ll2 = mc.fontRenderer.getStringWidth(line2); + drawRect(width - 17 - ll1 - 6, 0, width, 20, 0x33000000); + + if(mc.gameSettings.keyBindPlayerList.pressed || (mc.currentScreen != null && ((mc.currentScreen instanceof GuiIngameMenu) || (mc.currentScreen instanceof GuiScreenVoiceChannel)))) { + if(connectedUsers.length > 0) { + int wid = 0; + for(int i = 0; i < connectedUsers.length; ++i) { + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + int sw = mc.fontRenderer.getStringWidth(connectedUsers[i]); + mc.fontRenderer.drawStringWithShadow(connectedUsers[i], width - 12 - sw, 26 + i*11, 0xffeeeeee); + if(wid < sw) { + wid = sw; + } + + boolean isTalking = false; + for(int j = 0; j < talkingUsers.length; ++j) { + if(talkingUsers[j].equals(connectedUsers[i])) { + isTalking = true; + break; + } + } + + tex_gui.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 0.65f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(width - 9, 27 + i*11, 0f); + EaglerAdapter.glScalef(0.5f, 0.5f, 0.5f); + static_drawTexturedModalRect(0, 0, isTalking ? 208 : 224, 0, 15, 15); + EaglerAdapter.glPopMatrix(); + } + + drawRect(width - wid - 15, 24, width, 26 + connectedUsers.length*11, 0x33000000); + } + }else { + if(talkingUsers.length > 0) { + int wid = 0; + for(int i = 0; i < talkingUsers.length; ++i) { + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + int sw = mc.fontRenderer.getStringWidth(talkingUsers[i]); + mc.fontRenderer.drawStringWithShadow(talkingUsers[i], width - 12 - sw, 26 + i*11, 0xffeeeeee); + if(wid < sw) { + wid = sw; + } + + tex_gui.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 0.65f); + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(width - 9, 27 + i*11, 0f); + EaglerAdapter.glScalef(0.5f, 0.5f, 0.5f); + static_drawTexturedModalRect(0, 0, 208, 0, 15, 15); + EaglerAdapter.glPopMatrix(); + } + + drawRect(width - wid - 15, 24, width, 26 + talkingUsers.length*11, 0x33000000); + } + } + + mc.fontRenderer.drawStringWithShadow(line1, width - 16 - ll1 - 4, 2, 0xffffffff); + + EaglerAdapter.glPushMatrix(); + EaglerAdapter.glTranslatef(width - 20, 11f, 0f); + EaglerAdapter.glScalef(0.75f, 0.75f, 0.75f); + mc.fontRenderer.drawStringWithShadow(line2, -ll2, 0, 0xffffffff); + EaglerAdapter.glPopMatrix(); + + boolean b = ((System.currentTimeMillis() / 800l) % 2l) == 1l; + + tex_gui.bindTexture(); + EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND); + EaglerAdapter.glBlendFunc(EaglerAdapter.GL_SRC_ALPHA, EaglerAdapter.GL_ONE_MINUS_SRC_ALPHA); + EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 0.65f); + static_drawTexturedModalRect(width - 17, 2, b ? 192 : 224, 0, 15, 15); + + if(titleScreen) { + EaglerAdapter.glPopMatrix(); + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/ModelBipedNewSkins.java b/src/main/java/net/lax1dude/eaglercraft/ModelBipedNewSkins.java new file mode 100644 index 0000000..86b1f92 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/ModelBipedNewSkins.java @@ -0,0 +1,145 @@ +package net.lax1dude.eaglercraft; + +import net.minecraft.src.Entity; +import net.minecraft.src.ModelBiped; +import net.minecraft.src.ModelRenderer; + +public class ModelBipedNewSkins extends ModelBiped { + public ModelRenderer field_178734_a; + public ModelRenderer field_178732_b; + public ModelRenderer field_178733_c; + public ModelRenderer field_178731_d; + public ModelRenderer field_178730_v; + private ModelRenderer field_178729_w; + private ModelRenderer field_178736_x; + private boolean isAlex; + + public ModelBipedNewSkins(float p_i46304_1_, boolean p_i46304_2_) + { + super(p_i46304_1_, 0.0F, 64, 64); + this.isAlex = p_i46304_2_; + this.field_178736_x = new ModelRenderer(this, 24, 0); + this.field_178736_x.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1, p_i46304_1_); + this.field_178729_w = new ModelRenderer(this, 0, 0); + this.field_178729_w.setTextureSize(64, 32); + this.field_178729_w.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1, p_i46304_1_); + + if (p_i46304_2_) + { + this.bipedLeftArm = new ModelRenderer(this, 32, 48); + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_); + this.bipedLeftArm.setRotationPoint(5.0F, 2.5F, 0.0F); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-2.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_); + this.bipedRightArm.setRotationPoint(-5.0F, 2.5F, 0.0F); + this.field_178734_a = new ModelRenderer(this, 48, 48); + this.field_178734_a.addBox(-1.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_ + 0.25F); + this.field_178734_a.setRotationPoint(5.0F, 2.5F, 0.0F); + this.field_178732_b = new ModelRenderer(this, 40, 32); + this.field_178732_b.addBox(-2.0F, -2.0F, -2.0F, 3, 12, 4, p_i46304_1_ + 0.25F); + this.field_178732_b.setRotationPoint(-5.0F, 2.5F, 10.0F); + } + else + { + this.bipedLeftArm = new ModelRenderer(this, 32, 48); + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, p_i46304_1_); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); + this.field_178734_a = new ModelRenderer(this, 48, 48); + this.field_178734_a.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178734_a.setRotationPoint(5.0F, 2.0F, 0.0F); + this.field_178732_b = new ModelRenderer(this, 40, 32); + this.field_178732_b.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178732_b.setRotationPoint(-5.0F, 2.0F, 10.0F); + } + + this.bipedLeftLeg = new ModelRenderer(this, 16, 48); + this.bipedLeftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, p_i46304_1_); + this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F, 0.0F); + this.field_178733_c = new ModelRenderer(this, 0, 48); + this.field_178733_c.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178733_c.setRotationPoint(1.9F, 12.0F, 0.0F); + this.field_178731_d = new ModelRenderer(this, 0, 32); + this.field_178731_d.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, p_i46304_1_ + 0.25F); + this.field_178731_d.setRotationPoint(-1.9F, 12.0F, 0.0F); + this.field_178730_v = new ModelRenderer(this, 16, 32); + this.field_178730_v.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, p_i46304_1_ + 0.25F); + this.field_178730_v.setRotationPoint(0.0F, 0.0F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity p_78088_1_, float p_78088_2_, float p_78088_3_, float p_78088_4_, float p_78088_5_, float p_78088_6_, float p_78088_7_) { + super.render(p_78088_1_, p_78088_2_, p_78088_3_, p_78088_4_, p_78088_5_, p_78088_6_, p_78088_7_); + //EaglerAdapter.glPushMatrix(); + + //if (p_78088_1_ != null && p_78088_1_.isSneaking()) { + // EaglerAdapter.glTranslatef(0.0F, 0.2F, 0.0F); + //} + + this.field_178733_c.render(p_78088_7_); + this.field_178731_d.render(p_78088_7_); + this.field_178734_a.render(p_78088_7_); + this.field_178732_b.render(p_78088_7_); + this.field_178730_v.render(p_78088_7_); + + //EaglerAdapter.glPopMatrix(); + } + + public void func_178727_b(float p_178727_1_) { + func_178685_a(this.bipedHead, this.field_178736_x); + this.field_178736_x.rotationPointX = 0.0F; + this.field_178736_x.rotationPointY = 0.0F; + this.field_178736_x.render(p_178727_1_); + } + + public void func_178728_c(float p_178728_1_) { + this.field_178729_w.render(p_178728_1_); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used + * for animating the movement of arms and legs, where par1 represents the + * time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float p_78087_1_, float p_78087_2_, float p_78087_3_, float p_78087_4_, float p_78087_5_, float p_78087_6_, Entity p_78087_7_) { + super.setRotationAngles(p_78087_1_, p_78087_2_, p_78087_3_, p_78087_4_, p_78087_5_, p_78087_6_, p_78087_7_); + func_178685_a(this.bipedLeftLeg, this.field_178733_c); + func_178685_a(this.bipedRightLeg, this.field_178731_d); + func_178685_a(this.bipedLeftArm, this.field_178734_a); + func_178685_a(this.bipedRightArm, this.field_178732_b); + func_178685_a(this.bipedBody, this.field_178730_v); + } + + public void func_178725_a() { + this.bipedRightArm.render(0.0625F); + this.field_178732_b.render(0.0625F); + } + + public void func_178726_b() { + this.bipedLeftArm.render(0.0625F); + this.field_178734_a.render(0.0625F); + } + + public void postRenderHiddenArm(float p_178718_1_) { + if (this.isAlex) { + ++this.bipedRightArm.rotationPointX; + this.bipedRightArm.postRender(p_178718_1_); + --this.bipedRightArm.rotationPointX; + } else { + this.bipedRightArm.postRender(p_178718_1_); + } + } + + public static void func_178685_a(ModelRenderer p_178685_0_, ModelRenderer p_178685_1_) + { + p_178685_1_.rotateAngleX = p_178685_0_.rotateAngleX; + p_178685_1_.rotateAngleY = p_178685_0_.rotateAngleY; + p_178685_1_.rotateAngleZ = p_178685_0_.rotateAngleZ; + p_178685_1_.rotationPointX = p_178685_0_.rotationPointX; + p_178685_1_.rotationPointY = p_178685_0_.rotationPointY; + p_178685_1_.rotationPointZ = p_178685_0_.rotationPointZ; + } + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/ProfileUUID.java b/src/main/java/net/lax1dude/eaglercraft/ProfileUUID.java new file mode 100644 index 0000000..8352f1d --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/ProfileUUID.java @@ -0,0 +1,97 @@ +package net.lax1dude.eaglercraft; + +public class ProfileUUID { + + public final long msb; + public final long lsb; + + public ProfileUUID(long msb, long lsb) { + this.msb = msb; + this.lsb = lsb; + } + + public ProfileUUID(byte[] uuid) { + long msb = 0; + long lsb = 0; + for (int i = 0; i < 8; i++) + msb = (msb << 8) | (uuid[i] & 0xff); + for (int i = 8; i < 16; i++) + lsb = (lsb << 8) | (uuid[i] & 0xff); + this.msb = msb; + this.lsb = lsb; + } + + public ProfileUUID(String uuid) { + String[] components = uuid.split("-"); + if (components.length != 5) + throw new IllegalArgumentException("Invalid UUID string: " + uuid); + for (int i = 0; i < 5; i++) + components[i] = "0x" + components[i]; + + long mostSigBits = Long.decode(components[0]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]).longValue(); + + long leastSigBits = Long.decode(components[3]).longValue(); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]).longValue(); + + this.msb = mostSigBits; + this.lsb = leastSigBits; + } + + private static byte long7(long x) { return (byte)(x >> 56); } + private static byte long6(long x) { return (byte)(x >> 48); } + private static byte long5(long x) { return (byte)(x >> 40); } + private static byte long4(long x) { return (byte)(x >> 32); } + private static byte long3(long x) { return (byte)(x >> 24); } + private static byte long2(long x) { return (byte)(x >> 16); } + private static byte long1(long x) { return (byte)(x >> 8); } + private static byte long0(long x) { return (byte)(x ); } + + public byte[] getBytes() { + byte[] ret = new byte[16]; + ret[0] = long7(msb); + ret[1] = long6(msb); + ret[2] = long5(msb); + ret[3] = long4(msb); + ret[4] = long3(msb); + ret[5] = long2(msb); + ret[6] = long1(msb); + ret[7] = long0(msb); + ret[8] = long7(lsb); + ret[9] = long6(lsb); + ret[10] = long5(lsb); + ret[11] = long4(lsb); + ret[12] = long3(lsb); + ret[13] = long2(lsb); + ret[14] = long1(lsb); + ret[15] = long0(lsb); + return ret; + } + + @Override + public String toString() { + return (digits(msb >> 32, 8) + "-" + digits(msb >> 16, 4) + "-" + digits(msb, 4) + "-" + + digits(lsb >> 48, 4) + "-" + digits(lsb, 12)); + } + + private static String digits(long val, int digits) { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + @Override + public int hashCode() { + long hilo = msb ^ lsb; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + @Override + public boolean equals(Object o) { + return (o instanceof ProfileUUID) && ((ProfileUUID)o).lsb == lsb && ((ProfileUUID)o).msb == msb; + } + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/SHA1Digest.java b/src/main/java/net/lax1dude/eaglercraft/SHA1Digest.java new file mode 100644 index 0000000..2163594 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/SHA1Digest.java @@ -0,0 +1,258 @@ +package net.lax1dude.eaglercraft; + + +/** + * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349. + * + * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5 + * is the "endienness" of the word processing! + */ +public class SHA1Digest + extends GeneralDigest +{ + private static final int DIGEST_LENGTH = 20; + + private int H1, H2, H3, H4, H5; + + private int[] X = new int[80]; + private int xOff; + + /** + * Standard constructor + */ + public SHA1Digest() + { + reset(); + } + + /** + * Copy constructor. This will copy the state of the provided + * message digest. + */ + public SHA1Digest(SHA1Digest t) + { + super(t); + + H1 = t.H1; + H2 = t.H2; + H3 = t.H3; + H4 = t.H4; + H5 = t.H5; + + System.arraycopy(t.X, 0, X, 0, t.X.length); + xOff = t.xOff; + } + + public String getAlgorithmName() + { + return "SHA-1"; + } + + public int getDigestSize() + { + return DIGEST_LENGTH; + } + + protected void processWord( + byte[] in, + int inOff) + { + X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16) + | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff)); + + if (xOff == 16) + { + processBlock(); + } + } + + private void unpackWord( + int word, + byte[] out, + int outOff) + { + out[outOff] = (byte)(word >>> 24); + out[outOff + 1] = (byte)(word >>> 16); + out[outOff + 2] = (byte)(word >>> 8); + out[outOff + 3] = (byte)word; + } + + protected void processLength( + long bitLength) + { + if (xOff > 14) + { + processBlock(); + } + + X[14] = (int)(bitLength >>> 32); + X[15] = (int)(bitLength & 0xffffffff); + } + + public int doFinal( + byte[] out, + int outOff) + { + finish(); + + unpackWord(H1, out, outOff); + unpackWord(H2, out, outOff + 4); + unpackWord(H3, out, outOff + 8); + unpackWord(H4, out, outOff + 12); + unpackWord(H5, out, outOff + 16); + + reset(); + + return DIGEST_LENGTH; + } + + /** + * reset the chaining variables + */ + public void reset() + { + super.reset(); + + H1 = 0x67452301; + H2 = 0xefcdab89; + H3 = 0x98badcfe; + H4 = 0x10325476; + H5 = 0xc3d2e1f0; + + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } + + // + // Additive constants + // + private static final int Y1 = 0x5a827999; + private static final int Y2 = 0x6ed9eba1; + private static final int Y3 = 0x8f1bbcdc; + private static final int Y4 = 0xca62c1d6; + + private int f( + int u, + int v, + int w) + { + return ((u & v) | ((~u) & w)); + } + + private int h( + int u, + int v, + int w) + { + return (u ^ v ^ w); + } + + private int g( + int u, + int v, + int w) + { + return ((u & v) | (u & w) | (v & w)); + } + + private int rotateLeft( + int x, + int n) + { + return (x << n) | (x >>> (32 - n)); + } + + protected void processBlock() + { + // + // expand 16 word block into 80 word block. + // + for (int i = 16; i <= 79; i++) + { + X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1); + } + + // + // set up working variables. + // + int A = H1; + int B = H2; + int C = H3; + int D = H4; + int E = H5; + + // + // round 1 + // + for (int j = 0; j <= 19; j++) + { + int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 2 + // + for (int j = 20; j <= 39; j++) + { + int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 3 + // + for (int j = 40; j <= 59; j++) + { + int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + // + // round 4 + // + for (int j = 60; j <= 79; j++) + { + int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4; + + E = D; + D = C; + C = rotateLeft(B, 30); + B = A; + A = t; + } + + H1 += A; + H2 += B; + H3 += C; + H4 += D; + H5 += E; + + // + // reset the offset and clean out the word buffer. + // + xOff = 0; + for (int i = 0; i != X.length; i++) + { + X[i] = 0; + } + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/ServerQuery.java b/src/main/java/net/lax1dude/eaglercraft/ServerQuery.java new file mode 100644 index 0000000..b1cf927 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/ServerQuery.java @@ -0,0 +1,135 @@ +package net.lax1dude.eaglercraft; + +import org.json.JSONObject; + +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2.RateLimit; + +public interface ServerQuery { + + public static final long defaultTimeout = 10000l; + + public static class QueryResponse { + public final String responseType; + private final Object responseData; + public final String serverVersion; + public final String serverBrand; + public final String serverName; + public final long serverTime; + public final long clientTime; + public final boolean serverCracked; + public final RateLimit rateLimitStatus; + public final boolean rateLimitIsTCP; + public QueryResponse(JSONObject obj) { + this.responseType = obj.getString("type").toLowerCase(); + if(this.responseType.equals("blocked") || this.responseType.equals("locked")) { + this.responseData = null; + this.serverVersion = "Unknown"; + this.serverBrand = "Unknown"; + this.serverName = "Unknown"; + this.serverTime = 0l; + this.clientTime = System.currentTimeMillis(); + this.serverCracked = false; + this.rateLimitStatus = this.responseType.equals("locked") ? RateLimit.LOCKED : RateLimit.BLOCKED; + this.rateLimitIsTCP = false; + }else { + this.responseData = obj.get("data"); + this.serverVersion = obj.getString("vers"); + this.serverBrand = obj.getString("brand"); + this.serverName = obj.getString("name"); + this.serverTime = obj.getLong("time"); + this.clientTime = System.currentTimeMillis(); + this.serverCracked = obj.optBoolean("cracked", false); + this.rateLimitStatus = null; + this.rateLimitIsTCP = false; + } + } + public QueryResponse(boolean lockedNotBlocked) { + this.responseType = lockedNotBlocked ? "locked" : "blocked"; + this.responseData = null; + this.serverVersion = "Unknown"; + this.serverBrand = "Unknown"; + this.serverName = "Unknown"; + this.serverTime = 0l; + this.clientTime = System.currentTimeMillis(); + this.serverCracked = false; + this.rateLimitStatus = lockedNotBlocked ? RateLimit.LOCKED : RateLimit.BLOCKED; + this.rateLimitIsTCP = true; + } + public boolean isResponseString() { + return responseData instanceof String; + } + public boolean isResponseJSON() { + return responseData instanceof JSONObject; + } + public String getResponseString() { + return (String)responseData; + } + public JSONObject getResponseJSON() { + return (JSONObject)responseData; + } + } + + public boolean isQueryOpen(); + public void close(); + + public void send(String str); + + public default void send(JSONObject obj) { + send(obj.toString()); + } + + public int responseAvailable(); + public int responseBinaryAvailable(); + public QueryResponse getResponse(); + public byte[] getBinaryResponse(); + + // normally I wouldn't resort to race conditions but TeaVM has no + // java.util.concurrent classes for semaphore-like behavior + + public default boolean awaitResponseAvailable(long timeout) { + long start = System.currentTimeMillis(); + while(isQueryOpen() && responseAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) { + try { + Thread.sleep(0l, 250000); + } catch (InterruptedException e) { + } + } + return responseAvailable() > 0; + } + + public default boolean awaitResponseAvailable() { + return awaitResponseAvailable(defaultTimeout); + } + + public default boolean awaitResponseBinaryAvailable(long timeout) { + long start = System.currentTimeMillis(); + while(isQueryOpen() && responseBinaryAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) { + try { + Thread.sleep(0l, 250000); + } catch (InterruptedException e) { + } + } + return responseBinaryAvailable() > 0; + } + + public default boolean awaitResponseBinaryAvailable() { + return awaitResponseBinaryAvailable(defaultTimeout); + } + + public default QueryResponse awaitResponse(long timeout) { + return awaitResponseAvailable(timeout) ? getResponse() : null; + } + + public default QueryResponse awaitResponse() { + return awaitResponseAvailable() ? getResponse() : null; + } + + public default byte[] awaitResponseBinary(long timeout) { + return awaitResponseBinaryAvailable(timeout) ? getBinaryResponse() : null; + } + + public default byte[] awaitResponseBinary() { + return awaitResponseBinaryAvailable() ? getBinaryResponse() : null; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/TextureLocation.java b/src/main/java/net/lax1dude/eaglercraft/TextureLocation.java new file mode 100644 index 0000000..985da51 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/TextureLocation.java @@ -0,0 +1,38 @@ +package net.lax1dude.eaglercraft; + +import java.util.ArrayList; + +import net.minecraft.client.Minecraft; +import net.minecraft.src.RenderEngine; + +public class TextureLocation { + + private String path; + private int glObject; + + public TextureLocation(String path) { + this.path = path; + this.glObject = -1; + locations.add(this); + } + + public static void freeTextures() { + for(TextureLocation l : locations) { + l.glObject = -1; + } + } + + public void bindTexture() { + RenderEngine r = Minecraft.getMinecraft().renderEngine; + if(glObject == -1) { + glObject = r.getTexture(path); + if(glObject == -1) { + System.err.println("could not load: "+path); + } + } + r.bindTexture(glObject); + } + + private static final ArrayList locations = new ArrayList(); + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/WebsocketNetworkManager.java b/src/main/java/net/lax1dude/eaglercraft/WebsocketNetworkManager.java new file mode 100644 index 0000000..88ee272 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/WebsocketNetworkManager.java @@ -0,0 +1,145 @@ +package net.lax1dude.eaglercraft; + +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.LinkedList; + +import net.minecraft.src.INetworkManager; +import net.minecraft.src.NetHandler; +import net.minecraft.src.Packet; + +public class WebsocketNetworkManager implements INetworkManager { + + private NetHandler netHandler; + private String serverURI; + + public WebsocketNetworkManager(String uri, String eagler, NetHandler netHandler) throws IOException { + this.serverURI = uri; + this.netHandler = netHandler; + if(!EaglerAdapter.startConnection(uri)) { + throw new IOException("websocket to "+uri+" failed"); + } + EaglerAdapter.setDebugVar("minecraftServer", uri); + } + + public void setNetHandler(NetHandler netHandler) { + this.netHandler = netHandler; + } + + private ByteArrayOutputStream sendBuffer = new ByteArrayOutputStream(); + + public void addToSendQueue(Packet var1) { + try { + sendBuffer.reset(); + DataOutputStream yee = new DataOutputStream(sendBuffer); + Packet.writePacket(var1, yee); + EaglerAdapter.writePacket(sendBuffer.toByteArray()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void wakeThreads() { + } + + private static class ByteBufferDirectInputStream extends InputStream { + private ByteBuffer buf; + private ByteBufferDirectInputStream(ByteBuffer b) { + this.buf = b; + } + + @Override + public int read() throws IOException { + return buf.remaining() > 0 ? ((int)buf.get() & 0xFF) : -1; + } + + @Override + public int available() { + return buf.remaining(); + } + } + + private ByteBuffer oldChunkBuffer = null; + private LinkedList readChunks = new LinkedList(); + + public void processReadPackets() { + readChunks.clear(); + + if(oldChunkBuffer != null) { + readChunks.add(oldChunkBuffer); + } + + byte[] packet; + while((packet = EaglerAdapter.readPacket()) != null) { + readChunks.add(ByteBuffer.wrap(packet)); + } + if(!readChunks.isEmpty()) { + int cap = 0; + for(ByteBuffer b : readChunks) { + cap += b.limit(); + } + + ByteBuffer stream = ByteBuffer.allocate(cap); + for(ByteBuffer b : readChunks) { + stream.put(b); + } + stream.flip(); + + DataInputStream packetStream = new DataInputStream(new ByteBufferDirectInputStream(stream)); + while(stream.hasRemaining()) { + stream.mark(); + try { + Packet pkt = Packet.readPacket(packetStream, false); + //System.out.println(pkt.toString()); + pkt.processPacket(this.netHandler); + } catch (EOFException e) { + stream.reset(); + break; + } catch (IOException e) { + continue; + } catch (Throwable e2) { + e2.printStackTrace(); + } + } + + if(stream.hasRemaining()) { + oldChunkBuffer = stream.slice(); + }else { + oldChunkBuffer = null; + } + + } + } + + public void serverShutdown() { + if(EaglerAdapter.connectionOpen()) { + EaglerAdapter.endConnection(); + EaglerAdapter.setDebugVar("minecraftServer", "null"); + } + } + + public int packetSize() { + return 0; + } + + public void networkShutdown(String var1, Object... var2) { + serverShutdown(); + } + + public void closeConnections() { + if(EaglerAdapter.connectionOpen()) { + EaglerAdapter.endConnection(); + EaglerAdapter.setDebugVar("minecraftServer", "null"); + } + } + + public String getServerURI() { + return this.serverURI; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/compat/CompatEnum.java b/src/main/java/net/lax1dude/eaglercraft/compat/CompatEnum.java new file mode 100644 index 0000000..0eaf3fd --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/compat/CompatEnum.java @@ -0,0 +1,161 @@ +package net.lax1dude.eaglercraft.compat; + +import java.io.Serializable; + +public class CompatEnum> { + /** + * The name of this enum constant, as declared in the enum declaration. Most + * programmers should use the {@link #toString} method rather than accessing + * this field. + */ + private final String name; + + /** + * Returns the name of this enum constant, exactly as declared in its enum + * declaration. + * + * Most programmers should use the {@link #toString} method in preference to + * this one, as the toString method may return a more user-friendly name. + * This method is designed primarily for use in specialized situations where + * correctness depends on getting the exact name, which will not vary from + * release to release. + * + * @return the name of this enum constant + */ + public final String name() { + return name; + } + + /** + * The ordinal of this enumeration constant (its position in the enum + * declaration, where the initial constant is assigned an ordinal of zero). + * + * Most programmers will have no use for this field. It is designed for use by + * sophisticated enum-based data structures, such as {@link java.util.EnumSet} + * and {@link java.util.EnumMap}. + */ + private final int ordinal; + + /** + * Returns the ordinal of this enumeration constant (its position in its enum + * declaration, where the initial constant is assigned an ordinal of zero). + * + * Most programmers will have no use for this method. It is designed for use by + * sophisticated enum-based data structures, such as {@link java.util.EnumSet} + * and {@link java.util.EnumMap}. + * + * @return the ordinal of this enumeration constant + */ + public final int ordinal() { + return ordinal; + } + + /** + * Sole constructor. Programmers cannot invoke this constructor. + * It is for use by code emitted by the compiler in response to + * enum type declarations. + * + * @param name - The name of this enum constant, which is the identifier + * used to declare it. + * @param ordinal - The ordinal of this enumeration constant (its position + * in the enum declaration, where the initial constant is assigned + * an ordinal of zero). + */ + protected CompatEnum(String name, int ordinal) { + this.name = name; + this.ordinal = ordinal; + } + + /** + * Returns the name of this enum constant, as contained in the declaration. This + * method may be overridden, though it typically isn't necessary or desirable. + * An enum type should override this method when a more "programmer-friendly" + * string form exists. + * + * @return the name of this enum constant + */ + public String toString() { + return name; + } + + /** + * Returns true if the specified object is equal to this enum constant. + * + * @param other the object to be compared for equality with this object. + * @return true if the specified object is equal to this enum constant. + */ + public final boolean equals(Object other) { + return this == other; + } + + /** + * Returns a hash code for this enum constant. + * + * @return a hash code for this enum constant. + */ + public final int hashCode() { + return super.hashCode(); + } + + /** + * Throws CloneNotSupportedException. This guarantees that enums are never + * cloned, which is necessary to preserve their "singleton" status. + * + * @return (never returns) + */ + protected final Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + + /** + * Returns the Class object corresponding to this enum constant's enum type. Two + * enum constants e1 and e2 are of the same enum type if and only if + * e1.getDeclaringClass() == e2.getDeclaringClass(). (The value returned by this + * method may differ from the one returned by the {@link Object#getClass} method + * for enum constants with constant-specific class bodies.) + * + * @return the Class object corresponding to this enum constant's enum type + */ + @SuppressWarnings("unchecked") + public final Class getDeclaringClass() { + Class clazz = getClass(); + Class zuper = clazz.getSuperclass(); + return (zuper == CompatEnum.class) ? (Class) clazz : (Class) zuper; + } + + /** + * Returns the enum constant of the specified enum type with the specified name. + * The name must match exactly an identifier used to declare an enum constant in + * this type. (Extraneous whitespace characters are not permitted.) + * + *

+ * Note that for a particular enum type {@code T}, the implicitly declared + * {@code public static T valueOf(String)} method on that enum may be used + * instead of this method to map from a name to the corresponding enum constant. + * All the constants of an enum type can be obtained by calling the implicit + * {@code public static T[] values()} method of that type. + * + * @param The enum type whose constant is to be returned + * @param enumType the {@code Class} object of the enum type from which to + * return a constant + * @param name the name of the constant to return + * @return the enum constant of the specified enum type with the specified name + * @throws IllegalArgumentException if the specified enum type has no constant + * with the specified name, or the specified + * class object does not represent an enum type + * @throws NullPointerException if {@code enumType} or {@code name} is null + * @since 1.5 + */ + public static > T valueOf(Class enumType, String name) { + try { + T result = (T)enumType.getField(name).get(null); + if (result != null) + return result; + if (name == null) + throw new NullPointerException("Name is null"); + }catch(IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ee) { + } + throw new IllegalArgumentException("No enum constant " + enumType.getCanonicalName() + "." + name); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/compat/UnexpectedThrowable.java b/src/main/java/net/lax1dude/eaglercraft/compat/UnexpectedThrowable.java new file mode 100644 index 0000000..2ded6ed --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/compat/UnexpectedThrowable.java @@ -0,0 +1,13 @@ +package net.lax1dude.eaglercraft.compat; + +public class UnexpectedThrowable extends RuntimeException { + + public UnexpectedThrowable(Throwable t) { + super("Encountered an unexpected exception", t); + } + + public UnexpectedThrowable(String str, Throwable t) { + super(str, t); + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/EaglerAdapterGL30.java b/src/main/java/net/lax1dude/eaglercraft/glemu/EaglerAdapterGL30.java new file mode 100644 index 0000000..73b3cee --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/EaglerAdapterGL30.java @@ -0,0 +1,1404 @@ +package net.lax1dude.eaglercraft.glemu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.HashMap; + +import net.lax1dude.eaglercraft.EaglerAdapter; + +import net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2; +import net.lax1dude.eaglercraft.glemu.vector.Matrix4f; +import net.lax1dude.eaglercraft.glemu.vector.Vector3f; +import net.lax1dude.eaglercraft.glemu.vector.Vector4f; + +public class EaglerAdapterGL30 extends EaglerAdapterImpl2 { + + public static final int GL_ZERO = 0; + public static final int GL_ONE = 1; + public static final int GL_TEXTURE_2D = 2; + public static final int GL_SMOOTH = 3; + public static final int GL_DEPTH_TEST = 4; + public static final int GL_LEQUAL = 5; + public static final int GL_ALPHA_TEST = 6; + public static final int GL_GREATER = 7; + public static final int GL_BACK = 8; + public static final int GL_PROJECTION = 9; + public static final int GL_MODELVIEW = 10; + public static final int GL_COLOR_BUFFER_BIT = 1; + public static final int GL_DEPTH_BUFFER_BIT = 2; + public static final int GL_LIGHTING = 13; + public static final int GL_FOG = 14; + public static final int GL_COLOR_MATERIAL = 15; + public static final int GL_BLEND = 16; + public static final int GL_RGBA = 18; + public static final int GL_UNSIGNED_BYTE = 19; + public static final int GL_TEXTURE_WIDTH = 20; + public static final int GL_LIGHT0 = 21; + public static final int GL_LIGHT1 = 22; + public static final int GL_POSITION = 30; + public static final int GL_DIFFUSE = 31; + public static final int GL_SPECULAR = 32; + public static final int GL_AMBIENT = 33; + public static final int GL_FLAT = 34; + public static final int GL_LIGHT_MODEL_AMBIENT = 35; + public static final int GL_FRONT_AND_BACK = 36; + public static final int GL_AMBIENT_AND_DIFFUSE = 37; + public static final int GL_MODELVIEW_MATRIX = 38; + public static final int GL_PROJECTION_MATRIX = 39; + public static final int GL_VIEWPORT = 40; + public static final int GL_RESCALE_NORMAL = 41; + public static final int GL_SRC_ALPHA = 42; + public static final int GL_ONE_MINUS_SRC_ALPHA = 43; + public static final int GL_ONE_MINUS_DST_COLOR = 44; + public static final int GL_ONE_MINUS_SRC_COLOR = 45; + public static final int GL_CULL_FACE = 46; + public static final int GL_TEXTURE_MIN_FILTER = 47; + public static final int GL_TEXTURE_MAG_FILTER = 48; + public static final int GL_LINEAR = 49; + public static final int GL_COLOR_LOGIC_OP = 50; + public static final int GL_OR_REVERSE = 51; + public static final int GL_EQUAL = 52; + public static final int GL_SRC_COLOR = 53; + public static final int GL_TEXTURE = 54; + public static final int GL_FRONT = 55; + public static final int GL_COMPILE = 56; + public static final int GL_S = 57; + public static final int GL_T = 58; + public static final int GL_R = 59; + public static final int GL_Q = 60; + public static final int GL_TEXTURE_GEN_S = 61; + public static final int GL_TEXTURE_GEN_T = 62; + public static final int GL_TEXTURE_GEN_R = 63; + public static final int GL_TEXTURE_GEN_Q = 64; + public static final int GL_TEXTURE_GEN_MODE = 65; + public static final int GL_OBJECT_PLANE = 66; + public static final int GL_EYE_PLANE = 67; + public static final int GL_OBJECT_LINEAR = 68; + public static final int GL_EYE_LINEAR = 69; + public static final int GL_NEAREST = 70; + public static final int GL_CLAMP = 71; + public static final int GL_TEXTURE_WRAP_S = 72; + public static final int GL_TEXTURE_WRAP_T = 73; + public static final int GL_REPEAT = 74; + public static final int GL_BGRA = 75; + public static final int GL_UNSIGNED_INT_8_8_8_8_REV = 76; + public static final int GL_DST_COLOR = 77; + public static final int GL_POLYGON_OFFSET_FILL = 78; + public static final int GL_NORMALIZE = 79; + public static final int GL_DST_ALPHA = 80; + public static final int GL_FLOAT = 81; + public static final int GL_TEXTURE_COORD_ARRAY = 82; + public static final int GL_SHORT = 83; + public static final int GL_COLOR_ARRAY = 84; + public static final int GL_VERTEX_ARRAY = 85; + public static final int GL_TRIANGLES = 86; + public static final int GL_NORMAL_ARRAY = 87; + public static final int GL_TEXTURE_3D = 88; + public static final int GL_FOG_MODE = 89; + public static final int GL_EXP = 90; + public static final int GL_FOG_DENSITY = 91; + public static final int GL_FOG_START = 92; + public static final int GL_FOG_END = 93; + public static final int GL_FOG_COLOR = 94; + public static final int GL_TRIANGLE_STRIP = 95; + public static final int GL_PACK_ALIGNMENT = 96; + public static final int GL_UNPACK_ALIGNMENT = 97; + public static final int GL_QUADS = 98; + public static final int GL_TEXTURE0 = 99; + public static final int GL_TEXTURE1 = 100; + public static final int GL_TEXTURE2 = 101; + public static final int GL_TEXTURE3 = 102; + public static final int GL_INVALID_ENUM = 140; + public static final int GL_INVALID_VALUE= 141; + public static final int GL_INVALID_OPERATION = 142; + public static final int GL_OUT_OF_MEMORY = 143; + public static final int GL_CONTEXT_LOST_WEBGL = 144; + public static final int GL_TRIANGLE_FAN = 145; + public static final int GL_LINE_STRIP = 146; + public static final int GL_LIGHTING2 = 147; + public static final int GL_LINES = 148; + public static final int GL_NEAREST_MIPMAP_LINEAR = 149; + public static final int GL_TEXTURE_MAX_ANISOTROPY = 150; + public static final int GL_TEXTURE_MAX_LEVEL = 151; + public static final int GL_LINEAR_MIPMAP_LINEAR = 152; + public static final int GL_LINEAR_MIPMAP_NEAREST = 153; + public static final int GL_NEAREST_MIPMAP_NEAREST = 154; + + public static final boolean isWebGL = _wisWebGL(); + + private static final GLObjectMap texObjects = new GLObjectMap(256); + + private static boolean enableTexture2D = false; + private static boolean enableTexture2D_1 = false; + private static boolean enableLighting = false; + private static boolean enableAlphaTest = false; + private static float alphaThresh = 0.1f; + + private static boolean isCompilingDisplayList = false; + private static DisplayList compilingDisplayList = null; + + private static boolean enableColorArray = false; + private static boolean enableNormalArray = false; + private static boolean enableTex0Array = false; + private static boolean enableTex1Array = false; + + private static boolean enableAnisotropicFix = false; + private static float anisotropicFixX = 1024.0f; + private static float anisotropicFixY = 1024.0f; + + private static float colorR = 1.0f; + private static float colorG = 1.0f; + private static float colorB = 1.0f; + private static float colorA = 1.0f; + + private static float normalX = 1.0f; + private static float normalY = 0.0f; + private static float normalZ = 0.0f; + + private static int selectedTex = 0; + private static int selectedClientTex = 0; + private static float tex0X = 0; + private static float tex0Y = 0; + private static float tex1X = 0; + private static float tex1Y = 0; + private static TextureGL boundTexture0 = null; + private static boolean enableAnisotropicPatch = false; + private static boolean hintAnisotropicPatch = false; + + public static final void anisotropicPatch(boolean e) { + enableAnisotropicPatch = e; + } + + private static boolean enableTexGen = false; + private static boolean enableColorMaterial = false; + + private static int texS_plane = 0; + private static float texS_X = 0.0f; + private static float texS_Y = 0.0f; + private static float texS_Z = 0.0f; + private static float texS_W = 0.0f; + + private static int texT_plane = 0; + private static float texT_X = 0.0f; + private static float texT_Y = 0.0f; + private static float texT_Z = 0.0f; + private static float texT_W = 0.0f; + + private static int texR_plane = 0; + private static float texR_X = 0.0f; + private static float texR_Y = 0.0f; + private static float texR_Z = 0.0f; + private static float texR_W = 0.0f; + + private static int texQ_plane = 0; + private static float texQ_X = 0.0f; + private static float texQ_Y = 0.0f; + private static float texQ_Z = 0.0f; + private static float texQ_W = 0.0f; + + private static float fogColorR = 1.0f; + private static float fogColorG = 1.0f; + private static float fogColorB = 1.0f; + private static float fogColorA = 1.0f; + private static int fogMode = 1; + private static boolean fogEnabled = false; + private static boolean fogPremultiply = false; + private static float fogStart = 1.0f; + private static float fogEnd = 1.0f; + private static float fogDensity = 1.0f; + + private static int bytesUploaded = 0; + private static int vertexDrawn = 0; + private static int triangleDrawn = 0; + + private static int matrixMode = GL_MODELVIEW; + + static Matrix4f[] matModelV = new Matrix4f[32]; + static int matModelPointer = 0; + + static Matrix4f[] matProjV = new Matrix4f[6]; + static int matProjPointer = 0; + + static Matrix4f[] matTexV = new Matrix4f[16]; + static int matTexPointer = 0; + + static { + for(int i = 0; i < matModelV.length; ++i) { + matModelV[i] = new Matrix4f(); + } + for(int i = 0; i < matProjV.length; ++i) { + matProjV[i] = new Matrix4f(); + } + for(int i = 0; i < matTexV.length; ++i) { + matTexV[i] = new Matrix4f(); + } + } + + public static void glClearStack() { + matModelV[0].load(matModelV[matModelPointer]); matModelPointer = 0; + matProjV[0].load(matProjV[matProjPointer]); matProjPointer = 0; + matTexV[0].load(matTexV[matTexPointer]); matTexPointer = 0; + } + + private static BufferGL quadsToTrianglesBuffer = null; + private static BufferArrayGL currentArray = null; + + private static class DisplayList { + private final int id; + private BufferArrayGL glarray; + private BufferGL glbuffer; + private int shaderMode; + private int listLength; + private DisplayList(int id) { + this.id = id; + this.glarray = null; + this.glbuffer = null; + this.shaderMode = -1; + this.listLength = 0; + } + } + + private static final HashMap displayLists = new HashMap(); + private static final HashMap displayListsInitialized = new HashMap(); + + public static final int getDisplayListCount() { + return displayListsInitialized.size(); + } + + public static final void glEnable(int p1) { + switch(p1) { + case GL_DEPTH_TEST: + _wglEnable(_wGL_DEPTH_TEST); + break; + case GL_CULL_FACE: + _wglEnable(_wGL_CULL_FACE); + break; + case GL_BLEND: + _wglEnable(_wGL_BLEND); + break; + case GL_RESCALE_NORMAL: + break; + case GL_TEXTURE_2D: + if(selectedTex == 0) { + enableTexture2D = true; + } + if(selectedTex == 1) { + enableTexture2D_1 = true; + } + break; + case GL_LIGHTING: + enableLighting = true; + break; + case GL_LIGHTING2: + break; + case GL_ALPHA_TEST: + enableAlphaTest = true; + break; + case GL_FOG: + fogEnabled = true; + break; + case GL_COLOR_MATERIAL: + enableColorMaterial = true; + break; + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_Q: + enableTexGen = true; + break; + case GL_POLYGON_OFFSET_FILL: + _wglEnable(_wGL_POLYGON_OFFSET_FILL); + default: + break; + } + } + public static final void glShadeModel(int p1) { + + } + public static final void glClearDepth(float p1) { + _wglClearDepth(-p1); + } + public static final void glDepthFunc(int p1) { + int f = _wGL_GEQUAL; + switch(p1) { + case GL_GREATER: f = _wGL_LESS; break; + case GL_LEQUAL: f = _wGL_GEQUAL; break; + case GL_EQUAL: f = _wGL_EQUAL; + default: break; + } + _wglDepthFunc(f); + } + public static final void glAlphaFunc(int p1, float p2) { + alphaThresh = p2; + } + public static final void glCullFace(int p1) { + int f = _wGL_BACK; + switch(p1) { + case GL_BACK: f = _wGL_BACK; break; + case GL_FRONT: f = _wGL_FRONT; break; + case GL_FRONT_AND_BACK: f = _wGL_FRONT_AND_BACK; break; + default: break; + } + _wglCullFace(f); + } + public static final void glMatrixMode(int p1) { + matrixMode = p1; + } + private static final Matrix4f getMatrix() { + switch(matrixMode) { + case GL_MODELVIEW: + default: + return matModelV[matModelPointer]; + case GL_PROJECTION: + return matProjV[matProjPointer]; + case GL_TEXTURE: + return matTexV[matTexPointer]; + } + } + public static final void glLoadIdentity() { + getMatrix().setIdentity(); + } + public static final void glViewport(int p1, int p2, int p3, int p4) { + _wglViewport(p1, p2, p3, p4); + } + public static final void glClear(int p1) { + int f = 0; + if((p1 & GL_COLOR_BUFFER_BIT) == GL_COLOR_BUFFER_BIT) { + f = f | _wGL_COLOR_BUFFER_BIT; + } + if((p1 & GL_DEPTH_BUFFER_BIT) == GL_DEPTH_BUFFER_BIT) { + f = f | _wGL_DEPTH_BUFFER_BIT; + } + _wglClear(f); + } + public static final void glOrtho(float left, float right, float bottom, float top, float zNear, float zFar) { + Matrix4f res = getMatrix(); + res.m00 = 2.0f / (right - left); + res.m01 = 0.0f; + res.m02 = 0.0f; + res.m03 = 0.0f; + res.m10 = 0.0f; + res.m11 = 2.0f / (top - bottom); + res.m12 = 0.0f; + res.m13 = 0.0f; + res.m20 = 0.0f; + res.m21 = 0.0f; + res.m22 = 2.0f / (zFar - zNear); + res.m23 = 0.0f; + res.m30 = -(right + left) / (right - left); + res.m31 = -(top + bottom) / (top - bottom); + res.m32 = (zFar + zNear) / (zFar - zNear); + res.m33 = 1.0f; + } + private static final Vector3f deevis = new Vector3f(); + public static final void glTranslatef(float p1, float p2, float p3) { + deevis.set(p1, p2, p3); + getMatrix().translate(deevis); + if(isCompilingDisplayList) { + System.err.println("matrix is not supported while recording display list use tessellator class instead"); + } + } + public static final void glClearColor(float p1, float p2, float p3, float p4) { + _wglClearColor(p1, p2, p3, p4); + } + public static final void glDisable(int p1) { + switch(p1) { + case GL_DEPTH_TEST: + _wglDisable(_wGL_DEPTH_TEST); + break; + case GL_CULL_FACE: + _wglDisable(_wGL_CULL_FACE); + break; + case GL_BLEND: + _wglDisable(_wGL_BLEND); + break; + case GL_RESCALE_NORMAL: + break; + case GL_TEXTURE_2D: + if(selectedTex == 0) { + enableTexture2D = false; + } + if(selectedTex == 1) { + enableTexture2D_1 = false; + } + break; + case GL_LIGHTING: + enableLighting = false; + break; + case GL_LIGHTING2: + break; + case GL_ALPHA_TEST: + enableAlphaTest = false; + break; + case GL_FOG: + fogEnabled = false; + break; + case GL_COLOR_MATERIAL: + enableColorMaterial = false; + break; + case GL_TEXTURE_GEN_S: + case GL_TEXTURE_GEN_T: + case GL_TEXTURE_GEN_R: + case GL_TEXTURE_GEN_Q: + enableTexGen = false; + break; + case GL_POLYGON_OFFSET_FILL: + _wglDisable(_wGL_POLYGON_OFFSET_FILL); + default: + break; + } + } + public static final void glColor4f(float p1, float p2, float p3, float p4) { + colorR = p1; + colorG = p2; + colorB = p3; + colorA = p4; + } + public static final int glGetError() { + int err = _wglGetError(); + if(err == _wGL_INVALID_ENUM) return GL_INVALID_ENUM; + if(err == _wGL_INVALID_OPERATION) return GL_INVALID_OPERATION; + if(err == _wGL_INVALID_VALUE) return GL_INVALID_VALUE; + if(err == _wGL_OUT_OF_MEMORY) return GL_OUT_OF_MEMORY; + if(err == _wGL_CONTEXT_LOST_WEBGL) return GL_CONTEXT_LOST_WEBGL; + return err; + } + public static final void glFlush() { + EaglerAdapter._wglFlush(); + } + public static final void glLineWidth(float p1) { + + } + public static final void glTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + if(p2 == 0 && selectedTex == 0 && boundTexture0 != null) { + boundTexture0.w = p4; + boundTexture0.h = p5; + } + _wglTexImage2D(_wGL_TEXTURE_2D, p2, _wGL_RGBA8, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glLight(int p1, int p2, FloatBuffer p3) { + + } + public static final void glLightModel(int p1, FloatBuffer p2) { + + } + private static Vector4f lightPos0vec0 = new Vector4f(); + private static Vector4f lightPos1vec0 = new Vector4f(); + private static Vector4f lightPos0vec = new Vector4f(); + private static Vector4f lightPos1vec = new Vector4f(); + public static final void copyModelToLightMatrix() { + lightPos0vec0.set(lightPos0vec); + lightPos1vec0.set(lightPos1vec); + lightPos0vec.set(0.2f, 1.0f, -0.7f, 0.0f); lightPos0vec.normalise(); + lightPos1vec.set(-0.2f, 1.0f, 0.7f, 0.0f); lightPos1vec.normalise(); + Matrix4f.transform(matModelV[matModelPointer], lightPos0vec, lightPos0vec).normalise(); + Matrix4f.transform(matModelV[matModelPointer], lightPos1vec, lightPos1vec).normalise(); + } + public static final void flipLightMatrix() { + lightPos0vec.x = -lightPos0vec.x; + lightPos1vec.x = -lightPos1vec.x; + lightPos0vec.y = -lightPos0vec.y; + lightPos1vec.y = -lightPos1vec.y; + lightPos0vec.z = -lightPos0vec.z; + lightPos1vec.z = -lightPos1vec.z; + } + public static final void revertLightMatrix() { + lightPos0vec.set(lightPos0vec0); + lightPos1vec.set(lightPos1vec0); + } + public static final void glPushMatrix() { + switch(matrixMode) { + case GL_MODELVIEW: + default: + if(matModelPointer < matModelV.length - 1) { + ++matModelPointer; + matModelV[matModelPointer].load(matModelV[matModelPointer - 1]); + }else { + System.err.println("modelview matrix stack overflow"); + } + break; + case GL_PROJECTION: + if(matProjPointer < matProjV.length - 1) { + ++matProjPointer; + matProjV[matProjPointer].load(matProjV[matProjPointer - 1]); + }else { + System.err.println("projection matrix stack overflow"); + } + break; + case GL_TEXTURE: + if(matTexPointer < matTexV.length - 1) { + ++matTexPointer; + matTexV[matTexPointer].load(matTexV[matTexPointer - 1]); + }else { + System.err.println("texture matrix stack overflow"); + } + break; + } + } + private static final float toRad = 0.0174532925f; + public static final void glRotatef(float p1, float p2, float p3, float p4) { + deevis.set(p2, p3, p4); + getMatrix().rotate(p1 * toRad, deevis); + if(isCompilingDisplayList) { + System.err.println("matrix is not supported while recording display list use tessellator class instead"); + } + } + public static final void glPopMatrix() { + switch(matrixMode) { + case GL_MODELVIEW: + default: + if(matModelPointer > 0) { + --matModelPointer; + }else { + System.err.println("modelview matrix stack underflow"); + } + break; + case GL_PROJECTION: + if(matProjPointer > 0) { + --matProjPointer; + }else { + System.err.println("projection matrix stack underflow"); + } + break; + case GL_TEXTURE: + if(matTexPointer > 0) { + --matTexPointer; + }else { + System.err.println("texture matrix stack underflow"); + } + break; + } + } + public static final void glColorMaterial(int p1, int p2) { + + } + public static final void glGetFloat(int p1, FloatBuffer p2) { + switch(p1) { + case GL_MODELVIEW_MATRIX: + default: + matModelV[matModelPointer].store(p2); + break; + case GL_PROJECTION_MATRIX: + matProjV[matProjPointer].store(p2); + break; + } + } + public static final void glGetInteger(int p1, int[] p2) { + if(p1 == GL_VIEWPORT) { + _wglGetParameter(_wGL_VIEWPORT, 4, p2); + } + } + public static final void glScalef(float p1, float p2, float p3) { + deevis.set(p1, p2, p3); + getMatrix().scale(deevis); + if(isCompilingDisplayList) { + System.err.println("matrix is not supported while recording display list use tessellator class instead"); + } + } + public static final void glBlendFunc(int p1, int p2) { + int pp1 = 0; + int pp2 = 0; + switch(p1) { + default: + case GL_SRC_ALPHA: pp1 = _wGL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: pp1 = _wGL_ONE_MINUS_SRC_ALPHA; break; + case GL_DST_ALPHA: pp1 = _wGL_DST_ALPHA; break; + case GL_DST_COLOR: pp1 = _wGL_DST_COLOR; break; + case GL_SRC_COLOR: pp1 = _wGL_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: pp1 = _wGL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_DST_COLOR: pp1 = _wGL_ONE_MINUS_DST_COLOR; break; + case GL_ONE: pp1 = _wGL_ONE; break; + case GL_ZERO: pp1 = _wGL_ZERO; break; + } + switch(p2) { + default: + case GL_SRC_ALPHA: pp2 = _wGL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: pp2 = _wGL_ONE_MINUS_SRC_ALPHA; break; + case GL_DST_ALPHA: pp2 = _wGL_DST_ALPHA; break; + case GL_DST_COLOR: pp2 = _wGL_DST_COLOR; break; + case GL_SRC_COLOR: pp2 = _wGL_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: pp2 = _wGL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_DST_COLOR: pp1 = _wGL_ONE_MINUS_DST_COLOR; break; + case GL_ONE: pp2 = _wGL_ONE; break; + case GL_ZERO: pp2 = _wGL_ZERO; break; + } + fogPremultiply = (p1 == GL_ONE && p2 == GL_ONE_MINUS_SRC_ALPHA); + _wglBlendFunc(pp1, pp2); + } + public static final void glDepthMask(boolean p1) { + _wglDepthMask(p1); + } + public static final void glColorMask(boolean p1, boolean p2, boolean p3, boolean p4) { + _wglColorMask(p1, p2, p3, p4); + } + private static final void updateAnisotropicPatch() { + if(selectedTex == 0) { + enableAnisotropicFix = false; + if(enableAnisotropicPatch && boundTexture0 != null && boundTexture0.anisotropic && boundTexture0.nearest) { + enableAnisotropicFix = true; + anisotropicFixX = boundTexture0.w; + anisotropicFixY = boundTexture0.h; + } + } + } + public static final void glBindTexture(int p1, int p2) { + TextureGL t = texObjects.get(p2); + _wglBindTexture(_wGL_TEXTURE_2D, t); + if(selectedTex == 0) { + boundTexture0 = t; + updateAnisotropicPatch(); + } + } + public static final void glCopyTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) { + _wglCopyTexSubImage2D(_wGL_TEXTURE_2D, p2, p3, p4, p5, p6, p7, p8); + } + public static final void glTexParameteri(int p1, int p2, int p3) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + int pp2 = 0; + switch(p2) { + default: + case GL_TEXTURE_MAG_FILTER: pp2 = _wGL_TEXTURE_MAG_FILTER; break; + case GL_TEXTURE_MIN_FILTER: pp2 = _wGL_TEXTURE_MIN_FILTER; break; + case GL_TEXTURE_WRAP_S: pp2 = _wGL_TEXTURE_WRAP_S; break; + case GL_TEXTURE_WRAP_T: pp2 = _wGL_TEXTURE_WRAP_T; break; + case GL_TEXTURE_MAX_LEVEL: pp2 = _wGL_TEXTURE_MAX_LEVEL; break; + } + int pp3 = 0; + switch(p3) { + default: + pp3 = p3; break; + case GL_LINEAR: pp3 = _wGL_LINEAR; break; + case GL_NEAREST_MIPMAP_LINEAR: pp3 = _wGL_NEAREST_MIPMAP_LINEAR; break; + case GL_LINEAR_MIPMAP_LINEAR: pp3 = _wGL_LINEAR_MIPMAP_LINEAR; break; + case GL_LINEAR_MIPMAP_NEAREST: pp3 = _wGL_LINEAR_MIPMAP_NEAREST; break; + case GL_NEAREST_MIPMAP_NEAREST: pp3 = _wGL_NEAREST_MIPMAP_NEAREST; break; + case GL_NEAREST: pp3 = _wGL_NEAREST; break; + case GL_REPEAT: pp3 = _wGL_REPEAT; break; + case GL_CLAMP: pp3 = _wGL_CLAMP; break; + } + + if(selectedTex == 0 && boundTexture0 != null && pp2 == _wGL_TEXTURE_MAG_FILTER) { + boundTexture0.nearest = pp3 == _wGL_NEAREST; + } + _wglTexParameteri(pp1, pp2, pp3); + updateAnisotropicPatch(); + } + public static final void glTexParameterf(int p1, int p2, float p3) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + int pp2 = 0; + switch(p2) { + default: + case GL_TEXTURE_MAX_ANISOTROPY: pp2 = _wGL_TEXTURE_MAX_ANISOTROPY; break; + } + if(selectedTex == 0 && boundTexture0 != null && pp2 == _wGL_TEXTURE_MAX_ANISOTROPY) { + boundTexture0.anisotropic = p3 > 1.0f; + } + _wglTexParameterf(pp1, pp2, p3); + updateAnisotropicPatch(); + } + public static final void glLogicOp(int p1) { + + } + public static final void glNormal3f(float p1, float p2, float p3) { + float len = (float) Math.sqrt(p1 * p1 + p2 * p2 + p3 * p3); + normalX = p1 / len; + normalY = p2 / len; + normalZ = p3 / len; + } + public static final int glGenLists(int p1) { + int base = displayListId + 1; + for(int i = 0; i < p1; i++) { + int id = ++displayListId; + displayLists.put(id, new DisplayList(id)); + } + return base; + } + public static final void _wglBindVertexArray0(BufferArrayGL p1) { + currentArray = p1; + _wglBindVertexArray(p1); + } + private static int displayListId = 0; + public static final void glCallList(int p1) { + if(!isCompilingDisplayList) { + DisplayList d = displayListsInitialized.get(p1); + if(d != null && d.listLength > 0) { + bindTheShader(d.shaderMode | getShaderModeFlag1()); + _wglBindVertexArray0(d.glarray); + _wglDrawQuadArrays(0, d.listLength); + shader.unuseProgram(); + vertexDrawn += d.listLength * 6 / 4; + triangleDrawn += d.listLength / 2; + } + } + } + public static final void glNewList(int p1, int p2) { + if(!isCompilingDisplayList) { + compilingDisplayList = displayLists.get(p1); + if(compilingDisplayList != null) { + compilingDisplayList.shaderMode = -1; + compilingDisplayList.listLength = 0; + isCompilingDisplayList = true; + } + } + } + public static final void glEndList() { + if(isCompilingDisplayList) { + isCompilingDisplayList = false; + Object upload = _wGetLowLevelBuffersAppended(); + int l = _wArrayByteLength(upload); + if(l > 0) { + if(compilingDisplayList.glbuffer == null) { + displayListsInitialized.put(compilingDisplayList.id, compilingDisplayList); + compilingDisplayList.glarray = _wglCreateVertexArray(); + compilingDisplayList.glbuffer = _wglCreateBuffer(); + FixedFunctionShader f = FixedFunctionShader.instance(compilingDisplayList.shaderMode); + _wglBindVertexArray0(compilingDisplayList.glarray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, compilingDisplayList.glbuffer); + f.setupArrayForProgram(); + } + _wglBindBuffer(_wGL_ARRAY_BUFFER, compilingDisplayList.glbuffer); + _wglBufferData(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + bytesUploaded += l; + } + } + } + public static final void glColor3f(float p1, float p2, float p3) { + colorR = p1; + colorG = p2; + colorB = p3; + colorA = 1.0f; + } + public static final void glTexGeni(int p1, int p2, int p3) { + + } + public static final void glTexGen(int p1, int p2, FloatBuffer p3) { + switch(p1) { + case GL_S: + texS_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texS_X = p3.get(); + texS_Y = p3.get(); + texS_Z = p3.get(); + texS_W = p3.get(); + break; + case GL_T: + texT_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texT_X = p3.get(); + texT_Y = p3.get(); + texT_Z = p3.get(); + texT_W = p3.get(); + break; + case GL_R: + texR_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texR_X = p3.get(); + texR_Y = p3.get(); + texR_Z = p3.get(); + texR_W = p3.get(); + break; + case GL_Q: + texQ_plane = (p2 == GL_EYE_PLANE ? 1 : 0); + texQ_X = p3.get(); + texQ_Y = p3.get(); + texQ_Z = p3.get(); + texQ_W = p3.get(); + break; + } + } + public static final void glTexImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + /* + int pp2 = 0; + switch(p3) { + default: + case GL_RGBA: pp2 = _wGL_RGBA; break; + case GL_BGRA: pp2 = _wGL_BGRA; break; + } + int pp3 = 0; + switch(p7) { + default: + case GL_RGBA: pp3 = _wGL_RGBA; break; + case GL_BGRA: pp3 = _wGL_BGRA; break; + } + */ + if(p2 == 0 && selectedTex == 0 && boundTexture0 != null) { + boundTexture0.w = p4; + boundTexture0.h = p5; + } + bytesUploaded += p9.remaining()*4; + _wglTexImage2D(_wGL_TEXTURE_2D, p2, _wGL_RGBA8, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + updateAnisotropicPatch(); + } + public static final void glTexImage2D_2(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + if(p2 == 0 && selectedTex == 0 && boundTexture0 != null) { + boundTexture0.w = p4; + boundTexture0.h = p5; + } + bytesUploaded += p9.remaining()*4; + _wglTexImage2D(_wGL_TEXTURE_2D, p2, _wGL_RGB8, p4, p5, p6, _wGL_RGB, _wGL_UNSIGNED_BYTE, p9); + updateAnisotropicPatch(); + } + public static final void glTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, IntBuffer p9) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + /* + int pp3 = 0; + switch(p7) { + default: + case GL_RGBA: pp3 = _wGL_RGBA; break; + case GL_BGRA: pp3 = _wGL_BGRA; break; + } + */ + bytesUploaded += p9.remaining()*4; + _wglTexSubImage2D(pp1, p2, p3, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glDeleteTextures(int p1) { + _wglDeleteTextures(texObjects.free(p1)); + } + public static final void glPolygonOffset(float p1, float p2) { + _wglPolygonOffset(p1, p2); + } + public static final void glCallLists(IntBuffer p1) { + while(p1.hasRemaining()) { + glCallList(p1.get()); + } + } + public static final void glEnableVertexAttrib(int p1) { + switch(p1) { + case GL_COLOR_ARRAY: + enableColorArray = true; + break; + case GL_NORMAL_ARRAY: + enableNormalArray = true; + break; + case GL_TEXTURE_COORD_ARRAY: + switch(selectedClientTex) { + case 0: + enableTex0Array = true; + break; + case 1: + enableTex1Array = true; + break; + default: + break; + } + break; + default: + break; + } + } + public static final void glDisableVertexAttrib(int p1) { + switch(p1) { + case GL_COLOR_ARRAY: + enableColorArray = false; + break; + case GL_NORMAL_ARRAY: + enableNormalArray = false; + break; + case GL_TEXTURE_COORD_ARRAY: + switch(selectedClientTex) { + case 0: + enableTex0Array = false; + break; + case 1: + enableTex1Array = false; + break; + default: + break; + } + break; + default: + break; + } + } + public static final void hintAnisotropicFix(boolean hint) { + hintAnisotropicPatch = hint; + } + private static final int getShaderModeFlag0() { + int mode = 0; + mode = (mode | (enableColorArray ? FixedFunctionShader.COLOR : 0)); + mode = (mode | (enableNormalArray ? FixedFunctionShader.NORMAL : 0)); + mode = (mode | (enableTex0Array ? FixedFunctionShader.TEXTURE0 : 0)); + mode = (mode | (enableTex1Array ? FixedFunctionShader.TEXTURE1 : 0)); + return mode; + } + private static final int getShaderModeFlag1() { + int mode = 0; + mode = (mode | (enableTexGen ? FixedFunctionShader.TEXGEN : 0)); + mode = (mode | ((enableColorMaterial && enableLighting) ? FixedFunctionShader.LIGHTING : 0)); + mode = (mode | (fogEnabled ? FixedFunctionShader.FOG : 0)); + mode = (mode | (enableAlphaTest ? FixedFunctionShader.ALPHATEST : 0)); + mode = (mode | (enableTexture2D ? FixedFunctionShader.UNIT0 : 0)); + mode = (mode | (enableTexture2D_1 ? FixedFunctionShader.UNIT1 : 0)); + mode = (mode | ((enableTexture2D && (enableAnisotropicFix || (hintAnisotropicPatch && enableAnisotropicPatch))) ? FixedFunctionShader.FIX_ANISOTROPIC : 0)); + return mode; + } + private static final int getShaderModeFlag() { + int mode = 0; + mode = (mode | (enableColorArray ? FixedFunctionShader.COLOR : 0)); + mode = (mode | (enableNormalArray ? FixedFunctionShader.NORMAL : 0)); + mode = (mode | (enableTex0Array ? FixedFunctionShader.TEXTURE0 : 0)); + mode = (mode | (enableTex1Array ? FixedFunctionShader.TEXTURE1 : 0)); + mode = (mode | (enableTexGen ? FixedFunctionShader.TEXGEN : 0)); + mode = (mode | ((enableColorMaterial && enableLighting) ? FixedFunctionShader.LIGHTING : 0)); + mode = (mode | (fogEnabled ? FixedFunctionShader.FOG : 0)); + mode = (mode | (enableAlphaTest ? FixedFunctionShader.ALPHATEST : 0)); + mode = (mode | (enableTexture2D ? FixedFunctionShader.UNIT0 : 0)); + mode = (mode | (enableTexture2D_1 ? FixedFunctionShader.UNIT1 : 0)); + mode = (mode | ((enableTexture2D && (enableAnisotropicFix || (hintAnisotropicPatch && enableAnisotropicPatch))) ? FixedFunctionShader.FIX_ANISOTROPIC : 0)); + return mode; + } + private static FixedFunctionShader shader = null; + private static final void bindTheShader() { + bindTheShader(getShaderModeFlag()); + } + private static final void bindTheShader(int mode) { + FixedFunctionShader s = shader = FixedFunctionShader.instance(mode); + s.useProgram(); + if(enableAlphaTest) { + s.setAlphaTest(alphaThresh); + } + s.setColor(colorR, colorG, colorB, colorA); + if(fogEnabled) { + s.setFogMode((fogPremultiply ? 2 : 0) + fogMode); + s.setFogColor(fogColorR, fogColorG, fogColorB, fogColorA); + s.setFogDensity(fogDensity); + s.setFogStartEnd(fogStart, fogEnd); + } + s.setModelMatrix(matModelV[matModelPointer]); + s.setProjectionMatrix(matProjV[matProjPointer]); + s.setTextureMatrix(matTexV[matTexPointer]); + if(enableColorMaterial && enableLighting) { + s.setNormal(normalX, normalY, normalZ); + s.setLightPositions(lightPos0vec, lightPos1vec); + } + s.setTex0Coords(tex0X, tex0Y); + s.setTex1Coords(tex1X, tex1Y); + if(enableTexGen) { + s.setTexGenS(texS_plane, texS_X, texS_Y, texS_Z, texS_W); + s.setTexGenT(texT_plane, texT_X, texT_Y, texT_Z, texT_W); + s.setTexGenR(texR_plane, texR_X, texR_Y, texR_Z, texR_W); + s.setTexGenQ(texQ_plane, texQ_X, texQ_Y, texQ_Z, texQ_W); + } + if(enableAnisotropicFix) { + s.setAnisotropicFix(anisotropicFixX, anisotropicFixY); + } + } + private static Object blankUploadArray = _wCreateLowLevelIntBuffer(525000); + public static final void glDrawArrays(int p1, int p2, int p3, Object buffer) { + if(isCompilingDisplayList) { + if(p1 == GL_QUADS) { + if(compilingDisplayList.shaderMode == -1) { + compilingDisplayList.shaderMode = getShaderModeFlag0(); + }else { + if(compilingDisplayList.shaderMode != getShaderModeFlag0()) { + System.err.println("vertex format inconsistent in display list"); + } + } + compilingDisplayList.listLength += p3; + _wAppendLowLevelBuffer(buffer); + }else { + System.err.println("only GL_QUADS supported in a display list"); + } + }else { + bytesUploaded += _wArrayByteLength(buffer); + vertexDrawn += p3; + + bindTheShader(); + + _wglBindVertexArray0(shader.genericArray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, shader.genericBuffer); + if(!shader.bufferIsInitialized) { + shader.bufferIsInitialized = true; + _wglBufferData(_wGL_ARRAY_BUFFER, blankUploadArray, _wGL_DYNAMIC_DRAW); + } + _wglBufferSubData(_wGL_ARRAY_BUFFER, 0, buffer); + + if(p1 == GL_QUADS) { + _wglDrawQuadArrays(p2, p3); + triangleDrawn += p3 / 2; + }else { + int drawMode = 0; + switch(p1) { + default: + case GL_TRIANGLES: + drawMode = _wGL_TRIANGLES; + triangleDrawn += p3 / 3; + break; + case GL_TRIANGLE_STRIP: + drawMode = _wGL_TRIANGLE_STRIP; + triangleDrawn += p3 - 2; + break; + case GL_TRIANGLE_FAN: + drawMode = _wGL_TRIANGLE_FAN; + triangleDrawn += p3 - 2; + break; + case GL_LINE_STRIP: + drawMode = _wGL_LINE_STRIP; + triangleDrawn += p3 - 1; + break; + case GL_LINES: + drawMode = _wGL_LINES; + triangleDrawn += p3 / 2; + break; + } + _wglDrawArrays(drawMode, p2, p3); + } + + shader.unuseProgram(); + + } + } + + private static final void _wglDrawQuadArrays(int p2, int p3) { + if(quadsToTrianglesBuffer == null) { + IntBuffer upload = isWebGL ? IntBuffer.wrap(new int[98400 / 2]) : ByteBuffer.allocateDirect(98400 * 2).order(ByteOrder.nativeOrder()).asIntBuffer(); + for(int i = 0; i < 16384; ++i) { + int v1 = i * 4; + int v2 = i * 4 + 1; + int v3 = i * 4 + 2; + int v4 = i * 4 + 3; + upload.put(v1 | (v2 << 16)); + upload.put(v4 | (v2 << 16)); + upload.put(v3 | (v4 << 16)); + } + upload.flip(); + quadsToTrianglesBuffer = _wglCreateBuffer(); + _wglBindBuffer(_wGL_ELEMENT_ARRAY_BUFFER, quadsToTrianglesBuffer); + _wglBufferData0(_wGL_ELEMENT_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + } + if(!currentArray.isQuadBufferBound) { + currentArray.isQuadBufferBound = true; + _wglBindBuffer(_wGL_ELEMENT_ARRAY_BUFFER, quadsToTrianglesBuffer); + } + _wglDrawElements(_wGL_TRIANGLES, p3 * 6 / 4, _wGL_UNSIGNED_SHORT, p2 * 6 / 4); + } + + + private static BufferArrayGL occlusion_vao = null; + private static BufferGL occlusion_vbo = null; + private static ProgramGL occlusion_program = null; + private static UniformGL occlusion_matrix_m = null; + private static UniformGL occlusion_matrix_p = null; + + private static final void initializeOcclusionObjects() { + occlusion_vao = _wglCreateVertexArray(); + occlusion_vbo = _wglCreateBuffer(); + + IntBuffer upload = (isWebGL ? IntBuffer.wrap(new int[108]) : ByteBuffer.allocateDirect(108 << 2).order(ByteOrder.nativeOrder()).asIntBuffer()); + float[] verts = new float[] { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f + }; + for(int i = 0; i < verts.length; i++) { + upload.put(Float.floatToRawIntBits(verts[i])); + } + upload.flip(); + + _wglBindVertexArray(occlusion_vao); + _wglBindBuffer(_wGL_ARRAY_BUFFER, occlusion_vbo); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 3, _wGL_FLOAT, false, 12, 0); + + ShaderGL vert = _wglCreateShader(_wGL_VERTEX_SHADER); + ShaderGL frag = _wglCreateShader(_wGL_FRAGMENT_SHADER); + + String src = fileContents("/glsl/occl.glsl"); + _wglShaderSource(vert, _wgetShaderHeader() + "\n#define CC_VERT\n" + src); + _wglShaderSource(frag, _wgetShaderHeader() + "\n#define CC_FRAG\n" + src); + + _wglCompileShader(vert); + if (!_wglGetShaderCompiled(vert)) System.err.println(("\n" + _wglGetShaderInfoLog(vert)).replace("\n", "\n[/glsl/occl.glsl][VERT] ") + "\n"); + + _wglCompileShader(frag); + if (!_wglGetShaderCompiled(frag)) System.err.println(("\n" + _wglGetShaderInfoLog(frag)).replace("\n", "\n[/glsl/occl.glsl][FRAG] ") + "\n"); + + occlusion_program = _wglCreateProgram(); + + _wglAttachShader(occlusion_program, vert); + _wglAttachShader(occlusion_program, frag); + _wglLinkProgram(occlusion_program); + _wglDetachShader(occlusion_program, vert); + _wglDetachShader(occlusion_program, frag); + _wglDeleteShader(vert); + _wglDeleteShader(frag); + + if(!_wglGetProgramLinked(occlusion_program)) System.err.println(("\n\n"+_wglGetProgramInfoLog(occlusion_program)).replace("\n", "\n[/glsl/occl.glsl][LINKER] ")); + + _wglUseProgram(occlusion_program); + occlusion_matrix_m = _wglGetUniformLocation(occlusion_program, "matrix_m"); + occlusion_matrix_p = _wglGetUniformLocation(occlusion_program, "matrix_p"); + + } + + private static final GLObjectMap queryObjs = new GLObjectMap(256); + + public static final int glCreateQuery() { + return queryObjs.register(_wglCreateQuery()); + } + + public static final void glBeginQuery(int obj) { + _wglBeginQuery(_wGL_ANY_SAMPLES_PASSED, queryObjs.get(obj)); + } + + public static final void glDeleteQuery(int obj) { + _wglDeleteQuery(queryObjs.free(obj)); + } + + private static final Matrix4f cachedOcclusionP = (Matrix4f) (new Matrix4f()).setZero(); + private static float[] occlusionModel = new float[16]; + private static float[] occlusionProj = new float[16]; + + public static final void glBindOcclusionBB() { + if(occlusion_vao == null) initializeOcclusionObjects(); + _wglUseProgram(occlusion_program); + _wglBindVertexArray(occlusion_vao); + if(!cachedOcclusionP.equals(matProjV[matProjPointer])) { + cachedOcclusionP.load(matProjV[matProjPointer]); + cachedOcclusionP.store(occlusionProj); + _wglUniformMat4fv(occlusion_matrix_p, occlusionProj); + } + } + + public static final void glEndOcclusionBB() { + + } + + public static final void glDrawOcclusionBB(float posX, float posY, float posZ, float sizeX, float sizeY, float sizeZ) { + glPushMatrix(); + glTranslatef(posX - sizeX * 0.0001f, posY - sizeY * 0.0001f, posZ - sizeZ * 0.0001f); + glScalef(sizeX * 1.0002f, sizeY * 1.0002f, sizeZ * 1.0002f); + matModelV[matModelPointer].store(occlusionModel); + _wglUniformMat4fv(occlusion_matrix_m, occlusionModel); + _wglDrawArrays(_wGL_TRIANGLES, 0, 36); + glPopMatrix(); + //glPushMatrix(); + //glTranslatef(posX + sizeX * 0.0001f, posY + sizeY * 0.0001f, posZ + sizeZ * 0.0001f); + //glScalef(sizeX * 0.9998f, sizeY * 0.9998f, sizeZ * 0.9998f); + //matModelV[matModelPointer].store(occlusionModel); + //_wglUniformMat4fv(occlusion_matrix_m, occlusionModel); + //_wglDrawArrays(_wGL_TRIANGLES, 0, 36); + //glPopMatrix(); + + } + + public static final void glEndQuery() { + _wglEndQuery(_wGL_ANY_SAMPLES_PASSED); + } + + public static final boolean glGetQueryResult(int obj) { + QueryGL q = queryObjs.get(obj); + return _wglGetQueryObjecti(q, _wGL_QUERY_RESULT_AVAILABLE) == 0 || _wglGetQueryObjecti(q, _wGL_QUERY_RESULT) > 0; + } + + public static final int glGenTextures() { + return texObjects.register(_wglGenTextures()); + } + public static final void glTexSubImage2D(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, ByteBuffer p9) { + int pp1 = 0; + switch(p1) { + default: + case GL_TEXTURE_2D: pp1 = _wGL_TEXTURE_2D; break; + //case GL_TEXTURE_3D: pp1 = _wGL_TEXTURE_3D; break; + } + /* + int pp3 = 0; + switch(p7) { + default: + case GL_RGBA: pp3 = _wGL_RGBA; break; + case GL_BGRA: pp3 = _wGL_BGRA; break; + } + */ + bytesUploaded += p9.remaining(); + _wglTexSubImage2D(pp1, p2, p3, p4, p5, p6, _wGL_RGBA, _wGL_UNSIGNED_BYTE, p9); + } + public static final void glFogi(int p1, int p2) { + if(p1 == GL_FOG_MODE) { + switch(p2) { + default: + case GL_LINEAR: + fogMode = 1; + break; + case GL_EXP: + fogMode = 2; + break; + } + } + } + public static final void glFogf(int p1, float p2) { + switch(p1) { + case GL_FOG_START: + fogStart = p2; + break; + case GL_FOG_END: + fogEnd = p2; + break; + case GL_FOG_DENSITY: + fogDensity = p2; + break; + default: + break; + } + } + public static final void glFog(int p1, FloatBuffer p2) { + if(p1 == GL_FOG_COLOR) { + fogColorR = p2.get(); + fogColorG = p2.get(); + fogColorB = p2.get(); + fogColorA = p2.get(); + } + } + public static final void glDeleteLists(int p1, int p2) { + for(int i = 0; i < p2; i++) { + DisplayList d = displayListsInitialized.remove(p1 + i); + if(d != null) { + _wglDeleteVertexArray(d.glarray); + _wglDeleteBuffer(d.glbuffer); + } + displayLists.remove(p1 + i); + } + } + public static final void glActiveTexture(int p1) { + switch(p1) { + case GL_TEXTURE0: + selectedTex = 0; + _wglActiveTexture(_wGL_TEXTURE0); + break; + case GL_TEXTURE1: + selectedTex = 1; + _wglActiveTexture(_wGL_TEXTURE1); + break; + default: + System.err.println("only two texture units implemented"); + break; + } + } + public static final void glClientActiveTexture(int p1) { + switch(p1) { + case GL_TEXTURE0: + selectedClientTex = 0; + break; + case GL_TEXTURE1: + selectedClientTex = 1; + break; + default: + System.err.println("only two texture units implemented"); + break; + } + } + public static final void glMultiTexCoord2f(int p1, float p2, float p3) { + switch(p1) { + case GL_TEXTURE0: + tex0X = p2; + tex0Y = p3; + break; + case GL_TEXTURE1: + tex1X = p2; + tex1Y = p3; + break; + default: + System.err.println("only two texture units implemented"); + break; + } + } + private static Matrix4f unprojA = new Matrix4f(); + private static Matrix4f unprojB = new Matrix4f(); + private static Vector4f unprojC = new Vector4f(); + public static final void gluUnProject(float p1, float p2, float p3, FloatBuffer p4, FloatBuffer p5, int[] p6, FloatBuffer p7) { + unprojA.load(p4); + unprojB.load(p5); + Matrix4f.mul(unprojA, unprojB, unprojB); + unprojB.invert(); + unprojC.set(((p1 - (float)p6[0]) / (float)p6[2]) * 2f - 1f, ((p2 - (float)p6[1]) / (float)p6[3]) * 2f - 1f, p3, 1.0f); + Matrix4f.transform(unprojB, unprojC, unprojC); + p7.put(unprojC.x / unprojC.w); + p7.put(unprojC.y / unprojC.w); + p7.put(unprojC.z / unprojC.w); + } + public static final void gluPerspective(float fovy, float aspect, float zNear, float zFar) { + Matrix4f res = getMatrix(); + float cotangent = (float) Math.cos(fovy * toRad * 0.5f) / (float) Math.sin(fovy * toRad * 0.5f); + res.m00 = cotangent / aspect; + res.m01 = 0.0f; + res.m02 = 0.0f; + res.m03 = 0.0f; + res.m10 = 0.0f; + res.m11 = cotangent; + res.m12 = 0.0f; + res.m13 = 0.0f; + res.m20 = 0.0f; + res.m21 = 0.0f; + res.m22 = (zFar + zNear) / (zFar - zNear); + res.m23 = -1.0f; + res.m30 = 0.0f; + res.m31 = 0.0f; + res.m32 = 2.0f * zFar * zNear / (zFar - zNear); + res.m33 = 0.0f; + } + public static final void gluPerspectiveFlat(float fovy, float aspect, float zNear, float zFar) { + Matrix4f res = getMatrix(); + float cotangent = (float) Math.cos(fovy * toRad * 0.5f) / (float) Math.sin(fovy * toRad * 0.5f); + res.m00 = cotangent / aspect; + res.m01 = 0.0f; + res.m02 = 0.0f; + res.m03 = 0.0f; + res.m10 = 0.0f; + res.m11 = cotangent; + res.m12 = 0.0f; + res.m13 = 0.0f; + res.m20 = 0.0f; + res.m21 = 0.0f; + res.m22 = ((zFar + zNear) / (zFar - zNear)) * 0.001f; + res.m23 = -1.0f; + res.m30 = 0.0f; + res.m31 = 0.0f; + res.m32 = 2.0f * zFar * zNear / (zFar - zNear); + res.m33 = 0.0f; + } + public static final String gluErrorString(int p1) { + switch(p1) { + case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; + case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; + case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; + case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; + case GL_CONTEXT_LOST_WEBGL: return "CONTEXT_LOST_WEBGL"; + default: return "Unknown Error"; + } + } + private static long lastBandwidthReset = 0l; + private static int lastBandwidth = 0; + public static final int getBitsPerSecond() { + if(System.currentTimeMillis() - lastBandwidthReset > 1000) { + lastBandwidthReset = System.currentTimeMillis(); + lastBandwidth = bytesUploaded * 8; + bytesUploaded = 0; + } + return lastBandwidth; + } + public static final int getVertexesPerSecond() { + int ret = vertexDrawn; + vertexDrawn = 0; + return ret; + } + public static final int getTrianglesPerSecond() { + int ret = triangleDrawn; + triangleDrawn = 0; + return ret; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipeline.java b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipeline.java new file mode 100644 index 0000000..037adba --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipeline.java @@ -0,0 +1,482 @@ +package net.lax1dude.eaglercraft.glemu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.util.HashMap; + +import net.lax1dude.eaglercraft.EaglercraftRandom; +import net.lax1dude.eaglercraft.glemu.vector.Matrix4f; + +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wGL_CULL_FACE; +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wglDisable; +import static net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30.*; + +public class EffectPipeline { + + private static String[] pipeline_tmp = null; + public static String[] pipeline = new String[0]; + private static HashMap programs = new HashMap(); + private static HashMap uniforms = new HashMap(); + + private static FramebufferGL framebuffer; + private static FramebufferGL framebuffer1; + private static FramebufferGL framebuffer2; + private static TextureGL framebuffer_color; + private static TextureGL framebuffer_color1; + private static TextureGL framebuffer_color2; + private static TextureGL framebuffer_depth; + + private static FramebufferGL framebuffer_bloom_a = null; + private static TextureGL framebuffer_bloom_a_color = null; + private static FramebufferGL framebuffer_bloom_b = null; + private static TextureGL framebuffer_bloom_b_color = null; + + private static BufferArrayGL renderQuadArray; + private static BufferGL renderQuadBuffer; + + private static ShaderGL pvert_shader; + + private static int width = -1; + private static int height = -1; + + private static int[] originalViewport = null; + + public static void init() { + framebuffer = _wglCreateFramebuffer(); + //framebuffer1 = _wglCreateFramebuffer(); + //framebuffer2 = _wglCreateFramebuffer(); + framebuffer_color = _wglGenTextures(); + //framebuffer_color1 = _wglGenTextures(); + //framebuffer_color2 = _wglGenTextures(); + framebuffer_depth = _wglGenTextures(); + pvert_shader = _wglCreateShader(_wGL_VERTEX_SHADER); + + _wglShaderSource(pvert_shader, _wgetShaderHeader() + "\n" + fileContents("/glsl/pvert.glsl")); + _wglCompileShader(pvert_shader); + + if (!_wglGetShaderCompiled(pvert_shader)) System.err.println(("\n" + _wglGetShaderInfoLog(pvert_shader)).replace("\n", "\n[/glsl/pvert.glsl] ") + "\n"); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color1); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color2); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + //_wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_depth); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_color); + _wglFramebufferTexture2D(_wGL_DEPTH_STENCIL_ATTACHMENT, framebuffer_depth); + + //_wglBindFramebuffer(framebuffer1); + //_wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_color1); + + //_wglBindFramebuffer(framebuffer2); + //_wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_color2); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + + renderQuadArray = _wglCreateVertexArray(); + renderQuadBuffer = _wglCreateBuffer(); + IntBuffer upload = (isWebGL ? IntBuffer.wrap(new int[12]) : ByteBuffer.allocateDirect(12 << 2).order(ByteOrder.nativeOrder()).asIntBuffer()); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.flip(); + _wglBindBuffer(_wGL_ARRAY_BUFFER, renderQuadBuffer); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + _wglBindVertexArray(renderQuadArray); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + } + + public static void beginPipelineRender() { + if (pipeline_tmp != null) { + pipeline = pipeline_tmp; + pipeline_tmp = null; + } + + if (pipeline.length > 0) { + int[] viewport = new int[4]; + _wglGetParameter(_wGL_VIEWPORT, 4, viewport); + if (width != viewport[2] || height != viewport[3]) { + System.out.println("setting up framebuffer textures"); + width = viewport[2]; + height = viewport[3]; + originalViewport = viewport; + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color1); + //_wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + //_wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color2); + //_wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_depth); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_DEPTH24_STENCIL8, width, height, 0, _wGL_DEPTH_STENCIL, _wGL_UNSIGNED_INT_24_8, (ByteBuffer) null); + } + + _wglActiveTexture(_wGL_TEXTURE1); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, null); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglViewport(0, 0, width, height); + } + + } + + private static boolean framebufferFlip = false; + + private static int bloom_width = -1; + private static int bloom_height = -1; + + public static void reloadPipeline() { + System.out.println("reloading "+pipeline.length+" pipeline shader programs"); + String[] tmp1 = pipeline; + String[] tmp = programs.keySet().toArray(new String[0]); + for(ProgramGL i : programs.values()) { + _wglDeleteProgram(i); + } + programs.clear(); + uniforms.clear(); + setupPipeline(tmp1, tmp); + } + + public static void endPipelineRender() { + if (pipeline.length > 0) { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + + _wglDisable(_wGL_DEPTH_TEST); + _wglDisable(_wGL_CULL_FACE); + _wglDepthMask(true); + + _wglActiveTexture(_wGL_TEXTURE1); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_depth); + _wglActiveTexture(_wGL_TEXTURE0); + + _wglBindVertexArray(renderQuadArray); + + for(int i = 0; i < pipeline.length; ++i) { + framebufferFlip = !framebufferFlip; + if(i == 0) { + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + }else { + _wglBindTexture(_wGL_TEXTURE_2D, framebufferFlip ? framebuffer_color2 : framebuffer_color1); + } + + if(i == pipeline.length - 1) { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + }else { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebufferFlip ? framebuffer1 : framebuffer2); + _wglViewport(0, 0, width, height); + } + + _wglActiveTexture(_wGL_TEXTURE0); + + ProgramGL prog = programs.get(pipeline[i]); + _wglUseProgram(prog); + setUniforms(uniforms.get(pipeline[i])); + + _wglActiveTexture(_wGL_TEXTURE0); + if(i == 0) { + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_color); + }else { + _wglBindTexture(_wGL_TEXTURE_2D, framebufferFlip ? framebuffer_color2 : framebuffer_color1); + } + + if(i == pipeline.length - 1) { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + }else { + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebufferFlip ? framebuffer1 : framebuffer2); + _wglViewport(0, 0, width, height); + } + + _wglUseProgram(prog); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE1); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE2); + _wglBindTexture(_wGL_TEXTURE_2D, null); + _wglActiveTexture(_wGL_TEXTURE0); + } + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + } + } + + private static final EaglercraftRandom deevis = new EaglercraftRandom(); + + private static float[] projBuffer = new float[16]; + private static float[] projBufferInv = new float[16]; + private static Matrix4f projectionMatrix = (Matrix4f) new Matrix4f().setZero(); + private static Matrix4f projectionMatrixInv = (Matrix4f) new Matrix4f().setZero(); + + private static long randomInterTimer = 0l; + private static float randomInterA = 0.0f; + private static float randomInterB = 0.0f; + + private static void setUniforms(UniformGL[] is) { + if(is[0] != null) { + _wglUniform2f(is[0], width, height); + } + if(is[1] != null) { + _wglUniform1f(is[1], deevis.nextFloat()); + } + if(is[2] != null) { + /* + _wglUniform1i(is[2], 2); + makeSSAOTexture(); + _wglActiveTexture(_wGL_TEXTURE2); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_ssao_color); + _wglActiveTexture(_wGL_TEXTURE0); + */ + } + if((is[3] != null || is[4] != null) && !projectionMatrix.equals(matProjV[matProjPointer])) { + projectionMatrix.load(matProjV[matProjPointer]); + if(is[3] != null) { + projectionMatrix.store(projBuffer); + _wglUniformMat4fv(is[3], projBuffer); + } + if(is[4] != null) { + Matrix4f.invert(projectionMatrix, projectionMatrixInv); + projectionMatrixInv.store(projBufferInv); + _wglUniformMat4fv(is[4], projBufferInv); + } + } + if(is[5] != null) { + _wglUniform1i(is[5], 2); + makeBloomTexture(); + _wglActiveTexture(_wGL_TEXTURE2); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_LINEAR); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_LINEAR); + _wglActiveTexture(_wGL_TEXTURE0); + } + if(is[7] != null) { + long time = System.currentTimeMillis(); + if(time - randomInterTimer > 140l) { + randomInterTimer = time; + randomInterB = randomInterA; + randomInterA = deevis.nextFloat(); + } + _wglUniform2f(is[7], randomInterA, randomInterB); + float r = ((float)(time - randomInterTimer) / 140.0f); + _wglUniform1f(is[8], 0 - 2 * r * r * r + 3 * r * r); + } + } + + private static void makeBloomTexture() { + if(framebuffer_bloom_a == null) { + framebuffer_bloom_a = _wglCreateFramebuffer(); + framebuffer_bloom_a_color = _wglGenTextures(); + framebuffer_bloom_b = _wglCreateFramebuffer(); + framebuffer_bloom_b_color = _wglGenTextures(); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_b_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_a); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_bloom_a_color); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_b); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_bloom_b_color); + } + + int w = width / 4; + int h = height / 4; + if(bloom_width != w || bloom_height != h) { + bloom_width = w; + bloom_height = h; + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, bloom_width, bloom_height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_b_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, bloom_width, bloom_height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + } + + int[] viewport = new int[4]; + _wglGetParameter(_wGL_VIEWPORT, 4, viewport); + + _wglActiveTexture(_wGL_TEXTURE0); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_a); + _wglViewport(0, 0, bloom_width, bloom_height); + UniformGL i; + _wglUseProgram(programs.get("/glsl/bloom_a.glsl")); + i = uniforms.get("/glsl/bloom_a.glsl")[0]; + _wglUniform2i(i, bloom_width, bloom_height); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_b); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_a_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglUseProgram(programs.get("/glsl/bloom_b.glsl")); + i = uniforms.get("/glsl/bloom_b.glsl")[0]; + UniformGL j = uniforms.get("/glsl/bloom_b.glsl")[6]; + _wglUniform2i(i, bloom_width, bloom_height); + _wglUniform2i(j, 0, 1); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglBindTexture(_wGL_TEXTURE_2D, null); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer_bloom_a); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_bloom_b_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglUniform2i(j, 1, 0); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglBindTexture(_wGL_TEXTURE_2D, null); + + _wglViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + + } + + /* + private static void makeSSAOTexture() { + if(framebuffer_ssao == -1) { + framebuffer_ssao = _wglCreateFramebuffer(); + framebuffer_ssao_color = _wglGenTextures(); + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_ssao_color); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_LINEAR); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_LINEAR); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + + _wglBindFramebuffer(framebuffer_ssao); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, framebuffer_ssao_color); + } + + int sssao_width = width; + int sssao_height = height; + if(sssao_width != ssao_width || sssao_height != ssao_height) { + ssao_width = sssao_width; + ssao_height = sssao_height; + + _wglBindTexture(_wGL_TEXTURE_2D, framebuffer_ssao_color); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB, ssao_width, ssao_height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer) null); + } + + int[] viewport = _wglGetParameter(_wGL_VIEWPORT, 4); + _wglBindFramebuffer(framebuffer_ssao); + _wglViewport(0, 0, ssao_width, ssao_height); + _wglUseProgram(programs.get("/glsl/ssao_a.glsl")); + setUniforms(uniforms.get("/glsl/ssao_a.glsl")); + _wglColorMask(true, false, false, false); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglColorMask(true, true, true, true); + _wglViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + } + */ + + public static void setupPipeline(String[] shaders, String[] load) { + pipeline_tmp = shaders; + for(int i = 0; i < load.length; i++) { + if(!programs.containsKey(load[i])) { + ProgramGL prog = _wglCreateProgram(); + ShaderGL f = _wglCreateShader(_wGL_FRAGMENT_SHADER); + + _wglShaderSource(f, _wgetShaderHeader() + "\n" + fileContents(load[i])); + _wglCompileShader(f); + + if (!_wglGetShaderCompiled(f)) System.err.println(("\n" + _wglGetShaderInfoLog(f)).replace("\n", "\n["+load[i]+"][CC_FRAG] ") + "\n"); + + _wglAttachShader(prog, pvert_shader); + _wglAttachShader(prog, f); + _wglBindAttributeLocation(prog, 0, "a_pos"); + _wglLinkProgram(prog); + _wglDetachShader(prog, pvert_shader); + _wglDetachShader(prog, f); + _wglDeleteShader(f); + + if(!_wglGetProgramLinked(prog)) { + System.err.println(("\n"+_wglGetProgramInfoLog(prog)).replace("\n", "\n["+load[i]+"][LINKER] ") + "\n"); + pipeline_tmp = new String[0]; + return; + } + + _wglUseProgram(prog); + + UniformGL c = _wglGetUniformLocation(prog, "f_color"); + if(c != null) _wglUniform1i(c, 0); + UniformGL d = _wglGetUniformLocation(prog, "f_depth"); + if(d != null) _wglUniform1i(d, 1); + + + if(_wglGetUniformLocation(prog, "ssao_kernel[0]") != null) { + EaglercraftRandom r = new EaglercraftRandom("eeeaglerrENOPHILEr".hashCode()); + for(int j = 0; j < 24; j++) { + float x = r.nextFloat() * 2.0f - 1.0f; + float y = r.nextFloat() * 2.0f - 1.0f; + float z = r.nextFloat() * 2.0f - 1.0f; + + float s = 0.3f + 0.7f * r.nextFloat(); + float hypot = (1.0f / (float) Math.sqrt(x*x + y*y + z*z)) * s; + x *= hypot; + y *= hypot; + z *= hypot; + + _wglUniform3f(_wglGetUniformLocation(prog, "ssao_kernel["+j+"]"), x, y, z); + } + } + + programs.put(load[i], prog); + uniforms.put(load[i], new UniformGL[] { + _wglGetUniformLocation(prog, "screenSize"), + _wglGetUniformLocation(prog, "randomFloat"), + _wglGetUniformLocation(prog, "f_ssao"), + _wglGetUniformLocation(prog, "matrix_p"), + _wglGetUniformLocation(prog, "matrix_p_inv"), + _wglGetUniformLocation(prog, "f_bloom"), + _wglGetUniformLocation(prog, "direction"), + _wglGetUniformLocation(prog, "randomInter"), + _wglGetUniformLocation(prog, "randomInterF") + }); + } + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipelineFXAA.java b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipelineFXAA.java new file mode 100644 index 0000000..6e5feda --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/EffectPipelineFXAA.java @@ -0,0 +1,235 @@ +package net.lax1dude.eaglercraft.glemu; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.minecraft.client.Minecraft; + +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wGL_DEPTH_TEST; +import static net.lax1dude.eaglercraft.adapter.EaglerAdapterImpl2._wglDisable; +import static net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30.*; + +public class EffectPipelineFXAA { + + private static boolean isUsingFXAA = false; + + private static FramebufferGL framebuffer = null; + private static RenderbufferGL framebuffer_color = null; + private static RenderbufferGL framebuffer_depth = null; + + private static ProgramGL fxaaProgram = null; + private static TextureGL fxaaSourceTexture = null; + private static UniformGL fxaaScreenSize = null; + + private static BufferArrayGL renderQuadArray = null; + private static BufferGL renderQuadBuffer; + + public static int displayWidth = -1; + public static int displayHeight = -1; + public static int width = -1; + public static int height = -1; + + private static int[] originalViewport = new int[4]; + + private static int state = 1; + private static int newState = -1; + private static boolean msaaInit = false; + + private static void initFXAA() { + if(fxaaProgram == null) { + renderQuadArray = _wglCreateVertexArray(); + renderQuadBuffer = _wglCreateBuffer(); + + IntBuffer upload = (isWebGL ? IntBuffer.wrap(new int[12]) : ByteBuffer.allocateDirect(12 << 2).order(ByteOrder.nativeOrder()).asIntBuffer()); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.put(Float.floatToRawIntBits(0.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(1.0f)); + upload.put(Float.floatToRawIntBits(1.0f)); upload.put(Float.floatToRawIntBits(0.0f)); + upload.flip(); + + _wglBindVertexArray(renderQuadArray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, renderQuadBuffer); + _wglBufferData0(_wGL_ARRAY_BUFFER, upload, _wGL_STATIC_DRAW); + _wglEnableVertexAttribArray(0); + _wglVertexAttribPointer(0, 2, _wGL_FLOAT, false, 8, 0); + + ShaderGL pvert_shader = _wglCreateShader(_wGL_VERTEX_SHADER); + + _wglShaderSource(pvert_shader, _wgetShaderHeader() + "\n" + fileContents("/glsl/pvert.glsl")); + _wglCompileShader(pvert_shader); + + if (!_wglGetShaderCompiled(pvert_shader)) System.err.println(("\n" + _wglGetShaderInfoLog(pvert_shader)).replace("\n", "\n[/glsl/pvert.glsl] ") + "\n"); + + ShaderGL fxaa_shader = _wglCreateShader(_wGL_FRAGMENT_SHADER); + _wglShaderSource(fxaa_shader, _wgetShaderHeader() + "\n" + fileContents("/glsl/fxaa.glsl")); + _wglCompileShader(fxaa_shader); + + if (!_wglGetShaderCompiled(fxaa_shader)) System.err.println(("\n" + _wglGetShaderInfoLog(fxaa_shader)).replace("\n", "\n[/glsl/fxaa.glsl] ") + "\n"); + + fxaaProgram = _wglCreateProgram(); + _wglAttachShader(fxaaProgram, pvert_shader); + _wglAttachShader(fxaaProgram, fxaa_shader); + _wglLinkProgram(fxaaProgram); + _wglDetachShader(fxaaProgram, pvert_shader); + _wglDetachShader(fxaaProgram, fxaa_shader); + _wglDeleteShader(pvert_shader); + _wglDeleteShader(fxaa_shader); + + if(!_wglGetProgramLinked(fxaaProgram)) { + System.err.println(("\n"+_wglGetProgramInfoLog(fxaaProgram)).replace("\n", "\n[/glsl/fxaa.glsl][LINKER] ") + "\n"); + fxaaProgram = null; + throw new RuntimeException("Invalid shader code"); + } + + _wglUseProgram(fxaaProgram); + + UniformGL c = _wglGetUniformLocation(fxaaProgram, "f_color"); + if(c != null) _wglUniform1i(c, 0); + + fxaaScreenSize = _wglGetUniformLocation(fxaaProgram, "screenSize"); + } + + destroy(); + + isUsingFXAA = true; + framebuffer = _wglCreateFramebuffer(); + fxaaSourceTexture = _wglGenTextures(); + + _wglBindTexture(_wGL_TEXTURE_2D, fxaaSourceTexture); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MAG_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_MIN_FILTER, _wGL_NEAREST); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_S, _wGL_CLAMP); + _wglTexParameteri(_wGL_TEXTURE_2D, _wGL_TEXTURE_WRAP_T, _wGL_CLAMP); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB8, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer)null); + + + framebuffer_depth = _wglCreateRenderBuffer(); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorage(_wGL_DEPTH_COMPONENT32F, width, height); + + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglFramebufferTexture2D(_wGL_COLOR_ATTACHMENT0, fxaaSourceTexture); + _wglFramebufferRenderbuffer(_wGL_DEPTH_ATTACHMENT, framebuffer_depth); + } + + private static void initMSAA() { + destroy(); + msaaInit = true; + framebuffer = _wglCreateFramebuffer(); + framebuffer_color = _wglCreateRenderBuffer(); + framebuffer_depth = _wglCreateRenderBuffer(); + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglBindRenderbuffer(framebuffer_color); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_RGB8, width, height); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_DEPTH_COMPONENT32F, width, height); + _wglFramebufferRenderbuffer(_wGL_COLOR_ATTACHMENT0, framebuffer_color); + _wglFramebufferRenderbuffer(_wGL_DEPTH_ATTACHMENT, framebuffer_depth); + } + + public static void destroy() { + isUsingFXAA = false; + msaaInit = false; + if(framebuffer != null) _wglDeleteFramebuffer(framebuffer); + if(framebuffer_color != null) _wglDeleteRenderbuffer(framebuffer_color); + if(framebuffer_depth != null) _wglDeleteRenderbuffer(framebuffer_depth); + if(fxaaSourceTexture != null) _wglDeleteTextures(fxaaSourceTexture); + framebuffer = null; + framebuffer_color = null; + framebuffer_depth = null; + fxaaSourceTexture = null; + } + + public static void beginPipelineRender() { + if(displayWidth <= 0 || displayHeight <= 0) { + return; + } + int mode = 1; //Minecraft.getMinecraft().gameSettings.antialiasMode; //TODO: add + if(mode == 0) newState = 0; + if(mode == 1) newState = Minecraft.getMinecraft().gameSettings.fancyGraphics ? 1 : 0; + if(mode == 2) newState = 1; + if(mode == 3) newState = 2; + if(mode == 4) newState = 3; + if(newState == 0) { + state = newState; + destroy(); + return; + } + if(newState != state && !(newState == 3 && state == 2)) { + destroy(); + } + //_wglGetParameter(_wGL_VIEWPORT, 4, originalViewport); + if (displayWidth != width || displayHeight != height || state != newState) { + state = newState; + width = displayWidth; + height = displayHeight; + originalViewport[0] = 0; + originalViewport[1] = 0; + originalViewport[2] = width; + originalViewport[3] = height; + if(state == 1) { + if(isUsingFXAA == false) { + initFXAA(); + }else { + _wglBindTexture(_wGL_TEXTURE_2D, fxaaSourceTexture); + _wglTexImage2D(_wGL_TEXTURE_2D, 0, _wGL_RGB8, width, height, 0, _wGL_RGB, _wGL_UNSIGNED_BYTE, (ByteBuffer)null); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorage(_wGL_DEPTH_COMPONENT32F, width, height); + } + }else if(state == 2 || state == 3) { + if(msaaInit == false) { + initMSAA(); + }else { + _wglBindRenderbuffer(framebuffer_color); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_RGB8, width, height); + _wglBindRenderbuffer(framebuffer_depth); + _wglRenderbufferStorageMultisample(state == 2 ? 4 : 8, _wGL_DEPTH_COMPONENT32F, width, height); + } + } + } + _wglBindFramebuffer(_wGL_FRAMEBUFFER, framebuffer); + _wglViewport(0, 0, width, height); + if(!EaglerAdapter.isWebGL && (state == 2 || state == 3)) { + _wglEnable(_wGL_MULTISAMPLE); + _wglEnable(_wGL_LINE_SMOOTH); + } + } + + public static void endPipelineRender() { + if(displayWidth <= 0 || displayHeight <= 0 || state == 0) { + return; + } + _wglBindFramebuffer(_wGL_FRAMEBUFFER, null); + _wglClear(_wGL_COLOR_BUFFER_BIT | _wGL_DEPTH_BUFFER_BIT); + if(state == 1) { + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + _wglActiveTexture(_wGL_TEXTURE0); + _wglBindTexture(_wGL_TEXTURE_2D, fxaaSourceTexture); + _wglDisable(_wGL_DEPTH_TEST); + _wglDisable(_wGL_CULL_FACE); + _wglDepthMask(false); + _wglUseProgram(fxaaProgram); + _wglUniform2f(fxaaScreenSize, width, height); + _wglBindVertexArray(renderQuadArray); + _wglDrawArrays(_wGL_TRIANGLES, 0, 6); + _wglEnable(_wGL_DEPTH_TEST); + _wglDepthMask(true); + }else if(state == 2 || state == 3) { + if(!EaglerAdapter.isWebGL) { + _wglDisable(_wGL_MULTISAMPLE); + _wglDisable(_wGL_LINE_SMOOTH); + } + _wglViewport(originalViewport[0], originalViewport[1], originalViewport[2], originalViewport[3]); + _wglBindFramebuffer(_wGL_READ_FRAMEBUFFER, framebuffer); + _wglBindFramebuffer(_wGL_DRAW_FRAMEBUFFER, null); + _wglDrawBuffer(_wGL_BACK); + _wglBlitFramebuffer(0, 0, width, height, 0, 0, width, height, _wGL_COLOR_BUFFER_BIT, _wGL_NEAREST); + _wglBindFramebuffer(_wGL_READ_FRAMEBUFFER, null); + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/FixedFunctionShader.java b/src/main/java/net/lax1dude/eaglercraft/glemu/FixedFunctionShader.java new file mode 100644 index 0000000..799c6f7 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/FixedFunctionShader.java @@ -0,0 +1,503 @@ +package net.lax1dude.eaglercraft.glemu; + +import net.lax1dude.eaglercraft.EaglerAdapter; +import net.lax1dude.eaglercraft.glemu.vector.Matrix4f; +import net.lax1dude.eaglercraft.glemu.vector.Vector2f; +import net.lax1dude.eaglercraft.glemu.vector.Vector4f; + +import static net.lax1dude.eaglercraft.glemu.EaglerAdapterGL30.*; + +public class FixedFunctionShader { + + private static final FixedFunctionShader[] instances = new FixedFunctionShader[2048]; //lol + + public static void refreshCoreGL() { + for(int i = 0; i < instances.length; ++i) { + if(instances[i] != null) { + _wglDeleteProgram(instances[i].globject); + instances[i] = null; + } + } + shaderSource = null; + } + + public static final int COLOR = 1; + public static final int NORMAL = 2; + public static final int TEXTURE0 = 4; + public static final int TEXTURE1 = 8; + public static final int TEXGEN = 16; + public static final int LIGHTING = 32; + public static final int FOG = 64; + public static final int ALPHATEST = 128; + public static final int UNIT0 = 256; + public static final int UNIT1 = 512; + public static final int FIX_ANISOTROPIC = 1024; + + public static FixedFunctionShader instance(int i) { + FixedFunctionShader s = instances[i]; + if(s == null) { + boolean CC_a_color = false; + boolean CC_a_normal = false; + boolean CC_a_texture0 = false; + boolean CC_a_texture1 = false; + boolean CC_TEX_GEN_STRQ = false; + boolean CC_lighting = false; + boolean CC_fog = false; + boolean CC_alphatest = false; + boolean CC_unit0 = false; + boolean CC_unit1 = false; + boolean CC_anisotropic = false; + if((i & COLOR) == COLOR) { + CC_a_color = true; + } + if((i & NORMAL) == NORMAL) { + CC_a_normal = true; + } + if((i & TEXTURE0) == TEXTURE0) { + CC_a_texture0 = true; + } + if((i & TEXTURE1) == TEXTURE1) { + CC_a_texture1 = true; + } + if((i & TEXGEN) == TEXGEN) { + CC_TEX_GEN_STRQ = true; + } + if((i & LIGHTING) == LIGHTING) { + CC_lighting = true; + } + if((i & FOG) == FOG) { + CC_fog = true; + } + if((i & ALPHATEST) == ALPHATEST) { + CC_alphatest = true; + } + if((i & UNIT0) == UNIT0) { + CC_unit0 = true; + } + if((i & UNIT1) == UNIT1) { + CC_unit1 = true; + } + if((i & FIX_ANISOTROPIC) == FIX_ANISOTROPIC) { + CC_anisotropic = true; + } + s = new FixedFunctionShader(i, CC_a_color, CC_a_normal, CC_a_texture0, CC_a_texture1, CC_TEX_GEN_STRQ, CC_lighting, CC_fog, CC_alphatest, CC_unit0, CC_unit1, CC_anisotropic); + instances[i] = s; + } + return s; + } + + private static String shaderSource = null; + + private final boolean enable_color; + private final boolean enable_normal; + private final boolean enable_texture0; + private final boolean enable_texture1; + private final boolean enable_TEX_GEN_STRQ; + private final boolean enable_lighting; + private final boolean enable_fog; + private final boolean enable_alphatest; + private final boolean enable_unit0; + private final boolean enable_unit1; + private final boolean enable_anisotropic_fix; + private final ProgramGL globject; + + private UniformGL u_matrix_m = null; + private UniformGL u_matrix_p = null; + private UniformGL u_matrix_t = null; + + private UniformGL u_fogColor = null; + private UniformGL u_fogMode = null; + private UniformGL u_fogStart = null; + private UniformGL u_fogEnd = null; + private UniformGL u_fogDensity = null; + private UniformGL u_fogPremultiply = null; + + private UniformGL u_colorUniform = null; + private UniformGL u_normalUniform = null; + + private UniformGL u_alphaTestF = null; + + private UniformGL u_textureGenS_M = null; + private UniformGL u_textureGenT_M = null; + private UniformGL u_textureGenR_M = null; + private UniformGL u_textureGenQ_M = null; + private UniformGL u_textureGenS_V = null; + private UniformGL u_textureGenT_V = null; + private UniformGL u_textureGenR_V = null; + private UniformGL u_textureGenQ_V = null; + private UniformGL u_matrix_inverse_m = null; + + private UniformGL u_texCoordV0 = null; + private UniformGL u_texCoordV1 = null; + + private UniformGL u_light0Pos = null; + private UniformGL u_light1Pos = null; + //private UniformGL u_invertNormals = null; + + private UniformGL u_anisotropic_fix = null; + + private final int a_position; + private final int a_texture0; + private final int a_color; + private final int a_normal; + private final int a_texture1; + + private final int attributeIndexesToEnable; + + public final BufferArrayGL genericArray; + public final BufferGL genericBuffer; + public boolean bufferIsInitialized = false; + + private FixedFunctionShader(int j, boolean CC_a_color, boolean CC_a_normal, boolean CC_a_texture0, boolean CC_a_texture1, boolean CC_TEX_GEN_STRQ, boolean CC_lighting, boolean CC_fog, boolean CC_alphatest, boolean CC_unit0, boolean CC_unit1, boolean CC_anisotropic_fix) { + enable_color = CC_a_color; + enable_normal = CC_a_normal; + enable_texture0 = CC_a_texture0; + enable_texture1 = CC_a_texture1; + enable_TEX_GEN_STRQ = CC_TEX_GEN_STRQ; + enable_lighting = CC_lighting; + enable_fog = CC_fog; + enable_alphatest = CC_alphatest; + enable_unit0 = CC_unit0; + enable_unit1 = CC_unit1; + enable_anisotropic_fix = CC_anisotropic_fix; + + if(shaderSource == null) { + shaderSource = fileContents("/glsl/core.glsl"); + } + + String source = ""; + if(enable_color) source += "\n#define CC_a_color\n"; + if(enable_normal) source += "#define CC_a_normal\n"; + if(enable_texture0) source += "#define CC_a_texture0\n"; + if(enable_texture1) source += "#define CC_a_texture1\n"; + if(enable_TEX_GEN_STRQ) source += "#define CC_TEX_GEN_STRQ\n"; + if(enable_lighting) source += "#define CC_lighting\n"; + if(enable_fog) source += "#define CC_fog\n"; + if(enable_alphatest) source += "#define CC_alphatest\n"; + if(enable_unit0) source += "#define CC_unit0\n"; + if(enable_unit1) source += "#define CC_unit1\n"; + if(enable_anisotropic_fix) source += "#define CC_patch_anisotropic\n"; + source += shaderSource; + + ShaderGL v = _wglCreateShader(_wGL_VERTEX_SHADER); + _wglShaderSource(v, _wgetShaderHeader()+"\n#define CC_VERT\n"+source); + _wglCompileShader(v); + + if(!_wglGetShaderCompiled(v)) { + System.err.println(("\n\n"+_wglGetShaderInfoLog(v)).replace("\n", "\n[/glsl/core.glsl][CC_VERT] ")); + throw new RuntimeException("broken shader file"); + } + + ShaderGL f = _wglCreateShader(_wGL_FRAGMENT_SHADER); + _wglShaderSource(f, _wgetShaderHeader()+"\n#define CC_FRAG\n"+source); + _wglCompileShader(f); + + if(!_wglGetShaderCompiled(f)) { + System.err.println(("\n\n"+_wglGetShaderInfoLog(f)).replace("\n", "\n[/glsl/core.glsl][CC_FRAG] ")); + throw new RuntimeException("broken shader file"); + } + + globject = _wglCreateProgram(); + _wglAttachShader(globject, v); + _wglAttachShader(globject, f); + + int i = 0; + a_position = i++; + _wglBindAttributeLocation(globject, a_position, "a_position"); + + if(enable_texture0) { + a_texture0 = i++; + _wglBindAttributeLocation(globject, a_texture0, "a_texture0"); + }else { + a_texture0 = -1; + } + if(enable_color) { + a_color = i++; + _wglBindAttributeLocation(globject, a_color, "a_color"); + }else { + a_color = -1; + } + if(enable_normal) { + a_normal = i++; + _wglBindAttributeLocation(globject, a_normal, "a_normal"); + }else { + a_normal = -1; + } + if(enable_texture1) { + a_texture1 = i++; + _wglBindAttributeLocation(globject, a_texture1, "a_texture1"); + }else { + a_texture1 = -1; + } + + attributeIndexesToEnable = i; + + _wglLinkProgram(globject); + + _wglDetachShader(globject, v); + _wglDetachShader(globject, f); + _wglDeleteShader(v); + _wglDeleteShader(f); + + if(!_wglGetProgramLinked(globject)) { + System.err.println(("\n\n"+_wglGetProgramInfoLog(globject)).replace("\n", "\n[LINKER] ")); + throw new RuntimeException("broken shader file"); + } + + _wglUseProgram(globject); + + u_matrix_m = _wglGetUniformLocation(globject, "matrix_m"); + u_matrix_p = _wglGetUniformLocation(globject, "matrix_p"); + u_matrix_t = _wglGetUniformLocation(globject, "matrix_t"); + + u_colorUniform = _wglGetUniformLocation(globject, "colorUniform"); + + if(enable_lighting) { + u_normalUniform = _wglGetUniformLocation(globject, "normalUniform"); + //u_invertNormals = _wglGetUniformLocation(globject, "invertNormals"); + u_light0Pos = _wglGetUniformLocation(globject, "light0Pos"); + u_light1Pos = _wglGetUniformLocation(globject, "light1Pos"); + } + + if(enable_fog) { + u_fogColor = _wglGetUniformLocation(globject, "fogColor"); + u_fogMode = _wglGetUniformLocation(globject, "fogMode"); + u_fogStart = _wglGetUniformLocation(globject, "fogStart"); + u_fogEnd = _wglGetUniformLocation(globject, "fogEnd"); + u_fogDensity = _wglGetUniformLocation(globject, "fogDensity"); + u_fogPremultiply = _wglGetUniformLocation(globject, "fogPremultiply"); + } + + if(enable_alphatest) { + u_alphaTestF = _wglGetUniformLocation(globject, "alphaTestF"); + } + + if(enable_TEX_GEN_STRQ) { + u_textureGenS_M = _wglGetUniformLocation(globject, "textureGenS_M"); + u_textureGenT_M = _wglGetUniformLocation(globject, "textureGenT_M"); + u_textureGenR_M = _wglGetUniformLocation(globject, "textureGenR_M"); + u_textureGenQ_M = _wglGetUniformLocation(globject, "textureGenQ_M"); + u_textureGenS_V = _wglGetUniformLocation(globject, "textureGenS_V"); + u_textureGenT_V = _wglGetUniformLocation(globject, "textureGenT_V"); + u_textureGenR_V = _wglGetUniformLocation(globject, "textureGenR_V"); + u_textureGenQ_V = _wglGetUniformLocation(globject, "textureGenQ_V"); + u_matrix_inverse_m = _wglGetUniformLocation(globject, "matrix_inverse_m"); + } + + if(enable_anisotropic_fix) { + u_anisotropic_fix = _wglGetUniformLocation(globject, "anisotropic_fix"); + _wglUniform2f(u_anisotropic_fix, 1024.0f * 63.0f / 64.0f, 1024.0f * 63.0f / 64.0f); + } + + _wglUniform1i(_wglGetUniformLocation(globject, "tex0"), 0); + _wglUniform1i(_wglGetUniformLocation(globject, "tex1"), 1); + + u_texCoordV0 = _wglGetUniformLocation(globject, "texCoordV0"); + u_texCoordV1 = _wglGetUniformLocation(globject, "texCoordV1"); + + genericArray = _wglCreateVertexArray(); + genericBuffer = _wglCreateBuffer(); + _wglBindVertexArray(genericArray); + _wglBindBuffer(_wGL_ARRAY_BUFFER, genericBuffer); + setupArrayForProgram(); + + } + + public void setupArrayForProgram() { + _wglEnableVertexAttribArray(a_position); + _wglVertexAttribPointer(a_position, 3, EaglerAdapter._wGL_FLOAT, false, 32, 0); + if(enable_texture0) { + _wglEnableVertexAttribArray(a_texture0); + _wglVertexAttribPointer(a_texture0, 2, EaglerAdapter._wGL_FLOAT, false, 32, 12); + } + if(enable_color) { + _wglEnableVertexAttribArray(a_color); + _wglVertexAttribPointer(a_color, 4, EaglerAdapter._wGL_UNSIGNED_BYTE, true, 32, 20); + } + if(enable_normal) { + _wglEnableVertexAttribArray(a_normal); + _wglVertexAttribPointer(a_normal, 4, EaglerAdapter._wGL_UNSIGNED_BYTE, true, 32, 24); + } + if(enable_texture1) { + _wglEnableVertexAttribArray(a_texture1); + _wglVertexAttribPointer(a_texture1, 2, EaglerAdapter._wGL_SHORT, false, 32, 28); + } + } + + public void useProgram() { + _wglUseProgram(globject); + } + + public void unuseProgram() { + + } + + private float[] modelBuffer = new float[16]; + private float[] projectionBuffer = new float[16]; + private float[] textureBuffer = new float[16]; + + private Matrix4f modelMatrix = (Matrix4f) new Matrix4f().setZero(); + private Matrix4f projectionMatrix = (Matrix4f) new Matrix4f().setZero(); + private Matrix4f textureMatrix = (Matrix4f) new Matrix4f().setZero(); + private Matrix4f inverseModelMatrix = (Matrix4f) new Matrix4f().setZero(); + private Vector4f light0Pos = new Vector4f(); + private Vector4f light1Pos = new Vector4f(); + private Vector2f anisotropicFix = new Vector2f(0.0f, 0.0f); + + public void setAnisotropicFix(float x, float y) { + if(anisotropicFix.x != x || anisotropicFix.y != y) { + anisotropicFix.x = x; + anisotropicFix.y = y; + _wglUniform2f(u_anisotropic_fix, x, y); + } + } + + public void setModelMatrix(Matrix4f mat) { + if(!mat.equals(modelMatrix)) { + modelMatrix.load(mat).store(modelBuffer); + _wglUniformMat4fv(u_matrix_m, modelBuffer); + if(enable_TEX_GEN_STRQ) { + inverseModelMatrix.load(mat).invert(); + inverseModelMatrix.store(modelBuffer); + _wglUniformMat4fv(u_matrix_inverse_m, modelBuffer); + } + } + } + public void setProjectionMatrix(Matrix4f mat) { + if(!mat.equals(projectionMatrix)) { + projectionMatrix.load(mat).store(projectionBuffer); + _wglUniformMat4fv(u_matrix_p, projectionBuffer); + } + } + public void setTextureMatrix(Matrix4f mat) { + if(!mat.equals(textureMatrix)) { + textureMatrix.load(mat).store(textureBuffer); + _wglUniformMat4fv(u_matrix_t, textureBuffer); + } + } + public void setLightPositions(Vector4f pos0, Vector4f pos1) { + if(!pos0.equals(light0Pos) || !pos1.equals(light1Pos)) { + light0Pos.set(pos0); + light1Pos.set(pos1); + _wglUniform3f(u_light0Pos, light0Pos.x, light0Pos.y, light0Pos.z); + _wglUniform3f(u_light1Pos, light1Pos.x, light1Pos.y, light1Pos.z); + } + } + + private int fogMode = 0; + public void setFogMode(int mode) { + if(fogMode != mode) { + fogMode = mode; + _wglUniform1i(u_fogMode, mode % 2); + _wglUniform1f(u_fogPremultiply, mode / 2); + } + } + + private float fogColorR = 0.0f; + private float fogColorG = 0.0f; + private float fogColorB = 0.0f; + private float fogColorA = 0.0f; + public void setFogColor(float r, float g, float b, float a) { + if(fogColorR != r || fogColorG != g || fogColorB != b || fogColorA != a) { + fogColorR = r; + fogColorG = g; + fogColorB = b; + fogColorA = a; + _wglUniform4f(u_fogColor, fogColorR, fogColorG, fogColorB, fogColorA); + } + } + + private float fogStart = 0.0f; + private float fogEnd = 0.0f; + public void setFogStartEnd(float s, float e) { + if(fogStart != s || fogEnd != e) { + fogStart = s; + fogEnd = e; + _wglUniform1f(u_fogStart, fogStart); + _wglUniform1f(u_fogEnd, fogEnd); + } + } + + private float fogDensity = 0.0f; + public void setFogDensity(float d) { + if(fogDensity != d) { + fogDensity = d; + _wglUniform1f(u_fogDensity, fogDensity); + } + } + + private float alphaTestValue = 0.0f; + public void setAlphaTest(float limit) { + if(alphaTestValue != limit) { + alphaTestValue = limit; + _wglUniform1f(u_alphaTestF, alphaTestValue); + } + } + + private float tex0x = 0.0f; + private float tex0y = 0.0f; + public void setTex0Coords(float x, float y) { + if(tex0x != x || tex0y != y) { + tex0x = x; + tex0y = y; + _wglUniform2f(u_texCoordV0, tex0x, tex0y); + } + } + + private float tex1x = 0.0f; + private float tex1y = 0.0f; + public void setTex1Coords(float x, float y) { + if(tex1x != x || tex1y != y) { + tex1x = x; + tex1y = y; + _wglUniform2f(u_texCoordV1, tex1x, tex1y); + } + } + + public void setTexGenS(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenS_M, plane); + _wglUniform4f(u_textureGenS_V, x, y, z, w); + } + + public void setTexGenT(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenT_M, plane); + _wglUniform4f(u_textureGenT_V, x, y, z, w); + } + + public void setTexGenR(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenR_M, plane); + _wglUniform4f(u_textureGenR_V, x, y, z, w); + } + + public void setTexGenQ(int plane, float x, float y, float z, float w) { + _wglUniform1i(u_textureGenQ_M, plane); + _wglUniform4f(u_textureGenQ_V, x, y, z, w); + } + + private float colorUniformR = 0.0f; + private float colorUniformG = 0.0f; + private float colorUniformB = 0.0f; + private float colorUniformA = 0.0f; + public void setColor(float r, float g, float b, float a) { + if(colorUniformR != r || colorUniformG != g || colorUniformB != b || colorUniformA != a) { + colorUniformR = r; + colorUniformG = g; + colorUniformB = b; + colorUniformA = a; + _wglUniform4f(u_colorUniform, colorUniformR, colorUniformG, colorUniformB, colorUniformA); + } + } + + private float normalUniformX = 0.0f; + private float normalUniformY = 0.0f; + private float normalUniformZ = 0.0f; + public void setNormal(float x, float y, float z) { + if(normalUniformX != x || normalUniformY != y || normalUniformZ != z) { + normalUniformX = x; + normalUniformY = y; + normalUniformZ = z; + _wglUniform3f(u_normalUniform, normalUniformX, normalUniformY, normalUniformZ); + } + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/GLObjectMap.java b/src/main/java/net/lax1dude/eaglercraft/glemu/GLObjectMap.java new file mode 100644 index 0000000..acedc5a --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/GLObjectMap.java @@ -0,0 +1,53 @@ +package net.lax1dude.eaglercraft.glemu; + +public class GLObjectMap { + private Object[] values; + private int size; + private int insertIndex; + public int allocatedObjects; + + public GLObjectMap(int initialSize) { + this.values = new Object[initialSize]; + this.size = initialSize; + this.insertIndex = 0; + this.allocatedObjects = 0; + } + + public int register(T obj) { + int start = insertIndex; + do { + ++insertIndex; + if(insertIndex >= size) { + insertIndex = 0; + } + if(insertIndex == start) { + resize(); + return register(obj); + } + }while(values[insertIndex] != null); + values[insertIndex] = obj; + ++allocatedObjects; + return insertIndex; + } + + public T free(int obj) { + if(obj >= size || obj < 0) return null; + Object ret = values[obj]; + values[obj] = null; + --allocatedObjects; + return (T) ret; + } + + public T get(int obj) { + if(obj >= size || obj < 0) return null; + return (T) values[obj]; + } + + private void resize() { + int oldSize = size; + size += size / 2; + Object[] oldValues = values; + values = new Object[size]; + System.arraycopy(oldValues, 0, values, 0, oldSize); + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix.java new file mode 100644 index 0000000..d27abab --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Base class for matrices. When a matrix is constructed it will be the identity + * matrix unless otherwise stated. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ +public abstract class Matrix implements Serializable { + + /** + * Constructor for Matrix. + */ + protected Matrix() { + super(); + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public abstract Matrix setIdentity(); + + + /** + * Invert this matrix + * @return this + */ + public abstract Matrix invert(); + + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public abstract Matrix load(FloatBuffer buf); + + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (mathematical) order. + * + * @param buf A float buffer to read from + * @return this + */ + public abstract Matrix loadTranspose(FloatBuffer buf); + + + /** + * Negate this matrix + * @return this + */ + public abstract Matrix negate(); + + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + * @return this + */ + public abstract Matrix store(FloatBuffer buf); + + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + * @return this + */ + public abstract Matrix storeTranspose(FloatBuffer buf); + + + /** + * Transpose this matrix + * @return this + */ + public abstract Matrix transpose(); + + + /** + * Set this matrix to 0. + * @return this + */ + public abstract Matrix setZero(); + + + /** + * @return the determinant of the matrix + */ + public abstract float determinant(); + + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix2f.java new file mode 100644 index 0000000..10598b9 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix2f.java @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 2x2 matrix + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Matrix2f extends Matrix implements Serializable { + + private static final long serialVersionUID = 1L; + + public float m00, m01, m10, m11; + + /** + * Constructor for Matrix2f. The matrix is initialised to the identity. + */ + public Matrix2f() { + setIdentity(); + } + + /** + * Constructor + */ + public Matrix2f(Matrix2f src) { + load(src); + } + + /** + * Load from another matrix + * @param src The source matrix + * @return this + */ + public Matrix2f load(Matrix2f src) { + return load(src, this); + } + + /** + * Copy the source matrix to the destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new one should be created. + * @return The copied matrix + */ + public static Matrix2f load(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = src.m00; + dest.m01 = src.m01; + dest.m10 = src.m10; + dest.m11 = src.m11; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (mathematical) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m10); + buf.put(m11); + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m01); + buf.put(m11); + return this; + } + + + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f add(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f sub(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f mul(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + float m00 = left.m00 * right.m00 + left.m10 * right.m01; + float m01 = left.m01 * right.m00 + left.m11 * right.m01; + float m10 = left.m00 * right.m10 + left.m10 * right.m11; + float m11 = left.m01 * right.m10 + left.m11 * right.m11; + + dest.m00 = m00; + dest.m01 = m01; + dest.m10 = m10; + dest.m11 = m11; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector2f transform(Matrix2f left, Vector2f right, Vector2f dest) { + if (dest == null) + dest = new Vector2f(); + + float x = left.m00 * right.x + left.m10 * right.y; + float y = left.m01 * right.x + left.m11 * right.y; + + dest.x = x; + dest.y = y; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this); + } + + /** + * Transpose this matrix and place the result in another matrix. + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix2f transpose(Matrix2f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result in the destination matrix. + * @param src The source matrix or null if a new matrix is to be created + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix2f transpose(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + float m01 = src.m10; + float m10 = src.m01; + + dest.m01 = m01; + dest.m10 = m10; + + return dest; + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and place the result in the destination matrix. + * @param src The source matrix to be inverted + * @param dest The destination matrix or null if a new matrix is to be created + * @return The inverted matrix, or null if source can't be reverted. + */ + public static Matrix2f invert(Matrix2f src, Matrix2f dest) { + /* + *inv(A) = 1/det(A) * adj(A); + */ + + float determinant = src.determinant(); + if (determinant != 0) { + if (dest == null) + dest = new Matrix2f(); + float determinant_inv = 1f/determinant; + float t00 = src.m11*determinant_inv; + float t01 = -src.m01*determinant_inv; + float t11 = src.m00*determinant_inv; + float t10 = -src.m10*determinant_inv; + + dest.m00 = t00; + dest.m01 = t01; + dest.m10 = t10; + dest.m11 = t11; + return dest; + } else + return null; + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append('\n'); + return buf.toString(); + } + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and stash the result in another matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix2f negate(Matrix2f dest) { + return negate(this, dest); + } + + /** + * Negate the source matrix and stash the result in the destination matrix. + * @param src The source matrix to be negated + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public static Matrix2f negate(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m01; + dest.m10 = -src.m10; + dest.m11 = -src.m11; + + return dest; + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the source matrix to be the identity matrix. + * @param src The matrix to set to the identity. + * @return The source matrix + */ + public static Matrix2f setIdentity(Matrix2f src) { + src.m00 = 1.0f; + src.m01 = 0.0f; + src.m10 = 0.0f; + src.m11 = 1.0f; + return src; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + public static Matrix2f setZero(Matrix2f src) { + src.m00 = 0.0f; + src.m01 = 0.0f; + src.m10 = 0.0f; + src.m11 = 0.0f; + return src; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Matrix#determinant() + */ + public float determinant() { + return m00 * m11 - m01*m10; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix3f.java new file mode 100644 index 0000000..d743b1d --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix3f.java @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 3x3 matrix. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Matrix3f extends Matrix implements Serializable { + + private static final long serialVersionUID = 1L; + + public float m00, + m01, + m02, + m10, + m11, + m12, + m20, + m21, + m22; + + /** + * Constructor for Matrix3f. Matrix is initialised to the identity. + */ + public Matrix3f() { + super(); + setIdentity(); + } + + /** + * Load from another matrix + * @param src The source matrix + * @return this + */ + public Matrix3f load(Matrix3f src) { + return load(src, this); + } + + /** + * Copy source matrix to destination matrix + * @param src The source matrix + * @param dest The destination matrix, or null of a new matrix is to be created + * @return The copied matrix + */ + public static Matrix3f load(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = src.m00; + dest.m10 = src.m10; + dest.m20 = src.m20; + dest.m01 = src.m01; + dest.m11 = src.m11; + dest.m21 = src.m21; + dest.m02 = src.m02; + dest.m12 = src.m12; + dest.m22 = src.m22; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m02 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + m12 = buf.get(); + m20 = buf.get(); + m21 = buf.get(); + m22 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (maths) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m20 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + m21 = buf.get(); + m02 = buf.get(); + m12 = buf.get(); + m22 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m20); + buf.put(m21); + buf.put(m22); + return this; + } + + public Matrix store(float[] buf) { + buf[0] = m00; + buf[1] = m01; + buf[2] = m02; + buf[3] = m10; + buf[4] = m11; + buf[5] = m12; + buf[6] = m20; + buf[7] = m21; + buf[8] = m22; + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m20); + buf.put(m01); + buf.put(m11); + buf.put(m21); + buf.put(m02); + buf.put(m12); + buf.put(m22); + return this; + } + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f add(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m02 = left.m02 + right.m02; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + dest.m12 = left.m12 + right.m12; + dest.m20 = left.m20 + right.m20; + dest.m21 = left.m21 + right.m21; + dest.m22 = left.m22 + right.m22; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f sub(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m02 = left.m02 - right.m02; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + dest.m12 = left.m12 - right.m12; + dest.m20 = left.m20 - right.m20; + dest.m21 = left.m21 - right.m21; + dest.m22 = left.m22 - right.m22; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f mul(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + float m00 = + left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02; + float m01 = + left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02; + float m02 = + left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02; + float m10 = + left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12; + float m11 = + left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12; + float m12 = + left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12; + float m20 = + left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22; + float m21 = + left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22; + float m22 = + left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector3f transform(Matrix3f left, Vector3f right, Vector3f dest) { + if (dest == null) + dest = new Vector3f(); + + float x = left.m00 * right.x + left.m10 * right.y + left.m20 * right.z; + float y = left.m01 * right.x + left.m11 * right.y + left.m21 * right.z; + float z = left.m02 * right.x + left.m12 * right.y + left.m22 * right.z; + + dest.x = x; + dest.y = y; + dest.z = z; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this, this); + } + + /** + * Transpose this matrix and place the result in another matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix3f transpose(Matrix3f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result into the destination matrix + * @param src The source matrix to be transposed + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix3f transpose(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + float m00 = src.m00; + float m01 = src.m10; + float m02 = src.m20; + float m10 = src.m01; + float m11 = src.m11; + float m12 = src.m21; + float m20 = src.m02; + float m21 = src.m12; + float m22 = src.m22; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + return dest; + } + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 * (m11 * m22 - m12 * m21) + + m01 * (m12 * m20 - m10 * m22) + + m02 * (m10 * m21 - m11 * m20); + return f; + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append(m20).append(' ').append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append(m21).append(' ').append('\n'); + buf.append(m02).append(' ').append(m12).append(' ').append(m22).append(' ').append('\n'); + return buf.toString(); + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and put the result into the destination matrix + * @param src The source matrix to be inverted + * @param dest The destination matrix, or null if a new one is to be created + * @return The inverted matrix if successful, null otherwise + */ + public static Matrix3f invert(Matrix3f src, Matrix3f dest) { + float determinant = src.determinant(); + + if (determinant != 0) { + if (dest == null) + dest = new Matrix3f(); + /* do it the ordinary way + * + * inv(A) = 1/det(A) * adj(T), where adj(T) = transpose(Conjugate Matrix) + * + * m00 m01 m02 + * m10 m11 m12 + * m20 m21 m22 + */ + float determinant_inv = 1f/determinant; + + // get the conjugate matrix + float t00 = src.m11 * src.m22 - src.m12* src.m21; + float t01 = - src.m10 * src.m22 + src.m12 * src.m20; + float t02 = src.m10 * src.m21 - src.m11 * src.m20; + float t10 = - src.m01 * src.m22 + src.m02 * src.m21; + float t11 = src.m00 * src.m22 - src.m02 * src.m20; + float t12 = - src.m00 * src.m21 + src.m01 * src.m20; + float t20 = src.m01 * src.m12 - src.m02 * src.m11; + float t21 = -src.m00 * src.m12 + src.m02 * src.m10; + float t22 = src.m00 * src.m11 - src.m01 * src.m10; + + dest.m00 = t00*determinant_inv; + dest.m11 = t11*determinant_inv; + dest.m22 = t22*determinant_inv; + dest.m01 = t10*determinant_inv; + dest.m10 = t01*determinant_inv; + dest.m20 = t02*determinant_inv; + dest.m02 = t20*determinant_inv; + dest.m12 = t21*determinant_inv; + dest.m21 = t12*determinant_inv; + return dest; + } else + return null; + } + + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix3f negate(Matrix3f dest) { + return negate(this, dest); + } + + /** + * Negate the source matrix and place the result in the destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public static Matrix3f negate(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m02; + dest.m02 = -src.m01; + dest.m10 = -src.m10; + dest.m11 = -src.m12; + dest.m12 = -src.m11; + dest.m20 = -src.m20; + dest.m21 = -src.m22; + dest.m22 = -src.m21; + return dest; + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the matrix to be the identity matrix. + * @param m The matrix to be set to the identity + * @return m + */ + public static Matrix3f setIdentity(Matrix3f m) { + m.m00 = 1.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m10 = 0.0f; + m.m11 = 1.0f; + m.m12 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 1.0f; + return m; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + /** + * Set the matrix matrix to 0. + * @param m The matrix to be set to 0 + * @return m + */ + public static Matrix3f setZero(Matrix3f m) { + m.m00 = 0.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m10 = 0.0f; + m.m11 = 0.0f; + m.m12 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 0.0f; + return m; + } + + public boolean equals(Object m) { + return (m instanceof Matrix3f) && equal(this, (Matrix3f)m); + } + + public static boolean equal(Matrix3f a, Matrix3f b) { + return a.m00 == b.m00 && + a.m01 == b.m01 && + a.m02 == b.m02 && + a.m10 == b.m10 && + a.m11 == b.m11 && + a.m12 == b.m12 && + a.m20 == b.m20 && + a.m21 == b.m21 && + a.m22 == b.m22; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix4f.java new file mode 100644 index 0000000..d7bd730 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Matrix4f.java @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * Holds a 4x4 float matrix. + * + * @author foo + */ +public class Matrix4f extends Matrix implements Serializable { + private static final long serialVersionUID = 1L; + + public float m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33; + + /** + * Construct a new matrix, initialized to the identity. + */ + public Matrix4f() { + super(); + setIdentity(); + } + + public Matrix4f(final Matrix4f src) { + super(); + load(src); + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append(m20).append(' ').append(m30).append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append(m21).append(' ').append(m31).append('\n'); + buf.append(m02).append(' ').append(m12).append(' ').append(m22).append(' ').append(m32).append('\n'); + buf.append(m03).append(' ').append(m13).append(' ').append(m23).append(' ').append(m33).append('\n'); + return buf.toString(); + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the given matrix to be the identity matrix. + * @param m The matrix to set to the identity + * @return m + */ + public static Matrix4f setIdentity(Matrix4f m) { + m.m00 = 1.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m03 = 0.0f; + m.m10 = 0.0f; + m.m11 = 1.0f; + m.m12 = 0.0f; + m.m13 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 1.0f; + m.m23 = 0.0f; + m.m30 = 0.0f; + m.m31 = 0.0f; + m.m32 = 0.0f; + m.m33 = 1.0f; + + return m; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + /** + * Set the given matrix to 0. + * @param m The matrix to set to 0 + * @return m + */ + public static Matrix4f setZero(Matrix4f m) { + m.m00 = 0.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m03 = 0.0f; + m.m10 = 0.0f; + m.m11 = 0.0f; + m.m12 = 0.0f; + m.m13 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 0.0f; + m.m23 = 0.0f; + m.m30 = 0.0f; + m.m31 = 0.0f; + m.m32 = 0.0f; + m.m33 = 0.0f; + + return m; + } + + /** + * Load from another matrix4f + * @param src The source matrix + * @return this + */ + public Matrix4f load(Matrix4f src) { + return load(src, this); + } + + /** + * Copy the source matrix to the destination matrix + * @param src The source matrix + * @param dest The destination matrix, or null of a new one is to be created + * @return The copied matrix + */ + public static Matrix4f load(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + dest.m00 = src.m00; + dest.m01 = src.m01; + dest.m02 = src.m02; + dest.m03 = src.m03; + dest.m10 = src.m10; + dest.m11 = src.m11; + dest.m12 = src.m12; + dest.m13 = src.m13; + dest.m20 = src.m20; + dest.m21 = src.m21; + dest.m22 = src.m22; + dest.m23 = src.m23; + dest.m30 = src.m30; + dest.m31 = src.m31; + dest.m32 = src.m32; + dest.m33 = src.m33; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m02 = buf.get(); + m03 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + m12 = buf.get(); + m13 = buf.get(); + m20 = buf.get(); + m21 = buf.get(); + m22 = buf.get(); + m23 = buf.get(); + m30 = buf.get(); + m31 = buf.get(); + m32 = buf.get(); + m33 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (maths) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m20 = buf.get(); + m30 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + m21 = buf.get(); + m31 = buf.get(); + m02 = buf.get(); + m12 = buf.get(); + m22 = buf.get(); + m32 = buf.get(); + m03 = buf.get(); + m13 = buf.get(); + m23 = buf.get(); + m33 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m03); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m13); + buf.put(m20); + buf.put(m21); + buf.put(m22); + buf.put(m23); + buf.put(m30); + buf.put(m31); + buf.put(m32); + buf.put(m33); + return this; + } + + public Matrix store(float[] buf) { + buf[0] = m00; + buf[1] = m01; + buf[2] = m02; + buf[3] = m03; + buf[4] = m10; + buf[5] = m11; + buf[6] = m12; + buf[7] = m13; + buf[8] = m20; + buf[9] = m21; + buf[10] = m22; + buf[11] = m23; + buf[12] = m30; + buf[13] = m31; + buf[14] = m32; + buf[15] = m33; + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m20); + buf.put(m30); + buf.put(m01); + buf.put(m11); + buf.put(m21); + buf.put(m31); + buf.put(m02); + buf.put(m12); + buf.put(m22); + buf.put(m32); + buf.put(m03); + buf.put(m13); + buf.put(m23); + buf.put(m33); + return this; + } + + /** + * Store the rotation portion of this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store3f(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m20); + buf.put(m21); + buf.put(m22); + return this; + } + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f add(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m02 = left.m02 + right.m02; + dest.m03 = left.m03 + right.m03; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + dest.m12 = left.m12 + right.m12; + dest.m13 = left.m13 + right.m13; + dest.m20 = left.m20 + right.m20; + dest.m21 = left.m21 + right.m21; + dest.m22 = left.m22 + right.m22; + dest.m23 = left.m23 + right.m23; + dest.m30 = left.m30 + right.m30; + dest.m31 = left.m31 + right.m31; + dest.m32 = left.m32 + right.m32; + dest.m33 = left.m33 + right.m33; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f sub(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m02 = left.m02 - right.m02; + dest.m03 = left.m03 - right.m03; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + dest.m12 = left.m12 - right.m12; + dest.m13 = left.m13 - right.m13; + dest.m20 = left.m20 - right.m20; + dest.m21 = left.m21 - right.m21; + dest.m22 = left.m22 - right.m22; + dest.m23 = left.m23 - right.m23; + dest.m30 = left.m30 - right.m30; + dest.m31 = left.m31 - right.m31; + dest.m32 = left.m32 - right.m32; + dest.m33 = left.m33 - right.m33; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f mul(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + float m00 = left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02 + left.m30 * right.m03; + float m01 = left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02 + left.m31 * right.m03; + float m02 = left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02 + left.m32 * right.m03; + float m03 = left.m03 * right.m00 + left.m13 * right.m01 + left.m23 * right.m02 + left.m33 * right.m03; + float m10 = left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12 + left.m30 * right.m13; + float m11 = left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12 + left.m31 * right.m13; + float m12 = left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12 + left.m32 * right.m13; + float m13 = left.m03 * right.m10 + left.m13 * right.m11 + left.m23 * right.m12 + left.m33 * right.m13; + float m20 = left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22 + left.m30 * right.m23; + float m21 = left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22 + left.m31 * right.m23; + float m22 = left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22 + left.m32 * right.m23; + float m23 = left.m03 * right.m20 + left.m13 * right.m21 + left.m23 * right.m22 + left.m33 * right.m23; + float m30 = left.m00 * right.m30 + left.m10 * right.m31 + left.m20 * right.m32 + left.m30 * right.m33; + float m31 = left.m01 * right.m30 + left.m11 * right.m31 + left.m21 * right.m32 + left.m31 * right.m33; + float m32 = left.m02 * right.m30 + left.m12 * right.m31 + left.m22 * right.m32 + left.m32 * right.m33; + float m33 = left.m03 * right.m30 + left.m13 * right.m31 + left.m23 * right.m32 + left.m33 * right.m33; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m03 = m03; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m13 = m13; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + dest.m23 = m23; + dest.m30 = m30; + dest.m31 = m31; + dest.m32 = m32; + dest.m33 = m33; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector4f transform(Matrix4f left, Vector4f right, Vector4f dest) { + if (dest == null) + dest = new Vector4f(); + + float x = left.m00 * right.x + left.m10 * right.y + left.m20 * right.z + left.m30 * right.w; + float y = left.m01 * right.x + left.m11 * right.y + left.m21 * right.z + left.m31 * right.w; + float z = left.m02 * right.x + left.m12 * right.y + left.m22 * right.z + left.m32 * right.w; + float w = left.m03 * right.x + left.m13 * right.y + left.m23 * right.z + left.m33 * right.w; + + dest.x = x; + dest.y = y; + dest.z = z; + dest.w = w; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this); + } + + /** + * Translate this matrix + * @param vec The vector to translate by + * @return this + */ + public Matrix4f translate(Vector2f vec) { + return translate(vec, this); + } + + /** + * Translate this matrix + * @param vec The vector to translate by + * @return this + */ + public Matrix4f translate(Vector3f vec) { + return translate(vec, this); + } + + /** + * Scales this matrix + * @param vec The vector to scale by + * @return this + */ + public Matrix4f scale(Vector3f vec) { + return scale(vec, this, this); + } + + /** + * Scales the source matrix and put the result in the destination matrix + * @param vec The vector to scale by + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The scaled matrix + */ + public static Matrix4f scale(Vector3f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + dest.m00 = src.m00 * vec.x; + dest.m01 = src.m01 * vec.x; + dest.m02 = src.m02 * vec.x; + dest.m03 = src.m03 * vec.x; + dest.m10 = src.m10 * vec.y; + dest.m11 = src.m11 * vec.y; + dest.m12 = src.m12 * vec.y; + dest.m13 = src.m13 * vec.y; + dest.m20 = src.m20 * vec.z; + dest.m21 = src.m21 * vec.z; + dest.m22 = src.m22 * vec.z; + dest.m23 = src.m23 * vec.z; + return dest; + } + + /** + * Rotates the matrix around the given axis the specified angle + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @return this + */ + public Matrix4f rotate(float angle, Vector3f axis) { + return rotate(angle, axis, this); + } + + /** + * Rotates the matrix around the given axis the specified angle + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @param dest The matrix to put the result, or null if a new matrix is to be created + * @return The rotated matrix + */ + public Matrix4f rotate(float angle, Vector3f axis, Matrix4f dest) { + return rotate(angle, axis, this, dest); + } + + /** + * Rotates the source matrix around the given axis the specified angle and + * put the result in the destination matrix. + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @param src The matrix to rotate + * @param dest The matrix to put the result, or null if a new matrix is to be created + * @return The rotated matrix + */ + public static Matrix4f rotate(float angle, Vector3f axis, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + float c = (float) Math.cos(angle); + float s = (float) Math.sin(angle); + float oneminusc = 1.0f - c; + float xy = axis.x*axis.y; + float yz = axis.y*axis.z; + float xz = axis.x*axis.z; + float xs = axis.x*s; + float ys = axis.y*s; + float zs = axis.z*s; + + float f00 = axis.x*axis.x*oneminusc+c; + float f01 = xy*oneminusc+zs; + float f02 = xz*oneminusc-ys; + // n[3] not used + float f10 = xy*oneminusc-zs; + float f11 = axis.y*axis.y*oneminusc+c; + float f12 = yz*oneminusc+xs; + // n[7] not used + float f20 = xz*oneminusc+ys; + float f21 = yz*oneminusc-xs; + float f22 = axis.z*axis.z*oneminusc+c; + + float t00 = src.m00 * f00 + src.m10 * f01 + src.m20 * f02; + float t01 = src.m01 * f00 + src.m11 * f01 + src.m21 * f02; + float t02 = src.m02 * f00 + src.m12 * f01 + src.m22 * f02; + float t03 = src.m03 * f00 + src.m13 * f01 + src.m23 * f02; + float t10 = src.m00 * f10 + src.m10 * f11 + src.m20 * f12; + float t11 = src.m01 * f10 + src.m11 * f11 + src.m21 * f12; + float t12 = src.m02 * f10 + src.m12 * f11 + src.m22 * f12; + float t13 = src.m03 * f10 + src.m13 * f11 + src.m23 * f12; + dest.m20 = src.m00 * f20 + src.m10 * f21 + src.m20 * f22; + dest.m21 = src.m01 * f20 + src.m11 * f21 + src.m21 * f22; + dest.m22 = src.m02 * f20 + src.m12 * f21 + src.m22 * f22; + dest.m23 = src.m03 * f20 + src.m13 * f21 + src.m23 * f22; + dest.m00 = t00; + dest.m01 = t01; + dest.m02 = t02; + dest.m03 = t03; + dest.m10 = t10; + dest.m11 = t11; + dest.m12 = t12; + dest.m13 = t13; + return dest; + } + + /** + * Translate this matrix and stash the result in another matrix + * @param vec The vector to translate by + * @param dest The destination matrix or null if a new matrix is to be created + * @return the translated matrix + */ + public Matrix4f translate(Vector3f vec, Matrix4f dest) { + return translate(vec, this, dest); + } + + /** + * Translate the source matrix and stash the result in the destination matrix + * @param vec The vector to translate by + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return The translated matrix + */ + public static Matrix4f translate(Vector3f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m30 += src.m00 * vec.x + src.m10 * vec.y + src.m20 * vec.z; + dest.m31 += src.m01 * vec.x + src.m11 * vec.y + src.m21 * vec.z; + dest.m32 += src.m02 * vec.x + src.m12 * vec.y + src.m22 * vec.z; + dest.m33 += src.m03 * vec.x + src.m13 * vec.y + src.m23 * vec.z; + + return dest; + } + + /** + * Translate this matrix and stash the result in another matrix + * @param vec The vector to translate by + * @param dest The destination matrix or null if a new matrix is to be created + * @return the translated matrix + */ + public Matrix4f translate(Vector2f vec, Matrix4f dest) { + return translate(vec, this, dest); + } + + /** + * Translate the source matrix and stash the result in the destination matrix + * @param vec The vector to translate by + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return The translated matrix + */ + public static Matrix4f translate(Vector2f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m30 += src.m00 * vec.x + src.m10 * vec.y; + dest.m31 += src.m01 * vec.x + src.m11 * vec.y; + dest.m32 += src.m02 * vec.x + src.m12 * vec.y; + dest.m33 += src.m03 * vec.x + src.m13 * vec.y; + + return dest; + } + + /** + * Transpose this matrix and place the result in another matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix4f transpose(Matrix4f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result in the destination matrix + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix4f transpose(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + float m00 = src.m00; + float m01 = src.m10; + float m02 = src.m20; + float m03 = src.m30; + float m10 = src.m01; + float m11 = src.m11; + float m12 = src.m21; + float m13 = src.m31; + float m20 = src.m02; + float m21 = src.m12; + float m22 = src.m22; + float m23 = src.m32; + float m30 = src.m03; + float m31 = src.m13; + float m32 = src.m23; + float m33 = src.m33; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m03 = m03; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m13 = m13; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + dest.m23 = m23; + dest.m30 = m30; + dest.m31 = m31; + dest.m32 = m32; + dest.m33 = m33; + + return dest; + } + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 + * ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32) + - m13 * m22 * m31 + - m11 * m23 * m32 + - m12 * m21 * m33); + f -= m01 + * ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32) + - m13 * m22 * m30 + - m10 * m23 * m32 + - m12 * m20 * m33); + f += m02 + * ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31) + - m13 * m21 * m30 + - m10 * m23 * m31 + - m11 * m20 * m33); + f -= m03 + * ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31) + - m12 * m21 * m30 + - m10 * m22 * m31 + - m11 * m20 * m32); + return f; + } + + /** + * Calculate the determinant of a 3x3 matrix + * @return result + */ + + private static float determinant3x3(float t00, float t01, float t02, + float t10, float t11, float t12, + float t20, float t21, float t22) + { + return t00 * (t11 * t22 - t12 * t21) + + t01 * (t12 * t20 - t10 * t22) + + t02 * (t10 * t21 - t11 * t20); + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and put the result in the destination + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The inverted matrix if successful, null otherwise + */ + public static Matrix4f invert(Matrix4f src, Matrix4f dest) { + float determinant = src.determinant(); + + if (determinant != 0) { + /* + * m00 m01 m02 m03 + * m10 m11 m12 m13 + * m20 m21 m22 m23 + * m30 m31 m32 m33 + */ + if (dest == null) + dest = new Matrix4f(); + float determinant_inv = 1f/determinant; + + // first row + float t00 = determinant3x3(src.m11, src.m12, src.m13, src.m21, src.m22, src.m23, src.m31, src.m32, src.m33); + float t01 = -determinant3x3(src.m10, src.m12, src.m13, src.m20, src.m22, src.m23, src.m30, src.m32, src.m33); + float t02 = determinant3x3(src.m10, src.m11, src.m13, src.m20, src.m21, src.m23, src.m30, src.m31, src.m33); + float t03 = -determinant3x3(src.m10, src.m11, src.m12, src.m20, src.m21, src.m22, src.m30, src.m31, src.m32); + // second row + float t10 = -determinant3x3(src.m01, src.m02, src.m03, src.m21, src.m22, src.m23, src.m31, src.m32, src.m33); + float t11 = determinant3x3(src.m00, src.m02, src.m03, src.m20, src.m22, src.m23, src.m30, src.m32, src.m33); + float t12 = -determinant3x3(src.m00, src.m01, src.m03, src.m20, src.m21, src.m23, src.m30, src.m31, src.m33); + float t13 = determinant3x3(src.m00, src.m01, src.m02, src.m20, src.m21, src.m22, src.m30, src.m31, src.m32); + // third row + float t20 = determinant3x3(src.m01, src.m02, src.m03, src.m11, src.m12, src.m13, src.m31, src.m32, src.m33); + float t21 = -determinant3x3(src.m00, src.m02, src.m03, src.m10, src.m12, src.m13, src.m30, src.m32, src.m33); + float t22 = determinant3x3(src.m00, src.m01, src.m03, src.m10, src.m11, src.m13, src.m30, src.m31, src.m33); + float t23 = -determinant3x3(src.m00, src.m01, src.m02, src.m10, src.m11, src.m12, src.m30, src.m31, src.m32); + // fourth row + float t30 = -determinant3x3(src.m01, src.m02, src.m03, src.m11, src.m12, src.m13, src.m21, src.m22, src.m23); + float t31 = determinant3x3(src.m00, src.m02, src.m03, src.m10, src.m12, src.m13, src.m20, src.m22, src.m23); + float t32 = -determinant3x3(src.m00, src.m01, src.m03, src.m10, src.m11, src.m13, src.m20, src.m21, src.m23); + float t33 = determinant3x3(src.m00, src.m01, src.m02, src.m10, src.m11, src.m12, src.m20, src.m21, src.m22); + + // transpose and divide by the determinant + dest.m00 = t00*determinant_inv; + dest.m11 = t11*determinant_inv; + dest.m22 = t22*determinant_inv; + dest.m33 = t33*determinant_inv; + dest.m01 = t10*determinant_inv; + dest.m10 = t01*determinant_inv; + dest.m20 = t02*determinant_inv; + dest.m02 = t20*determinant_inv; + dest.m12 = t21*determinant_inv; + dest.m21 = t12*determinant_inv; + dest.m03 = t30*determinant_inv; + dest.m30 = t03*determinant_inv; + dest.m13 = t31*determinant_inv; + dest.m31 = t13*determinant_inv; + dest.m32 = t23*determinant_inv; + dest.m23 = t32*determinant_inv; + return dest; + } else + return null; + } + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix4f negate(Matrix4f dest) { + return negate(this, dest); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The negated matrix + */ + public static Matrix4f negate(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m01; + dest.m02 = -src.m02; + dest.m03 = -src.m03; + dest.m10 = -src.m10; + dest.m11 = -src.m11; + dest.m12 = -src.m12; + dest.m13 = -src.m13; + dest.m20 = -src.m20; + dest.m21 = -src.m21; + dest.m22 = -src.m22; + dest.m23 = -src.m23; + dest.m30 = -src.m30; + dest.m31 = -src.m31; + dest.m32 = -src.m32; + dest.m33 = -src.m33; + + return dest; + } + + public boolean equals(Object m) { + return (m instanceof Matrix4f) && equal(this, (Matrix4f)m); + } + + public static boolean equal(Matrix4f a, Matrix4f b) { + return a.m00 == b.m00 && + a.m01 == b.m01 && + a.m02 == b.m02 && + a.m03 == b.m03 && + a.m10 == b.m10 && + a.m11 == b.m11 && + a.m12 == b.m12 && + a.m13 == b.m13 && + a.m20 == b.m20 && + a.m21 == b.m21 && + a.m22 == b.m22 && + a.m23 == b.m23 && + a.m30 == b.m30 && + a.m31 == b.m31 && + a.m32 == b.m32 && + a.m33 == b.m33; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Quaternion.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Quaternion.java new file mode 100644 index 0000000..9a592d2 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Quaternion.java @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * + * Quaternions for LWJGL! + * + * @author fbi + * @version $Revision$ + * $Id$ + */ + +import java.nio.FloatBuffer; + +public class Quaternion extends Vector implements ReadableVector4f { + private static final long serialVersionUID = 1L; + + public float x, y, z, w; + + /** + * C'tor. The quaternion will be initialized to the identity. + */ + public Quaternion() { + super(); + setIdentity(); + } + + /** + * C'tor + * + * @param src + */ + public Quaternion(ReadableVector4f src) { + set(src); + } + + /** + * C'tor + * + */ + public Quaternion(float x, float y, float z, float w) { + set(x, y, z, w); + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector4f#set(float, float, float, + * float) + */ + public void set(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** + * Load from another Vector4f + * + * @param src + * The source vector + * @return this + */ + public Quaternion set(ReadableVector4f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + w = src.getW(); + return this; + } + + /** + * Set this quaternion to the multiplication identity. + * @return this + */ + public Quaternion setIdentity() { + return setIdentity(this); + } + + /** + * Set the given quaternion to the multiplication identity. + * @param q The quaternion + * @return q + */ + public static Quaternion setIdentity(Quaternion q) { + q.x = 0; + q.y = 0; + q.z = 0; + q.w = 1; + return q; + } + + /** + * @return the length squared of the quaternion + */ + public float lengthSquared() { + return x * x + y * y + z * z + w * w; + } + + /** + * Normalise the source quaternion and place the result in another quaternion. + * + * @param src + * The source quaternion + * @param dest + * The destination quaternion, or null if a new quaternion is to be + * created + * @return The normalised quaternion + */ + public static Quaternion normalise(Quaternion src, Quaternion dest) { + float inv_l = 1f/src.length(); + + if (dest == null) + dest = new Quaternion(); + + dest.set(src.x * inv_l, src.y * inv_l, src.z * inv_l, src.w * inv_l); + + return dest; + } + + /** + * Normalise this quaternion and place the result in another quaternion. + * + * @param dest + * The destination quaternion, or null if a new quaternion is to be + * created + * @return the normalised quaternion + */ + public Quaternion normalise(Quaternion dest) { + return normalise(this, dest); + } + + /** + * The dot product of two quaternions + * + * @param left + * The LHS quat + * @param right + * The RHS quat + * @return left dot right + */ + public static float dot(Quaternion left, Quaternion right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w + * right.w; + } + + /** + * Calculate the conjugate of this quaternion and put it into the given one + * + * @param dest + * The quaternion which should be set to the conjugate of this + * quaternion + */ + public Quaternion negate(Quaternion dest) { + return negate(this, dest); + } + + /** + * Calculate the conjugate of this quaternion and put it into the given one + * + * @param src + * The source quaternion + * @param dest + * The quaternion which should be set to the conjugate of this + * quaternion + */ + public static Quaternion negate(Quaternion src, Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + + dest.x = -src.x; + dest.y = -src.y; + dest.z = -src.z; + dest.w = src.w; + + return dest; + } + + /** + * Calculate the conjugate of this quaternion + */ + public Vector negate() { + return negate(this, this); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.Vector#load(java.nio.FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + w = buf.get(); + return this; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + return scale(scale, this, this); + } + + /** + * Scale the source quaternion by scale and put the result in the destination + * @param scale The amount to scale by + * @param src The source quaternion + * @param dest The destination quaternion, or null if a new quaternion is to be created + * @return The scaled quaternion + */ + public static Quaternion scale(float scale, Quaternion src, Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + dest.x = src.x * scale; + dest.y = src.y * scale; + dest.z = src.z * scale; + dest.w = src.w * scale; + return dest; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.ReadableVector#store(java.nio.FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + buf.put(x); + buf.put(y); + buf.put(z); + buf.put(w); + + return this; + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + /* + * (Overrides) + * + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + /** + * Set W + * + * @param w + */ + public void setW(float w) { + this.w = w; + } + + /* + * (Overrides) + * + * @see org.lwjgl.vector.ReadableVector3f#getW() + */ + public float getW() { + return w; + } + + public String toString() { + return "Quaternion: " + x + " " + y + " " + z + " " + w; + } + + /** + * Sets the value of this quaternion to the quaternion product of + * quaternions left and right (this = left * right). Note that this is safe + * for aliasing (e.g. this can be left or right). + * + * @param left + * the first quaternion + * @param right + * the second quaternion + */ + public static Quaternion mul(Quaternion left, Quaternion right, + Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + dest.set(left.x * right.w + left.w * right.x + left.y * right.z + - left.z * right.y, left.y * right.w + left.w * right.y + + left.z * right.x - left.x * right.z, left.z * right.w + + left.w * right.z + left.x * right.y - left.y * right.x, + left.w * right.w - left.x * right.x - left.y * right.y + - left.z * right.z); + return dest; + } + + /** + * + * Multiplies quaternion left by the inverse of quaternion right and places + * the value into this quaternion. The value of both argument quaternions is + * preservered (this = left * right^-1). + * + * @param left + * the left quaternion + * @param right + * the right quaternion + */ + public static Quaternion mulInverse(Quaternion left, Quaternion right, + Quaternion dest) { + float n = right.lengthSquared(); + // zero-div may occur. + n = (n == 0.0 ? n : 1 / n); + // store on stack once for aliasing-safty + if (dest == null) + dest = new Quaternion(); + dest + .set((left.x * right.w - left.w * right.x - left.y + * right.z + left.z * right.y) + * n, (left.y * right.w - left.w * right.y - left.z + * right.x + left.x * right.z) + * n, (left.z * right.w - left.w * right.z - left.x + * right.y + left.y * right.x) + * n, (left.w * right.w + left.x * right.x + left.y + * right.y + left.z * right.z) + * n); + + return dest; + } + + /** + * Sets the value of this quaternion to the equivalent rotation of the + * Axis-Angle argument. + * + * @param a1 + * the axis-angle: (x,y,z) is the axis and w is the angle + */ + public final void setFromAxisAngle(Vector4f a1) { + x = a1.x; + y = a1.y; + z = a1.z; + float n = (float) Math.sqrt(x * x + y * y + z * z); + // zero-div may occur. + float s = (float) (Math.sin(0.5 * a1.w) / n); + x *= s; + y *= s; + z *= s; + w = (float) Math.cos(0.5 * a1.w); + } + + /** + * Sets the value of this quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The matrix + * @return this + */ + public final Quaternion setFromMatrix(Matrix4f m) { + return setFromMatrix(m, this); + } + + /** + * Sets the value of the source quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + * @param q + * The destination quaternion, or null if a new quaternion is to be created + * @return q + */ + public static Quaternion setFromMatrix(Matrix4f m, Quaternion q) { + return q.setFromMat(m.m00, m.m01, m.m02, m.m10, m.m11, m.m12, m.m20, + m.m21, m.m22); + } + + /** + * Sets the value of this quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + */ + public final Quaternion setFromMatrix(Matrix3f m) { + return setFromMatrix(m, this); + } + + /** + * Sets the value of the source quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + * @param q + * The destination quaternion, or null if a new quaternion is to be created + * @return q + */ + public static Quaternion setFromMatrix(Matrix3f m, Quaternion q) { + return q.setFromMat(m.m00, m.m01, m.m02, m.m10, m.m11, m.m12, m.m20, + m.m21, m.m22); + } + + /** + * Private method to perform the matrix-to-quaternion conversion + */ + private Quaternion setFromMat(float m00, float m01, float m02, float m10, + float m11, float m12, float m20, float m21, float m22) { + + float s; + float tr = m00 + m11 + m22; + if (tr >= 0.0) { + s = (float) Math.sqrt(tr + 1.0); + w = s * 0.5f; + s = 0.5f / s; + x = (m21 - m12) * s; + y = (m02 - m20) * s; + z = (m10 - m01) * s; + } else { + float max = Math.max(Math.max(m00, m11), m22); + if (max == m00) { + s = (float) Math.sqrt(m00 - (m11 + m22) + 1.0); + x = s * 0.5f; + s = 0.5f / s; + y = (m01 + m10) * s; + z = (m20 + m02) * s; + w = (m21 - m12) * s; + } else if (max == m11) { + s = (float) Math.sqrt(m11 - (m22 + m00) + 1.0); + y = s * 0.5f; + s = 0.5f / s; + z = (m12 + m21) * s; + x = (m01 + m10) * s; + w = (m02 - m20) * s; + } else { + s = (float) Math.sqrt(m22 - (m00 + m11) + 1.0); + z = s * 0.5f; + s = 0.5f / s; + x = (m20 + m02) * s; + y = (m12 + m21) * s; + w = (m10 - m01) * s; + } + } + return this; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector.java new file mode 100644 index 0000000..6ae8f63 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.nio.FloatBuffer; + +/** + * @author foo + */ +public interface ReadableVector { + /** + * @return the length of the vector + */ + float length(); + /** + * @return the length squared of the vector + */ + float lengthSquared(); + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + Vector store(FloatBuffer buf); +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector2f.java new file mode 100644 index 0000000..1d0eb4f --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector2f.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * @author foo + */ +public interface ReadableVector2f extends ReadableVector { + /** + * @return x + */ + float getX(); + /** + * @return y + */ + float getY(); +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector3f.java new file mode 100644 index 0000000..216e1dc --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector3f.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * @author foo + */ +public interface ReadableVector3f extends ReadableVector2f { + /** + * @return z + */ + float getZ(); +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector4f.java new file mode 100644 index 0000000..81ca284 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/ReadableVector4f.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * @author foo + */ +public interface ReadableVector4f extends ReadableVector3f { + + /** + * @return w + */ + float getW(); + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector.java new file mode 100644 index 0000000..6d226e6 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Base class for vectors. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ +public abstract class Vector implements Serializable, ReadableVector { + + /** + * Constructor for Vector. + */ + protected Vector() { + super(); + } + + /** + * @return the length of the vector + */ + public final float length() { + return (float) Math.sqrt(lengthSquared()); + } + + + /** + * @return the length squared of the vector + */ + public abstract float lengthSquared(); + + /** + * Load this vector from a FloatBuffer + * @param buf The buffer to load it from, at the current position + * @return this + */ + public abstract Vector load(FloatBuffer buf); + + /** + * Negate a vector + * @return this + */ + public abstract Vector negate(); + + + /** + * Normalise this vector + * @return this + */ + public final Vector normalise() { + float len = length(); + if (len != 0.0f) { + float l = 1.0f / len; + return scale(l); + } else + throw new IllegalStateException("Zero length vector"); + } + + + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + public abstract Vector store(FloatBuffer buf); + + + /** + * Scale this vector + * @param scale The scale factor + * @return this + */ + public abstract Vector scale(float scale); + + + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector2f.java new file mode 100644 index 0000000..6b77ceb --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector2f.java @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 2-tuple vector. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Vector2f extends Vector implements Serializable, ReadableVector2f, WritableVector2f { + + private static final long serialVersionUID = 1L; + + public float x, y; + + /** + * Constructor for Vector2f. + */ + public Vector2f() { + super(); + } + + /** + * Constructor. + */ + public Vector2f(ReadableVector2f src) { + set(src); + } + + /** + * Constructor. + */ + public Vector2f(float x, float y) { + set(x, y); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /** + * Load from another Vector2f + * @param src The source vector + * @return this + */ + public Vector2f set(ReadableVector2f src) { + x = src.getX(); + y = src.getY(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector2f translate(float x, float y) { + this.x += x; + this.y += y; + return this; + } + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector2f negate(Vector2f dest) { + if (dest == null) + dest = new Vector2f(); + dest.x = -x; + dest.y = -y; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector2f normalise(Vector2f dest) { + float l = length(); + + if (dest == null) + dest = new Vector2f(x / l, y / l); + else + dest.set(x / l, y / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector2f left, Vector2f right) { + return left.x * right.x + left.y * right.y; + } + + + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector2f a, Vector2f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector2f add(Vector2f left, Vector2f right, Vector2f dest) { + if (dest == null) + return new Vector2f(left.x + right.x, left.y + right.y); + else { + dest.set(left.x + right.x, left.y + right.y); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector2f sub(Vector2f left, Vector2f right, Vector2f dest) { + if (dest == null) + return new Vector2f(left.x - right.x, left.y - right.y); + else { + dest.set(left.x - right.x, left.y - right.y); + return dest; + } + } + + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + public Vector store(FloatBuffer buf) { + buf.put(x); + buf.put(y); + return this; + } + + /** + * Load this vector from a FloatBuffer + * @param buf The buffer to load it from, at the current position + * @return this + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + + x *= scale; + y *= scale; + + return this; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(64); + + sb.append("Vector2f["); + sb.append(x); + sb.append(", "); + sb.append(y); + sb.append(']'); + return sb.toString(); + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Vector2f other = (Vector2f)obj; + + if (x == other.x && y == other.y) return true; + + return false; + } + +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector3f.java new file mode 100644 index 0000000..b56617f --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector3f.java @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 3-tuple vector. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Vector3f extends Vector implements Serializable, ReadableVector3f, WritableVector3f { + + private static final long serialVersionUID = 1L; + + public float x, y, z; + + /** + * Constructor for Vector3f. + */ + public Vector3f() { + super(); + } + + /** + * Constructor + */ + public Vector3f(ReadableVector3f src) { + set(src); + } + + /** + * Constructor + */ + public Vector3f(float x, float y, float z) { + set(x, y, z); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Load from another Vector3f + * @param src The source vector + * @return this + */ + public Vector3f set(ReadableVector3f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y + z * z; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector3f translate(float x, float y, float z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector3f add(Vector3f left, Vector3f right, Vector3f dest) { + if (dest == null) + return new Vector3f(left.x + right.x, left.y + right.y, left.z + right.z); + else { + dest.set(left.x + right.x, left.y + right.y, left.z + right.z); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector3f sub(Vector3f left, Vector3f right, Vector3f dest) { + if (dest == null) + return new Vector3f(left.x - right.x, left.y - right.y, left.z - right.z); + else { + dest.set(left.x - right.x, left.y - right.y, left.z - right.z); + return dest; + } + } + + /** + * The cross product of two vectors. + * + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination result, or null if a new vector is to be created + * @return left cross right + */ + public static Vector3f cross( + Vector3f left, + Vector3f right, + Vector3f dest) + { + + if (dest == null) + dest = new Vector3f(); + + dest.set( + left.y * right.z - left.z * right.y, + right.x * left.z - right.z * left.x, + left.x * right.y - left.y * right.x + ); + + return dest; + } + + + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + z = -z; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector3f negate(Vector3f dest) { + if (dest == null) + dest = new Vector3f(); + dest.x = -x; + dest.y = -y; + dest.z = -z; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector3f normalise(Vector3f dest) { + float l = length(); + + if (dest == null) + dest = new Vector3f(x / l, y / l, z / l); + else + dest.set(x / l, y / l, z / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector3f left, Vector3f right) { + return left.x * right.x + left.y * right.y + left.z * right.z; + } + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector3f a, Vector3f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#load(FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + + x *= scale; + y *= scale; + z *= scale; + + return this; + + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#store(FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + + buf.put(x); + buf.put(y); + buf.put(z); + + return this; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(64); + + sb.append("Vector3f["); + sb.append(x); + sb.append(", "); + sb.append(y); + sb.append(", "); + sb.append(z); + sb.append(']'); + return sb.toString(); + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Vector3f other = (Vector3f)obj; + + if (x == other.x && y == other.y && z == other.z) return true; + + return false; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector4f.java new file mode 100644 index 0000000..95b4ea2 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/Vector4f.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 4-tuple vector. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public class Vector4f extends Vector implements Serializable, ReadableVector4f, WritableVector4f { + + private static final long serialVersionUID = 1L; + + public float x, y, z, w; + + /** + * Constructor for Vector4f. + */ + public Vector4f() { + super(); + } + + /** + * Constructor + */ + public Vector4f(ReadableVector4f src) { + set(src); + } + + /** + * Constructor + */ + public Vector4f(float x, float y, float z, float w) { + set(x, y, z, w); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector4f#set(float, float, float, float) + */ + public void set(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** + * Load from another Vector4f + * @param src The source vector + * @return this + */ + public Vector4f set(ReadableVector4f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + w = src.getW(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y + z * z + w * w; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector4f translate(float x, float y, float z, float w) { + this.x += x; + this.y += y; + this.z += z; + this.w += w; + return this; + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector4f add(Vector4f left, Vector4f right, Vector4f dest) { + if (dest == null) + return new Vector4f(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + else { + dest.set(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector4f sub(Vector4f left, Vector4f right, Vector4f dest) { + if (dest == null) + return new Vector4f(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + else { + dest.set(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + return dest; + } + } + + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + z = -z; + w = -w; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector4f negate(Vector4f dest) { + if (dest == null) + dest = new Vector4f(); + dest.x = -x; + dest.y = -y; + dest.z = -z; + dest.w = -w; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector4f normalise(Vector4f dest) { + float l = length(); + + if (dest == null) + dest = new Vector4f(x / l, y / l, z / l, w / l); + else + dest.set(x / l, y / l, z / l, w / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector4f left, Vector4f right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + } + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector4f a, Vector4f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#load(FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + w = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + x *= scale; + y *= scale; + z *= scale; + w *= scale; + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#store(FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + + buf.put(x); + buf.put(y); + buf.put(z); + buf.put(w); + + return this; + } + + public String toString() { + return "Vector4f: " + x + " " + y + " " + z + " " + w; + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + /** + * Set W + * @param w + */ + public void setW(float w) { + this.w = w; + } + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getW() { + return w; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Vector4f other = (Vector4f)obj; + + if (x == other.x && y == other.y && z == other.z && w == other.w) return true; + + return false; + } +} diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector2f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector2f.java new file mode 100644 index 0000000..e4b478a --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector2f.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * Writable interface to Vector2fs + * @author $author$ + * @version $revision$ + * $Id$ + */ +public interface WritableVector2f { + + /** + * Set the X value + * @param x + */ + void setX(float x); + + /** + * Set the Y value + * @param y + */ + void setY(float y); + + /** + * Set the X,Y values + * @param x + * @param y + */ + void set(float x, float y); + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector3f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector3f.java new file mode 100644 index 0000000..2ed00d0 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector3f.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * Writable interface to Vector3fs + * @author $author$ + * @version $revision$ + * $Id$ + */ +public interface WritableVector3f extends WritableVector2f { + + /** + * Set the Z value + * @param z + */ + void setZ(float z); + + /** + * Set the X,Y,Z values + * @param x + * @param y + * @param z + */ + void set(float x, float y, float z); + +} \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector4f.java b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector4f.java new file mode 100644 index 0000000..7288c97 --- /dev/null +++ b/src/main/java/net/lax1dude/eaglercraft/glemu/vector/WritableVector4f.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.lax1dude.eaglercraft.glemu.vector; + +/** + * Writable interface to Vector4fs + * @author $author$ + * @version $revision$ + * $Id$ + */ +public interface WritableVector4f extends WritableVector3f { + + /** + * Set the W value + * @param w + */ + void setW(float w); + + /** + * Set the X,Y,Z,W values + * @param x + * @param y + * @param z + * @param w + */ + void set(float x, float y, float z, float w); + +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java new file mode 100644 index 0000000..d64be6d --- /dev/null +++ b/src/main/java/net/minecraft/client/Minecraft.java @@ -0,0 +1,1582 @@ +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +package net.minecraft.client; + +import java.awt.*; +import java.io.*; +import java.nio.ByteBuffer; +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.input.*; +import org.lwjgl.opengl.*; +import org.lwjgl.opengl.DisplayMode; +import org.lwjgl.util.glu.GLU; + +import net.minecraft.src.*; + +// Referenced classes of package net.minecraft.client: +// MinecraftApplet + +public class Minecraft implements Runnable +{ + + public Minecraft(Canvas canvas, int i, int j, boolean flag) + { + instance = this; + fullscreen = false; + timer = new Timer(20F); + session = null; + hideQuitButton = true; + isWorldLoaded = false; + currentScreen = null; + loadingScreen = new LoadingScreenRenderer(this); + entityRenderer = new EntityRenderer(this); + ticksRan = 0; + field_6282_S = 0; + field_6307_v = false; + field_9242_w = new ModelBiped(0.0F); + objectMouseOver = null; + sndManager = new SoundManager(); + textureWaterFX = new TextureWaterFX(); + textureLavaFX = new TextureLavaFX(); + running = true; + debug = ""; + isTakingScreenshot = false; + prevFrameTime = -1L; + field_6289_L = false; + field_6302_aa = 0; + isRaining = false; + systemTime = System.currentTimeMillis(); + field_6300_ab = 0; + field_9235_U = j; + fullscreen = flag; + new ThreadSleepForever(this, "Timer hack thread"); + mcCanvas = canvas; + displayWidth = i; + displayHeight = j; + fullscreen = flag; + hideQuitButton = false; + field_21900_a = this; + } + + public void setServer(String s, int i) + { + serverName = s; + serverPort = i; + } + + public void startGame() throws LWJGLException + { + if(mcCanvas != null) + { + Graphics g = mcCanvas.getGraphics(); + if(g != null) + { + g.setColor(Color.BLACK); + g.fillRect(0, 0, displayWidth, displayHeight); + g.dispose(); + } + Display.setParent(mcCanvas); + } else + if(fullscreen) + { + Display.setFullscreen(true); + displayWidth = Display.getDisplayMode().getWidth(); + displayHeight = Display.getDisplayMode().getHeight(); + if(displayWidth <= 0) + { + displayWidth = 1; + } + if(displayHeight <= 0) + { + displayHeight = 1; + } + } else + { + Display.setDisplayMode(new DisplayMode(displayWidth, displayHeight)); + } + Display.setTitle("Minecraft Minecraft Beta 1.3_01"); + try + { + Display.create(); + } + catch(LWJGLException lwjglexception) + { + lwjglexception.printStackTrace(); + try + { + Thread.sleep(1000L); + } + catch(InterruptedException interruptedexception) { } + Display.create(); + } + RenderManager.instance.itemRenderer = new ItemRenderer(this); + mcDataDir = getMinecraftDir(); + field_22008_V = new SaveConverterMcRegion(new File(mcDataDir, "saves")); + gameSettings = new GameSettings(this, mcDataDir); + texturePackList = new TexturePackList(this, mcDataDir); + renderEngine = new RenderEngine(texturePackList, gameSettings); + fontRenderer = new FontRenderer(gameSettings, "/font/default.png", renderEngine); + loadScreen(); + Keyboard.create(); + Mouse.create(); + mouseHelper = new MouseHelper(mcCanvas); + try + { + Controllers.create(); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + checkGLError("Pre startup"); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glShadeModel(7425 /*GL_SMOOTH*/); + GL11.glClearDepth(1.0D); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glDepthFunc(515); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glAlphaFunc(516, 0.1F); + GL11.glCullFace(1029 /*GL_BACK*/); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + checkGLError("Startup"); + glCapabilities = new OpenGlCapsChecker(); + sndManager.loadSoundSettings(gameSettings); + renderEngine.registerTextureFX(textureLavaFX); + renderEngine.registerTextureFX(textureWaterFX); + renderEngine.registerTextureFX(new TexturePortalFX()); + renderEngine.registerTextureFX(new TextureCompassFX(this)); + renderEngine.registerTextureFX(new TextureWatchFX(this)); + renderEngine.registerTextureFX(new TexureWaterFlowFX()); + renderEngine.registerTextureFX(new TextureLavaFlowFX()); + renderEngine.registerTextureFX(new TextureFlamesFX(0)); + renderEngine.registerTextureFX(new TextureFlamesFX(1)); + renderGlobal = new RenderGlobal(this, renderEngine); + GL11.glViewport(0, 0, displayWidth, displayHeight); + effectRenderer = new EffectRenderer(theWorld, renderEngine); + checkGLError("Post startup"); + ingameGUI = new GuiIngame(this); + if(serverName != null) + { + displayGuiScreen(new GuiConnecting(this, serverName, serverPort)); + } else + { + displayGuiScreen(new GuiMainMenu()); + } + } + + private void loadScreen() throws LWJGLException + { + ScaledResolution scaledresolution = new ScaledResolution(displayWidth, displayHeight); + int i = scaledresolution.getScaledWidth(); + int j = scaledresolution.getScaledHeight(); + GL11.glClear(16640); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, i, j, 0.0D, 1000D, 3000D); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -2000F); + GL11.glViewport(0, 0, displayWidth, displayHeight); + GL11.glClearColor(0.0F, 0.0F, 0.0F, 0.0F); + Tessellator tessellator = Tessellator.instance; + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(2912 /*GL_FOG*/); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/title/mojang.png")); + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0xffffff); + tessellator.addVertexWithUV(0.0D, displayHeight, 0.0D, 0.0D, 0.0D); + tessellator.addVertexWithUV(displayWidth, displayHeight, 0.0D, 0.0D, 0.0D); + tessellator.addVertexWithUV(displayWidth, 0.0D, 0.0D, 0.0D, 0.0D); + tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + char c = '\u0100'; + char c1 = '\u0100'; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tessellator.setColorOpaque_I(0xffffff); + func_6274_a((displayWidth / 2 - c) / 2, (displayHeight / 2 - c1) / 2, 0, 0, c, c1); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2912 /*GL_FOG*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glAlphaFunc(516, 0.1F); + Display.swapBuffers(); + } + + public void func_6274_a(int i, int j, int k, int l, int i1, int j1) + { + float f = 0.00390625F; + float f1 = 0.00390625F; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(i + 0, j + j1, 0.0D, (float)(k + 0) * f, (float)(l + j1) * f1); + tessellator.addVertexWithUV(i + i1, j + j1, 0.0D, (float)(k + i1) * f, (float)(l + j1) * f1); + tessellator.addVertexWithUV(i + i1, j + 0, 0.0D, (float)(k + i1) * f, (float)(l + 0) * f1); + tessellator.addVertexWithUV(i + 0, j + 0, 0.0D, (float)(k + 0) * f, (float)(l + 0) * f1); + tessellator.draw(); + } + + public static File getMinecraftDir() + { + if(minecraftDir == null) + { + minecraftDir = new File("."); + } + return minecraftDir; + } + + public static File getAppDir(String s) + { + String s1 = System.getProperty("user.home", "."); + File file; + switch(EnumOSMappingHelper.enumOSMappingArray[getOs().ordinal()]) + { + case 1: // '\001' + case 2: // '\002' + file = new File(s1, (new StringBuilder()).append('.').append(s).append('/').toString()); + break; + + case 3: // '\003' + String s2 = System.getenv("APPDATA"); + if(s2 != null) + { + file = new File(s2, (new StringBuilder()).append(".").append(s).append('/').toString()); + } else + { + file = new File(s1, (new StringBuilder()).append('.').append(s).append('/').toString()); + } + break; + + case 4: // '\004' + file = new File(s1, (new StringBuilder()).append("Library/Application Support/").append(s).toString()); + break; + + default: + file = new File(s1, (new StringBuilder()).append(s).append('/').toString()); + break; + } + if(!file.exists() && !file.mkdirs()) + { + throw new RuntimeException((new StringBuilder()).append("The working directory could not be created: ").append(file).toString()); + } else + { + return file; + } + } + + private static EnumOS2 getOs() + { + String s = System.getProperty("os.name").toLowerCase(); + if(s.contains("win")) + { + return EnumOS2.windows; + } + if(s.contains("mac")) + { + return EnumOS2.macos; + } + if(s.contains("solaris")) + { + return EnumOS2.solaris; + } + if(s.contains("sunos")) + { + return EnumOS2.solaris; + } + if(s.contains("linux")) + { + return EnumOS2.linux; + } + if(s.contains("unix")) + { + return EnumOS2.linux; + } else + { + return EnumOS2.unknown; + } + } + + public ISaveFormat func_22004_c() + { + return field_22008_V; + } + + public void displayGuiScreen(GuiScreen guiscreen) + { + if(currentScreen instanceof GuiUnused) + { + return; + } + if(currentScreen != null) + { + currentScreen.onGuiClosed(); + } + if(guiscreen == null && theWorld == null) + { + guiscreen = new GuiMainMenu(); + } else + if(guiscreen == null && thePlayer.health <= 0) + { + guiscreen = new GuiGameOver(); + } + currentScreen = guiscreen; + if(guiscreen != null) + { + func_6273_f(); + ScaledResolution scaledresolution = new ScaledResolution(displayWidth, displayHeight); + int i = scaledresolution.getScaledWidth(); + int j = scaledresolution.getScaledHeight(); + guiscreen.setWorldAndResolution(this, i, j); + field_6307_v = false; + } else + { + func_6259_e(); + } + } + + private void checkGLError(String s) + { + int i = GL11.glGetError(); + if(i != 0) + { + String s1 = GLU.gluErrorString(i); + System.out.println("########## GL ERROR ##########"); + System.out.println((new StringBuilder()).append("@ ").append(s).toString()); + System.out.println((new StringBuilder()).append(i).append(": ").append(s1).toString()); + System.exit(0); + } + } + + public void shutdownMinecraftApplet() + { + try + { + System.out.println("Stopping!"); + try + { + changeWorld1(null); + } + catch(Throwable throwable) { } + try + { + GLAllocation.deleteTexturesAndDisplayLists(); + } + catch(Throwable throwable1) { } + sndManager.closeMinecraft(); + Mouse.destroy(); + Keyboard.destroy(); + } + finally + { + Display.destroy(); + System.exit(0); + } + System.gc(); + } + + public void run() + { + running = true; + try + { + startGame(); + } + catch(Exception exception) + { + exception.printStackTrace(); + //displayUnexpectedThrowable(new UnexpectedThrowable("Failed to start game", exception)); //TODO: crash screen + return; + } + try + { + long l = System.currentTimeMillis(); + int i = 0; + while(running) + { + AxisAlignedBB.clearBoundingBoxPool(); + Vec3D.initialize(); + if(mcCanvas == null && Display.isCloseRequested()) + { + shutdown(); + } + if(isWorldLoaded && theWorld != null) + { + float f = timer.renderPartialTicks; + timer.updateTimer(); + timer.renderPartialTicks = f; + } else + { + timer.updateTimer(); + } + long l1 = System.nanoTime(); + for(int j = 0; j < timer.elapsedTicks; j++) + { + ticksRan++; + try + { + runTick(); + continue; + } + catch(MinecraftException minecraftexception) + { + theWorld = null; + } + changeWorld1(null); + displayGuiScreen(new GuiConflictWarning()); + } + + long l2 = System.nanoTime() - l1; + checkGLError("Pre render"); + sndManager.func_338_a(thePlayer, timer.renderPartialTicks); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + if(theWorld != null && !theWorld.multiplayerWorld) + { + theWorld.func_6465_g(); + } + if(theWorld != null && theWorld.multiplayerWorld) + { + theWorld.func_6465_g(); + } + if(gameSettings.limitFramerate) + { + Thread.sleep(5L); + } + if(!Keyboard.isKeyDown(65)) + { + Display.update(); + } + if(!field_6307_v) + { + if(playerController != null) + { + playerController.setPartialTime(timer.renderPartialTicks); + } + entityRenderer.func_4136_b(timer.renderPartialTicks); + } + if(!Display.isActive()) + { + if(fullscreen) + { + toggleFullscreen(); + } + Thread.sleep(10L); + } + if(gameSettings.showDebugInfo) + { + displayDebugInfo(l2); + } else + { + prevFrameTime = System.nanoTime(); + } + Thread.yield(); + if(Keyboard.isKeyDown(65)) + { + Display.update(); + } + screenshotListener(); + if(mcCanvas != null && !fullscreen && (mcCanvas.getWidth() != displayWidth || mcCanvas.getHeight() != displayHeight)) + { + displayWidth = mcCanvas.getWidth(); + displayHeight = mcCanvas.getHeight(); + if(displayWidth <= 0) + { + displayWidth = 1; + } + if(displayHeight <= 0) + { + displayHeight = 1; + } + resize(displayWidth, displayHeight); + } + checkGLError("Post render"); + i++; + isWorldLoaded = !isMultiplayerWorld() && currentScreen != null && currentScreen.doesGuiPauseGame(); + while(System.currentTimeMillis() >= l + 1000L) + { + debug = (new StringBuilder()).append(i).append(" fps, ").append(WorldRenderer.chunksUpdated).append(" chunk updates").toString(); + WorldRenderer.chunksUpdated = 0; + l += 1000L; + i = 0; + } + } + } + catch(MinecraftError minecrafterror) { } + catch(Throwable throwable) + { + theWorld = null; + throwable.printStackTrace(); + //displayUnexpectedThrowable(new UnexpectedThrowable("Unexpected error", throwable)); //TODO: crash screen + } + finally + { + shutdownMinecraftApplet(); + } + } + + private void screenshotListener() + { + if(Keyboard.isKeyDown(60)) + { + if(!isTakingScreenshot) + { + isTakingScreenshot = true; + if(Keyboard.isKeyDown(42)) + { + ingameGUI.addChatMessage(func_21001_a(minecraftDir, displayWidth, displayHeight, 36450, 17700)); + } else + { + ingameGUI.addChatMessage(ScreenShotHelper.saveScreenshot(minecraftDir, displayWidth, displayHeight)); + } + } + } else + { + isTakingScreenshot = false; + } + } + + private String func_21001_a(File file, int i, int j, int k, int l) + { + try + { + ByteBuffer bytebuffer = BufferUtils.createByteBuffer(i * j * 3); + ScreenShotHelper screenshothelper = new ScreenShotHelper(file, k, l, j); + double d = (double)k / (double)i; + double d1 = (double)l / (double)j; + double d2 = d <= d1 ? d1 : d; + for(int i1 = ((l - 1) / j) * j; i1 >= 0; i1 -= j) + { + for(int j1 = 0; j1 < k; j1 += i) + { + int k1 = i; + int l1 = j; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/terrain.png")); + double d3 = ((double)(k - i) / 2D) * 2D - (double)(j1 * 2); + double d4 = ((double)(l - j) / 2D) * 2D - (double)(i1 * 2); + d3 /= i; + d4 /= j; + entityRenderer.func_21152_a(d2, d3, d4); + entityRenderer.renderWorld(1.0F); + entityRenderer.func_21151_b(); + Display.update(); + try + { + Thread.sleep(10L); + } + catch(InterruptedException interruptedexception) + { + interruptedexception.printStackTrace(); + } + Display.update(); + bytebuffer.clear(); + GL11.glPixelStorei(3333 /*GL_PACK_ALIGNMENT*/, 1); + GL11.glPixelStorei(3317 /*GL_UNPACK_ALIGNMENT*/, 1); + GL11.glReadPixels(0, 0, k1, l1, 32992 /*GL_BGR_EXT*/, 5121 /*GL_UNSIGNED_BYTE*/, bytebuffer); + screenshothelper.func_21189_a(bytebuffer, j1, i1, k1, l1); + } + + screenshothelper.func_21191_a(); + } + + return screenshothelper.func_21190_b(); + } + catch(Exception exception) + { + exception.printStackTrace(); + return (new StringBuilder()).append("Failed to save image: ").append(exception).toString(); + } + } + + private void displayDebugInfo(long l) + { + long l1 = 0xfe502aL; + if(prevFrameTime == -1L) + { + prevFrameTime = System.nanoTime(); + } + long l2 = System.nanoTime(); + tickTimes[numRecordedFrameTimes & frameTimes.length - 1] = l; + frameTimes[numRecordedFrameTimes++ & frameTimes.length - 1] = l2 - prevFrameTime; + prevFrameTime = l2; + GL11.glClear(256); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, displayWidth, displayHeight, 0.0D, 1000D, 3000D); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -2000F); + GL11.glLineWidth(1.0F); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawing(7); + int i = (int)(l1 / 0x30d40L); + tessellator.setColorOpaque_I(0x20000000); + tessellator.addVertex(0.0D, displayHeight - i, 0.0D); + tessellator.addVertex(0.0D, displayHeight, 0.0D); + tessellator.addVertex(frameTimes.length, displayHeight, 0.0D); + tessellator.addVertex(frameTimes.length, displayHeight - i, 0.0D); + tessellator.setColorOpaque_I(0x20200000); + tessellator.addVertex(0.0D, displayHeight - i * 2, 0.0D); + tessellator.addVertex(0.0D, displayHeight - i, 0.0D); + tessellator.addVertex(frameTimes.length, displayHeight - i, 0.0D); + tessellator.addVertex(frameTimes.length, displayHeight - i * 2, 0.0D); + tessellator.draw(); + long l3 = 0L; + for(int j = 0; j < frameTimes.length; j++) + { + l3 += frameTimes[j]; + } + + int k = (int)(l3 / 0x30d40L / (long)frameTimes.length); + tessellator.startDrawing(7); + tessellator.setColorOpaque_I(0x20400000); + tessellator.addVertex(0.0D, displayHeight - k, 0.0D); + tessellator.addVertex(0.0D, displayHeight, 0.0D); + tessellator.addVertex(frameTimes.length, displayHeight, 0.0D); + tessellator.addVertex(frameTimes.length, displayHeight - k, 0.0D); + tessellator.draw(); + tessellator.startDrawing(1); + for(int i1 = 0; i1 < frameTimes.length; i1++) + { + int j1 = ((i1 - numRecordedFrameTimes & frameTimes.length - 1) * 255) / frameTimes.length; + int k1 = (j1 * j1) / 255; + k1 = (k1 * k1) / 255; + int i2 = (k1 * k1) / 255; + i2 = (i2 * i2) / 255; + if(frameTimes[i1] > l1) + { + tessellator.setColorOpaque_I(0xff000000 + k1 * 0x10000); + } else + { + tessellator.setColorOpaque_I(0xff000000 + k1 * 256); + } + long l4 = frameTimes[i1] / 0x30d40L; + long l5 = tickTimes[i1] / 0x30d40L; + tessellator.addVertex((float)i1 + 0.5F, (float)((long)displayHeight - l4) + 0.5F, 0.0D); + tessellator.addVertex((float)i1 + 0.5F, (float)displayHeight + 0.5F, 0.0D); + tessellator.setColorOpaque_I(0xff000000 + k1 * 0x10000 + k1 * 256 + k1 * 1); + tessellator.addVertex((float)i1 + 0.5F, (float)((long)displayHeight - l4) + 0.5F, 0.0D); + tessellator.addVertex((float)i1 + 0.5F, (float)((long)displayHeight - (l4 - l5)) + 0.5F, 0.0D); + } + + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + + public void shutdown() + { + running = false; + } + + public void func_6259_e() + { + if(!Display.isActive()) + { + return; + } + if(field_6289_L) + { + return; + } else + { + field_6289_L = true; + mouseHelper.func_774_a(); + displayGuiScreen(null); + field_6302_aa = ticksRan + 10000; + return; + } + } + + public void func_6273_f() + { + if(!field_6289_L) + { + return; + } + if(thePlayer != null) + { + thePlayer.resetPlayerKeyState(); + } + field_6289_L = false; + mouseHelper.func_773_b(); + } + + public void func_6252_g() + { + if(currentScreen != null) + { + return; + } else + { + displayGuiScreen(new GuiIngameMenu()); + return; + } + } + + private void func_6254_a(int i, boolean flag) + { + if(playerController.field_1064_b) + { + return; + } + if(i == 0 && field_6282_S > 0) + { + return; + } + if(flag && objectMouseOver != null && objectMouseOver.typeOfHit == EnumMovingObjectType.TILE && i == 0) + { + int j = objectMouseOver.blockX; + int k = objectMouseOver.blockY; + int l = objectMouseOver.blockZ; + playerController.sendBlockRemoving(j, k, l, objectMouseOver.sideHit); + effectRenderer.addBlockHitEffects(j, k, l, objectMouseOver.sideHit); + } else + { + playerController.func_6468_a(); + } + } + + private void clickMouse(int i) + { + if(i == 0 && field_6282_S > 0) + { + return; + } + if(i == 0) + { + thePlayer.swingItem(); + } + boolean flag = true; + if(objectMouseOver == null) + { + if(i == 0) + { + field_6282_S = 10; + } + } else + if(objectMouseOver.typeOfHit == EnumMovingObjectType.ENTITY) + { + if(i == 0) + { + playerController.func_6472_b(thePlayer, objectMouseOver.entityHit); + } + if(i == 1) + { + playerController.func_6475_a(thePlayer, objectMouseOver.entityHit); + } + } else + if(objectMouseOver.typeOfHit == EnumMovingObjectType.TILE) + { + int j = objectMouseOver.blockX; + int k = objectMouseOver.blockY; + int l = objectMouseOver.blockZ; + int i1 = objectMouseOver.sideHit; + Block block = Block.blocksList[theWorld.getBlockId(j, k, l)]; + if(i == 0) + { + theWorld.onBlockHit(j, k, l, objectMouseOver.sideHit); + if(block != Block.bedrock || thePlayer.field_9371_f >= 100) + { + playerController.clickBlock(j, k, l, objectMouseOver.sideHit); + } + } else + { + ItemStack itemstack1 = thePlayer.inventory.getCurrentItem(); + int j1 = itemstack1 == null ? 0 : itemstack1.stackSize; + if(playerController.sendPlaceBlock(thePlayer, theWorld, itemstack1, j, k, l, i1)) + { + flag = false; + thePlayer.swingItem(); + } + if(itemstack1 == null) + { + return; + } + if(itemstack1.stackSize == 0) + { + thePlayer.inventory.mainInventory[thePlayer.inventory.currentItem] = null; + } else + if(itemstack1.stackSize != j1) + { + entityRenderer.itemRenderer.func_9449_b(); + } + } + } + if(flag && i == 1) + { + ItemStack itemstack = thePlayer.inventory.getCurrentItem(); + if(itemstack != null && playerController.sendUseItem(thePlayer, theWorld, itemstack)) + { + entityRenderer.itemRenderer.func_9450_c(); + } + } + } + + public void toggleFullscreen() + { + try + { + fullscreen = !fullscreen; + System.out.println("Toggle fullscreen!"); + if(fullscreen) + { + Display.setDisplayMode(Display.getDesktopDisplayMode()); + displayWidth = Display.getDisplayMode().getWidth(); + displayHeight = Display.getDisplayMode().getHeight(); + if(displayWidth <= 0) + { + displayWidth = 1; + } + if(displayHeight <= 0) + { + displayHeight = 1; + } + } else + { + if(mcCanvas != null) + { + displayWidth = mcCanvas.getWidth(); + displayHeight = mcCanvas.getHeight(); + } else + { + displayWidth = field_9236_T; + displayHeight = field_9235_U; + } + if(displayWidth <= 0) + { + displayWidth = 1; + } + if(displayHeight <= 0) + { + displayHeight = 1; + } + Display.setDisplayMode(new DisplayMode(field_9236_T, field_9235_U)); + } + func_6273_f(); + Display.setFullscreen(fullscreen); + Display.update(); + Thread.sleep(1000L); + if(fullscreen) + { + func_6259_e(); + } + if(currentScreen != null) + { + func_6273_f(); + resize(displayWidth, displayHeight); + } + System.out.println((new StringBuilder()).append("Size: ").append(displayWidth).append(", ").append(displayHeight).toString()); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + private void resize(int i, int j) + { + if(i <= 0) + { + i = 1; + } + if(j <= 0) + { + j = 1; + } + displayWidth = i; + displayHeight = j; + if(currentScreen != null) + { + ScaledResolution scaledresolution = new ScaledResolution(i, j); + int k = scaledresolution.getScaledWidth(); + int l = scaledresolution.getScaledHeight(); + currentScreen.setWorldAndResolution(this, k, l); + } + } + + private void clickMiddleMouseButton() + { + if(objectMouseOver != null) + { + int i = theWorld.getBlockId(objectMouseOver.blockX, objectMouseOver.blockY, objectMouseOver.blockZ); + if(i == Block.grass.blockID) + { + i = Block.dirt.blockID; + } + if(i == Block.stairDouble.blockID) + { + i = Block.stairSingle.blockID; + } + if(i == Block.bedrock.blockID) + { + i = Block.stone.blockID; + } + thePlayer.inventory.setCurrentItem(i, false); + } + } + + public void runTick() + { + ingameGUI.updateTick(); + entityRenderer.getMouseOver(1.0F); + if(thePlayer != null) + { + IChunkProvider ichunkprovider = theWorld.func_21118_q(); + if(ichunkprovider instanceof ChunkProviderLoadOrGenerate) + { + ChunkProviderLoadOrGenerate chunkproviderloadorgenerate = (ChunkProviderLoadOrGenerate)ichunkprovider; + int j = MathHelper.floor_float((int)thePlayer.posX) >> 4; + int i1 = MathHelper.floor_float((int)thePlayer.posZ) >> 4; + chunkproviderloadorgenerate.func_21110_c(j, i1); + } + } + if(!isWorldLoaded && theWorld != null) + { + playerController.updateController(); + } + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/terrain.png")); + if(!isWorldLoaded) + { + renderEngine.func_1067_a(); + } + if(currentScreen == null && thePlayer != null) + { + if(thePlayer.health <= 0) + { + displayGuiScreen(null); + } else + if(thePlayer.isPlayerSleeping() && theWorld != null && theWorld.multiplayerWorld) + { + displayGuiScreen(new GuiSleepMP()); + } + } else + if(currentScreen != null && (currentScreen instanceof GuiSleepMP) && !thePlayer.isPlayerSleeping()) + { + displayGuiScreen(null); + } + if(currentScreen != null) + { + field_6302_aa = ticksRan + 10000; + } + if(currentScreen != null) + { + currentScreen.handleInput(); + if(currentScreen != null) + { + currentScreen.updateScreen(); + } + } + if(currentScreen == null || currentScreen.field_948_f) + { + do + { + if(!Mouse.next()) + { + break; + } + long l = System.currentTimeMillis() - systemTime; + if(l <= 200L) + { + int k = Mouse.getEventDWheel(); + if(k != 0) + { + thePlayer.inventory.changeCurrentItem(k); + if(gameSettings.field_22275_C) + { + if(k > 0) + { + k = 1; + } + if(k < 0) + { + k = -1; + } + gameSettings.field_22272_F += (float)k * 0.25F; + } + } + if(currentScreen == null) + { + if(!field_6289_L && Mouse.getEventButtonState()) + { + func_6259_e(); + } else + { + if(Mouse.getEventButton() == 0 && Mouse.getEventButtonState()) + { + clickMouse(0); + field_6302_aa = ticksRan; + } + if(Mouse.getEventButton() == 1 && Mouse.getEventButtonState()) + { + clickMouse(1); + field_6302_aa = ticksRan; + } + if(Mouse.getEventButton() == 2 && Mouse.getEventButtonState()) + { + clickMiddleMouseButton(); + } + } + } else + if(currentScreen != null) + { + currentScreen.handleMouseInput(); + } + } + } while(true); + if(field_6282_S > 0) + { + field_6282_S--; + } + do + { + if(!Keyboard.next()) + { + break; + } + thePlayer.handleKeyPress(Keyboard.getEventKey(), Keyboard.getEventKeyState()); + if(Keyboard.getEventKeyState()) + { + if(Keyboard.getEventKey() == 87) + { + toggleFullscreen(); + } else + { + if(currentScreen != null) + { + currentScreen.handleKeyboardInput(); + } else + { + if(Keyboard.getEventKey() == 1) + { + func_6252_g(); + } + if(Keyboard.getEventKey() == 31 && Keyboard.isKeyDown(61)) + { + forceReload(); + } + if(Keyboard.getEventKey() == 59) + { + gameSettings.field_22277_y = !gameSettings.field_22277_y; + } + if(Keyboard.getEventKey() == 61) + { + gameSettings.showDebugInfo = !gameSettings.showDebugInfo; + } + if(Keyboard.getEventKey() == 63) + { + gameSettings.thirdPersonView = !gameSettings.thirdPersonView; + } + if(Keyboard.getEventKey() == 66) + { + gameSettings.field_22274_D = !gameSettings.field_22274_D; + } + if(Keyboard.getEventKey() == gameSettings.keyBindInventory.keyCode) + { + displayGuiScreen(new GuiInventory(thePlayer)); + } + if(Keyboard.getEventKey() == gameSettings.keyBindDrop.keyCode) + { + thePlayer.dropCurrentItem(); + } + if(isMultiplayerWorld() && Keyboard.getEventKey() == gameSettings.keyBindChat.keyCode) + { + displayGuiScreen(new GuiChat()); + } + } + for(int i = 0; i < 9; i++) + { + if(Keyboard.getEventKey() == 2 + i) + { + thePlayer.inventory.currentItem = i; + } + } + + if(Keyboard.getEventKey() == gameSettings.keyBindToggleFog.keyCode) + { + gameSettings.setOptionValue(EnumOptions.RENDER_DISTANCE, !Keyboard.isKeyDown(42) && !Keyboard.isKeyDown(54) ? 1 : -1); + } + } + } + } while(true); + if(currentScreen == null) + { + if(Mouse.isButtonDown(0) && (float)(ticksRan - field_6302_aa) >= timer.ticksPerSecond / 4F && field_6289_L) + { + clickMouse(0); + field_6302_aa = ticksRan; + } + if(Mouse.isButtonDown(1) && (float)(ticksRan - field_6302_aa) >= timer.ticksPerSecond / 4F && field_6289_L) + { + clickMouse(1); + field_6302_aa = ticksRan; + } + } + func_6254_a(0, currentScreen == null && Mouse.isButtonDown(0) && field_6289_L); + } + if(theWorld != null) + { + if(thePlayer != null) + { + field_6300_ab++; + if(field_6300_ab == 30) + { + field_6300_ab = 0; + theWorld.joinEntityInSurroundings(thePlayer); + } + } + theWorld.difficultySetting = gameSettings.difficulty; + if(theWorld.multiplayerWorld) + { + theWorld.difficultySetting = 3; + } + if(!isWorldLoaded) + { + entityRenderer.updateRenderer(); + } + if(!isWorldLoaded) + { + renderGlobal.func_945_d(); + } + if(!isWorldLoaded) + { + theWorld.func_633_c(); + } + if(!isWorldLoaded || isMultiplayerWorld()) + { + theWorld.func_21114_a(gameSettings.difficulty > 0, true); + theWorld.tick(); + } + if(!isWorldLoaded && theWorld != null) + { + theWorld.randomDisplayUpdates(MathHelper.floor_double(thePlayer.posX), MathHelper.floor_double(thePlayer.posY), MathHelper.floor_double(thePlayer.posZ)); + } + if(!isWorldLoaded) + { + effectRenderer.updateEffects(); + } + } + systemTime = System.currentTimeMillis(); + } + + private void forceReload() + { + System.out.println("FORCING RELOAD!"); + sndManager = new SoundManager(); + sndManager.loadSoundSettings(gameSettings); + } + + public boolean isMultiplayerWorld() + { + return theWorld != null && theWorld.multiplayerWorld; + } + + public void startWorld(String s, String s1, long l) + { + changeWorld1(null); + System.gc(); + if(field_22008_V.func_22175_a(s)) + { + func_22002_b(s, s1); + } else + { + ISaveHandler isavehandler = field_22008_V.func_22174_a(s, false); + World world = new World(isavehandler, s1, l); + if(world.isNewWorld) + { + changeWorld2(world, "Generating level"); + } else + { + changeWorld2(world, "Loading level"); + } + } + } + + public void usePortal() + { + if(thePlayer.dimension == -1) + { + thePlayer.dimension = 0; + } else + { + thePlayer.dimension = -1; + } + theWorld.setEntityDead(thePlayer); + thePlayer.isDead = false; + double d = thePlayer.posX; + double d1 = thePlayer.posZ; + double d2 = 8D; + if(thePlayer.dimension == -1) + { + d /= d2; + d1 /= d2; + thePlayer.setLocationAndAngles(d, thePlayer.posY, d1, thePlayer.rotationYaw, thePlayer.rotationPitch); + theWorld.updateEntityWithOptionalForce(thePlayer, false); + World world = new World(theWorld, new WorldProviderHell()); + changeWorld(world, "Entering the Nether", thePlayer); + } else + { + d *= d2; + d1 *= d2; + thePlayer.setLocationAndAngles(d, thePlayer.posY, d1, thePlayer.rotationYaw, thePlayer.rotationPitch); + theWorld.updateEntityWithOptionalForce(thePlayer, false); + World world1 = new World(theWorld, new WorldProvider()); + changeWorld(world1, "Leaving the Nether", thePlayer); + } + thePlayer.worldObj = theWorld; + thePlayer.setLocationAndAngles(d, thePlayer.posY, d1, thePlayer.rotationYaw, thePlayer.rotationPitch); + theWorld.updateEntityWithOptionalForce(thePlayer, false); + (new Teleporter()).func_4107_a(theWorld, thePlayer); + } + + public void changeWorld1(World world) + { + changeWorld2(world, ""); + } + + public void changeWorld2(World world, String s) + { + changeWorld(world, s, null); + } + + public void changeWorld(World world, String s, EntityPlayer entityplayer) + { + field_22009_h = null; + loadingScreen.printText(s); + loadingScreen.displayLoadingString(""); + sndManager.func_331_a(null, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F); + if(theWorld != null) + { + theWorld.func_651_a(loadingScreen); + } + theWorld = world; + if(world != null) + { + playerController.func_717_a(world); + if(!isMultiplayerWorld()) + { + if(entityplayer == null) + { + thePlayer = (EntityPlayerSP)world.func_4085_a(EntityPlayerSP.class); + } + } else + if(thePlayer != null) + { + thePlayer.preparePlayerToSpawn(); + if(world != null) + { + world.entityJoinedWorld(thePlayer); + } + } + if(!world.multiplayerWorld) + { + func_6255_d(s); + } + if(thePlayer == null) + { + thePlayer = (EntityPlayerSP)playerController.func_4087_b(world); + thePlayer.preparePlayerToSpawn(); + playerController.flipPlayer(thePlayer); + } + thePlayer.movementInput = new MovementInputFromOptions(gameSettings); + if(renderGlobal != null) + { + renderGlobal.func_946_a(world); + } + if(effectRenderer != null) + { + effectRenderer.clearEffects(world); + } + playerController.func_6473_b(thePlayer); + if(entityplayer != null) + { + world.func_6464_c(); + } + IChunkProvider ichunkprovider = world.func_21118_q(); + if(ichunkprovider instanceof ChunkProviderLoadOrGenerate) + { + ChunkProviderLoadOrGenerate chunkproviderloadorgenerate = (ChunkProviderLoadOrGenerate)ichunkprovider; + int i = MathHelper.floor_float((int)thePlayer.posX) >> 4; + int j = MathHelper.floor_float((int)thePlayer.posZ) >> 4; + chunkproviderloadorgenerate.func_21110_c(i, j); + } + world.spawnPlayerWithLoadedChunks(thePlayer); + if(world.isNewWorld) + { + world.func_651_a(loadingScreen); + } + field_22009_h = thePlayer; + } else + { + thePlayer = null; + } + System.gc(); + systemTime = 0L; + } + + private void func_22002_b(String s, String s1) + { + loadingScreen.printText((new StringBuilder()).append("Converting World to ").append(field_22008_V.func_22178_a()).toString()); + loadingScreen.displayLoadingString("This may take a while :)"); + field_22008_V.func_22171_a(s, loadingScreen); + startWorld(s, s1, 0L); + } + + private void func_6255_d(String s) + { + loadingScreen.printText(s); + loadingScreen.displayLoadingString("Building terrain"); + char c = '\200'; + int i = 0; + int j = (c * 2) / 16 + 1; + j *= j; + IChunkProvider ichunkprovider = theWorld.func_21118_q(); + ChunkCoordinates chunkcoordinates = theWorld.func_22137_s(); + if(thePlayer != null) + { + chunkcoordinates.field_22395_a = (int)thePlayer.posX; + chunkcoordinates.field_22396_c = (int)thePlayer.posZ; + } + if(ichunkprovider instanceof ChunkProviderLoadOrGenerate) + { + ChunkProviderLoadOrGenerate chunkproviderloadorgenerate = (ChunkProviderLoadOrGenerate)ichunkprovider; + chunkproviderloadorgenerate.func_21110_c(chunkcoordinates.field_22395_a >> 4, chunkcoordinates.field_22396_c >> 4); + } + for(int k = -c; k <= c; k += 16) + { + for(int l = -c; l <= c; l += 16) + { + loadingScreen.setLoadingProgress((i++ * 100) / j); + theWorld.getBlockId(chunkcoordinates.field_22395_a + k, 64, chunkcoordinates.field_22396_c + l); + while(theWorld.func_6465_g()) ; + } + + } + + loadingScreen.displayLoadingString("Simulating world for a bit"); + j = 2000; + theWorld.func_656_j(); + } + + public void installResource(String s, File file) + { + int i = s.indexOf("/"); + String s1 = s.substring(0, i); + s = s.substring(i + 1); + if(s1.equalsIgnoreCase("sound")) + { + sndManager.addSound(s, file); + } else + if(s1.equalsIgnoreCase("newsound")) + { + sndManager.addSound(s, file); + } else + if(s1.equalsIgnoreCase("streaming")) + { + sndManager.addStreaming(s, file); + } else + if(s1.equalsIgnoreCase("music")) + { + sndManager.addMusic(s, file); + } else + if(s1.equalsIgnoreCase("newmusic")) + { + sndManager.addMusic(s, file); + } + } + + public OpenGlCapsChecker func_6251_l() + { + return glCapabilities; + } + + public String func_6241_m() + { + return renderGlobal.func_953_b(); + } + + public String func_6262_n() + { + return renderGlobal.func_957_c(); + } + + public String func_21002_o() + { + return theWorld.func_21119_g(); + } + + public String func_6245_o() + { + return (new StringBuilder()).append("P: ").append(effectRenderer.getStatistics()).append(". T: ").append(theWorld.func_687_d()).toString(); + } + + public void respawn() + { + if(!theWorld.worldProvider.canRespawnHere()) + { + usePortal(); + } + ChunkCoordinates chunkcoordinates = theWorld.func_22137_s(); + IChunkProvider ichunkprovider = theWorld.func_21118_q(); + if(ichunkprovider instanceof ChunkProviderLoadOrGenerate) + { + ChunkProviderLoadOrGenerate chunkproviderloadorgenerate = (ChunkProviderLoadOrGenerate)ichunkprovider; + chunkproviderloadorgenerate.func_21110_c(chunkcoordinates.field_22395_a >> 4, chunkcoordinates.field_22396_c >> 4); + } + theWorld.setSpawnLocation(); + theWorld.updateEntityList(); + int i = 0; + if(thePlayer != null) + { + i = thePlayer.entityId; + theWorld.setEntityDead(thePlayer); + } + field_22009_h = null; + thePlayer = (EntityPlayerSP)playerController.func_4087_b(theWorld); + field_22009_h = thePlayer; + thePlayer.preparePlayerToSpawn(); + playerController.flipPlayer(thePlayer); + theWorld.spawnPlayerWithLoadedChunks(thePlayer); + thePlayer.movementInput = new MovementInputFromOptions(gameSettings); + thePlayer.entityId = i; + thePlayer.func_6420_o(); + playerController.func_6473_b(thePlayer); + func_6255_d("Respawning"); + if(currentScreen instanceof GuiGameOver) + { + displayGuiScreen(null); + } + } + + public static void startMainThread(String s, String s1, String s2) + { + boolean flag = false; + String s3 = s; + Frame frame = new Frame("Minecraft"); + Canvas canvas = new Canvas(); + frame.setLayout(new BorderLayout()); + frame.add(canvas, "Center"); + canvas.setPreferredSize(new Dimension(854, 480)); + frame.pack(); + frame.setLocationRelativeTo(null); + Minecraft minecraftimpl = new Minecraft(canvas, 854, 480, flag); + Thread thread = new Thread(minecraftimpl, "Minecraft main thread"); + thread.setPriority(10); + minecraftimpl.minecraftUri = "www.minecraft.net"; + if(s3 != null && s1 != null) + { + minecraftimpl.session = new Session(s3, s1); + } else + { + minecraftimpl.session = new Session((new StringBuilder()).append("Player").append(System.currentTimeMillis() % 1000L).toString(), ""); + } + if(s2 != null) + { + String as[] = s2.split(":"); + minecraftimpl.setServer(as[0], Integer.parseInt(as[1])); + } + frame.setVisible(true); + frame.addWindowListener(new GameWindowListener(minecraftimpl, thread)); + thread.start(); + } + + public NetClientHandler func_20001_q() + { + if(thePlayer instanceof EntityClientPlayerMP) + { + return ((EntityClientPlayerMP)thePlayer).sendQueue; + } else + { + return null; + } + } + + public static boolean func_22006_t() + { + return field_21900_a == null || !field_21900_a.gameSettings.field_22277_y; + } + + public static boolean func_22001_u() + { + return field_21900_a != null && field_21900_a.gameSettings.fancyGraphics; + } + + public static boolean func_22005_v() + { + return field_21900_a != null && field_21900_a.gameSettings.field_22278_j; + } + + public static boolean func_22007_w() + { + return field_21900_a != null && field_21900_a.gameSettings.showDebugInfo; + } + + public boolean func_22003_b(String s) + { + if(!s.startsWith("/")); + return false; + } + + private static Minecraft field_21900_a; + public PlayerController playerController; + private boolean fullscreen; + public int displayWidth; + public int displayHeight; + private OpenGlCapsChecker glCapabilities; + private Timer timer; + public World theWorld; + public RenderGlobal renderGlobal; + public EntityPlayerSP thePlayer; + public EntityLiving field_22009_h; + public EffectRenderer effectRenderer; + public Session session; + public String minecraftUri; + public Canvas mcCanvas; + public boolean hideQuitButton; + public volatile boolean isWorldLoaded; + public RenderEngine renderEngine; + public FontRenderer fontRenderer; + public GuiScreen currentScreen; + public LoadingScreenRenderer loadingScreen; + public EntityRenderer entityRenderer; + private int ticksRan; + private int field_6282_S; + private int field_9236_T; + private int field_9235_U; + public GuiIngame ingameGUI; + public boolean field_6307_v; + public ModelBiped field_9242_w; + public MovingObjectPosition objectMouseOver; + public GameSettings gameSettings; + public SoundManager sndManager; + public MouseHelper mouseHelper; + public TexturePackList texturePackList; + private File mcDataDir; + private ISaveFormat field_22008_V; + public static long frameTimes[] = new long[512]; + public static long tickTimes[] = new long[512]; + public static int numRecordedFrameTimes = 0; + private String serverName; + private int serverPort; + private TextureWaterFX textureWaterFX; + private TextureLavaFX textureLavaFX; + private static File minecraftDir = null; + public volatile boolean running; + public String debug; + boolean isTakingScreenshot; + long prevFrameTime; + public boolean field_6289_L; + private int field_6302_aa; + public boolean isRaining; + long systemTime; + private int field_6300_ab; + + private static Minecraft instance = null; + + public static Minecraft getMinecraft() { + return instance; + } + +} diff --git a/src/main/java/net/minecraft/src/AxisAlignedBB.java b/src/main/java/net/minecraft/src/AxisAlignedBB.java new file mode 100644 index 0000000..f6aeef1 --- /dev/null +++ b/src/main/java/net/minecraft/src/AxisAlignedBB.java @@ -0,0 +1,388 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.ArrayList; +import java.util.List; + +public class AxisAlignedBB +{ + + public static AxisAlignedBB getBoundingBox(double d, double d1, double d2, double d3, + double d4, double d5) + { + return new AxisAlignedBB(d, d1, d2, d3, d4, d5); + } + + public static void clearBoundingBoxPool() + { + numBoundingBoxesInUse = 0; + } + + public static AxisAlignedBB getBoundingBoxFromPool(double d, double d1, double d2, double d3, + double d4, double d5) + { + if(numBoundingBoxesInUse >= boundingBoxes.size()) + { + boundingBoxes.add(getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D)); + } + return ((AxisAlignedBB)boundingBoxes.get(numBoundingBoxesInUse++)).setBounds(d, d1, d2, d3, d4, d5); + } + + private AxisAlignedBB(double d, double d1, double d2, double d3, double d4, double d5) + { + minX = d; + minY = d1; + minZ = d2; + maxX = d3; + maxY = d4; + maxZ = d5; + } + + public AxisAlignedBB setBounds(double d, double d1, double d2, double d3, double d4, double d5) + { + minX = d; + minY = d1; + minZ = d2; + maxX = d3; + maxY = d4; + maxZ = d5; + return this; + } + + public AxisAlignedBB addCoord(double d, double d1, double d2) + { + double d3 = minX; + double d4 = minY; + double d5 = minZ; + double d6 = maxX; + double d7 = maxY; + double d8 = maxZ; + if(d < 0.0D) + { + d3 += d; + } + if(d > 0.0D) + { + d6 += d; + } + if(d1 < 0.0D) + { + d4 += d1; + } + if(d1 > 0.0D) + { + d7 += d1; + } + if(d2 < 0.0D) + { + d5 += d2; + } + if(d2 > 0.0D) + { + d8 += d2; + } + return getBoundingBoxFromPool(d3, d4, d5, d6, d7, d8); + } + + public AxisAlignedBB expand(double d, double d1, double d2) + { + double d3 = minX - d; + double d4 = minY - d1; + double d5 = minZ - d2; + double d6 = maxX + d; + double d7 = maxY + d1; + double d8 = maxZ + d2; + return getBoundingBoxFromPool(d3, d4, d5, d6, d7, d8); + } + + public AxisAlignedBB getOffsetBoundingBox(double d, double d1, double d2) + { + return getBoundingBoxFromPool(minX + d, minY + d1, minZ + d2, maxX + d, maxY + d1, maxZ + d2); + } + + public double calculateXOffset(AxisAlignedBB axisalignedbb, double d) + { + if(axisalignedbb.maxY <= minY || axisalignedbb.minY >= maxY) + { + return d; + } + if(axisalignedbb.maxZ <= minZ || axisalignedbb.minZ >= maxZ) + { + return d; + } + if(d > 0.0D && axisalignedbb.maxX <= minX) + { + double d1 = minX - axisalignedbb.maxX; + if(d1 < d) + { + d = d1; + } + } + if(d < 0.0D && axisalignedbb.minX >= maxX) + { + double d2 = maxX - axisalignedbb.minX; + if(d2 > d) + { + d = d2; + } + } + return d; + } + + public double calculateYOffset(AxisAlignedBB axisalignedbb, double d) + { + if(axisalignedbb.maxX <= minX || axisalignedbb.minX >= maxX) + { + return d; + } + if(axisalignedbb.maxZ <= minZ || axisalignedbb.minZ >= maxZ) + { + return d; + } + if(d > 0.0D && axisalignedbb.maxY <= minY) + { + double d1 = minY - axisalignedbb.maxY; + if(d1 < d) + { + d = d1; + } + } + if(d < 0.0D && axisalignedbb.minY >= maxY) + { + double d2 = maxY - axisalignedbb.minY; + if(d2 > d) + { + d = d2; + } + } + return d; + } + + public double calculateZOffset(AxisAlignedBB axisalignedbb, double d) + { + if(axisalignedbb.maxX <= minX || axisalignedbb.minX >= maxX) + { + return d; + } + if(axisalignedbb.maxY <= minY || axisalignedbb.minY >= maxY) + { + return d; + } + if(d > 0.0D && axisalignedbb.maxZ <= minZ) + { + double d1 = minZ - axisalignedbb.maxZ; + if(d1 < d) + { + d = d1; + } + } + if(d < 0.0D && axisalignedbb.minZ >= maxZ) + { + double d2 = maxZ - axisalignedbb.minZ; + if(d2 > d) + { + d = d2; + } + } + return d; + } + + public boolean intersectsWith(AxisAlignedBB axisalignedbb) + { + if(axisalignedbb.maxX <= minX || axisalignedbb.minX >= maxX) + { + return false; + } + if(axisalignedbb.maxY <= minY || axisalignedbb.minY >= maxY) + { + return false; + } + return axisalignedbb.maxZ > minZ && axisalignedbb.minZ < maxZ; + } + + public AxisAlignedBB offset(double d, double d1, double d2) + { + minX += d; + minY += d1; + minZ += d2; + maxX += d; + maxY += d1; + maxZ += d2; + return this; + } + + public boolean isVecInside(Vec3D vec3d) + { + if(vec3d.xCoord <= minX || vec3d.xCoord >= maxX) + { + return false; + } + if(vec3d.yCoord <= minY || vec3d.yCoord >= maxY) + { + return false; + } + return vec3d.zCoord > minZ && vec3d.zCoord < maxZ; + } + + public double getAverageEdgeLength() + { + double d = maxX - minX; + double d1 = maxY - minY; + double d2 = maxZ - minZ; + return (d + d1 + d2) / 3D; + } + + public AxisAlignedBB copy() + { + return getBoundingBoxFromPool(minX, minY, minZ, maxX, maxY, maxZ); + } + + public MovingObjectPosition func_1169_a(Vec3D vec3d, Vec3D vec3d1) + { + Vec3D vec3d2 = vec3d.getIntermediateWithXValue(vec3d1, minX); + Vec3D vec3d3 = vec3d.getIntermediateWithXValue(vec3d1, maxX); + Vec3D vec3d4 = vec3d.getIntermediateWithYValue(vec3d1, minY); + Vec3D vec3d5 = vec3d.getIntermediateWithYValue(vec3d1, maxY); + Vec3D vec3d6 = vec3d.getIntermediateWithZValue(vec3d1, minZ); + Vec3D vec3d7 = vec3d.getIntermediateWithZValue(vec3d1, maxZ); + if(!isVecInYZ(vec3d2)) + { + vec3d2 = null; + } + if(!isVecInYZ(vec3d3)) + { + vec3d3 = null; + } + if(!isVecInXZ(vec3d4)) + { + vec3d4 = null; + } + if(!isVecInXZ(vec3d5)) + { + vec3d5 = null; + } + if(!isVecInXY(vec3d6)) + { + vec3d6 = null; + } + if(!isVecInXY(vec3d7)) + { + vec3d7 = null; + } + Vec3D vec3d8 = null; + if(vec3d2 != null && (vec3d8 == null || vec3d.squareDistanceTo(vec3d2) < vec3d.squareDistanceTo(vec3d8))) + { + vec3d8 = vec3d2; + } + if(vec3d3 != null && (vec3d8 == null || vec3d.squareDistanceTo(vec3d3) < vec3d.squareDistanceTo(vec3d8))) + { + vec3d8 = vec3d3; + } + if(vec3d4 != null && (vec3d8 == null || vec3d.squareDistanceTo(vec3d4) < vec3d.squareDistanceTo(vec3d8))) + { + vec3d8 = vec3d4; + } + if(vec3d5 != null && (vec3d8 == null || vec3d.squareDistanceTo(vec3d5) < vec3d.squareDistanceTo(vec3d8))) + { + vec3d8 = vec3d5; + } + if(vec3d6 != null && (vec3d8 == null || vec3d.squareDistanceTo(vec3d6) < vec3d.squareDistanceTo(vec3d8))) + { + vec3d8 = vec3d6; + } + if(vec3d7 != null && (vec3d8 == null || vec3d.squareDistanceTo(vec3d7) < vec3d.squareDistanceTo(vec3d8))) + { + vec3d8 = vec3d7; + } + if(vec3d8 == null) + { + return null; + } + byte byte0 = -1; + if(vec3d8 == vec3d2) + { + byte0 = 4; + } + if(vec3d8 == vec3d3) + { + byte0 = 5; + } + if(vec3d8 == vec3d4) + { + byte0 = 0; + } + if(vec3d8 == vec3d5) + { + byte0 = 1; + } + if(vec3d8 == vec3d6) + { + byte0 = 2; + } + if(vec3d8 == vec3d7) + { + byte0 = 3; + } + return new MovingObjectPosition(0, 0, 0, byte0, vec3d8); + } + + private boolean isVecInYZ(Vec3D vec3d) + { + if(vec3d == null) + { + return false; + } else + { + return vec3d.yCoord >= minY && vec3d.yCoord <= maxY && vec3d.zCoord >= minZ && vec3d.zCoord <= maxZ; + } + } + + private boolean isVecInXZ(Vec3D vec3d) + { + if(vec3d == null) + { + return false; + } else + { + return vec3d.xCoord >= minX && vec3d.xCoord <= maxX && vec3d.zCoord >= minZ && vec3d.zCoord <= maxZ; + } + } + + private boolean isVecInXY(Vec3D vec3d) + { + if(vec3d == null) + { + return false; + } else + { + return vec3d.xCoord >= minX && vec3d.xCoord <= maxX && vec3d.yCoord >= minY && vec3d.yCoord <= maxY; + } + } + + public void setBB(AxisAlignedBB axisalignedbb) + { + minX = axisalignedbb.minX; + minY = axisalignedbb.minY; + minZ = axisalignedbb.minZ; + maxX = axisalignedbb.maxX; + maxY = axisalignedbb.maxY; + maxZ = axisalignedbb.maxZ; + } + + public String toString() + { + return (new StringBuilder()).append("box[").append(minX).append(", ").append(minY).append(", ").append(minZ).append(" -> ").append(maxX).append(", ").append(maxY).append(", ").append(maxZ).append("]").toString(); + } + + private static List boundingBoxes = new ArrayList(); + private static int numBoundingBoxesInUse = 0; + public double minX; + public double minY; + public double minZ; + public double maxX; + public double maxY; + public double maxZ; + +} diff --git a/src/main/java/net/minecraft/src/Block.java b/src/main/java/net/minecraft/src/Block.java new file mode 100644 index 0000000..32429cc --- /dev/null +++ b/src/main/java/net/minecraft/src/Block.java @@ -0,0 +1,752 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.ArrayList; +import java.util.Random; + +public class Block +{ + + protected Block(int i, Material material) + { + stepSound = soundPowderFootstep; + blockParticleGravity = 1.0F; + slipperiness = 0.6F; + if(blocksList[i] != null) + { + throw new IllegalArgumentException((new StringBuilder()).append("Slot ").append(i).append(" is already occupied by ").append(blocksList[i]).append(" when adding ").append(this).toString()); + } else + { + blockMaterial = material; + blocksList[i] = this; + blockID = i; + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + opaqueCubeLookup[i] = isOpaqueCube(); + lightOpacity[i] = isOpaqueCube() ? 255 : 0; + field_340_s[i] = !material.getCanBlockGrass(); + isBlockContainer[i] = false; + return; + } + } + + protected Block(int i, int j, Material material) + { + this(i, material); + blockIndexInTexture = j; + } + + protected Block setStepSound(StepSound stepsound) + { + stepSound = stepsound; + return this; + } + + protected Block setLightOpacity(int i) + { + lightOpacity[blockID] = i; + return this; + } + + protected Block setLightValue(float f) + { + lightValue[blockID] = (int)(15F * f); + return this; + } + + protected Block setResistance(float f) + { + blockResistance = f * 3F; + return this; + } + + public boolean renderAsNormalBlock() + { + return true; + } + + public int getRenderType() + { + return 0; + } + + protected Block setHardness(float f) + { + blockHardness = f; + if(blockResistance < f * 5F) + { + blockResistance = f * 5F; + } + return this; + } + + protected void setTickOnLoad(boolean flag) + { + tickOnLoad[blockID] = flag; + } + + public void setBlockBounds(float f, float f1, float f2, float f3, float f4, float f5) + { + minX = f; + minY = f1; + minZ = f2; + maxX = f3; + maxY = f4; + maxZ = f5; + } + + public float getBlockBrightness(IBlockAccess iblockaccess, int i, int j, int k) + { + return iblockaccess.getLightBrightness(i, j, k); + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(l == 0 && minY > 0.0D) + { + return true; + } + if(l == 1 && maxY < 1.0D) + { + return true; + } + if(l == 2 && minZ > 0.0D) + { + return true; + } + if(l == 3 && maxZ < 1.0D) + { + return true; + } + if(l == 4 && minX > 0.0D) + { + return true; + } + if(l == 5 && maxX < 1.0D) + { + return true; + } else + { + return !iblockaccess.isBlockOpaqueCube(i, j, k); + } + } + + public int getBlockTexture(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return getBlockTextureFromSideAndMetadata(l, iblockaccess.getBlockMetadata(i, j, k)); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + return getBlockTextureFromSide(i); + } + + public int getBlockTextureFromSide(int i) + { + return blockIndexInTexture; + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + return AxisAlignedBB.getBoundingBoxFromPool((double)i + minX, (double)j + minY, (double)k + minZ, (double)i + maxX, (double)j + maxY, (double)k + maxZ); + } + + public void getCollidingBoundingBoxes(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, ArrayList arraylist) + { + AxisAlignedBB axisalignedbb1 = getCollisionBoundingBoxFromPool(world, i, j, k); + if(axisalignedbb1 != null && axisalignedbb.intersectsWith(axisalignedbb1)) + { + arraylist.add(axisalignedbb1); + } + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return AxisAlignedBB.getBoundingBoxFromPool((double)i + minX, (double)j + minY, (double)k + minZ, (double)i + maxX, (double)j + maxY, (double)k + maxZ); + } + + public boolean isOpaqueCube() + { + return true; + } + + public boolean canCollideCheck(int i, boolean flag) + { + return isCollidable(); + } + + public boolean isCollidable() + { + return true; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + } + + public void onBlockDestroyedByPlayer(World world, int i, int j, int k, int l) + { + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + } + + public int tickRate() + { + return 10; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + } + + public int quantityDropped(Random random) + { + return 1; + } + + public int idDropped(int i, Random random) + { + return blockID; + } + + public float blockStrength(EntityPlayer entityplayer) + { + if(blockHardness < 0.0F) + { + return 0.0F; + } + if(!entityplayer.canHarvestBlock(this)) + { + return 1.0F / blockHardness / 100F; + } else + { + return entityplayer.getCurrentPlayerStrVsBlock(this) / blockHardness / 30F; + } + } + + public void dropBlockAsItem(World world, int i, int j, int k, int l) + { + dropBlockAsItemWithChance(world, i, j, k, l, 1.0F); + } + + public void dropBlockAsItemWithChance(World world, int i, int j, int k, int l, float f) + { + if(world.multiplayerWorld) + { + return; + } + int i1 = quantityDropped(world.rand); + for(int j1 = 0; j1 < i1; j1++) + { + if(world.rand.nextFloat() > f) + { + continue; + } + int k1 = idDropped(l, world.rand); + if(k1 > 0) + { + float f1 = 0.7F; + double d = (double)(world.rand.nextFloat() * f1) + (double)(1.0F - f1) * 0.5D; + double d1 = (double)(world.rand.nextFloat() * f1) + (double)(1.0F - f1) * 0.5D; + double d2 = (double)(world.rand.nextFloat() * f1) + (double)(1.0F - f1) * 0.5D; + EntityItem entityitem = new EntityItem(world, (double)i + d, (double)j + d1, (double)k + d2, new ItemStack(k1, 1, damageDropped(l))); + entityitem.delayBeforeCanPickup = 10; + world.entityJoinedWorld(entityitem); + } + } + + } + + protected int damageDropped(int i) + { + return 0; + } + + public float getExplosionResistance(Entity entity) + { + return blockResistance / 5F; + } + + public MovingObjectPosition collisionRayTrace(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) + { + setBlockBoundsBasedOnState(world, i, j, k); + vec3d = vec3d.addVector(-i, -j, -k); + vec3d1 = vec3d1.addVector(-i, -j, -k); + Vec3D vec3d2 = vec3d.getIntermediateWithXValue(vec3d1, minX); + Vec3D vec3d3 = vec3d.getIntermediateWithXValue(vec3d1, maxX); + Vec3D vec3d4 = vec3d.getIntermediateWithYValue(vec3d1, minY); + Vec3D vec3d5 = vec3d.getIntermediateWithYValue(vec3d1, maxY); + Vec3D vec3d6 = vec3d.getIntermediateWithZValue(vec3d1, minZ); + Vec3D vec3d7 = vec3d.getIntermediateWithZValue(vec3d1, maxZ); + if(!isVecInsideYZBounds(vec3d2)) + { + vec3d2 = null; + } + if(!isVecInsideYZBounds(vec3d3)) + { + vec3d3 = null; + } + if(!isVecInsideXZBounds(vec3d4)) + { + vec3d4 = null; + } + if(!isVecInsideXZBounds(vec3d5)) + { + vec3d5 = null; + } + if(!isVecInsideXYBounds(vec3d6)) + { + vec3d6 = null; + } + if(!isVecInsideXYBounds(vec3d7)) + { + vec3d7 = null; + } + Vec3D vec3d8 = null; + if(vec3d2 != null && (vec3d8 == null || vec3d.distanceTo(vec3d2) < vec3d.distanceTo(vec3d8))) + { + vec3d8 = vec3d2; + } + if(vec3d3 != null && (vec3d8 == null || vec3d.distanceTo(vec3d3) < vec3d.distanceTo(vec3d8))) + { + vec3d8 = vec3d3; + } + if(vec3d4 != null && (vec3d8 == null || vec3d.distanceTo(vec3d4) < vec3d.distanceTo(vec3d8))) + { + vec3d8 = vec3d4; + } + if(vec3d5 != null && (vec3d8 == null || vec3d.distanceTo(vec3d5) < vec3d.distanceTo(vec3d8))) + { + vec3d8 = vec3d5; + } + if(vec3d6 != null && (vec3d8 == null || vec3d.distanceTo(vec3d6) < vec3d.distanceTo(vec3d8))) + { + vec3d8 = vec3d6; + } + if(vec3d7 != null && (vec3d8 == null || vec3d.distanceTo(vec3d7) < vec3d.distanceTo(vec3d8))) + { + vec3d8 = vec3d7; + } + if(vec3d8 == null) + { + return null; + } + byte byte0 = -1; + if(vec3d8 == vec3d2) + { + byte0 = 4; + } + if(vec3d8 == vec3d3) + { + byte0 = 5; + } + if(vec3d8 == vec3d4) + { + byte0 = 0; + } + if(vec3d8 == vec3d5) + { + byte0 = 1; + } + if(vec3d8 == vec3d6) + { + byte0 = 2; + } + if(vec3d8 == vec3d7) + { + byte0 = 3; + } + return new MovingObjectPosition(i, j, k, byte0, vec3d8.addVector(i, j, k)); + } + + private boolean isVecInsideYZBounds(Vec3D vec3d) + { + if(vec3d == null) + { + return false; + } else + { + return vec3d.yCoord >= minY && vec3d.yCoord <= maxY && vec3d.zCoord >= minZ && vec3d.zCoord <= maxZ; + } + } + + private boolean isVecInsideXZBounds(Vec3D vec3d) + { + if(vec3d == null) + { + return false; + } else + { + return vec3d.xCoord >= minX && vec3d.xCoord <= maxX && vec3d.zCoord >= minZ && vec3d.zCoord <= maxZ; + } + } + + private boolean isVecInsideXYBounds(Vec3D vec3d) + { + if(vec3d == null) + { + return false; + } else + { + return vec3d.xCoord >= minX && vec3d.xCoord <= maxX && vec3d.yCoord >= minY && vec3d.yCoord <= maxY; + } + } + + public void onBlockDestroyedByExplosion(World world, int i, int j, int k) + { + } + + public int getRenderBlockPass() + { + return 0; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j, k); + return l == 0 || blocksList[l].blockMaterial.getIsLiquid(); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + return false; + } + + public void onEntityWalking(World world, int i, int j, int k, Entity entity) + { + } + + public void onBlockPlaced(World world, int i, int j, int k, int l) + { + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + } + + public void velocityToAddToEntity(World world, int i, int j, int k, Entity entity, Vec3D vec3d) + { + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + } + + public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k) + { + return 0xffffff; + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return false; + } + + public boolean canProvidePower() + { + return false; + } + + public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) + { + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + return false; + } + + public void func_237_e() + { + } + + public void harvestBlock(World world, int i, int j, int k, int l) + { + dropBlockAsItem(world, i, j, k, l); + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + return true; + } + + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) + { + } + + public Block setBlockName(String s) + { + blockName = (new StringBuilder()).append("tile.").append(s).toString(); + return this; + } + + public String getBlockName() + { + return blockName; + } + + public void playBlock(World world, int i, int j, int k, int l, int i1) + { + } + + static Class _mthclass$(String s) + { + try + { + return Class.forName(s); + } + catch(ClassNotFoundException classnotfoundexception) + { + throw new NoClassDefFoundError(classnotfoundexception.getMessage()); + } + } + + public static final StepSound soundPowderFootstep; + public static final StepSound soundWoodFootstep; + public static final StepSound soundGravelFootstep; + public static final StepSound soundGrassFootstep; + public static final StepSound soundStoneFootstep; + public static final StepSound soundMetalFootstep; + public static final StepSound soundGlassFootstep; + public static final StepSound soundClothFootstep; + public static final StepSound soundSandFootstep; + public static final Block blocksList[]; + public static final boolean tickOnLoad[] = new boolean[256]; + public static final boolean opaqueCubeLookup[] = new boolean[256]; + public static final boolean isBlockContainer[] = new boolean[256]; + public static final int lightOpacity[] = new int[256]; + public static final boolean field_340_s[]; + public static final int lightValue[] = new int[256]; + public static final Block stone; + public static final BlockGrass grass; + public static final Block dirt; + public static final Block cobblestone; + public static final Block planks; + public static final Block sapling; + public static final Block bedrock; + public static final Block waterStill; + public static final Block waterMoving; + public static final Block lavaStill; + public static final Block lavaMoving; + public static final Block sand; + public static final Block gravel; + public static final Block oreGold; + public static final Block oreIron; + public static final Block oreCoal; + public static final Block wood; + public static final BlockLeaves leaves; + public static final Block sponge; + public static final Block glass; + public static final Block oreLapis; + public static final Block blockLapis; + public static final Block dispenser; + public static final Block sandStone; + public static final Block musicBlock; + public static final Block field_9262_S; + public static final Block field_9261_T = null; + public static final Block field_9260_U = null; + public static final Block field_9259_V = null; + public static final Block field_9258_W = null; + public static final Block field_9257_X = null; + public static final Block field_9256_Y = null; + public static final Block field_9255_Z = null; + public static final Block field_9269_aa = null; + public static final Block cloth; + public static final Block field_9268_ac = null; + public static final BlockFlower plantYellow; + public static final BlockFlower plantRed; + public static final BlockFlower mushroomBrown; + public static final BlockFlower mushroomRed; + public static final Block blockGold; + public static final Block blockSteel; + public static final Block stairDouble; + public static final Block stairSingle; + public static final Block brick; + public static final Block tnt; + public static final Block bookShelf; + public static final Block cobblestoneMossy; + public static final Block obsidian; + public static final Block torchWood; + public static final BlockFire fire; + public static final Block mobSpawner; + public static final Block stairCompactPlanks; + public static final Block crate; + public static final Block redstoneWire; + public static final Block oreDiamond; + public static final Block blockDiamond; + public static final Block workbench; + public static final Block crops; + public static final Block tilledField; + public static final Block stoneOvenIdle; + public static final Block stoneOvenActive; + public static final Block signPost; + public static final Block doorWood; + public static final Block ladder; + public static final Block minecartTrack; + public static final Block stairCompactCobblestone; + public static final Block signWall; + public static final Block lever; + public static final Block pressurePlateStone; + public static final Block doorSteel; + public static final Block pressurePlatePlanks; + public static final Block oreRedstone; + public static final Block oreRedstoneGlowing; + public static final Block torchRedstoneIdle; + public static final Block torchRedstoneActive; + public static final Block button; + public static final Block snow; + public static final Block ice; + public static final Block blockSnow; + public static final Block cactus; + public static final Block blockClay; + public static final Block reed; + public static final Block jukebox; + public static final Block fence; + public static final Block pumpkin; + public static final Block bloodStone; + public static final Block slowSand; + public static final Block lightStone; + public static final BlockPortal portal; + public static final Block pumpkinLantern; + public static final Block cake; + public static final Block field_22021_bh; + public static final Block field_22020_bi; + public int blockIndexInTexture; + public final int blockID; + protected float blockHardness; + protected float blockResistance; + public double minX; + public double minY; + public double minZ; + public double maxX; + public double maxY; + public double maxZ; + public StepSound stepSound; + public float blockParticleGravity; + public final Material blockMaterial; + public float slipperiness; + private String blockName; + + static + { + soundPowderFootstep = new StepSound("stone", 1.0F, 1.0F); + soundWoodFootstep = new StepSound("wood", 1.0F, 1.0F); + soundGravelFootstep = new StepSound("gravel", 1.0F, 1.0F); + soundGrassFootstep = new StepSound("grass", 1.0F, 1.0F); + soundStoneFootstep = new StepSound("stone", 1.0F, 1.0F); + soundMetalFootstep = new StepSound("stone", 1.0F, 1.5F); + soundGlassFootstep = new StepSoundStone("stone", 1.0F, 1.0F); + soundClothFootstep = new StepSound("cloth", 1.0F, 1.0F); + soundSandFootstep = new StepSoundSand("sand", 1.0F, 1.0F); + blocksList = new Block[256]; + field_340_s = new boolean[256]; + stone = (new BlockStone(1, 1)).setHardness(1.5F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("stone"); + grass = (BlockGrass)(new BlockGrass(2)).setHardness(0.6F).setStepSound(soundGrassFootstep).setBlockName("grass"); + dirt = (new BlockDirt(3, 2)).setHardness(0.5F).setStepSound(soundGravelFootstep).setBlockName("dirt"); + cobblestone = (new Block(4, 16, Material.rock)).setHardness(2.0F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("stonebrick"); + planks = (new Block(5, 4, Material.wood)).setHardness(2.0F).setResistance(5F).setStepSound(soundWoodFootstep).setBlockName("wood"); + sapling = (new BlockSapling(6, 15)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("sapling"); + bedrock = (new Block(7, 17, Material.rock)).setHardness(-1F).setResistance(6000000F).setStepSound(soundStoneFootstep).setBlockName("bedrock"); + waterStill = (new BlockFlowing(8, Material.water)).setHardness(100F).setLightOpacity(3).setBlockName("water"); + waterMoving = (new BlockStationary(9, Material.water)).setHardness(100F).setLightOpacity(3).setBlockName("water"); + lavaStill = (new BlockFlowing(10, Material.lava)).setHardness(0.0F).setLightValue(1.0F).setLightOpacity(255).setBlockName("lava"); + lavaMoving = (new BlockStationary(11, Material.lava)).setHardness(100F).setLightValue(1.0F).setLightOpacity(255).setBlockName("lava"); + sand = (new BlockSand(12, 18)).setHardness(0.5F).setStepSound(soundSandFootstep).setBlockName("sand"); + gravel = (new BlockGravel(13, 19)).setHardness(0.6F).setStepSound(soundGravelFootstep).setBlockName("gravel"); + oreGold = (new BlockOre(14, 32)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreGold"); + oreIron = (new BlockOre(15, 33)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreIron"); + oreCoal = (new BlockOre(16, 34)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreCoal"); + wood = (new BlockLog(17)).setHardness(2.0F).setStepSound(soundWoodFootstep).setBlockName("log"); + leaves = (BlockLeaves)(new BlockLeaves(18, 52)).setHardness(0.2F).setLightOpacity(1).setStepSound(soundGrassFootstep).setBlockName("leaves"); + sponge = (new BlockSponge(19)).setHardness(0.6F).setStepSound(soundGrassFootstep).setBlockName("sponge"); + glass = (new BlockGlass(20, 49, Material.glass, false)).setHardness(0.3F).setStepSound(soundGlassFootstep).setBlockName("glass"); + oreLapis = (new BlockOre(21, 160)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreLapis"); + blockLapis = (new Block(22, 144, Material.rock)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("blockLapis"); + dispenser = (new BlockDispenser(23)).setHardness(3.5F).setStepSound(soundStoneFootstep).setBlockName("dispenser"); + sandStone = (new BlockSandStone(24)).setStepSound(soundStoneFootstep).setHardness(0.8F).setBlockName("sandStone"); + musicBlock = (new BlockNote(25)).setHardness(0.8F).setBlockName("musicBlock"); + field_9262_S = (new BlockBed(26)).setHardness(0.2F).setBlockName("bed"); + cloth = (new BlockCloth()).setHardness(0.8F).setStepSound(soundClothFootstep).setBlockName("cloth"); + plantYellow = (BlockFlower)(new BlockFlower(37, 13)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("flower"); + plantRed = (BlockFlower)(new BlockFlower(38, 12)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("rose"); + mushroomBrown = (BlockFlower)(new BlockMushroom(39, 29)).setHardness(0.0F).setStepSound(soundGrassFootstep).setLightValue(0.125F).setBlockName("mushroom"); + mushroomRed = (BlockFlower)(new BlockMushroom(40, 28)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("mushroom"); + blockGold = (new BlockOreBlock(41, 23)).setHardness(3F).setResistance(10F).setStepSound(soundMetalFootstep).setBlockName("blockGold"); + blockSteel = (new BlockOreBlock(42, 22)).setHardness(5F).setResistance(10F).setStepSound(soundMetalFootstep).setBlockName("blockIron"); + stairDouble = (new BlockStep(43, true)).setHardness(2.0F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("stoneSlab"); + stairSingle = (new BlockStep(44, false)).setHardness(2.0F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("stoneSlab"); + brick = (new Block(45, 7, Material.rock)).setHardness(2.0F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("brick"); + tnt = (new BlockTNT(46, 8)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("tnt"); + bookShelf = (new BlockBookshelf(47, 35)).setHardness(1.5F).setStepSound(soundWoodFootstep).setBlockName("bookshelf"); + cobblestoneMossy = (new Block(48, 36, Material.rock)).setHardness(2.0F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("stoneMoss"); + obsidian = (new BlockObsidian(49, 37)).setHardness(10F).setResistance(2000F).setStepSound(soundStoneFootstep).setBlockName("obsidian"); + torchWood = (new BlockTorch(50, 80)).setHardness(0.0F).setLightValue(0.9375F).setStepSound(soundWoodFootstep).setBlockName("torch"); + fire = (BlockFire)(new BlockFire(51, 31)).setHardness(0.0F).setLightValue(1.0F).setStepSound(soundWoodFootstep).setBlockName("fire"); + mobSpawner = (new BlockMobSpawner(52, 65)).setHardness(5F).setStepSound(soundMetalFootstep).setBlockName("mobSpawner"); + stairCompactPlanks = (new BlockStairs(53, planks)).setBlockName("stairsWood"); + crate = (new BlockChest(54)).setHardness(2.5F).setStepSound(soundWoodFootstep).setBlockName("chest"); + redstoneWire = (new BlockRedstoneWire(55, 164)).setHardness(0.0F).setStepSound(soundPowderFootstep).setBlockName("redstoneDust"); + oreDiamond = (new BlockOre(56, 50)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreDiamond"); + blockDiamond = (new BlockOreBlock(57, 24)).setHardness(5F).setResistance(10F).setStepSound(soundMetalFootstep).setBlockName("blockDiamond"); + workbench = (new BlockWorkbench(58)).setHardness(2.5F).setStepSound(soundWoodFootstep).setBlockName("workbench"); + crops = (new BlockCrops(59, 88)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("crops"); + tilledField = (new BlockSoil(60)).setHardness(0.6F).setStepSound(soundGravelFootstep).setBlockName("farmland"); + stoneOvenIdle = (new BlockFurnace(61, false)).setHardness(3.5F).setStepSound(soundStoneFootstep).setBlockName("furnace"); + stoneOvenActive = (new BlockFurnace(62, true)).setHardness(3.5F).setStepSound(soundStoneFootstep).setLightValue(0.875F).setBlockName("furnace"); + signPost = (new BlockSign(63, TileEntitySign.class, true)).setHardness(1.0F).setStepSound(soundWoodFootstep).setBlockName("sign"); + doorWood = (new BlockDoor(64, Material.wood)).setHardness(3F).setStepSound(soundWoodFootstep).setBlockName("doorWood"); + ladder = (new BlockLadder(65, 83)).setHardness(0.4F).setStepSound(soundWoodFootstep).setBlockName("ladder"); + minecartTrack = (new BlockMinecartTrack(66, 128)).setHardness(0.7F).setStepSound(soundMetalFootstep).setBlockName("rail"); + stairCompactCobblestone = (new BlockStairs(67, cobblestone)).setBlockName("stairsStone"); + signWall = (new BlockSign(68, TileEntitySign.class, false)).setHardness(1.0F).setStepSound(soundWoodFootstep).setBlockName("sign"); + lever = (new BlockLever(69, 96)).setHardness(0.5F).setStepSound(soundWoodFootstep).setBlockName("lever"); + pressurePlateStone = (new BlockPressurePlate(70, stone.blockIndexInTexture, EnumMobType.mobs)).setHardness(0.5F).setStepSound(soundStoneFootstep).setBlockName("pressurePlate"); + doorSteel = (new BlockDoor(71, Material.iron)).setHardness(5F).setStepSound(soundMetalFootstep).setBlockName("doorIron"); + pressurePlatePlanks = (new BlockPressurePlate(72, planks.blockIndexInTexture, EnumMobType.everything)).setHardness(0.5F).setStepSound(soundWoodFootstep).setBlockName("pressurePlate"); + oreRedstone = (new BlockRedstoneOre(73, 51, false)).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreRedstone"); + oreRedstoneGlowing = (new BlockRedstoneOre(74, 51, true)).setLightValue(0.625F).setHardness(3F).setResistance(5F).setStepSound(soundStoneFootstep).setBlockName("oreRedstone"); + torchRedstoneIdle = (new BlockRedstoneTorch(75, 115, false)).setHardness(0.0F).setStepSound(soundWoodFootstep).setBlockName("notGate"); + torchRedstoneActive = (new BlockRedstoneTorch(76, 99, true)).setHardness(0.0F).setLightValue(0.5F).setStepSound(soundWoodFootstep).setBlockName("notGate"); + button = (new BlockButton(77, stone.blockIndexInTexture)).setHardness(0.5F).setStepSound(soundStoneFootstep).setBlockName("button"); + snow = (new BlockSnow(78, 66)).setHardness(0.1F).setStepSound(soundClothFootstep).setBlockName("snow"); + ice = (new BlockIce(79, 67)).setHardness(0.5F).setLightOpacity(3).setStepSound(soundGlassFootstep).setBlockName("ice"); + blockSnow = (new BlockSnowBlock(80, 66)).setHardness(0.2F).setStepSound(soundClothFootstep).setBlockName("snow"); + cactus = (new BlockCactus(81, 70)).setHardness(0.4F).setStepSound(soundClothFootstep).setBlockName("cactus"); + blockClay = (new BlockClay(82, 72)).setHardness(0.6F).setStepSound(soundGravelFootstep).setBlockName("clay"); + reed = (new BlockReed(83, 73)).setHardness(0.0F).setStepSound(soundGrassFootstep).setBlockName("reeds"); + jukebox = (new BlockJukeBox(84, 74)).setHardness(2.0F).setResistance(10F).setStepSound(soundStoneFootstep).setBlockName("jukebox"); + fence = (new BlockFence(85, 4)).setHardness(2.0F).setResistance(5F).setStepSound(soundWoodFootstep).setBlockName("fence"); + pumpkin = (new BlockPumpkin(86, 102, false)).setHardness(1.0F).setStepSound(soundWoodFootstep).setBlockName("pumpkin"); + bloodStone = (new BlockBloodStone(87, 103)).setHardness(0.4F).setStepSound(soundStoneFootstep).setBlockName("hellrock"); + slowSand = (new BlockSlowSand(88, 104)).setHardness(0.5F).setStepSound(soundSandFootstep).setBlockName("hellsand"); + lightStone = (new BlockLightStone(89, 105, Material.glass)).setHardness(0.3F).setStepSound(soundGlassFootstep).setLightValue(1.0F).setBlockName("lightgem"); + portal = (BlockPortal)(new BlockPortal(90, 14)).setHardness(-1F).setStepSound(soundGlassFootstep).setLightValue(0.75F).setBlockName("portal"); + pumpkinLantern = (new BlockPumpkin(91, 102, true)).setHardness(1.0F).setStepSound(soundWoodFootstep).setLightValue(1.0F).setBlockName("litpumpkin"); + cake = (new BlockCake(92, 121)).setHardness(0.5F).setStepSound(soundClothFootstep).setBlockName("cake"); + field_22021_bh = (new BlockRedstoneRepeater(93, false)).setHardness(0.0F).setStepSound(soundWoodFootstep).setBlockName("diode"); + field_22020_bi = (new BlockRedstoneRepeater(94, true)).setHardness(0.0F).setLightValue(0.625F).setStepSound(soundWoodFootstep).setBlockName("diode"); + Item.itemsList[cloth.blockID] = (new ItemCloth(cloth.blockID - 256)).setItemName("cloth"); + Item.itemsList[wood.blockID] = (new ItemLog(wood.blockID - 256)).setItemName("log"); + Item.itemsList[stairSingle.blockID] = (new ItemSlab(stairSingle.blockID - 256)).setItemName("stoneSlab"); + for(int i = 0; i < 256; i++) + { + if(blocksList[i] != null && Item.itemsList[i] == null) + { + Item.itemsList[i] = new ItemBlock(i - 256); + } + } + + field_340_s[0] = true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockBed.java b/src/main/java/net/minecraft/src/BlockBed.java new file mode 100644 index 0000000..d4d4abb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBed.java @@ -0,0 +1,213 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockBed extends Block +{ + + public BlockBed(int i) + { + super(i, 134, Material.cloth); + func_22027_j(); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + int l = world.getBlockMetadata(i, j, k); + if(!func_22032_d(l)) + { + int i1 = func_22030_c(l); + i += field_22033_a[i1][0]; + k += field_22033_a[i1][1]; + if(world.getBlockId(i, j, k) != blockID) + { + return true; + } + l = world.getBlockMetadata(i, j, k); + } + if(func_22029_f(l)) + { + entityplayer.func_22055_b("tile.bed.occupied"); + return true; + } + if(entityplayer.func_22053_b(i, j, k)) + { + func_22031_a(world, i, j, k, true); + return true; + } else + { + entityplayer.func_22055_b("tile.bed.noSleep"); + return true; + } + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 0) + { + return Block.planks.blockIndexInTexture; + } + int k = func_22030_c(j); + int l = ModelBed.field_22281_c[k][i]; + if(func_22032_d(j)) + { + if(l == 2) + { + return blockIndexInTexture + 2 + 16; + } + if(l == 5 || l == 4) + { + return blockIndexInTexture + 1 + 16; + } else + { + return blockIndexInTexture + 1; + } + } + if(l == 3) + { + return (blockIndexInTexture - 1) + 16; + } + if(l == 5 || l == 4) + { + return blockIndexInTexture + 16; + } else + { + return blockIndexInTexture; + } + } + + public int getRenderType() + { + return 14; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean isOpaqueCube() + { + return false; + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + func_22027_j(); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + int j1 = func_22030_c(i1); + if(func_22032_d(i1)) + { + if(world.getBlockId(i - field_22033_a[j1][0], j, k - field_22033_a[j1][1]) != blockID) + { + world.setBlockWithNotify(i, j, k, 0); + } + } else + if(world.getBlockId(i + field_22033_a[j1][0], j, k + field_22033_a[j1][1]) != blockID) + { + world.setBlockWithNotify(i, j, k, 0); + if(!world.multiplayerWorld) + { + dropBlockAsItem(world, i, j, k, i1); + } + } + } + + public int idDropped(int i, Random random) + { + if(func_22032_d(i)) + { + return 0; + } else + { + return Item.field_22019_aY.shiftedIndex; + } + } + + private void func_22027_j() + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5625F, 1.0F); + } + + public static int func_22030_c(int i) + { + return i & 3; + } + + public static boolean func_22032_d(int i) + { + return (i & 8) != 0; + } + + public static boolean func_22029_f(int i) + { + return (i & 4) != 0; + } + + public static void func_22031_a(World world, int i, int j, int k, boolean flag) + { + int l = world.getBlockMetadata(i, j, k); + if(flag) + { + l |= 4; + } else + { + l &= -5; + } + world.setBlockMetadataWithNotify(i, j, k, l); + } + + public static ChunkCoordinates func_22028_g(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + int j1 = func_22030_c(i1); + for(int k1 = 0; k1 <= 1; k1++) + { + int l1 = i - field_22033_a[j1][0] * k1 - 1; + int i2 = k - field_22033_a[j1][1] * k1 - 1; + int j2 = l1 + 2; + int k2 = i2 + 2; + for(int l2 = l1; l2 <= j2; l2++) + { + for(int i3 = i2; i3 <= k2; i3++) + { + if(!world.isBlockOpaqueCube(l2, j - 1, i3) || !world.isAirBlock(l2, j, i3) || !world.isAirBlock(l2, j + 1, i3)) + { + continue; + } + if(l > 0) + { + l--; + } else + { + return new ChunkCoordinates(l2, j, i3); + } + } + + } + + } + + return new ChunkCoordinates(i, j + 1, k); + } + + public static final int field_22033_a[][] = { + { + 0, 1 + }, { + -1, 0 + }, { + 0, -1 + }, { + 1, 0 + } + }; + +} diff --git a/src/main/java/net/minecraft/src/BlockBloodStone.java b/src/main/java/net/minecraft/src/BlockBloodStone.java new file mode 100644 index 0000000..a1cd9b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBloodStone.java @@ -0,0 +1,14 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockBloodStone extends Block +{ + + public BlockBloodStone(int i, int j) + { + super(i, j, Material.rock); + } +} diff --git a/src/main/java/net/minecraft/src/BlockBookshelf.java b/src/main/java/net/minecraft/src/BlockBookshelf.java new file mode 100644 index 0000000..285b55a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBookshelf.java @@ -0,0 +1,31 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockBookshelf extends Block +{ + + public BlockBookshelf(int i, int j) + { + super(i, j, Material.wood); + } + + public int getBlockTextureFromSide(int i) + { + if(i <= 1) + { + return 4; + } else + { + return blockIndexInTexture; + } + } + + public int quantityDropped(Random random) + { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockBreakable.java b/src/main/java/net/minecraft/src/BlockBreakable.java new file mode 100644 index 0000000..cd1ca02 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockBreakable.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockBreakable extends Block +{ + + protected BlockBreakable(int i, int j, Material material, boolean flag) + { + super(i, j, material); + field_6363_a = flag; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + int i1 = iblockaccess.getBlockId(i, j, k); + if(!field_6363_a && i1 == blockID) + { + return false; + } else + { + return super.shouldSideBeRendered(iblockaccess, i, j, k, l); + } + } + + private boolean field_6363_a; +} diff --git a/src/main/java/net/minecraft/src/BlockButton.java b/src/main/java/net/minecraft/src/BlockButton.java new file mode 100644 index 0000000..17cd786 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockButton.java @@ -0,0 +1,324 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockButton extends Block +{ + + protected BlockButton(int i, int j) + { + super(i, j, Material.circuits); + setTickOnLoad(true); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public int tickRate() + { + return 20; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + return true; + } + return world.isBlockOpaqueCube(i, j, k + 1); + } + + public void onBlockPlaced(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + int j1 = i1 & 8; + i1 &= 7; + if(l == 2 && world.isBlockOpaqueCube(i, j, k + 1)) + { + i1 = 4; + } else + if(l == 3 && world.isBlockOpaqueCube(i, j, k - 1)) + { + i1 = 3; + } else + if(l == 4 && world.isBlockOpaqueCube(i + 1, j, k)) + { + i1 = 2; + } else + if(l == 5 && world.isBlockOpaqueCube(i - 1, j, k)) + { + i1 = 1; + } else + { + i1 = func_22036_h(world, i, j, k); + } + world.setBlockMetadataWithNotify(i, j, k, i1 + j1); + } + + private int func_22036_h(World world, int i, int j, int k) + { + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + return 1; + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + return 2; + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + return 3; + } + return !world.isBlockOpaqueCube(i, j, k + 1) ? 1 : 4; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(func_305_h(world, i, j, k)) + { + int i1 = world.getBlockMetadata(i, j, k) & 7; + boolean flag = false; + if(!world.isBlockOpaqueCube(i - 1, j, k) && i1 == 1) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i + 1, j, k) && i1 == 2) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j, k - 1) && i1 == 3) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j, k + 1) && i1 == 4) + { + flag = true; + } + if(flag) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + } + + private boolean func_305_h(World world, int i, int j, int k) + { + if(!canPlaceBlockAt(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + return false; + } else + { + return true; + } + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + int l = iblockaccess.getBlockMetadata(i, j, k); + int i1 = l & 7; + boolean flag = (l & 8) > 0; + float f = 0.375F; + float f1 = 0.625F; + float f2 = 0.1875F; + float f3 = 0.125F; + if(flag) + { + f3 = 0.0625F; + } + if(i1 == 1) + { + setBlockBounds(0.0F, f, 0.5F - f2, f3, f1, 0.5F + f2); + } else + if(i1 == 2) + { + setBlockBounds(1.0F - f3, f, 0.5F - f2, 1.0F, f1, 0.5F + f2); + } else + if(i1 == 3) + { + setBlockBounds(0.5F - f2, f, 0.0F, 0.5F + f2, f1, f3); + } else + if(i1 == 4) + { + setBlockBounds(0.5F - f2, f, 1.0F - f3, 0.5F + f2, f1, 1.0F); + } + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + blockActivated(world, i, j, k, entityplayer); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + int l = world.getBlockMetadata(i, j, k); + int i1 = l & 7; + int j1 = 8 - (l & 8); + if(j1 == 0) + { + return true; + } + world.setBlockMetadataWithNotify(i, j, k, i1 + j1); + world.markBlocksDirty(i, j, k, i, j, k); + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.click", 0.3F, 0.6F); + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + if(i1 == 1) + { + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + } else + if(i1 == 2) + { + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + } else + if(i1 == 3) + { + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + } else + if(i1 == 4) + { + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } else + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + } + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + return true; + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + if((l & 8) > 0) + { + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + int i1 = l & 7; + if(i1 == 1) + { + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + } else + if(i1 == 2) + { + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + } else + if(i1 == 3) + { + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + } else + if(i1 == 4) + { + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } else + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + } + } + super.onBlockRemoval(world, i, j, k); + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return (iblockaccess.getBlockMetadata(i, j, k) & 8) > 0; + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + if((i1 & 8) == 0) + { + return false; + } + int j1 = i1 & 7; + if(j1 == 5 && l == 1) + { + return true; + } + if(j1 == 4 && l == 2) + { + return true; + } + if(j1 == 3 && l == 3) + { + return true; + } + if(j1 == 2 && l == 4) + { + return true; + } + return j1 == 1 && l == 5; + } + + public boolean canProvidePower() + { + return true; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.multiplayerWorld) + { + return; + } + int l = world.getBlockMetadata(i, j, k); + if((l & 8) == 0) + { + return; + } + world.setBlockMetadataWithNotify(i, j, k, l & 7); + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + int i1 = l & 7; + if(i1 == 1) + { + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + } else + if(i1 == 2) + { + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + } else + if(i1 == 3) + { + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + } else + if(i1 == 4) + { + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } else + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + } + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.click", 0.3F, 0.5F); + world.markBlocksDirty(i, j, k, i, j, k); + } + + public void func_237_e() + { + float f = 0.1875F; + float f1 = 0.125F; + float f2 = 0.125F; + setBlockBounds(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2); + } +} diff --git a/src/main/java/net/minecraft/src/BlockCactus.java b/src/main/java/net/minecraft/src/BlockCactus.java new file mode 100644 index 0000000..226551f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCactus.java @@ -0,0 +1,128 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockCactus extends Block +{ + + protected BlockCactus(int i, int j) + { + super(i, j, Material.cactus); + setTickOnLoad(true); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.isAirBlock(i, j + 1, k)) + { + int l; + for(l = 1; world.getBlockId(i, j - l, k) == blockID; l++) { } + if(l < 3) + { + int i1 = world.getBlockMetadata(i, j, k); + if(i1 == 15) + { + world.setBlockWithNotify(i, j + 1, k, blockID); + world.setBlockMetadataWithNotify(i, j, k, 0); + } else + { + world.setBlockMetadataWithNotify(i, j, k, i1 + 1); + } + } + } + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + float f = 0.0625F; + return AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, (float)(j + 1) - f, (float)(k + 1) - f); + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + float f = 0.0625F; + return AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, j + 1, (float)(k + 1) - f); + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture - 1; + } + if(i == 0) + { + return blockIndexInTexture + 1; + } else + { + return blockIndexInTexture; + } + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean isOpaqueCube() + { + return false; + } + + public int getRenderType() + { + return 13; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(!super.canPlaceBlockAt(world, i, j, k)) + { + return false; + } else + { + return canBlockStay(world, i, j, k); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(!canBlockStay(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + if(world.getBlockMaterial(i - 1, j, k).isSolid()) + { + return false; + } + if(world.getBlockMaterial(i + 1, j, k).isSolid()) + { + return false; + } + if(world.getBlockMaterial(i, j, k - 1).isSolid()) + { + return false; + } + if(world.getBlockMaterial(i, j, k + 1).isSolid()) + { + return false; + } else + { + int l = world.getBlockId(i, j - 1, k); + return l == Block.cactus.blockID || l == Block.sand.blockID; + } + } + + public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) + { + entity.attackEntityFrom(null, 1); + } +} diff --git a/src/main/java/net/minecraft/src/BlockCake.java b/src/main/java/net/minecraft/src/BlockCake.java new file mode 100644 index 0000000..062e3e8 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCake.java @@ -0,0 +1,157 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockCake extends Block +{ + + protected BlockCake(int i, int j) + { + super(i, j, Material.field_21150_y); + setTickOnLoad(true); + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + int l = iblockaccess.getBlockMetadata(i, j, k); + float f = 0.0625F; + float f1 = (float)(1 + l * 2) / 16F; + float f2 = 0.5F; + setBlockBounds(f1, 0.0F, f, 1.0F - f, f2, 1.0F - f); + } + + public void func_237_e() + { + float f = 0.0625F; + float f1 = 0.5F; + setBlockBounds(f, 0.0F, f, 1.0F - f, f1, 1.0F - f); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + float f = 0.0625F; + float f1 = (float)(1 + l * 2) / 16F; + float f2 = 0.5F; + return AxisAlignedBB.getBoundingBoxFromPool((float)i + f1, j, (float)k + f, (float)(i + 1) - f, ((float)j + f2) - f, (float)(k + 1) - f); + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + float f = 0.0625F; + float f1 = (float)(1 + l * 2) / 16F; + float f2 = 0.5F; + return AxisAlignedBB.getBoundingBoxFromPool((float)i + f1, j, (float)k + f, (float)(i + 1) - f, (float)j + f2, (float)(k + 1) - f); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 1) + { + return blockIndexInTexture; + } + if(i == 0) + { + return blockIndexInTexture + 3; + } + if(j > 0 && i == 4) + { + return blockIndexInTexture + 2; + } else + { + return blockIndexInTexture + 1; + } + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture; + } + if(i == 0) + { + return blockIndexInTexture + 3; + } else + { + return blockIndexInTexture + 1; + } + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + func_21029_c(world, i, j, k, entityplayer); + return true; + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + func_21029_c(world, i, j, k, entityplayer); + } + + private void func_21029_c(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(entityplayer.health < 20) + { + entityplayer.heal(3); + int l = world.getBlockMetadata(i, j, k) + 1; + if(l >= 6) + { + world.setBlockWithNotify(i, j, k, 0); + } else + { + world.setBlockMetadataWithNotify(i, j, k, l); + world.markBlockAsNeedsUpdate(i, j, k); + } + } + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(!super.canPlaceBlockAt(world, i, j, k)) + { + return false; + } else + { + return canBlockStay(world, i, j, k); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(!canBlockStay(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + return world.getBlockMaterial(i, j - 1, k).isSolid(); + } + + public int quantityDropped(Random random) + { + return 0; + } + + public int idDropped(int i, Random random) + { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockChest.java b/src/main/java/net/minecraft/src/BlockChest.java new file mode 100644 index 0000000..6f9ddb7 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockChest.java @@ -0,0 +1,279 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockChest extends BlockContainer +{ + + protected BlockChest(int i) + { + super(i, Material.wood); + random = new Random(); + blockIndexInTexture = 26; + } + + public int getBlockTexture(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(l == 1) + { + return blockIndexInTexture - 1; + } + if(l == 0) + { + return blockIndexInTexture - 1; + } + int i1 = iblockaccess.getBlockId(i, j, k - 1); + int j1 = iblockaccess.getBlockId(i, j, k + 1); + int k1 = iblockaccess.getBlockId(i - 1, j, k); + int l1 = iblockaccess.getBlockId(i + 1, j, k); + if(i1 == blockID || j1 == blockID) + { + if(l == 2 || l == 3) + { + return blockIndexInTexture; + } + int i2 = 0; + if(i1 == blockID) + { + i2 = -1; + } + int k2 = iblockaccess.getBlockId(i - 1, j, i1 != blockID ? k + 1 : k - 1); + int i3 = iblockaccess.getBlockId(i + 1, j, i1 != blockID ? k + 1 : k - 1); + if(l == 4) + { + i2 = -1 - i2; + } + byte byte1 = 5; + if((Block.opaqueCubeLookup[k1] || Block.opaqueCubeLookup[k2]) && !Block.opaqueCubeLookup[l1] && !Block.opaqueCubeLookup[i3]) + { + byte1 = 5; + } + if((Block.opaqueCubeLookup[l1] || Block.opaqueCubeLookup[i3]) && !Block.opaqueCubeLookup[k1] && !Block.opaqueCubeLookup[k2]) + { + byte1 = 4; + } + return (l != byte1 ? blockIndexInTexture + 32 : blockIndexInTexture + 16) + i2; + } + if(k1 == blockID || l1 == blockID) + { + if(l == 4 || l == 5) + { + return blockIndexInTexture; + } + int j2 = 0; + if(k1 == blockID) + { + j2 = -1; + } + int l2 = iblockaccess.getBlockId(k1 != blockID ? i + 1 : i - 1, j, k - 1); + int j3 = iblockaccess.getBlockId(k1 != blockID ? i + 1 : i - 1, j, k + 1); + if(l == 3) + { + j2 = -1 - j2; + } + byte byte2 = 3; + if((Block.opaqueCubeLookup[i1] || Block.opaqueCubeLookup[l2]) && !Block.opaqueCubeLookup[j1] && !Block.opaqueCubeLookup[j3]) + { + byte2 = 3; + } + if((Block.opaqueCubeLookup[j1] || Block.opaqueCubeLookup[j3]) && !Block.opaqueCubeLookup[i1] && !Block.opaqueCubeLookup[l2]) + { + byte2 = 2; + } + return (l != byte2 ? blockIndexInTexture + 32 : blockIndexInTexture + 16) + j2; + } + byte byte0 = 3; + if(Block.opaqueCubeLookup[i1] && !Block.opaqueCubeLookup[j1]) + { + byte0 = 3; + } + if(Block.opaqueCubeLookup[j1] && !Block.opaqueCubeLookup[i1]) + { + byte0 = 2; + } + if(Block.opaqueCubeLookup[k1] && !Block.opaqueCubeLookup[l1]) + { + byte0 = 5; + } + if(Block.opaqueCubeLookup[l1] && !Block.opaqueCubeLookup[k1]) + { + byte0 = 4; + } + return l != byte0 ? blockIndexInTexture : blockIndexInTexture + 1; + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture - 1; + } + if(i == 0) + { + return blockIndexInTexture - 1; + } + if(i == 3) + { + return blockIndexInTexture + 1; + } else + { + return blockIndexInTexture; + } + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + int l = 0; + if(world.getBlockId(i - 1, j, k) == blockID) + { + l++; + } + if(world.getBlockId(i + 1, j, k) == blockID) + { + l++; + } + if(world.getBlockId(i, j, k - 1) == blockID) + { + l++; + } + if(world.getBlockId(i, j, k + 1) == blockID) + { + l++; + } + if(l > 1) + { + return false; + } + if(isThereANeighborChest(world, i - 1, j, k)) + { + return false; + } + if(isThereANeighborChest(world, i + 1, j, k)) + { + return false; + } + if(isThereANeighborChest(world, i, j, k - 1)) + { + return false; + } + return !isThereANeighborChest(world, i, j, k + 1); + } + + private boolean isThereANeighborChest(World world, int i, int j, int k) + { + if(world.getBlockId(i, j, k) != blockID) + { + return false; + } + if(world.getBlockId(i - 1, j, k) == blockID) + { + return true; + } + if(world.getBlockId(i + 1, j, k) == blockID) + { + return true; + } + if(world.getBlockId(i, j, k - 1) == blockID) + { + return true; + } + return world.getBlockId(i, j, k + 1) == blockID; + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + TileEntityChest tileentitychest = (TileEntityChest)world.getBlockTileEntity(i, j, k); +label0: + for(int l = 0; l < tileentitychest.getSizeInventory(); l++) + { + ItemStack itemstack = tileentitychest.getStackInSlot(l); + if(itemstack == null) + { + continue; + } + float f = random.nextFloat() * 0.8F + 0.1F; + float f1 = random.nextFloat() * 0.8F + 0.1F; + float f2 = random.nextFloat() * 0.8F + 0.1F; + do + { + if(itemstack.stackSize <= 0) + { + continue label0; + } + int i1 = random.nextInt(21) + 10; + if(i1 > itemstack.stackSize) + { + i1 = itemstack.stackSize; + } + itemstack.stackSize -= i1; + EntityItem entityitem = new EntityItem(world, (float)i + f, (float)j + f1, (float)k + f2, new ItemStack(itemstack.itemID, i1, itemstack.getItemDamage())); + float f3 = 0.05F; + entityitem.motionX = (float)random.nextGaussian() * f3; + entityitem.motionY = (float)random.nextGaussian() * f3 + 0.2F; + entityitem.motionZ = (float)random.nextGaussian() * f3; + world.entityJoinedWorld(entityitem); + } while(true); + } + + super.onBlockRemoval(world, i, j, k); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + Object obj = (TileEntityChest)world.getBlockTileEntity(i, j, k); + if(world.isBlockOpaqueCube(i, j + 1, k)) + { + return true; + } + if(world.getBlockId(i - 1, j, k) == blockID && world.isBlockOpaqueCube(i - 1, j + 1, k)) + { + return true; + } + if(world.getBlockId(i + 1, j, k) == blockID && world.isBlockOpaqueCube(i + 1, j + 1, k)) + { + return true; + } + if(world.getBlockId(i, j, k - 1) == blockID && world.isBlockOpaqueCube(i, j + 1, k - 1)) + { + return true; + } + if(world.getBlockId(i, j, k + 1) == blockID && world.isBlockOpaqueCube(i, j + 1, k + 1)) + { + return true; + } + if(world.getBlockId(i - 1, j, k) == blockID) + { + obj = new InventoryLargeChest("Large chest", (TileEntityChest)world.getBlockTileEntity(i - 1, j, k), ((IInventory) (obj))); + } + if(world.getBlockId(i + 1, j, k) == blockID) + { + obj = new InventoryLargeChest("Large chest", ((IInventory) (obj)), (TileEntityChest)world.getBlockTileEntity(i + 1, j, k)); + } + if(world.getBlockId(i, j, k - 1) == blockID) + { + obj = new InventoryLargeChest("Large chest", (TileEntityChest)world.getBlockTileEntity(i, j, k - 1), ((IInventory) (obj))); + } + if(world.getBlockId(i, j, k + 1) == blockID) + { + obj = new InventoryLargeChest("Large chest", ((IInventory) (obj)), (TileEntityChest)world.getBlockTileEntity(i, j, k + 1)); + } + if(world.multiplayerWorld) + { + return true; + } else + { + entityplayer.displayGUIChest(((IInventory) (obj))); + return true; + } + } + + protected TileEntity getBlockEntity() + { + return new TileEntityChest(); + } + + private Random random; +} diff --git a/src/main/java/net/minecraft/src/BlockClay.java b/src/main/java/net/minecraft/src/BlockClay.java new file mode 100644 index 0000000..e93c239 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockClay.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockClay extends Block +{ + + public BlockClay(int i, int j) + { + super(i, j, Material.clay); + } + + public int idDropped(int i, Random random) + { + return Item.clay.shiftedIndex; + } + + public int quantityDropped(Random random) + { + return 4; + } +} diff --git a/src/main/java/net/minecraft/src/BlockCloth.java b/src/main/java/net/minecraft/src/BlockCloth.java new file mode 100644 index 0000000..e520de2 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCloth.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockCloth extends Block +{ + + public BlockCloth() + { + super(35, 64, Material.cloth); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(j == 0) + { + return blockIndexInTexture; + } else + { + j = ~(j & 0xf); + return 113 + ((j & 8) >> 3) + (j & 7) * 16; + } + } + + protected int damageDropped(int i) + { + return i; + } + + public static int func_21034_c(int i) + { + return ~i & 0xf; + } + + public static int func_21035_d(int i) + { + return ~i & 0xf; + } +} diff --git a/src/main/java/net/minecraft/src/BlockContainer.java b/src/main/java/net/minecraft/src/BlockContainer.java new file mode 100644 index 0000000..4490447 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockContainer.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public abstract class BlockContainer extends Block +{ + + protected BlockContainer(int i, Material material) + { + super(i, material); + isBlockContainer[i] = true; + } + + protected BlockContainer(int i, int j, Material material) + { + super(i, j, material); + isBlockContainer[i] = true; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + super.onBlockAdded(world, i, j, k); + world.setBlockTileEntity(i, j, k, getBlockEntity()); + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + super.onBlockRemoval(world, i, j, k); + world.removeBlockTileEntity(i, j, k); + } + + protected abstract TileEntity getBlockEntity(); +} diff --git a/src/main/java/net/minecraft/src/BlockCrops.java b/src/main/java/net/minecraft/src/BlockCrops.java new file mode 100644 index 0000000..7274448 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockCrops.java @@ -0,0 +1,143 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockCrops extends BlockFlower +{ + + protected BlockCrops(int i, int j) + { + super(i, j); + blockIndexInTexture = j; + setTickOnLoad(true); + float f = 0.5F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); + } + + protected boolean canThisPlantGrowOnThisBlockID(int i) + { + return i == Block.tilledField.blockID; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + super.updateTick(world, i, j, k, random); + if(world.getBlockLightValue(i, j + 1, k) >= 9) + { + int l = world.getBlockMetadata(i, j, k); + if(l < 7) + { + float f = getGrowthRate(world, i, j, k); + if(random.nextInt((int)(100F / f)) == 0) + { + l++; + world.setBlockMetadataWithNotify(i, j, k, l); + } + } + } + } + + public void func_21027_c_(World world, int i, int j, int k) + { + world.setBlockMetadataWithNotify(i, j, k, 7); + } + + private float getGrowthRate(World world, int i, int j, int k) + { + float f = 1.0F; + int l = world.getBlockId(i, j, k - 1); + int i1 = world.getBlockId(i, j, k + 1); + int j1 = world.getBlockId(i - 1, j, k); + int k1 = world.getBlockId(i + 1, j, k); + int l1 = world.getBlockId(i - 1, j, k - 1); + int i2 = world.getBlockId(i + 1, j, k - 1); + int j2 = world.getBlockId(i + 1, j, k + 1); + int k2 = world.getBlockId(i - 1, j, k + 1); + boolean flag = j1 == blockID || k1 == blockID; + boolean flag1 = l == blockID || i1 == blockID; + boolean flag2 = l1 == blockID || i2 == blockID || j2 == blockID || k2 == blockID; + for(int l2 = i - 1; l2 <= i + 1; l2++) + { + for(int i3 = k - 1; i3 <= k + 1; i3++) + { + int j3 = world.getBlockId(l2, j - 1, i3); + float f1 = 0.0F; + if(j3 == Block.tilledField.blockID) + { + f1 = 1.0F; + if(world.getBlockMetadata(l2, j - 1, i3) > 0) + { + f1 = 3F; + } + } + if(l2 != i || i3 != k) + { + f1 /= 4F; + } + f += f1; + } + + } + + if(flag2 || flag && flag1) + { + f /= 2.0F; + } + return f; + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(j < 0) + { + j = 7; + } + return blockIndexInTexture + j; + } + + public int getRenderType() + { + return 6; + } + + public void onBlockDestroyedByPlayer(World world, int i, int j, int k, int l) + { + super.onBlockDestroyedByPlayer(world, i, j, k, l); + if(!world.multiplayerWorld) + { + for(int i1 = 0; i1 < 3; i1++) + { + if(world.rand.nextInt(15) <= l) + { + float f = 0.7F; + float f1 = world.rand.nextFloat() * f + (1.0F - f) * 0.5F; + float f2 = world.rand.nextFloat() * f + (1.0F - f) * 0.5F; + float f3 = world.rand.nextFloat() * f + (1.0F - f) * 0.5F; + EntityItem entityitem = new EntityItem(world, (float)i + f1, (float)j + f2, (float)k + f3, new ItemStack(Item.seeds)); + entityitem.delayBeforeCanPickup = 10; + world.entityJoinedWorld(entityitem); + } + } + + } + } + + public int idDropped(int i, Random random) + { + if(i == 7) + { + return Item.wheat.shiftedIndex; + } else + { + return -1; + } + } + + public int quantityDropped(Random random) + { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/BlockDirt.java b/src/main/java/net/minecraft/src/BlockDirt.java new file mode 100644 index 0000000..ccb4c05 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDirt.java @@ -0,0 +1,14 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockDirt extends Block +{ + + protected BlockDirt(int i, int j) + { + super(i, j, Material.ground); + } +} diff --git a/src/main/java/net/minecraft/src/BlockDispenser.java b/src/main/java/net/minecraft/src/BlockDispenser.java new file mode 100644 index 0000000..062af68 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDispenser.java @@ -0,0 +1,234 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockDispenser extends BlockContainer +{ + + protected BlockDispenser(int i) + { + super(i, Material.rock); + blockIndexInTexture = 45; + } + + public int tickRate() + { + return 4; + } + + public int idDropped(int i, Random random) + { + return Block.dispenser.blockID; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + super.onBlockAdded(world, i, j, k); + setDispenserDefaultDirection(world, i, j, k); + } + + private void setDispenserDefaultDirection(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j, k - 1); + int i1 = world.getBlockId(i, j, k + 1); + int j1 = world.getBlockId(i - 1, j, k); + int k1 = world.getBlockId(i + 1, j, k); + byte byte0 = 3; + if(Block.opaqueCubeLookup[l] && !Block.opaqueCubeLookup[i1]) + { + byte0 = 3; + } + if(Block.opaqueCubeLookup[i1] && !Block.opaqueCubeLookup[l]) + { + byte0 = 2; + } + if(Block.opaqueCubeLookup[j1] && !Block.opaqueCubeLookup[k1]) + { + byte0 = 5; + } + if(Block.opaqueCubeLookup[k1] && !Block.opaqueCubeLookup[j1]) + { + byte0 = 4; + } + world.setBlockMetadataWithNotify(i, j, k, byte0); + } + + public int getBlockTexture(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(l == 1) + { + return blockIndexInTexture + 17; + } + if(l == 0) + { + return blockIndexInTexture + 17; + } + int i1 = iblockaccess.getBlockMetadata(i, j, k); + if(l != i1) + { + return blockIndexInTexture; + } else + { + return blockIndexInTexture + 1; + } + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture + 17; + } + if(i == 0) + { + return blockIndexInTexture + 17; + } + if(i == 3) + { + return blockIndexInTexture + 1; + } else + { + return blockIndexInTexture; + } + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(world.multiplayerWorld) + { + return true; + } else + { + TileEntityDispenser tileentitydispenser = (TileEntityDispenser)world.getBlockTileEntity(i, j, k); + entityplayer.displayGUIDispenser(tileentitydispenser); + return true; + } + } + + private void dispenseItem(World world, int i, int j, int k, Random random) + { + int l = world.getBlockMetadata(i, j, k); + float f = 0.0F; + float f1 = 0.0F; + if(l == 3) + { + f1 = 1.0F; + } else + if(l == 2) + { + f1 = -1F; + } else + if(l == 5) + { + f = 1.0F; + } else + { + f = -1F; + } + TileEntityDispenser tileentitydispenser = (TileEntityDispenser)world.getBlockTileEntity(i, j, k); + ItemStack itemstack = tileentitydispenser.getRandomStackFromInventory(); + double d = (double)i + (double)f * 0.5D + 0.5D; + double d1 = (double)j + 0.5D; + double d2 = (double)k + (double)f1 * 0.5D + 0.5D; + if(itemstack == null) + { + world.playSoundEffect(i, j, k, "random.click", 1.0F, 1.2F); + } else + { + if(itemstack.itemID == Item.arrow.shiftedIndex) + { + EntityArrow entityarrow = new EntityArrow(world, d, d1, d2); + entityarrow.setArrowHeading(f, 0.10000000149011612D, f1, 1.1F, 6F); + world.entityJoinedWorld(entityarrow); + world.playSoundEffect(i, j, k, "random.bow", 1.0F, 1.2F); + } else + if(itemstack.itemID == Item.egg.shiftedIndex) + { + EntityEgg entityegg = new EntityEgg(world, d, d1, d2); + entityegg.func_20048_a(f, 0.10000000149011612D, f1, 1.1F, 6F); + world.entityJoinedWorld(entityegg); + world.playSoundEffect(i, j, k, "random.bow", 1.0F, 1.2F); + } else + if(itemstack.itemID == Item.snowball.shiftedIndex) + { + EntitySnowball entitysnowball = new EntitySnowball(world, d, d1, d2); + entitysnowball.func_467_a(f, 0.10000000149011612D, f1, 1.1F, 6F); + world.entityJoinedWorld(entitysnowball); + world.playSoundEffect(i, j, k, "random.bow", 1.0F, 1.2F); + } else + { + EntityItem entityitem = new EntityItem(world, d, d1 - 0.29999999999999999D, d2, itemstack); + double d3 = random.nextDouble() * 0.10000000000000001D + 0.20000000000000001D; + entityitem.motionX = (double)f * d3; + entityitem.motionY = 0.20000000298023224D; + entityitem.motionZ = (double)f1 * d3; + entityitem.motionX += random.nextGaussian() * 0.0074999998323619366D * 6D; + entityitem.motionY += random.nextGaussian() * 0.0074999998323619366D * 6D; + entityitem.motionZ += random.nextGaussian() * 0.0074999998323619366D * 6D; + world.entityJoinedWorld(entityitem); + world.playSoundEffect(i, j, k, "random.click", 1.0F, 1.0F); + } + for(int i1 = 0; i1 < 10; i1++) + { + double d4 = random.nextDouble() * 0.20000000000000001D + 0.01D; + double d5 = d + (double)f * 0.01D + (random.nextDouble() - 0.5D) * (double)f1 * 0.5D; + double d6 = d1 + (random.nextDouble() - 0.5D) * 0.5D; + double d7 = d2 + (double)f1 * 0.01D + (random.nextDouble() - 0.5D) * (double)f * 0.5D; + double d8 = (double)f * d4 + random.nextGaussian() * 0.01D; + double d9 = -0.029999999999999999D + random.nextGaussian() * 0.01D; + double d10 = (double)f1 * d4 + random.nextGaussian() * 0.01D; + world.spawnParticle("smoke", d5, d6, d7, d8, d9, d10); + } + + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(l > 0 && Block.blocksList[l].canProvidePower()) + { + boolean flag = world.isBlockIndirectlyGettingPowered(i, j, k) || world.isBlockIndirectlyGettingPowered(i, j + 1, k); + if(flag) + { + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + } + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.isBlockIndirectlyGettingPowered(i, j, k) || world.isBlockIndirectlyGettingPowered(i, j + 1, k)) + { + dispenseItem(world, i, j, k, random); + } + } + + protected TileEntity getBlockEntity() + { + return new TileEntityDispenser(); + } + + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) + { + int l = MathHelper.floor_double((double)((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3; + if(l == 0) + { + world.setBlockMetadataWithNotify(i, j, k, 2); + } + if(l == 1) + { + world.setBlockMetadataWithNotify(i, j, k, 5); + } + if(l == 2) + { + world.setBlockMetadataWithNotify(i, j, k, 3); + } + if(l == 3) + { + world.setBlockMetadataWithNotify(i, j, k, 4); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockDoor.java b/src/main/java/net/minecraft/src/BlockDoor.java new file mode 100644 index 0000000..7d2f73c --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockDoor.java @@ -0,0 +1,253 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockDoor extends Block +{ + + protected BlockDoor(int i, Material material) + { + super(i, material); + blockIndexInTexture = 97; + if(material == Material.iron) + { + blockIndexInTexture++; + } + float f = 0.5F; + float f1 = 1.0F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 0 || i == 1) + { + return blockIndexInTexture; + } + int k = func_312_c(j); + if((k == 0 || k == 2) ^ (i <= 3)) + { + return blockIndexInTexture; + } + int l = k / 2 + (i & 1 ^ k); + l += (j & 4) / 4; + int i1 = blockIndexInTexture - (j & 8) * 2; + if((l & 1) != 0) + { + i1 = -i1; + } + return i1; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 7; + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + setBlockBoundsBasedOnState(world, i, j, k); + return super.getSelectedBoundingBoxFromPool(world, i, j, k); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + setBlockBoundsBasedOnState(world, i, j, k); + return super.getCollisionBoundingBoxFromPool(world, i, j, k); + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + func_313_b(func_312_c(iblockaccess.getBlockMetadata(i, j, k))); + } + + public void func_313_b(int i) + { + float f = 0.1875F; + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F); + if(i == 0) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + } + if(i == 1) + { + setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + if(i == 2) + { + setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + } + if(i == 3) + { + setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + } + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + blockActivated(world, i, j, k, entityplayer); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(blockMaterial == Material.iron) + { + return true; + } + int l = world.getBlockMetadata(i, j, k); + if((l & 8) != 0) + { + if(world.getBlockId(i, j - 1, k) == blockID) + { + blockActivated(world, i, j - 1, k, entityplayer); + } + return true; + } + if(world.getBlockId(i, j + 1, k) == blockID) + { + world.setBlockMetadataWithNotify(i, j + 1, k, (l ^ 4) + 8); + } + world.setBlockMetadataWithNotify(i, j, k, l ^ 4); + world.markBlocksDirty(i, j - 1, k, i, j, k); + if(Math.random() < 0.5D) + { + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.door_open", 1.0F, world.rand.nextFloat() * 0.1F + 0.9F); + } else + { + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.door_close", 1.0F, world.rand.nextFloat() * 0.1F + 0.9F); + } + return true; + } + + public void func_311_a(World world, int i, int j, int k, boolean flag) + { + int l = world.getBlockMetadata(i, j, k); + if((l & 8) != 0) + { + if(world.getBlockId(i, j - 1, k) == blockID) + { + func_311_a(world, i, j - 1, k, flag); + } + return; + } + boolean flag1 = (world.getBlockMetadata(i, j, k) & 4) > 0; + if(flag1 == flag) + { + return; + } + if(world.getBlockId(i, j + 1, k) == blockID) + { + world.setBlockMetadataWithNotify(i, j + 1, k, (l ^ 4) + 8); + } + world.setBlockMetadataWithNotify(i, j, k, l ^ 4); + world.markBlocksDirty(i, j - 1, k, i, j, k); + if(Math.random() < 0.5D) + { + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.door_open", 1.0F, world.rand.nextFloat() * 0.1F + 0.9F); + } else + { + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.door_close", 1.0F, world.rand.nextFloat() * 0.1F + 0.9F); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + if((i1 & 8) != 0) + { + if(world.getBlockId(i, j - 1, k) != blockID) + { + world.setBlockWithNotify(i, j, k, 0); + } + if(l > 0 && Block.blocksList[l].canProvidePower()) + { + onNeighborBlockChange(world, i, j - 1, k, l); + } + } else + { + boolean flag = false; + if(world.getBlockId(i, j + 1, k) != blockID) + { + world.setBlockWithNotify(i, j, k, 0); + flag = true; + } + if(!world.isBlockOpaqueCube(i, j - 1, k)) + { + world.setBlockWithNotify(i, j, k, 0); + flag = true; + if(world.getBlockId(i, j + 1, k) == blockID) + { + world.setBlockWithNotify(i, j + 1, k, 0); + } + } + if(flag) + { + if(!world.multiplayerWorld) + { + dropBlockAsItem(world, i, j, k, i1); + } + } else + if(l > 0 && Block.blocksList[l].canProvidePower()) + { + boolean flag1 = world.isBlockIndirectlyGettingPowered(i, j, k) || world.isBlockIndirectlyGettingPowered(i, j + 1, k); + func_311_a(world, i, j, k, flag1); + } + } + } + + public int idDropped(int i, Random random) + { + if((i & 8) != 0) + { + return 0; + } + if(blockMaterial == Material.iron) + { + return Item.doorSteel.shiftedIndex; + } else + { + return Item.doorWood.shiftedIndex; + } + } + + public MovingObjectPosition collisionRayTrace(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) + { + setBlockBoundsBasedOnState(world, i, j, k); + return super.collisionRayTrace(world, i, j, k, vec3d, vec3d1); + } + + public int func_312_c(int i) + { + if((i & 4) == 0) + { + return i - 1 & 3; + } else + { + return i & 3; + } + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(j >= 127) + { + return false; + } else + { + return world.isBlockOpaqueCube(i, j - 1, k) && super.canPlaceBlockAt(world, i, j, k) && super.canPlaceBlockAt(world, i, j + 1, k); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockFence.java b/src/main/java/net/minecraft/src/BlockFence.java new file mode 100644 index 0000000..9cebd28 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFence.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockFence extends Block +{ + + public BlockFence(int i, int j) + { + super(i, j, Material.wood); + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(world.getBlockId(i, j - 1, k) == blockID) + { + return false; + } + if(!world.getBlockMaterial(i, j - 1, k).isSolid()) + { + return false; + } else + { + return super.canPlaceBlockAt(world, i, j, k); + } + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return AxisAlignedBB.getBoundingBoxFromPool(i, j, k, i + 1, (float)j + 1.5F, k + 1); + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 11; + } +} diff --git a/src/main/java/net/minecraft/src/BlockFire.java b/src/main/java/net/minecraft/src/BlockFire.java new file mode 100644 index 0000000..0916d1b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFire.java @@ -0,0 +1,326 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockFire extends Block +{ + + protected BlockFire(int i, int j) + { + super(i, j, Material.fire); + chanceToEncourageFire = new int[256]; + abilityToCatchFire = new int[256]; + setBurnRate(Block.planks.blockID, 5, 20); + setBurnRate(Block.wood.blockID, 5, 5); + setBurnRate(Block.leaves.blockID, 30, 60); + setBurnRate(Block.bookShelf.blockID, 30, 20); + setBurnRate(Block.tnt.blockID, 15, 100); + setBurnRate(Block.cloth.blockID, 30, 60); + setTickOnLoad(true); + } + + private void setBurnRate(int i, int j, int k) + { + chanceToEncourageFire[i] = j; + abilityToCatchFire[i] = k; + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 3; + } + + public int quantityDropped(Random random) + { + return 0; + } + + public int tickRate() + { + return 10; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + boolean flag = world.getBlockId(i, j - 1, k) == Block.bloodStone.blockID; + int l = world.getBlockMetadata(i, j, k); + if(l < 15) + { + world.setBlockMetadataWithNotify(i, j, k, l + 1); + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + if(!flag && !func_263_h(world, i, j, k)) + { + if(!world.isBlockOpaqueCube(i, j - 1, k) || l > 3) + { + world.setBlockWithNotify(i, j, k, 0); + } + return; + } + if(!flag && !canBlockCatchFire(world, i, j - 1, k) && l == 15 && random.nextInt(4) == 0) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } + if(l % 2 == 0 && l > 2) + { + tryToCatchBlockOnFire(world, i + 1, j, k, 300, random); + tryToCatchBlockOnFire(world, i - 1, j, k, 300, random); + tryToCatchBlockOnFire(world, i, j - 1, k, 250, random); + tryToCatchBlockOnFire(world, i, j + 1, k, 250, random); + tryToCatchBlockOnFire(world, i, j, k - 1, 300, random); + tryToCatchBlockOnFire(world, i, j, k + 1, 300, random); + for(int i1 = i - 1; i1 <= i + 1; i1++) + { + for(int j1 = k - 1; j1 <= k + 1; j1++) + { + for(int k1 = j - 1; k1 <= j + 4; k1++) + { + if(i1 == i && k1 == j && j1 == k) + { + continue; + } + int l1 = 100; + if(k1 > j + 1) + { + l1 += (k1 - (j + 1)) * 100; + } + int i2 = getChanceOfNeighborsEncouragingFire(world, i1, k1, j1); + if(i2 > 0 && random.nextInt(l1) <= i2) + { + world.setBlockWithNotify(i1, k1, j1, blockID); + } + } + + } + + } + + } + if(l == 15) + { + tryToCatchBlockOnFire(world, i + 1, j, k, 1, random); + tryToCatchBlockOnFire(world, i - 1, j, k, 1, random); + tryToCatchBlockOnFire(world, i, j - 1, k, 1, random); + tryToCatchBlockOnFire(world, i, j + 1, k, 1, random); + tryToCatchBlockOnFire(world, i, j, k - 1, 1, random); + tryToCatchBlockOnFire(world, i, j, k + 1, 1, random); + } + } + + private void tryToCatchBlockOnFire(World world, int i, int j, int k, int l, Random random) + { + int i1 = abilityToCatchFire[world.getBlockId(i, j, k)]; + if(random.nextInt(l) < i1) + { + boolean flag = world.getBlockId(i, j, k) == Block.tnt.blockID; + if(random.nextInt(2) == 0) + { + world.setBlockWithNotify(i, j, k, blockID); + } else + { + world.setBlockWithNotify(i, j, k, 0); + } + if(flag) + { + Block.tnt.onBlockDestroyedByPlayer(world, i, j, k, 0); + } + } + } + + private boolean func_263_h(World world, int i, int j, int k) + { + if(canBlockCatchFire(world, i + 1, j, k)) + { + return true; + } + if(canBlockCatchFire(world, i - 1, j, k)) + { + return true; + } + if(canBlockCatchFire(world, i, j - 1, k)) + { + return true; + } + if(canBlockCatchFire(world, i, j + 1, k)) + { + return true; + } + if(canBlockCatchFire(world, i, j, k - 1)) + { + return true; + } + return canBlockCatchFire(world, i, j, k + 1); + } + + private int getChanceOfNeighborsEncouragingFire(World world, int i, int j, int k) + { + int l = 0; + if(!world.isAirBlock(i, j, k)) + { + return 0; + } else + { + l = getChanceToEncourageFire(world, i + 1, j, k, l); + l = getChanceToEncourageFire(world, i - 1, j, k, l); + l = getChanceToEncourageFire(world, i, j - 1, k, l); + l = getChanceToEncourageFire(world, i, j + 1, k, l); + l = getChanceToEncourageFire(world, i, j, k - 1, l); + l = getChanceToEncourageFire(world, i, j, k + 1, l); + return l; + } + } + + public boolean isCollidable() + { + return false; + } + + public boolean canBlockCatchFire(IBlockAccess iblockaccess, int i, int j, int k) + { + return chanceToEncourageFire[iblockaccess.getBlockId(i, j, k)] > 0; + } + + public int getChanceToEncourageFire(World world, int i, int j, int k, int l) + { + int i1 = chanceToEncourageFire[world.getBlockId(i, j, k)]; + if(i1 > l) + { + return i1; + } else + { + return l; + } + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + return world.isBlockOpaqueCube(i, j - 1, k) || func_263_h(world, i, j, k); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(!world.isBlockOpaqueCube(i, j - 1, k) && !func_263_h(world, i, j, k)) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } else + { + return; + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + if(world.getBlockId(i, j - 1, k) == Block.obsidian.blockID && Block.portal.tryToCreatePortal(world, i, j, k)) + { + return; + } + if(!world.isBlockOpaqueCube(i, j - 1, k) && !func_263_h(world, i, j, k)) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } else + { + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + return; + } + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(random.nextInt(24) == 0) + { + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, "fire.fire", 1.0F + random.nextFloat(), random.nextFloat() * 0.7F + 0.3F); + } + if(world.isBlockOpaqueCube(i, j - 1, k) || Block.fire.canBlockCatchFire(world, i, j - 1, k)) + { + for(int l = 0; l < 3; l++) + { + float f = (float)i + random.nextFloat(); + float f6 = (float)j + random.nextFloat() * 0.5F + 0.5F; + float f12 = (float)k + random.nextFloat(); + world.spawnParticle("largesmoke", f, f6, f12, 0.0D, 0.0D, 0.0D); + } + + } else + { + if(Block.fire.canBlockCatchFire(world, i - 1, j, k)) + { + for(int i1 = 0; i1 < 2; i1++) + { + float f1 = (float)i + random.nextFloat() * 0.1F; + float f7 = (float)j + random.nextFloat(); + float f13 = (float)k + random.nextFloat(); + world.spawnParticle("largesmoke", f1, f7, f13, 0.0D, 0.0D, 0.0D); + } + + } + if(Block.fire.canBlockCatchFire(world, i + 1, j, k)) + { + for(int j1 = 0; j1 < 2; j1++) + { + float f2 = (float)(i + 1) - random.nextFloat() * 0.1F; + float f8 = (float)j + random.nextFloat(); + float f14 = (float)k + random.nextFloat(); + world.spawnParticle("largesmoke", f2, f8, f14, 0.0D, 0.0D, 0.0D); + } + + } + if(Block.fire.canBlockCatchFire(world, i, j, k - 1)) + { + for(int k1 = 0; k1 < 2; k1++) + { + float f3 = (float)i + random.nextFloat(); + float f9 = (float)j + random.nextFloat(); + float f15 = (float)k + random.nextFloat() * 0.1F; + world.spawnParticle("largesmoke", f3, f9, f15, 0.0D, 0.0D, 0.0D); + } + + } + if(Block.fire.canBlockCatchFire(world, i, j, k + 1)) + { + for(int l1 = 0; l1 < 2; l1++) + { + float f4 = (float)i + random.nextFloat(); + float f10 = (float)j + random.nextFloat(); + float f16 = (float)(k + 1) - random.nextFloat() * 0.1F; + world.spawnParticle("largesmoke", f4, f10, f16, 0.0D, 0.0D, 0.0D); + } + + } + if(Block.fire.canBlockCatchFire(world, i, j + 1, k)) + { + for(int i2 = 0; i2 < 2; i2++) + { + float f5 = (float)i + random.nextFloat(); + float f11 = (float)(j + 1) - random.nextFloat() * 0.1F; + float f17 = (float)k + random.nextFloat(); + world.spawnParticle("largesmoke", f5, f11, f17, 0.0D, 0.0D, 0.0D); + } + + } + } + } + + private int chanceToEncourageFire[]; + private int abilityToCatchFire[]; +} diff --git a/src/main/java/net/minecraft/src/BlockFlower.java b/src/main/java/net/minecraft/src/BlockFlower.java new file mode 100644 index 0000000..4e51b01 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFlower.java @@ -0,0 +1,74 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockFlower extends Block +{ + + protected BlockFlower(int i, int j) + { + super(i, Material.plants); + blockIndexInTexture = j; + setTickOnLoad(true); + float f = 0.2F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 3F, 0.5F + f); + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + return canThisPlantGrowOnThisBlockID(world.getBlockId(i, j - 1, k)); + } + + protected boolean canThisPlantGrowOnThisBlockID(int i) + { + return i == Block.grass.blockID || i == Block.dirt.blockID || i == Block.tilledField.blockID; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + super.onNeighborBlockChange(world, i, j, k, l); + func_268_h(world, i, j, k); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + func_268_h(world, i, j, k); + } + + protected final void func_268_h(World world, int i, int j, int k) + { + if(!canBlockStay(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + return (world.getBlockLightValue(i, j, k) >= 8 || world.canBlockSeeTheSky(i, j, k)) && canThisPlantGrowOnThisBlockID(world.getBlockId(i, j - 1, k)); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/BlockFlowing.java b/src/main/java/net/minecraft/src/BlockFlowing.java new file mode 100644 index 0000000..a753c7a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFlowing.java @@ -0,0 +1,322 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockFlowing extends BlockFluids +{ + + protected BlockFlowing(int i, Material material) + { + super(i, material); + field_460_a = 0; + field_459_b = new boolean[4]; + field_461_c = new int[4]; + } + + private void func_22034_j(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + world.setBlockAndMetadata(i, j, k, blockID + 1, l); + world.markBlocksDirty(i, j, k, i, j, k); + world.markBlockNeedsUpdate(i, j, k); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + int l = func_290_h(world, i, j, k); + byte byte0 = 1; + if(blockMaterial == Material.lava && !world.worldProvider.isHellWorld) + { + byte0 = 2; + } + boolean flag = true; + if(l > 0) + { + int i1 = -100; + field_460_a = 0; + i1 = func_296_f(world, i - 1, j, k, i1); + i1 = func_296_f(world, i + 1, j, k, i1); + i1 = func_296_f(world, i, j, k - 1, i1); + i1 = func_296_f(world, i, j, k + 1, i1); + int j1 = i1 + byte0; + if(j1 >= 8 || i1 < 0) + { + j1 = -1; + } + if(func_290_h(world, i, j + 1, k) >= 0) + { + int l1 = func_290_h(world, i, j + 1, k); + if(l1 >= 8) + { + j1 = l1; + } else + { + j1 = l1 + 8; + } + } + if(field_460_a >= 2 && blockMaterial == Material.water) + { + if(world.isBlockOpaqueCube(i, j - 1, k)) + { + j1 = 0; + } else + if(world.getBlockMaterial(i, j - 1, k) == blockMaterial && world.getBlockMetadata(i, j, k) == 0) + { + j1 = 0; + } + } + if(blockMaterial == Material.lava && l < 8 && j1 < 8 && j1 > l && random.nextInt(4) != 0) + { + j1 = l; + flag = false; + } + if(j1 != l) + { + l = j1; + if(l < 0) + { + world.setBlockWithNotify(i, j, k, 0); + } else + { + world.setBlockMetadataWithNotify(i, j, k, l); + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + } + } else + if(flag) + { + func_22034_j(world, i, j, k); + } + } else + { + func_22034_j(world, i, j, k); + } + if(func_298_m(world, i, j - 1, k)) + { + if(l >= 8) + { + world.setBlockAndMetadataWithNotify(i, j - 1, k, blockID, l); + } else + { + world.setBlockAndMetadataWithNotify(i, j - 1, k, blockID, l + 8); + } + } else + if(l >= 0 && (l == 0 || func_295_l(world, i, j - 1, k))) + { + boolean aflag[] = func_297_k(world, i, j, k); + int k1 = l + byte0; + if(l >= 8) + { + k1 = 1; + } + if(k1 >= 8) + { + return; + } + if(aflag[0]) + { + func_299_g(world, i - 1, j, k, k1); + } + if(aflag[1]) + { + func_299_g(world, i + 1, j, k, k1); + } + if(aflag[2]) + { + func_299_g(world, i, j, k - 1, k1); + } + if(aflag[3]) + { + func_299_g(world, i, j, k + 1, k1); + } + } + } + + private void func_299_g(World world, int i, int j, int k, int l) + { + if(func_298_m(world, i, j, k)) + { + int i1 = world.getBlockId(i, j, k); + if(i1 > 0) + { + if(blockMaterial == Material.lava) + { + func_292_i(world, i, j, k); + } else + { + Block.blocksList[i1].dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + } + } + world.setBlockAndMetadataWithNotify(i, j, k, blockID, l); + } + } + + private int func_300_a(World world, int i, int j, int k, int l, int i1) + { + int j1 = 1000; + for(int k1 = 0; k1 < 4; k1++) + { + if(k1 == 0 && i1 == 1 || k1 == 1 && i1 == 0 || k1 == 2 && i1 == 3 || k1 == 3 && i1 == 2) + { + continue; + } + int l1 = i; + int i2 = j; + int j2 = k; + if(k1 == 0) + { + l1--; + } + if(k1 == 1) + { + l1++; + } + if(k1 == 2) + { + j2--; + } + if(k1 == 3) + { + j2++; + } + if(func_295_l(world, l1, i2, j2) || world.getBlockMaterial(l1, i2, j2) == blockMaterial && world.getBlockMetadata(l1, i2, j2) == 0) + { + continue; + } + if(!func_295_l(world, l1, i2 - 1, j2)) + { + return l; + } + if(l >= 4) + { + continue; + } + int k2 = func_300_a(world, l1, i2, j2, l + 1, k1); + if(k2 < j1) + { + j1 = k2; + } + } + + return j1; + } + + private boolean[] func_297_k(World world, int i, int j, int k) + { + for(int l = 0; l < 4; l++) + { + field_461_c[l] = 1000; + int j1 = i; + int i2 = j; + int j2 = k; + if(l == 0) + { + j1--; + } + if(l == 1) + { + j1++; + } + if(l == 2) + { + j2--; + } + if(l == 3) + { + j2++; + } + if(func_295_l(world, j1, i2, j2) || world.getBlockMaterial(j1, i2, j2) == blockMaterial && world.getBlockMetadata(j1, i2, j2) == 0) + { + continue; + } + if(!func_295_l(world, j1, i2 - 1, j2)) + { + field_461_c[l] = 0; + } else + { + field_461_c[l] = func_300_a(world, j1, i2, j2, 1, l); + } + } + + int i1 = field_461_c[0]; + for(int k1 = 1; k1 < 4; k1++) + { + if(field_461_c[k1] < i1) + { + i1 = field_461_c[k1]; + } + } + + for(int l1 = 0; l1 < 4; l1++) + { + field_459_b[l1] = field_461_c[l1] == i1; + } + + return field_459_b; + } + + private boolean func_295_l(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j, k); + if(l == Block.doorWood.blockID || l == Block.doorSteel.blockID || l == Block.signPost.blockID || l == Block.ladder.blockID || l == Block.reed.blockID) + { + return true; + } + if(l == 0) + { + return false; + } + Material material = Block.blocksList[l].blockMaterial; + return material.isSolid(); + } + + protected int func_296_f(World world, int i, int j, int k, int l) + { + int i1 = func_290_h(world, i, j, k); + if(i1 < 0) + { + return l; + } + if(i1 == 0) + { + field_460_a++; + } + if(i1 >= 8) + { + i1 = 0; + } + return l >= 0 && i1 >= l ? l : i1; + } + + private boolean func_298_m(World world, int i, int j, int k) + { + Material material = world.getBlockMaterial(i, j, k); + if(material == blockMaterial) + { + return false; + } + if(material == Material.lava) + { + return false; + } else + { + return !func_295_l(world, i, j, k); + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + super.onBlockAdded(world, i, j, k); + if(world.getBlockId(i, j, k) == blockID) + { + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + } + + int field_460_a; + boolean field_459_b[]; + int field_461_c[]; +} diff --git a/src/main/java/net/minecraft/src/BlockFluids.java b/src/main/java/net/minecraft/src/BlockFluids.java new file mode 100644 index 0000000..c26ac1f --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFluids.java @@ -0,0 +1,349 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public abstract class BlockFluids extends Block +{ + + protected BlockFluids(int i, Material material) + { + super(i, (material != Material.lava ? 12 : 14) * 16 + 13, material); + float f = 0.0F; + float f1 = 0.0F; + setBlockBounds(0.0F + f1, 0.0F + f, 0.0F + f1, 1.0F + f1, 1.0F + f, 1.0F + f1); + setTickOnLoad(true); + } + + public static float setFluidHeight(int i) + { + if(i >= 8) + { + i = 0; + } + float f = (float)(i + 1) / 9F; + return f; + } + + public int getBlockTextureFromSide(int i) + { + if(i == 0 || i == 1) + { + return blockIndexInTexture; + } else + { + return blockIndexInTexture + 1; + } + } + + protected int func_290_h(World world, int i, int j, int k) + { + if(world.getBlockMaterial(i, j, k) != blockMaterial) + { + return -1; + } else + { + return world.getBlockMetadata(i, j, k); + } + } + + protected int func_289_b(IBlockAccess iblockaccess, int i, int j, int k) + { + if(iblockaccess.getBlockMaterial(i, j, k) != blockMaterial) + { + return -1; + } + int l = iblockaccess.getBlockMetadata(i, j, k); + if(l >= 8) + { + l = 0; + } + return l; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean canCollideCheck(int i, boolean flag) + { + return flag && i == 0; + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + Material material = iblockaccess.getBlockMaterial(i, j, k); + if(material == blockMaterial) + { + return false; + } + if(material == Material.ice) + { + return false; + } + if(l == 1) + { + return true; + } else + { + return super.shouldSideBeRendered(iblockaccess, i, j, k, l); + } + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public int getRenderType() + { + return 4; + } + + public int idDropped(int i, Random random) + { + return 0; + } + + public int quantityDropped(Random random) + { + return 0; + } + + private Vec3D func_291_e(IBlockAccess iblockaccess, int i, int j, int k) + { + Vec3D vec3d = Vec3D.createVector(0.0D, 0.0D, 0.0D); + int l = func_289_b(iblockaccess, i, j, k); + for(int i1 = 0; i1 < 4; i1++) + { + int j1 = i; + int k1 = j; + int l1 = k; + if(i1 == 0) + { + j1--; + } + if(i1 == 1) + { + l1--; + } + if(i1 == 2) + { + j1++; + } + if(i1 == 3) + { + l1++; + } + int i2 = func_289_b(iblockaccess, j1, k1, l1); + if(i2 < 0) + { + if(iblockaccess.getBlockMaterial(j1, k1, l1).getIsSolid()) + { + continue; + } + i2 = func_289_b(iblockaccess, j1, k1 - 1, l1); + if(i2 >= 0) + { + int j2 = i2 - (l - 8); + vec3d = vec3d.addVector((j1 - i) * j2, (k1 - j) * j2, (l1 - k) * j2); + } + continue; + } + if(i2 >= 0) + { + int k2 = i2 - l; + vec3d = vec3d.addVector((j1 - i) * k2, (k1 - j) * k2, (l1 - k) * k2); + } + } + + if(iblockaccess.getBlockMetadata(i, j, k) >= 8) + { + boolean flag = false; + if(flag || shouldSideBeRendered(iblockaccess, i, j, k - 1, 2)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i, j, k + 1, 3)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i - 1, j, k, 4)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i + 1, j, k, 5)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i, j + 1, k - 1, 2)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i, j + 1, k + 1, 3)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i - 1, j + 1, k, 4)) + { + flag = true; + } + if(flag || shouldSideBeRendered(iblockaccess, i + 1, j + 1, k, 5)) + { + flag = true; + } + if(flag) + { + vec3d = vec3d.normalize().addVector(0.0D, -6D, 0.0D); + } + } + vec3d = vec3d.normalize(); + return vec3d; + } + + public void velocityToAddToEntity(World world, int i, int j, int k, Entity entity, Vec3D vec3d) + { + Vec3D vec3d1 = func_291_e(world, i, j, k); + vec3d.xCoord += vec3d1.xCoord; + vec3d.yCoord += vec3d1.yCoord; + vec3d.zCoord += vec3d1.zCoord; + } + + public int tickRate() + { + if(blockMaterial == Material.water) + { + return 5; + } + return blockMaterial != Material.lava ? 0 : 30; + } + + public float getBlockBrightness(IBlockAccess iblockaccess, int i, int j, int k) + { + float f = iblockaccess.getLightBrightness(i, j, k); + float f1 = iblockaccess.getLightBrightness(i, j + 1, k); + return f <= f1 ? f1 : f; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + super.updateTick(world, i, j, k, random); + } + + public int getRenderBlockPass() + { + return blockMaterial != Material.water ? 0 : 1; + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(blockMaterial == Material.water && random.nextInt(64) == 0) + { + int l = world.getBlockMetadata(i, j, k); + if(l > 0 && l < 8) + { + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, "liquid.water", random.nextFloat() * 0.25F + 0.75F, random.nextFloat() * 1.0F + 0.5F); + } + } + if(blockMaterial == Material.lava && world.getBlockMaterial(i, j + 1, k) == Material.air && !world.isBlockOpaqueCube(i, j + 1, k) && random.nextInt(100) == 0) + { + double d = (float)i + random.nextFloat(); + double d1 = (double)j + maxY; + double d2 = (float)k + random.nextFloat(); + world.spawnParticle("lava", d, d1, d2, 0.0D, 0.0D, 0.0D); + } + } + + public static double func_293_a(IBlockAccess iblockaccess, int i, int j, int k, Material material) + { + Vec3D vec3d = null; + if(material == Material.water) + { + vec3d = ((BlockFluids)Block.waterStill).func_291_e(iblockaccess, i, j, k); + } + if(material == Material.lava) + { + vec3d = ((BlockFluids)Block.lavaStill).func_291_e(iblockaccess, i, j, k); + } + if(vec3d.xCoord == 0.0D && vec3d.zCoord == 0.0D) + { + return -1000D; + } else + { + return Math.atan2(vec3d.zCoord, vec3d.xCoord) - 1.5707963267948966D; + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + checkForHarden(world, i, j, k); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + checkForHarden(world, i, j, k); + } + + private void checkForHarden(World world, int i, int j, int k) + { + if(world.getBlockId(i, j, k) != blockID) + { + return; + } + if(blockMaterial == Material.lava) + { + boolean flag = false; + if(flag || world.getBlockMaterial(i, j, k - 1) == Material.water) + { + flag = true; + } + if(flag || world.getBlockMaterial(i, j, k + 1) == Material.water) + { + flag = true; + } + if(flag || world.getBlockMaterial(i - 1, j, k) == Material.water) + { + flag = true; + } + if(flag || world.getBlockMaterial(i + 1, j, k) == Material.water) + { + flag = true; + } + if(flag || world.getBlockMaterial(i, j + 1, k) == Material.water) + { + flag = true; + } + if(flag) + { + int l = world.getBlockMetadata(i, j, k); + if(l == 0) + { + world.setBlockWithNotify(i, j, k, Block.obsidian.blockID); + } else + if(l <= 4) + { + world.setBlockWithNotify(i, j, k, Block.cobblestone.blockID); + } + func_292_i(world, i, j, k); + } + } + } + + protected void func_292_i(World world, int i, int j, int k) + { + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F); + for(int l = 0; l < 8; l++) + { + world.spawnParticle("largesmoke", (double)i + Math.random(), (double)j + 1.2D, (double)k + Math.random(), 0.0D, 0.0D, 0.0D); + } + + } +} diff --git a/src/main/java/net/minecraft/src/BlockFurnace.java b/src/main/java/net/minecraft/src/BlockFurnace.java new file mode 100644 index 0000000..390e15b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockFurnace.java @@ -0,0 +1,187 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockFurnace extends BlockContainer +{ + + protected BlockFurnace(int i, boolean flag) + { + super(i, Material.rock); + isActive = flag; + blockIndexInTexture = 45; + } + + public int idDropped(int i, Random random) + { + return Block.stoneOvenIdle.blockID; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + super.onBlockAdded(world, i, j, k); + setDefaultDirection(world, i, j, k); + } + + private void setDefaultDirection(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j, k - 1); + int i1 = world.getBlockId(i, j, k + 1); + int j1 = world.getBlockId(i - 1, j, k); + int k1 = world.getBlockId(i + 1, j, k); + byte byte0 = 3; + if(Block.opaqueCubeLookup[l] && !Block.opaqueCubeLookup[i1]) + { + byte0 = 3; + } + if(Block.opaqueCubeLookup[i1] && !Block.opaqueCubeLookup[l]) + { + byte0 = 2; + } + if(Block.opaqueCubeLookup[j1] && !Block.opaqueCubeLookup[k1]) + { + byte0 = 5; + } + if(Block.opaqueCubeLookup[k1] && !Block.opaqueCubeLookup[j1]) + { + byte0 = 4; + } + world.setBlockMetadataWithNotify(i, j, k, byte0); + } + + public int getBlockTexture(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(l == 1) + { + return blockIndexInTexture + 17; + } + if(l == 0) + { + return blockIndexInTexture + 17; + } + int i1 = iblockaccess.getBlockMetadata(i, j, k); + if(l != i1) + { + return blockIndexInTexture; + } + if(isActive) + { + return blockIndexInTexture + 16; + } else + { + return blockIndexInTexture - 1; + } + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(!isActive) + { + return; + } + int l = world.getBlockMetadata(i, j, k); + float f = (float)i + 0.5F; + float f1 = (float)j + 0.0F + (random.nextFloat() * 6F) / 16F; + float f2 = (float)k + 0.5F; + float f3 = 0.52F; + float f4 = random.nextFloat() * 0.6F - 0.3F; + if(l == 4) + { + world.spawnParticle("smoke", f - f3, f1, f2 + f4, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", f - f3, f1, f2 + f4, 0.0D, 0.0D, 0.0D); + } else + if(l == 5) + { + world.spawnParticle("smoke", f + f3, f1, f2 + f4, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", f + f3, f1, f2 + f4, 0.0D, 0.0D, 0.0D); + } else + if(l == 2) + { + world.spawnParticle("smoke", f + f4, f1, f2 - f3, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", f + f4, f1, f2 - f3, 0.0D, 0.0D, 0.0D); + } else + if(l == 3) + { + world.spawnParticle("smoke", f + f4, f1, f2 + f3, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", f + f4, f1, f2 + f3, 0.0D, 0.0D, 0.0D); + } + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture + 17; + } + if(i == 0) + { + return blockIndexInTexture + 17; + } + if(i == 3) + { + return blockIndexInTexture - 1; + } else + { + return blockIndexInTexture; + } + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(world.multiplayerWorld) + { + return true; + } else + { + TileEntityFurnace tileentityfurnace = (TileEntityFurnace)world.getBlockTileEntity(i, j, k); + entityplayer.displayGUIFurnace(tileentityfurnace); + return true; + } + } + + public static void updateFurnaceBlockState(boolean flag, World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + TileEntity tileentity = world.getBlockTileEntity(i, j, k); + if(flag) + { + world.setBlockWithNotify(i, j, k, Block.stoneOvenActive.blockID); + } else + { + world.setBlockWithNotify(i, j, k, Block.stoneOvenIdle.blockID); + } + world.setBlockMetadataWithNotify(i, j, k, l); + world.setBlockTileEntity(i, j, k, tileentity); + } + + protected TileEntity getBlockEntity() + { + return new TileEntityFurnace(); + } + + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) + { + int l = MathHelper.floor_double((double)((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3; + if(l == 0) + { + world.setBlockMetadataWithNotify(i, j, k, 2); + } + if(l == 1) + { + world.setBlockMetadataWithNotify(i, j, k, 5); + } + if(l == 2) + { + world.setBlockMetadataWithNotify(i, j, k, 3); + } + if(l == 3) + { + world.setBlockMetadataWithNotify(i, j, k, 4); + } + } + + private final boolean isActive; +} diff --git a/src/main/java/net/minecraft/src/BlockGlass.java b/src/main/java/net/minecraft/src/BlockGlass.java new file mode 100644 index 0000000..24cf254 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGlass.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockGlass extends BlockBreakable +{ + + public BlockGlass(int i, int j, Material material, boolean flag) + { + super(i, j, material, flag); + } + + public int quantityDropped(Random random) + { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/BlockGrass.java b/src/main/java/net/minecraft/src/BlockGrass.java new file mode 100644 index 0000000..a9fce9a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGrass.java @@ -0,0 +1,70 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockGrass extends Block +{ + + protected BlockGrass(int i) + { + super(i, Material.ground); + blockIndexInTexture = 3; + setTickOnLoad(true); + } + + public int getBlockTexture(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(l == 1) + { + return 0; + } + if(l == 0) + { + return 2; + } + Material material = iblockaccess.getBlockMaterial(i, j + 1, k); + return material != Material.snow && material != Material.builtSnow ? 3 : 68; + } + + public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k) + { + iblockaccess.getWorldChunkManager().func_4069_a(i, k, 1, 1); + double d = iblockaccess.getWorldChunkManager().temperature[0]; + double d1 = iblockaccess.getWorldChunkManager().humidity[0]; + return ColorizerGrass.getGrassColor(d, d1); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.multiplayerWorld) + { + return; + } + if(world.getBlockLightValue(i, j + 1, k) < 4 && world.getBlockMaterial(i, j + 1, k).getCanBlockGrass()) + { + if(random.nextInt(4) != 0) + { + return; + } + world.setBlockWithNotify(i, j, k, Block.dirt.blockID); + } else + if(world.getBlockLightValue(i, j + 1, k) >= 9) + { + int l = (i + random.nextInt(3)) - 1; + int i1 = (j + random.nextInt(5)) - 3; + int j1 = (k + random.nextInt(3)) - 1; + if(world.getBlockId(l, i1, j1) == Block.dirt.blockID && world.getBlockLightValue(l, i1 + 1, j1) >= 4 && !world.getBlockMaterial(l, i1 + 1, j1).getCanBlockGrass()) + { + world.setBlockWithNotify(l, i1, j1, Block.grass.blockID); + } + } + } + + public int idDropped(int i, Random random) + { + return Block.dirt.idDropped(0, random); + } +} diff --git a/src/main/java/net/minecraft/src/BlockGravel.java b/src/main/java/net/minecraft/src/BlockGravel.java new file mode 100644 index 0000000..2966def --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockGravel.java @@ -0,0 +1,26 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockGravel extends BlockSand +{ + + public BlockGravel(int i, int j) + { + super(i, j); + } + + public int idDropped(int i, Random random) + { + if(random.nextInt(10) == 0) + { + return Item.flint.shiftedIndex; + } else + { + return blockID; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockIce.java b/src/main/java/net/minecraft/src/BlockIce.java new file mode 100644 index 0000000..83eb162 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockIce.java @@ -0,0 +1,50 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockIce extends BlockBreakable +{ + + public BlockIce(int i, int j) + { + super(i, j, Material.ice, false); + slipperiness = 0.98F; + setTickOnLoad(true); + } + + public int getRenderBlockPass() + { + return 1; + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return super.shouldSideBeRendered(iblockaccess, i, j, k, 1 - l); + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + Material material = world.getBlockMaterial(i, j - 1, k); + if(material.getIsSolid() || material.getIsLiquid()) + { + world.setBlockWithNotify(i, j, k, Block.waterStill.blockID); + } + } + + public int quantityDropped(Random random) + { + return 0; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.getSavedLightValue(EnumSkyBlock.Block, i, j, k) > 11 - Block.lightOpacity[blockID]) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, Block.waterMoving.blockID); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockJukeBox.java b/src/main/java/net/minecraft/src/BlockJukeBox.java new file mode 100644 index 0000000..5f61fc5 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockJukeBox.java @@ -0,0 +1,60 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockJukeBox extends Block +{ + + protected BlockJukeBox(int i, int j) + { + super(i, j, Material.wood); + } + + public int getBlockTextureFromSide(int i) + { + return blockIndexInTexture + (i != 1 ? 0 : 1); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + int l = world.getBlockMetadata(i, j, k); + if(l > 0) + { + ejectRecord(world, i, j, k, l); + return true; + } else + { + return false; + } + } + + public void ejectRecord(World world, int i, int j, int k, int l) + { + world.playRecord(null, i, j, k); + world.setBlockMetadataWithNotify(i, j, k, 0); + int i1 = (Item.record13.shiftedIndex + l) - 1; + float f = 0.7F; + double d = (double)(world.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D; + double d1 = (double)(world.rand.nextFloat() * f) + (double)(1.0F - f) * 0.20000000000000001D + 0.59999999999999998D; + double d2 = (double)(world.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D; + EntityItem entityitem = new EntityItem(world, (double)i + d, (double)j + d1, (double)k + d2, new ItemStack(i1, 1, 0)); + entityitem.delayBeforeCanPickup = 10; + world.entityJoinedWorld(entityitem); + } + + public void dropBlockAsItemWithChance(World world, int i, int j, int k, int l, float f) + { + if(world.multiplayerWorld) + { + return; + } + if(l > 0) + { + ejectRecord(world, i, j, k, l); + } + super.dropBlockAsItemWithChance(world, i, j, k, l, f); + } +} diff --git a/src/main/java/net/minecraft/src/BlockLadder.java b/src/main/java/net/minecraft/src/BlockLadder.java new file mode 100644 index 0000000..73b1e65 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLadder.java @@ -0,0 +1,148 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockLadder extends Block +{ + + protected BlockLadder(int i, int j) + { + super(i, j, Material.circuits); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + float f = 0.125F; + if(l == 2) + { + setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + } + if(l == 3) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + } + if(l == 4) + { + setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + if(l == 5) + { + setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + } + return super.getCollisionBoundingBoxFromPool(world, i, j, k); + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + float f = 0.125F; + if(l == 2) + { + setBlockBounds(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + } + if(l == 3) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + } + if(l == 4) + { + setBlockBounds(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + if(l == 5) + { + setBlockBounds(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + } + return super.getSelectedBoundingBoxFromPool(world, i, j, k); + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 8; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + return true; + } + return world.isBlockOpaqueCube(i, j, k + 1); + } + + public void onBlockPlaced(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + if((i1 == 0 || l == 2) && world.isBlockOpaqueCube(i, j, k + 1)) + { + i1 = 2; + } + if((i1 == 0 || l == 3) && world.isBlockOpaqueCube(i, j, k - 1)) + { + i1 = 3; + } + if((i1 == 0 || l == 4) && world.isBlockOpaqueCube(i + 1, j, k)) + { + i1 = 4; + } + if((i1 == 0 || l == 5) && world.isBlockOpaqueCube(i - 1, j, k)) + { + i1 = 5; + } + world.setBlockMetadataWithNotify(i, j, k, i1); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + boolean flag = false; + if(i1 == 2 && world.isBlockOpaqueCube(i, j, k + 1)) + { + flag = true; + } + if(i1 == 3 && world.isBlockOpaqueCube(i, j, k - 1)) + { + flag = true; + } + if(i1 == 4 && world.isBlockOpaqueCube(i + 1, j, k)) + { + flag = true; + } + if(i1 == 5 && world.isBlockOpaqueCube(i - 1, j, k)) + { + flag = true; + } + if(!flag) + { + dropBlockAsItem(world, i, j, k, i1); + world.setBlockWithNotify(i, j, k, 0); + } + super.onNeighborBlockChange(world, i, j, k, l); + } + + public int quantityDropped(Random random) + { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLeaves.java b/src/main/java/net/minecraft/src/BlockLeaves.java new file mode 100644 index 0000000..21e1aae --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLeaves.java @@ -0,0 +1,210 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockLeaves extends BlockLeavesBase +{ + + protected BlockLeaves(int i, int j) + { + super(i, j, Material.leaves, false); + baseIndexInPNG = j; + setTickOnLoad(true); + } + + public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k) + { + int l = iblockaccess.getBlockMetadata(i, j, k); + if((l & 1) == 1) + { + return ColorizerFoliage.func_21175_a(); + } + if((l & 2) == 2) + { + return ColorizerFoliage.func_21174_b(); + } else + { + iblockaccess.getWorldChunkManager().func_4069_a(i, k, 1, 1); + double d = iblockaccess.getWorldChunkManager().temperature[0]; + double d1 = iblockaccess.getWorldChunkManager().humidity[0]; + return ColorizerFoliage.getFoliageColor(d, d1); + } + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + int l = 1; + int i1 = l + 1; + if(world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) + { + for(int j1 = -l; j1 <= l; j1++) + { + for(int k1 = -l; k1 <= l; k1++) + { + for(int l1 = -l; l1 <= l; l1++) + { + int i2 = world.getBlockId(i + j1, j + k1, k + l1); + if(i2 == Block.leaves.blockID) + { + int j2 = world.getBlockMetadata(i + j1, j + k1, k + l1); + world.setBlockMetadata(i + j1, j + k1, k + l1, j2 | 4); + } + } + + } + + } + + } + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.multiplayerWorld) + { + return; + } + int l = world.getBlockMetadata(i, j, k); + if((l & 4) != 0) + { + byte byte0 = 4; + int i1 = byte0 + 1; + byte byte1 = 32; + int j1 = byte1 * byte1; + int k1 = byte1 / 2; + if(adjacentTreeBlocks == null) + { + adjacentTreeBlocks = new int[byte1 * byte1 * byte1]; + } + if(world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1)) + { + for(int l1 = -byte0; l1 <= byte0; l1++) + { + for(int k2 = -byte0; k2 <= byte0; k2++) + { + for(int i3 = -byte0; i3 <= byte0; i3++) + { + int k3 = world.getBlockId(i + l1, j + k2, k + i3); + if(k3 == Block.wood.blockID) + { + adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = 0; + continue; + } + if(k3 == Block.leaves.blockID) + { + adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -2; + } else + { + adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -1; + } + } + + } + + } + + for(int i2 = 1; i2 <= 4; i2++) + { + for(int l2 = -byte0; l2 <= byte0; l2++) + { + for(int j3 = -byte0; j3 <= byte0; j3++) + { + for(int l3 = -byte0; l3 <= byte0; l3++) + { + if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] != i2 - 1) + { + continue; + } + if(adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2) + { + adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2; + } + if(adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2) + { + adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2; + } + if(adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] == -2) + { + adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] = i2; + } + if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] == -2) + { + adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] = i2; + } + if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] == -2) + { + adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] = i2; + } + if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] == -2) + { + adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] = i2; + } + } + + } + + } + + } + + } + int j2 = adjacentTreeBlocks[k1 * j1 + k1 * byte1 + k1]; + if(j2 >= 0) + { + world.setBlockMetadataWithNotify(i, j, k, l & -5); + } else + { + removeLeaves(world, i, j, k); + } + } + } + + private void removeLeaves(World world, int i, int j, int k) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + + public int quantityDropped(Random random) + { + return random.nextInt(16) != 0 ? 0 : 1; + } + + public int idDropped(int i, Random random) + { + return Block.sapling.blockID; + } + + public boolean isOpaqueCube() + { + return !graphicsLevel; + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if((j & 3) == 1) + { + return blockIndexInTexture + 80; + } else + { + return blockIndexInTexture; + } + } + + public void setGraphicsLevel(boolean flag) + { + graphicsLevel = flag; + blockIndexInTexture = baseIndexInPNG + (flag ? 0 : 1); + } + + public void onEntityWalking(World world, int i, int j, int k, Entity entity) + { + super.onEntityWalking(world, i, j, k, entity); + } + + private int baseIndexInPNG; + int adjacentTreeBlocks[]; +} diff --git a/src/main/java/net/minecraft/src/BlockLeavesBase.java b/src/main/java/net/minecraft/src/BlockLeavesBase.java new file mode 100644 index 0000000..8a5eaf5 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLeavesBase.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockLeavesBase extends Block +{ + + protected BlockLeavesBase(int i, int j, Material material, boolean flag) + { + super(i, j, material); + graphicsLevel = flag; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + int i1 = iblockaccess.getBlockId(i, j, k); + if(!graphicsLevel && i1 == blockID) + { + return false; + } else + { + return super.shouldSideBeRendered(iblockaccess, i, j, k, l); + } + } + + protected boolean graphicsLevel; +} diff --git a/src/main/java/net/minecraft/src/BlockLever.java b/src/main/java/net/minecraft/src/BlockLever.java new file mode 100644 index 0000000..82538eb --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLever.java @@ -0,0 +1,264 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockLever extends Block +{ + + protected BlockLever(int i, int j) + { + super(i, j, Material.circuits); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 12; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + return true; + } + if(world.isBlockOpaqueCube(i, j, k + 1)) + { + return true; + } + return world.isBlockOpaqueCube(i, j - 1, k); + } + + public void onBlockPlaced(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + int j1 = i1 & 8; + i1 &= 7; + if(l == 1 && world.isBlockOpaqueCube(i, j - 1, k)) + { + i1 = 5 + world.rand.nextInt(2); + } + if(l == 2 && world.isBlockOpaqueCube(i, j, k + 1)) + { + i1 = 4; + } + if(l == 3 && world.isBlockOpaqueCube(i, j, k - 1)) + { + i1 = 3; + } + if(l == 4 && world.isBlockOpaqueCube(i + 1, j, k)) + { + i1 = 2; + } + if(l == 5 && world.isBlockOpaqueCube(i - 1, j, k)) + { + i1 = 1; + } + world.setBlockMetadataWithNotify(i, j, k, i1 + j1); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(checkIfAttachedToBlock(world, i, j, k)) + { + int i1 = world.getBlockMetadata(i, j, k) & 7; + boolean flag = false; + if(!world.isBlockOpaqueCube(i - 1, j, k) && i1 == 1) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i + 1, j, k) && i1 == 2) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j, k - 1) && i1 == 3) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j, k + 1) && i1 == 4) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j - 1, k) && i1 == 5) + { + flag = true; + } + if(flag) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + } + + private boolean checkIfAttachedToBlock(World world, int i, int j, int k) + { + if(!canPlaceBlockAt(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + return false; + } else + { + return true; + } + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + int l = iblockaccess.getBlockMetadata(i, j, k) & 7; + float f = 0.1875F; + if(l == 1) + { + setBlockBounds(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f); + } else + if(l == 2) + { + setBlockBounds(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f); + } else + if(l == 3) + { + setBlockBounds(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F); + } else + if(l == 4) + { + setBlockBounds(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F); + } else + { + float f1 = 0.25F; + setBlockBounds(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, 0.6F, 0.5F + f1); + } + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + blockActivated(world, i, j, k, entityplayer); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(world.multiplayerWorld) + { + return true; + } + int l = world.getBlockMetadata(i, j, k); + int i1 = l & 7; + int j1 = 8 - (l & 8); + world.setBlockMetadataWithNotify(i, j, k, i1 + j1); + world.markBlocksDirty(i, j, k, i, j, k); + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "random.click", 0.3F, j1 <= 0 ? 0.5F : 0.6F); + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + if(i1 == 1) + { + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + } else + if(i1 == 2) + { + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + } else + if(i1 == 3) + { + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + } else + if(i1 == 4) + { + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } else + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + } + return true; + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + if((l & 8) > 0) + { + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + int i1 = l & 7; + if(i1 == 1) + { + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + } else + if(i1 == 2) + { + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + } else + if(i1 == 3) + { + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + } else + if(i1 == 4) + { + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } else + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + } + } + super.onBlockRemoval(world, i, j, k); + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return (iblockaccess.getBlockMetadata(i, j, k) & 8) > 0; + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + if((i1 & 8) == 0) + { + return false; + } + int j1 = i1 & 7; + if(j1 == 5 && l == 1) + { + return true; + } + if(j1 == 4 && l == 2) + { + return true; + } + if(j1 == 3 && l == 3) + { + return true; + } + if(j1 == 2 && l == 4) + { + return true; + } + return j1 == 1 && l == 5; + } + + public boolean canProvidePower() + { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLightStone.java b/src/main/java/net/minecraft/src/BlockLightStone.java new file mode 100644 index 0000000..b467567 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLightStone.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockLightStone extends Block +{ + + public BlockLightStone(int i, int j, Material material) + { + super(i, j, material); + } + + public int idDropped(int i, Random random) + { + return Item.lightStoneDust.shiftedIndex; + } +} diff --git a/src/main/java/net/minecraft/src/BlockLog.java b/src/main/java/net/minecraft/src/BlockLog.java new file mode 100644 index 0000000..6ebc621 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockLog.java @@ -0,0 +1,79 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockLog extends Block +{ + + protected BlockLog(int i) + { + super(i, Material.wood); + blockIndexInTexture = 20; + } + + public int quantityDropped(Random random) + { + return 1; + } + + public int idDropped(int i, Random random) + { + return Block.wood.blockID; + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + byte byte0 = 4; + int l = byte0 + 1; + if(world.checkChunksExist(i - l, j - l, k - l, i + l, j + l, k + l)) + { + for(int i1 = -byte0; i1 <= byte0; i1++) + { + for(int j1 = -byte0; j1 <= byte0; j1++) + { + for(int k1 = -byte0; k1 <= byte0; k1++) + { + int l1 = world.getBlockId(i + i1, j + j1, k + k1); + if(l1 != Block.leaves.blockID) + { + continue; + } + int i2 = world.getBlockMetadata(i + i1, j + j1, k + k1); + if((i2 & 4) == 0) + { + world.setBlockMetadata(i + i1, j + j1, k + k1, i2 | 4); + } + } + + } + + } + + } + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 1) + { + return 21; + } + if(i == 0) + { + return 21; + } + if(j == 1) + { + return 116; + } + return j != 2 ? 20 : 117; + } + + protected int damageDropped(int i) + { + return i; + } +} diff --git a/src/main/java/net/minecraft/src/BlockMinecartTrack.java b/src/main/java/net/minecraft/src/BlockMinecartTrack.java new file mode 100644 index 0000000..4daf0db --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMinecartTrack.java @@ -0,0 +1,135 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockMinecartTrack extends Block +{ + + protected BlockMinecartTrack(int i, int j) + { + super(i, j, Material.circuits); + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public MovingObjectPosition collisionRayTrace(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) + { + setBlockBoundsBasedOnState(world, i, j, k); + return super.collisionRayTrace(world, i, j, k, vec3d, vec3d1); + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + int l = iblockaccess.getBlockMetadata(i, j, k); + if(l >= 2 && l <= 5) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + } else + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(j >= 6) + { + return blockIndexInTexture - 16; + } else + { + return blockIndexInTexture; + } + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 9; + } + + public int quantityDropped(Random random) + { + return 1; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + return world.isBlockOpaqueCube(i, j - 1, k); + } + + public void onBlockAdded(World world, int i, int j, int k) + { + if(!world.multiplayerWorld) + { + world.setBlockMetadataWithNotify(i, j, k, 15); + func_4031_h(world, i, j, k); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(world.multiplayerWorld) + { + return; + } + int i1 = world.getBlockMetadata(i, j, k); + boolean flag = false; + if(!world.isBlockOpaqueCube(i, j - 1, k)) + { + flag = true; + } + if(i1 == 2 && !world.isBlockOpaqueCube(i + 1, j, k)) + { + flag = true; + } + if(i1 == 3 && !world.isBlockOpaqueCube(i - 1, j, k)) + { + flag = true; + } + if(i1 == 4 && !world.isBlockOpaqueCube(i, j, k - 1)) + { + flag = true; + } + if(i1 == 5 && !world.isBlockOpaqueCube(i, j, k + 1)) + { + flag = true; + } + if(flag) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } else + if(l > 0 && Block.blocksList[l].canProvidePower() && MinecartTrackLogic.getNAdjacentTracks(new MinecartTrackLogic(this, world, i, j, k)) == 3) + { + func_4031_h(world, i, j, k); + } + } + + private void func_4031_h(World world, int i, int j, int k) + { + if(world.multiplayerWorld) + { + return; + } else + { + (new MinecartTrackLogic(this, world, i, j, k)).func_792_a(world.isBlockIndirectlyGettingPowered(i, j, k)); + return; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockMobSpawner.java b/src/main/java/net/minecraft/src/BlockMobSpawner.java new file mode 100644 index 0000000..95cdf7a --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMobSpawner.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockMobSpawner extends BlockContainer +{ + + protected BlockMobSpawner(int i, int j) + { + super(i, j, Material.rock); + } + + protected TileEntity getBlockEntity() + { + return new TileEntityMobSpawner(); + } + + public int idDropped(int i, Random random) + { + return 0; + } + + public int quantityDropped(Random random) + { + return 0; + } + + public boolean isOpaqueCube() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/BlockMushroom.java b/src/main/java/net/minecraft/src/BlockMushroom.java new file mode 100644 index 0000000..0ee9d6b --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockMushroom.java @@ -0,0 +1,26 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockMushroom extends BlockFlower +{ + + protected BlockMushroom(int i, int j) + { + super(i, j); + float f = 0.2F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); + } + + protected boolean canThisPlantGrowOnThisBlockID(int i) + { + return Block.opaqueCubeLookup[i]; + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + return world.getBlockLightValue(i, j, k) <= 13 && canThisPlantGrowOnThisBlockID(world.getBlockId(i, j - 1, k)); + } +} diff --git a/src/main/java/net/minecraft/src/BlockNote.java b/src/main/java/net/minecraft/src/BlockNote.java new file mode 100644 index 0000000..e73f197 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockNote.java @@ -0,0 +1,92 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockNote extends BlockContainer +{ + + public BlockNote(int i) + { + super(i, 74, Material.wood); + } + + public int getBlockTextureFromSide(int i) + { + return blockIndexInTexture; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(l > 0 && Block.blocksList[l].canProvidePower()) + { + boolean flag = world.isBlockGettingPowered(i, j, k); + TileEntityNote tileentitynote = (TileEntityNote)world.getBlockTileEntity(i, j, k); + if(tileentitynote.previousRedstoneState != flag) + { + if(flag) + { + tileentitynote.triggerNote(world, i, j, k); + } + tileentitynote.previousRedstoneState = flag; + } + } + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(world.multiplayerWorld) + { + return true; + } else + { + TileEntityNote tileentitynote = (TileEntityNote)world.getBlockTileEntity(i, j, k); + tileentitynote.changePitch(); + tileentitynote.triggerNote(world, i, j, k); + return true; + } + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(world.multiplayerWorld) + { + return; + } else + { + TileEntityNote tileentitynote = (TileEntityNote)world.getBlockTileEntity(i, j, k); + tileentitynote.triggerNote(world, i, j, k); + return; + } + } + + protected TileEntity getBlockEntity() + { + return new TileEntityNote(); + } + + public void playBlock(World world, int i, int j, int k, int l, int i1) + { + float f = (float)Math.pow(2D, (double)(i1 - 12) / 12D); + String s = "harp"; + if(l == 1) + { + s = "bd"; + } + if(l == 2) + { + s = "snare"; + } + if(l == 3) + { + s = "hat"; + } + if(l == 4) + { + s = "bassattack"; + } + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, (new StringBuilder()).append("note.").append(s).toString(), 3F, f); + world.spawnParticle("note", (double)i + 0.5D, (double)j + 1.2D, (double)k + 0.5D, (double)i1 / 24D, 0.0D, 0.0D); + } +} diff --git a/src/main/java/net/minecraft/src/BlockObsidian.java b/src/main/java/net/minecraft/src/BlockObsidian.java new file mode 100644 index 0000000..a43a7c6 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockObsidian.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockObsidian extends BlockStone +{ + + public BlockObsidian(int i, int j) + { + super(i, j); + } + + public int quantityDropped(Random random) + { + return 1; + } + + public int idDropped(int i, Random random) + { + return Block.obsidian.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockOre.java b/src/main/java/net/minecraft/src/BlockOre.java new file mode 100644 index 0000000..e6b8a9c --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockOre.java @@ -0,0 +1,50 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockOre extends Block +{ + + public BlockOre(int i, int j) + { + super(i, j, Material.rock); + } + + public int idDropped(int i, Random random) + { + if(blockID == Block.oreCoal.blockID) + { + return Item.coal.shiftedIndex; + } + if(blockID == Block.oreDiamond.blockID) + { + return Item.diamond.shiftedIndex; + } + if(blockID == Block.oreLapis.blockID) + { + return Item.dyePowder.shiftedIndex; + } else + { + return blockID; + } + } + + public int quantityDropped(Random random) + { + if(blockID == Block.oreLapis.blockID) + { + return 4 + random.nextInt(5); + } else + { + return 1; + } + } + + protected int damageDropped(int i) + { + return blockID != Block.oreLapis.blockID ? 0 : 4; + } +} diff --git a/src/main/java/net/minecraft/src/BlockOreBlock.java b/src/main/java/net/minecraft/src/BlockOreBlock.java new file mode 100644 index 0000000..68486e3 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockOreBlock.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockOreBlock extends Block +{ + + public BlockOreBlock(int i, int j) + { + super(i, Material.iron); + blockIndexInTexture = j; + } + + public int getBlockTextureFromSide(int i) + { + return blockIndexInTexture; + } +} diff --git a/src/main/java/net/minecraft/src/BlockPortal.java b/src/main/java/net/minecraft/src/BlockPortal.java new file mode 100644 index 0000000..200bd11 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPortal.java @@ -0,0 +1,207 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.Random; + +public class BlockPortal extends BlockBreakable +{ + + public BlockPortal(int i, int j) + { + super(i, j, Material.portal, false); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + if(iblockaccess.getBlockId(i - 1, j, k) == blockID || iblockaccess.getBlockId(i + 1, j, k) == blockID) + { + float f = 0.5F; + float f2 = 0.125F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f2, 0.5F + f, 1.0F, 0.5F + f2); + } else + { + float f1 = 0.125F; + float f3 = 0.5F; + setBlockBounds(0.5F - f1, 0.0F, 0.5F - f3, 0.5F + f1, 1.0F, 0.5F + f3); + } + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean tryToCreatePortal(World world, int i, int j, int k) + { + int l = 0; + int i1 = 0; + if(world.getBlockId(i - 1, j, k) == Block.obsidian.blockID || world.getBlockId(i + 1, j, k) == Block.obsidian.blockID) + { + l = 1; + } + if(world.getBlockId(i, j, k - 1) == Block.obsidian.blockID || world.getBlockId(i, j, k + 1) == Block.obsidian.blockID) + { + i1 = 1; + } + System.out.println((new StringBuilder()).append(l).append(", ").append(i1).toString()); + if(l == i1) + { + return false; + } + if(world.getBlockId(i - l, j, k - i1) == 0) + { + i -= l; + k -= i1; + } + for(int j1 = -1; j1 <= 2; j1++) + { + for(int l1 = -1; l1 <= 3; l1++) + { + boolean flag = j1 == -1 || j1 == 2 || l1 == -1 || l1 == 3; + if((j1 == -1 || j1 == 2) && (l1 == -1 || l1 == 3)) + { + continue; + } + int j2 = world.getBlockId(i + l * j1, j + l1, k + i1 * j1); + if(flag) + { + if(j2 != Block.obsidian.blockID) + { + return false; + } + continue; + } + if(j2 != 0 && j2 != Block.fire.blockID) + { + return false; + } + } + + } + + world.field_1043_h = true; + for(int k1 = 0; k1 < 2; k1++) + { + for(int i2 = 0; i2 < 3; i2++) + { + world.setBlockWithNotify(i + l * k1, j + i2, k + i1 * k1, Block.portal.blockID); + } + + } + + world.field_1043_h = false; + return true; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + int i1 = 0; + int j1 = 1; + if(world.getBlockId(i - 1, j, k) == blockID || world.getBlockId(i + 1, j, k) == blockID) + { + i1 = 1; + j1 = 0; + } + int k1; + for(k1 = j; world.getBlockId(i, k1 - 1, k) == blockID; k1--) { } + if(world.getBlockId(i, k1 - 1, k) != Block.obsidian.blockID) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } + int l1; + for(l1 = 1; l1 < 4 && world.getBlockId(i, k1 + l1, k) == blockID; l1++) { } + if(l1 != 3 || world.getBlockId(i, k1 + l1, k) != Block.obsidian.blockID) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } + boolean flag = world.getBlockId(i - 1, j, k) == blockID || world.getBlockId(i + 1, j, k) == blockID; + boolean flag1 = world.getBlockId(i, j, k - 1) == blockID || world.getBlockId(i, j, k + 1) == blockID; + if(flag && flag1) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } + if((world.getBlockId(i + i1, j, k + j1) != Block.obsidian.blockID || world.getBlockId(i - i1, j, k - j1) != blockID) && (world.getBlockId(i - i1, j, k - j1) != Block.obsidian.blockID || world.getBlockId(i + i1, j, k + j1) != blockID)) + { + world.setBlockWithNotify(i, j, k, 0); + return; + } else + { + return; + } + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return true; + } + + public int quantityDropped(Random random) + { + return 0; + } + + public int getRenderBlockPass() + { + return 1; + } + + public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) + { + if(world.multiplayerWorld) + { + return; + } else + { + entity.setInPortal(); + return; + } + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(random.nextInt(100) == 0) + { + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "portal.portal", 1.0F, random.nextFloat() * 0.4F + 0.8F); + } + for(int l = 0; l < 4; l++) + { + double d = (float)i + random.nextFloat(); + double d1 = (float)j + random.nextFloat(); + double d2 = (float)k + random.nextFloat(); + double d3 = 0.0D; + double d4 = 0.0D; + double d5 = 0.0D; + int i1 = random.nextInt(2) * 2 - 1; + d3 = ((double)random.nextFloat() - 0.5D) * 0.5D; + d4 = ((double)random.nextFloat() - 0.5D) * 0.5D; + d5 = ((double)random.nextFloat() - 0.5D) * 0.5D; + if(world.getBlockId(i - 1, j, k) == blockID || world.getBlockId(i + 1, j, k) == blockID) + { + d2 = (double)k + 0.5D + 0.25D * (double)i1; + d5 = random.nextFloat() * 2.0F * (float)i1; + } else + { + d = (double)i + 0.5D + 0.25D * (double)i1; + d3 = random.nextFloat() * 2.0F * (float)i1; + } + world.spawnParticle("portal", d, d1, d2, d3, d4, d5); + } + + } +} diff --git a/src/main/java/net/minecraft/src/BlockPressurePlate.java b/src/main/java/net/minecraft/src/BlockPressurePlate.java new file mode 100644 index 0000000..4ea2cca --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPressurePlate.java @@ -0,0 +1,194 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class BlockPressurePlate extends Block +{ + + protected BlockPressurePlate(int i, int j, EnumMobType enummobtype) + { + super(i, j, Material.rock); + triggerMobType = enummobtype; + setTickOnLoad(true); + float f = 0.0625F; + setBlockBounds(f, 0.0F, f, 1.0F - f, 0.03125F, 1.0F - f); + } + + public int tickRate() + { + return 20; + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + return world.isBlockOpaqueCube(i, j - 1, k); + } + + public void onBlockAdded(World world, int i, int j, int k) + { + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + boolean flag = false; + if(!world.isBlockOpaqueCube(i, j - 1, k)) + { + flag = true; + } + if(flag) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.multiplayerWorld) + { + return; + } + if(world.getBlockMetadata(i, j, k) == 0) + { + return; + } else + { + setStateIfMobInteractsWithPlate(world, i, j, k); + return; + } + } + + public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) + { + if(world.multiplayerWorld) + { + return; + } + if(world.getBlockMetadata(i, j, k) == 1) + { + return; + } else + { + setStateIfMobInteractsWithPlate(world, i, j, k); + return; + } + } + + private void setStateIfMobInteractsWithPlate(World world, int i, int j, int k) + { + boolean flag = world.getBlockMetadata(i, j, k) == 1; + boolean flag1 = false; + float f = 0.125F; + List list = null; + if(triggerMobType == EnumMobType.everything) + { + list = world.getEntitiesWithinAABBExcludingEntity(null, AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, (double)j + 0.25D, (float)(k + 1) - f)); + } + if(triggerMobType == EnumMobType.mobs) + { + list = world.getEntitiesWithinAABB(EntityLiving.class, AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, (double)j + 0.25D, (float)(k + 1) - f)); + } + if(triggerMobType == EnumMobType.players) + { + list = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, (double)j + 0.25D, (float)(k + 1) - f)); + } + if(list.size() > 0) + { + flag1 = true; + } + if(flag1 && !flag) + { + world.setBlockMetadataWithNotify(i, j, k, 1); + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + world.markBlocksDirty(i, j, k, i, j, k); + world.playSoundEffect((double)i + 0.5D, (double)j + 0.10000000000000001D, (double)k + 0.5D, "random.click", 0.3F, 0.6F); + } + if(!flag1 && flag) + { + world.setBlockMetadataWithNotify(i, j, k, 0); + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + world.markBlocksDirty(i, j, k, i, j, k); + world.playSoundEffect((double)i + 0.5D, (double)j + 0.10000000000000001D, (double)k + 0.5D, "random.click", 0.3F, 0.5F); + } + if(flag1) + { + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + if(l > 0) + { + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + } + super.onBlockRemoval(world, i, j, k); + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + boolean flag = iblockaccess.getBlockMetadata(i, j, k) == 1; + float f = 0.0625F; + if(flag) + { + setBlockBounds(f, 0.0F, f, 1.0F - f, 0.03125F, 1.0F - f); + } else + { + setBlockBounds(f, 0.0F, f, 1.0F - f, 0.0625F, 1.0F - f); + } + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return iblockaccess.getBlockMetadata(i, j, k) > 0; + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + if(world.getBlockMetadata(i, j, k) == 0) + { + return false; + } else + { + return l == 1; + } + } + + public boolean canProvidePower() + { + return true; + } + + public void func_237_e() + { + float f = 0.5F; + float f1 = 0.125F; + float f2 = 0.5F; + setBlockBounds(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2); + } + + private EnumMobType triggerMobType; +} diff --git a/src/main/java/net/minecraft/src/BlockPumpkin.java b/src/main/java/net/minecraft/src/BlockPumpkin.java new file mode 100644 index 0000000..d79acf5 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockPumpkin.java @@ -0,0 +1,91 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockPumpkin extends Block +{ + + protected BlockPumpkin(int i, int j, boolean flag) + { + super(i, Material.pumpkin); + blockIndexInTexture = j; + setTickOnLoad(true); + blockType = flag; + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 1) + { + return blockIndexInTexture; + } + if(i == 0) + { + return blockIndexInTexture; + } + int k = blockIndexInTexture + 1 + 16; + if(blockType) + { + k++; + } + if(j == 0 && i == 2) + { + return k; + } + if(j == 1 && i == 5) + { + return k; + } + if(j == 2 && i == 3) + { + return k; + } + if(j == 3 && i == 4) + { + return k; + } else + { + return blockIndexInTexture + 16; + } + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture; + } + if(i == 0) + { + return blockIndexInTexture; + } + if(i == 3) + { + return blockIndexInTexture + 1 + 16; + } else + { + return blockIndexInTexture + 16; + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + super.onBlockAdded(world, i, j, k); + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j, k); + return (l == 0 || Block.blocksList[l].blockMaterial.getIsLiquid()) && world.isBlockOpaqueCube(i, j - 1, k); + } + + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) + { + int l = MathHelper.floor_double((double)((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3; + world.setBlockMetadataWithNotify(i, j, k, l); + } + + private boolean blockType; +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneOre.java b/src/main/java/net/minecraft/src/BlockRedstoneOre.java new file mode 100644 index 0000000..8bf2af3 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneOre.java @@ -0,0 +1,121 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockRedstoneOre extends Block +{ + + public BlockRedstoneOre(int i, int j, boolean flag) + { + super(i, j, Material.rock); + if(flag) + { + setTickOnLoad(true); + } + field_468_a = flag; + } + + public int tickRate() + { + return 30; + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + func_320_h(world, i, j, k); + super.onBlockClicked(world, i, j, k, entityplayer); + } + + public void onEntityWalking(World world, int i, int j, int k, Entity entity) + { + func_320_h(world, i, j, k); + super.onEntityWalking(world, i, j, k, entity); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + func_320_h(world, i, j, k); + return super.blockActivated(world, i, j, k, entityplayer); + } + + private void func_320_h(World world, int i, int j, int k) + { + func_319_i(world, i, j, k); + if(blockID == Block.oreRedstone.blockID) + { + world.setBlockWithNotify(i, j, k, Block.oreRedstoneGlowing.blockID); + } + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(blockID == Block.oreRedstoneGlowing.blockID) + { + world.setBlockWithNotify(i, j, k, Block.oreRedstone.blockID); + } + } + + public int idDropped(int i, Random random) + { + return Item.redstone.shiftedIndex; + } + + public int quantityDropped(Random random) + { + return 4 + random.nextInt(2); + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(field_468_a) + { + func_319_i(world, i, j, k); + } + } + + private void func_319_i(World world, int i, int j, int k) + { + Random random = world.rand; + double d = 0.0625D; + for(int l = 0; l < 6; l++) + { + double d1 = (float)i + random.nextFloat(); + double d2 = (float)j + random.nextFloat(); + double d3 = (float)k + random.nextFloat(); + if(l == 0 && !world.isBlockOpaqueCube(i, j + 1, k)) + { + d2 = (double)(j + 1) + d; + } + if(l == 1 && !world.isBlockOpaqueCube(i, j - 1, k)) + { + d2 = (double)(j + 0) - d; + } + if(l == 2 && !world.isBlockOpaqueCube(i, j, k + 1)) + { + d3 = (double)(k + 1) + d; + } + if(l == 3 && !world.isBlockOpaqueCube(i, j, k - 1)) + { + d3 = (double)(k + 0) - d; + } + if(l == 4 && !world.isBlockOpaqueCube(i + 1, j, k)) + { + d1 = (double)(i + 1) + d; + } + if(l == 5 && !world.isBlockOpaqueCube(i - 1, j, k)) + { + d1 = (double)(i + 0) - d; + } + if(d1 < (double)i || d1 > (double)(i + 1) || d2 < 0.0D || d2 > (double)(j + 1) || d3 < (double)k || d3 > (double)(k + 1)) + { + world.spawnParticle("reddust", d1, d2, d3, 0.0D, 0.0D, 0.0D); + } + } + + } + + private boolean field_468_a; +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java b/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java new file mode 100644 index 0000000..5de1619 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java @@ -0,0 +1,272 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockRedstoneRepeater extends Block +{ + + protected BlockRedstoneRepeater(int i, boolean flag) + { + super(i, 102, Material.circuits); + field_22025_c = flag; + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(!world.isBlockOpaqueCube(i, j - 1, k)) + { + return false; + } else + { + return super.canPlaceBlockAt(world, i, j, k); + } + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + if(!world.isBlockOpaqueCube(i, j - 1, k)) + { + return false; + } else + { + return super.canBlockStay(world, i, j, k); + } + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + int l = world.getBlockMetadata(i, j, k); + boolean flag = func_22022_g(world, i, j, k, l); + if(field_22025_c && !flag) + { + world.setBlockAndMetadataWithNotify(i, j, k, Block.field_22021_bh.blockID, l); + } else + if(!field_22025_c) + { + world.setBlockAndMetadataWithNotify(i, j, k, Block.field_22020_bi.blockID, l); + if(!flag) + { + int i1 = (l & 0xc) >> 2; + world.scheduleBlockUpdate(i, j, k, Block.field_22020_bi.blockID, field_22023_b[i1] * 2); + } + } + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 0) + { + return !field_22025_c ? 115 : 99; + } + if(i == 1) + { + return !field_22025_c ? 131 : 147; + } else + { + return 5; + } + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return l != 0 && l != 1; + } + + public int getRenderType() + { + return 15; + } + + public int getBlockTextureFromSide(int i) + { + return getBlockTextureFromSideAndMetadata(i, 0); + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + return isPoweringTo(world, i, j, k, l); + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(!field_22025_c) + { + return false; + } + int i1 = iblockaccess.getBlockMetadata(i, j, k) & 3; + if(i1 == 0 && l == 3) + { + return true; + } + if(i1 == 1 && l == 4) + { + return true; + } + if(i1 == 2 && l == 2) + { + return true; + } + return i1 == 3 && l == 5; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(!canBlockStay(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + return; + } + int i1 = world.getBlockMetadata(i, j, k); + boolean flag = func_22022_g(world, i, j, k, i1); + int j1 = (i1 & 0xc) >> 2; + if(field_22025_c && !flag) + { + world.scheduleBlockUpdate(i, j, k, blockID, field_22023_b[j1] * 2); + } else + if(!field_22025_c && flag) + { + world.scheduleBlockUpdate(i, j, k, blockID, field_22023_b[j1] * 2); + } + } + + private boolean func_22022_g(World world, int i, int j, int k, int l) + { + int i1 = l & 3; + switch(i1) + { + case 0: // '\0' + return world.isBlockIndirectlyProvidingPowerTo(i, j, k + 1, 3); + + case 2: // '\002' + return world.isBlockIndirectlyProvidingPowerTo(i, j, k - 1, 2); + + case 3: // '\003' + return world.isBlockIndirectlyProvidingPowerTo(i + 1, j, k, 5); + + case 1: // '\001' + return world.isBlockIndirectlyProvidingPowerTo(i - 1, j, k, 4); + } + return false; + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + int l = world.getBlockMetadata(i, j, k); + int i1 = (l & 0xc) >> 2; + i1 = i1 + 1 << 2 & 0xc; + world.setBlockMetadataWithNotify(i, j, k, i1 | l & 3); + return true; + } + + public boolean canProvidePower() + { + return false; + } + + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) + { + int l = ((MathHelper.floor_double((double)((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3) + 2) % 4; + world.setBlockMetadataWithNotify(i, j, k, l); + boolean flag = func_22022_g(world, i, j, k, l); + if(flag) + { + world.scheduleBlockUpdate(i, j, k, blockID, 1); + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + world.notifyBlocksOfNeighborChange(i, j + 1, k, blockID); + } + + public boolean isOpaqueCube() + { + return false; + } + + public int idDropped(int i, Random random) + { + return Item.field_22018_aZ.shiftedIndex; + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(!field_22025_c) + { + return; + } + int l = world.getBlockMetadata(i, j, k); + double d = (double)((float)i + 0.5F) + (double)(random.nextFloat() - 0.5F) * 0.20000000000000001D; + double d1 = (double)((float)j + 0.4F) + (double)(random.nextFloat() - 0.5F) * 0.20000000000000001D; + double d2 = (double)((float)k + 0.5F) + (double)(random.nextFloat() - 0.5F) * 0.20000000000000001D; + double d3 = 0.0D; + double d4 = 0.0D; + if(random.nextInt(2) == 0) + { + switch(l & 3) + { + case 0: // '\0' + d4 = -0.3125D; + break; + + case 2: // '\002' + d4 = 0.3125D; + break; + + case 3: // '\003' + d3 = -0.3125D; + break; + + case 1: // '\001' + d3 = 0.3125D; + break; + } + } else + { + int i1 = (l & 0xc) >> 2; + switch(l & 3) + { + case 0: // '\0' + d4 = field_22024_a[i1]; + break; + + case 2: // '\002' + d4 = -field_22024_a[i1]; + break; + + case 3: // '\003' + d3 = field_22024_a[i1]; + break; + + case 1: // '\001' + d3 = -field_22024_a[i1]; + break; + } + } + world.spawnParticle("reddust", d + d3, d1, d2 + d4, 0.0D, 0.0D, 0.0D); + } + + public static final double field_22024_a[] = { + -0.0625D, 0.0625D, 0.1875D, 0.3125D + }; + private static final int field_22023_b[] = { + 1, 2, 3, 4 + }; + private final boolean field_22025_c; + +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneTorch.java b/src/main/java/net/minecraft/src/BlockRedstoneTorch.java new file mode 100644 index 0000000..abbe7c0 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneTorch.java @@ -0,0 +1,224 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class BlockRedstoneTorch extends BlockTorch +{ + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 1) + { + return Block.redstoneWire.getBlockTextureFromSideAndMetadata(i, j); + } else + { + return super.getBlockTextureFromSideAndMetadata(i, j); + } + } + + private boolean checkForBurnout(World world, int i, int j, int k, boolean flag) + { + if(flag) + { + torchUpdates.add(new RedstoneUpdateInfo(i, j, k, world.func_22139_r())); + } + int l = 0; + for(int i1 = 0; i1 < torchUpdates.size(); i1++) + { + RedstoneUpdateInfo redstoneupdateinfo = (RedstoneUpdateInfo)torchUpdates.get(i1); + if(redstoneupdateinfo.x == i && redstoneupdateinfo.y == j && redstoneupdateinfo.z == k && ++l >= 8) + { + return true; + } + } + + return false; + } + + protected BlockRedstoneTorch(int i, int j, boolean flag) + { + super(i, j); + torchActive = false; + torchActive = flag; + setTickOnLoad(true); + } + + public int tickRate() + { + return 2; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + if(world.getBlockMetadata(i, j, k) == 0) + { + super.onBlockAdded(world, i, j, k); + } + if(torchActive) + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + world.notifyBlocksOfNeighborChange(i, j + 1, k, blockID); + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + if(torchActive) + { + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + world.notifyBlocksOfNeighborChange(i, j + 1, k, blockID); + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + } + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(!torchActive) + { + return false; + } + int i1 = iblockaccess.getBlockMetadata(i, j, k); + if(i1 == 5 && l == 1) + { + return false; + } + if(i1 == 3 && l == 3) + { + return false; + } + if(i1 == 4 && l == 2) + { + return false; + } + if(i1 == 1 && l == 5) + { + return false; + } + return i1 != 2 || l != 4; + } + + private boolean func_22026_h(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + if(l == 5 && world.isBlockIndirectlyProvidingPowerTo(i, j - 1, k, 0)) + { + return true; + } + if(l == 3 && world.isBlockIndirectlyProvidingPowerTo(i, j, k - 1, 2)) + { + return true; + } + if(l == 4 && world.isBlockIndirectlyProvidingPowerTo(i, j, k + 1, 3)) + { + return true; + } + if(l == 1 && world.isBlockIndirectlyProvidingPowerTo(i - 1, j, k, 4)) + { + return true; + } + return l == 2 && world.isBlockIndirectlyProvidingPowerTo(i + 1, j, k, 5); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + boolean flag = func_22026_h(world, i, j, k); + for(; torchUpdates.size() > 0 && world.func_22139_r() - ((RedstoneUpdateInfo)torchUpdates.get(0)).updateTime > 100L; torchUpdates.remove(0)) { } + if(torchActive) + { + if(flag) + { + world.setBlockAndMetadataWithNotify(i, j, k, Block.torchRedstoneIdle.blockID, world.getBlockMetadata(i, j, k)); + if(checkForBurnout(world, i, j, k, true)) + { + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F); + for(int l = 0; l < 5; l++) + { + double d = (double)i + random.nextDouble() * 0.59999999999999998D + 0.20000000000000001D; + double d1 = (double)j + random.nextDouble() * 0.59999999999999998D + 0.20000000000000001D; + double d2 = (double)k + random.nextDouble() * 0.59999999999999998D + 0.20000000000000001D; + world.spawnParticle("smoke", d, d1, d2, 0.0D, 0.0D, 0.0D); + } + + } + } + } else + if(!flag && !checkForBurnout(world, i, j, k, false)) + { + world.setBlockAndMetadataWithNotify(i, j, k, Block.torchRedstoneActive.blockID, world.getBlockMetadata(i, j, k)); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + super.onNeighborBlockChange(world, i, j, k, l); + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + if(l == 0) + { + return isPoweringTo(world, i, j, k, l); + } else + { + return false; + } + } + + public int idDropped(int i, Random random) + { + return Block.torchRedstoneActive.blockID; + } + + public boolean canProvidePower() + { + return true; + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + if(!torchActive) + { + return; + } + int l = world.getBlockMetadata(i, j, k); + double d = (double)((float)i + 0.5F) + (double)(random.nextFloat() - 0.5F) * 0.20000000000000001D; + double d1 = (double)((float)j + 0.7F) + (double)(random.nextFloat() - 0.5F) * 0.20000000000000001D; + double d2 = (double)((float)k + 0.5F) + (double)(random.nextFloat() - 0.5F) * 0.20000000000000001D; + double d3 = 0.2199999988079071D; + double d4 = 0.27000001072883606D; + if(l == 1) + { + world.spawnParticle("reddust", d - d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + } else + if(l == 2) + { + world.spawnParticle("reddust", d + d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + } else + if(l == 3) + { + world.spawnParticle("reddust", d, d1 + d3, d2 - d4, 0.0D, 0.0D, 0.0D); + } else + if(l == 4) + { + world.spawnParticle("reddust", d, d1 + d3, d2 + d4, 0.0D, 0.0D, 0.0D); + } else + { + world.spawnParticle("reddust", d, d1, d2, 0.0D, 0.0D, 0.0D); + } + } + + private boolean torchActive; + private static List torchUpdates = new ArrayList(); + +} diff --git a/src/main/java/net/minecraft/src/BlockRedstoneWire.java b/src/main/java/net/minecraft/src/BlockRedstoneWire.java new file mode 100644 index 0000000..4de90db --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockRedstoneWire.java @@ -0,0 +1,449 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class BlockRedstoneWire extends Block +{ + + public BlockRedstoneWire(int i, int j) + { + super(i, j, Material.circuits); + wiresProvidePower = true; + field_21031_b = new HashSet(); + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + return blockIndexInTexture; + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 5; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + return world.isBlockOpaqueCube(i, j - 1, k); + } + + private void updateAndPropagateCurrentStrength(World world, int i, int j, int k) + { + func_21030_a(world, i, j, k, i, j, k); + ArrayList arraylist = new ArrayList(field_21031_b); + field_21031_b.clear(); + for(int l = 0; l < arraylist.size(); l++) + { + ChunkPosition chunkposition = (ChunkPosition)arraylist.get(l); + world.notifyBlocksOfNeighborChange(chunkposition.x, chunkposition.y, chunkposition.z, blockID); + } + + } + + private void func_21030_a(World world, int i, int j, int k, int l, int i1, int j1) + { + int k1 = world.getBlockMetadata(i, j, k); + int l1 = 0; + wiresProvidePower = false; + boolean flag = world.isBlockIndirectlyGettingPowered(i, j, k); + wiresProvidePower = true; + if(flag) + { + l1 = 15; + } else + { + for(int i2 = 0; i2 < 4; i2++) + { + int k2 = i; + int i3 = k; + if(i2 == 0) + { + k2--; + } + if(i2 == 1) + { + k2++; + } + if(i2 == 2) + { + i3--; + } + if(i2 == 3) + { + i3++; + } + if(k2 != l || j != i1 || i3 != j1) + { + l1 = getMaxCurrentStrength(world, k2, j, i3, l1); + } + if(world.isBlockOpaqueCube(k2, j, i3) && !world.isBlockOpaqueCube(i, j + 1, k)) + { + if(k2 != l || j + 1 != i1 || i3 != j1) + { + l1 = getMaxCurrentStrength(world, k2, j + 1, i3, l1); + } + continue; + } + if(!world.isBlockOpaqueCube(k2, j, i3) && (k2 != l || j - 1 != i1 || i3 != j1)) + { + l1 = getMaxCurrentStrength(world, k2, j - 1, i3, l1); + } + } + + if(l1 > 0) + { + l1--; + } else + { + l1 = 0; + } + } + if(k1 != l1) + { + world.field_1043_h = true; + world.setBlockMetadataWithNotify(i, j, k, l1); + world.markBlocksDirty(i, j, k, i, j, k); + world.field_1043_h = false; + for(int j2 = 0; j2 < 4; j2++) + { + int l2 = i; + int j3 = k; + int k3 = j - 1; + if(j2 == 0) + { + l2--; + } + if(j2 == 1) + { + l2++; + } + if(j2 == 2) + { + j3--; + } + if(j2 == 3) + { + j3++; + } + if(world.isBlockOpaqueCube(l2, j, j3)) + { + k3 += 2; + } + int l3 = 0; + l3 = getMaxCurrentStrength(world, l2, j, j3, -1); + l1 = world.getBlockMetadata(i, j, k); + if(l1 > 0) + { + l1--; + } + if(l3 >= 0 && l3 != l1) + { + func_21030_a(world, l2, j, j3, i, j, k); + } + l3 = getMaxCurrentStrength(world, l2, k3, j3, -1); + l1 = world.getBlockMetadata(i, j, k); + if(l1 > 0) + { + l1--; + } + if(l3 >= 0 && l3 != l1) + { + func_21030_a(world, l2, k3, j3, i, j, k); + } + } + + if(k1 == 0 || l1 == 0) + { + field_21031_b.add(new ChunkPosition(i, j, k)); + field_21031_b.add(new ChunkPosition(i - 1, j, k)); + field_21031_b.add(new ChunkPosition(i + 1, j, k)); + field_21031_b.add(new ChunkPosition(i, j - 1, k)); + field_21031_b.add(new ChunkPosition(i, j + 1, k)); + field_21031_b.add(new ChunkPosition(i, j, k - 1)); + field_21031_b.add(new ChunkPosition(i, j, k + 1)); + } + } + } + + private void notifyWireNeighborsOfNeighborChange(World world, int i, int j, int k) + { + if(world.getBlockId(i, j, k) != blockID) + { + return; + } else + { + world.notifyBlocksOfNeighborChange(i, j, k, blockID); + world.notifyBlocksOfNeighborChange(i - 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i + 1, j, k, blockID); + world.notifyBlocksOfNeighborChange(i, j, k - 1, blockID); + world.notifyBlocksOfNeighborChange(i, j, k + 1, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + world.notifyBlocksOfNeighborChange(i, j + 1, k, blockID); + return; + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + super.onBlockAdded(world, i, j, k); + if(world.multiplayerWorld) + { + return; + } + updateAndPropagateCurrentStrength(world, i, j, k); + world.notifyBlocksOfNeighborChange(i, j + 1, k, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + notifyWireNeighborsOfNeighborChange(world, i - 1, j, k); + notifyWireNeighborsOfNeighborChange(world, i + 1, j, k); + notifyWireNeighborsOfNeighborChange(world, i, j, k - 1); + notifyWireNeighborsOfNeighborChange(world, i, j, k + 1); + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + notifyWireNeighborsOfNeighborChange(world, i - 1, j + 1, k); + } else + { + notifyWireNeighborsOfNeighborChange(world, i - 1, j - 1, k); + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + notifyWireNeighborsOfNeighborChange(world, i + 1, j + 1, k); + } else + { + notifyWireNeighborsOfNeighborChange(world, i + 1, j - 1, k); + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + notifyWireNeighborsOfNeighborChange(world, i, j + 1, k - 1); + } else + { + notifyWireNeighborsOfNeighborChange(world, i, j - 1, k - 1); + } + if(world.isBlockOpaqueCube(i, j, k + 1)) + { + notifyWireNeighborsOfNeighborChange(world, i, j + 1, k + 1); + } else + { + notifyWireNeighborsOfNeighborChange(world, i, j - 1, k + 1); + } + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + super.onBlockRemoval(world, i, j, k); + if(world.multiplayerWorld) + { + return; + } + world.notifyBlocksOfNeighborChange(i, j + 1, k, blockID); + world.notifyBlocksOfNeighborChange(i, j - 1, k, blockID); + updateAndPropagateCurrentStrength(world, i, j, k); + notifyWireNeighborsOfNeighborChange(world, i - 1, j, k); + notifyWireNeighborsOfNeighborChange(world, i + 1, j, k); + notifyWireNeighborsOfNeighborChange(world, i, j, k - 1); + notifyWireNeighborsOfNeighborChange(world, i, j, k + 1); + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + notifyWireNeighborsOfNeighborChange(world, i - 1, j + 1, k); + } else + { + notifyWireNeighborsOfNeighborChange(world, i - 1, j - 1, k); + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + notifyWireNeighborsOfNeighborChange(world, i + 1, j + 1, k); + } else + { + notifyWireNeighborsOfNeighborChange(world, i + 1, j - 1, k); + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + notifyWireNeighborsOfNeighborChange(world, i, j + 1, k - 1); + } else + { + notifyWireNeighborsOfNeighborChange(world, i, j - 1, k - 1); + } + if(world.isBlockOpaqueCube(i, j, k + 1)) + { + notifyWireNeighborsOfNeighborChange(world, i, j + 1, k + 1); + } else + { + notifyWireNeighborsOfNeighborChange(world, i, j - 1, k + 1); + } + } + + private int getMaxCurrentStrength(World world, int i, int j, int k, int l) + { + if(world.getBlockId(i, j, k) != blockID) + { + return l; + } + int i1 = world.getBlockMetadata(i, j, k); + if(i1 > l) + { + return i1; + } else + { + return l; + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(world.multiplayerWorld) + { + return; + } + int i1 = world.getBlockMetadata(i, j, k); + boolean flag = canPlaceBlockAt(world, i, j, k); + if(!flag) + { + dropBlockAsItem(world, i, j, k, i1); + world.setBlockWithNotify(i, j, k, 0); + } else + { + updateAndPropagateCurrentStrength(world, i, j, k); + } + super.onNeighborBlockChange(world, i, j, k, l); + } + + public int idDropped(int i, Random random) + { + return Item.redstone.shiftedIndex; + } + + public boolean isIndirectlyPoweringTo(World world, int i, int j, int k, int l) + { + if(!wiresProvidePower) + { + return false; + } else + { + return isPoweringTo(world, i, j, k, l); + } + } + + public boolean isPoweringTo(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(!wiresProvidePower) + { + return false; + } + if(iblockaccess.getBlockMetadata(i, j, k) == 0) + { + return false; + } + if(l == 1) + { + return true; + } + boolean flag = isPowerProviderOrWire(iblockaccess, i - 1, j, k) || !iblockaccess.isBlockOpaqueCube(i - 1, j, k) && isPowerProviderOrWire(iblockaccess, i - 1, j - 1, k); + boolean flag1 = isPowerProviderOrWire(iblockaccess, i + 1, j, k) || !iblockaccess.isBlockOpaqueCube(i + 1, j, k) && isPowerProviderOrWire(iblockaccess, i + 1, j - 1, k); + boolean flag2 = isPowerProviderOrWire(iblockaccess, i, j, k - 1) || !iblockaccess.isBlockOpaqueCube(i, j, k - 1) && isPowerProviderOrWire(iblockaccess, i, j - 1, k - 1); + boolean flag3 = isPowerProviderOrWire(iblockaccess, i, j, k + 1) || !iblockaccess.isBlockOpaqueCube(i, j, k + 1) && isPowerProviderOrWire(iblockaccess, i, j - 1, k + 1); + if(!iblockaccess.isBlockOpaqueCube(i, j + 1, k)) + { + if(iblockaccess.isBlockOpaqueCube(i - 1, j, k) && isPowerProviderOrWire(iblockaccess, i - 1, j + 1, k)) + { + flag = true; + } + if(iblockaccess.isBlockOpaqueCube(i + 1, j, k) && isPowerProviderOrWire(iblockaccess, i + 1, j + 1, k)) + { + flag1 = true; + } + if(iblockaccess.isBlockOpaqueCube(i, j, k - 1) && isPowerProviderOrWire(iblockaccess, i, j + 1, k - 1)) + { + flag2 = true; + } + if(iblockaccess.isBlockOpaqueCube(i, j, k + 1) && isPowerProviderOrWire(iblockaccess, i, j + 1, k + 1)) + { + flag3 = true; + } + } + if(!flag2 && !flag1 && !flag && !flag3 && l >= 2 && l <= 5) + { + return true; + } + if(l == 2 && flag2 && !flag && !flag1) + { + return true; + } + if(l == 3 && flag3 && !flag && !flag1) + { + return true; + } + if(l == 4 && flag && !flag2 && !flag3) + { + return true; + } + return l == 5 && flag1 && !flag2 && !flag3; + } + + public boolean canProvidePower() + { + return wiresProvidePower; + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + int l = world.getBlockMetadata(i, j, k); + if(l > 0) + { + double d = (double)i + 0.5D + ((double)random.nextFloat() - 0.5D) * 0.20000000000000001D; + double d1 = (float)j + 0.0625F; + double d2 = (double)k + 0.5D + ((double)random.nextFloat() - 0.5D) * 0.20000000000000001D; + float f = (float)l / 15F; + float f1 = f * 0.6F + 0.4F; + if(l == 0) + { + f1 = 0.0F; + } + float f2 = f * f * 0.7F - 0.5F; + float f3 = f * f * 0.6F - 0.7F; + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f3 < 0.0F) + { + f3 = 0.0F; + } + world.spawnParticle("reddust", d, d1, d2, f1, f2, f3); + } + } + + public static boolean isPowerProviderOrWire(IBlockAccess iblockaccess, int i, int j, int k) + { + int l = iblockaccess.getBlockId(i, j, k); + if(l == Block.redstoneWire.blockID) + { + return true; + } + if(l == 0) + { + return false; + } + return Block.blocksList[l].canProvidePower(); + } + + private boolean wiresProvidePower; + private Set field_21031_b; +} diff --git a/src/main/java/net/minecraft/src/BlockReed.java b/src/main/java/net/minecraft/src/BlockReed.java new file mode 100644 index 0000000..c2c3e44 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockReed.java @@ -0,0 +1,110 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockReed extends Block +{ + + protected BlockReed(int i, int j) + { + super(i, Material.plants); + blockIndexInTexture = j; + float f = 0.375F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f); + setTickOnLoad(true); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.isAirBlock(i, j + 1, k)) + { + int l; + for(l = 1; world.getBlockId(i, j - l, k) == blockID; l++) { } + if(l < 3) + { + int i1 = world.getBlockMetadata(i, j, k); + if(i1 == 15) + { + world.setBlockWithNotify(i, j + 1, k, blockID); + world.setBlockMetadataWithNotify(i, j, k, 0); + } else + { + world.setBlockMetadataWithNotify(i, j, k, i1 + 1); + } + } + } + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j - 1, k); + if(l == blockID) + { + return true; + } + if(l != Block.grass.blockID && l != Block.dirt.blockID) + { + return false; + } + if(world.getBlockMaterial(i - 1, j - 1, k) == Material.water) + { + return true; + } + if(world.getBlockMaterial(i + 1, j - 1, k) == Material.water) + { + return true; + } + if(world.getBlockMaterial(i, j - 1, k - 1) == Material.water) + { + return true; + } + return world.getBlockMaterial(i, j - 1, k + 1) == Material.water; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + checkBlockCoordValid(world, i, j, k); + } + + protected final void checkBlockCoordValid(World world, int i, int j, int k) + { + if(!canBlockStay(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public boolean canBlockStay(World world, int i, int j, int k) + { + return canPlaceBlockAt(world, i, j, k); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public int idDropped(int i, Random random) + { + return Item.reed.shiftedIndex; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 1; + } +} diff --git a/src/main/java/net/minecraft/src/BlockSand.java b/src/main/java/net/minecraft/src/BlockSand.java new file mode 100644 index 0000000..b0ca21e --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSand.java @@ -0,0 +1,81 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockSand extends Block +{ + + public BlockSand(int i, int j) + { + super(i, j, Material.sand); + } + + public void onBlockAdded(World world, int i, int j, int k) + { + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + world.scheduleBlockUpdate(i, j, k, blockID, tickRate()); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + tryToFall(world, i, j, k); + } + + private void tryToFall(World world, int i, int j, int k) + { + int l = i; + int i1 = j; + int j1 = k; + if(canFallBelow(world, l, i1 - 1, j1) && i1 >= 0) + { + byte byte0 = 32; + if(fallInstantly || !world.checkChunksExist(i - byte0, j - byte0, k - byte0, i + byte0, j + byte0, k + byte0)) + { + world.setBlockWithNotify(i, j, k, 0); + for(; canFallBelow(world, i, j - 1, k) && j > 0; j--) { } + if(j > 0) + { + world.setBlockWithNotify(i, j, k, blockID); + } + } else + { + EntityFallingSand entityfallingsand = new EntityFallingSand(world, (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, blockID); + world.entityJoinedWorld(entityfallingsand); + } + } + } + + public int tickRate() + { + return 3; + } + + public static boolean canFallBelow(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j, k); + if(l == 0) + { + return true; + } + if(l == Block.fire.blockID) + { + return true; + } + Material material = Block.blocksList[l].blockMaterial; + if(material == Material.water) + { + return true; + } + return material == Material.lava; + } + + public static boolean fallInstantly = false; + +} diff --git a/src/main/java/net/minecraft/src/BlockSandStone.java b/src/main/java/net/minecraft/src/BlockSandStone.java new file mode 100644 index 0000000..5198521 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSandStone.java @@ -0,0 +1,29 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockSandStone extends Block +{ + + public BlockSandStone(int i) + { + super(i, 192, Material.rock); + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture - 16; + } + if(i == 0) + { + return blockIndexInTexture + 16; + } else + { + return blockIndexInTexture; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSapling.java b/src/main/java/net/minecraft/src/BlockSapling.java new file mode 100644 index 0000000..85c4b44 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSapling.java @@ -0,0 +1,47 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockSapling extends BlockFlower +{ + + protected BlockSapling(int i, int j) + { + super(i, j); + float f = 0.4F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + super.updateTick(world, i, j, k, random); + if(world.getBlockLightValue(i, j + 1, k) >= 9 && random.nextInt(5) == 0) + { + int l = world.getBlockMetadata(i, j, k); + if(l < 15) + { + world.setBlockMetadataWithNotify(i, j, k, l + 1); + } else + { + growTree(world, i, j, k, random); + } + } + } + + public void growTree(World world, int i, int j, int k, Random random) + { + world.setBlock(i, j, k, 0); + Object obj = new WorldGenTrees(); + if(random.nextInt(10) == 0) + { + obj = new WorldGenBigTree(); + } + if(!((WorldGenerator) (obj)).generate(world, random, i, j, k)) + { + world.setBlock(i, j, k, blockID); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSign.java b/src/main/java/net/minecraft/src/BlockSign.java new file mode 100644 index 0000000..63f154e --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSign.java @@ -0,0 +1,136 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockSign extends BlockContainer +{ + + protected BlockSign(int i, Class class1, boolean flag) + { + super(i, Material.wood); + isFreestanding = flag; + blockIndexInTexture = 4; + signEntityClass = class1; + float f = 0.25F; + float f1 = 1.0F; + setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + setBlockBoundsBasedOnState(world, i, j, k); + return super.getSelectedBoundingBoxFromPool(world, i, j, k); + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + if(isFreestanding) + { + return; + } + int l = iblockaccess.getBlockMetadata(i, j, k); + float f = 0.28125F; + float f1 = 0.78125F; + float f2 = 0.0F; + float f3 = 1.0F; + float f4 = 0.125F; + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + if(l == 2) + { + setBlockBounds(f2, f, 1.0F - f4, f3, f1, 1.0F); + } + if(l == 3) + { + setBlockBounds(f2, f, 0.0F, f3, f1, f4); + } + if(l == 4) + { + setBlockBounds(1.0F - f4, f, f2, 1.0F, f1, f3); + } + if(l == 5) + { + setBlockBounds(0.0F, f, f2, f4, f1, f3); + } + } + + public int getRenderType() + { + return -1; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean isOpaqueCube() + { + return false; + } + + protected TileEntity getBlockEntity() + { + try + { + return (TileEntity)signEntityClass.newInstance(); + } + catch(Exception exception) + { + throw new RuntimeException(exception); + } + } + + public int idDropped(int i, Random random) + { + return Item.sign.shiftedIndex; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + boolean flag = false; + if(isFreestanding) + { + if(!world.getBlockMaterial(i, j - 1, k).isSolid()) + { + flag = true; + } + } else + { + int i1 = world.getBlockMetadata(i, j, k); + flag = true; + if(i1 == 2 && world.getBlockMaterial(i, j, k + 1).isSolid()) + { + flag = false; + } + if(i1 == 3 && world.getBlockMaterial(i, j, k - 1).isSolid()) + { + flag = false; + } + if(i1 == 4 && world.getBlockMaterial(i + 1, j, k).isSolid()) + { + flag = false; + } + if(i1 == 5 && world.getBlockMaterial(i - 1, j, k).isSolid()) + { + flag = false; + } + } + if(flag) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + super.onNeighborBlockChange(world, i, j, k, l); + } + + private Class signEntityClass; + private boolean isFreestanding; +} diff --git a/src/main/java/net/minecraft/src/BlockSlowSand.java b/src/main/java/net/minecraft/src/BlockSlowSand.java new file mode 100644 index 0000000..a0a3591 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSlowSand.java @@ -0,0 +1,26 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockSlowSand extends Block +{ + + public BlockSlowSand(int i, int j) + { + super(i, j, Material.sand); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + float f = 0.125F; + return AxisAlignedBB.getBoundingBoxFromPool(i, j, k, i + 1, (float)(j + 1) - f, k + 1); + } + + public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) + { + entity.motionX *= 0.40000000000000002D; + entity.motionZ *= 0.40000000000000002D; + } +} diff --git a/src/main/java/net/minecraft/src/BlockSnow.java b/src/main/java/net/minecraft/src/BlockSnow.java new file mode 100644 index 0000000..bfe386d --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSnow.java @@ -0,0 +1,110 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockSnow extends Block +{ + + protected BlockSnow(int i, int j) + { + super(i, j, Material.snow); + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + setTickOnLoad(true); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + int l = world.getBlockId(i, j - 1, k); + if(l == 0 || !Block.blocksList[l].isOpaqueCube()) + { + return false; + } else + { + return world.getBlockMaterial(i, j - 1, k).getIsSolid(); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + func_314_h(world, i, j, k); + } + + private boolean func_314_h(World world, int i, int j, int k) + { + if(!canPlaceBlockAt(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + return false; + } else + { + return true; + } + } + + public void harvestBlock(World world, int i, int j, int k, int l) + { + int i1 = Item.snowball.shiftedIndex; + float f = 0.7F; + double d = (double)(world.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D; + double d1 = (double)(world.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D; + double d2 = (double)(world.rand.nextFloat() * f) + (double)(1.0F - f) * 0.5D; + EntityItem entityitem = new EntityItem(world, (double)i + d, (double)j + d1, (double)k + d2, new ItemStack(i1, 1, 0)); + entityitem.delayBeforeCanPickup = 10; + world.entityJoinedWorld(entityitem); + world.setBlockWithNotify(i, j, k, 0); + } + + public int idDropped(int i, Random random) + { + return Item.snowball.shiftedIndex; + } + + public int quantityDropped(Random random) + { + return 0; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.getSavedLightValue(EnumSkyBlock.Block, i, j, k) > 11) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + Material material = iblockaccess.getBlockMaterial(i, j, k); + if(l == 1) + { + return true; + } + if(material == blockMaterial) + { + return false; + } else + { + return super.shouldSideBeRendered(iblockaccess, i, j, k, l); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSnowBlock.java b/src/main/java/net/minecraft/src/BlockSnowBlock.java new file mode 100644 index 0000000..a975e41 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSnowBlock.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockSnowBlock extends Block +{ + + protected BlockSnowBlock(int i, int j) + { + super(i, j, Material.builtSnow); + setTickOnLoad(true); + } + + public int idDropped(int i, Random random) + { + return Item.snowball.shiftedIndex; + } + + public int quantityDropped(Random random) + { + return 4; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(world.getSavedLightValue(EnumSkyBlock.Block, i, j, k) > 11) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockSoil.java b/src/main/java/net/minecraft/src/BlockSoil.java new file mode 100644 index 0000000..2324855 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSoil.java @@ -0,0 +1,133 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockSoil extends Block +{ + + protected BlockSoil(int i) + { + super(i, Material.ground); + blockIndexInTexture = 87; + setTickOnLoad(true); + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); + setLightOpacity(255); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return AxisAlignedBB.getBoundingBoxFromPool(i + 0, j + 0, k + 0, i + 1, j + 1, k + 1); + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(i == 1 && j > 0) + { + return blockIndexInTexture - 1; + } + if(i == 1) + { + return blockIndexInTexture; + } else + { + return 2; + } + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(random.nextInt(5) == 0) + { + if(isWaterNearby(world, i, j, k)) + { + world.setBlockMetadataWithNotify(i, j, k, 7); + } else + { + int l = world.getBlockMetadata(i, j, k); + if(l > 0) + { + world.setBlockMetadataWithNotify(i, j, k, l - 1); + } else + if(!isCropsNearby(world, i, j, k)) + { + world.setBlockWithNotify(i, j, k, Block.dirt.blockID); + } + } + } + } + + public void onEntityWalking(World world, int i, int j, int k, Entity entity) + { + if(world.rand.nextInt(4) == 0) + { + world.setBlockWithNotify(i, j, k, Block.dirt.blockID); + } + } + + private boolean isCropsNearby(World world, int i, int j, int k) + { + int l = 0; + for(int i1 = i - l; i1 <= i + l; i1++) + { + for(int j1 = k - l; j1 <= k + l; j1++) + { + if(world.getBlockId(i1, j + 1, j1) == Block.crops.blockID) + { + return true; + } + } + + } + + return false; + } + + private boolean isWaterNearby(World world, int i, int j, int k) + { + for(int l = i - 4; l <= i + 4; l++) + { + for(int i1 = j; i1 <= j + 1; i1++) + { + for(int j1 = k - 4; j1 <= k + 4; j1++) + { + if(world.getBlockMaterial(l, i1, j1) == Material.water) + { + return true; + } + } + + } + + } + + return false; + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + super.onNeighborBlockChange(world, i, j, k, l); + Material material = world.getBlockMaterial(i, j + 1, k); + if(material.isSolid()) + { + world.setBlockWithNotify(i, j, k, Block.dirt.blockID); + } + } + + public int idDropped(int i, Random random) + { + return Block.dirt.idDropped(0, random); + } +} diff --git a/src/main/java/net/minecraft/src/BlockSponge.java b/src/main/java/net/minecraft/src/BlockSponge.java new file mode 100644 index 0000000..11c8257 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockSponge.java @@ -0,0 +1,51 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockSponge extends Block +{ + + protected BlockSponge(int i) + { + super(i, Material.sponge); + blockIndexInTexture = 48; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + byte byte0 = 2; + for(int l = i - byte0; l <= i + byte0; l++) + { + for(int i1 = j - byte0; i1 <= j + byte0; i1++) + { + for(int j1 = k - byte0; j1 <= k + byte0; j1++) + { + if(world.getBlockMaterial(l, i1, j1) != Material.water); + } + + } + + } + + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + byte byte0 = 2; + for(int l = i - byte0; l <= i + byte0; l++) + { + for(int i1 = j - byte0; i1 <= j + byte0; i1++) + { + for(int j1 = k - byte0; j1 <= k + byte0; j1++) + { + world.notifyBlocksOfNeighborChange(l, i1, j1, world.getBlockId(l, i1, j1)); + } + + } + + } + + } +} diff --git a/src/main/java/net/minecraft/src/BlockStairs.java b/src/main/java/net/minecraft/src/BlockStairs.java new file mode 100644 index 0000000..8d8bb36 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStairs.java @@ -0,0 +1,233 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.ArrayList; +import java.util.Random; + +public class BlockStairs extends Block +{ + + protected BlockStairs(int i, Block block) + { + super(i, block.blockIndexInTexture, block.blockMaterial); + modelBlock = block; + setHardness(block.blockHardness); + setResistance(block.blockResistance / 3F); + setStepSound(block.stepSound); + } + + public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return super.getCollisionBoundingBoxFromPool(world, i, j, k); + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 10; + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return super.shouldSideBeRendered(iblockaccess, i, j, k, l); + } + + public void getCollidingBoundingBoxes(World world, int i, int j, int k, AxisAlignedBB axisalignedbb, ArrayList arraylist) + { + int l = world.getBlockMetadata(i, j, k); + if(l == 0) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 0.5F, 0.5F, 1.0F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + setBlockBounds(0.5F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + } else + if(l == 1) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 0.5F, 1.0F, 1.0F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + setBlockBounds(0.5F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + } else + if(l == 2) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 0.5F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + setBlockBounds(0.0F, 0.0F, 0.5F, 1.0F, 1.0F, 1.0F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + } else + if(l == 3) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + setBlockBounds(0.0F, 0.0F, 0.5F, 1.0F, 0.5F, 1.0F); + super.getCollidingBoundingBoxes(world, i, j, k, axisalignedbb, arraylist); + } + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + modelBlock.randomDisplayTick(world, i, j, k, random); + } + + public void onBlockClicked(World world, int i, int j, int k, EntityPlayer entityplayer) + { + modelBlock.onBlockClicked(world, i, j, k, entityplayer); + } + + public void onBlockDestroyedByPlayer(World world, int i, int j, int k, int l) + { + modelBlock.onBlockDestroyedByPlayer(world, i, j, k, l); + } + + public float getBlockBrightness(IBlockAccess iblockaccess, int i, int j, int k) + { + return modelBlock.getBlockBrightness(iblockaccess, i, j, k); + } + + public float getExplosionResistance(Entity entity) + { + return modelBlock.getExplosionResistance(entity); + } + + public int getRenderBlockPass() + { + return modelBlock.getRenderBlockPass(); + } + + public int idDropped(int i, Random random) + { + return modelBlock.idDropped(i, random); + } + + public int quantityDropped(Random random) + { + return modelBlock.quantityDropped(random); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + return modelBlock.getBlockTextureFromSideAndMetadata(i, j); + } + + public int getBlockTextureFromSide(int i) + { + return modelBlock.getBlockTextureFromSide(i); + } + + public int getBlockTexture(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + return modelBlock.getBlockTexture(iblockaccess, i, j, k, l); + } + + public int tickRate() + { + return modelBlock.tickRate(); + } + + public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) + { + return modelBlock.getSelectedBoundingBoxFromPool(world, i, j, k); + } + + public void velocityToAddToEntity(World world, int i, int j, int k, Entity entity, Vec3D vec3d) + { + modelBlock.velocityToAddToEntity(world, i, j, k, entity, vec3d); + } + + public boolean isCollidable() + { + return modelBlock.isCollidable(); + } + + public boolean canCollideCheck(int i, boolean flag) + { + return modelBlock.canCollideCheck(i, flag); + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + return modelBlock.canPlaceBlockAt(world, i, j, k); + } + + public void onBlockAdded(World world, int i, int j, int k) + { + onNeighborBlockChange(world, i, j, k, 0); + modelBlock.onBlockAdded(world, i, j, k); + } + + public void onBlockRemoval(World world, int i, int j, int k) + { + modelBlock.onBlockRemoval(world, i, j, k); + } + + public void dropBlockAsItemWithChance(World world, int i, int j, int k, int l, float f) + { + modelBlock.dropBlockAsItemWithChance(world, i, j, k, l, f); + } + + public void dropBlockAsItem(World world, int i, int j, int k, int l) + { + modelBlock.dropBlockAsItem(world, i, j, k, l); + } + + public void onEntityWalking(World world, int i, int j, int k, Entity entity) + { + modelBlock.onEntityWalking(world, i, j, k, entity); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + modelBlock.updateTick(world, i, j, k, random); + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + return modelBlock.blockActivated(world, i, j, k, entityplayer); + } + + public void onBlockDestroyedByExplosion(World world, int i, int j, int k) + { + modelBlock.onBlockDestroyedByExplosion(world, i, j, k); + } + + public void onBlockPlacedBy(World world, int i, int j, int k, EntityLiving entityliving) + { + int l = MathHelper.floor_double((double)((entityliving.rotationYaw * 4F) / 360F) + 0.5D) & 3; + if(l == 0) + { + world.setBlockMetadataWithNotify(i, j, k, 2); + } + if(l == 1) + { + world.setBlockMetadataWithNotify(i, j, k, 1); + } + if(l == 2) + { + world.setBlockMetadataWithNotify(i, j, k, 3); + } + if(l == 3) + { + world.setBlockMetadataWithNotify(i, j, k, 0); + } + } + + private Block modelBlock; +} diff --git a/src/main/java/net/minecraft/src/BlockStationary.java b/src/main/java/net/minecraft/src/BlockStationary.java new file mode 100644 index 0000000..a124096 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStationary.java @@ -0,0 +1,73 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockStationary extends BlockFluids +{ + + protected BlockStationary(int i, Material material) + { + super(i, material); + setTickOnLoad(false); + if(material == Material.lava) + { + setTickOnLoad(true); + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + super.onNeighborBlockChange(world, i, j, k, l); + if(world.getBlockId(i, j, k) == blockID) + { + func_22035_j(world, i, j, k); + } + } + + private void func_22035_j(World world, int i, int j, int k) + { + int l = world.getBlockMetadata(i, j, k); + world.field_1043_h = true; + world.setBlockAndMetadata(i, j, k, blockID - 1, l); + world.markBlocksDirty(i, j, k, i, j, k); + world.scheduleBlockUpdate(i, j, k, blockID - 1, tickRate()); + world.field_1043_h = false; + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + if(blockMaterial == Material.lava) + { + int l = random.nextInt(3); + for(int i1 = 0; i1 < l; i1++) + { + i += random.nextInt(3) - 1; + j++; + k += random.nextInt(3) - 1; + int j1 = world.getBlockId(i, j, k); + if(j1 == 0) + { + if(func_301_k(world, i - 1, j, k) || func_301_k(world, i + 1, j, k) || func_301_k(world, i, j, k - 1) || func_301_k(world, i, j, k + 1) || func_301_k(world, i, j - 1, k) || func_301_k(world, i, j + 1, k)) + { + world.setBlockWithNotify(i, j, k, Block.fire.blockID); + return; + } + continue; + } + if(Block.blocksList[j1].blockMaterial.getIsSolid()) + { + return; + } + } + + } + } + + private boolean func_301_k(World world, int i, int j, int k) + { + return world.getBlockMaterial(i, j, k).getBurning(); + } +} diff --git a/src/main/java/net/minecraft/src/BlockStep.java b/src/main/java/net/minecraft/src/BlockStep.java new file mode 100644 index 0000000..98b69f3 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStep.java @@ -0,0 +1,121 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockStep extends Block +{ + + public BlockStep(int i, boolean flag) + { + super(i, 6, Material.rock); + blockType = flag; + if(!flag) + { + setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + setLightOpacity(255); + } + + public int getBlockTextureFromSideAndMetadata(int i, int j) + { + if(j == 0) + { + return i > 1 ? 5 : 6; + } + if(j == 1) + { + if(i == 0) + { + return 208; + } + return i != 1 ? 192 : 176; + } + if(j == 2) + { + return 4; + } + return j != 3 ? 6 : 16; + } + + public int getBlockTextureFromSide(int i) + { + return getBlockTextureFromSideAndMetadata(i, 0); + } + + public boolean isOpaqueCube() + { + return blockType; + } + + public void onBlockAdded(World world, int i, int j, int k) + { + if(this != Block.stairSingle) + { + super.onBlockAdded(world, i, j, k); + } + int l = world.getBlockId(i, j - 1, k); + int i1 = world.getBlockMetadata(i, j, k); + int j1 = world.getBlockMetadata(i, j - 1, k); + if(i1 != j1) + { + return; + } + if(l == stairSingle.blockID) + { + world.setBlockWithNotify(i, j, k, 0); + world.setBlockAndMetadataWithNotify(i, j - 1, k, Block.stairDouble.blockID, i1); + } + } + + public int idDropped(int i, Random random) + { + return Block.stairSingle.blockID; + } + + public int quantityDropped(Random random) + { + return !blockType ? 1 : 2; + } + + protected int damageDropped(int i) + { + return i; + } + + public boolean renderAsNormalBlock() + { + return blockType; + } + + public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) + { + if(this != Block.stairSingle) + { + super.shouldSideBeRendered(iblockaccess, i, j, k, l); + } + if(l == 1) + { + return true; + } + if(!super.shouldSideBeRendered(iblockaccess, i, j, k, l)) + { + return false; + } + if(l == 0) + { + return true; + } else + { + return iblockaccess.getBlockId(i, j, k) != blockID; + } + } + + public static final String field_22037_a[] = { + "stone", "sand", "wood", "cobble" + }; + private boolean blockType; + +} diff --git a/src/main/java/net/minecraft/src/BlockStone.java b/src/main/java/net/minecraft/src/BlockStone.java new file mode 100644 index 0000000..0417255 --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockStone.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockStone extends Block +{ + + public BlockStone(int i, int j) + { + super(i, j, Material.rock); + } + + public int idDropped(int i, Random random) + { + return Block.cobblestone.blockID; + } +} diff --git a/src/main/java/net/minecraft/src/BlockTNT.java b/src/main/java/net/minecraft/src/BlockTNT.java new file mode 100644 index 0000000..7f2d32c --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTNT.java @@ -0,0 +1,65 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockTNT extends Block +{ + + public BlockTNT(int i, int j) + { + super(i, j, Material.tnt); + } + + public int getBlockTextureFromSide(int i) + { + if(i == 0) + { + return blockIndexInTexture + 2; + } + if(i == 1) + { + return blockIndexInTexture + 1; + } else + { + return blockIndexInTexture; + } + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(l > 0 && Block.blocksList[l].canProvidePower() && world.isBlockIndirectlyGettingPowered(i, j, k)) + { + onBlockDestroyedByPlayer(world, i, j, k, 0); + world.setBlockWithNotify(i, j, k, 0); + } + } + + public int quantityDropped(Random random) + { + return 0; + } + + public void onBlockDestroyedByExplosion(World world, int i, int j, int k) + { + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F); + entitytntprimed.fuse = world.rand.nextInt(entitytntprimed.fuse / 4) + entitytntprimed.fuse / 8; + world.entityJoinedWorld(entitytntprimed); + } + + public void onBlockDestroyedByPlayer(World world, int i, int j, int k, int l) + { + if(world.multiplayerWorld) + { + return; + } else + { + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F); + world.entityJoinedWorld(entitytntprimed); + world.playSoundAtEntity(entitytntprimed, "random.fuse", 1.0F, 1.0F); + return; + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockTorch.java b/src/main/java/net/minecraft/src/BlockTorch.java new file mode 100644 index 0000000..aecb1ab --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockTorch.java @@ -0,0 +1,225 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class BlockTorch extends Block +{ + + protected BlockTorch(int i, int j) + { + super(i, j, Material.circuits); + setTickOnLoad(true); + } + + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) + { + return null; + } + + public boolean isOpaqueCube() + { + return false; + } + + public boolean renderAsNormalBlock() + { + return false; + } + + public int getRenderType() + { + return 2; + } + + public boolean canPlaceBlockAt(World world, int i, int j, int k) + { + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + return true; + } + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + return true; + } + if(world.isBlockOpaqueCube(i, j, k + 1)) + { + return true; + } + return world.isBlockOpaqueCube(i, j - 1, k); + } + + public void onBlockPlaced(World world, int i, int j, int k, int l) + { + int i1 = world.getBlockMetadata(i, j, k); + if(l == 1 && world.isBlockOpaqueCube(i, j - 1, k)) + { + i1 = 5; + } + if(l == 2 && world.isBlockOpaqueCube(i, j, k + 1)) + { + i1 = 4; + } + if(l == 3 && world.isBlockOpaqueCube(i, j, k - 1)) + { + i1 = 3; + } + if(l == 4 && world.isBlockOpaqueCube(i + 1, j, k)) + { + i1 = 2; + } + if(l == 5 && world.isBlockOpaqueCube(i - 1, j, k)) + { + i1 = 1; + } + world.setBlockMetadataWithNotify(i, j, k, i1); + } + + public void updateTick(World world, int i, int j, int k, Random random) + { + super.updateTick(world, i, j, k, random); + if(world.getBlockMetadata(i, j, k) == 0) + { + onBlockAdded(world, i, j, k); + } + } + + public void onBlockAdded(World world, int i, int j, int k) + { + if(world.isBlockOpaqueCube(i - 1, j, k)) + { + world.setBlockMetadataWithNotify(i, j, k, 1); + } else + if(world.isBlockOpaqueCube(i + 1, j, k)) + { + world.setBlockMetadataWithNotify(i, j, k, 2); + } else + if(world.isBlockOpaqueCube(i, j, k - 1)) + { + world.setBlockMetadataWithNotify(i, j, k, 3); + } else + if(world.isBlockOpaqueCube(i, j, k + 1)) + { + world.setBlockMetadataWithNotify(i, j, k, 4); + } else + if(world.isBlockOpaqueCube(i, j - 1, k)) + { + world.setBlockMetadataWithNotify(i, j, k, 5); + } + dropTorchIfCantStay(world, i, j, k); + } + + public void onNeighborBlockChange(World world, int i, int j, int k, int l) + { + if(dropTorchIfCantStay(world, i, j, k)) + { + int i1 = world.getBlockMetadata(i, j, k); + boolean flag = false; + if(!world.isBlockOpaqueCube(i - 1, j, k) && i1 == 1) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i + 1, j, k) && i1 == 2) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j, k - 1) && i1 == 3) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j, k + 1) && i1 == 4) + { + flag = true; + } + if(!world.isBlockOpaqueCube(i, j - 1, k) && i1 == 5) + { + flag = true; + } + if(flag) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + } + } + } + + private boolean dropTorchIfCantStay(World world, int i, int j, int k) + { + if(!canPlaceBlockAt(world, i, j, k)) + { + dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k)); + world.setBlockWithNotify(i, j, k, 0); + return false; + } else + { + return true; + } + } + + public MovingObjectPosition collisionRayTrace(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) + { + int l = world.getBlockMetadata(i, j, k) & 7; + float f = 0.15F; + if(l == 1) + { + setBlockBounds(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f); + } else + if(l == 2) + { + setBlockBounds(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f); + } else + if(l == 3) + { + setBlockBounds(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F); + } else + if(l == 4) + { + setBlockBounds(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F); + } else + { + float f1 = 0.1F; + setBlockBounds(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, 0.6F, 0.5F + f1); + } + return super.collisionRayTrace(world, i, j, k, vec3d, vec3d1); + } + + public void randomDisplayTick(World world, int i, int j, int k, Random random) + { + int l = world.getBlockMetadata(i, j, k); + double d = (float)i + 0.5F; + double d1 = (float)j + 0.7F; + double d2 = (float)k + 0.5F; + double d3 = 0.2199999988079071D; + double d4 = 0.27000001072883606D; + if(l == 1) + { + world.spawnParticle("smoke", d - d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d - d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + } else + if(l == 2) + { + world.spawnParticle("smoke", d + d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d + d4, d1 + d3, d2, 0.0D, 0.0D, 0.0D); + } else + if(l == 3) + { + world.spawnParticle("smoke", d, d1 + d3, d2 - d4, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d, d1 + d3, d2 - d4, 0.0D, 0.0D, 0.0D); + } else + if(l == 4) + { + world.spawnParticle("smoke", d, d1 + d3, d2 + d4, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d, d1 + d3, d2 + d4, 0.0D, 0.0D, 0.0D); + } else + { + world.spawnParticle("smoke", d, d1, d2, 0.0D, 0.0D, 0.0D); + world.spawnParticle("flame", d, d1, d2, 0.0D, 0.0D, 0.0D); + } + } +} diff --git a/src/main/java/net/minecraft/src/BlockWorkbench.java b/src/main/java/net/minecraft/src/BlockWorkbench.java new file mode 100644 index 0000000..1f94f0c --- /dev/null +++ b/src/main/java/net/minecraft/src/BlockWorkbench.java @@ -0,0 +1,46 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class BlockWorkbench extends Block +{ + + protected BlockWorkbench(int i) + { + super(i, Material.wood); + blockIndexInTexture = 59; + } + + public int getBlockTextureFromSide(int i) + { + if(i == 1) + { + return blockIndexInTexture - 16; + } + if(i == 0) + { + return Block.planks.getBlockTextureFromSide(0); + } + if(i == 2 || i == 4) + { + return blockIndexInTexture + 1; + } else + { + return blockIndexInTexture; + } + } + + public boolean blockActivated(World world, int i, int j, int k, EntityPlayer entityplayer) + { + if(world.multiplayerWorld) + { + return true; + } else + { + entityplayer.displayWorkbenchGUI(i, j, k); + return true; + } + } +} diff --git a/src/main/java/net/minecraft/src/CanvasMajongLogo.java b/src/main/java/net/minecraft/src/CanvasMajongLogo.java new file mode 100644 index 0000000..674eadc --- /dev/null +++ b/src/main/java/net/minecraft/src/CanvasMajongLogo.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +class CanvasMajongLogo extends Canvas +{ + + public CanvasMajongLogo() + { + try + { + logo = ImageIO.read(new File("resources/gui/logo.png")); + } + catch(IOException ioexception) { } + byte byte0 = 100; + setPreferredSize(new Dimension(byte0, byte0)); + setMinimumSize(new Dimension(byte0, byte0)); + } + + public void paint(Graphics g) + { + super.paint(g); + g.drawImage(logo, getWidth() / 2 - logo.getWidth() / 2, 32, null); + } + + private BufferedImage logo; +} diff --git a/src/main/java/net/minecraft/src/ChatLine.java b/src/main/java/net/minecraft/src/ChatLine.java new file mode 100644 index 0000000..30b1ca4 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChatLine.java @@ -0,0 +1,18 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ChatLine +{ + + public ChatLine(String s) + { + message = s; + updateCounter = 0; + } + + public String message; + public int updateCounter; +} diff --git a/src/main/java/net/minecraft/src/Chunk.java b/src/main/java/net/minecraft/src/Chunk.java new file mode 100644 index 0000000..7f6f3e2 --- /dev/null +++ b/src/main/java/net/minecraft/src/Chunk.java @@ -0,0 +1,668 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.*; + +public class Chunk +{ + + public Chunk(World world, int i, int j) + { + chunkTileEntityMap = new HashMap(); + entities = new List[8]; + isTerrainPopulated = false; + isModified = false; + hasEntities = false; + lastSaveTime = 0L; + worldObj = world; + xPosition = i; + zPosition = j; + heightMap = new byte[256]; + for(int k = 0; k < entities.length; k++) + { + entities[k] = new ArrayList(); + } + + } + + public Chunk(World world, byte abyte0[], int i, int j) + { + this(world, i, j); + blocks = abyte0; + data = new NibbleArray(abyte0.length); + skylightMap = new NibbleArray(abyte0.length); + blocklightMap = new NibbleArray(abyte0.length); + } + + public boolean isAtLocation(int i, int j) + { + return i == xPosition && j == zPosition; + } + + public int getHeightValue(int i, int j) + { + return heightMap[j << 4 | i] & 0xff; + } + + public void func_1014_a() + { + } + + public void generateHeightMap() + { + int i = 127; + for(int j = 0; j < 16; j++) + { + for(int k = 0; k < 16; k++) + { + int l = 127; + for(int i1 = j << 11 | k << 7; l > 0 && Block.lightOpacity[blocks[(i1 + l) - 1]] == 0; l--) { } + heightMap[k << 4 | j] = (byte)l; + if(l < i) + { + i = l; + } + } + + } + + field_1532_i = i; + isModified = true; + } + + public void func_1024_c() + { + int i = 127; + for(int j = 0; j < 16; j++) + { + for(int l = 0; l < 16; l++) + { + int j1 = 127; + int k1; + for(k1 = j << 11 | l << 7; j1 > 0 && Block.lightOpacity[blocks[(k1 + j1) - 1]] == 0; j1--) { } + heightMap[l << 4 | j] = (byte)j1; + if(j1 < i) + { + i = j1; + } + if(worldObj.worldProvider.field_6478_e) + { + continue; + } + int l1 = 15; + int i2 = 127; + do + { + l1 -= Block.lightOpacity[blocks[k1 + i2]]; + if(l1 > 0) + { + skylightMap.setNibble(j, i2, l, l1); + } + } while(--i2 > 0 && l1 > 0); + } + + } + + field_1532_i = i; + for(int k = 0; k < 16; k++) + { + for(int i1 = 0; i1 < 16; i1++) + { + func_996_c(k, i1); + } + + } + + isModified = true; + } + + public void func_4143_d() + { + } + + private void func_996_c(int i, int j) + { + int k = getHeightValue(i, j); + int l = xPosition * 16 + i; + int i1 = zPosition * 16 + j; + func_1020_f(l - 1, i1, k); + func_1020_f(l + 1, i1, k); + func_1020_f(l, i1 - 1, k); + func_1020_f(l, i1 + 1, k); + } + + private void func_1020_f(int i, int j, int k) + { + int l = worldObj.getHeightValue(i, j); + if(l > k) + { + worldObj.func_616_a(EnumSkyBlock.Sky, i, k, j, i, l, j); + isModified = true; + } else + if(l < k) + { + worldObj.func_616_a(EnumSkyBlock.Sky, i, l, j, i, k, j); + isModified = true; + } + } + + private void func_1003_g(int i, int j, int k) + { + int l = heightMap[k << 4 | i] & 0xff; + int i1 = l; + if(j > l) + { + i1 = j; + } + for(int j1 = i << 11 | k << 7; i1 > 0 && Block.lightOpacity[blocks[(j1 + i1) - 1]] == 0; i1--) { } + if(i1 == l) + { + return; + } + worldObj.markBlocksDirtyVertical(i, k, i1, l); + heightMap[k << 4 | i] = (byte)i1; + if(i1 < field_1532_i) + { + field_1532_i = i1; + } else + { + int k1 = 127; + for(int i2 = 0; i2 < 16; i2++) + { + for(int k2 = 0; k2 < 16; k2++) + { + if((heightMap[k2 << 4 | i2] & 0xff) < k1) + { + k1 = heightMap[k2 << 4 | i2] & 0xff; + } + } + + } + + field_1532_i = k1; + } + int l1 = xPosition * 16 + i; + int j2 = zPosition * 16 + k; + if(i1 < l) + { + for(int l2 = i1; l2 < l; l2++) + { + skylightMap.setNibble(i, l2, k, 15); + } + + } else + { + worldObj.func_616_a(EnumSkyBlock.Sky, l1, l, j2, l1, i1, j2); + for(int i3 = l; i3 < i1; i3++) + { + skylightMap.setNibble(i, i3, k, 0); + } + + } + int j3 = 15; + int k3 = i1; + while(i1 > 0 && j3 > 0) + { + i1--; + int l3 = Block.lightOpacity[getBlockID(i, i1, k)]; + if(l3 == 0) + { + l3 = 1; + } + j3 -= l3; + if(j3 < 0) + { + j3 = 0; + } + skylightMap.setNibble(i, i1, k, j3); + } + for(; i1 > 0 && Block.lightOpacity[getBlockID(i, i1 - 1, k)] == 0; i1--) { } + if(i1 != k3) + { + worldObj.func_616_a(EnumSkyBlock.Sky, l1 - 1, i1, j2 - 1, l1 + 1, k3, j2 + 1); + } + isModified = true; + } + + public int getBlockID(int i, int j, int k) + { + return blocks[i << 11 | k << 7 | j]; + } + + public boolean setBlockIDWithMetadata(int i, int j, int k, int l, int i1) + { + byte byte0 = (byte)l; + int j1 = heightMap[k << 4 | i] & 0xff; + int k1 = blocks[i << 11 | k << 7 | j] & 0xff; + if(k1 == l && data.getNibble(i, j, k) == i1) + { + return false; + } + int l1 = xPosition * 16 + i; + int i2 = zPosition * 16 + k; + blocks[i << 11 | k << 7 | j] = byte0; + if(k1 != 0 && !worldObj.multiplayerWorld) + { + Block.blocksList[k1].onBlockRemoval(worldObj, l1, j, i2); + } + data.setNibble(i, j, k, i1); + if(!worldObj.worldProvider.field_6478_e) + { + if(Block.lightOpacity[byte0] != 0) + { + if(j >= j1) + { + func_1003_g(i, j + 1, k); + } + } else + if(j == j1 - 1) + { + func_1003_g(i, j, k); + } + worldObj.func_616_a(EnumSkyBlock.Sky, l1, j, i2, l1, j, i2); + } + worldObj.func_616_a(EnumSkyBlock.Block, l1, j, i2, l1, j, i2); + func_996_c(i, k); + data.setNibble(i, j, k, i1); + if(l != 0) + { + Block.blocksList[l].onBlockAdded(worldObj, l1, j, i2); + } + isModified = true; + return true; + } + + public boolean setBlockID(int i, int j, int k, int l) + { + byte byte0 = (byte)l; + int i1 = heightMap[k << 4 | i] & 0xff; + int j1 = blocks[i << 11 | k << 7 | j] & 0xff; + if(j1 == l) + { + return false; + } + int k1 = xPosition * 16 + i; + int l1 = zPosition * 16 + k; + blocks[i << 11 | k << 7 | j] = byte0; + if(j1 != 0) + { + Block.blocksList[j1].onBlockRemoval(worldObj, k1, j, l1); + } + data.setNibble(i, j, k, 0); + if(Block.lightOpacity[byte0] != 0) + { + if(j >= i1) + { + func_1003_g(i, j + 1, k); + } + } else + if(j == i1 - 1) + { + func_1003_g(i, j, k); + } + worldObj.func_616_a(EnumSkyBlock.Sky, k1, j, l1, k1, j, l1); + worldObj.func_616_a(EnumSkyBlock.Block, k1, j, l1, k1, j, l1); + func_996_c(i, k); + if(l != 0 && !worldObj.multiplayerWorld) + { + Block.blocksList[l].onBlockAdded(worldObj, k1, j, l1); + } + isModified = true; + return true; + } + + public int getBlockMetadata(int i, int j, int k) + { + return data.getNibble(i, j, k); + } + + public void setBlockMetadata(int i, int j, int k, int l) + { + isModified = true; + data.setNibble(i, j, k, l); + } + + public int getSavedLightValue(EnumSkyBlock enumskyblock, int i, int j, int k) + { + if(enumskyblock == EnumSkyBlock.Sky) + { + return skylightMap.getNibble(i, j, k); + } + if(enumskyblock == EnumSkyBlock.Block) + { + return blocklightMap.getNibble(i, j, k); + } else + { + return 0; + } + } + + public void setLightValue(EnumSkyBlock enumskyblock, int i, int j, int k, int l) + { + isModified = true; + if(enumskyblock == EnumSkyBlock.Sky) + { + skylightMap.setNibble(i, j, k, l); + } else + if(enumskyblock == EnumSkyBlock.Block) + { + blocklightMap.setNibble(i, j, k, l); + } else + { + return; + } + } + + public int getBlockLightValue(int i, int j, int k, int l) + { + int i1 = skylightMap.getNibble(i, j, k); + if(i1 > 0) + { + isLit = true; + } + i1 -= l; + int j1 = blocklightMap.getNibble(i, j, k); + if(j1 > i1) + { + i1 = j1; + } + return i1; + } + + public void addEntity(Entity entity) + { + hasEntities = true; + int i = MathHelper.floor_double(entity.posX / 16D); + int j = MathHelper.floor_double(entity.posZ / 16D); + if(i != xPosition || j != zPosition) + { + System.out.println((new StringBuilder()).append("Wrong location! ").append(entity).toString()); + Thread.dumpStack(); + } + int k = MathHelper.floor_double(entity.posY / 16D); + if(k < 0) + { + k = 0; + } + if(k >= entities.length) + { + k = entities.length - 1; + } + entity.addedToChunk = true; + entity.chunkCoordX = xPosition; + entity.chunkCoordY = k; + entity.chunkCoordZ = zPosition; + entities[k].add(entity); + } + + public void func_1015_b(Entity entity) + { + func_1016_a(entity, entity.chunkCoordY); + } + + public void func_1016_a(Entity entity, int i) + { + if(i < 0) + { + i = 0; + } + if(i >= entities.length) + { + i = entities.length - 1; + } + entities[i].remove(entity); + } + + public boolean canBlockSeeTheSky(int i, int j, int k) + { + return j >= (heightMap[k << 4 | i] & 0xff); + } + + public TileEntity getChunkBlockTileEntity(int i, int j, int k) + { + ChunkPosition chunkposition = new ChunkPosition(i, j, k); + TileEntity tileentity = (TileEntity)chunkTileEntityMap.get(chunkposition); + if(tileentity == null) + { + int l = getBlockID(i, j, k); + if(!Block.isBlockContainer[l]) + { + return null; + } + BlockContainer blockcontainer = (BlockContainer)Block.blocksList[l]; + blockcontainer.onBlockAdded(worldObj, xPosition * 16 + i, j, zPosition * 16 + k); + tileentity = (TileEntity)chunkTileEntityMap.get(chunkposition); + } + return tileentity; + } + + public void func_1001_a(TileEntity tileentity) + { + int i = tileentity.xCoord - xPosition * 16; + int j = tileentity.yCoord; + int k = tileentity.zCoord - zPosition * 16; + setChunkBlockTileEntity(i, j, k, tileentity); + } + + public void setChunkBlockTileEntity(int i, int j, int k, TileEntity tileentity) + { + ChunkPosition chunkposition = new ChunkPosition(i, j, k); + tileentity.worldObj = worldObj; + tileentity.xCoord = xPosition * 16 + i; + tileentity.yCoord = j; + tileentity.zCoord = zPosition * 16 + k; + if(getBlockID(i, j, k) == 0 || !(Block.blocksList[getBlockID(i, j, k)] instanceof BlockContainer)) + { + System.out.println("Attempted to place a tile entity where there was no entity tile!"); + return; + } + if(isChunkLoaded) + { + if(chunkTileEntityMap.get(chunkposition) != null) + { + worldObj.loadedTileEntityList.remove(chunkTileEntityMap.get(chunkposition)); + } + worldObj.loadedTileEntityList.add(tileentity); + } + chunkTileEntityMap.put(chunkposition, tileentity); + } + + public void removeChunkBlockTileEntity(int i, int j, int k) + { + ChunkPosition chunkposition = new ChunkPosition(i, j, k); + if(isChunkLoaded) + { + worldObj.loadedTileEntityList.remove(chunkTileEntityMap.remove(chunkposition)); + } + } + + public void onChunkLoad() + { + isChunkLoaded = true; + worldObj.loadedTileEntityList.addAll(chunkTileEntityMap.values()); + for(int i = 0; i < entities.length; i++) + { + worldObj.func_636_a(entities[i]); + } + + } + + public void onChunkUnload() + { + isChunkLoaded = false; + worldObj.loadedTileEntityList.removeAll(chunkTileEntityMap.values()); + for(int i = 0; i < entities.length; i++) + { + worldObj.func_632_b(entities[i]); + } + + } + + public void setChunkModified() + { + isModified = true; + } + + public void getEntitiesWithinAABBForEntity(Entity entity, AxisAlignedBB axisalignedbb, List list) + { + int i = MathHelper.floor_double((axisalignedbb.minY - 2D) / 16D); + int j = MathHelper.floor_double((axisalignedbb.maxY + 2D) / 16D); + if(i < 0) + { + i = 0; + } + if(j >= entities.length) + { + j = entities.length - 1; + } + for(int k = i; k <= j; k++) + { + List list1 = entities[k]; + for(int l = 0; l < list1.size(); l++) + { + Entity entity1 = (Entity)list1.get(l); + if(entity1 != entity && entity1.boundingBox.intersectsWith(axisalignedbb)) + { + list.add(entity1); + } + } + + } + + } + + public void getEntitiesOfTypeWithinAAAB(Class class1, AxisAlignedBB axisalignedbb, List list) + { + int i = MathHelper.floor_double((axisalignedbb.minY - 2D) / 16D); + int j = MathHelper.floor_double((axisalignedbb.maxY + 2D) / 16D); + if(i < 0) + { + i = 0; + } + if(j >= entities.length) + { + j = entities.length - 1; + } + for(int k = i; k <= j; k++) + { + List list1 = entities[k]; + for(int l = 0; l < list1.size(); l++) + { + Entity entity = (Entity)list1.get(l); + if(class1.isAssignableFrom(entity.getClass()) && entity.boundingBox.intersectsWith(axisalignedbb)) + { + list.add(entity); + } + } + + } + + } + + public boolean needsSaving(boolean flag) + { + if(neverSave) + { + return false; + } + if(flag) + { + if(hasEntities && worldObj.func_22139_r() != lastSaveTime) + { + return true; + } + } else + if(hasEntities && worldObj.func_22139_r() >= lastSaveTime + 600L) + { + return true; + } + return isModified; + } + + public int setChunkData(byte abyte0[], int i, int j, int k, int l, int i1, int j1, + int k1) + { + for(int l1 = i; l1 < l; l1++) + { + for(int l2 = k; l2 < j1; l2++) + { + int l3 = l1 << 11 | l2 << 7 | j; + int l4 = i1 - j; + System.arraycopy(abyte0, k1, blocks, l3, l4); + k1 += l4; + } + + } + + generateHeightMap(); + for(int i2 = i; i2 < l; i2++) + { + for(int i3 = k; i3 < j1; i3++) + { + int i4 = (i2 << 11 | i3 << 7 | j) >> 1; + int i5 = (i1 - j) / 2; + System.arraycopy(abyte0, k1, data.data, i4, i5); + k1 += i5; + } + + } + + for(int j2 = i; j2 < l; j2++) + { + for(int j3 = k; j3 < j1; j3++) + { + int j4 = (j2 << 11 | j3 << 7 | j) >> 1; + int j5 = (i1 - j) / 2; + System.arraycopy(abyte0, k1, blocklightMap.data, j4, j5); + k1 += j5; + } + + } + + for(int k2 = i; k2 < l; k2++) + { + for(int k3 = k; k3 < j1; k3++) + { + int k4 = (k2 << 11 | k3 << 7 | j) >> 1; + int k5 = (i1 - j) / 2; + System.arraycopy(abyte0, k1, skylightMap.data, k4, k5); + k1 += k5; + } + + } + + return k1; + } + + public Random func_997_a(long l) + { + return new Random(worldObj.func_22138_q() + (long)(xPosition * xPosition * 0x4c1906) + (long)(xPosition * 0x5ac0db) + (long)(zPosition * zPosition) * 0x4307a7L + (long)(zPosition * 0x5f24f) ^ l); + } + + public boolean func_21167_h() + { + return false; + } + + public static boolean isLit; + public byte blocks[]; + public boolean isChunkLoaded; + public World worldObj; + public NibbleArray data; + public NibbleArray skylightMap; + public NibbleArray blocklightMap; + public byte heightMap[]; + public int field_1532_i; + public final int xPosition; + public final int zPosition; + public Map chunkTileEntityMap; + public List entities[]; + public boolean isTerrainPopulated; + public boolean isModified; + public boolean neverSave; + public boolean hasEntities; + public long lastSaveTime; +} diff --git a/src/main/java/net/minecraft/src/ChunkCache.java b/src/main/java/net/minecraft/src/ChunkCache.java new file mode 100644 index 0000000..2cf684c --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkCache.java @@ -0,0 +1,178 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ChunkCache + implements IBlockAccess +{ + + public ChunkCache(World world, int i, int j, int k, int l, int i1, int j1) + { + worldObj = world; + chunkX = i >> 4; + chunkZ = k >> 4; + int k1 = l >> 4; + int l1 = j1 >> 4; + chunkArray = new Chunk[(k1 - chunkX) + 1][(l1 - chunkZ) + 1]; + for(int i2 = chunkX; i2 <= k1; i2++) + { + for(int j2 = chunkZ; j2 <= l1; j2++) + { + chunkArray[i2 - chunkX][j2 - chunkZ] = world.getChunkFromChunkCoords(i2, j2); + } + + } + + } + + public int getBlockId(int i, int j, int k) + { + if(j < 0) + { + return 0; + } + if(j >= 128) + { + return 0; + } + int l = (i >> 4) - chunkX; + int i1 = (k >> 4) - chunkZ; + if(l < 0 || l >= chunkArray.length || i1 < 0 || i1 >= chunkArray[l].length) + { + return 0; + } + Chunk chunk = chunkArray[l][i1]; + if(chunk == null) + { + return 0; + } else + { + return chunk.getBlockID(i & 0xf, j, k & 0xf); + } + } + + public TileEntity getBlockTileEntity(int i, int j, int k) + { + int l = (i >> 4) - chunkX; + int i1 = (k >> 4) - chunkZ; + return chunkArray[l][i1].getChunkBlockTileEntity(i & 0xf, j, k & 0xf); + } + + public float getLightBrightness(int i, int j, int k) + { + return worldObj.worldProvider.lightBrightnessTable[func_4086_d(i, j, k)]; + } + + public int func_4086_d(int i, int j, int k) + { + return func_716_a(i, j, k, true); + } + + public int func_716_a(int i, int j, int k, boolean flag) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return 15; + } + if(flag) + { + int l = getBlockId(i, j, k); + if(l == Block.stairSingle.blockID || l == Block.tilledField.blockID) + { + int k1 = func_716_a(i, j + 1, k, false); + int i2 = func_716_a(i + 1, j, k, false); + int j2 = func_716_a(i - 1, j, k, false); + int k2 = func_716_a(i, j, k + 1, false); + int l2 = func_716_a(i, j, k - 1, false); + if(i2 > k1) + { + k1 = i2; + } + if(j2 > k1) + { + k1 = j2; + } + if(k2 > k1) + { + k1 = k2; + } + if(l2 > k1) + { + k1 = l2; + } + return k1; + } + } + if(j < 0) + { + return 0; + } + if(j >= 128) + { + int i1 = 15 - worldObj.skylightSubtracted; + if(i1 < 0) + { + i1 = 0; + } + return i1; + } else + { + int j1 = (i >> 4) - chunkX; + int l1 = (k >> 4) - chunkZ; + return chunkArray[j1][l1].getBlockLightValue(i & 0xf, j, k & 0xf, worldObj.skylightSubtracted); + } + } + + public int getBlockMetadata(int i, int j, int k) + { + if(j < 0) + { + return 0; + } + if(j >= 128) + { + return 0; + } else + { + int l = (i >> 4) - chunkX; + int i1 = (k >> 4) - chunkZ; + return chunkArray[l][i1].getBlockMetadata(i & 0xf, j, k & 0xf); + } + } + + public Material getBlockMaterial(int i, int j, int k) + { + int l = getBlockId(i, j, k); + if(l == 0) + { + return Material.air; + } else + { + return Block.blocksList[l].blockMaterial; + } + } + + public boolean isBlockOpaqueCube(int i, int j, int k) + { + Block block = Block.blocksList[getBlockId(i, j, k)]; + if(block == null) + { + return false; + } else + { + return block.isOpaqueCube(); + } + } + + public WorldChunkManager getWorldChunkManager() + { + return worldObj.getWorldChunkManager(); + } + + private int chunkX; + private int chunkZ; + private Chunk chunkArray[][]; + private World worldObj; +} diff --git a/src/main/java/net/minecraft/src/ChunkCoordIntPair.java b/src/main/java/net/minecraft/src/ChunkCoordIntPair.java new file mode 100644 index 0000000..248b9a4 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkCoordIntPair.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ChunkCoordIntPair +{ + + public ChunkCoordIntPair(int i, int j) + { + chunkXPos = i; + chunkZPos = j; + } + + public static int func_22011_a(int i, int j) + { + return (i >= 0 ? 0 : 0x80000000) | (i & 0x7fff) << 16 | (j >= 0 ? 0 : 0x8000) | j & 0x7fff; + } + + public int hashCode() + { + return func_22011_a(chunkXPos, chunkZPos); + } + + public boolean equals(Object obj) + { + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair)obj; + return chunkcoordintpair.chunkXPos == chunkXPos && chunkcoordintpair.chunkZPos == chunkZPos; + } + + public final int chunkXPos; + public final int chunkZPos; +} diff --git a/src/main/java/net/minecraft/src/ChunkCoordinates.java b/src/main/java/net/minecraft/src/ChunkCoordinates.java new file mode 100644 index 0000000..5be6d99 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkCoordinates.java @@ -0,0 +1,64 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ChunkCoordinates + implements Comparable +{ + + public ChunkCoordinates() + { + } + + public ChunkCoordinates(int i, int j, int k) + { + field_22395_a = i; + field_22394_b = j; + field_22396_c = k; + } + + public boolean equals(Object obj) + { + if(!(obj instanceof ChunkCoordinates)) + { + return false; + } else + { + ChunkCoordinates chunkcoordinates = (ChunkCoordinates)obj; + return field_22395_a == chunkcoordinates.field_22395_a && field_22394_b == chunkcoordinates.field_22394_b && field_22396_c == chunkcoordinates.field_22396_c; + } + } + + public int hashCode() + { + return field_22395_a + field_22396_c << 8 + field_22394_b << 16; + } + + public int func_22393_a(ChunkCoordinates chunkcoordinates) + { + if(field_22394_b == chunkcoordinates.field_22394_b) + { + if(field_22396_c == chunkcoordinates.field_22396_c) + { + return field_22395_a - chunkcoordinates.field_22395_a; + } else + { + return field_22396_c - chunkcoordinates.field_22396_c; + } + } else + { + return field_22394_b - chunkcoordinates.field_22394_b; + } + } + + public int compareTo(Object obj) + { + return func_22393_a((ChunkCoordinates)obj); + } + + public int field_22395_a; + public int field_22394_b; + public int field_22396_c; +} diff --git a/src/main/java/net/minecraft/src/ChunkFilePattern.java b/src/main/java/net/minecraft/src/ChunkFilePattern.java new file mode 100644 index 0000000..caaaa86 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkFilePattern.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.io.FilenameFilter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class ChunkFilePattern + implements FilenameFilter +{ + + private ChunkFilePattern() + { + } + + public boolean accept(File file, String s) + { + Matcher matcher = field_22189_a.matcher(s); + return matcher.matches(); + } + + ChunkFilePattern(Empty2 empty2) + { + this(); + } + + public static final Pattern field_22189_a = Pattern.compile("c\\.(-?[0-9a-z]+)\\.(-?[0-9a-z]+)\\.dat"); + +} diff --git a/src/main/java/net/minecraft/src/ChunkFolderPattern.java b/src/main/java/net/minecraft/src/ChunkFolderPattern.java new file mode 100644 index 0000000..bddde29 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkFolderPattern.java @@ -0,0 +1,38 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.io.FileFilter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class ChunkFolderPattern + implements FileFilter +{ + + private ChunkFolderPattern() + { + } + + public boolean accept(File file) + { + if(file.isDirectory()) + { + Matcher matcher = field_22392_a.matcher(file.getName()); + return matcher.matches(); + } else + { + return false; + } + } + + ChunkFolderPattern(Empty2 empty2) + { + this(); + } + + public static final Pattern field_22392_a = Pattern.compile("[0-9a-z]|([0-9a-z][0-9a-z])"); + +} diff --git a/src/main/java/net/minecraft/src/ChunkLoader.java b/src/main/java/net/minecraft/src/ChunkLoader.java new file mode 100644 index 0000000..11bce36 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkLoader.java @@ -0,0 +1,245 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.*; + +public class ChunkLoader + implements IChunkLoader +{ + + public ChunkLoader(File file, boolean flag) + { + saveDir = file; + createIfNecessary = flag; + } + + private File chunkFileForXZ(int i, int j) + { + String s = (new StringBuilder()).append("c.").append(Integer.toString(i, 36)).append(".").append(Integer.toString(j, 36)).append(".dat").toString(); + String s1 = Integer.toString(i & 0x3f, 36); + String s2 = Integer.toString(j & 0x3f, 36); + File file = new File(saveDir, s1); + if(!file.exists()) + { + if(createIfNecessary) + { + file.mkdir(); + } else + { + return null; + } + } + file = new File(file, s2); + if(!file.exists()) + { + if(createIfNecessary) + { + file.mkdir(); + } else + { + return null; + } + } + file = new File(file, s); + if(!file.exists() && !createIfNecessary) + { + return null; + } else + { + return file; + } + } + + public Chunk loadChunk(World world, int i, int j) + { + File file = chunkFileForXZ(i, j); + if(file != null && file.exists()) + { + try + { + FileInputStream fileinputstream = new FileInputStream(file); + NBTTagCompound nbttagcompound = CompressedStreamTools.func_1138_a(fileinputstream); + if(!nbttagcompound.hasKey("Level")) + { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is missing level data, skipping").toString()); + return null; + } + if(!nbttagcompound.getCompoundTag("Level").hasKey("Blocks")) + { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is missing block data, skipping").toString()); + return null; + } + Chunk chunk = loadChunkIntoWorldFromCompound(world, nbttagcompound.getCompoundTag("Level")); + if(!chunk.isAtLocation(i, j)) + { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is in the wrong location; relocating. (Expected ").append(i).append(", ").append(j).append(", got ").append(chunk.xPosition).append(", ").append(chunk.zPosition).append(")").toString()); + nbttagcompound.setInteger("xPos", i); + nbttagcompound.setInteger("zPos", j); + chunk = loadChunkIntoWorldFromCompound(world, nbttagcompound.getCompoundTag("Level")); + } + return chunk; + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + return null; + } + + public void saveChunk(World world, Chunk chunk) + { + world.checkSessionLock(); + File file = chunkFileForXZ(chunk.xPosition, chunk.zPosition); + if(file.exists()) + { + WorldInfo worldinfo = world.func_22144_v(); + worldinfo.func_22297_b(worldinfo.func_22306_g() - file.length()); + } + try + { + File file1 = new File(saveDir, "tmp_chunk.dat"); + FileOutputStream fileoutputstream = new FileOutputStream(file1); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound.setTag("Level", nbttagcompound1); + storeChunkInCompound(chunk, world, nbttagcompound1); + CompressedStreamTools.writeGzippedCompoundToOutputStream(nbttagcompound, fileoutputstream); + fileoutputstream.close(); + if(file.exists()) + { + file.delete(); + } + file1.renameTo(file); + WorldInfo worldinfo1 = world.func_22144_v(); + worldinfo1.func_22297_b(worldinfo1.func_22306_g() + file.length()); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + public static void storeChunkInCompound(Chunk chunk, World world, NBTTagCompound nbttagcompound) + { + world.checkSessionLock(); + nbttagcompound.setInteger("xPos", chunk.xPosition); + nbttagcompound.setInteger("zPos", chunk.zPosition); + nbttagcompound.setLong("LastUpdate", world.func_22139_r()); + nbttagcompound.setByteArray("Blocks", chunk.blocks); + nbttagcompound.setByteArray("Data", chunk.data.data); + nbttagcompound.setByteArray("SkyLight", chunk.skylightMap.data); + nbttagcompound.setByteArray("BlockLight", chunk.blocklightMap.data); + nbttagcompound.setByteArray("HeightMap", chunk.heightMap); + nbttagcompound.setBoolean("TerrainPopulated", chunk.isTerrainPopulated); + chunk.hasEntities = false; + NBTTagList nbttaglist = new NBTTagList(); +label0: + for(int i = 0; i < chunk.entities.length; i++) + { + Iterator iterator = chunk.entities[i].iterator(); + do + { + if(!iterator.hasNext()) + { + continue label0; + } + Entity entity = (Entity)iterator.next(); + chunk.hasEntities = true; + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + if(entity.addEntityID(nbttagcompound1)) + { + nbttaglist.setTag(nbttagcompound1); + } + } while(true); + } + + nbttagcompound.setTag("Entities", nbttaglist); + NBTTagList nbttaglist1 = new NBTTagList(); + NBTTagCompound nbttagcompound2; + for(Iterator iterator1 = chunk.chunkTileEntityMap.values().iterator(); iterator1.hasNext(); nbttaglist1.setTag(nbttagcompound2)) + { + TileEntity tileentity = (TileEntity)iterator1.next(); + nbttagcompound2 = new NBTTagCompound(); + tileentity.writeToNBT(nbttagcompound2); + } + + nbttagcompound.setTag("TileEntities", nbttaglist1); + } + + public static Chunk loadChunkIntoWorldFromCompound(World world, NBTTagCompound nbttagcompound) + { + int i = nbttagcompound.getInteger("xPos"); + int j = nbttagcompound.getInteger("zPos"); + Chunk chunk = new Chunk(world, i, j); + chunk.blocks = nbttagcompound.getByteArray("Blocks"); + chunk.data = new NibbleArray(nbttagcompound.getByteArray("Data")); + chunk.skylightMap = new NibbleArray(nbttagcompound.getByteArray("SkyLight")); + chunk.blocklightMap = new NibbleArray(nbttagcompound.getByteArray("BlockLight")); + chunk.heightMap = nbttagcompound.getByteArray("HeightMap"); + chunk.isTerrainPopulated = nbttagcompound.getBoolean("TerrainPopulated"); + if(!chunk.data.isValid()) + { + chunk.data = new NibbleArray(chunk.blocks.length); + } + if(chunk.heightMap == null || !chunk.skylightMap.isValid()) + { + chunk.heightMap = new byte[256]; + chunk.skylightMap = new NibbleArray(chunk.blocks.length); + chunk.func_1024_c(); + } + if(!chunk.blocklightMap.isValid()) + { + chunk.blocklightMap = new NibbleArray(chunk.blocks.length); + chunk.func_1014_a(); + } + NBTTagList nbttaglist = nbttagcompound.getTagList("Entities"); + if(nbttaglist != null) + { + for(int k = 0; k < nbttaglist.tagCount(); k++) + { + NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(k); + Entity entity = EntityList.createEntityFromNBT(nbttagcompound1, world); + chunk.hasEntities = true; + if(entity != null) + { + chunk.addEntity(entity); + } + } + + } + NBTTagList nbttaglist1 = nbttagcompound.getTagList("TileEntities"); + if(nbttaglist1 != null) + { + for(int l = 0; l < nbttaglist1.tagCount(); l++) + { + NBTTagCompound nbttagcompound2 = (NBTTagCompound)nbttaglist1.tagAt(l); + TileEntity tileentity = TileEntity.createAndLoadEntity(nbttagcompound2); + if(tileentity != null) + { + chunk.func_1001_a(tileentity); + } + } + + } + return chunk; + } + + public void func_814_a() + { + } + + public void saveExtraData() + { + } + + public void saveExtraChunkData(World world, Chunk chunk) + { + } + + private File saveDir; + private boolean createIfNecessary; +} diff --git a/src/main/java/net/minecraft/src/ChunkPosition.java b/src/main/java/net/minecraft/src/ChunkPosition.java new file mode 100644 index 0000000..a10118d --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkPosition.java @@ -0,0 +1,37 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ChunkPosition +{ + + public ChunkPosition(int i, int j, int k) + { + x = i; + y = j; + z = k; + } + + public boolean equals(Object obj) + { + if(obj instanceof ChunkPosition) + { + ChunkPosition chunkposition = (ChunkPosition)obj; + return chunkposition.x == x && chunkposition.y == y && chunkposition.z == z; + } else + { + return false; + } + } + + public int hashCode() + { + return x * 0x88f9fa + y * 0xef88b + z; + } + + public final int x; + public final int y; + public final int z; +} diff --git a/src/main/java/net/minecraft/src/ChunkProviderClient.java b/src/main/java/net/minecraft/src/ChunkProviderClient.java new file mode 100644 index 0000000..fbee670 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkProviderClient.java @@ -0,0 +1,89 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class ChunkProviderClient + implements IChunkProvider +{ + + public ChunkProviderClient(World world) + { + chunkMapping = new HashMap(); + field_889_c = new ArrayList(); + blankChunk = new EmptyChunk(world, new byte[32768], 0, 0); + worldObj = world; + } + + public boolean chunkExists(int i, int j) + { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + return chunkMapping.containsKey(chunkcoordintpair); + } + + public void func_539_c(int i, int j) + { + Chunk chunk = provideChunk(i, j); + if(!chunk.func_21167_h()) + { + chunk.onChunkUnload(); + } + chunkMapping.remove(new ChunkCoordIntPair(i, j)); + field_889_c.remove(chunk); + } + + public Chunk func_538_d(int i, int j) + { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + byte abyte0[] = new byte[32768]; + Chunk chunk = new Chunk(worldObj, abyte0, i, j); + Arrays.fill(chunk.skylightMap.data, (byte)-1); + chunkMapping.put(chunkcoordintpair, chunk); + chunk.isChunkLoaded = true; + return chunk; + } + + public Chunk provideChunk(int i, int j) + { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + Chunk chunk = (Chunk)chunkMapping.get(chunkcoordintpair); + if(chunk == null) + { + return blankChunk; + } else + { + return chunk; + } + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) + { + return true; + } + + public boolean func_532_a() + { + return false; + } + + public boolean func_536_b() + { + return false; + } + + public void populate(IChunkProvider ichunkprovider, int i, int j) + { + } + + public String toString() + { + return (new StringBuilder()).append("MultiplayerChunkCache: ").append(chunkMapping.size()).toString(); + } + + private Chunk blankChunk; + private Map chunkMapping; + private List field_889_c; + private World worldObj; +} diff --git a/src/main/java/net/minecraft/src/ChunkProviderGenerate.java b/src/main/java/net/minecraft/src/ChunkProviderGenerate.java new file mode 100644 index 0000000..b48c401 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkProviderGenerate.java @@ -0,0 +1,620 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ChunkProviderGenerate + implements IChunkProvider +{ + + public ChunkProviderGenerate(World world, long l) + { + sandNoise = new double[256]; + gravelNoise = new double[256]; + stoneNoise = new double[256]; + field_902_u = new MapGenCaves(); + field_914_i = new int[32][32]; + worldObj = world; + rand = new Random(l); + field_912_k = new NoiseGeneratorOctaves(rand, 16); + field_911_l = new NoiseGeneratorOctaves(rand, 16); + field_910_m = new NoiseGeneratorOctaves(rand, 8); + field_909_n = new NoiseGeneratorOctaves(rand, 4); + field_908_o = new NoiseGeneratorOctaves(rand, 4); + field_922_a = new NoiseGeneratorOctaves(rand, 10); + field_921_b = new NoiseGeneratorOctaves(rand, 16); + mobSpawnerNoise = new NoiseGeneratorOctaves(rand, 8); + } + + public void generateTerrain(int i, int j, byte abyte0[], MobSpawnerBase amobspawnerbase[], double ad[]) + { + byte byte0 = 4; + byte byte1 = 64; + int k = byte0 + 1; + byte byte2 = 17; + int l = byte0 + 1; + field_4180_q = func_4061_a(field_4180_q, i * byte0, 0, j * byte0, k, byte2, l); + for(int i1 = 0; i1 < byte0; i1++) + { + for(int j1 = 0; j1 < byte0; j1++) + { + for(int k1 = 0; k1 < 16; k1++) + { + double d = 0.125D; + double d1 = field_4180_q[((i1 + 0) * l + (j1 + 0)) * byte2 + (k1 + 0)]; + double d2 = field_4180_q[((i1 + 0) * l + (j1 + 1)) * byte2 + (k1 + 0)]; + double d3 = field_4180_q[((i1 + 1) * l + (j1 + 0)) * byte2 + (k1 + 0)]; + double d4 = field_4180_q[((i1 + 1) * l + (j1 + 1)) * byte2 + (k1 + 0)]; + double d5 = (field_4180_q[((i1 + 0) * l + (j1 + 0)) * byte2 + (k1 + 1)] - d1) * d; + double d6 = (field_4180_q[((i1 + 0) * l + (j1 + 1)) * byte2 + (k1 + 1)] - d2) * d; + double d7 = (field_4180_q[((i1 + 1) * l + (j1 + 0)) * byte2 + (k1 + 1)] - d3) * d; + double d8 = (field_4180_q[((i1 + 1) * l + (j1 + 1)) * byte2 + (k1 + 1)] - d4) * d; + for(int l1 = 0; l1 < 8; l1++) + { + double d9 = 0.25D; + double d10 = d1; + double d11 = d2; + double d12 = (d3 - d1) * d9; + double d13 = (d4 - d2) * d9; + for(int i2 = 0; i2 < 4; i2++) + { + int j2 = i2 + i1 * 4 << 11 | 0 + j1 * 4 << 7 | k1 * 8 + l1; + char c = '\200'; + double d14 = 0.25D; + double d15 = d10; + double d16 = (d11 - d10) * d14; + for(int k2 = 0; k2 < 4; k2++) + { + double d17 = ad[(i1 * 4 + i2) * 16 + (j1 * 4 + k2)]; + int l2 = 0; + if(k1 * 8 + l1 < byte1) + { + if(d17 < 0.5D && k1 * 8 + l1 >= byte1 - 1) + { + l2 = Block.ice.blockID; + } else + { + l2 = Block.waterMoving.blockID; + } + } + if(d15 > 0.0D) + { + l2 = Block.stone.blockID; + } + abyte0[j2] = (byte)l2; + j2 += c; + d15 += d16; + } + + d10 += d12; + d11 += d13; + } + + d1 += d5; + d2 += d6; + d3 += d7; + d4 += d8; + } + + } + + } + + } + + } + + public void replaceBlocksForBiome(int i, int j, byte abyte0[], MobSpawnerBase amobspawnerbase[]) + { + byte byte0 = 64; + double d = 0.03125D; + sandNoise = field_909_n.generateNoiseOctaves(sandNoise, i * 16, j * 16, 0.0D, 16, 16, 1, d, d, 1.0D); + gravelNoise = field_909_n.generateNoiseOctaves(gravelNoise, i * 16, 109.0134D, j * 16, 16, 1, 16, d, 1.0D, d); + stoneNoise = field_908_o.generateNoiseOctaves(stoneNoise, i * 16, j * 16, 0.0D, 16, 16, 1, d * 2D, d * 2D, d * 2D); + for(int k = 0; k < 16; k++) + { + for(int l = 0; l < 16; l++) + { + MobSpawnerBase mobspawnerbase = amobspawnerbase[k + l * 16]; + boolean flag = sandNoise[k + l * 16] + rand.nextDouble() * 0.20000000000000001D > 0.0D; + boolean flag1 = gravelNoise[k + l * 16] + rand.nextDouble() * 0.20000000000000001D > 3D; + int i1 = (int)(stoneNoise[k + l * 16] / 3D + 3D + rand.nextDouble() * 0.25D); + int j1 = -1; + byte byte1 = mobspawnerbase.topBlock; + byte byte2 = mobspawnerbase.fillerBlock; + for(int k1 = 127; k1 >= 0; k1--) + { + int l1 = (l * 16 + k) * 128 + k1; + if(k1 <= 0 + rand.nextInt(5)) + { + abyte0[l1] = (byte)Block.bedrock.blockID; + continue; + } + byte byte3 = abyte0[l1]; + if(byte3 == 0) + { + j1 = -1; + continue; + } + if(byte3 != Block.stone.blockID) + { + continue; + } + if(j1 == -1) + { + if(i1 <= 0) + { + byte1 = 0; + byte2 = (byte)Block.stone.blockID; + } else + if(k1 >= byte0 - 4 && k1 <= byte0 + 1) + { + byte1 = mobspawnerbase.topBlock; + byte2 = mobspawnerbase.fillerBlock; + if(flag1) + { + byte1 = 0; + } + if(flag1) + { + byte2 = (byte)Block.gravel.blockID; + } + if(flag) + { + byte1 = (byte)Block.sand.blockID; + } + if(flag) + { + byte2 = (byte)Block.sand.blockID; + } + } + if(k1 < byte0 && byte1 == 0) + { + byte1 = (byte)Block.waterMoving.blockID; + } + j1 = i1; + if(k1 >= byte0 - 1) + { + abyte0[l1] = byte1; + } else + { + abyte0[l1] = byte2; + } + continue; + } + if(j1 <= 0) + { + continue; + } + j1--; + abyte0[l1] = byte2; + if(j1 == 0 && byte2 == Block.sand.blockID) + { + j1 = rand.nextInt(4); + byte2 = (byte)Block.sandStone.blockID; + } + } + + } + + } + + } + + public Chunk provideChunk(int i, int j) + { + rand.setSeed((long)i * 0x4f9939f508L + (long)j * 0x1ef1565bd5L); + byte abyte0[] = new byte[32768]; + Chunk chunk = new Chunk(worldObj, abyte0, i, j); + biomesForGeneration = worldObj.getWorldChunkManager().loadBlockGeneratorData(biomesForGeneration, i * 16, j * 16, 16, 16); + double ad[] = worldObj.getWorldChunkManager().temperature; + generateTerrain(i, j, abyte0, biomesForGeneration, ad); + replaceBlocksForBiome(i, j, abyte0, biomesForGeneration); + field_902_u.func_867_a(this, worldObj, i, j, abyte0); + chunk.func_1024_c(); + return chunk; + } + + private double[] func_4061_a(double ad[], int i, int j, int k, int l, int i1, int j1) + { + if(ad == null) + { + ad = new double[l * i1 * j1]; + } + double d = 684.41200000000003D; + double d1 = 684.41200000000003D; + double ad1[] = worldObj.getWorldChunkManager().temperature; + double ad2[] = worldObj.getWorldChunkManager().humidity; + field_4182_g = field_922_a.func_4109_a(field_4182_g, i, k, l, j1, 1.121D, 1.121D, 0.5D); + field_4181_h = field_921_b.func_4109_a(field_4181_h, i, k, l, j1, 200D, 200D, 0.5D); + field_4185_d = field_910_m.generateNoiseOctaves(field_4185_d, i, j, k, l, i1, j1, d / 80D, d1 / 160D, d / 80D); + field_4184_e = field_912_k.generateNoiseOctaves(field_4184_e, i, j, k, l, i1, j1, d, d1, d); + field_4183_f = field_911_l.generateNoiseOctaves(field_4183_f, i, j, k, l, i1, j1, d, d1, d); + int k1 = 0; + int l1 = 0; + int i2 = 16 / l; + for(int j2 = 0; j2 < l; j2++) + { + int k2 = j2 * i2 + i2 / 2; + for(int l2 = 0; l2 < j1; l2++) + { + int i3 = l2 * i2 + i2 / 2; + double d2 = ad1[k2 * 16 + i3]; + double d3 = ad2[k2 * 16 + i3] * d2; + double d4 = 1.0D - d3; + d4 *= d4; + d4 *= d4; + d4 = 1.0D - d4; + double d5 = (field_4182_g[l1] + 256D) / 512D; + d5 *= d4; + if(d5 > 1.0D) + { + d5 = 1.0D; + } + double d6 = field_4181_h[l1] / 8000D; + if(d6 < 0.0D) + { + d6 = -d6 * 0.29999999999999999D; + } + d6 = d6 * 3D - 2D; + if(d6 < 0.0D) + { + d6 /= 2D; + if(d6 < -1D) + { + d6 = -1D; + } + d6 /= 1.3999999999999999D; + d6 /= 2D; + d5 = 0.0D; + } else + { + if(d6 > 1.0D) + { + d6 = 1.0D; + } + d6 /= 8D; + } + if(d5 < 0.0D) + { + d5 = 0.0D; + } + d5 += 0.5D; + d6 = (d6 * (double)i1) / 16D; + double d7 = (double)i1 / 2D + d6 * 4D; + l1++; + for(int j3 = 0; j3 < i1; j3++) + { + double d8 = 0.0D; + double d9 = (((double)j3 - d7) * 12D) / d5; + if(d9 < 0.0D) + { + d9 *= 4D; + } + double d10 = field_4184_e[k1] / 512D; + double d11 = field_4183_f[k1] / 512D; + double d12 = (field_4185_d[k1] / 10D + 1.0D) / 2D; + if(d12 < 0.0D) + { + d8 = d10; + } else + if(d12 > 1.0D) + { + d8 = d11; + } else + { + d8 = d10 + (d11 - d10) * d12; + } + d8 -= d9; + if(j3 > i1 - 4) + { + double d13 = (float)(j3 - (i1 - 4)) / 3F; + d8 = d8 * (1.0D - d13) + -10D * d13; + } + ad[k1] = d8; + k1++; + } + + } + + } + + return ad; + } + + public boolean chunkExists(int i, int j) + { + return true; + } + + public void populate(IChunkProvider ichunkprovider, int i, int j) + { + BlockSand.fallInstantly = true; + int k = i * 16; + int l = j * 16; + MobSpawnerBase mobspawnerbase = worldObj.getWorldChunkManager().func_4073_a(k + 16, l + 16); + rand.setSeed(worldObj.func_22138_q()); + long l1 = (rand.nextLong() / 2L) * 2L + 1L; + long l2 = (rand.nextLong() / 2L) * 2L + 1L; + rand.setSeed((long)i * l1 + (long)j * l2 ^ worldObj.func_22138_q()); + double d = 0.25D; + if(rand.nextInt(4) == 0) + { + int i1 = k + rand.nextInt(16) + 8; + int l4 = rand.nextInt(128); + int i8 = l + rand.nextInt(16) + 8; + (new WorldGenLakes(Block.waterMoving.blockID)).generate(worldObj, rand, i1, l4, i8); + } + if(rand.nextInt(8) == 0) + { + int j1 = k + rand.nextInt(16) + 8; + int i5 = rand.nextInt(rand.nextInt(120) + 8); + int j8 = l + rand.nextInt(16) + 8; + if(i5 < 64 || rand.nextInt(10) == 0) + { + (new WorldGenLakes(Block.lavaMoving.blockID)).generate(worldObj, rand, j1, i5, j8); + } + } + for(int k1 = 0; k1 < 8; k1++) + { + int j5 = k + rand.nextInt(16) + 8; + int k8 = rand.nextInt(128); + int i13 = l + rand.nextInt(16) + 8; + (new WorldGenDungeons()).generate(worldObj, rand, j5, k8, i13); + } + + for(int i2 = 0; i2 < 10; i2++) + { + int k5 = k + rand.nextInt(16); + int l8 = rand.nextInt(128); + int j13 = l + rand.nextInt(16); + (new WorldGenClay(32)).generate(worldObj, rand, k5, l8, j13); + } + + for(int j2 = 0; j2 < 20; j2++) + { + int l5 = k + rand.nextInt(16); + int i9 = rand.nextInt(128); + int k13 = l + rand.nextInt(16); + (new WorldGenMinable(Block.dirt.blockID, 32)).generate(worldObj, rand, l5, i9, k13); + } + + for(int k2 = 0; k2 < 10; k2++) + { + int i6 = k + rand.nextInt(16); + int j9 = rand.nextInt(128); + int l13 = l + rand.nextInt(16); + (new WorldGenMinable(Block.gravel.blockID, 32)).generate(worldObj, rand, i6, j9, l13); + } + + for(int i3 = 0; i3 < 20; i3++) + { + int j6 = k + rand.nextInt(16); + int k9 = rand.nextInt(128); + int i14 = l + rand.nextInt(16); + (new WorldGenMinable(Block.oreCoal.blockID, 16)).generate(worldObj, rand, j6, k9, i14); + } + + for(int j3 = 0; j3 < 20; j3++) + { + int k6 = k + rand.nextInt(16); + int l9 = rand.nextInt(64); + int j14 = l + rand.nextInt(16); + (new WorldGenMinable(Block.oreIron.blockID, 8)).generate(worldObj, rand, k6, l9, j14); + } + + for(int k3 = 0; k3 < 2; k3++) + { + int l6 = k + rand.nextInt(16); + int i10 = rand.nextInt(32); + int k14 = l + rand.nextInt(16); + (new WorldGenMinable(Block.oreGold.blockID, 8)).generate(worldObj, rand, l6, i10, k14); + } + + for(int l3 = 0; l3 < 8; l3++) + { + int i7 = k + rand.nextInt(16); + int j10 = rand.nextInt(16); + int l14 = l + rand.nextInt(16); + (new WorldGenMinable(Block.oreRedstone.blockID, 7)).generate(worldObj, rand, i7, j10, l14); + } + + for(int i4 = 0; i4 < 1; i4++) + { + int j7 = k + rand.nextInt(16); + int k10 = rand.nextInt(16); + int i15 = l + rand.nextInt(16); + (new WorldGenMinable(Block.oreDiamond.blockID, 7)).generate(worldObj, rand, j7, k10, i15); + } + + for(int j4 = 0; j4 < 1; j4++) + { + int k7 = k + rand.nextInt(16); + int l10 = rand.nextInt(16) + rand.nextInt(16); + int j15 = l + rand.nextInt(16); + (new WorldGenMinable(Block.oreLapis.blockID, 6)).generate(worldObj, rand, k7, l10, j15); + } + + d = 0.5D; + int k4 = (int)((mobSpawnerNoise.func_806_a((double)k * d, (double)l * d) / 8D + rand.nextDouble() * 4D + 4D) / 3D); + int l7 = 0; + if(rand.nextInt(10) == 0) + { + l7++; + } + if(mobspawnerbase == MobSpawnerBase.forest) + { + l7 += k4 + 5; + } + if(mobspawnerbase == MobSpawnerBase.rainforest) + { + l7 += k4 + 5; + } + if(mobspawnerbase == MobSpawnerBase.seasonalForest) + { + l7 += k4 + 2; + } + if(mobspawnerbase == MobSpawnerBase.taiga) + { + l7 += k4 + 5; + } + if(mobspawnerbase == MobSpawnerBase.desert) + { + l7 -= 20; + } + if(mobspawnerbase == MobSpawnerBase.tundra) + { + l7 -= 20; + } + if(mobspawnerbase == MobSpawnerBase.plains) + { + l7 -= 20; + } + for(int i11 = 0; i11 < l7; i11++) + { + int k15 = k + rand.nextInt(16) + 8; + int j18 = l + rand.nextInt(16) + 8; + WorldGenerator worldgenerator = mobspawnerbase.getRandomWorldGenForTrees(rand); + worldgenerator.func_517_a(1.0D, 1.0D, 1.0D); + worldgenerator.generate(worldObj, rand, k15, worldObj.getHeightValue(k15, j18), j18); + } + + for(int j11 = 0; j11 < 2; j11++) + { + int l15 = k + rand.nextInt(16) + 8; + int k18 = rand.nextInt(128); + int i21 = l + rand.nextInt(16) + 8; + (new WorldGenFlowers(Block.plantYellow.blockID)).generate(worldObj, rand, l15, k18, i21); + } + + if(rand.nextInt(2) == 0) + { + int k11 = k + rand.nextInt(16) + 8; + int i16 = rand.nextInt(128); + int l18 = l + rand.nextInt(16) + 8; + (new WorldGenFlowers(Block.plantRed.blockID)).generate(worldObj, rand, k11, i16, l18); + } + if(rand.nextInt(4) == 0) + { + int l11 = k + rand.nextInt(16) + 8; + int j16 = rand.nextInt(128); + int i19 = l + rand.nextInt(16) + 8; + (new WorldGenFlowers(Block.mushroomBrown.blockID)).generate(worldObj, rand, l11, j16, i19); + } + if(rand.nextInt(8) == 0) + { + int i12 = k + rand.nextInt(16) + 8; + int k16 = rand.nextInt(128); + int j19 = l + rand.nextInt(16) + 8; + (new WorldGenFlowers(Block.mushroomRed.blockID)).generate(worldObj, rand, i12, k16, j19); + } + for(int j12 = 0; j12 < 10; j12++) + { + int l16 = k + rand.nextInt(16) + 8; + int k19 = rand.nextInt(128); + int j21 = l + rand.nextInt(16) + 8; + (new WorldGenReed()).generate(worldObj, rand, l16, k19, j21); + } + + if(rand.nextInt(32) == 0) + { + int k12 = k + rand.nextInt(16) + 8; + int i17 = rand.nextInt(128); + int l19 = l + rand.nextInt(16) + 8; + (new WorldGenPumpkin()).generate(worldObj, rand, k12, i17, l19); + } + int l12 = 0; + if(mobspawnerbase == MobSpawnerBase.desert) + { + l12 += 10; + } + for(int j17 = 0; j17 < l12; j17++) + { + int i20 = k + rand.nextInt(16) + 8; + int k21 = rand.nextInt(128); + int k22 = l + rand.nextInt(16) + 8; + (new WorldGenCactus()).generate(worldObj, rand, i20, k21, k22); + } + + for(int k17 = 0; k17 < 50; k17++) + { + int j20 = k + rand.nextInt(16) + 8; + int l21 = rand.nextInt(rand.nextInt(120) + 8); + int l22 = l + rand.nextInt(16) + 8; + (new WorldGenLiquids(Block.waterStill.blockID)).generate(worldObj, rand, j20, l21, l22); + } + + for(int l17 = 0; l17 < 20; l17++) + { + int k20 = k + rand.nextInt(16) + 8; + int i22 = rand.nextInt(rand.nextInt(rand.nextInt(112) + 8) + 8); + int i23 = l + rand.nextInt(16) + 8; + (new WorldGenLiquids(Block.lavaStill.blockID)).generate(worldObj, rand, k20, i22, i23); + } + + generatedTemperatures = worldObj.getWorldChunkManager().getTemperatures(generatedTemperatures, k + 8, l + 8, 16, 16); + for(int i18 = k + 8; i18 < k + 8 + 16; i18++) + { + for(int l20 = l + 8; l20 < l + 8 + 16; l20++) + { + int j22 = i18 - (k + 8); + int j23 = l20 - (l + 8); + int k23 = worldObj.findTopSolidBlock(i18, l20); + double d1 = generatedTemperatures[j22 * 16 + j23] - ((double)(k23 - 64) / 64D) * 0.29999999999999999D; + if(d1 < 0.5D && k23 > 0 && k23 < 128 && worldObj.isAirBlock(i18, k23, l20) && worldObj.getBlockMaterial(i18, k23 - 1, l20).getIsSolid() && worldObj.getBlockMaterial(i18, k23 - 1, l20) != Material.ice) + { + worldObj.setBlockWithNotify(i18, k23, l20, Block.snow.blockID); + } + } + + } + + BlockSand.fallInstantly = false; + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) + { + return true; + } + + public boolean func_532_a() + { + return false; + } + + public boolean func_536_b() + { + return true; + } + + public String toString() + { + return "RandomLevelSource"; + } + + private Random rand; + private NoiseGeneratorOctaves field_912_k; + private NoiseGeneratorOctaves field_911_l; + private NoiseGeneratorOctaves field_910_m; + private NoiseGeneratorOctaves field_909_n; + private NoiseGeneratorOctaves field_908_o; + public NoiseGeneratorOctaves field_922_a; + public NoiseGeneratorOctaves field_921_b; + public NoiseGeneratorOctaves mobSpawnerNoise; + private World worldObj; + private double field_4180_q[]; + private double sandNoise[]; + private double gravelNoise[]; + private double stoneNoise[]; + private MapGenBase field_902_u; + private MobSpawnerBase biomesForGeneration[]; + double field_4185_d[]; + double field_4184_e[]; + double field_4183_f[]; + double field_4182_g[]; + double field_4181_h[]; + int field_914_i[][]; + private double generatedTemperatures[]; +} diff --git a/src/main/java/net/minecraft/src/ChunkProviderHell.java b/src/main/java/net/minecraft/src/ChunkProviderHell.java new file mode 100644 index 0000000..daeee27 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkProviderHell.java @@ -0,0 +1,422 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ChunkProviderHell + implements IChunkProvider +{ + + public ChunkProviderHell(World world, long l) + { + field_4162_p = new double[256]; + field_4161_q = new double[256]; + field_4160_r = new double[256]; + field_4159_s = new MapGenCavesHell(); + field_4164_n = world; + hellRNG = new Random(l); + field_4169_i = new NoiseGeneratorOctaves(hellRNG, 16); + field_4168_j = new NoiseGeneratorOctaves(hellRNG, 16); + field_4167_k = new NoiseGeneratorOctaves(hellRNG, 8); + field_4166_l = new NoiseGeneratorOctaves(hellRNG, 4); + field_4165_m = new NoiseGeneratorOctaves(hellRNG, 4); + field_4177_a = new NoiseGeneratorOctaves(hellRNG, 10); + field_4176_b = new NoiseGeneratorOctaves(hellRNG, 16); + } + + public void func_4059_a(int i, int j, byte abyte0[]) + { + byte byte0 = 4; + byte byte1 = 32; + int k = byte0 + 1; + byte byte2 = 17; + int l = byte0 + 1; + field_4163_o = func_4057_a(field_4163_o, i * byte0, 0, j * byte0, k, byte2, l); + for(int i1 = 0; i1 < byte0; i1++) + { + for(int j1 = 0; j1 < byte0; j1++) + { + for(int k1 = 0; k1 < 16; k1++) + { + double d = 0.125D; + double d1 = field_4163_o[((i1 + 0) * l + (j1 + 0)) * byte2 + (k1 + 0)]; + double d2 = field_4163_o[((i1 + 0) * l + (j1 + 1)) * byte2 + (k1 + 0)]; + double d3 = field_4163_o[((i1 + 1) * l + (j1 + 0)) * byte2 + (k1 + 0)]; + double d4 = field_4163_o[((i1 + 1) * l + (j1 + 1)) * byte2 + (k1 + 0)]; + double d5 = (field_4163_o[((i1 + 0) * l + (j1 + 0)) * byte2 + (k1 + 1)] - d1) * d; + double d6 = (field_4163_o[((i1 + 0) * l + (j1 + 1)) * byte2 + (k1 + 1)] - d2) * d; + double d7 = (field_4163_o[((i1 + 1) * l + (j1 + 0)) * byte2 + (k1 + 1)] - d3) * d; + double d8 = (field_4163_o[((i1 + 1) * l + (j1 + 1)) * byte2 + (k1 + 1)] - d4) * d; + for(int l1 = 0; l1 < 8; l1++) + { + double d9 = 0.25D; + double d10 = d1; + double d11 = d2; + double d12 = (d3 - d1) * d9; + double d13 = (d4 - d2) * d9; + for(int i2 = 0; i2 < 4; i2++) + { + int j2 = i2 + i1 * 4 << 11 | 0 + j1 * 4 << 7 | k1 * 8 + l1; + char c = '\200'; + double d14 = 0.25D; + double d15 = d10; + double d16 = (d11 - d10) * d14; + for(int k2 = 0; k2 < 4; k2++) + { + int l2 = 0; + if(k1 * 8 + l1 < byte1) + { + l2 = Block.lavaMoving.blockID; + } + if(d15 > 0.0D) + { + l2 = Block.bloodStone.blockID; + } + abyte0[j2] = (byte)l2; + j2 += c; + d15 += d16; + } + + d10 += d12; + d11 += d13; + } + + d1 += d5; + d2 += d6; + d3 += d7; + d4 += d8; + } + + } + + } + + } + + } + + public void func_4058_b(int i, int j, byte abyte0[]) + { + byte byte0 = 64; + double d = 0.03125D; + field_4162_p = field_4166_l.generateNoiseOctaves(field_4162_p, i * 16, j * 16, 0.0D, 16, 16, 1, d, d, 1.0D); + field_4161_q = field_4166_l.generateNoiseOctaves(field_4161_q, i * 16, 109.0134D, j * 16, 16, 1, 16, d, 1.0D, d); + field_4160_r = field_4165_m.generateNoiseOctaves(field_4160_r, i * 16, j * 16, 0.0D, 16, 16, 1, d * 2D, d * 2D, d * 2D); + for(int k = 0; k < 16; k++) + { + for(int l = 0; l < 16; l++) + { + boolean flag = field_4162_p[k + l * 16] + hellRNG.nextDouble() * 0.20000000000000001D > 0.0D; + boolean flag1 = field_4161_q[k + l * 16] + hellRNG.nextDouble() * 0.20000000000000001D > 0.0D; + int i1 = (int)(field_4160_r[k + l * 16] / 3D + 3D + hellRNG.nextDouble() * 0.25D); + int j1 = -1; + byte byte1 = (byte)Block.bloodStone.blockID; + byte byte2 = (byte)Block.bloodStone.blockID; + for(int k1 = 127; k1 >= 0; k1--) + { + int l1 = (l * 16 + k) * 128 + k1; + if(k1 >= 127 - hellRNG.nextInt(5)) + { + abyte0[l1] = (byte)Block.bedrock.blockID; + continue; + } + if(k1 <= 0 + hellRNG.nextInt(5)) + { + abyte0[l1] = (byte)Block.bedrock.blockID; + continue; + } + byte byte3 = abyte0[l1]; + if(byte3 == 0) + { + j1 = -1; + continue; + } + if(byte3 != Block.bloodStone.blockID) + { + continue; + } + if(j1 == -1) + { + if(i1 <= 0) + { + byte1 = 0; + byte2 = (byte)Block.bloodStone.blockID; + } else + if(k1 >= byte0 - 4 && k1 <= byte0 + 1) + { + byte1 = (byte)Block.bloodStone.blockID; + byte2 = (byte)Block.bloodStone.blockID; + if(flag1) + { + byte1 = (byte)Block.gravel.blockID; + } + if(flag1) + { + byte2 = (byte)Block.bloodStone.blockID; + } + if(flag) + { + byte1 = (byte)Block.slowSand.blockID; + } + if(flag) + { + byte2 = (byte)Block.slowSand.blockID; + } + } + if(k1 < byte0 && byte1 == 0) + { + byte1 = (byte)Block.lavaMoving.blockID; + } + j1 = i1; + if(k1 >= byte0 - 1) + { + abyte0[l1] = byte1; + } else + { + abyte0[l1] = byte2; + } + continue; + } + if(j1 > 0) + { + j1--; + abyte0[l1] = byte2; + } + } + + } + + } + + } + + public Chunk provideChunk(int i, int j) + { + hellRNG.setSeed((long)i * 0x4f9939f508L + (long)j * 0x1ef1565bd5L); + byte abyte0[] = new byte[32768]; + func_4059_a(i, j, abyte0); + func_4058_b(i, j, abyte0); + field_4159_s.func_867_a(this, field_4164_n, i, j, abyte0); + Chunk chunk = new Chunk(field_4164_n, abyte0, i, j); + return chunk; + } + + private double[] func_4057_a(double ad[], int i, int j, int k, int l, int i1, int j1) + { + if(ad == null) + { + ad = new double[l * i1 * j1]; + } + double d = 684.41200000000003D; + double d1 = 2053.2359999999999D; + field_4172_f = field_4177_a.generateNoiseOctaves(field_4172_f, i, j, k, l, 1, j1, 1.0D, 0.0D, 1.0D); + field_4171_g = field_4176_b.generateNoiseOctaves(field_4171_g, i, j, k, l, 1, j1, 100D, 0.0D, 100D); + field_4175_c = field_4167_k.generateNoiseOctaves(field_4175_c, i, j, k, l, i1, j1, d / 80D, d1 / 60D, d / 80D); + field_4174_d = field_4169_i.generateNoiseOctaves(field_4174_d, i, j, k, l, i1, j1, d, d1, d); + field_4173_e = field_4168_j.generateNoiseOctaves(field_4173_e, i, j, k, l, i1, j1, d, d1, d); + int k1 = 0; + int l1 = 0; + double ad1[] = new double[i1]; + for(int i2 = 0; i2 < i1; i2++) + { + ad1[i2] = Math.cos(((double)i2 * 3.1415926535897931D * 6D) / (double)i1) * 2D; + double d2 = i2; + if(i2 > i1 / 2) + { + d2 = i1 - 1 - i2; + } + if(d2 < 4D) + { + d2 = 4D - d2; + ad1[i2] -= d2 * d2 * d2 * 10D; + } + } + + for(int j2 = 0; j2 < l; j2++) + { + for(int k2 = 0; k2 < j1; k2++) + { + double d3 = (field_4172_f[l1] + 256D) / 512D; + if(d3 > 1.0D) + { + d3 = 1.0D; + } + double d4 = 0.0D; + double d5 = field_4171_g[l1] / 8000D; + if(d5 < 0.0D) + { + d5 = -d5; + } + d5 = d5 * 3D - 3D; + if(d5 < 0.0D) + { + d5 /= 2D; + if(d5 < -1D) + { + d5 = -1D; + } + d5 /= 1.3999999999999999D; + d5 /= 2D; + d3 = 0.0D; + } else + { + if(d5 > 1.0D) + { + d5 = 1.0D; + } + d5 /= 6D; + } + d3 += 0.5D; + d5 = (d5 * (double)i1) / 16D; + l1++; + for(int l2 = 0; l2 < i1; l2++) + { + double d6 = 0.0D; + double d7 = ad1[l2]; + double d8 = field_4174_d[k1] / 512D; + double d9 = field_4173_e[k1] / 512D; + double d10 = (field_4175_c[k1] / 10D + 1.0D) / 2D; + if(d10 < 0.0D) + { + d6 = d8; + } else + if(d10 > 1.0D) + { + d6 = d9; + } else + { + d6 = d8 + (d9 - d8) * d10; + } + d6 -= d7; + if(l2 > i1 - 4) + { + double d11 = (float)(l2 - (i1 - 4)) / 3F; + d6 = d6 * (1.0D - d11) + -10D * d11; + } + if((double)l2 < d4) + { + double d12 = (d4 - (double)l2) / 4D; + if(d12 < 0.0D) + { + d12 = 0.0D; + } + if(d12 > 1.0D) + { + d12 = 1.0D; + } + d6 = d6 * (1.0D - d12) + -10D * d12; + } + ad[k1] = d6; + k1++; + } + + } + + } + + return ad; + } + + public boolean chunkExists(int i, int j) + { + return true; + } + + public void populate(IChunkProvider ichunkprovider, int i, int j) + { + BlockSand.fallInstantly = true; + int k = i * 16; + int l = j * 16; + for(int i1 = 0; i1 < 8; i1++) + { + int k1 = k + hellRNG.nextInt(16) + 8; + int i3 = hellRNG.nextInt(120) + 4; + int k4 = l + hellRNG.nextInt(16) + 8; + (new WorldGenHellLava(Block.lavaStill.blockID)).generate(field_4164_n, hellRNG, k1, i3, k4); + } + + int j1 = hellRNG.nextInt(hellRNG.nextInt(10) + 1) + 1; + for(int l1 = 0; l1 < j1; l1++) + { + int j3 = k + hellRNG.nextInt(16) + 8; + int l4 = hellRNG.nextInt(120) + 4; + int i6 = l + hellRNG.nextInt(16) + 8; + (new WorldGenFire()).generate(field_4164_n, hellRNG, j3, l4, i6); + } + + j1 = hellRNG.nextInt(hellRNG.nextInt(10) + 1); + for(int i2 = 0; i2 < j1; i2++) + { + int k3 = k + hellRNG.nextInt(16) + 8; + int i5 = hellRNG.nextInt(120) + 4; + int j6 = l + hellRNG.nextInt(16) + 8; + (new WorldGenLightStone1()).generate(field_4164_n, hellRNG, k3, i5, j6); + } + + for(int j2 = 0; j2 < 10; j2++) + { + int l3 = k + hellRNG.nextInt(16) + 8; + int j5 = hellRNG.nextInt(128); + int k6 = l + hellRNG.nextInt(16) + 8; + (new WorldGenLightStone2()).generate(field_4164_n, hellRNG, l3, j5, k6); + } + + if(hellRNG.nextInt(1) == 0) + { + int k2 = k + hellRNG.nextInt(16) + 8; + int i4 = hellRNG.nextInt(128); + int k5 = l + hellRNG.nextInt(16) + 8; + (new WorldGenFlowers(Block.mushroomBrown.blockID)).generate(field_4164_n, hellRNG, k2, i4, k5); + } + if(hellRNG.nextInt(1) == 0) + { + int l2 = k + hellRNG.nextInt(16) + 8; + int j4 = hellRNG.nextInt(128); + int l5 = l + hellRNG.nextInt(16) + 8; + (new WorldGenFlowers(Block.mushroomRed.blockID)).generate(field_4164_n, hellRNG, l2, j4, l5); + } + BlockSand.fallInstantly = false; + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) + { + return true; + } + + public boolean func_532_a() + { + return false; + } + + public boolean func_536_b() + { + return true; + } + + public String toString() + { + return "HellRandomLevelSource"; + } + + private Random hellRNG; + private NoiseGeneratorOctaves field_4169_i; + private NoiseGeneratorOctaves field_4168_j; + private NoiseGeneratorOctaves field_4167_k; + private NoiseGeneratorOctaves field_4166_l; + private NoiseGeneratorOctaves field_4165_m; + public NoiseGeneratorOctaves field_4177_a; + public NoiseGeneratorOctaves field_4176_b; + private World field_4164_n; + private double field_4163_o[]; + private double field_4162_p[]; + private double field_4161_q[]; + private double field_4160_r[]; + private MapGenBase field_4159_s; + double field_4175_c[]; + double field_4174_d[]; + double field_4173_e[]; + double field_4172_f[]; + double field_4171_g[]; +} diff --git a/src/main/java/net/minecraft/src/ChunkProviderLoadOrGenerate.java b/src/main/java/net/minecraft/src/ChunkProviderLoadOrGenerate.java new file mode 100644 index 0000000..6e87f37 --- /dev/null +++ b/src/main/java/net/minecraft/src/ChunkProviderLoadOrGenerate.java @@ -0,0 +1,265 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.IOException; + +public class ChunkProviderLoadOrGenerate + implements IChunkProvider +{ + + public ChunkProviderLoadOrGenerate(World world, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) + { + chunks = new Chunk[1024]; + lastQueriedChunkXPos = 0xc4653601; + lastQueriedChunkZPos = 0xc4653601; + blankChunk = new EmptyChunk(world, new byte[32768], 0, 0); + worldObj = world; + chunkLoader = ichunkloader; + chunkProvider = ichunkprovider; + } + + public void func_21110_c(int i, int j) + { + field_21113_i = i; + field_21112_j = j; + } + + public boolean func_21111_d(int i, int j) + { + byte byte0 = 15; + return i >= field_21113_i - byte0 && j >= field_21112_j - byte0 && i <= field_21113_i + byte0 && j <= field_21112_j + byte0; + } + + public boolean chunkExists(int i, int j) + { + if(!func_21111_d(i, j)) + { + return false; + } + if(i == lastQueriedChunkXPos && j == lastQueriedChunkZPos && lastQueriedChunk != null) + { + return true; + } else + { + int k = i & 0x1f; + int l = j & 0x1f; + int i1 = k + l * 32; + return chunks[i1] != null && (chunks[i1] == blankChunk || chunks[i1].isAtLocation(i, j)); + } + } + + public Chunk provideChunk(int i, int j) + { + if(i == lastQueriedChunkXPos && j == lastQueriedChunkZPos && lastQueriedChunk != null) + { + return lastQueriedChunk; + } + if(!worldObj.field_9430_x && !func_21111_d(i, j)) + { + return blankChunk; + } + int k = i & 0x1f; + int l = j & 0x1f; + int i1 = k + l * 32; + if(!chunkExists(i, j)) + { + if(chunks[i1] != null) + { + chunks[i1].onChunkUnload(); + saveChunk(chunks[i1]); + saveExtraChunkData(chunks[i1]); + } + Chunk chunk = func_542_c(i, j); + if(chunk == null) + { + if(chunkProvider == null) + { + chunk = blankChunk; + } else + { + chunk = chunkProvider.provideChunk(i, j); + } + } + chunks[i1] = chunk; + chunk.func_4143_d(); + if(chunks[i1] != null) + { + chunks[i1].onChunkLoad(); + } + if(!chunks[i1].isTerrainPopulated && chunkExists(i + 1, j + 1) && chunkExists(i, j + 1) && chunkExists(i + 1, j)) + { + populate(this, i, j); + } + if(chunkExists(i - 1, j) && !provideChunk(i - 1, j).isTerrainPopulated && chunkExists(i - 1, j + 1) && chunkExists(i, j + 1) && chunkExists(i - 1, j)) + { + populate(this, i - 1, j); + } + if(chunkExists(i, j - 1) && !provideChunk(i, j - 1).isTerrainPopulated && chunkExists(i + 1, j - 1) && chunkExists(i, j - 1) && chunkExists(i + 1, j)) + { + populate(this, i, j - 1); + } + if(chunkExists(i - 1, j - 1) && !provideChunk(i - 1, j - 1).isTerrainPopulated && chunkExists(i - 1, j - 1) && chunkExists(i, j - 1) && chunkExists(i - 1, j)) + { + populate(this, i - 1, j - 1); + } + } + lastQueriedChunkXPos = i; + lastQueriedChunkZPos = j; + lastQueriedChunk = chunks[i1]; + return chunks[i1]; + } + + private Chunk func_542_c(int i, int j) + { + if(chunkLoader == null) + { + return blankChunk; + } + try + { + Chunk chunk = chunkLoader.loadChunk(worldObj, i, j); + if(chunk != null) + { + chunk.lastSaveTime = worldObj.func_22139_r(); + } + return chunk; + } + catch(Exception exception) + { + exception.printStackTrace(); + } + return blankChunk; + } + + private void saveExtraChunkData(Chunk chunk) + { + if(chunkLoader == null) + { + return; + } + try + { + chunkLoader.saveExtraChunkData(worldObj, chunk); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + private void saveChunk(Chunk chunk) + { + if(chunkLoader == null) + { + return; + } + try + { + chunk.lastSaveTime = worldObj.func_22139_r(); + chunkLoader.saveChunk(worldObj, chunk); + } + catch(Throwable ioexception) + { + ioexception.printStackTrace(); + } + } + + public void populate(IChunkProvider ichunkprovider, int i, int j) + { + Chunk chunk = provideChunk(i, j); + if(!chunk.isTerrainPopulated) + { + chunk.isTerrainPopulated = true; + if(chunkProvider != null) + { + chunkProvider.populate(ichunkprovider, i, j); + chunk.setChunkModified(); + } + } + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) + { + int i = 0; + int j = 0; + if(iprogressupdate != null) + { + for(int k = 0; k < chunks.length; k++) + { + if(chunks[k] != null && chunks[k].needsSaving(flag)) + { + j++; + } + } + + } + int l = 0; + for(int i1 = 0; i1 < chunks.length; i1++) + { + if(chunks[i1] == null) + { + continue; + } + if(flag && !chunks[i1].neverSave) + { + saveExtraChunkData(chunks[i1]); + } + if(!chunks[i1].needsSaving(flag)) + { + continue; + } + saveChunk(chunks[i1]); + chunks[i1].isModified = false; + if(++i == 2 && !flag) + { + return false; + } + if(iprogressupdate != null && ++l % 10 == 0) + { + iprogressupdate.setLoadingProgress((l * 100) / j); + } + } + + if(flag) + { + if(chunkLoader == null) + { + return true; + } + chunkLoader.saveExtraData(); + } + return true; + } + + public boolean func_532_a() + { + if(chunkLoader != null) + { + chunkLoader.func_814_a(); + } + return chunkProvider.func_532_a(); + } + + public boolean func_536_b() + { + return true; + } + + public String toString() + { + return (new StringBuilder()).append("ChunkCache: ").append(chunks.length).toString(); + } + + private Chunk blankChunk; + private IChunkProvider chunkProvider; + private IChunkLoader chunkLoader; + private Chunk chunks[]; + private World worldObj; + int lastQueriedChunkXPos; + int lastQueriedChunkZPos; + private Chunk lastQueriedChunk; + private int field_21113_i; + private int field_21112_j; +} diff --git a/src/main/java/net/minecraft/src/ClippingHelper.java b/src/main/java/net/minecraft/src/ClippingHelper.java new file mode 100644 index 0000000..b01f79e --- /dev/null +++ b/src/main/java/net/minecraft/src/ClippingHelper.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ClippingHelper +{ + + public ClippingHelper() + { + frustum = new float[16][16]; + projectionMatrix = new float[16]; + modelviewMatrix = new float[16]; + clippingMatrix = new float[16]; + } + + public boolean isBoxInFrustum(double d, double d1, double d2, double d3, double d4, double d5) + { + for(int i = 0; i < 6; i++) + { + if((double)frustum[i][0] * d + (double)frustum[i][1] * d1 + (double)frustum[i][2] * d2 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d3 + (double)frustum[i][1] * d1 + (double)frustum[i][2] * d2 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d + (double)frustum[i][1] * d4 + (double)frustum[i][2] * d2 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d3 + (double)frustum[i][1] * d4 + (double)frustum[i][2] * d2 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d + (double)frustum[i][1] * d1 + (double)frustum[i][2] * d5 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d3 + (double)frustum[i][1] * d1 + (double)frustum[i][2] * d5 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d + (double)frustum[i][1] * d4 + (double)frustum[i][2] * d5 + (double)frustum[i][3] <= 0.0D && (double)frustum[i][0] * d3 + (double)frustum[i][1] * d4 + (double)frustum[i][2] * d5 + (double)frustum[i][3] <= 0.0D) + { + return false; + } + } + + return true; + } + + public float frustum[][]; + public float projectionMatrix[]; + public float modelviewMatrix[]; + public float clippingMatrix[]; +} diff --git a/src/main/java/net/minecraft/src/ClippingHelperImplementation.java b/src/main/java/net/minecraft/src/ClippingHelperImplementation.java new file mode 100644 index 0000000..4f089ce --- /dev/null +++ b/src/main/java/net/minecraft/src/ClippingHelperImplementation.java @@ -0,0 +1,99 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.nio.Buffer; +import java.nio.FloatBuffer; +import org.lwjgl.opengl.GL11; + +public class ClippingHelperImplementation extends ClippingHelper +{ + + public ClippingHelperImplementation() + { + projectionMatrixBuffer = GLAllocation.createDirectFloatBuffer(16); + modelviewMatrixBuffer = GLAllocation.createDirectFloatBuffer(16); + field_1691_h = GLAllocation.createDirectFloatBuffer(16); + } + + public static ClippingHelper getInstance() + { + instance.init(); + return instance; + } + + private void normalize(float af[][], int i) + { + float f = MathHelper.sqrt_float(af[i][0] * af[i][0] + af[i][1] * af[i][1] + af[i][2] * af[i][2]); + af[i][0] /= f; + af[i][1] /= f; + af[i][2] /= f; + af[i][3] /= f; + } + + private void init() + { + projectionMatrixBuffer.clear(); + modelviewMatrixBuffer.clear(); + field_1691_h.clear(); + GL11.glGetFloat(2983 /*GL_PROJECTION_MATRIX*/, projectionMatrixBuffer); + GL11.glGetFloat(2982 /*GL_MODELVIEW_MATRIX*/, modelviewMatrixBuffer); + projectionMatrixBuffer.flip().limit(16); + projectionMatrixBuffer.get(projectionMatrix); + modelviewMatrixBuffer.flip().limit(16); + modelviewMatrixBuffer.get(modelviewMatrix); + clippingMatrix[0] = modelviewMatrix[0] * projectionMatrix[0] + modelviewMatrix[1] * projectionMatrix[4] + modelviewMatrix[2] * projectionMatrix[8] + modelviewMatrix[3] * projectionMatrix[12]; + clippingMatrix[1] = modelviewMatrix[0] * projectionMatrix[1] + modelviewMatrix[1] * projectionMatrix[5] + modelviewMatrix[2] * projectionMatrix[9] + modelviewMatrix[3] * projectionMatrix[13]; + clippingMatrix[2] = modelviewMatrix[0] * projectionMatrix[2] + modelviewMatrix[1] * projectionMatrix[6] + modelviewMatrix[2] * projectionMatrix[10] + modelviewMatrix[3] * projectionMatrix[14]; + clippingMatrix[3] = modelviewMatrix[0] * projectionMatrix[3] + modelviewMatrix[1] * projectionMatrix[7] + modelviewMatrix[2] * projectionMatrix[11] + modelviewMatrix[3] * projectionMatrix[15]; + clippingMatrix[4] = modelviewMatrix[4] * projectionMatrix[0] + modelviewMatrix[5] * projectionMatrix[4] + modelviewMatrix[6] * projectionMatrix[8] + modelviewMatrix[7] * projectionMatrix[12]; + clippingMatrix[5] = modelviewMatrix[4] * projectionMatrix[1] + modelviewMatrix[5] * projectionMatrix[5] + modelviewMatrix[6] * projectionMatrix[9] + modelviewMatrix[7] * projectionMatrix[13]; + clippingMatrix[6] = modelviewMatrix[4] * projectionMatrix[2] + modelviewMatrix[5] * projectionMatrix[6] + modelviewMatrix[6] * projectionMatrix[10] + modelviewMatrix[7] * projectionMatrix[14]; + clippingMatrix[7] = modelviewMatrix[4] * projectionMatrix[3] + modelviewMatrix[5] * projectionMatrix[7] + modelviewMatrix[6] * projectionMatrix[11] + modelviewMatrix[7] * projectionMatrix[15]; + clippingMatrix[8] = modelviewMatrix[8] * projectionMatrix[0] + modelviewMatrix[9] * projectionMatrix[4] + modelviewMatrix[10] * projectionMatrix[8] + modelviewMatrix[11] * projectionMatrix[12]; + clippingMatrix[9] = modelviewMatrix[8] * projectionMatrix[1] + modelviewMatrix[9] * projectionMatrix[5] + modelviewMatrix[10] * projectionMatrix[9] + modelviewMatrix[11] * projectionMatrix[13]; + clippingMatrix[10] = modelviewMatrix[8] * projectionMatrix[2] + modelviewMatrix[9] * projectionMatrix[6] + modelviewMatrix[10] * projectionMatrix[10] + modelviewMatrix[11] * projectionMatrix[14]; + clippingMatrix[11] = modelviewMatrix[8] * projectionMatrix[3] + modelviewMatrix[9] * projectionMatrix[7] + modelviewMatrix[10] * projectionMatrix[11] + modelviewMatrix[11] * projectionMatrix[15]; + clippingMatrix[12] = modelviewMatrix[12] * projectionMatrix[0] + modelviewMatrix[13] * projectionMatrix[4] + modelviewMatrix[14] * projectionMatrix[8] + modelviewMatrix[15] * projectionMatrix[12]; + clippingMatrix[13] = modelviewMatrix[12] * projectionMatrix[1] + modelviewMatrix[13] * projectionMatrix[5] + modelviewMatrix[14] * projectionMatrix[9] + modelviewMatrix[15] * projectionMatrix[13]; + clippingMatrix[14] = modelviewMatrix[12] * projectionMatrix[2] + modelviewMatrix[13] * projectionMatrix[6] + modelviewMatrix[14] * projectionMatrix[10] + modelviewMatrix[15] * projectionMatrix[14]; + clippingMatrix[15] = modelviewMatrix[12] * projectionMatrix[3] + modelviewMatrix[13] * projectionMatrix[7] + modelviewMatrix[14] * projectionMatrix[11] + modelviewMatrix[15] * projectionMatrix[15]; + frustum[0][0] = clippingMatrix[3] - clippingMatrix[0]; + frustum[0][1] = clippingMatrix[7] - clippingMatrix[4]; + frustum[0][2] = clippingMatrix[11] - clippingMatrix[8]; + frustum[0][3] = clippingMatrix[15] - clippingMatrix[12]; + normalize(frustum, 0); + frustum[1][0] = clippingMatrix[3] + clippingMatrix[0]; + frustum[1][1] = clippingMatrix[7] + clippingMatrix[4]; + frustum[1][2] = clippingMatrix[11] + clippingMatrix[8]; + frustum[1][3] = clippingMatrix[15] + clippingMatrix[12]; + normalize(frustum, 1); + frustum[2][0] = clippingMatrix[3] + clippingMatrix[1]; + frustum[2][1] = clippingMatrix[7] + clippingMatrix[5]; + frustum[2][2] = clippingMatrix[11] + clippingMatrix[9]; + frustum[2][3] = clippingMatrix[15] + clippingMatrix[13]; + normalize(frustum, 2); + frustum[3][0] = clippingMatrix[3] - clippingMatrix[1]; + frustum[3][1] = clippingMatrix[7] - clippingMatrix[5]; + frustum[3][2] = clippingMatrix[11] - clippingMatrix[9]; + frustum[3][3] = clippingMatrix[15] - clippingMatrix[13]; + normalize(frustum, 3); + frustum[4][0] = clippingMatrix[3] - clippingMatrix[2]; + frustum[4][1] = clippingMatrix[7] - clippingMatrix[6]; + frustum[4][2] = clippingMatrix[11] - clippingMatrix[10]; + frustum[4][3] = clippingMatrix[15] - clippingMatrix[14]; + normalize(frustum, 4); + frustum[5][0] = clippingMatrix[3] + clippingMatrix[2]; + frustum[5][1] = clippingMatrix[7] + clippingMatrix[6]; + frustum[5][2] = clippingMatrix[11] + clippingMatrix[10]; + frustum[5][3] = clippingMatrix[15] + clippingMatrix[14]; + normalize(frustum, 5); + } + + private static ClippingHelperImplementation instance = new ClippingHelperImplementation(); + private FloatBuffer projectionMatrixBuffer; + private FloatBuffer modelviewMatrixBuffer; + private FloatBuffer field_1691_h; + +} diff --git a/src/main/java/net/minecraft/src/ColorizerFoliage.java b/src/main/java/net/minecraft/src/ColorizerFoliage.java new file mode 100644 index 0000000..8798df9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ColorizerFoliage.java @@ -0,0 +1,61 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +public class ColorizerFoliage +{ + + public ColorizerFoliage() + { + } + + public static int getFoliageColor(double d, double d1) + { + d1 *= d; + int i = (int)((1.0D - d) * 255D); + int j = (int)((1.0D - d1) * 255D); + return foliageBuffer[j << 8 | i]; + } + + public static int func_21175_a() + { + return 0x619961; + } + + public static int func_21174_b() + { + return 0x80a755; + } + + static Class _mthclass$(String s) + { + try + { + return Class.forName(s); + } + catch(ClassNotFoundException classnotfoundexception) + { + throw new NoClassDefFoundError(classnotfoundexception.getMessage()); + } + } + + private static final int foliageBuffer[]; + + static + { + foliageBuffer = new int[0x10000]; + try + { + BufferedImage bufferedimage = ImageIO.read((ColorizerFoliage.class).getResource("/misc/foliagecolor.png")); + bufferedimage.getRGB(0, 0, 256, 256, foliageBuffer, 0, 256); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } +} diff --git a/src/main/java/net/minecraft/src/ColorizerGrass.java b/src/main/java/net/minecraft/src/ColorizerGrass.java new file mode 100644 index 0000000..aa92eae --- /dev/null +++ b/src/main/java/net/minecraft/src/ColorizerGrass.java @@ -0,0 +1,51 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; + +public class ColorizerGrass +{ + + public ColorizerGrass() + { + } + + public static int getGrassColor(double d, double d1) + { + d1 *= d; + int i = (int)((1.0D - d) * 255D); + int j = (int)((1.0D - d1) * 255D); + return grassBuffer[j << 8 | i]; + } + + static Class _mthclass$(String s) + { + try + { + return Class.forName(s); + } + catch(ClassNotFoundException classnotfoundexception) + { + throw new NoClassDefFoundError(classnotfoundexception.getMessage()); + } + } + + private static final int grassBuffer[]; + + static + { + grassBuffer = new int[0x10000]; + try + { + BufferedImage bufferedimage = ImageIO.read((ColorizerFoliage.class).getResource("/misc/grasscolor.png")); + bufferedimage.getRGB(0, 0, 256, 256, grassBuffer, 0, 256); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } +} diff --git a/src/main/java/net/minecraft/src/CompressedStreamTools.java b/src/main/java/net/minecraft/src/CompressedStreamTools.java new file mode 100644 index 0000000..c97a632 --- /dev/null +++ b/src/main/java/net/minecraft/src/CompressedStreamTools.java @@ -0,0 +1,60 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class CompressedStreamTools +{ + + public CompressedStreamTools() + { + } + + public static NBTTagCompound func_1138_a(InputStream inputstream) throws IOException + { + DataInputStream datainputstream = new DataInputStream(new GZIPInputStream(inputstream)); + try + { + NBTTagCompound nbttagcompound = func_1141_a(datainputstream); + return nbttagcompound; + } + finally + { + datainputstream.close(); + } + } + + public static void writeGzippedCompoundToOutputStream(NBTTagCompound nbttagcompound, OutputStream outputstream) throws IOException + { + DataOutputStream dataoutputstream = new DataOutputStream(new GZIPOutputStream(outputstream)); + try + { + func_1139_a(nbttagcompound, dataoutputstream); + } + finally + { + dataoutputstream.close(); + } + } + + public static NBTTagCompound func_1141_a(DataInput datainput) throws IOException + { + NBTBase nbtbase = NBTBase.readTag(datainput); + if(nbtbase instanceof NBTTagCompound) + { + return (NBTTagCompound)nbtbase; + } else + { + throw new IOException("Root tag must be a named compound tag"); + } + } + + public static void func_1139_a(NBTTagCompound nbttagcompound, DataOutput dataoutput) throws IOException + { + NBTBase.writeTag(nbttagcompound, dataoutput); + } +} diff --git a/src/main/java/net/minecraft/src/CraftingInventoryCB.java b/src/main/java/net/minecraft/src/CraftingInventoryCB.java new file mode 100644 index 0000000..fcbc9f5 --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingInventoryCB.java @@ -0,0 +1,220 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public abstract class CraftingInventoryCB +{ + + public CraftingInventoryCB() + { + field_20123_d = new ArrayList(); + slots = new ArrayList(); + windowId = 0; + field_20917_a = 0; + field_20121_g = new ArrayList(); + field_20918_b = new HashSet(); + } + + protected void func_20117_a(Slot slot) + { + slot.field_20007_a = slots.size(); + slots.add(slot); + field_20123_d.add(null); + } + + public void func_20114_a() + { + for(int i = 0; i < slots.size(); i++) + { + ItemStack itemstack = ((Slot)slots.get(i)).getStack(); + ItemStack itemstack1 = (ItemStack)field_20123_d.get(i); + if(ItemStack.areItemStacksEqual(itemstack1, itemstack)) + { + continue; + } + itemstack1 = itemstack != null ? itemstack.copy() : null; + field_20123_d.set(i, itemstack1); + for(int j = 0; j < field_20121_g.size(); j++) + { + ((ICrafting)field_20121_g.get(j)).func_20159_a(this, i, itemstack1); + } + + } + + } + + public Slot getSlot(int i) + { + return (Slot)slots.get(i); + } + + public ItemStack func_20116_a(int i, int j, EntityPlayer entityplayer) + { + ItemStack itemstack = null; + if(j == 0 || j == 1) + { + InventoryPlayer inventoryplayer = entityplayer.inventory; + if(i == -999) + { + if(inventoryplayer.getItemStack() != null && i == -999) + { + if(j == 0) + { + entityplayer.dropPlayerItem(inventoryplayer.getItemStack()); + inventoryplayer.setItemStack(null); + } + if(j == 1) + { + entityplayer.dropPlayerItem(inventoryplayer.getItemStack().splitStack(1)); + if(inventoryplayer.getItemStack().stackSize == 0) + { + inventoryplayer.setItemStack(null); + } + } + } + } else + { + Slot slot = (Slot)slots.get(i); + if(slot != null) + { + slot.onSlotChanged(); + ItemStack itemstack1 = slot.getStack(); + ItemStack itemstack2 = inventoryplayer.getItemStack(); + if(itemstack1 != null) + { + itemstack = itemstack1.copy(); + } + if(itemstack1 == null) + { + if(itemstack2 != null && slot.isItemValid(itemstack2)) + { + int k = j != 0 ? 1 : itemstack2.stackSize; + if(k > slot.getSlotStackLimit()) + { + k = slot.getSlotStackLimit(); + } + slot.putStack(itemstack2.splitStack(k)); + if(itemstack2.stackSize == 0) + { + inventoryplayer.setItemStack(null); + } + } + } else + if(itemstack2 == null) + { + int l = j != 0 ? (itemstack1.stackSize + 1) / 2 : itemstack1.stackSize; + inventoryplayer.setItemStack(slot.decrStackSize(l)); + if(itemstack1.stackSize == 0) + { + slot.putStack(null); + } + slot.onPickupFromSlot(); + } else + if(slot.isItemValid(itemstack2)) + { + if(itemstack1.itemID != itemstack2.itemID || itemstack1.getHasSubtypes() && itemstack1.getItemDamage() != itemstack2.getItemDamage()) + { + if(itemstack2.stackSize <= slot.getSlotStackLimit()) + { + ItemStack itemstack3 = itemstack1; + slot.putStack(itemstack2); + inventoryplayer.setItemStack(itemstack3); + } + } else + { + int i1 = j != 0 ? 1 : itemstack2.stackSize; + if(i1 > slot.getSlotStackLimit() - itemstack1.stackSize) + { + i1 = slot.getSlotStackLimit() - itemstack1.stackSize; + } + if(i1 > itemstack2.getMaxStackSize() - itemstack1.stackSize) + { + i1 = itemstack2.getMaxStackSize() - itemstack1.stackSize; + } + itemstack2.splitStack(i1); + if(itemstack2.stackSize == 0) + { + inventoryplayer.setItemStack(null); + } + itemstack1.stackSize += i1; + } + } else + if(itemstack1.itemID == itemstack2.itemID && itemstack2.getMaxStackSize() > 1 && (!itemstack1.getHasSubtypes() || itemstack1.getItemDamage() == itemstack2.getItemDamage())) + { + int j1 = itemstack1.stackSize; + if(j1 > 0 && j1 + itemstack2.stackSize <= itemstack2.getMaxStackSize()) + { + itemstack2.stackSize += j1; + itemstack1.splitStack(j1); + if(itemstack1.stackSize == 0) + { + slot.putStack(null); + } + slot.onPickupFromSlot(); + } + } + } + } + } + return itemstack; + } + + public void onCraftGuiClosed(EntityPlayer entityplayer) + { + InventoryPlayer inventoryplayer = entityplayer.inventory; + if(inventoryplayer.getItemStack() != null) + { + entityplayer.dropPlayerItem(inventoryplayer.getItemStack()); + inventoryplayer.setItemStack(null); + } + } + + public void onCraftMatrixChanged(IInventory iinventory) + { + func_20114_a(); + } + + public void putStackInSlot(int i, ItemStack itemstack) + { + getSlot(i).putStack(itemstack); + } + + public void putStacksInSlots(ItemStack aitemstack[]) + { + for(int i = 0; i < aitemstack.length; i++) + { + getSlot(i).putStack(aitemstack[i]); + } + + } + + public void func_20112_a(int i, int j) + { + } + + public short func_20111_a(InventoryPlayer inventoryplayer) + { + field_20917_a++; + return field_20917_a; + } + + public void func_20113_a(short word0) + { + } + + public void func_20110_b(short word0) + { + } + + public abstract boolean func_20120_b(EntityPlayer entityplayer); + + public List field_20123_d; + public List slots; + public int windowId; + private short field_20917_a; + protected List field_20121_g; + private Set field_20918_b; +} diff --git a/src/main/java/net/minecraft/src/CraftingInventoryChestCB.java b/src/main/java/net/minecraft/src/CraftingInventoryChestCB.java new file mode 100644 index 0000000..03c24c5 --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingInventoryChestCB.java @@ -0,0 +1,46 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class CraftingInventoryChestCB extends CraftingInventoryCB +{ + + public CraftingInventoryChestCB(IInventory iinventory, IInventory iinventory1) + { + field_20125_a = iinventory1; + int i = iinventory1.getSizeInventory() / 9; + int j = (i - 4) * 18; + for(int k = 0; k < i; k++) + { + for(int j1 = 0; j1 < 9; j1++) + { + func_20117_a(new Slot(iinventory1, j1 + k * 9, 8 + j1 * 18, 18 + k * 18)); + } + + } + + for(int l = 0; l < 3; l++) + { + for(int k1 = 0; k1 < 9; k1++) + { + func_20117_a(new Slot(iinventory, k1 + l * 9 + 9, 8 + k1 * 18, 103 + l * 18 + j)); + } + + } + + for(int i1 = 0; i1 < 9; i1++) + { + func_20117_a(new Slot(iinventory, i1, 8 + i1 * 18, 161 + j)); + } + + } + + public boolean func_20120_b(EntityPlayer entityplayer) + { + return field_20125_a.canInteractWith(entityplayer); + } + + private IInventory field_20125_a; +} diff --git a/src/main/java/net/minecraft/src/CraftingInventoryDispenserCB.java b/src/main/java/net/minecraft/src/CraftingInventoryDispenserCB.java new file mode 100644 index 0000000..bb016ca --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingInventoryDispenserCB.java @@ -0,0 +1,44 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class CraftingInventoryDispenserCB extends CraftingInventoryCB +{ + + public CraftingInventoryDispenserCB(IInventory iinventory, TileEntityDispenser tileentitydispenser) + { + field_21149_a = tileentitydispenser; + for(int i = 0; i < 3; i++) + { + for(int l = 0; l < 3; l++) + { + func_20117_a(new Slot(tileentitydispenser, l + i * 3, 61 + l * 18, 17 + i * 18)); + } + + } + + for(int j = 0; j < 3; j++) + { + for(int i1 = 0; i1 < 9; i1++) + { + func_20117_a(new Slot(iinventory, i1 + j * 9 + 9, 8 + i1 * 18, 84 + j * 18)); + } + + } + + for(int k = 0; k < 9; k++) + { + func_20117_a(new Slot(iinventory, k, 8 + k * 18, 142)); + } + + } + + public boolean func_20120_b(EntityPlayer entityplayer) + { + return field_21149_a.canInteractWith(entityplayer); + } + + private TileEntityDispenser field_21149_a; +} diff --git a/src/main/java/net/minecraft/src/CraftingInventoryFurnaceCB.java b/src/main/java/net/minecraft/src/CraftingInventoryFurnaceCB.java new file mode 100644 index 0000000..a884cfe --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingInventoryFurnaceCB.java @@ -0,0 +1,86 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public class CraftingInventoryFurnaceCB extends CraftingInventoryCB +{ + + public CraftingInventoryFurnaceCB(IInventory iinventory, TileEntityFurnace tileentityfurnace) + { + field_20126_b = 0; + field_20129_c = 0; + field_20128_h = 0; + field_20127_a = tileentityfurnace; + func_20117_a(new Slot(tileentityfurnace, 0, 56, 17)); + func_20117_a(new Slot(tileentityfurnace, 1, 56, 53)); + func_20117_a(new Slot(tileentityfurnace, 2, 116, 35)); + for(int i = 0; i < 3; i++) + { + for(int k = 0; k < 9; k++) + { + func_20117_a(new Slot(iinventory, k + i * 9 + 9, 8 + k * 18, 84 + i * 18)); + } + + } + + for(int j = 0; j < 9; j++) + { + func_20117_a(new Slot(iinventory, j, 8 + j * 18, 142)); + } + + } + + public void func_20114_a() + { + super.func_20114_a(); + for(int i = 0; i < field_20121_g.size(); i++) + { + ICrafting icrafting = (ICrafting)field_20121_g.get(i); + if(field_20126_b != field_20127_a.furnaceCookTime) + { + icrafting.func_20158_a(this, 0, field_20127_a.furnaceCookTime); + } + if(field_20129_c != field_20127_a.furnaceBurnTime) + { + icrafting.func_20158_a(this, 1, field_20127_a.furnaceBurnTime); + } + if(field_20128_h != field_20127_a.currentItemBurnTime) + { + icrafting.func_20158_a(this, 2, field_20127_a.currentItemBurnTime); + } + } + + field_20126_b = field_20127_a.furnaceCookTime; + field_20129_c = field_20127_a.furnaceBurnTime; + field_20128_h = field_20127_a.currentItemBurnTime; + } + + public void func_20112_a(int i, int j) + { + if(i == 0) + { + field_20127_a.furnaceCookTime = j; + } + if(i == 1) + { + field_20127_a.furnaceBurnTime = j; + } + if(i == 2) + { + field_20127_a.currentItemBurnTime = j; + } + } + + public boolean func_20120_b(EntityPlayer entityplayer) + { + return field_20127_a.canInteractWith(entityplayer); + } + + private TileEntityFurnace field_20127_a; + private int field_20126_b; + private int field_20129_c; + private int field_20128_h; +} diff --git a/src/main/java/net/minecraft/src/CraftingInventoryPlayerCB.java b/src/main/java/net/minecraft/src/CraftingInventoryPlayerCB.java new file mode 100644 index 0000000..8ca8689 --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingInventoryPlayerCB.java @@ -0,0 +1,82 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class CraftingInventoryPlayerCB extends CraftingInventoryCB +{ + + public CraftingInventoryPlayerCB(InventoryPlayer inventoryplayer) + { + this(inventoryplayer, true); + } + + public CraftingInventoryPlayerCB(InventoryPlayer inventoryplayer, boolean flag) + { + craftMatrix = new InventoryCrafting(this, 2, 2); + craftResult = new InventoryCraftResult(); + isSinglePlayer = false; + isSinglePlayer = flag; + func_20117_a(new SlotCrafting(craftMatrix, craftResult, 0, 144, 36)); + for(int i = 0; i < 2; i++) + { + for(int i1 = 0; i1 < 2; i1++) + { + func_20117_a(new Slot(craftMatrix, i1 + i * 2, 88 + i1 * 18, 26 + i * 18)); + } + + } + + for(int j = 0; j < 4; j++) + { + int j1 = j; + func_20117_a(new SlotArmor(this, inventoryplayer, inventoryplayer.getSizeInventory() - 1 - j, 8, 8 + j * 18, j1)); + } + + for(int k = 0; k < 3; k++) + { + for(int k1 = 0; k1 < 9; k1++) + { + func_20117_a(new Slot(inventoryplayer, k1 + (k + 1) * 9, 8 + k1 * 18, 84 + k * 18)); + } + + } + + for(int l = 0; l < 9; l++) + { + func_20117_a(new Slot(inventoryplayer, l, 8 + l * 18, 142)); + } + + onCraftMatrixChanged(craftMatrix); + } + + public void onCraftMatrixChanged(IInventory iinventory) + { + craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(craftMatrix)); + } + + public void onCraftGuiClosed(EntityPlayer entityplayer) + { + super.onCraftGuiClosed(entityplayer); + for(int i = 0; i < 4; i++) + { + ItemStack itemstack = craftMatrix.getStackInSlot(i); + if(itemstack != null) + { + entityplayer.dropPlayerItem(itemstack); + craftMatrix.setInventorySlotContents(i, null); + } + } + + } + + public boolean func_20120_b(EntityPlayer entityplayer) + { + return true; + } + + public InventoryCrafting craftMatrix; + public IInventory craftResult; + public boolean isSinglePlayer; +} diff --git a/src/main/java/net/minecraft/src/CraftingInventoryWorkbenchCB.java b/src/main/java/net/minecraft/src/CraftingInventoryWorkbenchCB.java new file mode 100644 index 0000000..2672c02 --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingInventoryWorkbenchCB.java @@ -0,0 +1,79 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class CraftingInventoryWorkbenchCB extends CraftingInventoryCB +{ + + public CraftingInventoryWorkbenchCB(InventoryPlayer inventoryplayer, World world, int i, int j, int k) + { + craftMatrix = new InventoryCrafting(this, 3, 3); + craftResult = new InventoryCraftResult(); + field_20133_c = world; + field_20132_h = i; + field_20131_i = j; + field_20130_j = k; + func_20117_a(new SlotCrafting(craftMatrix, craftResult, 0, 124, 35)); + for(int l = 0; l < 3; l++) + { + for(int k1 = 0; k1 < 3; k1++) + { + func_20117_a(new Slot(craftMatrix, k1 + l * 3, 30 + k1 * 18, 17 + l * 18)); + } + + } + + for(int i1 = 0; i1 < 3; i1++) + { + for(int l1 = 0; l1 < 9; l1++) + { + func_20117_a(new Slot(inventoryplayer, l1 + i1 * 9 + 9, 8 + l1 * 18, 84 + i1 * 18)); + } + + } + + for(int j1 = 0; j1 < 9; j1++) + { + func_20117_a(new Slot(inventoryplayer, j1, 8 + j1 * 18, 142)); + } + + onCraftMatrixChanged(craftMatrix); + } + + public void onCraftMatrixChanged(IInventory iinventory) + { + craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(craftMatrix)); + } + + public void onCraftGuiClosed(EntityPlayer entityplayer) + { + super.onCraftGuiClosed(entityplayer); + for(int i = 0; i < 9; i++) + { + ItemStack itemstack = craftMatrix.getStackInSlot(i); + if(itemstack != null) + { + entityplayer.dropPlayerItem(itemstack); + } + } + + } + + public boolean func_20120_b(EntityPlayer entityplayer) + { + if(field_20133_c.getBlockId(field_20132_h, field_20131_i, field_20130_j) != Block.workbench.blockID) + { + return false; + } + return entityplayer.getDistanceSq((double)field_20132_h + 0.5D, (double)field_20131_i + 0.5D, (double)field_20130_j + 0.5D) <= 64D; + } + + public InventoryCrafting craftMatrix; + public IInventory craftResult; + private World field_20133_c; + private int field_20132_h; + private int field_20131_i; + private int field_20130_j; +} diff --git a/src/main/java/net/minecraft/src/CraftingManager.java b/src/main/java/net/minecraft/src/CraftingManager.java new file mode 100644 index 0000000..8824751 --- /dev/null +++ b/src/main/java/net/minecraft/src/CraftingManager.java @@ -0,0 +1,295 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.*; + +public class CraftingManager +{ + + public static final CraftingManager getInstance() + { + return instance; + } + + private CraftingManager() + { + recipes = new ArrayList(); + (new RecipesTools()).addRecipes(this); + (new RecipesWeapons()).addRecipes(this); + (new RecipesIngots()).addRecipes(this); + (new RecipesFood()).addRecipes(this); + (new RecipesCrafting()).addRecipes(this); + (new RecipesArmor()).addRecipes(this); + (new RecipesDyes()).addRecipes(this); + addRecipe(new ItemStack(Item.paper, 3), new Object[] { + "###", Character.valueOf('#'), Item.reed + }); + addRecipe(new ItemStack(Item.book, 1), new Object[] { + "#", "#", "#", Character.valueOf('#'), Item.paper + }); + addRecipe(new ItemStack(Block.fence, 2), new Object[] { + "###", "###", Character.valueOf('#'), Item.stick + }); + addRecipe(new ItemStack(Block.jukebox, 1), new Object[] { + "###", "#X#", "###", Character.valueOf('#'), Block.planks, Character.valueOf('X'), Item.diamond + }); + addRecipe(new ItemStack(Block.musicBlock, 1), new Object[] { + "###", "#X#", "###", Character.valueOf('#'), Block.planks, Character.valueOf('X'), Item.redstone + }); + addRecipe(new ItemStack(Block.bookShelf, 1), new Object[] { + "###", "XXX", "###", Character.valueOf('#'), Block.planks, Character.valueOf('X'), Item.book + }); + addRecipe(new ItemStack(Block.blockSnow, 1), new Object[] { + "##", "##", Character.valueOf('#'), Item.snowball + }); + addRecipe(new ItemStack(Block.blockClay, 1), new Object[] { + "##", "##", Character.valueOf('#'), Item.clay + }); + addRecipe(new ItemStack(Block.brick, 1), new Object[] { + "##", "##", Character.valueOf('#'), Item.brick + }); + addRecipe(new ItemStack(Block.lightStone, 1), new Object[] { + "###", "###", "###", Character.valueOf('#'), Item.lightStoneDust + }); + addRecipe(new ItemStack(Block.cloth, 1), new Object[] { + "###", "###", "###", Character.valueOf('#'), Item.silk + }); + addRecipe(new ItemStack(Block.tnt, 1), new Object[] { + "X#X", "#X#", "X#X", Character.valueOf('X'), Item.gunpowder, Character.valueOf('#'), Block.sand + }); + addRecipe(new ItemStack(Block.stairSingle, 3, 3), new Object[] { + "###", Character.valueOf('#'), Block.cobblestone + }); + addRecipe(new ItemStack(Block.stairSingle, 3, 0), new Object[] { + "###", Character.valueOf('#'), Block.stone + }); + addRecipe(new ItemStack(Block.stairSingle, 3, 1), new Object[] { + "###", Character.valueOf('#'), Block.sandStone + }); + addRecipe(new ItemStack(Block.stairSingle, 3, 2), new Object[] { + "###", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Block.ladder, 1), new Object[] { + "# #", "###", "# #", Character.valueOf('#'), Item.stick + }); + addRecipe(new ItemStack(Item.doorWood, 1), new Object[] { + "##", "##", "##", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Item.doorSteel, 1), new Object[] { + "##", "##", "##", Character.valueOf('#'), Item.ingotIron + }); + addRecipe(new ItemStack(Item.sign, 1), new Object[] { + "###", "###", " X ", Character.valueOf('#'), Block.planks, Character.valueOf('X'), Item.stick + }); + addRecipe(new ItemStack(Item.cake, 1), new Object[] { + "AAA", "BEB", "CCC", Character.valueOf('A'), Item.bucketMilk, Character.valueOf('B'), Item.sugar, Character.valueOf('C'), Item.wheat, Character.valueOf('E'), + Item.egg + }); + addRecipe(new ItemStack(Item.sugar, 1), new Object[] { + "#", Character.valueOf('#'), Item.reed + }); + addRecipe(new ItemStack(Block.planks, 4), new Object[] { + "#", Character.valueOf('#'), Block.wood + }); + addRecipe(new ItemStack(Item.stick, 4), new Object[] { + "#", "#", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Block.torchWood, 4), new Object[] { + "X", "#", Character.valueOf('X'), Item.coal, Character.valueOf('#'), Item.stick + }); + addRecipe(new ItemStack(Block.torchWood, 4), new Object[] { + "X", "#", Character.valueOf('X'), new ItemStack(Item.coal, 1, 1), Character.valueOf('#'), Item.stick + }); + addRecipe(new ItemStack(Item.bowlEmpty, 4), new Object[] { + "# #", " # ", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Block.minecartTrack, 16), new Object[] { + "X X", "X#X", "X X", Character.valueOf('X'), Item.ingotIron, Character.valueOf('#'), Item.stick + }); + addRecipe(new ItemStack(Item.minecartEmpty, 1), new Object[] { + "# #", "###", Character.valueOf('#'), Item.ingotIron + }); + addRecipe(new ItemStack(Block.pumpkinLantern, 1), new Object[] { + "A", "B", Character.valueOf('A'), Block.pumpkin, Character.valueOf('B'), Block.torchWood + }); + addRecipe(new ItemStack(Item.minecartCrate, 1), new Object[] { + "A", "B", Character.valueOf('A'), Block.crate, Character.valueOf('B'), Item.minecartEmpty + }); + addRecipe(new ItemStack(Item.minecartPowered, 1), new Object[] { + "A", "B", Character.valueOf('A'), Block.stoneOvenIdle, Character.valueOf('B'), Item.minecartEmpty + }); + addRecipe(new ItemStack(Item.boat, 1), new Object[] { + "# #", "###", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Item.bucketEmpty, 1), new Object[] { + "# #", " # ", Character.valueOf('#'), Item.ingotIron + }); + addRecipe(new ItemStack(Item.flintAndSteel, 1), new Object[] { + "A ", " B", Character.valueOf('A'), Item.ingotIron, Character.valueOf('B'), Item.flint + }); + addRecipe(new ItemStack(Item.bread, 1), new Object[] { + "###", Character.valueOf('#'), Item.wheat + }); + addRecipe(new ItemStack(Block.stairCompactPlanks, 4), new Object[] { + "# ", "## ", "###", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Item.fishingRod, 1), new Object[] { + " #", " #X", "# X", Character.valueOf('#'), Item.stick, Character.valueOf('X'), Item.silk + }); + addRecipe(new ItemStack(Block.stairCompactCobblestone, 4), new Object[] { + "# ", "## ", "###", Character.valueOf('#'), Block.cobblestone + }); + addRecipe(new ItemStack(Item.painting, 1), new Object[] { + "###", "#X#", "###", Character.valueOf('#'), Item.stick, Character.valueOf('X'), Block.cloth + }); + addRecipe(new ItemStack(Item.appleGold, 1), new Object[] { + "###", "#X#", "###", Character.valueOf('#'), Block.blockGold, Character.valueOf('X'), Item.appleRed + }); + addRecipe(new ItemStack(Block.lever, 1), new Object[] { + "X", "#", Character.valueOf('#'), Block.cobblestone, Character.valueOf('X'), Item.stick + }); + addRecipe(new ItemStack(Block.torchRedstoneActive, 1), new Object[] { + "X", "#", Character.valueOf('#'), Item.stick, Character.valueOf('X'), Item.redstone + }); + addRecipe(new ItemStack(Item.field_22018_aZ, 1), new Object[] { + "#X#", "III", Character.valueOf('#'), Block.torchRedstoneActive, Character.valueOf('X'), Item.redstone, Character.valueOf('I'), Block.stone + }); + addRecipe(new ItemStack(Item.pocketSundial, 1), new Object[] { + " # ", "#X#", " # ", Character.valueOf('#'), Item.ingotGold, Character.valueOf('X'), Item.redstone + }); + addRecipe(new ItemStack(Item.compass, 1), new Object[] { + " # ", "#X#", " # ", Character.valueOf('#'), Item.ingotIron, Character.valueOf('X'), Item.redstone + }); + addRecipe(new ItemStack(Block.button, 1), new Object[] { + "#", "#", Character.valueOf('#'), Block.stone + }); + addRecipe(new ItemStack(Block.pressurePlateStone, 1), new Object[] { + "##", Character.valueOf('#'), Block.stone + }); + addRecipe(new ItemStack(Block.pressurePlatePlanks, 1), new Object[] { + "##", Character.valueOf('#'), Block.planks + }); + addRecipe(new ItemStack(Block.dispenser, 1), new Object[] { + "###", "#X#", "#R#", Character.valueOf('#'), Block.cobblestone, Character.valueOf('X'), Item.bow, Character.valueOf('R'), Item.redstone + }); + addRecipe(new ItemStack(Item.field_22019_aY, 1), new Object[] { + "###", "XXX", Character.valueOf('#'), Block.cloth, Character.valueOf('X'), Block.planks + }); + Collections.sort(recipes, new RecipeSorter(this)); + System.out.println((new StringBuilder()).append(recipes.size()).append(" recipes").toString()); + } + + void addRecipe(ItemStack itemstack, Object aobj[]) + { + String s = ""; + int i = 0; + int j = 0; + int k = 0; + if(aobj[i] instanceof String[]) + { + String as[] = (String[])aobj[i++]; + for(int l = 0; l < as.length; l++) + { + String s2 = as[l]; + k++; + j = s2.length(); + s = (new StringBuilder()).append(s).append(s2).toString(); + } + + } else + { + while(aobj[i] instanceof String) + { + String s1 = (String)aobj[i++]; + k++; + j = s1.length(); + s = (new StringBuilder()).append(s).append(s1).toString(); + } + } + HashMap hashmap = new HashMap(); + for(; i < aobj.length; i += 2) + { + Character character = (Character)aobj[i]; + ItemStack itemstack1 = null; + if(aobj[i + 1] instanceof Item) + { + itemstack1 = new ItemStack((Item)aobj[i + 1]); + } else + if(aobj[i + 1] instanceof Block) + { + itemstack1 = new ItemStack((Block)aobj[i + 1], 1, -1); + } else + if(aobj[i + 1] instanceof ItemStack) + { + itemstack1 = (ItemStack)aobj[i + 1]; + } + hashmap.put(character, itemstack1); + } + + ItemStack aitemstack[] = new ItemStack[j * k]; + for(int i1 = 0; i1 < j * k; i1++) + { + char c = s.charAt(i1); + if(hashmap.containsKey(Character.valueOf(c))) + { + aitemstack[i1] = ((ItemStack)hashmap.get(Character.valueOf(c))).copy(); + } else + { + aitemstack[i1] = null; + } + } + + recipes.add(new ShapedRecipes(j, k, aitemstack, itemstack)); + } + + void addShapelessRecipe(ItemStack itemstack, Object aobj[]) + { + ArrayList arraylist = new ArrayList(); + Object aobj1[] = aobj; + int i = aobj1.length; + for(int j = 0; j < i; j++) + { + Object obj = aobj1[j]; + if(obj instanceof ItemStack) + { + arraylist.add(((ItemStack)obj).copy()); + continue; + } + if(obj instanceof Item) + { + arraylist.add(new ItemStack((Item)obj)); + continue; + } + if(obj instanceof Block) + { + arraylist.add(new ItemStack((Block)obj)); + } else + { + throw new RuntimeException("Invalid shapeless recipy!"); + } + } + + recipes.add(new ShapelessRecipes(itemstack, arraylist)); + } + + public ItemStack findMatchingRecipe(InventoryCrafting inventorycrafting) + { + for(int i = 0; i < recipes.size(); i++) + { + IRecipe irecipe = (IRecipe)recipes.get(i); + if(irecipe.func_21135_a(inventorycrafting)) + { + return irecipe.func_21136_b(inventorycrafting); + } + } + + return null; + } + + private static final CraftingManager instance = new CraftingManager(); + private List recipes; + +} diff --git a/src/main/java/net/minecraft/src/DataWatcher.java b/src/main/java/net/minecraft/src/DataWatcher.java new file mode 100644 index 0000000..fa6cbb4 --- /dev/null +++ b/src/main/java/net/minecraft/src/DataWatcher.java @@ -0,0 +1,238 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.*; + +import net.lax1dude.eaglercraft.compat.UnexpectedThrowable; + +public class DataWatcher +{ + + public DataWatcher() + { + } + + public void addObject(int i, Object obj) + { + Integer integer = (Integer)dataTypes.get(obj.getClass()); + if(integer == null) + { + throw new IllegalArgumentException((new StringBuilder()).append("Unknown data type: ").append(obj.getClass()).toString()); + } + if(i > 31) + { + throw new IllegalArgumentException((new StringBuilder()).append("Data value id is too big with ").append(i).append("! (Max is ").append(31).append(")").toString()); + } + if(watchedObjects.containsKey(Integer.valueOf(i))) + { + throw new IllegalArgumentException((new StringBuilder()).append("Duplicate id value for ").append(i).append("!").toString()); + } else + { + WatchableObject watchableobject = new WatchableObject(integer.intValue(), i, obj); + watchedObjects.put(Integer.valueOf(i), watchableobject); + return; + } + } + + public byte getWatchableObjectByte(int i) + { + return ((Byte)((WatchableObject)watchedObjects.get(Integer.valueOf(i))).getObject()).byteValue(); + } + + public void updateObject(int i, Object obj) + { + WatchableObject watchableobject = (WatchableObject)watchedObjects.get(Integer.valueOf(i)); + if(!obj.equals(watchableobject.getObject())) + { + watchableobject.setObject(obj); + watchableobject.setWatching(true); + objectChanged = true; + } + } + + public static void writeObjectsInListToStream(List list, DataOutputStream dataoutputstream) + { + if(list != null) + { + WatchableObject watchableobject; + for(Iterator iterator = list.iterator(); iterator.hasNext(); writeWatchableObject(dataoutputstream, watchableobject)) + { + watchableobject = (WatchableObject)iterator.next(); + } + + } + try { + dataoutputstream.writeByte(127); + }catch(Throwable t) { + throw new UnexpectedThrowable(t); + } + + } + + public void writeWatchableObjects(DataOutputStream dataoutputstream) + { + WatchableObject watchableobject; + for(Iterator iterator = watchedObjects.values().iterator(); iterator.hasNext(); writeWatchableObject(dataoutputstream, watchableobject)) + { + watchableobject = (WatchableObject)iterator.next(); + } + try { + dataoutputstream.writeByte(127); + }catch(Throwable t) { + throw new UnexpectedThrowable(t); + } + } + + private static void writeWatchableObject(DataOutputStream dataoutputstream, WatchableObject watchableobject) + { + try { + int i = (watchableobject.getObjectType() << 5 | watchableobject.getDataValueId() & 0x1f) & 0xff; + dataoutputstream.writeByte(i); + switch(watchableobject.getObjectType()) + { + case 0: // '\0' + dataoutputstream.writeByte(((Byte)watchableobject.getObject()).byteValue()); + break; + + case 1: // '\001' + dataoutputstream.writeShort(((Short)watchableobject.getObject()).shortValue()); + break; + + case 2: // '\002' + dataoutputstream.writeInt(((Integer)watchableobject.getObject()).intValue()); + break; + + case 3: // '\003' + dataoutputstream.writeFloat(((Float)watchableobject.getObject()).floatValue()); + break; + + case 4: // '\004' + dataoutputstream.writeUTF((String)watchableobject.getObject()); + break; + + case 5: // '\005' + ItemStack itemstack = (ItemStack)watchableobject.getObject(); + dataoutputstream.writeShort(itemstack.getItem().shiftedIndex); + dataoutputstream.writeByte(itemstack.stackSize); + dataoutputstream.writeShort(itemstack.getItemDamage()); + // fall through + + case 6: // '\006' + ChunkCoordinates chunkcoordinates = (ChunkCoordinates)watchableobject.getObject(); + dataoutputstream.writeInt(chunkcoordinates.field_22395_a); + dataoutputstream.writeInt(chunkcoordinates.field_22394_b); + dataoutputstream.writeInt(chunkcoordinates.field_22396_c); + break; + } + }catch(Throwable t) { + throw new UnexpectedThrowable(t); + } + } + + public static List readWatchableObjects(DataInputStream datainputstream) + { + try { + ArrayList arraylist = null; + for(byte byte0 = datainputstream.readByte(); byte0 != 127; byte0 = datainputstream.readByte()) + { + if(arraylist == null) + { + arraylist = new ArrayList(); + } + int i = (byte0 & 0xe0) >> 5; + int j = byte0 & 0x1f; + WatchableObject watchableobject = null; + switch(i) + { + case 0: // '\0' + watchableobject = new WatchableObject(i, j, Byte.valueOf(datainputstream.readByte())); + break; + + case 1: // '\001' + watchableobject = new WatchableObject(i, j, Short.valueOf(datainputstream.readShort())); + break; + + case 2: // '\002' + watchableobject = new WatchableObject(i, j, Integer.valueOf(datainputstream.readInt())); + break; + + case 3: // '\003' + watchableobject = new WatchableObject(i, j, Float.valueOf(datainputstream.readFloat())); + break; + + case 4: // '\004' + watchableobject = new WatchableObject(i, j, datainputstream.readUTF()); + break; + + case 5: // '\005' + short word0 = datainputstream.readShort(); + byte byte1 = datainputstream.readByte(); + short word1 = datainputstream.readShort(); + watchableobject = new WatchableObject(i, j, new ItemStack(word0, byte1, word1)); + // fall through + + case 6: // '\006' + int k = datainputstream.readInt(); + int l = datainputstream.readInt(); + int i1 = datainputstream.readInt(); + watchableobject = new WatchableObject(i, j, new ChunkCoordinates(k, l, i1)); + break; + } + arraylist.add(watchableobject); + } + + return arraylist; + }catch(Throwable t) { + throw new UnexpectedThrowable(t); + } + } + + public void updateWatchedObjectsFromList(List list) + { + Iterator iterator = list.iterator(); + do + { + if(!iterator.hasNext()) + { + break; + } + WatchableObject watchableobject = (WatchableObject)iterator.next(); + WatchableObject watchableobject1 = (WatchableObject)watchedObjects.get(Integer.valueOf(watchableobject.getDataValueId())); + if(watchableobject1 != null) + { + watchableobject1.setObject(watchableobject.getObject()); + } + } while(true); + } + + static Class _mthclass$(String s) + { + try + { + return Class.forName(s); + } + catch(ClassNotFoundException classnotfoundexception) + { + throw new NoClassDefFoundError(classnotfoundexception.getMessage()); + } + } + + private static final HashMap dataTypes; + private final Map watchedObjects = new HashMap(); + private boolean objectChanged; + + static + { + dataTypes = new HashMap(); + dataTypes.put(java.lang.Byte.class, Integer.valueOf(0)); + dataTypes.put(java.lang.Short.class, Integer.valueOf(1)); + dataTypes.put(java.lang.Integer.class, Integer.valueOf(2)); + dataTypes.put(java.lang.Float.class, Integer.valueOf(3)); + dataTypes.put(java.lang.String.class, Integer.valueOf(4)); + dataTypes.put(ItemStack.class, Integer.valueOf(5)); + dataTypes.put(ChunkCoordinates.class, Integer.valueOf(6)); + } +} diff --git a/src/main/java/net/minecraft/src/EffectRenderer.java b/src/main/java/net/minecraft/src/EffectRenderer.java new file mode 100644 index 0000000..d572d79 --- /dev/null +++ b/src/main/java/net/minecraft/src/EffectRenderer.java @@ -0,0 +1,196 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; +import org.lwjgl.opengl.GL11; + +public class EffectRenderer +{ + + public EffectRenderer(World world, RenderEngine renderengine) + { + fxLayers = new List[4]; + rand = new Random(); + if(world != null) + { + worldObj = world; + } + renderer = renderengine; + for(int i = 0; i < 4; i++) + { + fxLayers[i] = new ArrayList(); + } + + } + + public void addEffect(EntityFX entityfx) + { + int i = entityfx.getFXLayer(); + fxLayers[i].add(entityfx); + } + + public void updateEffects() + { + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < fxLayers[i].size(); j++) + { + EntityFX entityfx = (EntityFX)fxLayers[i].get(j); + entityfx.onUpdate(); + if(entityfx.isDead) + { + fxLayers[i].remove(j--); + } + } + + } + + } + + public void renderParticles(Entity entity, float f) + { + float f1 = MathHelper.cos((entity.rotationYaw * 3.141593F) / 180F); + float f2 = MathHelper.sin((entity.rotationYaw * 3.141593F) / 180F); + float f3 = -f2 * MathHelper.sin((entity.rotationPitch * 3.141593F) / 180F); + float f4 = f1 * MathHelper.sin((entity.rotationPitch * 3.141593F) / 180F); + float f5 = MathHelper.cos((entity.rotationPitch * 3.141593F) / 180F); + EntityFX.interpPosX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)f; + EntityFX.interpPosY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)f; + EntityFX.interpPosZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double)f; + for(int i = 0; i < 3; i++) + { + if(fxLayers[i].size() == 0) + { + continue; + } + int j = 0; + if(i == 0) + { + j = renderer.getTexture("/particles.png"); + } + if(i == 1) + { + j = renderer.getTexture("/terrain.png"); + } + if(i == 2) + { + j = renderer.getTexture("/gui/items.png"); + } + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, j); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + for(int k = 0; k < fxLayers[i].size(); k++) + { + EntityFX entityfx = (EntityFX)fxLayers[i].get(k); + entityfx.renderParticle(tessellator, f, f1, f5, f2, f3, f4); + } + + tessellator.draw(); + } + + } + + public void func_1187_b(Entity entity, float f) + { + byte byte0 = 3; + if(fxLayers[byte0].size() == 0) + { + return; + } + Tessellator tessellator = Tessellator.instance; + for(int i = 0; i < fxLayers[byte0].size(); i++) + { + EntityFX entityfx = (EntityFX)fxLayers[byte0].get(i); + entityfx.renderParticle(tessellator, f, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F); + } + + } + + public void clearEffects(World world) + { + worldObj = world; + for(int i = 0; i < 4; i++) + { + fxLayers[i].clear(); + } + + } + + public void addBlockDestroyEffects(int i, int j, int k) + { + int l = worldObj.getBlockId(i, j, k); + if(l == 0) + { + return; + } + Block block = Block.blocksList[l]; + int i1 = 4; + for(int j1 = 0; j1 < i1; j1++) + { + for(int k1 = 0; k1 < i1; k1++) + { + for(int l1 = 0; l1 < i1; l1++) + { + double d = (double)i + ((double)j1 + 0.5D) / (double)i1; + double d1 = (double)j + ((double)k1 + 0.5D) / (double)i1; + double d2 = (double)k + ((double)l1 + 0.5D) / (double)i1; + addEffect((new EntityDiggingFX(worldObj, d, d1, d2, d - (double)i - 0.5D, d1 - (double)j - 0.5D, d2 - (double)k - 0.5D, block)).func_4041_a(i, j, k)); + } + + } + + } + + } + + public void addBlockHitEffects(int i, int j, int k, int l) + { + int i1 = worldObj.getBlockId(i, j, k); + if(i1 == 0) + { + return; + } + Block block = Block.blocksList[i1]; + float f = 0.1F; + double d = (double)i + rand.nextDouble() * (block.maxX - block.minX - (double)(f * 2.0F)) + (double)f + block.minX; + double d1 = (double)j + rand.nextDouble() * (block.maxY - block.minY - (double)(f * 2.0F)) + (double)f + block.minY; + double d2 = (double)k + rand.nextDouble() * (block.maxZ - block.minZ - (double)(f * 2.0F)) + (double)f + block.minZ; + if(l == 0) + { + d1 = ((double)j + block.minY) - (double)f; + } + if(l == 1) + { + d1 = (double)j + block.maxY + (double)f; + } + if(l == 2) + { + d2 = ((double)k + block.minZ) - (double)f; + } + if(l == 3) + { + d2 = (double)k + block.maxZ + (double)f; + } + if(l == 4) + { + d = ((double)i + block.minX) - (double)f; + } + if(l == 5) + { + d = (double)i + block.maxX + (double)f; + } + addEffect((new EntityDiggingFX(worldObj, d, d1, d2, 0.0D, 0.0D, 0.0D, block)).func_4041_a(i, j, k).func_407_b(0.2F).func_405_d(0.6F)); + } + + public String getStatistics() + { + return (new StringBuilder()).append("").append(fxLayers[0].size() + fxLayers[1].size() + fxLayers[2].size()).toString(); + } + + protected World worldObj; + private List fxLayers[]; + private RenderEngine renderer; + private Random rand; +} diff --git a/src/main/java/net/minecraft/src/Empty1.java b/src/main/java/net/minecraft/src/Empty1.java new file mode 100644 index 0000000..1baf0b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/Empty1.java @@ -0,0 +1,9 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class Empty1 +{ +} diff --git a/src/main/java/net/minecraft/src/Empty2.java b/src/main/java/net/minecraft/src/Empty2.java new file mode 100644 index 0000000..4c7e078 --- /dev/null +++ b/src/main/java/net/minecraft/src/Empty2.java @@ -0,0 +1,9 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class Empty2 +{ +} diff --git a/src/main/java/net/minecraft/src/EmptyChunk.java b/src/main/java/net/minecraft/src/EmptyChunk.java new file mode 100644 index 0000000..a1eff33 --- /dev/null +++ b/src/main/java/net/minecraft/src/EmptyChunk.java @@ -0,0 +1,166 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EmptyChunk extends Chunk +{ + + public EmptyChunk(World world, int i, int j) + { + super(world, i, j); + neverSave = true; + } + + public EmptyChunk(World world, byte abyte0[], int i, int j) + { + super(world, abyte0, i, j); + neverSave = true; + } + + public boolean isAtLocation(int i, int j) + { + return i == xPosition && j == zPosition; + } + + public int getHeightValue(int i, int j) + { + return 0; + } + + public void func_1014_a() + { + } + + public void generateHeightMap() + { + } + + public void func_1024_c() + { + } + + public void func_4143_d() + { + } + + public int getBlockID(int i, int j, int k) + { + return 0; + } + + public boolean setBlockIDWithMetadata(int i, int j, int k, int l, int i1) + { + return true; + } + + public boolean setBlockID(int i, int j, int k, int l) + { + return true; + } + + public int getBlockMetadata(int i, int j, int k) + { + return 0; + } + + public void setBlockMetadata(int i, int j, int k, int l) + { + } + + public int getSavedLightValue(EnumSkyBlock enumskyblock, int i, int j, int k) + { + return 0; + } + + public void setLightValue(EnumSkyBlock enumskyblock, int i, int j, int k, int l) + { + } + + public int getBlockLightValue(int i, int j, int k, int l) + { + return 0; + } + + public void addEntity(Entity entity) + { + } + + public void func_1015_b(Entity entity) + { + } + + public void func_1016_a(Entity entity, int i) + { + } + + public boolean canBlockSeeTheSky(int i, int j, int k) + { + return false; + } + + public TileEntity getChunkBlockTileEntity(int i, int j, int k) + { + return null; + } + + public void func_1001_a(TileEntity tileentity) + { + } + + public void setChunkBlockTileEntity(int i, int j, int k, TileEntity tileentity) + { + } + + public void removeChunkBlockTileEntity(int i, int j, int k) + { + } + + public void onChunkLoad() + { + } + + public void onChunkUnload() + { + } + + public void setChunkModified() + { + } + + public void getEntitiesWithinAABBForEntity(Entity entity, AxisAlignedBB axisalignedbb, List list) + { + } + + public void getEntitiesOfTypeWithinAAAB(Class class1, AxisAlignedBB axisalignedbb, List list) + { + } + + public boolean needsSaving(boolean flag) + { + return false; + } + + public int setChunkData(byte abyte0[], int i, int j, int k, int l, int i1, int j1, + int k1) + { + int l1 = l - i; + int i2 = i1 - j; + int j2 = j1 - k; + int k2 = l1 * i2 * j2; + return k2 + (k2 / 2) * 3; + } + + public Random func_997_a(long l) + { + return new Random(worldObj.func_22138_q() + (long)(xPosition * xPosition * 0x4c1906) + (long)(xPosition * 0x5ac0db) + (long)(zPosition * zPosition) * 0x4307a7L + (long)(zPosition * 0x5f24f) ^ l); + } + + public boolean func_21167_h() + { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/Entity.java b/src/main/java/net/minecraft/src/Entity.java new file mode 100644 index 0000000..c83900d --- /dev/null +++ b/src/main/java/net/minecraft/src/Entity.java @@ -0,0 +1,1132 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public abstract class Entity +{ + + public Entity(World world) + { + entityId = nextEntityID++; + renderDistanceWeight = 1.0D; + preventEntitySpawning = false; + onGround = false; + isCollided = false; + beenAttacked = false; + field_9293_aM = true; + isDead = false; + yOffset = 0.0F; + width = 0.6F; + height = 1.8F; + prevDistanceWalkedModified = 0.0F; + distanceWalkedModified = 0.0F; + entityWalks = true; + fallDistance = 0.0F; + nextStepDistance = 1; + ySize = 0.0F; + stepHeight = 0.0F; + noClip = false; + entityCollisionReduction = 0.0F; + field_9313_bc = false; + rand = new Random(); + ticksExisted = 0; + fireResistance = 1; + fire = 0; + maxAir = 300; + inWater = false; + field_9306_bj = 0; + air = 300; + field_862_c = true; + isImmuneToFire = false; + dataWatcher = new DataWatcher(); + addedToChunk = false; + worldObj = world; + setPosition(0.0D, 0.0D, 0.0D); + dataWatcher.addObject(0, Byte.valueOf((byte)0)); + entityInit(); + } + + protected abstract void entityInit(); + + public DataWatcher getDataWatcher() + { + return dataWatcher; + } + + public boolean equals(Object obj) + { + if(obj instanceof Entity) + { + return ((Entity)obj).entityId == entityId; + } else + { + return false; + } + } + + public int hashCode() + { + return entityId; + } + + protected void preparePlayerToSpawn() + { + if(worldObj == null) + { + return; + } + do + { + if(posY <= 0.0D) + { + break; + } + setPosition(posX, posY, posZ); + if(worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0) + { + break; + } + posY++; + } while(true); + motionX = motionY = motionZ = 0.0D; + rotationPitch = 0.0F; + } + + public void setEntityDead() + { + isDead = true; + } + + protected void setSize(float f, float f1) + { + width = f; + height = f1; + } + + protected void setRotation(float f, float f1) + { + rotationYaw = f; + rotationPitch = f1; + } + + public void setPosition(double d, double d1, double d2) + { + posX = d; + posY = d1; + posZ = d2; + float f = width / 2.0F; + float f1 = height; + boundingBox.setBounds(d - (double)f, (d1 - (double)yOffset) + (double)ySize, d2 - (double)f, d + (double)f, (d1 - (double)yOffset) + (double)ySize + (double)f1, d2 + (double)f); + } + + public void func_346_d(float f, float f1) + { + float f2 = rotationPitch; + float f3 = rotationYaw; + rotationYaw += (double)f * 0.14999999999999999D; + rotationPitch -= (double)f1 * 0.14999999999999999D; + if(rotationPitch < -90F) + { + rotationPitch = -90F; + } + if(rotationPitch > 90F) + { + rotationPitch = 90F; + } + prevRotationPitch += rotationPitch - f2; + prevRotationYaw += rotationYaw - f3; + } + + public void onUpdate() + { + onEntityUpdate(); + } + + public void onEntityUpdate() + { + if(ridingEntity != null && ridingEntity.isDead) + { + ridingEntity = null; + } + ticksExisted++; + prevDistanceWalkedModified = distanceWalkedModified; + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + prevRotationPitch = rotationPitch; + prevRotationYaw = rotationYaw; + if(handleWaterMovement()) + { + if(!inWater && !field_862_c) + { + float f = MathHelper.sqrt_double(motionX * motionX * 0.20000000298023224D + motionY * motionY + motionZ * motionZ * 0.20000000298023224D) * 0.2F; + if(f > 1.0F) + { + f = 1.0F; + } + worldObj.playSoundAtEntity(this, "random.splash", f, 1.0F + (rand.nextFloat() - rand.nextFloat()) * 0.4F); + float f1 = MathHelper.floor_double(boundingBox.minY); + for(int i = 0; (float)i < 1.0F + width * 20F; i++) + { + float f2 = (rand.nextFloat() * 2.0F - 1.0F) * width; + float f4 = (rand.nextFloat() * 2.0F - 1.0F) * width; + worldObj.spawnParticle("bubble", posX + (double)f2, f1 + 1.0F, posZ + (double)f4, motionX, motionY - (double)(rand.nextFloat() * 0.2F), motionZ); + } + + for(int j = 0; (float)j < 1.0F + width * 20F; j++) + { + float f3 = (rand.nextFloat() * 2.0F - 1.0F) * width; + float f5 = (rand.nextFloat() * 2.0F - 1.0F) * width; + worldObj.spawnParticle("splash", posX + (double)f3, f1 + 1.0F, posZ + (double)f5, motionX, motionY, motionZ); + } + + } + fallDistance = 0.0F; + inWater = true; + fire = 0; + } else + { + inWater = false; + } + if(worldObj.multiplayerWorld) + { + fire = 0; + } else + if(fire > 0) + { + if(isImmuneToFire) + { + fire -= 4; + if(fire < 0) + { + fire = 0; + } + } else + { + if(fire % 20 == 0) + { + attackEntityFrom(null, 1); + } + fire--; + } + } + if(handleLavaMovement()) + { + setOnFireFromLava(); + } + if(posY < -64D) + { + kill(); + } + if(!worldObj.multiplayerWorld) + { + func_21059_b(0, fire > 0); + func_21059_b(2, ridingEntity != null); + } + field_862_c = false; + } + + protected void setOnFireFromLava() + { + if(!isImmuneToFire) + { + attackEntityFrom(null, 4); + fire = 600; + } + } + + protected void kill() + { + setEntityDead(); + } + + public boolean isOffsetPositionInLiquid(double d, double d1, double d2) + { + AxisAlignedBB axisalignedbb = boundingBox.getOffsetBoundingBox(d, d1, d2); + List list = worldObj.getCollidingBoundingBoxes(this, axisalignedbb); + if(list.size() > 0) + { + return false; + } + return !worldObj.getIsAnyLiquid(axisalignedbb); + } + + public void moveEntity(double d, double d1, double d2) + { + if(noClip) + { + boundingBox.offset(d, d1, d2); + posX = (boundingBox.minX + boundingBox.maxX) / 2D; + posY = (boundingBox.minY + (double)yOffset) - (double)ySize; + posZ = (boundingBox.minZ + boundingBox.maxZ) / 2D; + return; + } + double d3 = posX; + double d4 = posZ; + double d5 = d; + double d6 = d1; + double d7 = d2; + AxisAlignedBB axisalignedbb = boundingBox.copy(); + boolean flag = onGround && isSneaking(); + if(flag) + { + double d8 = 0.050000000000000003D; + for(; d != 0.0D && worldObj.getCollidingBoundingBoxes(this, boundingBox.getOffsetBoundingBox(d, -1D, 0.0D)).size() == 0; d5 = d) + { + if(d < d8 && d >= -d8) + { + d = 0.0D; + continue; + } + if(d > 0.0D) + { + d -= d8; + } else + { + d += d8; + } + } + + for(; d2 != 0.0D && worldObj.getCollidingBoundingBoxes(this, boundingBox.getOffsetBoundingBox(0.0D, -1D, d2)).size() == 0; d7 = d2) + { + if(d2 < d8 && d2 >= -d8) + { + d2 = 0.0D; + continue; + } + if(d2 > 0.0D) + { + d2 -= d8; + } else + { + d2 += d8; + } + } + + } + List list = worldObj.getCollidingBoundingBoxes(this, boundingBox.addCoord(d, d1, d2)); + for(int i = 0; i < list.size(); i++) + { + d1 = ((AxisAlignedBB)list.get(i)).calculateYOffset(boundingBox, d1); + } + + boundingBox.offset(0.0D, d1, 0.0D); + if(!field_9293_aM && d6 != d1) + { + d = d1 = d2 = 0.0D; + } + boolean flag1 = onGround || d6 != d1 && d6 < 0.0D; + for(int j = 0; j < list.size(); j++) + { + d = ((AxisAlignedBB)list.get(j)).calculateXOffset(boundingBox, d); + } + + boundingBox.offset(d, 0.0D, 0.0D); + if(!field_9293_aM && d5 != d) + { + d = d1 = d2 = 0.0D; + } + for(int k = 0; k < list.size(); k++) + { + d2 = ((AxisAlignedBB)list.get(k)).calculateZOffset(boundingBox, d2); + } + + boundingBox.offset(0.0D, 0.0D, d2); + if(!field_9293_aM && d7 != d2) + { + d = d1 = d2 = 0.0D; + } + if(stepHeight > 0.0F && flag1 && ySize < 0.05F && (d5 != d || d7 != d2)) + { + double d9 = d; + double d11 = d1; + double d13 = d2; + d = d5; + d1 = stepHeight; + d2 = d7; + AxisAlignedBB axisalignedbb1 = boundingBox.copy(); + boundingBox.setBB(axisalignedbb); + List list1 = worldObj.getCollidingBoundingBoxes(this, boundingBox.addCoord(d, d1, d2)); + for(int j2 = 0; j2 < list1.size(); j2++) + { + d1 = ((AxisAlignedBB)list1.get(j2)).calculateYOffset(boundingBox, d1); + } + + boundingBox.offset(0.0D, d1, 0.0D); + if(!field_9293_aM && d6 != d1) + { + d = d1 = d2 = 0.0D; + } + for(int k2 = 0; k2 < list1.size(); k2++) + { + d = ((AxisAlignedBB)list1.get(k2)).calculateXOffset(boundingBox, d); + } + + boundingBox.offset(d, 0.0D, 0.0D); + if(!field_9293_aM && d5 != d) + { + d = d1 = d2 = 0.0D; + } + for(int l2 = 0; l2 < list1.size(); l2++) + { + d2 = ((AxisAlignedBB)list1.get(l2)).calculateZOffset(boundingBox, d2); + } + + boundingBox.offset(0.0D, 0.0D, d2); + if(!field_9293_aM && d7 != d2) + { + d = d1 = d2 = 0.0D; + } + if(d9 * d9 + d13 * d13 >= d * d + d2 * d2) + { + d = d9; + d1 = d11; + d2 = d13; + boundingBox.setBB(axisalignedbb1); + } else + { + ySize += 0.5D; + } + } + posX = (boundingBox.minX + boundingBox.maxX) / 2D; + posY = (boundingBox.minY + (double)yOffset) - (double)ySize; + posZ = (boundingBox.minZ + boundingBox.maxZ) / 2D; + isCollidedHorizontally = d5 != d || d7 != d2; + isCollidedVertically = d6 != d1; + onGround = d6 != d1 && d6 < 0.0D; + isCollided = isCollidedHorizontally || isCollidedVertically; + updateFallState(d1, onGround); + if(d5 != d) + { + motionX = 0.0D; + } + if(d6 != d1) + { + motionY = 0.0D; + } + if(d7 != d2) + { + motionZ = 0.0D; + } + double d10 = posX - d3; + double d12 = posZ - d4; + if(entityWalks && !flag) + { + distanceWalkedModified += (double)MathHelper.sqrt_double(d10 * d10 + d12 * d12) * 0.59999999999999998D; + int l = MathHelper.floor_double(posX); + int j1 = MathHelper.floor_double(posY - 0.20000000298023224D - (double)yOffset); + int l1 = MathHelper.floor_double(posZ); + int i3 = worldObj.getBlockId(l, j1, l1); + if(distanceWalkedModified > (float)nextStepDistance && i3 > 0) + { + nextStepDistance++; + StepSound stepsound = Block.blocksList[i3].stepSound; + if(worldObj.getBlockId(l, j1 + 1, l1) == Block.snow.blockID) + { + stepsound = Block.snow.stepSound; + worldObj.playSoundAtEntity(this, stepsound.func_1145_d(), stepsound.func_1147_b() * 0.15F, stepsound.func_1144_c()); + } else + if(!Block.blocksList[i3].blockMaterial.getIsLiquid()) + { + worldObj.playSoundAtEntity(this, stepsound.func_1145_d(), stepsound.func_1147_b() * 0.15F, stepsound.func_1144_c()); + } + Block.blocksList[i3].onEntityWalking(worldObj, l, j1, l1, this); + } + } + int i1 = MathHelper.floor_double(boundingBox.minX); + int k1 = MathHelper.floor_double(boundingBox.minY); + int i2 = MathHelper.floor_double(boundingBox.minZ); + int j3 = MathHelper.floor_double(boundingBox.maxX); + int k3 = MathHelper.floor_double(boundingBox.maxY); + int l3 = MathHelper.floor_double(boundingBox.maxZ); + if(worldObj.checkChunksExist(i1, k1, i2, j3, k3, l3)) + { + for(int i4 = i1; i4 <= j3; i4++) + { + for(int j4 = k1; j4 <= k3; j4++) + { + for(int k4 = i2; k4 <= l3; k4++) + { + int l4 = worldObj.getBlockId(i4, j4, k4); + if(l4 > 0) + { + Block.blocksList[l4].onEntityCollidedWithBlock(worldObj, i4, j4, k4, this); + } + } + + } + + } + + } + ySize *= 0.4F; + boolean flag2 = handleWaterMovement(); + if(worldObj.isBoundingBoxBurning(boundingBox)) + { + dealFireDamage(1); + if(!flag2) + { + fire++; + if(fire == 0) + { + fire = 300; + } + } + } else + if(fire <= 0) + { + fire = -fireResistance; + } + if(flag2 && fire > 0) + { + worldObj.playSoundAtEntity(this, "random.fizz", 0.7F, 1.6F + (rand.nextFloat() - rand.nextFloat()) * 0.4F); + fire = -fireResistance; + } + } + + protected void updateFallState(double d, boolean flag) + { + if(flag) + { + if(fallDistance > 0.0F) + { + fall(fallDistance); + fallDistance = 0.0F; + } + } else + if(d < 0.0D) + { + fallDistance -= d; + } + } + + public AxisAlignedBB getBoundingBox() + { + return null; + } + + protected void dealFireDamage(int i) + { + if(!isImmuneToFire) + { + attackEntityFrom(null, i); + } + } + + protected void fall(float f) + { + } + + public boolean handleWaterMovement() + { + return worldObj.handleMaterialAcceleration(boundingBox.expand(0.0D, -0.40000000596046448D, 0.0D), Material.water, this); + } + + public boolean isInsideOfMaterial(Material material) + { + double d = posY + (double)getEyeHeight(); + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_float(MathHelper.floor_double(d)); + int k = MathHelper.floor_double(posZ); + int l = worldObj.getBlockId(i, j, k); + if(l != 0 && Block.blocksList[l].blockMaterial == material) + { + float f = BlockFluids.setFluidHeight(worldObj.getBlockMetadata(i, j, k)) - 0.1111111F; + float f1 = (float)(j + 1) - f; + return d < (double)f1; + } else + { + return false; + } + } + + public float getEyeHeight() + { + return 0.0F; + } + + public boolean handleLavaMovement() + { + return worldObj.isMaterialInBB(boundingBox.expand(-0.10000000149011612D, -0.40000000596046448D, -0.10000000149011612D), Material.lava); + } + + public void moveFlying(float f, float f1, float f2) + { + float f3 = MathHelper.sqrt_float(f * f + f1 * f1); + if(f3 < 0.01F) + { + return; + } + if(f3 < 1.0F) + { + f3 = 1.0F; + } + f3 = f2 / f3; + f *= f3; + f1 *= f3; + float f4 = MathHelper.sin((rotationYaw * 3.141593F) / 180F); + float f5 = MathHelper.cos((rotationYaw * 3.141593F) / 180F); + motionX += f * f5 - f1 * f4; + motionZ += f1 * f5 + f * f4; + } + + public float getEntityBrightness(float f) + { + int i = MathHelper.floor_double(posX); + double d = (boundingBox.maxY - boundingBox.minY) * 0.66000000000000003D; + int j = MathHelper.floor_double((posY - (double)yOffset) + d); + int k = MathHelper.floor_double(posZ); + if(worldObj.checkChunksExist(MathHelper.floor_double(boundingBox.minX), MathHelper.floor_double(boundingBox.minY), MathHelper.floor_double(boundingBox.minZ), MathHelper.floor_double(boundingBox.maxX), MathHelper.floor_double(boundingBox.maxY), MathHelper.floor_double(boundingBox.maxZ))) + { + return worldObj.getLightBrightness(i, j, k); + } else + { + return 0.0F; + } + } + + public void setWorld(World world) + { + worldObj = world; + } + + public void setPositionAndRotation(double d, double d1, double d2, float f, + float f1) + { + prevPosX = posX = d; + prevPosY = posY = d1; + prevPosZ = posZ = d2; + prevRotationYaw = rotationYaw = f; + prevRotationPitch = rotationPitch = f1; + ySize = 0.0F; + double d3 = prevRotationYaw - f; + if(d3 < -180D) + { + prevRotationYaw += 360F; + } + if(d3 >= 180D) + { + prevRotationYaw -= 360F; + } + setPosition(posX, posY, posZ); + setRotation(f, f1); + } + + public void setLocationAndAngles(double d, double d1, double d2, float f, + float f1) + { + lastTickPosX = prevPosX = posX = d; + lastTickPosY = prevPosY = posY = d1 + (double)yOffset; + lastTickPosZ = prevPosZ = posZ = d2; + rotationYaw = f; + rotationPitch = f1; + setPosition(posX, posY, posZ); + } + + public float getDistanceToEntity(Entity entity) + { + float f = (float)(posX - entity.posX); + float f1 = (float)(posY - entity.posY); + float f2 = (float)(posZ - entity.posZ); + return MathHelper.sqrt_float(f * f + f1 * f1 + f2 * f2); + } + + public double getDistanceSq(double d, double d1, double d2) + { + double d3 = posX - d; + double d4 = posY - d1; + double d5 = posZ - d2; + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public double getDistance(double d, double d1, double d2) + { + double d3 = posX - d; + double d4 = posY - d1; + double d5 = posZ - d2; + return (double)MathHelper.sqrt_double(d3 * d3 + d4 * d4 + d5 * d5); + } + + public double getDistanceSqToEntity(Entity entity) + { + double d = posX - entity.posX; + double d1 = posY - entity.posY; + double d2 = posZ - entity.posZ; + return d * d + d1 * d1 + d2 * d2; + } + + public void onCollideWithPlayer(EntityPlayer entityplayer) + { + } + + public void applyEntityCollision(Entity entity) + { + if(entity.riddenByEntity == this || entity.ridingEntity == this) + { + return; + } + double d = entity.posX - posX; + double d1 = entity.posZ - posZ; + double d2 = MathHelper.abs_max(d, d1); + if(d2 >= 0.0099999997764825821D) + { + d2 = MathHelper.sqrt_double(d2); + d /= d2; + d1 /= d2; + double d3 = 1.0D / d2; + if(d3 > 1.0D) + { + d3 = 1.0D; + } + d *= d3; + d1 *= d3; + d *= 0.05000000074505806D; + d1 *= 0.05000000074505806D; + d *= 1.0F - entityCollisionReduction; + d1 *= 1.0F - entityCollisionReduction; + addVelocity(-d, 0.0D, -d1); + entity.addVelocity(d, 0.0D, d1); + } + } + + public void addVelocity(double d, double d1, double d2) + { + motionX += d; + motionY += d1; + motionZ += d2; + } + + protected void setBeenAttacked() + { + beenAttacked = true; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + setBeenAttacked(); + return false; + } + + public boolean canBeCollidedWith() + { + return false; + } + + public boolean canBePushed() + { + return false; + } + + public void addToPlayerScore(Entity entity, int i) + { + } + + public boolean isInRangeToRenderVec3D(Vec3D vec3d) + { + double d = posX - vec3d.xCoord; + double d1 = posY - vec3d.yCoord; + double d2 = posZ - vec3d.zCoord; + double d3 = d * d + d1 * d1 + d2 * d2; + return isInRangeToRenderDist(d3); + } + + public boolean isInRangeToRenderDist(double d) + { + double d1 = boundingBox.getAverageEdgeLength(); + d1 *= 64D * renderDistanceWeight; + return d < d1 * d1; + } + + public String getEntityTexture() + { + return null; + } + + public boolean addEntityID(NBTTagCompound nbttagcompound) + { + String s = getEntityString(); + if(isDead || s == null) + { + return false; + } else + { + nbttagcompound.setString("id", s); + writeToNBT(nbttagcompound); + return true; + } + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setTag("Pos", newDoubleNBTList(new double[] { + posX, posY, posZ + })); + nbttagcompound.setTag("Motion", newDoubleNBTList(new double[] { + motionX, motionY, motionZ + })); + nbttagcompound.setTag("Rotation", func_377_a(new float[] { + rotationYaw, rotationPitch + })); + nbttagcompound.setFloat("FallDistance", fallDistance); + nbttagcompound.setShort("Fire", (short)fire); + nbttagcompound.setShort("Air", (short)air); + nbttagcompound.setBoolean("OnGround", onGround); + writeEntityToNBT(nbttagcompound); + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + NBTTagList nbttaglist = nbttagcompound.getTagList("Pos"); + NBTTagList nbttaglist1 = nbttagcompound.getTagList("Motion"); + NBTTagList nbttaglist2 = nbttagcompound.getTagList("Rotation"); + setPosition(0.0D, 0.0D, 0.0D); + motionX = ((NBTTagDouble)nbttaglist1.tagAt(0)).doubleValue; + motionY = ((NBTTagDouble)nbttaglist1.tagAt(1)).doubleValue; + motionZ = ((NBTTagDouble)nbttaglist1.tagAt(2)).doubleValue; + if(Math.abs(motionX) > 10D) + { + motionX = 0.0D; + } + if(Math.abs(motionY) > 10D) + { + motionY = 0.0D; + } + if(Math.abs(motionZ) > 10D) + { + motionZ = 0.0D; + } + prevPosX = lastTickPosX = posX = ((NBTTagDouble)nbttaglist.tagAt(0)).doubleValue; + prevPosY = lastTickPosY = posY = ((NBTTagDouble)nbttaglist.tagAt(1)).doubleValue; + prevPosZ = lastTickPosZ = posZ = ((NBTTagDouble)nbttaglist.tagAt(2)).doubleValue; + prevRotationYaw = rotationYaw = ((NBTTagFloat)nbttaglist2.tagAt(0)).floatValue % 6.283185F; + prevRotationPitch = rotationPitch = ((NBTTagFloat)nbttaglist2.tagAt(1)).floatValue % 6.283185F; + fallDistance = nbttagcompound.getFloat("FallDistance"); + fire = nbttagcompound.getShort("Fire"); + air = nbttagcompound.getShort("Air"); + onGround = nbttagcompound.getBoolean("OnGround"); + setPosition(posX, posY, posZ); + readEntityFromNBT(nbttagcompound); + } + + protected final String getEntityString() + { + return EntityList.getEntityString(this); + } + + protected abstract void readEntityFromNBT(NBTTagCompound nbttagcompound); + + protected abstract void writeEntityToNBT(NBTTagCompound nbttagcompound); + + protected NBTTagList newDoubleNBTList(double ad[]) + { + NBTTagList nbttaglist = new NBTTagList(); + double ad1[] = ad; + int i = ad1.length; + for(int j = 0; j < i; j++) + { + double d = ad1[j]; + nbttaglist.setTag(new NBTTagDouble(d)); + } + + return nbttaglist; + } + + protected NBTTagList func_377_a(float af[]) + { + NBTTagList nbttaglist = new NBTTagList(); + float af1[] = af; + int i = af1.length; + for(int j = 0; j < i; j++) + { + float f = af1[j]; + nbttaglist.setTag(new NBTTagFloat(f)); + } + + return nbttaglist; + } + + public float getShadowSize() + { + return height / 2.0F; + } + + public EntityItem dropItem(int i, int j) + { + return dropItemWithOffset(i, j, 0.0F); + } + + public EntityItem dropItemWithOffset(int i, int j, float f) + { + return entityDropItem(new ItemStack(i, j, 0), f); + } + + public EntityItem entityDropItem(ItemStack itemstack, float f) + { + EntityItem entityitem = new EntityItem(worldObj, posX, posY + (double)f, posZ, itemstack); + entityitem.delayBeforeCanPickup = 10; + worldObj.entityJoinedWorld(entityitem); + return entityitem; + } + + public boolean isEntityAlive() + { + return !isDead; + } + + public boolean func_345_I() + { + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(posY + (double)getEyeHeight()); + int k = MathHelper.floor_double(posZ); + return worldObj.isBlockOpaqueCube(i, j, k); + } + + public boolean interact(EntityPlayer entityplayer) + { + return false; + } + + public AxisAlignedBB func_383_b_(Entity entity) + { + return null; + } + + public void updateRidden() + { + if(ridingEntity.isDead) + { + ridingEntity = null; + return; + } + motionX = 0.0D; + motionY = 0.0D; + motionZ = 0.0D; + onUpdate(); + ridingEntity.updateRiderPosition(); + entityRiderYawDelta += ridingEntity.rotationYaw - ridingEntity.prevRotationYaw; + entityRiderPitchDelta += ridingEntity.rotationPitch - ridingEntity.prevRotationPitch; + for(; entityRiderYawDelta >= 180D; entityRiderYawDelta -= 360D) { } + for(; entityRiderYawDelta < -180D; entityRiderYawDelta += 360D) { } + for(; entityRiderPitchDelta >= 180D; entityRiderPitchDelta -= 360D) { } + for(; entityRiderPitchDelta < -180D; entityRiderPitchDelta += 360D) { } + double d = entityRiderYawDelta * 0.5D; + double d1 = entityRiderPitchDelta * 0.5D; + float f = 10F; + if(d > (double)f) + { + d = f; + } + if(d < (double)(-f)) + { + d = -f; + } + if(d1 > (double)f) + { + d1 = f; + } + if(d1 < (double)(-f)) + { + d1 = -f; + } + entityRiderYawDelta -= d; + entityRiderPitchDelta -= d1; + rotationYaw += d; + rotationPitch += d1; + } + + public void updateRiderPosition() + { + riddenByEntity.setPosition(posX, posY + getMountedYOffset() + riddenByEntity.getYOffset(), posZ); + } + + public double getYOffset() + { + return (double)yOffset; + } + + public double getMountedYOffset() + { + return (double)height * 0.75D; + } + + public void mountEntity(Entity entity) + { + entityRiderPitchDelta = 0.0D; + entityRiderYawDelta = 0.0D; + if(entity == null) + { + if(ridingEntity != null) + { + setLocationAndAngles(ridingEntity.posX, ridingEntity.boundingBox.minY + (double)ridingEntity.height, ridingEntity.posZ, rotationYaw, rotationPitch); + ridingEntity.riddenByEntity = null; + } + ridingEntity = null; + return; + } + if(ridingEntity == entity) + { + ridingEntity.riddenByEntity = null; + ridingEntity = null; + setLocationAndAngles(entity.posX, entity.boundingBox.minY + (double)entity.height, entity.posZ, rotationYaw, rotationPitch); + return; + } + if(ridingEntity != null) + { + ridingEntity.riddenByEntity = null; + } + if(entity.riddenByEntity != null) + { + entity.riddenByEntity.ridingEntity = null; + } + ridingEntity = entity; + entity.riddenByEntity = this; + } + + public void setPositionAndRotation2(double d, double d1, double d2, float f, + float f1, int i) + { + setPosition(d, d1, d2); + setRotation(f, f1); + } + + public float getCollisionBorderSize() + { + return 0.1F; + } + + public Vec3D getLookVec() + { + return null; + } + + public void setInPortal() + { + } + + public void setVelocity(double d, double d1, double d2) + { + motionX = d; + motionY = d1; + motionZ = d2; + } + + public void handleHealthUpdate(byte byte0) + { + } + + public void performHurtAnimation() + { + } + + public void updateCloak() + { + } + + public void outfitWithItem(int i, int j, int k) + { + } + + public boolean func_21062_U() + { + return fire > 0 || func_21060_d(0); + } + + public boolean func_21063_V() + { + return ridingEntity != null || func_21060_d(2); + } + + public boolean isSneaking() + { + return func_21060_d(1); + } + + protected boolean func_21060_d(int i) + { + return (dataWatcher.getWatchableObjectByte(0) & 1 << i) != 0; + } + + protected void func_21059_b(int i, boolean flag) + { + byte byte0 = dataWatcher.getWatchableObjectByte(0); + if(flag) + { + dataWatcher.updateObject(0, Byte.valueOf((byte)(byte0 | 1 << i))); + } else + { + dataWatcher.updateObject(0, Byte.valueOf((byte)(byte0 & ~(1 << i)))); + } + } + + private static int nextEntityID = 0; + public int entityId; + public double renderDistanceWeight; + public boolean preventEntitySpawning; + public Entity riddenByEntity; + public Entity ridingEntity; + public World worldObj; + public double prevPosX; + public double prevPosY; + public double prevPosZ; + public double posX; + public double posY; + public double posZ; + public double motionX; + public double motionY; + public double motionZ; + public float rotationYaw; + public float rotationPitch; + public float prevRotationYaw; + public float prevRotationPitch; + public final AxisAlignedBB boundingBox = AxisAlignedBB.getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + public boolean onGround; + public boolean isCollidedHorizontally; + public boolean isCollidedVertically; + public boolean isCollided; + public boolean beenAttacked; + public boolean field_9293_aM; + public boolean isDead; + public float yOffset; + public float width; + public float height; + public float prevDistanceWalkedModified; + public float distanceWalkedModified; + protected boolean entityWalks; + protected float fallDistance; + private int nextStepDistance; + public double lastTickPosX; + public double lastTickPosY; + public double lastTickPosZ; + public float ySize; + public float stepHeight; + public boolean noClip; + public float entityCollisionReduction; + public boolean field_9313_bc; + protected Random rand; + public int ticksExisted; + public int fireResistance; + public int fire; + protected int maxAir; + protected boolean inWater; + public int field_9306_bj; + public int air; + private boolean field_862_c; + public String skinUrl; + public String cloakUrl; + protected boolean isImmuneToFire; + protected DataWatcher dataWatcher; + private double entityRiderPitchDelta; + private double entityRiderYawDelta; + public boolean addedToChunk; + public int chunkCoordX; + public int chunkCoordY; + public int chunkCoordZ; + public int serverPosX; + public int serverPosY; + public int serverPosZ; + +} diff --git a/src/main/java/net/minecraft/src/EntityAnimals.java b/src/main/java/net/minecraft/src/EntityAnimals.java new file mode 100644 index 0000000..9c1ab49 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityAnimals.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public abstract class EntityAnimals extends EntityCreature +{ + + public EntityAnimals(World world) + { + super(world); + } + + protected float getBlockPathWeight(int i, int j, int k) + { + if(worldObj.getBlockId(i, j - 1, k) == Block.grass.blockID) + { + return 10F; + } else + { + return worldObj.getLightBrightness(i, j, k) - 0.5F; + } + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + public boolean getCanSpawnHere() + { + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(boundingBox.minY); + int k = MathHelper.floor_double(posZ); + return worldObj.getBlockId(i, j - 1, k) == Block.grass.blockID && worldObj.getBlockLightValue(i, j, k) > 8 && super.getCanSpawnHere(); + } + + public int func_421_b() + { + return 120; + } +} diff --git a/src/main/java/net/minecraft/src/EntityArrow.java b/src/main/java/net/minecraft/src/EntityArrow.java new file mode 100644 index 0000000..f5afc0c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityArrow.java @@ -0,0 +1,291 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityArrow extends Entity +{ + + public EntityArrow(World world) + { + super(world); + xTile = -1; + yTile = -1; + zTile = -1; + inTile = 0; + inGround = false; + arrowShake = 0; + field_680_i = 0; + setSize(0.5F, 0.5F); + } + + public EntityArrow(World world, double d, double d1, double d2) + { + super(world); + xTile = -1; + yTile = -1; + zTile = -1; + inTile = 0; + inGround = false; + arrowShake = 0; + field_680_i = 0; + setSize(0.5F, 0.5F); + setPosition(d, d1, d2); + yOffset = 0.0F; + } + + public EntityArrow(World world, EntityLiving entityliving) + { + super(world); + xTile = -1; + yTile = -1; + zTile = -1; + inTile = 0; + inGround = false; + arrowShake = 0; + field_680_i = 0; + field_682_g = entityliving; + setSize(0.5F, 0.5F); + setLocationAndAngles(entityliving.posX, entityliving.posY + (double)entityliving.getEyeHeight(), entityliving.posZ, entityliving.rotationYaw, entityliving.rotationPitch); + posX -= MathHelper.cos((rotationYaw / 180F) * 3.141593F) * 0.16F; + posY -= 0.10000000149011612D; + posZ -= MathHelper.sin((rotationYaw / 180F) * 3.141593F) * 0.16F; + setPosition(posX, posY, posZ); + yOffset = 0.0F; + motionX = -MathHelper.sin((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F); + motionZ = MathHelper.cos((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F); + motionY = -MathHelper.sin((rotationPitch / 180F) * 3.141593F); + setArrowHeading(motionX, motionY, motionZ, 1.5F, 1.0F); + } + + protected void entityInit() + { + } + + public void setArrowHeading(double d, double d1, double d2, float f, + float f1) + { + float f2 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + d /= f2; + d1 /= f2; + d2 /= f2; + d += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d1 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d2 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d *= f; + d1 *= f; + d2 *= f; + motionX = d; + motionY = d1; + motionZ = d2; + float f3 = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f3) * 180D) / 3.1415927410125732D); + field_681_h = 0; + } + + public void setVelocity(double d, double d1, double d2) + { + motionX = d; + motionY = d1; + motionZ = d2; + if(prevRotationPitch == 0.0F && prevRotationYaw == 0.0F) + { + float f = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f) * 180D) / 3.1415927410125732D); + } + } + + public void onUpdate() + { + super.onUpdate(); + if(prevRotationPitch == 0.0F && prevRotationYaw == 0.0F) + { + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + prevRotationYaw = rotationYaw = (float)((Math.atan2(motionX, motionZ) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(motionY, f) * 180D) / 3.1415927410125732D); + } + if(arrowShake > 0) + { + arrowShake--; + } + if(inGround) + { + int i = worldObj.getBlockId(xTile, yTile, zTile); + if(i != inTile) + { + inGround = false; + motionX *= rand.nextFloat() * 0.2F; + motionY *= rand.nextFloat() * 0.2F; + motionZ *= rand.nextFloat() * 0.2F; + field_681_h = 0; + field_680_i = 0; + } else + { + field_681_h++; + if(field_681_h == 1200) + { + setEntityDead(); + } + return; + } + } else + { + field_680_i++; + } + Vec3D vec3d = Vec3D.createVector(posX, posY, posZ); + Vec3D vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d1); + vec3d = Vec3D.createVector(posX, posY, posZ); + vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + if(movingobjectposition != null) + { + vec3d1 = Vec3D.createVector(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); + } + Entity entity = null; + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D)); + double d = 0.0D; + for(int j = 0; j < list.size(); j++) + { + Entity entity1 = (Entity)list.get(j); + if(!entity1.canBeCollidedWith() || entity1 == field_682_g && field_680_i < 5) + { + continue; + } + float f4 = 0.3F; + AxisAlignedBB axisalignedbb = entity1.boundingBox.expand(f4, f4, f4); + MovingObjectPosition movingobjectposition1 = axisalignedbb.func_1169_a(vec3d, vec3d1); + if(movingobjectposition1 == null) + { + continue; + } + double d1 = vec3d.distanceTo(movingobjectposition1.hitVec); + if(d1 < d || d == 0.0D) + { + entity = entity1; + d = d1; + } + } + + if(entity != null) + { + movingobjectposition = new MovingObjectPosition(entity); + } + if(movingobjectposition != null) + { + if(movingobjectposition.entityHit != null) + { + if(movingobjectposition.entityHit.attackEntityFrom(field_682_g, 4)) + { + worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (rand.nextFloat() * 0.2F + 0.9F)); + setEntityDead(); + } else + { + motionX *= -0.10000000149011612D; + motionY *= -0.10000000149011612D; + motionZ *= -0.10000000149011612D; + rotationYaw += 180F; + prevRotationYaw += 180F; + field_680_i = 0; + } + } else + { + xTile = movingobjectposition.blockX; + yTile = movingobjectposition.blockY; + zTile = movingobjectposition.blockZ; + inTile = worldObj.getBlockId(xTile, yTile, zTile); + motionX = (float)(movingobjectposition.hitVec.xCoord - posX); + motionY = (float)(movingobjectposition.hitVec.yCoord - posY); + motionZ = (float)(movingobjectposition.hitVec.zCoord - posZ); + float f1 = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ); + posX -= (motionX / (double)f1) * 0.05000000074505806D; + posY -= (motionY / (double)f1) * 0.05000000074505806D; + posZ -= (motionZ / (double)f1) * 0.05000000074505806D; + worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (rand.nextFloat() * 0.2F + 0.9F)); + inGround = true; + arrowShake = 7; + } + } + posX += motionX; + posY += motionY; + posZ += motionZ; + float f2 = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + rotationYaw = (float)((Math.atan2(motionX, motionZ) * 180D) / 3.1415927410125732D); + for(rotationPitch = (float)((Math.atan2(motionY, f2) * 180D) / 3.1415927410125732D); rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } + for(; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + for(; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } + for(; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } + rotationPitch = prevRotationPitch + (rotationPitch - prevRotationPitch) * 0.2F; + rotationYaw = prevRotationYaw + (rotationYaw - prevRotationYaw) * 0.2F; + float f3 = 0.99F; + float f5 = 0.03F; + if(handleWaterMovement()) + { + for(int k = 0; k < 4; k++) + { + float f6 = 0.25F; + worldObj.spawnParticle("bubble", posX - motionX * (double)f6, posY - motionY * (double)f6, posZ - motionZ * (double)f6, motionX, motionY, motionZ); + } + + f3 = 0.8F; + } + motionX *= f3; + motionY *= f3; + motionZ *= f3; + motionY -= f5; + setPosition(posX, posY, posZ); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("xTile", (short)xTile); + nbttagcompound.setShort("yTile", (short)yTile); + nbttagcompound.setShort("zTile", (short)zTile); + nbttagcompound.setByte("inTile", (byte)inTile); + nbttagcompound.setByte("shake", (byte)arrowShake); + nbttagcompound.setByte("inGround", (byte)(inGround ? 1 : 0)); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + xTile = nbttagcompound.getShort("xTile"); + yTile = nbttagcompound.getShort("yTile"); + zTile = nbttagcompound.getShort("zTile"); + inTile = nbttagcompound.getByte("inTile") & 0xff; + arrowShake = nbttagcompound.getByte("shake") & 0xff; + inGround = nbttagcompound.getByte("inGround") == 1; + } + + public void onCollideWithPlayer(EntityPlayer entityplayer) + { + if(worldObj.multiplayerWorld) + { + return; + } + if(inGround && field_682_g == entityplayer && arrowShake <= 0 && entityplayer.inventory.addItemStackToInventory(new ItemStack(Item.arrow, 1))) + { + worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + entityplayer.onItemPickup(this, 1); + setEntityDead(); + } + } + + public float getShadowSize() + { + return 0.0F; + } + + private int xTile; + private int yTile; + private int zTile; + private int inTile; + private boolean inGround; + public int arrowShake; + public EntityLiving field_682_g; + private int field_681_h; + private int field_680_i; +} diff --git a/src/main/java/net/minecraft/src/EntityBoat.java b/src/main/java/net/minecraft/src/EntityBoat.java new file mode 100644 index 0000000..a2bca03 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBoat.java @@ -0,0 +1,348 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityBoat extends Entity +{ + + public EntityBoat(World world) + { + super(world); + field_807_a = 0; + field_806_b = 0; + field_808_c = 1; + preventEntitySpawning = true; + setSize(1.5F, 0.6F); + yOffset = height / 2.0F; + entityWalks = false; + } + + protected void entityInit() + { + } + + public AxisAlignedBB func_383_b_(Entity entity) + { + return entity.boundingBox; + } + + public AxisAlignedBB getBoundingBox() + { + return boundingBox; + } + + public boolean canBePushed() + { + return true; + } + + public EntityBoat(World world, double d, double d1, double d2) + { + this(world); + setPosition(d, d1 + (double)yOffset, d2); + motionX = 0.0D; + motionY = 0.0D; + motionZ = 0.0D; + prevPosX = d; + prevPosY = d1; + prevPosZ = d2; + } + + public double getMountedYOffset() + { + return (double)height * 0.0D - 0.30000001192092896D; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(worldObj.multiplayerWorld || isDead) + { + return true; + } + field_808_c = -field_808_c; + field_806_b = 10; + field_807_a += i * 10; + setBeenAttacked(); + if(field_807_a > 40) + { + for(int j = 0; j < 3; j++) + { + dropItemWithOffset(Block.planks.blockID, 1, 0.0F); + } + + for(int k = 0; k < 2; k++) + { + dropItemWithOffset(Item.stick.shiftedIndex, 1, 0.0F); + } + + setEntityDead(); + } + return true; + } + + public void performHurtAnimation() + { + field_808_c = -field_808_c; + field_806_b = 10; + field_807_a += field_807_a * 10; + } + + public boolean canBeCollidedWith() + { + return !isDead; + } + + public void setPositionAndRotation2(double d, double d1, double d2, float f, + float f1, int i) + { + field_9393_e = d; + field_9392_f = d1; + field_9391_g = d2; + field_9390_h = f; + field_9389_i = f1; + field_9394_d = i + 4; + motionX = field_9388_j; + motionY = field_9387_k; + motionZ = field_9386_l; + } + + public void setVelocity(double d, double d1, double d2) + { + field_9388_j = motionX = d; + field_9387_k = motionY = d1; + field_9386_l = motionZ = d2; + } + + public void onUpdate() + { + super.onUpdate(); + if(field_806_b > 0) + { + field_806_b--; + } + if(field_807_a > 0) + { + field_807_a--; + } + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + int i = 5; + double d = 0.0D; + for(int j = 0; j < i; j++) + { + double d4 = (boundingBox.minY + ((boundingBox.maxY - boundingBox.minY) * (double)(j + 0)) / (double)i) - 0.125D; + double d8 = (boundingBox.minY + ((boundingBox.maxY - boundingBox.minY) * (double)(j + 1)) / (double)i) - 0.125D; + AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBoxFromPool(boundingBox.minX, d4, boundingBox.minZ, boundingBox.maxX, d8, boundingBox.maxZ); + if(worldObj.isAABBInMaterial(axisalignedbb, Material.water)) + { + d += 1.0D / (double)i; + } + } + + if(worldObj.multiplayerWorld) + { + if(field_9394_d > 0) + { + double d1 = posX + (field_9393_e - posX) / (double)field_9394_d; + double d5 = posY + (field_9392_f - posY) / (double)field_9394_d; + double d9 = posZ + (field_9391_g - posZ) / (double)field_9394_d; + double d12; + for(d12 = field_9390_h - (double)rotationYaw; d12 < -180D; d12 += 360D) { } + for(; d12 >= 180D; d12 -= 360D) { } + rotationYaw += d12 / (double)field_9394_d; + rotationPitch += (field_9389_i - (double)rotationPitch) / (double)field_9394_d; + field_9394_d--; + setPosition(d1, d5, d9); + setRotation(rotationYaw, rotationPitch); + } else + { + double d2 = posX + motionX; + double d6 = posY + motionY; + double d10 = posZ + motionZ; + setPosition(d2, d6, d10); + if(onGround) + { + motionX *= 0.5D; + motionY *= 0.5D; + motionZ *= 0.5D; + } + motionX *= 0.99000000953674316D; + motionY *= 0.94999998807907104D; + motionZ *= 0.99000000953674316D; + } + return; + } + double d3 = d * 2D - 1.0D; + motionY += 0.039999999105930328D * d3; + if(riddenByEntity != null) + { + motionX += riddenByEntity.motionX * 0.20000000000000001D; + motionZ += riddenByEntity.motionZ * 0.20000000000000001D; + } + double d7 = 0.40000000000000002D; + if(motionX < -d7) + { + motionX = -d7; + } + if(motionX > d7) + { + motionX = d7; + } + if(motionZ < -d7) + { + motionZ = -d7; + } + if(motionZ > d7) + { + motionZ = d7; + } + if(onGround) + { + motionX *= 0.5D; + motionY *= 0.5D; + motionZ *= 0.5D; + } + moveEntity(motionX, motionY, motionZ); + double d11 = Math.sqrt(motionX * motionX + motionZ * motionZ); + if(d11 > 0.14999999999999999D) + { + double d13 = Math.cos(((double)rotationYaw * 3.1415926535897931D) / 180D); + double d15 = Math.sin(((double)rotationYaw * 3.1415926535897931D) / 180D); + for(int i1 = 0; (double)i1 < 1.0D + d11 * 60D; i1++) + { + double d18 = rand.nextFloat() * 2.0F - 1.0F; + double d20 = (double)(rand.nextInt(2) * 2 - 1) * 0.69999999999999996D; + if(rand.nextBoolean()) + { + double d21 = (posX - d13 * d18 * 0.80000000000000004D) + d15 * d20; + double d23 = posZ - d15 * d18 * 0.80000000000000004D - d13 * d20; + worldObj.spawnParticle("splash", d21, posY - 0.125D, d23, motionX, motionY, motionZ); + } else + { + double d22 = posX + d13 + d15 * d18 * 0.69999999999999996D; + double d24 = (posZ + d15) - d13 * d18 * 0.69999999999999996D; + worldObj.spawnParticle("splash", d22, posY - 0.125D, d24, motionX, motionY, motionZ); + } + } + + } + if(isCollidedHorizontally && d11 > 0.14999999999999999D) + { + if(!worldObj.multiplayerWorld) + { + setEntityDead(); + for(int k = 0; k < 3; k++) + { + dropItemWithOffset(Block.planks.blockID, 1, 0.0F); + } + + for(int l = 0; l < 2; l++) + { + dropItemWithOffset(Item.stick.shiftedIndex, 1, 0.0F); + } + + } + } else + { + motionX *= 0.99000000953674316D; + motionY *= 0.94999998807907104D; + motionZ *= 0.99000000953674316D; + } + rotationPitch = 0.0F; + double d14 = rotationYaw; + double d16 = prevPosX - posX; + double d17 = prevPosZ - posZ; + if(d16 * d16 + d17 * d17 > 0.001D) + { + d14 = (float)((Math.atan2(d17, d16) * 180D) / 3.1415926535897931D); + } + double d19; + for(d19 = d14 - (double)rotationYaw; d19 >= 180D; d19 -= 360D) { } + for(; d19 < -180D; d19 += 360D) { } + if(d19 > 20D) + { + d19 = 20D; + } + if(d19 < -20D) + { + d19 = -20D; + } + rotationYaw += d19; + setRotation(rotationYaw, rotationPitch); + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + if(list != null && list.size() > 0) + { + for(int j1 = 0; j1 < list.size(); j1++) + { + Entity entity = (Entity)list.get(j1); + if(entity != riddenByEntity && entity.canBePushed() && (entity instanceof EntityBoat)) + { + entity.applyEntityCollision(this); + } + } + + } + if(riddenByEntity != null && riddenByEntity.isDead) + { + riddenByEntity = null; + } + } + + public void updateRiderPosition() + { + if(riddenByEntity == null) + { + return; + } else + { + double d = Math.cos(((double)rotationYaw * 3.1415926535897931D) / 180D) * 0.40000000000000002D; + double d1 = Math.sin(((double)rotationYaw * 3.1415926535897931D) / 180D) * 0.40000000000000002D; + riddenByEntity.setPosition(posX + d, posY + getMountedYOffset() + riddenByEntity.getYOffset(), posZ + d1); + return; + } + } + + protected void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + } + + protected void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + } + + public float getShadowSize() + { + return 0.0F; + } + + public boolean interact(EntityPlayer entityplayer) + { + if(riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer) + { + return true; + } + if(!worldObj.multiplayerWorld) + { + entityplayer.mountEntity(this); + } + return true; + } + + public int field_807_a; + public int field_806_b; + public int field_808_c; + private int field_9394_d; + private double field_9393_e; + private double field_9392_f; + private double field_9391_g; + private double field_9390_h; + private double field_9389_i; + private double field_9388_j; + private double field_9387_k; + private double field_9386_l; +} diff --git a/src/main/java/net/minecraft/src/EntityBubbleFX.java b/src/main/java/net/minecraft/src/EntityBubbleFX.java new file mode 100644 index 0000000..ea757ff --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityBubbleFX.java @@ -0,0 +1,46 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityBubbleFX extends EntityFX +{ + + public EntityBubbleFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + super(world, d, d1, d2, d3, d4, d5); + particleRed = 1.0F; + particleGreen = 1.0F; + particleBlue = 1.0F; + particleTextureIndex = 32; + setSize(0.02F, 0.02F); + particleScale = particleScale * (rand.nextFloat() * 0.6F + 0.2F); + motionX = d3 * 0.20000000298023224D + (double)((float)(Math.random() * 2D - 1.0D) * 0.02F); + motionY = d4 * 0.20000000298023224D + (double)((float)(Math.random() * 2D - 1.0D) * 0.02F); + motionZ = d5 * 0.20000000298023224D + (double)((float)(Math.random() * 2D - 1.0D) * 0.02F); + particleMaxAge = (int)(8D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + motionY += 0.002D; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.85000002384185791D; + motionY *= 0.85000002384185791D; + motionZ *= 0.85000002384185791D; + if(worldObj.getBlockMaterial(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)) != Material.water) + { + setEntityDead(); + } + if(particleMaxAge-- <= 0) + { + setEntityDead(); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityChicken.java b/src/main/java/net/minecraft/src/EntityChicken.java new file mode 100644 index 0000000..d733f85 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityChicken.java @@ -0,0 +1,97 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityChicken extends EntityAnimals +{ + + public EntityChicken(World world) + { + super(world); + field_753_a = false; + field_752_b = 0.0F; + field_758_c = 0.0F; + field_755_h = 1.0F; + texture = "/mob/chicken.png"; + setSize(0.3F, 0.4F); + health = 4; + timeUntilNextEgg = rand.nextInt(6000) + 6000; + } + + public void onLivingUpdate() + { + super.onLivingUpdate(); + field_756_e = field_752_b; + field_757_d = field_758_c; + field_758_c += (double)(onGround ? -1 : 4) * 0.29999999999999999D; + if(field_758_c < 0.0F) + { + field_758_c = 0.0F; + } + if(field_758_c > 1.0F) + { + field_758_c = 1.0F; + } + if(!onGround && field_755_h < 1.0F) + { + field_755_h = 1.0F; + } + field_755_h *= 0.90000000000000002D; + if(!onGround && motionY < 0.0D) + { + motionY *= 0.59999999999999998D; + } + field_752_b += field_755_h * 2.0F; + if(!worldObj.multiplayerWorld && --timeUntilNextEgg <= 0) + { + worldObj.playSoundAtEntity(this, "mob.chickenplop", 1.0F, (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + dropItem(Item.egg.shiftedIndex, 1); + timeUntilNextEgg = rand.nextInt(6000) + 6000; + } + } + + protected void fall(float f) + { + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + protected String getLivingSound() + { + return "mob.chicken"; + } + + protected String getHurtSound() + { + return "mob.chickenhurt"; + } + + protected String getDeathSound() + { + return "mob.chickenhurt"; + } + + protected int getDropItemId() + { + return Item.feather.shiftedIndex; + } + + public boolean field_753_a; + public float field_752_b; + public float field_758_c; + public float field_757_d; + public float field_756_e; + public float field_755_h; + public int timeUntilNextEgg; +} diff --git a/src/main/java/net/minecraft/src/EntityClientPlayerMP.java b/src/main/java/net/minecraft/src/EntityClientPlayerMP.java new file mode 100644 index 0000000..f91b32b --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityClientPlayerMP.java @@ -0,0 +1,188 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +public class EntityClientPlayerMP extends EntityPlayerSP +{ + + public EntityClientPlayerMP(Minecraft minecraft, World world, Session session, NetClientHandler netclienthandler) + { + super(minecraft, world, session, 0); + field_9380_bx = 0; + field_21093_bH = false; + field_9382_bF = false; + field_9381_bG = false; + field_12242_bI = 0; + sendQueue = netclienthandler; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + return false; + } + + public void heal(int i) + { + } + + public void onUpdate() + { + if(!worldObj.blockExists(MathHelper.floor_double(posX), 64, MathHelper.floor_double(posZ))) + { + return; + } else + { + super.onUpdate(); + func_4056_N(); + return; + } + } + + public void func_4056_N() + { + if(field_9380_bx++ == 20) + { + sendInventoryChanged(); + field_9380_bx = 0; + } + boolean flag = isSneaking(); + if(flag != field_9381_bG) + { + if(flag) + { + sendQueue.addToSendQueue(new Packet19(this, 1)); + } else + { + sendQueue.addToSendQueue(new Packet19(this, 2)); + } + field_9381_bG = flag; + } + double d = posX - field_9379_by; + double d1 = boundingBox.minY - field_9378_bz; + double d2 = posY - field_9377_bA; + double d3 = posZ - field_9376_bB; + double d4 = rotationYaw - field_9385_bC; + double d5 = rotationPitch - field_9384_bD; + boolean flag1 = d1 != 0.0D || d2 != 0.0D || d != 0.0D || d3 != 0.0D; + boolean flag2 = d4 != 0.0D || d5 != 0.0D; + if(ridingEntity != null) + { + if(flag2) + { + sendQueue.addToSendQueue(new Packet11PlayerPosition(motionX, -999D, -999D, motionZ, onGround)); + } else + { + sendQueue.addToSendQueue(new Packet13PlayerLookMove(motionX, -999D, -999D, motionZ, rotationYaw, rotationPitch, onGround)); + } + flag1 = false; + } else + if(flag1 && flag2) + { + sendQueue.addToSendQueue(new Packet13PlayerLookMove(posX, boundingBox.minY, posY, posZ, rotationYaw, rotationPitch, onGround)); + field_12242_bI = 0; + } else + if(flag1) + { + sendQueue.addToSendQueue(new Packet11PlayerPosition(posX, boundingBox.minY, posY, posZ, onGround)); + field_12242_bI = 0; + } else + if(flag2) + { + sendQueue.addToSendQueue(new Packet12PlayerLook(rotationYaw, rotationPitch, onGround)); + field_12242_bI = 0; + } else + { + sendQueue.addToSendQueue(new Packet10Flying(onGround)); + if(field_9382_bF != onGround || field_12242_bI > 200) + { + field_12242_bI = 0; + } else + { + field_12242_bI++; + } + } + field_9382_bF = onGround; + if(flag1) + { + field_9379_by = posX; + field_9378_bz = boundingBox.minY; + field_9377_bA = posY; + field_9376_bB = posZ; + } + if(flag2) + { + field_9385_bC = rotationYaw; + field_9384_bD = rotationPitch; + } + } + + public void dropCurrentItem() + { + sendQueue.addToSendQueue(new Packet14BlockDig(4, 0, 0, 0, 0)); + } + + private void sendInventoryChanged() + { + } + + protected void joinEntityItemWithWorld(EntityItem entityitem) + { + } + + public void sendChatMessage(String s) + { + sendQueue.addToSendQueue(new Packet3Chat(s)); + } + + public void swingItem() + { + super.swingItem(); + sendQueue.addToSendQueue(new Packet18ArmAnimation(this, 1)); + } + + public void respawnPlayer() + { + sendInventoryChanged(); + sendQueue.addToSendQueue(new Packet9()); + } + + protected void damageEntity(int i) + { + health -= i; + } + + public void func_20059_m() + { + sendQueue.addToSendQueue(new Packet101(craftingInventory.windowId)); + inventory.setItemStack(null); + super.func_20059_m(); + } + + public void setHealth(int i) + { + if(field_21093_bH) + { + super.setHealth(i); + } else + { + health = i; + field_21093_bH = true; + } + } + + public NetClientHandler sendQueue; + private int field_9380_bx; + private boolean field_21093_bH; + private double field_9379_by; + private double field_9378_bz; + private double field_9377_bA; + private double field_9376_bB; + private float field_9385_bC; + private float field_9384_bD; + private boolean field_9382_bF; + private boolean field_9381_bG; + private int field_12242_bI; +} diff --git a/src/main/java/net/minecraft/src/EntityCow.java b/src/main/java/net/minecraft/src/EntityCow.java new file mode 100644 index 0000000..594d380 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCow.java @@ -0,0 +1,64 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityCow extends EntityAnimals +{ + + public EntityCow(World world) + { + super(world); + texture = "/mob/cow.png"; + setSize(0.9F, 1.3F); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + protected String getLivingSound() + { + return "mob.cow"; + } + + protected String getHurtSound() + { + return "mob.cowhurt"; + } + + protected String getDeathSound() + { + return "mob.cowhurt"; + } + + protected float getSoundVolume() + { + return 0.4F; + } + + protected int getDropItemId() + { + return Item.leather.shiftedIndex; + } + + public boolean interact(EntityPlayer entityplayer) + { + ItemStack itemstack = entityplayer.inventory.getCurrentItem(); + if(itemstack != null && itemstack.itemID == Item.bucketEmpty.shiftedIndex) + { + entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, new ItemStack(Item.bucketMilk)); + return true; + } else + { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityCreature.java b/src/main/java/net/minecraft/src/EntityCreature.java new file mode 100644 index 0000000..44e8db0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCreature.java @@ -0,0 +1,170 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityCreature extends EntityLiving +{ + + public EntityCreature(World world) + { + super(world); + hasAttacked = false; + } + + protected void updatePlayerActionState() + { + hasAttacked = false; + float f = 16F; + if(playerToAttack == null) + { + playerToAttack = findPlayerToAttack(); + if(playerToAttack != null) + { + pathToEntity = worldObj.getPathToEntity(this, playerToAttack, f); + } + } else + if(!playerToAttack.isEntityAlive()) + { + playerToAttack = null; + } else + { + float f1 = playerToAttack.getDistanceToEntity(this); + if(canEntityBeSeen(playerToAttack)) + { + attackEntity(playerToAttack, f1); + } + } + if(!hasAttacked && playerToAttack != null && (pathToEntity == null || rand.nextInt(20) == 0)) + { + pathToEntity = worldObj.getPathToEntity(this, playerToAttack, f); + } else + if(pathToEntity == null && rand.nextInt(80) == 0 || rand.nextInt(80) == 0) + { + boolean flag = false; + int j = -1; + int k = -1; + int l = -1; + float f2 = -99999F; + for(int i1 = 0; i1 < 10; i1++) + { + int j1 = MathHelper.floor_double((posX + (double)rand.nextInt(13)) - 6D); + int k1 = MathHelper.floor_double((posY + (double)rand.nextInt(7)) - 3D); + int l1 = MathHelper.floor_double((posZ + (double)rand.nextInt(13)) - 6D); + float f3 = getBlockPathWeight(j1, k1, l1); + if(f3 > f2) + { + f2 = f3; + j = j1; + k = k1; + l = l1; + flag = true; + } + } + + if(flag) + { + pathToEntity = worldObj.getEntityPathToXYZ(this, j, k, l, 10F); + } + } + int i = MathHelper.floor_double(boundingBox.minY); + boolean flag1 = handleWaterMovement(); + boolean flag2 = handleLavaMovement(); + rotationPitch = 0.0F; + if(pathToEntity == null || rand.nextInt(100) == 0) + { + super.updatePlayerActionState(); + pathToEntity = null; + return; + } + Vec3D vec3d = pathToEntity.getPosition(this); + for(double d = width * 2.0F; vec3d != null && vec3d.squareDistanceTo(posX, vec3d.yCoord, posZ) < d * d;) + { + pathToEntity.incrementPathIndex(); + if(pathToEntity.isFinished()) + { + vec3d = null; + pathToEntity = null; + } else + { + vec3d = pathToEntity.getPosition(this); + } + } + + isJumping = false; + if(vec3d != null) + { + double d1 = vec3d.xCoord - posX; + double d2 = vec3d.zCoord - posZ; + double d3 = vec3d.yCoord - (double)i; + float f4 = (float)((Math.atan2(d2, d1) * 180D) / 3.1415927410125732D) - 90F; + float f5 = f4 - rotationYaw; + moveForward = moveSpeed; + for(; f5 < -180F; f5 += 360F) { } + for(; f5 >= 180F; f5 -= 360F) { } + if(f5 > 30F) + { + f5 = 30F; + } + if(f5 < -30F) + { + f5 = -30F; + } + rotationYaw += f5; + if(hasAttacked && playerToAttack != null) + { + double d4 = playerToAttack.posX - posX; + double d5 = playerToAttack.posZ - posZ; + float f7 = rotationYaw; + rotationYaw = (float)((Math.atan2(d5, d4) * 180D) / 3.1415927410125732D) - 90F; + float f6 = (((f7 - rotationYaw) + 90F) * 3.141593F) / 180F; + moveStrafing = -MathHelper.sin(f6) * moveForward * 1.0F; + moveForward = MathHelper.cos(f6) * moveForward * 1.0F; + } + if(d3 > 0.0D) + { + isJumping = true; + } + } + if(playerToAttack != null) + { + faceEntity(playerToAttack, 30F); + } + if(isCollidedHorizontally) + { + isJumping = true; + } + if(rand.nextFloat() < 0.8F && (flag1 || flag2)) + { + isJumping = true; + } + } + + protected void attackEntity(Entity entity, float f) + { + } + + protected float getBlockPathWeight(int i, int j, int k) + { + return 0.0F; + } + + protected Entity findPlayerToAttack() + { + return null; + } + + public boolean getCanSpawnHere() + { + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(boundingBox.minY); + int k = MathHelper.floor_double(posZ); + return super.getCanSpawnHere() && getBlockPathWeight(i, j, k) >= 0.0F; + } + + private PathEntity pathToEntity; + protected Entity playerToAttack; + protected boolean hasAttacked; +} diff --git a/src/main/java/net/minecraft/src/EntityCreeper.java b/src/main/java/net/minecraft/src/EntityCreeper.java new file mode 100644 index 0000000..aa54f96 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityCreeper.java @@ -0,0 +1,125 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityCreeper extends EntityMobs +{ + + public EntityCreeper(World world) + { + super(world); + texture = "/mob/creeper.png"; + } + + protected void entityInit() + { + super.entityInit(); + dataWatcher.addObject(16, Byte.valueOf((byte)-1)); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + public void onUpdate() + { + lastActiveTime = timeSinceIgnited; + if(worldObj.multiplayerWorld) + { + int i = func_21091_q(); + if(i > 0 && timeSinceIgnited == 0) + { + worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 0.5F); + } + timeSinceIgnited += i; + if(timeSinceIgnited < 0) + { + timeSinceIgnited = 0; + } + if(timeSinceIgnited >= 30) + { + timeSinceIgnited = 30; + } + } + super.onUpdate(); + } + + protected String getHurtSound() + { + return "mob.creeper"; + } + + protected String getDeathSound() + { + return "mob.creeperdeath"; + } + + public void onDeath(Entity entity) + { + super.onDeath(entity); + if(entity instanceof EntitySkeleton) + { + dropItem(Item.record13.shiftedIndex + rand.nextInt(2), 1); + } + } + + protected void attackEntity(Entity entity, float f) + { + int i = func_21091_q(); + if(i <= 0 && f < 3F || i > 0 && f < 7F) + { + if(timeSinceIgnited == 0) + { + worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 0.5F); + } + func_21090_e(1); + timeSinceIgnited++; + if(timeSinceIgnited >= 30) + { + worldObj.createExplosion(this, posX, posY, posZ, 3F); + setEntityDead(); + } + hasAttacked = true; + } else + { + func_21090_e(-1); + timeSinceIgnited--; + if(timeSinceIgnited < 0) + { + timeSinceIgnited = 0; + } + } + } + + public float func_440_b(float f) + { + return ((float)lastActiveTime + (float)(timeSinceIgnited - lastActiveTime) * f) / 28F; + } + + protected int getDropItemId() + { + return Item.gunpowder.shiftedIndex; + } + + private int func_21091_q() + { + return dataWatcher.getWatchableObjectByte(16); + } + + private void func_21090_e(int i) + { + dataWatcher.updateObject(16, Byte.valueOf((byte)i)); + } + + int timeSinceIgnited; + int lastActiveTime; +} diff --git a/src/main/java/net/minecraft/src/EntityDiggingFX.java b/src/main/java/net/minecraft/src/EntityDiggingFX.java new file mode 100644 index 0000000..9039f4a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityDiggingFX.java @@ -0,0 +1,60 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityDiggingFX extends EntityFX +{ + + public EntityDiggingFX(World world, double d, double d1, double d2, + double d3, double d4, double d5, Block block) + { + super(world, d, d1, d2, d3, d4, d5); + field_4082_a = block; + particleTextureIndex = block.blockIndexInTexture; + particleGravity = block.blockParticleGravity; + particleRed = particleGreen = particleBlue = 0.6F; + particleScale /= 2.0F; + } + + public EntityDiggingFX func_4041_a(int i, int j, int k) + { + if(field_4082_a == Block.grass) + { + return this; + } else + { + int l = field_4082_a.colorMultiplier(worldObj, i, j, k); + particleRed *= (float)(l >> 16 & 0xff) / 255F; + particleGreen *= (float)(l >> 8 & 0xff) / 255F; + particleBlue *= (float)(l & 0xff) / 255F; + return this; + } + } + + public int getFXLayer() + { + return 1; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = ((float)(particleTextureIndex % 16) + particleTextureJitterX / 4F) / 16F; + float f7 = f6 + 0.01560938F; + float f8 = ((float)(particleTextureIndex / 16) + particleTextureJitterY / 4F) / 16F; + float f9 = f8 + 0.01560938F; + float f10 = 0.1F * particleScale; + float f11 = (float)((prevPosX + (posX - prevPosX) * (double)f) - interpPosX); + float f12 = (float)((prevPosY + (posY - prevPosY) * (double)f) - interpPosY); + float f13 = (float)((prevPosZ + (posZ - prevPosZ) * (double)f) - interpPosZ); + float f14 = getEntityBrightness(f); + tessellator.setColorOpaque_F(f14 * particleRed, f14 * particleGreen, f14 * particleBlue); + tessellator.addVertexWithUV(f11 - f1 * f10 - f4 * f10, f12 - f2 * f10, f13 - f3 * f10 - f5 * f10, f6, f9); + tessellator.addVertexWithUV((f11 - f1 * f10) + f4 * f10, f12 + f2 * f10, (f13 - f3 * f10) + f5 * f10, f6, f8); + tessellator.addVertexWithUV(f11 + f1 * f10 + f4 * f10, f12 + f2 * f10, f13 + f3 * f10 + f5 * f10, f7, f8); + tessellator.addVertexWithUV((f11 + f1 * f10) - f4 * f10, f12 - f2 * f10, (f13 + f3 * f10) - f5 * f10, f7, f9); + } + + private Block field_4082_a; +} diff --git a/src/main/java/net/minecraft/src/EntityEgg.java b/src/main/java/net/minecraft/src/EntityEgg.java new file mode 100644 index 0000000..bfdc093 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityEgg.java @@ -0,0 +1,289 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityEgg extends Entity +{ + + public EntityEgg(World world) + { + super(world); + field_20056_b = -1; + field_20055_c = -1; + field_20054_d = -1; + field_20053_e = 0; + field_20052_f = false; + field_20057_a = 0; + field_20049_i = 0; + setSize(0.25F, 0.25F); + } + + protected void entityInit() + { + } + + public boolean isInRangeToRenderDist(double d) + { + double d1 = boundingBox.getAverageEdgeLength() * 4D; + d1 *= 64D; + return d < d1 * d1; + } + + public EntityEgg(World world, EntityLiving entityliving) + { + super(world); + field_20056_b = -1; + field_20055_c = -1; + field_20054_d = -1; + field_20053_e = 0; + field_20052_f = false; + field_20057_a = 0; + field_20049_i = 0; + field_20051_g = entityliving; + setSize(0.25F, 0.25F); + setLocationAndAngles(entityliving.posX, entityliving.posY + (double)entityliving.getEyeHeight(), entityliving.posZ, entityliving.rotationYaw, entityliving.rotationPitch); + posX -= MathHelper.cos((rotationYaw / 180F) * 3.141593F) * 0.16F; + posY -= 0.10000000149011612D; + posZ -= MathHelper.sin((rotationYaw / 180F) * 3.141593F) * 0.16F; + setPosition(posX, posY, posZ); + yOffset = 0.0F; + float f = 0.4F; + motionX = -MathHelper.sin((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f; + motionZ = MathHelper.cos((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f; + motionY = -MathHelper.sin((rotationPitch / 180F) * 3.141593F) * f; + func_20048_a(motionX, motionY, motionZ, 1.5F, 1.0F); + } + + public EntityEgg(World world, double d, double d1, double d2) + { + super(world); + field_20056_b = -1; + field_20055_c = -1; + field_20054_d = -1; + field_20053_e = 0; + field_20052_f = false; + field_20057_a = 0; + field_20049_i = 0; + field_20050_h = 0; + setSize(0.25F, 0.25F); + setPosition(d, d1, d2); + yOffset = 0.0F; + } + + public void func_20048_a(double d, double d1, double d2, float f, + float f1) + { + float f2 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + d /= f2; + d1 /= f2; + d2 /= f2; + d += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d1 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d2 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d *= f; + d1 *= f; + d2 *= f; + motionX = d; + motionY = d1; + motionZ = d2; + float f3 = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f3) * 180D) / 3.1415927410125732D); + field_20050_h = 0; + } + + public void setVelocity(double d, double d1, double d2) + { + motionX = d; + motionY = d1; + motionZ = d2; + if(prevRotationPitch == 0.0F && prevRotationYaw == 0.0F) + { + float f = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f) * 180D) / 3.1415927410125732D); + } + } + + public void onUpdate() + { + lastTickPosX = posX; + lastTickPosY = posY; + lastTickPosZ = posZ; + super.onUpdate(); + if(field_20057_a > 0) + { + field_20057_a--; + } + if(field_20052_f) + { + int i = worldObj.getBlockId(field_20056_b, field_20055_c, field_20054_d); + if(i != field_20053_e) + { + field_20052_f = false; + motionX *= rand.nextFloat() * 0.2F; + motionY *= rand.nextFloat() * 0.2F; + motionZ *= rand.nextFloat() * 0.2F; + field_20050_h = 0; + field_20049_i = 0; + } else + { + field_20050_h++; + if(field_20050_h == 1200) + { + setEntityDead(); + } + return; + } + } else + { + field_20049_i++; + } + Vec3D vec3d = Vec3D.createVector(posX, posY, posZ); + Vec3D vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d1); + vec3d = Vec3D.createVector(posX, posY, posZ); + vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + if(movingobjectposition != null) + { + vec3d1 = Vec3D.createVector(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); + } + if(!worldObj.multiplayerWorld) + { + Entity entity = null; + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D)); + double d = 0.0D; + for(int i1 = 0; i1 < list.size(); i1++) + { + Entity entity1 = (Entity)list.get(i1); + if(!entity1.canBeCollidedWith() || entity1 == field_20051_g && field_20049_i < 5) + { + continue; + } + float f4 = 0.3F; + AxisAlignedBB axisalignedbb = entity1.boundingBox.expand(f4, f4, f4); + MovingObjectPosition movingobjectposition1 = axisalignedbb.func_1169_a(vec3d, vec3d1); + if(movingobjectposition1 == null) + { + continue; + } + double d1 = vec3d.distanceTo(movingobjectposition1.hitVec); + if(d1 < d || d == 0.0D) + { + entity = entity1; + d = d1; + } + } + + if(entity != null) + { + movingobjectposition = new MovingObjectPosition(entity); + } + } + if(movingobjectposition != null) + { + if(movingobjectposition.entityHit != null) + { + if(!movingobjectposition.entityHit.attackEntityFrom(field_20051_g, 0)); + } + if(!worldObj.multiplayerWorld && rand.nextInt(8) == 0) + { + byte byte0 = 1; + if(rand.nextInt(32) == 0) + { + byte0 = 4; + } + for(int k = 0; k < byte0; k++) + { + EntityChicken entitychicken = new EntityChicken(worldObj); + entitychicken.setLocationAndAngles(posX, posY, posZ, rotationYaw, 0.0F); + worldObj.entityJoinedWorld(entitychicken); + } + + } + for(int j = 0; j < 8; j++) + { + worldObj.spawnParticle("snowballpoof", posX, posY, posZ, 0.0D, 0.0D, 0.0D); + } + + setEntityDead(); + } + posX += motionX; + posY += motionY; + posZ += motionZ; + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + rotationYaw = (float)((Math.atan2(motionX, motionZ) * 180D) / 3.1415927410125732D); + for(rotationPitch = (float)((Math.atan2(motionY, f) * 180D) / 3.1415927410125732D); rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } + for(; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + for(; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } + for(; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } + rotationPitch = prevRotationPitch + (rotationPitch - prevRotationPitch) * 0.2F; + rotationYaw = prevRotationYaw + (rotationYaw - prevRotationYaw) * 0.2F; + float f1 = 0.99F; + float f2 = 0.03F; + if(handleWaterMovement()) + { + for(int l = 0; l < 4; l++) + { + float f3 = 0.25F; + worldObj.spawnParticle("bubble", posX - motionX * (double)f3, posY - motionY * (double)f3, posZ - motionZ * (double)f3, motionX, motionY, motionZ); + } + + f1 = 0.8F; + } + motionX *= f1; + motionY *= f1; + motionZ *= f1; + motionY -= f2; + setPosition(posX, posY, posZ); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("xTile", (short)field_20056_b); + nbttagcompound.setShort("yTile", (short)field_20055_c); + nbttagcompound.setShort("zTile", (short)field_20054_d); + nbttagcompound.setByte("inTile", (byte)field_20053_e); + nbttagcompound.setByte("shake", (byte)field_20057_a); + nbttagcompound.setByte("inGround", (byte)(field_20052_f ? 1 : 0)); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + field_20056_b = nbttagcompound.getShort("xTile"); + field_20055_c = nbttagcompound.getShort("yTile"); + field_20054_d = nbttagcompound.getShort("zTile"); + field_20053_e = nbttagcompound.getByte("inTile") & 0xff; + field_20057_a = nbttagcompound.getByte("shake") & 0xff; + field_20052_f = nbttagcompound.getByte("inGround") == 1; + } + + public void onCollideWithPlayer(EntityPlayer entityplayer) + { + if(field_20052_f && field_20051_g == entityplayer && field_20057_a <= 0 && entityplayer.inventory.addItemStackToInventory(new ItemStack(Item.arrow, 1))) + { + worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + entityplayer.onItemPickup(this, 1); + setEntityDead(); + } + } + + public float getShadowSize() + { + return 0.0F; + } + + private int field_20056_b; + private int field_20055_c; + private int field_20054_d; + private int field_20053_e; + private boolean field_20052_f; + public int field_20057_a; + private EntityLiving field_20051_g; + private int field_20050_h; + private int field_20049_i; +} diff --git a/src/main/java/net/minecraft/src/EntityExplodeFX.java b/src/main/java/net/minecraft/src/EntityExplodeFX.java new file mode 100644 index 0000000..df3d883 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityExplodeFX.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityExplodeFX extends EntityFX +{ + + public EntityExplodeFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + super(world, d, d1, d2, d3, d4, d5); + motionX = d3 + (double)((float)(Math.random() * 2D - 1.0D) * 0.05F); + motionY = d4 + (double)((float)(Math.random() * 2D - 1.0D) * 0.05F); + motionZ = d5 + (double)((float)(Math.random() * 2D - 1.0D) * 0.05F); + particleRed = particleGreen = particleBlue = rand.nextFloat() * 0.3F + 0.7F; + particleScale = rand.nextFloat() * rand.nextFloat() * 6F + 1.0F; + particleMaxAge = (int)(16D / ((double)rand.nextFloat() * 0.80000000000000004D + 0.20000000000000001D)) + 2; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + particleTextureIndex = 7 - (particleAge * 8) / particleMaxAge; + motionY += 0.0040000000000000001D; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.89999997615814209D; + motionY *= 0.89999997615814209D; + motionZ *= 0.89999997615814209D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityFX.java b/src/main/java/net/minecraft/src/EntityFX.java new file mode 100644 index 0000000..c757853 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFX.java @@ -0,0 +1,121 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityFX extends Entity +{ + + public EntityFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + super(world); + particleAge = 0; + particleMaxAge = 0; + setSize(0.2F, 0.2F); + yOffset = height / 2.0F; + setPosition(d, d1, d2); + particleRed = particleGreen = particleBlue = 1.0F; + motionX = d3 + (double)((float)(Math.random() * 2D - 1.0D) * 0.4F); + motionY = d4 + (double)((float)(Math.random() * 2D - 1.0D) * 0.4F); + motionZ = d5 + (double)((float)(Math.random() * 2D - 1.0D) * 0.4F); + float f = (float)(Math.random() + Math.random() + 1.0D) * 0.15F; + float f1 = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ); + motionX = (motionX / (double)f1) * (double)f * 0.40000000596046448D; + motionY = (motionY / (double)f1) * (double)f * 0.40000000596046448D + 0.10000000149011612D; + motionZ = (motionZ / (double)f1) * (double)f * 0.40000000596046448D; + particleTextureJitterX = rand.nextFloat() * 3F; + particleTextureJitterY = rand.nextFloat() * 3F; + particleScale = (rand.nextFloat() * 0.5F + 0.5F) * 2.0F; + particleMaxAge = (int)(4F / (rand.nextFloat() * 0.9F + 0.1F)); + particleAge = 0; + entityWalks = false; + } + + public EntityFX func_407_b(float f) + { + motionX *= f; + motionY = (motionY - 0.10000000149011612D) * (double)f + 0.10000000149011612D; + motionZ *= f; + return this; + } + + public EntityFX func_405_d(float f) + { + setSize(0.2F * f, 0.2F * f); + particleScale *= f; + return this; + } + + protected void entityInit() + { + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + motionY -= 0.040000000000000001D * (double)particleGravity; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.98000001907348633D; + motionY *= 0.98000001907348633D; + motionZ *= 0.98000001907348633D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = (float)(particleTextureIndex % 16) / 16F; + float f7 = f6 + 0.0624375F; + float f8 = (float)(particleTextureIndex / 16) / 16F; + float f9 = f8 + 0.0624375F; + float f10 = 0.1F * particleScale; + float f11 = (float)((prevPosX + (posX - prevPosX) * (double)f) - interpPosX); + float f12 = (float)((prevPosY + (posY - prevPosY) * (double)f) - interpPosY); + float f13 = (float)((prevPosZ + (posZ - prevPosZ) * (double)f) - interpPosZ); + float f14 = getEntityBrightness(f); + tessellator.setColorOpaque_F(particleRed * f14, particleGreen * f14, particleBlue * f14); + tessellator.addVertexWithUV(f11 - f1 * f10 - f4 * f10, f12 - f2 * f10, f13 - f3 * f10 - f5 * f10, f7, f9); + tessellator.addVertexWithUV((f11 - f1 * f10) + f4 * f10, f12 + f2 * f10, (f13 - f3 * f10) + f5 * f10, f7, f8); + tessellator.addVertexWithUV(f11 + f1 * f10 + f4 * f10, f12 + f2 * f10, f13 + f3 * f10 + f5 * f10, f6, f8); + tessellator.addVertexWithUV((f11 + f1 * f10) - f4 * f10, f12 - f2 * f10, (f13 + f3 * f10) - f5 * f10, f6, f9); + } + + public int getFXLayer() + { + return 0; + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + } + + protected int particleTextureIndex; + protected float particleTextureJitterX; + protected float particleTextureJitterY; + protected int particleAge; + protected int particleMaxAge; + protected float particleScale; + protected float particleGravity; + protected float particleRed; + protected float particleGreen; + protected float particleBlue; + public static double interpPosX; + public static double interpPosY; + public static double interpPosZ; +} diff --git a/src/main/java/net/minecraft/src/EntityFallingSand.java b/src/main/java/net/minecraft/src/EntityFallingSand.java new file mode 100644 index 0000000..4a5b49e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFallingSand.java @@ -0,0 +1,107 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityFallingSand extends Entity +{ + + public EntityFallingSand(World world) + { + super(world); + fallTime = 0; + } + + public EntityFallingSand(World world, double d, double d1, double d2, + int i) + { + super(world); + fallTime = 0; + blockID = i; + preventEntitySpawning = true; + setSize(0.98F, 0.98F); + yOffset = height / 2.0F; + setPosition(d, d1, d2); + motionX = 0.0D; + motionY = 0.0D; + motionZ = 0.0D; + entityWalks = false; + prevPosX = d; + prevPosY = d1; + prevPosZ = d2; + } + + protected void entityInit() + { + } + + public boolean canBeCollidedWith() + { + return !isDead; + } + + public void onUpdate() + { + if(blockID == 0) + { + setEntityDead(); + return; + } + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + fallTime++; + motionY -= 0.039999999105930328D; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.98000001907348633D; + motionY *= 0.98000001907348633D; + motionZ *= 0.98000001907348633D; + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(posY); + int k = MathHelper.floor_double(posZ); + if(worldObj.getBlockId(i, j, k) == blockID) + { + worldObj.setBlockWithNotify(i, j, k, 0); + } + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + motionY *= -0.5D; + setEntityDead(); + if((!worldObj.canBlockBePlacedAt(blockID, i, j, k, true) || !worldObj.setBlockWithNotify(i, j, k, blockID)) && !worldObj.multiplayerWorld) + { + dropItem(blockID, 1); + } + } else + if(fallTime > 100 && !worldObj.multiplayerWorld) + { + dropItem(blockID, 1); + setEntityDead(); + } + } + + protected void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setByte("Tile", (byte)blockID); + } + + protected void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + blockID = nbttagcompound.getByte("Tile") & 0xff; + } + + public float getShadowSize() + { + return 0.0F; + } + + public World func_465_i() + { + return worldObj; + } + + public int blockID; + public int fallTime; +} diff --git a/src/main/java/net/minecraft/src/EntityFireball.java b/src/main/java/net/minecraft/src/EntityFireball.java new file mode 100644 index 0000000..d2cc143 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFireball.java @@ -0,0 +1,241 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityFireball extends Entity +{ + + public EntityFireball(World world) + { + super(world); + field_9402_e = -1; + field_9401_f = -1; + field_9400_g = -1; + field_9399_h = 0; + field_9398_i = false; + field_9406_a = 0; + field_9395_l = 0; + setSize(1.0F, 1.0F); + } + + protected void entityInit() + { + } + + public boolean isInRangeToRenderDist(double d) + { + double d1 = boundingBox.getAverageEdgeLength() * 4D; + d1 *= 64D; + return d < d1 * d1; + } + + public EntityFireball(World world, EntityLiving entityliving, double d, double d1, double d2) + { + super(world); + field_9402_e = -1; + field_9401_f = -1; + field_9400_g = -1; + field_9399_h = 0; + field_9398_i = false; + field_9406_a = 0; + field_9395_l = 0; + field_9397_j = entityliving; + setSize(1.0F, 1.0F); + setLocationAndAngles(entityliving.posX, entityliving.posY, entityliving.posZ, entityliving.rotationYaw, entityliving.rotationPitch); + setPosition(posX, posY, posZ); + yOffset = 0.0F; + motionX = motionY = motionZ = 0.0D; + d += rand.nextGaussian() * 0.40000000000000002D; + d1 += rand.nextGaussian() * 0.40000000000000002D; + d2 += rand.nextGaussian() * 0.40000000000000002D; + double d3 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + field_9405_b = (d / d3) * 0.10000000000000001D; + field_9404_c = (d1 / d3) * 0.10000000000000001D; + field_9403_d = (d2 / d3) * 0.10000000000000001D; + } + + public void onUpdate() + { + super.onUpdate(); + fire = 10; + if(field_9406_a > 0) + { + field_9406_a--; + } + if(field_9398_i) + { + int i = worldObj.getBlockId(field_9402_e, field_9401_f, field_9400_g); + if(i != field_9399_h) + { + field_9398_i = false; + motionX *= rand.nextFloat() * 0.2F; + motionY *= rand.nextFloat() * 0.2F; + motionZ *= rand.nextFloat() * 0.2F; + field_9396_k = 0; + field_9395_l = 0; + } else + { + field_9396_k++; + if(field_9396_k == 1200) + { + setEntityDead(); + } + return; + } + } else + { + field_9395_l++; + } + Vec3D vec3d = Vec3D.createVector(posX, posY, posZ); + Vec3D vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d1); + vec3d = Vec3D.createVector(posX, posY, posZ); + vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + if(movingobjectposition != null) + { + vec3d1 = Vec3D.createVector(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); + } + Entity entity = null; + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D)); + double d = 0.0D; + for(int j = 0; j < list.size(); j++) + { + Entity entity1 = (Entity)list.get(j); + if(!entity1.canBeCollidedWith() || entity1 == field_9397_j && field_9395_l < 25) + { + continue; + } + float f2 = 0.3F; + AxisAlignedBB axisalignedbb = entity1.boundingBox.expand(f2, f2, f2); + MovingObjectPosition movingobjectposition1 = axisalignedbb.func_1169_a(vec3d, vec3d1); + if(movingobjectposition1 == null) + { + continue; + } + double d1 = vec3d.distanceTo(movingobjectposition1.hitVec); + if(d1 < d || d == 0.0D) + { + entity = entity1; + d = d1; + } + } + + if(entity != null) + { + movingobjectposition = new MovingObjectPosition(entity); + } + if(movingobjectposition != null) + { + if(movingobjectposition.entityHit != null) + { + if(!movingobjectposition.entityHit.attackEntityFrom(field_9397_j, 0)); + } + worldObj.newExplosion(null, posX, posY, posZ, 1.0F, true); + setEntityDead(); + } + posX += motionX; + posY += motionY; + posZ += motionZ; + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + rotationYaw = (float)((Math.atan2(motionX, motionZ) * 180D) / 3.1415927410125732D); + for(rotationPitch = (float)((Math.atan2(motionY, f) * 180D) / 3.1415927410125732D); rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } + for(; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + for(; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } + for(; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } + rotationPitch = prevRotationPitch + (rotationPitch - prevRotationPitch) * 0.2F; + rotationYaw = prevRotationYaw + (rotationYaw - prevRotationYaw) * 0.2F; + float f1 = 0.95F; + if(handleWaterMovement()) + { + for(int k = 0; k < 4; k++) + { + float f3 = 0.25F; + worldObj.spawnParticle("bubble", posX - motionX * (double)f3, posY - motionY * (double)f3, posZ - motionZ * (double)f3, motionX, motionY, motionZ); + } + + f1 = 0.8F; + } + motionX += field_9405_b; + motionY += field_9404_c; + motionZ += field_9403_d; + motionX *= f1; + motionY *= f1; + motionZ *= f1; + worldObj.spawnParticle("smoke", posX, posY + 0.5D, posZ, 0.0D, 0.0D, 0.0D); + setPosition(posX, posY, posZ); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("xTile", (short)field_9402_e); + nbttagcompound.setShort("yTile", (short)field_9401_f); + nbttagcompound.setShort("zTile", (short)field_9400_g); + nbttagcompound.setByte("inTile", (byte)field_9399_h); + nbttagcompound.setByte("shake", (byte)field_9406_a); + nbttagcompound.setByte("inGround", (byte)(field_9398_i ? 1 : 0)); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + field_9402_e = nbttagcompound.getShort("xTile"); + field_9401_f = nbttagcompound.getShort("yTile"); + field_9400_g = nbttagcompound.getShort("zTile"); + field_9399_h = nbttagcompound.getByte("inTile") & 0xff; + field_9406_a = nbttagcompound.getByte("shake") & 0xff; + field_9398_i = nbttagcompound.getByte("inGround") == 1; + } + + public boolean canBeCollidedWith() + { + return true; + } + + public float getCollisionBorderSize() + { + return 1.0F; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + setBeenAttacked(); + if(entity != null) + { + Vec3D vec3d = entity.getLookVec(); + if(vec3d != null) + { + motionX = vec3d.xCoord; + motionY = vec3d.yCoord; + motionZ = vec3d.zCoord; + field_9405_b = motionX * 0.10000000000000001D; + field_9404_c = motionY * 0.10000000000000001D; + field_9403_d = motionZ * 0.10000000000000001D; + } + return true; + } else + { + return false; + } + } + + public float getShadowSize() + { + return 0.0F; + } + + private int field_9402_e; + private int field_9401_f; + private int field_9400_g; + private int field_9399_h; + private boolean field_9398_i; + public int field_9406_a; + private EntityLiving field_9397_j; + private int field_9396_k; + private int field_9395_l; + public double field_9405_b; + public double field_9404_c; + public double field_9403_d; +} diff --git a/src/main/java/net/minecraft/src/EntityFish.java b/src/main/java/net/minecraft/src/EntityFish.java new file mode 100644 index 0000000..8e49265 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFish.java @@ -0,0 +1,394 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityFish extends Entity +{ + + public EntityFish(World world) + { + super(world); + tileX = -1; + tileY = -1; + tileZ = -1; + field_4092_g = 0; + field_4091_h = false; + field_4098_a = 0; + field_4089_j = 0; + field_4088_k = 0; + field_4096_c = null; + setSize(0.25F, 0.25F); + } + + protected void entityInit() + { + } + + public boolean isInRangeToRenderDist(double d) + { + double d1 = boundingBox.getAverageEdgeLength() * 4D; + d1 *= 64D; + return d < d1 * d1; + } + + public EntityFish(World world, double d, double d1, double d2) + { + this(world); + setPosition(d, d1, d2); + } + + public EntityFish(World world, EntityPlayer entityplayer) + { + super(world); + tileX = -1; + tileY = -1; + tileZ = -1; + field_4092_g = 0; + field_4091_h = false; + field_4098_a = 0; + field_4089_j = 0; + field_4088_k = 0; + field_4096_c = null; + angler = entityplayer; + angler.fishEntity = this; + setSize(0.25F, 0.25F); + setLocationAndAngles(entityplayer.posX, (entityplayer.posY + 1.6200000000000001D) - (double)entityplayer.yOffset, entityplayer.posZ, entityplayer.rotationYaw, entityplayer.rotationPitch); + posX -= MathHelper.cos((rotationYaw / 180F) * 3.141593F) * 0.16F; + posY -= 0.10000000149011612D; + posZ -= MathHelper.sin((rotationYaw / 180F) * 3.141593F) * 0.16F; + setPosition(posX, posY, posZ); + yOffset = 0.0F; + float f = 0.4F; + motionX = -MathHelper.sin((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f; + motionZ = MathHelper.cos((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f; + motionY = -MathHelper.sin((rotationPitch / 180F) * 3.141593F) * f; + func_4042_a(motionX, motionY, motionZ, 1.5F, 1.0F); + } + + public void func_4042_a(double d, double d1, double d2, float f, + float f1) + { + float f2 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + d /= f2; + d1 /= f2; + d2 /= f2; + d += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d1 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d2 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d *= f; + d1 *= f; + d2 *= f; + motionX = d; + motionY = d1; + motionZ = d2; + float f3 = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f3) * 180D) / 3.1415927410125732D); + field_4090_i = 0; + } + + public void setPositionAndRotation2(double d, double d1, double d2, float f, + float f1, int i) + { + field_6387_m = d; + field_6386_n = d1; + field_6385_o = d2; + field_6384_p = f; + field_6383_q = f1; + field_6388_l = i; + motionX = velocityX; + motionY = velocityY; + motionZ = velocityZ; + } + + public void setVelocity(double d, double d1, double d2) + { + velocityX = motionX = d; + velocityY = motionY = d1; + velocityZ = motionZ = d2; + } + + public void onUpdate() + { + super.onUpdate(); + if(field_6388_l > 0) + { + double d = posX + (field_6387_m - posX) / (double)field_6388_l; + double d1 = posY + (field_6386_n - posY) / (double)field_6388_l; + double d2 = posZ + (field_6385_o - posZ) / (double)field_6388_l; + double d4; + for(d4 = field_6384_p - (double)rotationYaw; d4 < -180D; d4 += 360D) { } + for(; d4 >= 180D; d4 -= 360D) { } + rotationYaw += d4 / (double)field_6388_l; + rotationPitch += (field_6383_q - (double)rotationPitch) / (double)field_6388_l; + field_6388_l--; + setPosition(d, d1, d2); + setRotation(rotationYaw, rotationPitch); + return; + } + if(!worldObj.multiplayerWorld) + { + ItemStack itemstack = angler.getCurrentEquippedItem(); + if(angler.isDead || !angler.isEntityAlive() || itemstack == null || itemstack.getItem() != Item.fishingRod || getDistanceSqToEntity(angler) > 1024D) + { + setEntityDead(); + angler.fishEntity = null; + return; + } + if(field_4096_c != null) + { + if(field_4096_c.isDead) + { + field_4096_c = null; + } else + { + posX = field_4096_c.posX; + posY = field_4096_c.boundingBox.minY + (double)field_4096_c.height * 0.80000000000000004D; + posZ = field_4096_c.posZ; + return; + } + } + } + if(field_4098_a > 0) + { + field_4098_a--; + } + if(field_4091_h) + { + int i = worldObj.getBlockId(tileX, tileY, tileZ); + if(i != field_4092_g) + { + field_4091_h = false; + motionX *= rand.nextFloat() * 0.2F; + motionY *= rand.nextFloat() * 0.2F; + motionZ *= rand.nextFloat() * 0.2F; + field_4090_i = 0; + field_4089_j = 0; + } else + { + field_4090_i++; + if(field_4090_i == 1200) + { + setEntityDead(); + } + return; + } + } else + { + field_4089_j++; + } + Vec3D vec3d = Vec3D.createVector(posX, posY, posZ); + Vec3D vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d1); + vec3d = Vec3D.createVector(posX, posY, posZ); + vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + if(movingobjectposition != null) + { + vec3d1 = Vec3D.createVector(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); + } + Entity entity = null; + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D)); + double d3 = 0.0D; + for(int j = 0; j < list.size(); j++) + { + Entity entity1 = (Entity)list.get(j); + if(!entity1.canBeCollidedWith() || entity1 == angler && field_4089_j < 5) + { + continue; + } + float f2 = 0.3F; + AxisAlignedBB axisalignedbb = entity1.boundingBox.expand(f2, f2, f2); + MovingObjectPosition movingobjectposition1 = axisalignedbb.func_1169_a(vec3d, vec3d1); + if(movingobjectposition1 == null) + { + continue; + } + double d6 = vec3d.distanceTo(movingobjectposition1.hitVec); + if(d6 < d3 || d3 == 0.0D) + { + entity = entity1; + d3 = d6; + } + } + + if(entity != null) + { + movingobjectposition = new MovingObjectPosition(entity); + } + if(movingobjectposition != null) + { + if(movingobjectposition.entityHit != null) + { + if(movingobjectposition.entityHit.attackEntityFrom(angler, 0)) + { + field_4096_c = movingobjectposition.entityHit; + } + } else + { + field_4091_h = true; + } + } + if(field_4091_h) + { + return; + } + moveEntity(motionX, motionY, motionZ); + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + rotationYaw = (float)((Math.atan2(motionX, motionZ) * 180D) / 3.1415927410125732D); + for(rotationPitch = (float)((Math.atan2(motionY, f) * 180D) / 3.1415927410125732D); rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } + for(; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + for(; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } + for(; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } + rotationPitch = prevRotationPitch + (rotationPitch - prevRotationPitch) * 0.2F; + rotationYaw = prevRotationYaw + (rotationYaw - prevRotationYaw) * 0.2F; + float f1 = 0.92F; + if(onGround || isCollidedHorizontally) + { + f1 = 0.5F; + } + int k = 5; + double d5 = 0.0D; + for(int l = 0; l < k; l++) + { + double d8 = ((boundingBox.minY + ((boundingBox.maxY - boundingBox.minY) * (double)(l + 0)) / (double)k) - 0.125D) + 0.125D; + double d9 = ((boundingBox.minY + ((boundingBox.maxY - boundingBox.minY) * (double)(l + 1)) / (double)k) - 0.125D) + 0.125D; + AxisAlignedBB axisalignedbb1 = AxisAlignedBB.getBoundingBoxFromPool(boundingBox.minX, d8, boundingBox.minZ, boundingBox.maxX, d9, boundingBox.maxZ); + if(worldObj.isAABBInMaterial(axisalignedbb1, Material.water)) + { + d5 += 1.0D / (double)k; + } + } + + if(d5 > 0.0D) + { + if(field_4088_k > 0) + { + field_4088_k--; + } else + if(rand.nextInt(500) == 0) + { + field_4088_k = rand.nextInt(30) + 10; + motionY -= 0.20000000298023224D; + worldObj.playSoundAtEntity(this, "random.splash", 0.25F, 1.0F + (rand.nextFloat() - rand.nextFloat()) * 0.4F); + float f3 = MathHelper.floor_double(boundingBox.minY); + for(int i1 = 0; (float)i1 < 1.0F + width * 20F; i1++) + { + float f4 = (rand.nextFloat() * 2.0F - 1.0F) * width; + float f6 = (rand.nextFloat() * 2.0F - 1.0F) * width; + worldObj.spawnParticle("bubble", posX + (double)f4, f3 + 1.0F, posZ + (double)f6, motionX, motionY - (double)(rand.nextFloat() * 0.2F), motionZ); + } + + for(int j1 = 0; (float)j1 < 1.0F + width * 20F; j1++) + { + float f5 = (rand.nextFloat() * 2.0F - 1.0F) * width; + float f7 = (rand.nextFloat() * 2.0F - 1.0F) * width; + worldObj.spawnParticle("splash", posX + (double)f5, f3 + 1.0F, posZ + (double)f7, motionX, motionY, motionZ); + } + + } + } + if(field_4088_k > 0) + { + motionY -= (double)(rand.nextFloat() * rand.nextFloat() * rand.nextFloat()) * 0.20000000000000001D; + } + double d7 = d5 * 2D - 1.0D; + motionY += 0.039999999105930328D * d7; + if(d5 > 0.0D) + { + f1 = (float)((double)f1 * 0.90000000000000002D); + motionY *= 0.80000000000000004D; + } + motionX *= f1; + motionY *= f1; + motionZ *= f1; + setPosition(posX, posY, posZ); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("xTile", (short)tileX); + nbttagcompound.setShort("yTile", (short)tileY); + nbttagcompound.setShort("zTile", (short)tileZ); + nbttagcompound.setByte("inTile", (byte)field_4092_g); + nbttagcompound.setByte("shake", (byte)field_4098_a); + nbttagcompound.setByte("inGround", (byte)(field_4091_h ? 1 : 0)); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + tileX = nbttagcompound.getShort("xTile"); + tileY = nbttagcompound.getShort("yTile"); + tileZ = nbttagcompound.getShort("zTile"); + field_4092_g = nbttagcompound.getByte("inTile") & 0xff; + field_4098_a = nbttagcompound.getByte("shake") & 0xff; + field_4091_h = nbttagcompound.getByte("inGround") == 1; + } + + public float getShadowSize() + { + return 0.0F; + } + + public int catchFish() + { + byte byte0 = 0; + if(field_4096_c != null) + { + double d = angler.posX - posX; + double d2 = angler.posY - posY; + double d4 = angler.posZ - posZ; + double d6 = MathHelper.sqrt_double(d * d + d2 * d2 + d4 * d4); + double d8 = 0.10000000000000001D; + field_4096_c.motionX += d * d8; + field_4096_c.motionY += d2 * d8 + (double)MathHelper.sqrt_double(d6) * 0.080000000000000002D; + field_4096_c.motionZ += d4 * d8; + byte0 = 3; + } else + if(field_4088_k > 0) + { + EntityItem entityitem = new EntityItem(worldObj, posX, posY, posZ, new ItemStack(Item.fishRaw)); + double d1 = angler.posX - posX; + double d3 = angler.posY - posY; + double d5 = angler.posZ - posZ; + double d7 = MathHelper.sqrt_double(d1 * d1 + d3 * d3 + d5 * d5); + double d9 = 0.10000000000000001D; + entityitem.motionX = d1 * d9; + entityitem.motionY = d3 * d9 + (double)MathHelper.sqrt_double(d7) * 0.080000000000000002D; + entityitem.motionZ = d5 * d9; + worldObj.entityJoinedWorld(entityitem); + byte0 = 1; + } + if(field_4091_h) + { + byte0 = 2; + } + setEntityDead(); + angler.fishEntity = null; + return byte0; + } + + private int tileX; + private int tileY; + private int tileZ; + private int field_4092_g; + private boolean field_4091_h; + public int field_4098_a; + public EntityPlayer angler; + private int field_4090_i; + private int field_4089_j; + private int field_4088_k; + public Entity field_4096_c; + private int field_6388_l; + private double field_6387_m; + private double field_6386_n; + private double field_6385_o; + private double field_6384_p; + private double field_6383_q; + private double velocityX; + private double velocityY; + private double velocityZ; +} diff --git a/src/main/java/net/minecraft/src/EntityFlameFX.java b/src/main/java/net/minecraft/src/EntityFlameFX.java new file mode 100644 index 0000000..b8a3f24 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFlameFX.java @@ -0,0 +1,71 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityFlameFX extends EntityFX +{ + + public EntityFlameFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + super(world, d, d1, d2, d3, d4, d5); + motionX = motionX * 0.0099999997764825821D + d3; + motionY = motionY * 0.0099999997764825821D + d4; + motionZ = motionZ * 0.0099999997764825821D + d5; + d += (rand.nextFloat() - rand.nextFloat()) * 0.05F; + d1 += (rand.nextFloat() - rand.nextFloat()) * 0.05F; + d2 += (rand.nextFloat() - rand.nextFloat()) * 0.05F; + field_672_a = particleScale; + particleRed = particleGreen = particleBlue = 1.0F; + particleMaxAge = (int)(8D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)) + 4; + noClip = true; + particleTextureIndex = 48; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = ((float)particleAge + f) / (float)particleMaxAge; + particleScale = field_672_a * (1.0F - f6 * f6 * 0.5F); + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public float getEntityBrightness(float f) + { + float f1 = ((float)particleAge + f) / (float)particleMaxAge; + if(f1 < 0.0F) + { + f1 = 0.0F; + } + if(f1 > 1.0F) + { + f1 = 1.0F; + } + float f2 = super.getEntityBrightness(f); + return f2 * f1 + (1.0F - f1); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + moveEntity(motionX, motionY, motionZ); + motionX *= 0.95999997854232788D; + motionY *= 0.95999997854232788D; + motionZ *= 0.95999997854232788D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } + + private float field_672_a; +} diff --git a/src/main/java/net/minecraft/src/EntityFlying.java b/src/main/java/net/minecraft/src/EntityFlying.java new file mode 100644 index 0000000..abab132 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityFlying.java @@ -0,0 +1,81 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityFlying extends EntityLiving +{ + + public EntityFlying(World world) + { + super(world); + } + + protected void fall(float f) + { + } + + public void moveEntityWithHeading(float f, float f1) + { + if(handleWaterMovement()) + { + moveFlying(f, f1, 0.02F); + moveEntity(motionX, motionY, motionZ); + motionX *= 0.80000001192092896D; + motionY *= 0.80000001192092896D; + motionZ *= 0.80000001192092896D; + } else + if(handleLavaMovement()) + { + moveFlying(f, f1, 0.02F); + moveEntity(motionX, motionY, motionZ); + motionX *= 0.5D; + motionY *= 0.5D; + motionZ *= 0.5D; + } else + { + float f2 = 0.91F; + if(onGround) + { + f2 = 0.5460001F; + int i = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(boundingBox.minY) - 1, MathHelper.floor_double(posZ)); + if(i > 0) + { + f2 = Block.blocksList[i].slipperiness * 0.91F; + } + } + float f3 = 0.1627714F / (f2 * f2 * f2); + moveFlying(f, f1, onGround ? 0.1F * f3 : 0.02F); + f2 = 0.91F; + if(onGround) + { + f2 = 0.5460001F; + int j = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(boundingBox.minY) - 1, MathHelper.floor_double(posZ)); + if(j > 0) + { + f2 = Block.blocksList[j].slipperiness * 0.91F; + } + } + moveEntity(motionX, motionY, motionZ); + motionX *= f2; + motionY *= f2; + motionZ *= f2; + } + field_705_Q = field_704_R; + double d = posX - prevPosX; + double d1 = posZ - prevPosZ; + float f4 = MathHelper.sqrt_double(d * d + d1 * d1) * 4F; + if(f4 > 1.0F) + { + f4 = 1.0F; + } + field_704_R += (f4 - field_704_R) * 0.4F; + field_703_S += field_704_R; + } + + public boolean isOnLadder() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/EntityGhast.java b/src/main/java/net/minecraft/src/EntityGhast.java new file mode 100644 index 0000000..60b7524 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityGhast.java @@ -0,0 +1,173 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityGhast extends EntityFlying + implements IMobs +{ + + public EntityGhast(World world) + { + super(world); + courseChangeCooldown = 0; + targetedEntity = null; + aggroCooldown = 0; + prevAttackCounter = 0; + attackCounter = 0; + texture = "/mob/ghast.png"; + setSize(4F, 4F); + isImmuneToFire = true; + } + + protected void updatePlayerActionState() + { + if(worldObj.difficultySetting == 0) + { + setEntityDead(); + } + prevAttackCounter = attackCounter; + double d = waypointX - posX; + double d1 = waypointY - posY; + double d2 = waypointZ - posZ; + double d3 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + if(d3 < 1.0D || d3 > 60D) + { + waypointX = posX + (double)((rand.nextFloat() * 2.0F - 1.0F) * 16F); + waypointY = posY + (double)((rand.nextFloat() * 2.0F - 1.0F) * 16F); + waypointZ = posZ + (double)((rand.nextFloat() * 2.0F - 1.0F) * 16F); + } + if(courseChangeCooldown-- <= 0) + { + courseChangeCooldown += rand.nextInt(5) + 2; + if(isCourseTraversable(waypointX, waypointY, waypointZ, d3)) + { + motionX += (d / d3) * 0.10000000000000001D; + motionY += (d1 / d3) * 0.10000000000000001D; + motionZ += (d2 / d3) * 0.10000000000000001D; + } else + { + waypointX = posX; + waypointY = posY; + waypointZ = posZ; + } + } + if(targetedEntity != null && targetedEntity.isDead) + { + targetedEntity = null; + } + if(targetedEntity == null || aggroCooldown-- <= 0) + { + targetedEntity = worldObj.getClosestPlayerToEntity(this, 100D); + if(targetedEntity != null) + { + aggroCooldown = 20; + } + } + double d4 = 64D; + if(targetedEntity != null && targetedEntity.getDistanceSqToEntity(this) < d4 * d4) + { + double d5 = targetedEntity.posX - posX; + double d6 = (targetedEntity.boundingBox.minY + (double)(targetedEntity.height / 2.0F)) - (posY + (double)(height / 2.0F)); + double d7 = targetedEntity.posZ - posZ; + renderYawOffset = rotationYaw = (-(float)Math.atan2(d5, d7) * 180F) / 3.141593F; + if(canEntityBeSeen(targetedEntity)) + { + if(attackCounter == 10) + { + worldObj.playSoundAtEntity(this, "mob.ghast.charge", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + } + attackCounter++; + if(attackCounter == 20) + { + worldObj.playSoundAtEntity(this, "mob.ghast.fireball", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + EntityFireball entityfireball = new EntityFireball(worldObj, this, d5, d6, d7); + double d8 = 4D; + Vec3D vec3d = getLook(1.0F); + entityfireball.posX = posX + vec3d.xCoord * d8; + entityfireball.posY = posY + (double)(height / 2.0F) + 0.5D; + entityfireball.posZ = posZ + vec3d.zCoord * d8; + worldObj.entityJoinedWorld(entityfireball); + attackCounter = -40; + } + } else + if(attackCounter > 0) + { + attackCounter--; + } + } else + { + renderYawOffset = rotationYaw = (-(float)Math.atan2(motionX, motionZ) * 180F) / 3.141593F; + if(attackCounter > 0) + { + attackCounter--; + } + } + texture = attackCounter <= 10 ? "/mob/ghast.png" : "/mob/ghast_fire.png"; + } + + private boolean isCourseTraversable(double d, double d1, double d2, double d3) + { + double d4 = (waypointX - posX) / d3; + double d5 = (waypointY - posY) / d3; + double d6 = (waypointZ - posZ) / d3; + AxisAlignedBB axisalignedbb = boundingBox.copy(); + for(int i = 1; (double)i < d3; i++) + { + axisalignedbb.offset(d4, d5, d6); + if(worldObj.getCollidingBoundingBoxes(this, axisalignedbb).size() > 0) + { + return false; + } + } + + return true; + } + + protected String getLivingSound() + { + return "mob.ghast.moan"; + } + + protected String getHurtSound() + { + return "mob.ghast.scream"; + } + + protected String getDeathSound() + { + return "mob.ghast.death"; + } + + protected int getDropItemId() + { + return Item.gunpowder.shiftedIndex; + } + + protected float getSoundVolume() + { + return 10F; + } + + public boolean getCanSpawnHere() + { + return rand.nextInt(20) == 0 && super.getCanSpawnHere() && worldObj.difficultySetting > 0; + } + + public int getMaxSpawnedInChunk() + { + return 1; + } + + public int courseChangeCooldown; + public double waypointX; + public double waypointY; + public double waypointZ; + private Entity targetedEntity; + private int aggroCooldown; + public int prevAttackCounter; + public int attackCounter; +} diff --git a/src/main/java/net/minecraft/src/EntityItem.java b/src/main/java/net/minecraft/src/EntityItem.java new file mode 100644 index 0000000..7a577a0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityItem.java @@ -0,0 +1,222 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityItem extends Entity +{ + + public EntityItem(World world, double d, double d1, double d2, + ItemStack itemstack) + { + super(world); + age = 0; + health = 5; + field_804_d = (float)(Math.random() * 3.1415926535897931D * 2D); + setSize(0.25F, 0.25F); + yOffset = height / 2.0F; + setPosition(d, d1, d2); + item = itemstack; + rotationYaw = (float)(Math.random() * 360D); + motionX = (float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D); + motionY = 0.20000000298023224D; + motionZ = (float)(Math.random() * 0.20000000298023224D - 0.10000000149011612D); + entityWalks = false; + } + + public EntityItem(World world) + { + super(world); + age = 0; + health = 5; + field_804_d = (float)(Math.random() * 3.1415926535897931D * 2D); + setSize(0.25F, 0.25F); + yOffset = height / 2.0F; + } + + protected void entityInit() + { + } + + public void onUpdate() + { + super.onUpdate(); + if(delayBeforeCanPickup > 0) + { + delayBeforeCanPickup--; + } + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + motionY -= 0.039999999105930328D; + if(worldObj.getBlockMaterial(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)) == Material.lava) + { + motionY = 0.20000000298023224D; + motionX = (rand.nextFloat() - rand.nextFloat()) * 0.2F; + motionZ = (rand.nextFloat() - rand.nextFloat()) * 0.2F; + worldObj.playSoundAtEntity(this, "random.fizz", 0.4F, 2.0F + rand.nextFloat() * 0.4F); + } + func_466_g(posX, posY, posZ); + moveEntity(motionX, motionY, motionZ); + float f = 0.98F; + if(onGround) + { + f = 0.5880001F; + int i = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(boundingBox.minY) - 1, MathHelper.floor_double(posZ)); + if(i > 0) + { + f = Block.blocksList[i].slipperiness * 0.98F; + } + } + motionX *= f; + motionY *= 0.98000001907348633D; + motionZ *= f; + if(onGround) + { + motionY *= -0.5D; + } + field_803_e++; + age++; + if(age >= 6000) + { + setEntityDead(); + } + } + + public boolean handleWaterMovement() + { + return worldObj.handleMaterialAcceleration(boundingBox, Material.water, this); + } + + private boolean func_466_g(double d, double d1, double d2) + { + int i = MathHelper.floor_double(d); + int j = MathHelper.floor_double(d1); + int k = MathHelper.floor_double(d2); + double d3 = d - (double)i; + double d4 = d1 - (double)j; + double d5 = d2 - (double)k; + if(Block.opaqueCubeLookup[worldObj.getBlockId(i, j, k)]) + { + boolean flag = !Block.opaqueCubeLookup[worldObj.getBlockId(i - 1, j, k)]; + boolean flag1 = !Block.opaqueCubeLookup[worldObj.getBlockId(i + 1, j, k)]; + boolean flag2 = !Block.opaqueCubeLookup[worldObj.getBlockId(i, j - 1, k)]; + boolean flag3 = !Block.opaqueCubeLookup[worldObj.getBlockId(i, j + 1, k)]; + boolean flag4 = !Block.opaqueCubeLookup[worldObj.getBlockId(i, j, k - 1)]; + boolean flag5 = !Block.opaqueCubeLookup[worldObj.getBlockId(i, j, k + 1)]; + byte byte0 = -1; + double d6 = 9999D; + if(flag && d3 < d6) + { + d6 = d3; + byte0 = 0; + } + if(flag1 && 1.0D - d3 < d6) + { + d6 = 1.0D - d3; + byte0 = 1; + } + if(flag2 && d4 < d6) + { + d6 = d4; + byte0 = 2; + } + if(flag3 && 1.0D - d4 < d6) + { + d6 = 1.0D - d4; + byte0 = 3; + } + if(flag4 && d5 < d6) + { + d6 = d5; + byte0 = 4; + } + if(flag5 && 1.0D - d5 < d6) + { + double d7 = 1.0D - d5; + byte0 = 5; + } + float f = rand.nextFloat() * 0.2F + 0.1F; + if(byte0 == 0) + { + motionX = -f; + } + if(byte0 == 1) + { + motionX = f; + } + if(byte0 == 2) + { + motionY = -f; + } + if(byte0 == 3) + { + motionY = f; + } + if(byte0 == 4) + { + motionZ = -f; + } + if(byte0 == 5) + { + motionZ = f; + } + } + return false; + } + + protected void dealFireDamage(int i) + { + attackEntityFrom(null, i); + } + + public boolean attackEntityFrom(Entity entity, int i) + { + setBeenAttacked(); + health -= i; + if(health <= 0) + { + setEntityDead(); + } + return false; + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("Health", (byte)health); + nbttagcompound.setShort("Age", (short)age); + nbttagcompound.setCompoundTag("Item", item.writeToNBT(new NBTTagCompound())); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + health = nbttagcompound.getShort("Health") & 0xff; + age = nbttagcompound.getShort("Age"); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Item"); + item = new ItemStack(nbttagcompound1); + } + + public void onCollideWithPlayer(EntityPlayer entityplayer) + { + if(worldObj.multiplayerWorld) + { + return; + } + int i = item.stackSize; + if(delayBeforeCanPickup == 0 && entityplayer.inventory.addItemStackToInventory(item)) + { + worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + entityplayer.onItemPickup(this, i); + setEntityDead(); + } + } + + public ItemStack item; + private int field_803_e; + public int age; + public int delayBeforeCanPickup; + private int health; + public float field_804_d; +} diff --git a/src/main/java/net/minecraft/src/EntityLavaFX.java b/src/main/java/net/minecraft/src/EntityLavaFX.java new file mode 100644 index 0000000..97b06ca --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLavaFX.java @@ -0,0 +1,65 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityLavaFX extends EntityFX +{ + + public EntityLavaFX(World world, double d, double d1, double d2) + { + super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); + motionX *= 0.80000001192092896D; + motionY *= 0.80000001192092896D; + motionZ *= 0.80000001192092896D; + motionY = rand.nextFloat() * 0.4F + 0.05F; + particleRed = particleGreen = particleBlue = 1.0F; + particleScale *= rand.nextFloat() * 2.0F + 0.2F; + field_674_a = particleScale; + particleMaxAge = (int)(16D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)); + noClip = false; + particleTextureIndex = 49; + } + + public float getEntityBrightness(float f) + { + return 1.0F; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = ((float)particleAge + f) / (float)particleMaxAge; + particleScale = field_674_a * (1.0F - f6 * f6); + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + float f = (float)particleAge / (float)particleMaxAge; + if(rand.nextFloat() > f) + { + worldObj.spawnParticle("smoke", posX, posY, posZ, motionX, motionY, motionZ); + } + motionY -= 0.029999999999999999D; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.99900001287460327D; + motionY *= 0.99900001287460327D; + motionZ *= 0.99900001287460327D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } + + private float field_674_a; +} diff --git a/src/main/java/net/minecraft/src/EntityList.java b/src/main/java/net/minecraft/src/EntityList.java new file mode 100644 index 0000000..aa0f24c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityList.java @@ -0,0 +1,144 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; + +public class EntityList +{ + + public EntityList() + { + } + + private static void addMapping(Class class1, String s, int i) + { + stringToClassMapping.put(s, class1); + classToStringMapping.put(class1, s); + IDtoClassMapping.put(Integer.valueOf(i), class1); + classToIDMapping.put(class1, Integer.valueOf(i)); + } + + public static Entity createEntityInWorld(String s, World world) + { + Entity entity = null; + try + { + Class class1 = (Class)stringToClassMapping.get(s); + if(class1 != null) + { + entity = (Entity)class1.getConstructor(new Class[] { + World.class + }).newInstance(new Object[] { + world + }); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + return entity; + } + + public static Entity createEntityFromNBT(NBTTagCompound nbttagcompound, World world) + { + Entity entity = null; + try + { + Class class1 = (Class)stringToClassMapping.get(nbttagcompound.getString("id")); + if(class1 != null) + { + entity = (Entity)class1.getConstructor(new Class[] { + World.class + }).newInstance(new Object[] { + world + }); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + if(entity != null) + { + entity.readFromNBT(nbttagcompound); + } else + { + System.out.println((new StringBuilder()).append("Skipping Entity with id ").append(nbttagcompound.getString("id")).toString()); + } + return entity; + } + + public static Entity createEntity(int i, World world) + { + Entity entity = null; + try + { + Class class1 = (Class)IDtoClassMapping.get(Integer.valueOf(i)); + if(class1 != null) + { + entity = (Entity)class1.getConstructor(new Class[] { + World.class + }).newInstance(new Object[] { + world + }); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + if(entity == null) + { + System.out.println((new StringBuilder()).append("Skipping Entity with id ").append(i).toString()); + } + return entity; + } + + public static int getEntityID(Entity entity) + { + return ((Integer)classToIDMapping.get(entity.getClass())).intValue(); + } + + public static String getEntityString(Entity entity) + { + return (String)classToStringMapping.get(entity.getClass()); + } + + private static Map stringToClassMapping = new HashMap(); + private static Map classToStringMapping = new HashMap(); + private static Map IDtoClassMapping = new HashMap(); + private static Map classToIDMapping = new HashMap(); + + static + { + addMapping(EntityArrow.class, "Arrow", 10); + addMapping(EntitySnowball.class, "Snowball", 11); + addMapping(EntityItem.class, "Item", 1); + addMapping(EntityPainting.class, "Painting", 9); + addMapping(EntityLiving.class, "Mob", 48); + addMapping(EntityMobs.class, "Monster", 49); + addMapping(EntityCreeper.class, "Creeper", 50); + addMapping(EntitySkeleton.class, "Skeleton", 51); + addMapping(EntitySpider.class, "Spider", 52); + addMapping(EntityZombieSimple.class, "Giant", 53); + addMapping(EntityZombie.class, "Zombie", 54); + addMapping(EntitySlime.class, "Slime", 55); + addMapping(EntityGhast.class, "Ghast", 56); + addMapping(EntityPigZombie.class, "PigZombie", 57); + addMapping(EntityPig.class, "Pig", 90); + addMapping(EntitySheep.class, "Sheep", 91); + addMapping(EntityCow.class, "Cow", 92); + addMapping(EntityChicken.class, "Chicken", 93); + addMapping(EntitySquid.class, "Squid", 94); + addMapping(EntityTNTPrimed.class, "PrimedTnt", 20); + addMapping(EntityFallingSand.class, "FallingSand", 21); + addMapping(EntityMinecart.class, "Minecart", 40); + addMapping(EntityBoat.class, "Boat", 41); + } +} diff --git a/src/main/java/net/minecraft/src/EntityLiving.java b/src/main/java/net/minecraft/src/EntityLiving.java new file mode 100644 index 0000000..d38883e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityLiving.java @@ -0,0 +1,894 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public abstract class EntityLiving extends Entity +{ + + public EntityLiving(World world) + { + super(world); + field_9366_o = 20; + renderYawOffset = 0.0F; + prevRenderYawOffset = 0.0F; + field_9358_y = true; + texture = "/mob/char.png"; + field_9355_A = true; + field_9353_B = 0.0F; + field_9351_C = null; + field_9349_D = 1.0F; + scoreValue = 0; + field_9345_F = 0.0F; + field_9343_G = false; + attackedAtYaw = 0.0F; + deathTime = 0; + attackTime = 0; + field_9327_S = false; + field_9326_T = -1; + field_9325_U = (float)(Math.random() * 0.89999997615814209D + 0.10000000149011612D); + field_9348_ae = 0.0F; + field_9346_af = 0; + field_9344_ag = 0; + isJumping = false; + defaultPitch = 0.0F; + moveSpeed = 0.7F; + field_4127_c = 0; + health = 10; + preventEntitySpawning = true; + field_9363_r = (float)(Math.random() + 1.0D) * 0.01F; + setPosition(posX, posY, posZ); + field_9365_p = (float)Math.random() * 12398F; + rotationYaw = (float)(Math.random() * 3.1415927410125732D * 2D); + stepHeight = 0.5F; + } + + protected void entityInit() + { + } + + public boolean canEntityBeSeen(Entity entity) + { + return worldObj.rayTraceBlocks(Vec3D.createVector(posX, posY + (double)getEyeHeight(), posZ), Vec3D.createVector(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ)) == null; + } + + public String getEntityTexture() + { + return texture; + } + + public boolean canBeCollidedWith() + { + return !isDead; + } + + public boolean canBePushed() + { + return !isDead; + } + + public float getEyeHeight() + { + return height * 0.85F; + } + + public int func_421_b() + { + return 80; + } + + public void func_22050_O() + { + String s = getLivingSound(); + if(s != null) + { + worldObj.playSoundAtEntity(this, s, getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + } + } + + public void onEntityUpdate() + { + prevSwingProgress = swingProgress; + super.onEntityUpdate(); + if(rand.nextInt(1000) < field_4121_a++) + { + field_4121_a = -func_421_b(); + func_22050_O(); + } + if(isEntityAlive() && func_345_I()) + { + attackEntityFrom(null, 1); + } + if(isImmuneToFire || worldObj.multiplayerWorld) + { + fire = 0; + } + if(isEntityAlive() && isInsideOfMaterial(Material.water) && !canBreatheUnderwater()) + { + air--; + if(air == -20) + { + air = 0; + for(int i = 0; i < 8; i++) + { + float f = rand.nextFloat() - rand.nextFloat(); + float f1 = rand.nextFloat() - rand.nextFloat(); + float f2 = rand.nextFloat() - rand.nextFloat(); + worldObj.spawnParticle("bubble", posX + (double)f, posY + (double)f1, posZ + (double)f2, motionX, motionY, motionZ); + } + + attackEntityFrom(null, 2); + } + fire = 0; + } else + { + air = maxAir; + } + field_9329_Q = field_9328_R; + if(attackTime > 0) + { + attackTime--; + } + if(hurtTime > 0) + { + hurtTime--; + } + if(field_9306_bj > 0) + { + field_9306_bj--; + } + if(health <= 0) + { + deathTime++; + if(deathTime > 20) + { + func_6392_F(); + setEntityDead(); + for(int j = 0; j < 20; j++) + { + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + worldObj.spawnParticle("explode", (posX + (double)(rand.nextFloat() * width * 2.0F)) - (double)width, posY + (double)(rand.nextFloat() * height), (posZ + (double)(rand.nextFloat() * width * 2.0F)) - (double)width, d, d1, d2); + } + + } + } + field_9359_x = field_9360_w; + prevRenderYawOffset = renderYawOffset; + prevRotationYaw = rotationYaw; + prevRotationPitch = rotationPitch; + } + + public void spawnExplosionParticle() + { + for(int i = 0; i < 20; i++) + { + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + double d3 = 10D; + worldObj.spawnParticle("explode", (posX + (double)(rand.nextFloat() * width * 2.0F)) - (double)width - d * d3, (posY + (double)(rand.nextFloat() * height)) - d1 * d3, (posZ + (double)(rand.nextFloat() * width * 2.0F)) - (double)width - d2 * d3, d, d1, d2); + } + + } + + public void updateRidden() + { + super.updateRidden(); + field_9362_u = field_9361_v; + field_9361_v = 0.0F; + } + + public void setPositionAndRotation2(double d, double d1, double d2, float f, + float f1, int i) + { + yOffset = 0.0F; + field_9323_Z = d; + field_9356_aa = d1; + field_9354_ab = d2; + field_9352_ac = f; + field_9350_ad = f1; + field_9324_Y = i; + } + + public void onUpdate() + { + super.onUpdate(); + onLivingUpdate(); + double d = posX - prevPosX; + double d1 = posZ - prevPosZ; + float f = MathHelper.sqrt_double(d * d + d1 * d1); + float f1 = renderYawOffset; + float f2 = 0.0F; + field_9362_u = field_9361_v; + float f3 = 0.0F; + if(f > 0.05F) + { + f3 = 1.0F; + f2 = f * 3F; + f1 = ((float)Math.atan2(d1, d) * 180F) / 3.141593F - 90F; + } + if(swingProgress > 0.0F) + { + f1 = rotationYaw; + } + if(!onGround) + { + f3 = 0.0F; + } + field_9361_v = field_9361_v + (f3 - field_9361_v) * 0.3F; + float f4; + for(f4 = f1 - renderYawOffset; f4 < -180F; f4 += 360F) { } + for(; f4 >= 180F; f4 -= 360F) { } + renderYawOffset += f4 * 0.3F; + float f5; + for(f5 = rotationYaw - renderYawOffset; f5 < -180F; f5 += 360F) { } + for(; f5 >= 180F; f5 -= 360F) { } + boolean flag = f5 < -90F || f5 >= 90F; + if(f5 < -75F) + { + f5 = -75F; + } + if(f5 >= 75F) + { + f5 = 75F; + } + renderYawOffset = rotationYaw - f5; + if(f5 * f5 > 2500F) + { + renderYawOffset += f5 * 0.2F; + } + if(flag) + { + f2 *= -1F; + } + for(; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } + for(; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } + for(; renderYawOffset - prevRenderYawOffset < -180F; prevRenderYawOffset -= 360F) { } + for(; renderYawOffset - prevRenderYawOffset >= 180F; prevRenderYawOffset += 360F) { } + for(; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } + for(; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + field_9360_w += f2; + } + + protected void setSize(float f, float f1) + { + super.setSize(f, f1); + } + + public void heal(int i) + { + if(health <= 0) + { + return; + } + health += i; + if(health > 20) + { + health = 20; + } + field_9306_bj = field_9366_o / 2; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(worldObj.multiplayerWorld) + { + return false; + } + field_9344_ag = 0; + if(health <= 0) + { + return false; + } + field_704_R = 1.5F; + boolean flag = true; + if((float)field_9306_bj > (float)field_9366_o / 2.0F) + { + if(i <= field_9346_af) + { + return false; + } + damageEntity(i - field_9346_af); + field_9346_af = i; + flag = false; + } else + { + field_9346_af = i; + prevHealth = health; + field_9306_bj = field_9366_o; + damageEntity(i); + hurtTime = maxHurtTime = 10; + } + attackedAtYaw = 0.0F; + if(flag) + { + worldObj.func_9425_a(this, (byte)2); + setBeenAttacked(); + if(entity != null) + { + double d = entity.posX - posX; + double d1; + for(d1 = entity.posZ - posZ; d * d + d1 * d1 < 0.0001D; d1 = (Math.random() - Math.random()) * 0.01D) + { + d = (Math.random() - Math.random()) * 0.01D; + } + + attackedAtYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - rotationYaw; + knockBack(entity, i, d, d1); + } else + { + attackedAtYaw = (int)(Math.random() * 2D) * 180; + } + } + if(health <= 0) + { + if(flag) + { + worldObj.playSoundAtEntity(this, getDeathSound(), getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + } + onDeath(entity); + } else + if(flag) + { + worldObj.playSoundAtEntity(this, getHurtSound(), getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + } + return true; + } + + public void performHurtAnimation() + { + hurtTime = maxHurtTime = 10; + attackedAtYaw = 0.0F; + } + + protected void damageEntity(int i) + { + health -= i; + } + + protected float getSoundVolume() + { + return 1.0F; + } + + protected String getLivingSound() + { + return null; + } + + protected String getHurtSound() + { + return "random.hurt"; + } + + protected String getDeathSound() + { + return "random.hurt"; + } + + public void knockBack(Entity entity, int i, double d, double d1) + { + float f = MathHelper.sqrt_double(d * d + d1 * d1); + float f1 = 0.4F; + motionX /= 2D; + motionY /= 2D; + motionZ /= 2D; + motionX -= (d / (double)f) * (double)f1; + motionY += 0.40000000596046448D; + motionZ -= (d1 / (double)f) * (double)f1; + if(motionY > 0.40000000596046448D) + { + motionY = 0.40000000596046448D; + } + } + + public void onDeath(Entity entity) + { + if(scoreValue > 0 && entity != null) + { + entity.addToPlayerScore(this, scoreValue); + } + field_9327_S = true; + if(!worldObj.multiplayerWorld) + { + func_21066_o(); + } + worldObj.func_9425_a(this, (byte)3); + } + + protected void func_21066_o() + { + int i = getDropItemId(); + if(i > 0) + { + int j = rand.nextInt(3); + for(int k = 0; k < j; k++) + { + dropItem(i, 1); + } + + } + } + + protected int getDropItemId() + { + return 0; + } + + protected void fall(float f) + { + int i = (int)Math.ceil(f - 3F); + if(i > 0) + { + attackEntityFrom(null, i); + int j = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(posY - 0.20000000298023224D - (double)yOffset), MathHelper.floor_double(posZ)); + if(j > 0) + { + StepSound stepsound = Block.blocksList[j].stepSound; + worldObj.playSoundAtEntity(this, stepsound.func_1145_d(), stepsound.func_1147_b() * 0.5F, stepsound.func_1144_c() * 0.75F); + } + } + } + + public void moveEntityWithHeading(float f, float f1) + { + if(handleWaterMovement()) + { + double d = posY; + moveFlying(f, f1, 0.02F); + moveEntity(motionX, motionY, motionZ); + motionX *= 0.80000001192092896D; + motionY *= 0.80000001192092896D; + motionZ *= 0.80000001192092896D; + motionY -= 0.02D; + if(isCollidedHorizontally && isOffsetPositionInLiquid(motionX, ((motionY + 0.60000002384185791D) - posY) + d, motionZ)) + { + motionY = 0.30000001192092896D; + } + } else + if(handleLavaMovement()) + { + double d1 = posY; + moveFlying(f, f1, 0.02F); + moveEntity(motionX, motionY, motionZ); + motionX *= 0.5D; + motionY *= 0.5D; + motionZ *= 0.5D; + motionY -= 0.02D; + if(isCollidedHorizontally && isOffsetPositionInLiquid(motionX, ((motionY + 0.60000002384185791D) - posY) + d1, motionZ)) + { + motionY = 0.30000001192092896D; + } + } else + { + float f2 = 0.91F; + if(onGround) + { + f2 = 0.5460001F; + int i = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(boundingBox.minY) - 1, MathHelper.floor_double(posZ)); + if(i > 0) + { + f2 = Block.blocksList[i].slipperiness * 0.91F; + } + } + float f3 = 0.1627714F / (f2 * f2 * f2); + moveFlying(f, f1, onGround ? 0.1F * f3 : 0.02F); + f2 = 0.91F; + if(onGround) + { + f2 = 0.5460001F; + int j = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(boundingBox.minY) - 1, MathHelper.floor_double(posZ)); + if(j > 0) + { + f2 = Block.blocksList[j].slipperiness * 0.91F; + } + } + if(isOnLadder()) + { + fallDistance = 0.0F; + if(motionY < -0.14999999999999999D) + { + motionY = -0.14999999999999999D; + } + } + moveEntity(motionX, motionY, motionZ); + if(isCollidedHorizontally && isOnLadder()) + { + motionY = 0.20000000000000001D; + } + motionY -= 0.080000000000000002D; + motionY *= 0.98000001907348633D; + motionX *= f2; + motionZ *= f2; + } + field_705_Q = field_704_R; + double d2 = posX - prevPosX; + double d3 = posZ - prevPosZ; + float f4 = MathHelper.sqrt_double(d2 * d2 + d3 * d3) * 4F; + if(f4 > 1.0F) + { + f4 = 1.0F; + } + field_704_R += (f4 - field_704_R) * 0.4F; + field_703_S += field_704_R; + } + + public boolean isOnLadder() + { + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(boundingBox.minY); + int k = MathHelper.floor_double(posZ); + return worldObj.getBlockId(i, j, k) == Block.ladder.blockID || worldObj.getBlockId(i, j + 1, k) == Block.ladder.blockID; + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("Health", (short)health); + nbttagcompound.setShort("HurtTime", (short)hurtTime); + nbttagcompound.setShort("DeathTime", (short)deathTime); + nbttagcompound.setShort("AttackTime", (short)attackTime); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + health = nbttagcompound.getShort("Health"); + if(!nbttagcompound.hasKey("Health")) + { + health = 10; + } + hurtTime = nbttagcompound.getShort("HurtTime"); + deathTime = nbttagcompound.getShort("DeathTime"); + attackTime = nbttagcompound.getShort("AttackTime"); + } + + public boolean isEntityAlive() + { + return !isDead && health > 0; + } + + public boolean canBreatheUnderwater() + { + return false; + } + + public void onLivingUpdate() + { + if(field_9324_Y > 0) + { + double d = posX + (field_9323_Z - posX) / (double)field_9324_Y; + double d1 = posY + (field_9356_aa - posY) / (double)field_9324_Y; + double d2 = posZ + (field_9354_ab - posZ) / (double)field_9324_Y; + double d3; + for(d3 = field_9352_ac - (double)rotationYaw; d3 < -180D; d3 += 360D) { } + for(; d3 >= 180D; d3 -= 360D) { } + rotationYaw += d3 / (double)field_9324_Y; + rotationPitch += (field_9350_ad - (double)rotationPitch) / (double)field_9324_Y; + field_9324_Y--; + setPosition(d, d1, d2); + setRotation(rotationYaw, rotationPitch); + } + if(func_22049_v()) + { + isJumping = false; + moveStrafing = 0.0F; + moveForward = 0.0F; + randomYawVelocity = 0.0F; + } else + if(!field_9343_G) + { + updatePlayerActionState(); + } + boolean flag = handleWaterMovement(); + boolean flag1 = handleLavaMovement(); + if(isJumping) + { + if(flag) + { + motionY += 0.039999999105930328D; + } else + if(flag1) + { + motionY += 0.039999999105930328D; + } else + if(onGround) + { + jump(); + } + } + moveStrafing *= 0.98F; + moveForward *= 0.98F; + randomYawVelocity *= 0.9F; + moveEntityWithHeading(moveStrafing, moveForward); + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + if(list != null && list.size() > 0) + { + for(int i = 0; i < list.size(); i++) + { + Entity entity = (Entity)list.get(i); + if(entity.canBePushed()) + { + entity.applyEntityCollision(this); + } + } + + } + } + + protected boolean func_22049_v() + { + return health <= 0; + } + + protected void jump() + { + motionY = 0.41999998688697815D; + } + + protected void updatePlayerActionState() + { + field_9344_ag++; + EntityPlayer entityplayer = worldObj.getClosestPlayerToEntity(this, -1D); + if(entityplayer != null) + { + double d = ((Entity) (entityplayer)).posX - posX; + double d1 = ((Entity) (entityplayer)).posY - posY; + double d2 = ((Entity) (entityplayer)).posZ - posZ; + double d3 = d * d + d1 * d1 + d2 * d2; + if(d3 > 16384D) + { + setEntityDead(); + } + if(field_9344_ag > 600 && rand.nextInt(800) == 0) + { + if(d3 < 1024D) + { + field_9344_ag = 0; + } else + { + setEntityDead(); + } + } + } + moveStrafing = 0.0F; + moveForward = 0.0F; + float f = 8F; + if(rand.nextFloat() < 0.02F) + { + EntityPlayer entityplayer1 = worldObj.getClosestPlayerToEntity(this, f); + if(entityplayer1 != null) + { + field_4120_b = entityplayer1; + field_4127_c = 10 + rand.nextInt(20); + } else + { + randomYawVelocity = (rand.nextFloat() - 0.5F) * 20F; + } + } + if(field_4120_b != null) + { + faceEntity(field_4120_b, 10F); + if(field_4127_c-- <= 0 || field_4120_b.isDead || field_4120_b.getDistanceSqToEntity(this) > (double)(f * f)) + { + field_4120_b = null; + } + } else + { + if(rand.nextFloat() < 0.05F) + { + randomYawVelocity = (rand.nextFloat() - 0.5F) * 20F; + } + rotationYaw += randomYawVelocity; + rotationPitch = defaultPitch; + } + boolean flag = handleWaterMovement(); + boolean flag1 = handleLavaMovement(); + if(flag || flag1) + { + isJumping = rand.nextFloat() < 0.8F; + } + } + + public void faceEntity(Entity entity, float f) + { + double d = entity.posX - posX; + double d2 = entity.posZ - posZ; + double d1; + if(entity instanceof EntityLiving) + { + EntityLiving entityliving = (EntityLiving)entity; + d1 = (entityliving.posY + (double)entityliving.getEyeHeight()) - (posY + (double)getEyeHeight()); + } else + { + d1 = (entity.boundingBox.minY + entity.boundingBox.maxY) / 2D - (posY + (double)getEyeHeight()); + } + double d3 = MathHelper.sqrt_double(d * d + d2 * d2); + float f1 = (float)((Math.atan2(d2, d) * 180D) / 3.1415927410125732D) - 90F; + float f2 = (float)((Math.atan2(d1, d3) * 180D) / 3.1415927410125732D); + rotationPitch = -updateRotation(rotationPitch, f2, f); + rotationYaw = updateRotation(rotationYaw, f1, f); + } + + private float updateRotation(float f, float f1, float f2) + { + float f3; + for(f3 = f1 - f; f3 < -180F; f3 += 360F) { } + for(; f3 >= 180F; f3 -= 360F) { } + if(f3 > f2) + { + f3 = f2; + } + if(f3 < -f2) + { + f3 = -f2; + } + return f + f3; + } + + public void func_6392_F() + { + } + + public boolean getCanSpawnHere() + { + return worldObj.checkIfAABBIsClear(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0 && !worldObj.getIsAnyLiquid(boundingBox); + } + + protected void kill() + { + attackEntityFrom(null, 4); + } + + public float getSwingProgress(float f) + { + float f1 = swingProgress - prevSwingProgress; + if(f1 < 0.0F) + { + f1++; + } + return prevSwingProgress + f1 * f; + } + + public Vec3D getPosition(float f) + { + if(f == 1.0F) + { + return Vec3D.createVector(posX, posY, posZ); + } else + { + double d = prevPosX + (posX - prevPosX) * (double)f; + double d1 = prevPosY + (posY - prevPosY) * (double)f; + double d2 = prevPosZ + (posZ - prevPosZ) * (double)f; + return Vec3D.createVector(d, d1, d2); + } + } + + public Vec3D getLookVec() + { + return getLook(1.0F); + } + + public Vec3D getLook(float f) + { + if(f == 1.0F) + { + float f1 = MathHelper.cos(-rotationYaw * 0.01745329F - 3.141593F); + float f3 = MathHelper.sin(-rotationYaw * 0.01745329F - 3.141593F); + float f5 = -MathHelper.cos(-rotationPitch * 0.01745329F); + float f7 = MathHelper.sin(-rotationPitch * 0.01745329F); + return Vec3D.createVector(f3 * f5, f7, f1 * f5); + } else + { + float f2 = prevRotationPitch + (rotationPitch - prevRotationPitch) * f; + float f4 = prevRotationYaw + (rotationYaw - prevRotationYaw) * f; + float f6 = MathHelper.cos(-f4 * 0.01745329F - 3.141593F); + float f8 = MathHelper.sin(-f4 * 0.01745329F - 3.141593F); + float f9 = -MathHelper.cos(-f2 * 0.01745329F); + float f10 = MathHelper.sin(-f2 * 0.01745329F); + return Vec3D.createVector(f8 * f9, f10, f6 * f9); + } + } + + public MovingObjectPosition rayTrace(double d, float f) + { + Vec3D vec3d = getPosition(f); + Vec3D vec3d1 = getLook(f); + Vec3D vec3d2 = vec3d.addVector(vec3d1.xCoord * d, vec3d1.yCoord * d, vec3d1.zCoord * d); + return worldObj.rayTraceBlocks(vec3d, vec3d2); + } + + public int getMaxSpawnedInChunk() + { + return 4; + } + + public ItemStack getHeldItem() + { + return null; + } + + public void handleHealthUpdate(byte byte0) + { + if(byte0 == 2) + { + field_704_R = 1.5F; + field_9306_bj = field_9366_o; + hurtTime = maxHurtTime = 10; + attackedAtYaw = 0.0F; + worldObj.playSoundAtEntity(this, getHurtSound(), getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + attackEntityFrom(null, 0); + } else + if(byte0 == 3) + { + worldObj.playSoundAtEntity(this, getDeathSound(), getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + health = 0; + onDeath(null); + } else + { + super.handleHealthUpdate(byte0); + } + } + + public boolean isPlayerSleeping() + { + return false; + } + + public int field_9366_o; + public float field_9365_p; + public float field_9363_r; + public float renderYawOffset; + public float prevRenderYawOffset; + protected float field_9362_u; + protected float field_9361_v; + protected float field_9360_w; + protected float field_9359_x; + protected boolean field_9358_y; + protected String texture; + protected boolean field_9355_A; + protected float field_9353_B; + protected String field_9351_C; + protected float field_9349_D; + protected int scoreValue; + protected float field_9345_F; + public boolean field_9343_G; + public float prevSwingProgress; + public float swingProgress; + public int health; + public int prevHealth; + private int field_4121_a; + public int hurtTime; + public int maxHurtTime; + public float attackedAtYaw; + public int deathTime; + public int attackTime; + public float field_9329_Q; + public float field_9328_R; + protected boolean field_9327_S; + public int field_9326_T; + public float field_9325_U; + public float field_705_Q; + public float field_704_R; + public float field_703_S; + protected int field_9324_Y; + protected double field_9323_Z; + protected double field_9356_aa; + protected double field_9354_ab; + protected double field_9352_ac; + protected double field_9350_ad; + float field_9348_ae; + protected int field_9346_af; + protected int field_9344_ag; + protected float moveStrafing; + protected float moveForward; + protected float randomYawVelocity; + protected boolean isJumping; + protected float defaultPitch; + protected float moveSpeed; + private Entity field_4120_b; + private int field_4127_c; +} diff --git a/src/main/java/net/minecraft/src/EntityMinecart.java b/src/main/java/net/minecraft/src/EntityMinecart.java new file mode 100644 index 0000000..ad26511 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMinecart.java @@ -0,0 +1,871 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.List; +import java.util.Random; + +public class EntityMinecart extends Entity + implements IInventory +{ + + public EntityMinecart(World world) + { + super(world); + cargoItems = new ItemStack[36]; + field_20910_a = 0; + field_20911_b = 0; + field_20912_c = 1; + field_856_i = false; + preventEntitySpawning = true; + setSize(0.98F, 0.7F); + yOffset = height / 2.0F; + entityWalks = false; + } + + protected void entityInit() + { + } + + public AxisAlignedBB func_383_b_(Entity entity) + { + return entity.boundingBox; + } + + public AxisAlignedBB getBoundingBox() + { + return null; + } + + public boolean canBePushed() + { + return true; + } + + public EntityMinecart(World world, double d, double d1, double d2, + int i) + { + this(world); + setPosition(d, d1 + (double)yOffset, d2); + motionX = 0.0D; + motionY = 0.0D; + motionZ = 0.0D; + prevPosX = d; + prevPosY = d1; + prevPosZ = d2; + minecartType = i; + } + + public double getMountedYOffset() + { + return (double)height * 0.0D - 0.30000001192092896D; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(worldObj.multiplayerWorld || isDead) + { + return true; + } + field_20912_c = -field_20912_c; + field_20911_b = 10; + setBeenAttacked(); + field_20910_a += i * 10; + if(field_20910_a > 40) + { + dropItemWithOffset(Item.minecartEmpty.shiftedIndex, 1, 0.0F); + if(minecartType == 1) + { + dropItemWithOffset(Block.crate.blockID, 1, 0.0F); + } else + if(minecartType == 2) + { + dropItemWithOffset(Block.stoneOvenIdle.blockID, 1, 0.0F); + } + setEntityDead(); + } + return true; + } + + public void performHurtAnimation() + { + System.out.println("Animating hurt"); + field_20912_c = -field_20912_c; + field_20911_b = 10; + field_20910_a += field_20910_a * 10; + } + + public boolean canBeCollidedWith() + { + return !isDead; + } + + public void setEntityDead() + { +label0: + for(int i = 0; i < getSizeInventory(); i++) + { + ItemStack itemstack = getStackInSlot(i); + if(itemstack == null) + { + continue; + } + float f = rand.nextFloat() * 0.8F + 0.1F; + float f1 = rand.nextFloat() * 0.8F + 0.1F; + float f2 = rand.nextFloat() * 0.8F + 0.1F; + do + { + if(itemstack.stackSize <= 0) + { + continue label0; + } + int j = rand.nextInt(21) + 10; + if(j > itemstack.stackSize) + { + j = itemstack.stackSize; + } + itemstack.stackSize -= j; + EntityItem entityitem = new EntityItem(worldObj, posX + (double)f, posY + (double)f1, posZ + (double)f2, new ItemStack(itemstack.itemID, j, itemstack.getItemDamage())); + float f3 = 0.05F; + entityitem.motionX = (float)rand.nextGaussian() * f3; + entityitem.motionY = (float)rand.nextGaussian() * f3 + 0.2F; + entityitem.motionZ = (float)rand.nextGaussian() * f3; + worldObj.entityJoinedWorld(entityitem); + } while(true); + } + + super.setEntityDead(); + } + + public void onUpdate() + { + if(field_20911_b > 0) + { + field_20911_b--; + } + if(field_20910_a > 0) + { + field_20910_a--; + } + if(worldObj.multiplayerWorld && field_9415_k > 0) + { + if(field_9415_k > 0) + { + double d = posX + (field_9414_l - posX) / (double)field_9415_k; + double d1 = posY + (field_9413_m - posY) / (double)field_9415_k; + double d3 = posZ + (field_9412_n - posZ) / (double)field_9415_k; + double d4; + for(d4 = field_9411_o - (double)rotationYaw; d4 < -180D; d4 += 360D) { } + for(; d4 >= 180D; d4 -= 360D) { } + rotationYaw += d4 / (double)field_9415_k; + rotationPitch += (field_9410_p - (double)rotationPitch) / (double)field_9415_k; + field_9415_k--; + setPosition(d, d1, d3); + setRotation(rotationYaw, rotationPitch); + } else + { + setPosition(posX, posY, posZ); + setRotation(rotationYaw, rotationPitch); + } + return; + } + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + motionY -= 0.039999999105930328D; + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(posY); + int k = MathHelper.floor_double(posZ); + if(worldObj.getBlockId(i, j - 1, k) == Block.minecartTrack.blockID) + { + j--; + } + double d2 = 0.40000000000000002D; + boolean flag = false; + double d5 = 0.0078125D; + if(worldObj.getBlockId(i, j, k) == Block.minecartTrack.blockID) + { + Vec3D vec3d = func_514_g(posX, posY, posZ); + int l = worldObj.getBlockMetadata(i, j, k); + posY = j; + if(l >= 2 && l <= 5) + { + posY = j + 1; + } + if(l == 2) + { + motionX -= d5; + } + if(l == 3) + { + motionX += d5; + } + if(l == 4) + { + motionZ += d5; + } + if(l == 5) + { + motionZ -= d5; + } + int ai[][] = field_855_j[l]; + double d8 = ai[1][0] - ai[0][0]; + double d10 = ai[1][2] - ai[0][2]; + double d11 = Math.sqrt(d8 * d8 + d10 * d10); + double d12 = motionX * d8 + motionZ * d10; + if(d12 < 0.0D) + { + d8 = -d8; + d10 = -d10; + } + double d13 = Math.sqrt(motionX * motionX + motionZ * motionZ); + motionX = (d13 * d8) / d11; + motionZ = (d13 * d10) / d11; + double d16 = 0.0D; + double d17 = (double)i + 0.5D + (double)ai[0][0] * 0.5D; + double d18 = (double)k + 0.5D + (double)ai[0][2] * 0.5D; + double d19 = (double)i + 0.5D + (double)ai[1][0] * 0.5D; + double d20 = (double)k + 0.5D + (double)ai[1][2] * 0.5D; + d8 = d19 - d17; + d10 = d20 - d18; + if(d8 == 0.0D) + { + posX = (double)i + 0.5D; + d16 = posZ - (double)k; + } else + if(d10 == 0.0D) + { + posZ = (double)k + 0.5D; + d16 = posX - (double)i; + } else + { + double d21 = posX - d17; + double d23 = posZ - d18; + double d25 = (d21 * d8 + d23 * d10) * 2D; + d16 = d25; + } + posX = d17 + d8 * d16; + posZ = d18 + d10 * d16; + setPosition(posX, posY + (double)yOffset, posZ); + double d22 = motionX; + double d24 = motionZ; + if(riddenByEntity != null) + { + d22 *= 0.75D; + d24 *= 0.75D; + } + if(d22 < -d2) + { + d22 = -d2; + } + if(d22 > d2) + { + d22 = d2; + } + if(d24 < -d2) + { + d24 = -d2; + } + if(d24 > d2) + { + d24 = d2; + } + moveEntity(d22, 0.0D, d24); + if(ai[0][1] != 0 && MathHelper.floor_double(posX) - i == ai[0][0] && MathHelper.floor_double(posZ) - k == ai[0][2]) + { + setPosition(posX, posY + (double)ai[0][1], posZ); + } else + if(ai[1][1] != 0 && MathHelper.floor_double(posX) - i == ai[1][0] && MathHelper.floor_double(posZ) - k == ai[1][2]) + { + setPosition(posX, posY + (double)ai[1][1], posZ); + } + if(riddenByEntity != null) + { + motionX *= 0.99699997901916504D; + motionY *= 0.0D; + motionZ *= 0.99699997901916504D; + } else + { + if(minecartType == 2) + { + double d26 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ); + if(d26 > 0.01D) + { + flag = true; + pushX /= d26; + pushZ /= d26; + double d28 = 0.040000000000000001D; + motionX *= 0.80000001192092896D; + motionY *= 0.0D; + motionZ *= 0.80000001192092896D; + motionX += pushX * d28; + motionZ += pushZ * d28; + } else + { + motionX *= 0.89999997615814209D; + motionY *= 0.0D; + motionZ *= 0.89999997615814209D; + } + } + motionX *= 0.95999997854232788D; + motionY *= 0.0D; + motionZ *= 0.95999997854232788D; + } + Vec3D vec3d1 = func_514_g(posX, posY, posZ); + if(vec3d1 != null && vec3d != null) + { + double d27 = (vec3d.yCoord - vec3d1.yCoord) * 0.050000000000000003D; + double d14 = Math.sqrt(motionX * motionX + motionZ * motionZ); + if(d14 > 0.0D) + { + motionX = (motionX / d14) * (d14 + d27); + motionZ = (motionZ / d14) * (d14 + d27); + } + setPosition(posX, vec3d1.yCoord, posZ); + } + int j1 = MathHelper.floor_double(posX); + int k1 = MathHelper.floor_double(posZ); + if(j1 != i || k1 != k) + { + double d15 = Math.sqrt(motionX * motionX + motionZ * motionZ); + motionX = d15 * (double)(j1 - i); + motionZ = d15 * (double)(k1 - k); + } + if(minecartType == 2) + { + double d29 = MathHelper.sqrt_double(pushX * pushX + pushZ * pushZ); + if(d29 > 0.01D && motionX * motionX + motionZ * motionZ > 0.001D) + { + pushX /= d29; + pushZ /= d29; + if(pushX * motionX + pushZ * motionZ < 0.0D) + { + pushX = 0.0D; + pushZ = 0.0D; + } else + { + pushX = motionX; + pushZ = motionZ; + } + } + } + } else + { + if(motionX < -d2) + { + motionX = -d2; + } + if(motionX > d2) + { + motionX = d2; + } + if(motionZ < -d2) + { + motionZ = -d2; + } + if(motionZ > d2) + { + motionZ = d2; + } + if(onGround) + { + motionX *= 0.5D; + motionY *= 0.5D; + motionZ *= 0.5D; + } + moveEntity(motionX, motionY, motionZ); + if(!onGround) + { + motionX *= 0.94999998807907104D; + motionY *= 0.94999998807907104D; + motionZ *= 0.94999998807907104D; + } + } + rotationPitch = 0.0F; + double d6 = prevPosX - posX; + double d7 = prevPosZ - posZ; + if(d6 * d6 + d7 * d7 > 0.001D) + { + rotationYaw = (float)((Math.atan2(d7, d6) * 180D) / 3.1415926535897931D); + if(field_856_i) + { + rotationYaw += 180F; + } + } + double d9; + for(d9 = rotationYaw - prevRotationYaw; d9 >= 180D; d9 -= 360D) { } + for(; d9 < -180D; d9 += 360D) { } + if(d9 < -170D || d9 >= 170D) + { + rotationYaw += 180F; + field_856_i = !field_856_i; + } + setRotation(rotationYaw, rotationPitch); + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + if(list != null && list.size() > 0) + { + for(int i1 = 0; i1 < list.size(); i1++) + { + Entity entity = (Entity)list.get(i1); + if(entity != riddenByEntity && entity.canBePushed() && (entity instanceof EntityMinecart)) + { + entity.applyEntityCollision(this); + } + } + + } + if(riddenByEntity != null && riddenByEntity.isDead) + { + riddenByEntity = null; + } + if(flag && rand.nextInt(4) == 0) + { + fuel--; + if(fuel < 0) + { + pushX = pushZ = 0.0D; + } + worldObj.spawnParticle("largesmoke", posX, posY + 0.80000000000000004D, posZ, 0.0D, 0.0D, 0.0D); + } + } + + public Vec3D func_515_a(double d, double d1, double d2, double d3) + { + int i = MathHelper.floor_double(d); + int j = MathHelper.floor_double(d1); + int k = MathHelper.floor_double(d2); + if(worldObj.getBlockId(i, j - 1, k) == Block.minecartTrack.blockID) + { + j--; + } + if(worldObj.getBlockId(i, j, k) == Block.minecartTrack.blockID) + { + int l = worldObj.getBlockMetadata(i, j, k); + d1 = j; + if(l >= 2 && l <= 5) + { + d1 = j + 1; + } + int ai[][] = field_855_j[l]; + double d4 = ai[1][0] - ai[0][0]; + double d5 = ai[1][2] - ai[0][2]; + double d6 = Math.sqrt(d4 * d4 + d5 * d5); + d4 /= d6; + d5 /= d6; + d += d4 * d3; + d2 += d5 * d3; + if(ai[0][1] != 0 && MathHelper.floor_double(d) - i == ai[0][0] && MathHelper.floor_double(d2) - k == ai[0][2]) + { + d1 += ai[0][1]; + } else + if(ai[1][1] != 0 && MathHelper.floor_double(d) - i == ai[1][0] && MathHelper.floor_double(d2) - k == ai[1][2]) + { + d1 += ai[1][1]; + } + return func_514_g(d, d1, d2); + } else + { + return null; + } + } + + public Vec3D func_514_g(double d, double d1, double d2) + { + int i = MathHelper.floor_double(d); + int j = MathHelper.floor_double(d1); + int k = MathHelper.floor_double(d2); + if(worldObj.getBlockId(i, j - 1, k) == Block.minecartTrack.blockID) + { + j--; + } + if(worldObj.getBlockId(i, j, k) == Block.minecartTrack.blockID) + { + int l = worldObj.getBlockMetadata(i, j, k); + d1 = j; + if(l >= 2 && l <= 5) + { + d1 = j + 1; + } + int ai[][] = field_855_j[l]; + double d3 = 0.0D; + double d4 = (double)i + 0.5D + (double)ai[0][0] * 0.5D; + double d5 = (double)j + 0.5D + (double)ai[0][1] * 0.5D; + double d6 = (double)k + 0.5D + (double)ai[0][2] * 0.5D; + double d7 = (double)i + 0.5D + (double)ai[1][0] * 0.5D; + double d8 = (double)j + 0.5D + (double)ai[1][1] * 0.5D; + double d9 = (double)k + 0.5D + (double)ai[1][2] * 0.5D; + double d10 = d7 - d4; + double d11 = (d8 - d5) * 2D; + double d12 = d9 - d6; + if(d10 == 0.0D) + { + d = (double)i + 0.5D; + d3 = d2 - (double)k; + } else + if(d12 == 0.0D) + { + d2 = (double)k + 0.5D; + d3 = d - (double)i; + } else + { + double d13 = d - d4; + double d14 = d2 - d6; + double d15 = (d13 * d10 + d14 * d12) * 2D; + d3 = d15; + } + d = d4 + d10 * d3; + d1 = d5 + d11 * d3; + d2 = d6 + d12 * d3; + if(d11 < 0.0D) + { + d1++; + } + if(d11 > 0.0D) + { + d1 += 0.5D; + } + return Vec3D.createVector(d, d1, d2); + } else + { + return null; + } + } + + protected void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setInteger("Type", minecartType); + if(minecartType == 2) + { + nbttagcompound.setDouble("PushX", pushX); + nbttagcompound.setDouble("PushZ", pushZ); + nbttagcompound.setShort("Fuel", (short)fuel); + } else + if(minecartType == 1) + { + NBTTagList nbttaglist = new NBTTagList(); + for(int i = 0; i < cargoItems.length; i++) + { + if(cargoItems[i] != null) + { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte)i); + cargoItems[i].writeToNBT(nbttagcompound1); + nbttaglist.setTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + } + + protected void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + minecartType = nbttagcompound.getInteger("Type"); + if(minecartType == 2) + { + pushX = nbttagcompound.getDouble("PushX"); + pushZ = nbttagcompound.getDouble("PushZ"); + fuel = nbttagcompound.getShort("Fuel"); + } else + if(minecartType == 1) + { + NBTTagList nbttaglist = nbttagcompound.getTagList("Items"); + cargoItems = new ItemStack[getSizeInventory()]; + for(int i = 0; i < nbttaglist.tagCount(); i++) + { + NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); + int j = nbttagcompound1.getByte("Slot") & 0xff; + if(j >= 0 && j < cargoItems.length) + { + cargoItems[j] = new ItemStack(nbttagcompound1); + } + } + + } + } + + public float getShadowSize() + { + return 0.0F; + } + + public void applyEntityCollision(Entity entity) + { + if(worldObj.multiplayerWorld) + { + return; + } + if(entity == riddenByEntity) + { + return; + } + if((entity instanceof EntityLiving) && !(entity instanceof EntityPlayer) && minecartType == 0 && motionX * motionX + motionZ * motionZ > 0.01D && riddenByEntity == null && entity.ridingEntity == null) + { + entity.mountEntity(this); + } + double d = entity.posX - posX; + double d1 = entity.posZ - posZ; + double d2 = d * d + d1 * d1; + if(d2 >= 9.9999997473787516E-005D) + { + d2 = MathHelper.sqrt_double(d2); + d /= d2; + d1 /= d2; + double d3 = 1.0D / d2; + if(d3 > 1.0D) + { + d3 = 1.0D; + } + d *= d3; + d1 *= d3; + d *= 0.10000000149011612D; + d1 *= 0.10000000149011612D; + d *= 1.0F - entityCollisionReduction; + d1 *= 1.0F - entityCollisionReduction; + d *= 0.5D; + d1 *= 0.5D; + if(entity instanceof EntityMinecart) + { + double d4 = entity.motionX + motionX; + double d5 = entity.motionZ + motionZ; + if(((EntityMinecart)entity).minecartType == 2 && minecartType != 2) + { + motionX *= 0.20000000298023224D; + motionZ *= 0.20000000298023224D; + addVelocity(entity.motionX - d, 0.0D, entity.motionZ - d1); + entity.motionX *= 0.69999998807907104D; + entity.motionZ *= 0.69999998807907104D; + } else + if(((EntityMinecart)entity).minecartType != 2 && minecartType == 2) + { + entity.motionX *= 0.20000000298023224D; + entity.motionZ *= 0.20000000298023224D; + entity.addVelocity(motionX + d, 0.0D, motionZ + d1); + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } else + { + d4 /= 2D; + d5 /= 2D; + motionX *= 0.20000000298023224D; + motionZ *= 0.20000000298023224D; + addVelocity(d4 - d, 0.0D, d5 - d1); + entity.motionX *= 0.20000000298023224D; + entity.motionZ *= 0.20000000298023224D; + entity.addVelocity(d4 + d, 0.0D, d5 + d1); + } + } else + { + addVelocity(-d, 0.0D, -d1); + entity.addVelocity(d / 4D, 0.0D, d1 / 4D); + } + } + } + + public int getSizeInventory() + { + return 27; + } + + public ItemStack getStackInSlot(int i) + { + return cargoItems[i]; + } + + public ItemStack decrStackSize(int i, int j) + { + if(cargoItems[i] != null) + { + if(cargoItems[i].stackSize <= j) + { + ItemStack itemstack = cargoItems[i]; + cargoItems[i] = null; + return itemstack; + } + ItemStack itemstack1 = cargoItems[i].splitStack(j); + if(cargoItems[i].stackSize == 0) + { + cargoItems[i] = null; + } + return itemstack1; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + cargoItems[i] = itemstack; + if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + { + itemstack.stackSize = getInventoryStackLimit(); + } + } + + public String getInvName() + { + return "Minecart"; + } + + public int getInventoryStackLimit() + { + return 64; + } + + public void onInventoryChanged() + { + } + + public boolean interact(EntityPlayer entityplayer) + { + if(minecartType == 0) + { + if(riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer) + { + return true; + } + if(!worldObj.multiplayerWorld) + { + entityplayer.mountEntity(this); + } + } else + if(minecartType == 1) + { + if(!worldObj.multiplayerWorld) + { + entityplayer.displayGUIChest(this); + } + } else + if(minecartType == 2) + { + ItemStack itemstack = entityplayer.inventory.getCurrentItem(); + if(itemstack != null && itemstack.itemID == Item.coal.shiftedIndex) + { + if(--itemstack.stackSize == 0) + { + entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); + } + fuel += 1200; + } + pushX = posX - entityplayer.posX; + pushZ = posZ - entityplayer.posZ; + } + return true; + } + + public void setPositionAndRotation2(double d, double d1, double d2, float f, + float f1, int i) + { + field_9414_l = d; + field_9413_m = d1; + field_9412_n = d2; + field_9411_o = f; + field_9410_p = f1; + field_9415_k = i + 2; + motionX = field_9409_q; + motionY = field_9408_r; + motionZ = field_9407_s; + } + + public void setVelocity(double d, double d1, double d2) + { + field_9409_q = motionX = d; + field_9408_r = motionY = d1; + field_9407_s = motionZ = d2; + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + if(isDead) + { + return false; + } + return entityplayer.getDistanceSqToEntity(this) <= 64D; + } + + private ItemStack cargoItems[]; + public int field_20910_a; + public int field_20911_b; + public int field_20912_c; + private boolean field_856_i; + public int minecartType; + public int fuel; + public double pushX; + public double pushZ; + private static final int field_855_j[][][] = { + { + { + 0, 0, -1 + }, { + 0, 0, 1 + } + }, { + { + -1, 0, 0 + }, { + 1, 0, 0 + } + }, { + { + -1, -1, 0 + }, { + 1, 0, 0 + } + }, { + { + -1, 0, 0 + }, { + 1, -1, 0 + } + }, { + { + 0, 0, -1 + }, { + 0, -1, 1 + } + }, { + { + 0, -1, -1 + }, { + 0, 0, 1 + } + }, { + { + 0, 0, 1 + }, { + 1, 0, 0 + } + }, { + { + 0, 0, 1 + }, { + -1, 0, 0 + } + }, { + { + 0, 0, -1 + }, { + -1, 0, 0 + } + }, { + { + 0, 0, -1 + }, { + 1, 0, 0 + } + } + }; + private int field_9415_k; + private double field_9414_l; + private double field_9413_m; + private double field_9412_n; + private double field_9411_o; + private double field_9410_p; + private double field_9409_q; + private double field_9408_r; + private double field_9407_s; + +} diff --git a/src/main/java/net/minecraft/src/EntityMobs.java b/src/main/java/net/minecraft/src/EntityMobs.java new file mode 100644 index 0000000..e23c21c --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityMobs.java @@ -0,0 +1,109 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityMobs extends EntityCreature + implements IMobs +{ + + public EntityMobs(World world) + { + super(world); + attackStrength = 2; + health = 20; + } + + public void onLivingUpdate() + { + float f = getEntityBrightness(1.0F); + if(f > 0.5F) + { + field_9344_ag += 2; + } + super.onLivingUpdate(); + } + + public void onUpdate() + { + super.onUpdate(); + if(worldObj.difficultySetting == 0) + { + setEntityDead(); + } + } + + protected Entity findPlayerToAttack() + { + EntityPlayer entityplayer = worldObj.getClosestPlayerToEntity(this, 16D); + if(entityplayer != null && canEntityBeSeen(entityplayer)) + { + return entityplayer; + } else + { + return null; + } + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(super.attackEntityFrom(entity, i)) + { + if(riddenByEntity == entity || ridingEntity == entity) + { + return true; + } + if(entity != this) + { + playerToAttack = entity; + } + return true; + } else + { + return false; + } + } + + protected void attackEntity(Entity entity, float f) + { + if((double)f < 1.5D && entity.boundingBox.maxY > boundingBox.minY && entity.boundingBox.minY < boundingBox.maxY) + { + attackTime = 20; + entity.attackEntityFrom(this, attackStrength); + } + } + + protected float getBlockPathWeight(int i, int j, int k) + { + return 0.5F - worldObj.getLightBrightness(i, j, k); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + public boolean getCanSpawnHere() + { + int i = MathHelper.floor_double(posX); + int j = MathHelper.floor_double(boundingBox.minY); + int k = MathHelper.floor_double(posZ); + if(worldObj.getSavedLightValue(EnumSkyBlock.Sky, i, j, k) > rand.nextInt(32)) + { + return false; + } else + { + int l = worldObj.getBlockLightValue(i, j, k); + return l <= rand.nextInt(8) && super.getCanSpawnHere(); + } + } + + protected int attackStrength; +} diff --git a/src/main/java/net/minecraft/src/EntityNoteFX.java b/src/main/java/net/minecraft/src/EntityNoteFX.java new file mode 100644 index 0000000..6243bcf --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityNoteFX.java @@ -0,0 +1,76 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityNoteFX extends EntityFX +{ + + public EntityNoteFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + this(world, d, d1, d2, d3, d4, d5, 2.0F); + } + + public EntityNoteFX(World world, double d, double d1, double d2, + double d3, double d4, double d5, float f) + { + super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); + motionX *= 0.0099999997764825821D; + motionY *= 0.0099999997764825821D; + motionZ *= 0.0099999997764825821D; + motionY += 0.20000000000000001D; + particleRed = MathHelper.sin(((float)d3 + 0.0F) * 3.141593F * 2.0F) * 0.65F + 0.35F; + particleGreen = MathHelper.sin(((float)d3 + 0.3333333F) * 3.141593F * 2.0F) * 0.65F + 0.35F; + particleBlue = MathHelper.sin(((float)d3 + 0.6666667F) * 3.141593F * 2.0F) * 0.65F + 0.35F; + particleScale *= 0.75F; + particleScale *= f; + field_21065_a = particleScale; + particleMaxAge = 6; + noClip = false; + particleTextureIndex = 64; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = (((float)particleAge + f) / (float)particleMaxAge) * 32F; + if(f6 < 0.0F) + { + f6 = 0.0F; + } + if(f6 > 1.0F) + { + f6 = 1.0F; + } + particleScale = field_21065_a * f6; + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + moveEntity(motionX, motionY, motionZ); + if(posY == prevPosY) + { + motionX *= 1.1000000000000001D; + motionZ *= 1.1000000000000001D; + } + motionX *= 0.6600000262260437D; + motionY *= 0.6600000262260437D; + motionZ *= 0.6600000262260437D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } + + float field_21065_a; +} diff --git a/src/main/java/net/minecraft/src/EntityOtherPlayerMP.java b/src/main/java/net/minecraft/src/EntityOtherPlayerMP.java new file mode 100644 index 0000000..c53147e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityOtherPlayerMP.java @@ -0,0 +1,131 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityOtherPlayerMP extends EntityPlayer +{ + + public EntityOtherPlayerMP(World world, String s) + { + super(world); + field_20924_a = 0.0F; + username = s; + yOffset = 0.0F; + stepHeight = 0.0F; + if(s != null && s.length() > 0) + { + skinUrl = (new StringBuilder()).append("http://s3.amazonaws.com/MinecraftSkins/").append(s).append(".png").toString(); + } + noClip = true; + field_22062_y = 0.25F; + renderDistanceWeight = 10D; + } + + protected void func_22058_C() + { + yOffset = 0.0F; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + return true; + } + + public void setPositionAndRotation2(double d, double d1, double d2, float f, + float f1, int i) + { + field_784_bh = d; + field_783_bi = d1; + field_782_bj = d2; + field_780_bk = f; + field_786_bl = f1; + field_785_bg = i; + } + + public void onUpdate() + { + super.onUpdate(); + field_705_Q = field_704_R; + double d = posX - prevPosX; + double d1 = posZ - prevPosZ; + float f = MathHelper.sqrt_double(d * d + d1 * d1) * 4F; + if(f > 1.0F) + { + f = 1.0F; + } + field_704_R += (f - field_704_R) * 0.4F; + field_703_S += field_704_R; + } + + public float getShadowSize() + { + return 0.0F; + } + + public void onLivingUpdate() + { + super.updatePlayerActionState(); + if(field_785_bg > 0) + { + double d = posX + (field_784_bh - posX) / (double)field_785_bg; + double d1 = posY + (field_783_bi - posY) / (double)field_785_bg; + double d2 = posZ + (field_782_bj - posZ) / (double)field_785_bg; + double d3; + for(d3 = field_780_bk - (double)rotationYaw; d3 < -180D; d3 += 360D) { } + for(; d3 >= 180D; d3 -= 360D) { } + rotationYaw += d3 / (double)field_785_bg; + rotationPitch += (field_786_bl - (double)rotationPitch) / (double)field_785_bg; + field_785_bg--; + setPosition(d, d1, d2); + setRotation(rotationYaw, rotationPitch); + } + field_775_e = field_774_f; + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + float f1 = (float)Math.atan(-motionY * 0.20000000298023224D) * 15F; + if(f > 0.1F) + { + f = 0.1F; + } + if(!onGround || health <= 0) + { + f = 0.0F; + } + if(onGround || health <= 0) + { + f1 = 0.0F; + } + field_774_f += (f - field_774_f) * 0.4F; + field_9328_R += (f1 - field_9328_R) * 0.8F; + } + + public void outfitWithItem(int i, int j, int k) + { + ItemStack itemstack = null; + if(j >= 0) + { + itemstack = new ItemStack(j, 1, k); + } + if(i == 0) + { + inventory.mainInventory[inventory.currentItem] = itemstack; + } else + { + inventory.armorInventory[i - 1] = itemstack; + } + } + + public void func_6420_o() + { + } + + private int field_785_bg; + private double field_784_bh; + private double field_783_bi; + private double field_782_bj; + private double field_780_bk; + private double field_786_bl; + float field_20924_a; + public byte[] skinPacket = null; +} diff --git a/src/main/java/net/minecraft/src/EntityPainting.java b/src/main/java/net/minecraft/src/EntityPainting.java new file mode 100644 index 0000000..1d0a8d3 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPainting.java @@ -0,0 +1,274 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class EntityPainting extends Entity +{ + + public EntityPainting(World world) + { + super(world); + field_695_c = 0; + direction = 0; + yOffset = 0.0F; + setSize(0.5F, 0.5F); + } + + public EntityPainting(World world, int i, int j, int k, int l) + { + this(world); + xPosition = i; + yPosition = j; + zPosition = k; + ArrayList arraylist = new ArrayList(); + EnumArt aenumart[] = EnumArt.values(); + int i1 = aenumart.length; + for(int j1 = 0; j1 < i1; j1++) + { + EnumArt enumart = aenumart[j1]; + art = enumart; + func_412_b(l); + if(func_410_i()) + { + arraylist.add(enumart); + } + } + + if(arraylist.size() > 0) + { + art = (EnumArt)arraylist.get(rand.nextInt(arraylist.size())); + } + func_412_b(l); + } + + public EntityPainting(World world, int i, int j, int k, int l, String s) + { + this(world); + xPosition = i; + yPosition = j; + zPosition = k; + EnumArt aenumart[] = EnumArt.values(); + int i1 = aenumart.length; + int j1 = 0; + do + { + if(j1 >= i1) + { + break; + } + EnumArt enumart = aenumart[j1]; + if(enumart.title.equals(s)) + { + art = enumart; + break; + } + j1++; + } while(true); + func_412_b(l); + } + + protected void entityInit() + { + } + + public void func_412_b(int i) + { + direction = i; + prevRotationYaw = rotationYaw = i * 90; + float f = art.sizeX; + float f1 = art.sizeY; + float f2 = art.sizeX; + if(i == 0 || i == 2) + { + f2 = 0.5F; + } else + { + f = 0.5F; + } + f /= 32F; + f1 /= 32F; + f2 /= 32F; + float f3 = (float)xPosition + 0.5F; + float f4 = (float)yPosition + 0.5F; + float f5 = (float)zPosition + 0.5F; + float f6 = 0.5625F; + if(i == 0) + { + f5 -= f6; + } + if(i == 1) + { + f3 -= f6; + } + if(i == 2) + { + f5 += f6; + } + if(i == 3) + { + f3 += f6; + } + if(i == 0) + { + f3 -= func_411_c(art.sizeX); + } + if(i == 1) + { + f5 += func_411_c(art.sizeX); + } + if(i == 2) + { + f3 += func_411_c(art.sizeX); + } + if(i == 3) + { + f5 -= func_411_c(art.sizeX); + } + f4 += func_411_c(art.sizeY); + setPosition(f3, f4, f5); + float f7 = -0.00625F; + boundingBox.setBounds(f3 - f - f7, f4 - f1 - f7, f5 - f2 - f7, f3 + f + f7, f4 + f1 + f7, f5 + f2 + f7); + } + + private float func_411_c(int i) + { + if(i == 32) + { + return 0.5F; + } + return i != 64 ? 0.0F : 0.5F; + } + + public void onUpdate() + { + if(field_695_c++ == 100 && !worldObj.multiplayerWorld) + { + field_695_c = 0; + if(!func_410_i()) + { + setEntityDead(); + worldObj.entityJoinedWorld(new EntityItem(worldObj, posX, posY, posZ, new ItemStack(Item.painting))); + } + } + } + + public boolean func_410_i() + { + if(worldObj.getCollidingBoundingBoxes(this, boundingBox).size() > 0) + { + return false; + } + int i = art.sizeX / 16; + int j = art.sizeY / 16; + int k = xPosition; + int l = yPosition; + int i1 = zPosition; + if(direction == 0) + { + k = MathHelper.floor_double(posX - (double)((float)art.sizeX / 32F)); + } + if(direction == 1) + { + i1 = MathHelper.floor_double(posZ - (double)((float)art.sizeX / 32F)); + } + if(direction == 2) + { + k = MathHelper.floor_double(posX - (double)((float)art.sizeX / 32F)); + } + if(direction == 3) + { + i1 = MathHelper.floor_double(posZ - (double)((float)art.sizeX / 32F)); + } + l = MathHelper.floor_double(posY - (double)((float)art.sizeY / 32F)); + for(int j1 = 0; j1 < i; j1++) + { + for(int k1 = 0; k1 < j; k1++) + { + Material material; + if(direction == 0 || direction == 2) + { + material = worldObj.getBlockMaterial(k + j1, l + k1, zPosition); + } else + { + material = worldObj.getBlockMaterial(xPosition, l + k1, i1 + j1); + } + if(!material.isSolid()) + { + return false; + } + } + + } + + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox); + for(int l1 = 0; l1 < list.size(); l1++) + { + if(list.get(l1) instanceof EntityPainting) + { + return false; + } + } + + return true; + } + + public boolean canBeCollidedWith() + { + return true; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(!isDead && !worldObj.multiplayerWorld) + { + setEntityDead(); + setBeenAttacked(); + worldObj.entityJoinedWorld(new EntityItem(worldObj, posX, posY, posZ, new ItemStack(Item.painting))); + } + return true; + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setByte("Dir", (byte)direction); + nbttagcompound.setString("Motive", art.title); + nbttagcompound.setInteger("TileX", xPosition); + nbttagcompound.setInteger("TileY", yPosition); + nbttagcompound.setInteger("TileZ", zPosition); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + direction = nbttagcompound.getByte("Dir"); + xPosition = nbttagcompound.getInteger("TileX"); + yPosition = nbttagcompound.getInteger("TileY"); + zPosition = nbttagcompound.getInteger("TileZ"); + String s = nbttagcompound.getString("Motive"); + EnumArt aenumart[] = EnumArt.values(); + int i = aenumart.length; + for(int j = 0; j < i; j++) + { + EnumArt enumart = aenumart[j]; + if(enumart.title.equals(s)) + { + art = enumart; + } + } + + if(art == null) + { + art = EnumArt.Kebab; + } + func_412_b(direction); + } + + private int field_695_c; + public int direction; + public int xPosition; + public int yPosition; + public int zPosition; + public EnumArt art; +} diff --git a/src/main/java/net/minecraft/src/EntityPickupFX.java b/src/main/java/net/minecraft/src/EntityPickupFX.java new file mode 100644 index 0000000..6c7882e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPickupFX.java @@ -0,0 +1,65 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class EntityPickupFX extends EntityFX +{ + + public EntityPickupFX(World world, Entity entity, Entity entity1, float f) + { + super(world, entity.posX, entity.posY, entity.posZ, entity.motionX, entity.motionY, entity.motionZ); + field_678_p = 0; + field_677_q = 0; + field_675_a = entity; + field_679_o = entity1; + field_677_q = 3; + field_676_r = f; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = ((float)field_678_p + f) / (float)field_677_q; + f6 *= f6; + double d = field_675_a.posX; + double d1 = field_675_a.posY; + double d2 = field_675_a.posZ; + double d3 = field_679_o.lastTickPosX + (field_679_o.posX - field_679_o.lastTickPosX) * (double)f; + double d4 = field_679_o.lastTickPosY + (field_679_o.posY - field_679_o.lastTickPosY) * (double)f + (double)field_676_r; + double d5 = field_679_o.lastTickPosZ + (field_679_o.posZ - field_679_o.lastTickPosZ) * (double)f; + double d6 = d + (d3 - d) * (double)f6; + double d7 = d1 + (d4 - d1) * (double)f6; + double d8 = d2 + (d5 - d2) * (double)f6; + int i = MathHelper.floor_double(d6); + int j = MathHelper.floor_double(d7 + (double)(yOffset / 2.0F)); + int k = MathHelper.floor_double(d8); + float f7 = worldObj.getLightBrightness(i, j, k); + d6 -= interpPosX; + d7 -= interpPosY; + d8 -= interpPosZ; + GL11.glColor4f(f7, f7, f7, 1.0F); + RenderManager.instance.renderEntityWithPosYaw(field_675_a, (float)d6, (float)d7, (float)d8, field_675_a.rotationYaw, f); + } + + public void onUpdate() + { + field_678_p++; + if(field_678_p == field_677_q) + { + setEntityDead(); + } + } + + public int getFXLayer() + { + return 3; + } + + private Entity field_675_a; + private Entity field_679_o; + private int field_678_p; + private int field_677_q; + private float field_676_r; +} diff --git a/src/main/java/net/minecraft/src/EntityPig.java b/src/main/java/net/minecraft/src/EntityPig.java new file mode 100644 index 0000000..78e244b --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPig.java @@ -0,0 +1,81 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityPig extends EntityAnimals +{ + + public EntityPig(World world) + { + super(world); + texture = "/mob/pig.png"; + setSize(0.9F, 0.9F); + } + + protected void entityInit() + { + dataWatcher.addObject(16, Byte.valueOf((byte)0)); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setBoolean("Saddle", func_21068_q()); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + func_21069_a(nbttagcompound.getBoolean("Saddle")); + } + + protected String getLivingSound() + { + return "mob.pig"; + } + + protected String getHurtSound() + { + return "mob.pig"; + } + + protected String getDeathSound() + { + return "mob.pigdeath"; + } + + public boolean interact(EntityPlayer entityplayer) + { + if(func_21068_q() && !worldObj.multiplayerWorld && (riddenByEntity == null || riddenByEntity == entityplayer)) + { + entityplayer.mountEntity(this); + return true; + } else + { + return false; + } + } + + protected int getDropItemId() + { + return Item.porkRaw.shiftedIndex; + } + + public boolean func_21068_q() + { + return (dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_21069_a(boolean flag) + { + if(flag) + { + dataWatcher.updateObject(16, Byte.valueOf((byte)1)); + } else + { + dataWatcher.updateObject(16, Byte.valueOf((byte)0)); + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityPigZombie.java b/src/main/java/net/minecraft/src/EntityPigZombie.java new file mode 100644 index 0000000..2af9544 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPigZombie.java @@ -0,0 +1,126 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntityPigZombie extends EntityZombie +{ + + public EntityPigZombie(World world) + { + super(world); + angerLevel = 0; + randomSoundDelay = 0; + texture = "/mob/pigzombie.png"; + moveSpeed = 0.5F; + attackStrength = 5; + isImmuneToFire = true; + } + + public void onUpdate() + { + moveSpeed = playerToAttack == null ? 0.5F : 0.95F; + if(randomSoundDelay > 0 && --randomSoundDelay == 0) + { + worldObj.playSoundAtEntity(this, "mob.zombiepig.zpigangry", getSoundVolume() * 2.0F, ((rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F) * 1.8F); + } + super.onUpdate(); + } + + public boolean getCanSpawnHere() + { + return worldObj.difficultySetting > 0 && worldObj.checkIfAABBIsClear(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0 && !worldObj.getIsAnyLiquid(boundingBox); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setShort("Anger", (short)angerLevel); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + angerLevel = nbttagcompound.getShort("Anger"); + } + + protected Entity findPlayerToAttack() + { + if(angerLevel == 0) + { + return null; + } else + { + return super.findPlayerToAttack(); + } + } + + public void onLivingUpdate() + { + super.onLivingUpdate(); + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(entity instanceof EntityPlayer) + { + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(32D, 32D, 32D)); + for(int j = 0; j < list.size(); j++) + { + Entity entity1 = (Entity)list.get(j); + if(entity1 instanceof EntityPigZombie) + { + EntityPigZombie entitypigzombie = (EntityPigZombie)entity1; + entitypigzombie.becomeAngryAt(entity); + } + } + + becomeAngryAt(entity); + } + return super.attackEntityFrom(entity, i); + } + + private void becomeAngryAt(Entity entity) + { + playerToAttack = entity; + angerLevel = 400 + rand.nextInt(400); + randomSoundDelay = rand.nextInt(40); + } + + protected String getLivingSound() + { + return "mob.zombiepig.zpig"; + } + + protected String getHurtSound() + { + return "mob.zombiepig.zpighurt"; + } + + protected String getDeathSound() + { + return "mob.zombiepig.zpigdeath"; + } + + protected int getDropItemId() + { + return Item.porkCooked.shiftedIndex; + } + + public ItemStack getHeldItem() + { + return defaultHeldItem; + } + + private int angerLevel; + private int randomSoundDelay; + private static final ItemStack defaultHeldItem; + + static + { + defaultHeldItem = new ItemStack(Item.swordGold, 1); + } +} diff --git a/src/main/java/net/minecraft/src/EntityPlayer.java b/src/main/java/net/minecraft/src/EntityPlayer.java new file mode 100644 index 0000000..b283368 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPlayer.java @@ -0,0 +1,673 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public abstract class EntityPlayer extends EntityLiving +{ + + public EntityPlayer(World world) + { + super(world); + inventory = new InventoryPlayer(this); + field_9371_f = 0; + score = 0; + isSwinging = false; + swingProgressInt = 0; + damageRemainder = 0; + fishEntity = null; + inventorySlots = new CraftingInventoryPlayerCB(inventory, !world.multiplayerWorld); + craftingInventory = inventorySlots; + yOffset = 1.62F; + ChunkCoordinates chunkcoordinates = world.func_22137_s(); + setLocationAndAngles((double)chunkcoordinates.field_22395_a + 0.5D, chunkcoordinates.field_22394_b + 1, (double)chunkcoordinates.field_22396_c + 0.5D, 0.0F, 0.0F); + health = 20; + field_9351_C = "humanoid"; + field_9353_B = 180F; + fireResistance = 20; + texture = "/mob/char.png"; + } + + protected void entityInit() + { + super.entityInit(); + dataWatcher.addObject(16, Byte.valueOf((byte)0)); + } + + public void onUpdate() + { + if(isPlayerSleeping()) + { + field_21907_c++; + if(field_21907_c > 100) + { + field_21907_c = 100; + } + if(!func_22057_q()) + { + func_22056_a(true, true); + } else + if(!worldObj.multiplayerWorld && worldObj.isDaytime()) + { + func_22056_a(false, true); + } + } else + if(field_21907_c > 0) + { + field_21907_c++; + if(field_21907_c >= 110) + { + field_21907_c = 0; + } + } + super.onUpdate(); + if(!worldObj.multiplayerWorld && craftingInventory != null && !craftingInventory.func_20120_b(this)) + { + func_20059_m(); + craftingInventory = inventorySlots; + } + field_20066_r = field_20063_u; + field_20065_s = field_20062_v; + field_20064_t = field_20061_w; + double d = posX - field_20063_u; + double d1 = posY - field_20062_v; + double d2 = posZ - field_20061_w; + double d3 = 10D; + if(d > d3) + { + field_20066_r = field_20063_u = posX; + } + if(d2 > d3) + { + field_20064_t = field_20061_w = posZ; + } + if(d1 > d3) + { + field_20065_s = field_20062_v = posY; + } + if(d < -d3) + { + field_20066_r = field_20063_u = posX; + } + if(d2 < -d3) + { + field_20064_t = field_20061_w = posZ; + } + if(d1 < -d3) + { + field_20065_s = field_20062_v = posY; + } + field_20063_u += d * 0.25D; + field_20061_w += d2 * 0.25D; + field_20062_v += d1 * 0.25D; + } + + protected boolean func_22049_v() + { + return health <= 0 || isPlayerSleeping(); + } + + protected void func_20059_m() + { + craftingInventory = inventorySlots; + } + + public void updateCloak() + { + field_20067_q = (new StringBuilder()).append("http://s3.amazonaws.com/MinecraftCloaks/").append(username).append(".png").toString(); + cloakUrl = field_20067_q; + } + + public void updateRidden() + { + super.updateRidden(); + field_775_e = field_774_f; + field_774_f = 0.0F; + } + + public void preparePlayerToSpawn() + { + yOffset = 1.62F; + setSize(0.6F, 1.8F); + super.preparePlayerToSpawn(); + health = 20; + deathTime = 0; + } + + protected void updatePlayerActionState() + { + if(isSwinging) + { + swingProgressInt++; + if(swingProgressInt == 8) + { + swingProgressInt = 0; + isSwinging = false; + } + } else + { + swingProgressInt = 0; + } + swingProgress = (float)swingProgressInt / 8F; + } + + public void onLivingUpdate() + { + if(worldObj.difficultySetting == 0 && health < 20 && (ticksExisted % 20) * 12 == 0) + { + heal(1); + } + inventory.decrementAnimations(); + field_775_e = field_774_f; + super.onLivingUpdate(); + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + float f1 = (float)Math.atan(-motionY * 0.20000000298023224D) * 15F; + if(f > 0.1F) + { + f = 0.1F; + } + if(!onGround || health <= 0) + { + f = 0.0F; + } + if(onGround || health <= 0) + { + f1 = 0.0F; + } + field_774_f += (f - field_774_f) * 0.4F; + field_9328_R += (f1 - field_9328_R) * 0.8F; + if(health > 0) + { + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(1.0D, 0.0D, 1.0D)); + if(list != null) + { + for(int i = 0; i < list.size(); i++) + { + Entity entity = (Entity)list.get(i); + if(!entity.isDead) + { + func_451_h(entity); + } + } + + } + } + } + + private void func_451_h(Entity entity) + { + entity.onCollideWithPlayer(this); + } + + public int getScore() + { + return score; + } + + public void onDeath(Entity entity) + { + super.onDeath(entity); + setSize(0.2F, 0.2F); + setPosition(posX, posY, posZ); + motionY = 0.10000000149011612D; + if(username.equals("Notch")) + { + dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true); + } + inventory.dropAllItems(); + if(entity != null) + { + motionX = -MathHelper.cos(((attackedAtYaw + rotationYaw) * 3.141593F) / 180F) * 0.1F; + motionZ = -MathHelper.sin(((attackedAtYaw + rotationYaw) * 3.141593F) / 180F) * 0.1F; + } else + { + motionX = motionZ = 0.0D; + } + yOffset = 0.1F; + } + + public void addToPlayerScore(Entity entity, int i) + { + score += i; + } + + public void dropCurrentItem() + { + dropPlayerItemWithRandomChoice(inventory.decrStackSize(inventory.currentItem, 1), false); + } + + public void dropPlayerItem(ItemStack itemstack) + { + dropPlayerItemWithRandomChoice(itemstack, false); + } + + public void dropPlayerItemWithRandomChoice(ItemStack itemstack, boolean flag) + { + if(itemstack == null) + { + return; + } + EntityItem entityitem = new EntityItem(worldObj, posX, (posY - 0.30000001192092896D) + (double)getEyeHeight(), posZ, itemstack); + entityitem.delayBeforeCanPickup = 40; + float f = 0.1F; + if(flag) + { + float f2 = rand.nextFloat() * 0.5F; + float f4 = rand.nextFloat() * 3.141593F * 2.0F; + entityitem.motionX = -MathHelper.sin(f4) * f2; + entityitem.motionZ = MathHelper.cos(f4) * f2; + entityitem.motionY = 0.20000000298023224D; + } else + { + float f1 = 0.3F; + entityitem.motionX = -MathHelper.sin((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f1; + entityitem.motionZ = MathHelper.cos((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f1; + entityitem.motionY = -MathHelper.sin((rotationPitch / 180F) * 3.141593F) * f1 + 0.1F; + f1 = 0.02F; + float f3 = rand.nextFloat() * 3.141593F * 2.0F; + f1 *= rand.nextFloat(); + entityitem.motionX += Math.cos(f3) * (double)f1; + entityitem.motionY += (rand.nextFloat() - rand.nextFloat()) * 0.1F; + entityitem.motionZ += Math.sin(f3) * (double)f1; + } + joinEntityItemWithWorld(entityitem); + } + + protected void joinEntityItemWithWorld(EntityItem entityitem) + { + worldObj.entityJoinedWorld(entityitem); + } + + public float getCurrentPlayerStrVsBlock(Block block) + { + float f = inventory.getStrVsBlock(block); + if(isInsideOfMaterial(Material.water)) + { + f /= 5F; + } + if(!onGround) + { + f /= 5F; + } + return f; + } + + public boolean canHarvestBlock(Block block) + { + return inventory.canHarvestBlock(block); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Inventory"); + inventory.readFromNBT(nbttaglist); + dimension = nbttagcompound.getInteger("Dimension"); + field_21901_a = nbttagcompound.getBoolean("Sleeping"); + field_21907_c = nbttagcompound.getShort("SleepTimer"); + if(field_21901_a) + { + field_21908_b = new ChunkCoordinates(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)); + func_22056_a(true, true); + } + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setTag("Inventory", inventory.writeToNBT(new NBTTagList())); + nbttagcompound.setInteger("Dimension", dimension); + nbttagcompound.setBoolean("Sleeping", field_21901_a); + nbttagcompound.setShort("SleepTimer", (short)field_21907_c); + } + + public void displayGUIChest(IInventory iinventory) + { + } + + public void displayWorkbenchGUI(int i, int j, int k) + { + } + + public void onItemPickup(Entity entity, int i) + { + } + + public float getEyeHeight() + { + return 0.12F; + } + + protected void func_22058_C() + { + yOffset = 1.62F; + } + + public boolean attackEntityFrom(Entity entity, int i) + { + field_9344_ag = 0; + if(health <= 0) + { + return false; + } + if(isPlayerSleeping()) + { + func_22056_a(true, true); + } + if((entity instanceof EntityMobs) || (entity instanceof EntityArrow)) + { + if(worldObj.difficultySetting == 0) + { + i = 0; + } + if(worldObj.difficultySetting == 1) + { + i = i / 3 + 1; + } + if(worldObj.difficultySetting == 3) + { + i = (i * 3) / 2; + } + } + if(i == 0) + { + return false; + } else + { + return super.attackEntityFrom(entity, i); + } + } + + protected void damageEntity(int i) + { + int j = 25 - inventory.getTotalArmorValue(); + int k = i * j + damageRemainder; + inventory.damageArmor(i); + i = k / 25; + damageRemainder = k % 25; + super.damageEntity(i); + } + + public void displayGUIFurnace(TileEntityFurnace tileentityfurnace) + { + } + + public void displayGUIDispenser(TileEntityDispenser tileentitydispenser) + { + } + + public void displayGUIEditSign(TileEntitySign tileentitysign) + { + } + + public void useCurrentItemOnEntity(Entity entity) + { + if(entity.interact(this)) + { + return; + } + ItemStack itemstack = getCurrentEquippedItem(); + if(itemstack != null && (entity instanceof EntityLiving)) + { + itemstack.useItemOnEntity((EntityLiving)entity); + if(itemstack.stackSize <= 0) + { + itemstack.func_1097_a(this); + destroyCurrentEquippedItem(); + } + } + } + + public ItemStack getCurrentEquippedItem() + { + return inventory.getCurrentItem(); + } + + public void destroyCurrentEquippedItem() + { + inventory.setInventorySlotContents(inventory.currentItem, null); + } + + public double getYOffset() + { + return (double)(yOffset - 0.5F); + } + + public void swingItem() + { + swingProgressInt = -1; + isSwinging = true; + } + + public void attackTargetEntityWithCurrentItem(Entity entity) + { + int i = inventory.getDamageVsEntity(entity); + if(i > 0) + { + entity.attackEntityFrom(this, i); + ItemStack itemstack = getCurrentEquippedItem(); + if(itemstack != null && (entity instanceof EntityLiving)) + { + itemstack.hitEntity((EntityLiving)entity); + if(itemstack.stackSize <= 0) + { + itemstack.func_1097_a(this); + destroyCurrentEquippedItem(); + } + } + } + } + + public void respawnPlayer() + { + } + + public abstract void func_6420_o(); + + public void onItemStackChanged(ItemStack itemstack) + { + } + + public void setEntityDead() + { + super.setEntityDead(); + inventorySlots.onCraftGuiClosed(this); + if(craftingInventory != null) + { + craftingInventory.onCraftGuiClosed(this); + } + } + + public boolean func_345_I() + { + return !field_21901_a && super.func_345_I(); + } + + public boolean func_22053_b(int i, int j, int k) + { + if(isPlayerSleeping() || !isEntityAlive()) + { + return false; + } + if(worldObj.worldProvider.field_4220_c) + { + return false; + } + if(worldObj.isDaytime()) + { + return false; + } + if(Math.abs(posX - (double)i) > 3D || Math.abs(posY - (double)j) > 2D || Math.abs(posZ - (double)k) > 3D) + { + return false; + } + setSize(0.2F, 0.2F); + yOffset = 0.2F; + if(worldObj.blockExists(i, j, k)) + { + int l = worldObj.getBlockMetadata(i, j, k); + int i1 = BlockBed.func_22030_c(l); + float f = 0.5F; + float f1 = 0.5F; + switch(i1) + { + case 0: // '\0' + f1 = 0.9F; + break; + + case 2: // '\002' + f1 = 0.1F; + break; + + case 1: // '\001' + f = 0.1F; + break; + + case 3: // '\003' + f = 0.9F; + break; + } + func_22052_e(i1); + setPosition((float)i + f, (float)j + 0.9375F, (float)k + f1); + } else + { + setPosition((float)i + 0.5F, (float)j + 0.9375F, (float)k + 0.5F); + } + field_21901_a = true; + field_21907_c = 0; + field_21908_b = new ChunkCoordinates(i, j, k); + motionX = motionZ = motionY = 0.0D; + if(!worldObj.multiplayerWorld) + { + worldObj.func_22140_w(); + } + return true; + } + + private void func_22052_e(int i) + { + field_22063_x = 0.0F; + field_22061_z = 0.0F; + switch(i) + { + case 0: // '\0' + field_22061_z = -1.8F; + break; + + case 2: // '\002' + field_22061_z = 1.8F; + break; + + case 1: // '\001' + field_22063_x = 1.8F; + break; + + case 3: // '\003' + field_22063_x = -1.8F; + break; + } + } + + public void func_22056_a(boolean flag, boolean flag1) + { + setSize(0.6F, 1.8F); + func_22058_C(); + ChunkCoordinates chunkcoordinates = field_21908_b; + if(chunkcoordinates != null && worldObj.getBlockId(chunkcoordinates.field_22395_a, chunkcoordinates.field_22394_b, chunkcoordinates.field_22396_c) == Block.field_9262_S.blockID) + { + BlockBed.func_22031_a(worldObj, chunkcoordinates.field_22395_a, chunkcoordinates.field_22394_b, chunkcoordinates.field_22396_c, false); + ChunkCoordinates chunkcoordinates1 = BlockBed.func_22028_g(worldObj, chunkcoordinates.field_22395_a, chunkcoordinates.field_22394_b, chunkcoordinates.field_22396_c, 0); + setPosition((float)chunkcoordinates1.field_22395_a + 0.5F, (float)chunkcoordinates1.field_22394_b + yOffset + 0.1F, (float)chunkcoordinates1.field_22396_c + 0.5F); + } + field_21901_a = false; + if(!worldObj.multiplayerWorld && flag1) + { + worldObj.func_22140_w(); + } + if(flag) + { + field_21907_c = 0; + } else + { + field_21907_c = 100; + } + } + + private boolean func_22057_q() + { + return worldObj.getBlockId(field_21908_b.field_22395_a, field_21908_b.field_22394_b, field_21908_b.field_22396_c) == Block.field_9262_S.blockID; + } + + public float func_22059_J() + { + if(field_21908_b != null) + { + int i = worldObj.getBlockMetadata(field_21908_b.field_22395_a, field_21908_b.field_22394_b, field_21908_b.field_22396_c); + int j = BlockBed.func_22030_c(i); + switch(j) + { + case 0: // '\0' + return 90F; + + case 1: // '\001' + return 0.0F; + + case 2: // '\002' + return 270F; + + case 3: // '\003' + return 180F; + } + } + return 0.0F; + } + + public boolean isPlayerSleeping() + { + return field_21901_a; + } + + public boolean func_22054_L() + { + return field_21901_a && field_21907_c >= 100; + } + + public int func_22060_M() + { + return field_21907_c; + } + + public void func_22055_b(String s) + { + } + + public InventoryPlayer inventory; + public CraftingInventoryCB inventorySlots; + public CraftingInventoryCB craftingInventory; + public byte field_9371_f; + public int score; + public float field_775_e; + public float field_774_f; + public boolean isSwinging; + public int swingProgressInt; + public String username; + public int dimension; + public String field_20067_q; + public double field_20066_r; + public double field_20065_s; + public double field_20064_t; + public double field_20063_u; + public double field_20062_v; + public double field_20061_w; + private boolean field_21901_a; + private ChunkCoordinates field_21908_b; + private int field_21907_c; + public float field_22063_x; + public float field_22062_y; + public float field_22061_z; + private int damageRemainder; + public EntityFish fishEntity; +} diff --git a/src/main/java/net/minecraft/src/EntityPlayerSP.java b/src/main/java/net/minecraft/src/EntityPlayerSP.java new file mode 100644 index 0000000..59d7b83 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPlayerSP.java @@ -0,0 +1,207 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; +import net.minecraft.client.Minecraft; + +public class EntityPlayerSP extends EntityPlayer +{ + + public EntityPlayerSP(Minecraft minecraft, World world, Session session, int i) + { + super(world); + field_9373_b = 20; + inPortal = false; + field_21903_bJ = new MouseFilter(); + field_21904_bK = new MouseFilter(); + field_21902_bL = new MouseFilter(); + mc = minecraft; + dimension = i; + if(session != null && session.username != null && session.username.length() > 0) + { + skinUrl = (new StringBuilder()).append("http://s3.amazonaws.com/MinecraftSkins/").append(session.username).append(".png").toString(); + } + username = session.username; + } + + public void moveEntity(double d, double d1, double d2) + { + super.moveEntity(d, d1, d2); + } + + public void updatePlayerActionState() + { + super.updatePlayerActionState(); + moveStrafing = movementInput.moveStrafe; + moveForward = movementInput.moveForward; + isJumping = movementInput.jump; + } + + public void onLivingUpdate() + { + prevTimeInPortal = timeInPortal; + if(inPortal) + { + if(timeInPortal == 0.0F) + { + mc.sndManager.func_337_a("portal.trigger", 1.0F, rand.nextFloat() * 0.4F + 0.8F); + } + timeInPortal += 0.0125F; + if(timeInPortal >= 1.0F) + { + timeInPortal = 1.0F; + field_9373_b = 10; + mc.sndManager.func_337_a("portal.travel", 1.0F, rand.nextFloat() * 0.4F + 0.8F); + mc.usePortal(); + } + inPortal = false; + } else + { + if(timeInPortal > 0.0F) + { + timeInPortal -= 0.05F; + } + if(timeInPortal < 0.0F) + { + timeInPortal = 0.0F; + } + } + if(field_9373_b > 0) + { + field_9373_b--; + } + movementInput.updatePlayerMoveState(this); + if(movementInput.sneak && ySize < 0.2F) + { + ySize = 0.2F; + } + super.onLivingUpdate(); + } + + public void resetPlayerKeyState() + { + movementInput.resetKeyState(); + } + + public void handleKeyPress(int i, boolean flag) + { + movementInput.checkKeyForMovementInput(i, flag); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setInteger("Score", score); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + score = nbttagcompound.getInteger("Score"); + } + + public void func_20059_m() + { + super.func_20059_m(); + mc.displayGuiScreen(null); + } + + public void displayGUIEditSign(TileEntitySign tileentitysign) + { + mc.displayGuiScreen(new GuiEditSign(tileentitysign)); + } + + public void displayGUIChest(IInventory iinventory) + { + mc.displayGuiScreen(new GuiChest(inventory, iinventory)); + } + + public void displayWorkbenchGUI(int i, int j, int k) + { + mc.displayGuiScreen(new GuiCrafting(inventory, worldObj, i, j, k)); + } + + public void displayGUIFurnace(TileEntityFurnace tileentityfurnace) + { + mc.displayGuiScreen(new GuiFurnace(inventory, tileentityfurnace)); + } + + public void displayGUIDispenser(TileEntityDispenser tileentitydispenser) + { + mc.displayGuiScreen(new GuiDispenser(inventory, tileentitydispenser)); + } + + public void onItemPickup(Entity entity, int i) + { + mc.effectRenderer.addEffect(new EntityPickupFX(mc.theWorld, entity, this, -0.5F)); + } + + public int getPlayerArmorValue() + { + return inventory.getTotalArmorValue(); + } + + public void sendChatMessage(String s) + { + } + + public boolean isSneaking() + { + return movementInput.sneak; + } + + public void setInPortal() + { + if(field_9373_b > 0) + { + field_9373_b = 10; + return; + } else + { + inPortal = true; + return; + } + } + + public void setHealth(int i) + { + int j = health - i; + if(j <= 0) + { + health = i; + } else + { + field_9346_af = j; + prevHealth = health; + field_9306_bj = field_9366_o; + damageEntity(j); + hurtTime = maxHurtTime = 10; + } + } + + public void respawnPlayer() + { + mc.respawn(); + } + + public void func_6420_o() + { + } + + public void func_22055_b(String s) + { + mc.ingameGUI.func_22064_c(s); + } + + public MovementInput movementInput; + protected Minecraft mc; + public int field_9373_b; + private boolean inPortal; + public float timeInPortal; + public float prevTimeInPortal; + private MouseFilter field_21903_bJ; + private MouseFilter field_21904_bK; + private MouseFilter field_21902_bL; +} diff --git a/src/main/java/net/minecraft/src/EntityPortalFX.java b/src/main/java/net/minecraft/src/EntityPortalFX.java new file mode 100644 index 0000000..498d5dc --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityPortalFX.java @@ -0,0 +1,72 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityPortalFX extends EntityFX +{ + + public EntityPortalFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + super(world, d, d1, d2, d3, d4, d5); + motionX = d3; + motionY = d4; + motionZ = d5; + field_4086_p = posX = d; + field_4085_q = posY = d1; + field_4084_r = posZ = d2; + float f = rand.nextFloat() * 0.6F + 0.4F; + field_4083_a = particleScale = rand.nextFloat() * 0.2F + 0.5F; + particleRed = particleGreen = particleBlue = 1.0F * f; + particleGreen *= 0.3F; + particleRed *= 0.9F; + particleMaxAge = (int)(Math.random() * 10D) + 40; + noClip = true; + particleTextureIndex = (int)(Math.random() * 8D); + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = ((float)particleAge + f) / (float)particleMaxAge; + f6 = 1.0F - f6; + f6 *= f6; + f6 = 1.0F - f6; + particleScale = field_4083_a * f6; + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public float getEntityBrightness(float f) + { + float f1 = super.getEntityBrightness(f); + float f2 = (float)particleAge / (float)particleMaxAge; + f2 *= f2; + f2 *= f2; + return f1 * (1.0F - f2) + f2; + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + float f = (float)particleAge / (float)particleMaxAge; + float f1 = f; + f = -f + f * f * 2.0F; + f = 1.0F - f; + posX = field_4086_p + motionX * (double)f; + posY = field_4085_q + motionY * (double)f + (double)(1.0F - f1); + posZ = field_4084_r + motionZ * (double)f; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + } + + private float field_4083_a; + private double field_4086_p; + private double field_4085_q; + private double field_4084_r; +} diff --git a/src/main/java/net/minecraft/src/EntityRainFX.java b/src/main/java/net/minecraft/src/EntityRainFX.java new file mode 100644 index 0000000..2c16ce7 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityRainFX.java @@ -0,0 +1,64 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityRainFX extends EntityFX +{ + + public EntityRainFX(World world, double d, double d1, double d2) + { + super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); + motionX *= 0.30000001192092896D; + motionY = (float)Math.random() * 0.2F + 0.1F; + motionZ *= 0.30000001192092896D; + particleRed = 1.0F; + particleGreen = 1.0F; + particleBlue = 1.0F; + particleTextureIndex = 19 + rand.nextInt(4); + setSize(0.01F, 0.01F); + particleGravity = 0.06F; + particleMaxAge = (int)(8D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)); + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + motionY -= particleGravity; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.98000001907348633D; + motionY *= 0.98000001907348633D; + motionZ *= 0.98000001907348633D; + if(particleMaxAge-- <= 0) + { + setEntityDead(); + } + if(onGround) + { + if(Math.random() < 0.5D) + { + setEntityDead(); + } + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + Material material = worldObj.getBlockMaterial(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)); + if(material.getIsLiquid() || material.isSolid()) + { + double d = (float)(MathHelper.floor_double(posY) + 1) - BlockFluids.setFluidHeight(worldObj.getBlockMetadata(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ))); + if(posY < d) + { + setEntityDead(); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/EntityReddustFX.java b/src/main/java/net/minecraft/src/EntityReddustFX.java new file mode 100644 index 0000000..97f3f59 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityReddustFX.java @@ -0,0 +1,81 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityReddustFX extends EntityFX +{ + + public EntityReddustFX(World world, double d, double d1, double d2, + float f, float f1, float f2) + { + this(world, d, d1, d2, 1.0F, f, f1, f2); + } + + public EntityReddustFX(World world, double d, double d1, double d2, + float f, float f1, float f2, float f3) + { + super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); + motionX *= 0.10000000149011612D; + motionY *= 0.10000000149011612D; + motionZ *= 0.10000000149011612D; + if(f1 == 0.0F) + { + f1 = 1.0F; + } + float f4 = (float)Math.random() * 0.4F + 0.6F; + particleRed = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) * f1 * f4; + particleGreen = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) * f2 * f4; + particleBlue = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) * f3 * f4; + particleScale *= 0.75F; + particleScale *= f; + field_673_a = particleScale; + particleMaxAge = (int)(8D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)); + particleMaxAge *= f; + noClip = false; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = (((float)particleAge + f) / (float)particleMaxAge) * 32F; + if(f6 < 0.0F) + { + f6 = 0.0F; + } + if(f6 > 1.0F) + { + f6 = 1.0F; + } + particleScale = field_673_a * f6; + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + particleTextureIndex = 7 - (particleAge * 8) / particleMaxAge; + moveEntity(motionX, motionY, motionZ); + if(posY == prevPosY) + { + motionX *= 1.1000000000000001D; + motionZ *= 1.1000000000000001D; + } + motionX *= 0.95999997854232788D; + motionY *= 0.95999997854232788D; + motionZ *= 0.95999997854232788D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } + + float field_673_a; +} diff --git a/src/main/java/net/minecraft/src/EntityRenderer.java b/src/main/java/net/minecraft/src/EntityRenderer.java new file mode 100644 index 0000000..13b9e79 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityRenderer.java @@ -0,0 +1,754 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.nio.FloatBuffer; +import java.util.List; +import java.util.Random; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.*; +import org.lwjgl.util.glu.GLU; + +public class EntityRenderer +{ + + public EntityRenderer(Minecraft minecraft) + { + farPlaneDistance = 0.0F; + field_1385_k = null; + field_22235_l = new MouseFilter(); + field_22234_m = new MouseFilter(); + field_22233_n = new MouseFilter(); + field_22232_o = new MouseFilter(); + field_22231_p = new MouseFilter(); + field_22229_q = new MouseFilter(); + field_22228_r = 4F; + field_22227_s = 4F; + field_22226_t = 0.0F; + field_22225_u = 0.0F; + field_22224_v = 0.0F; + field_22223_w = 0.0F; + field_22222_x = 0.0F; + field_22221_y = 0.0F; + field_22220_z = 0.0F; + field_22230_A = 0.0F; + field_21155_l = 1.0D; + field_21154_m = 0.0D; + field_21153_n = 0.0D; + field_1384_l = System.currentTimeMillis(); + random = new Random(); + field_1394_b = 0; + field_1393_c = 0; + field_1392_d = GLAllocation.createDirectFloatBuffer(16); + mc = minecraft; + itemRenderer = new ItemRenderer(minecraft); + } + + public void updateRenderer() + { + field_1382_n = field_1381_o; + field_22227_s = field_22228_r; + field_22225_u = field_22226_t; + field_22223_w = field_22224_v; + field_22221_y = field_22222_x; + field_22230_A = field_22220_z; + if(mc.field_22009_h == null) + { + mc.field_22009_h = mc.thePlayer; + } + float f = mc.theWorld.getLightBrightness(MathHelper.floor_double(mc.field_22009_h.posX), MathHelper.floor_double(mc.field_22009_h.posY), MathHelper.floor_double(mc.field_22009_h.posZ)); + float f1 = (float)(3 - mc.gameSettings.renderDistance) / 3F; + float f2 = f * (1.0F - f1) + f1; + field_1381_o += (f2 - field_1381_o) * 0.1F; + field_1386_j++; + itemRenderer.updateEquippedItem(); + if(mc.isRaining) + { + addRainParticles(); + } + } + + public void getMouseOver(float f) + { + if(mc.field_22009_h == null) + { + return; + } + if(mc.theWorld == null) + { + return; + } + double d = mc.playerController.getBlockReachDistance(); + mc.objectMouseOver = mc.field_22009_h.rayTrace(d, f); + double d1 = d; + Vec3D vec3d = mc.field_22009_h.getPosition(f); + if(mc.objectMouseOver != null) + { + d1 = mc.objectMouseOver.hitVec.distanceTo(vec3d); + } + if(d1 > 3D) + { + d1 = 3D; + } + d = d1; + Vec3D vec3d1 = mc.field_22009_h.getLook(f); + Vec3D vec3d2 = vec3d.addVector(vec3d1.xCoord * d, vec3d1.yCoord * d, vec3d1.zCoord * d); + field_1385_k = null; + float f1 = 1.0F; + List list = mc.theWorld.getEntitiesWithinAABBExcludingEntity(mc.field_22009_h, mc.field_22009_h.boundingBox.addCoord(vec3d1.xCoord * d, vec3d1.yCoord * d, vec3d1.zCoord * d).expand(f1, f1, f1)); + double d2 = 0.0D; + for(int i = 0; i < list.size(); i++) + { + Entity entity = (Entity)list.get(i); + if(!entity.canBeCollidedWith()) + { + continue; + } + float f2 = entity.getCollisionBorderSize(); + AxisAlignedBB axisalignedbb = entity.boundingBox.expand(f2, f2, f2); + MovingObjectPosition movingobjectposition = axisalignedbb.func_1169_a(vec3d, vec3d2); + if(axisalignedbb.isVecInside(vec3d)) + { + if(0.0D < d2 || d2 == 0.0D) + { + field_1385_k = entity; + d2 = 0.0D; + } + continue; + } + if(movingobjectposition == null) + { + continue; + } + double d3 = vec3d.distanceTo(movingobjectposition.hitVec); + if(d3 < d2 || d2 == 0.0D) + { + field_1385_k = entity; + d2 = d3; + } + } + + if(field_1385_k != null) + { + mc.objectMouseOver = new MovingObjectPosition(field_1385_k); + } + } + + private float func_914_d(float f) + { + EntityLiving entityliving = mc.field_22009_h; + float f1 = 70F; + if(entityliving.isInsideOfMaterial(Material.water)) + { + f1 = 60F; + } + if(entityliving.health <= 0) + { + float f2 = (float)entityliving.deathTime + f; + f1 /= (1.0F - 500F / (f2 + 500F)) * 2.0F + 1.0F; + } + return f1 + field_22221_y + (field_22222_x - field_22221_y) * f; + } + + private void hurtCameraEffect(float f) + { + EntityLiving entityliving = mc.field_22009_h; + float f1 = (float)entityliving.hurtTime - f; + if(entityliving.health <= 0) + { + float f2 = (float)entityliving.deathTime + f; + GL11.glRotatef(40F - 8000F / (f2 + 200F), 0.0F, 0.0F, 1.0F); + } + if(f1 < 0.0F) + { + return; + } else + { + f1 /= entityliving.maxHurtTime; + f1 = MathHelper.sin(f1 * f1 * f1 * f1 * 3.141593F); + float f3 = entityliving.attackedAtYaw; + GL11.glRotatef(-f3, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-f1 * 14F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(f3, 0.0F, 1.0F, 0.0F); + return; + } + } + + private void setupViewBobbing(float f) + { + if(!(mc.field_22009_h instanceof EntityPlayer)) + { + return; + } else + { + EntityPlayer entityplayer = (EntityPlayer)mc.field_22009_h; + float f1 = entityplayer.distanceWalkedModified - entityplayer.prevDistanceWalkedModified; + float f2 = -(entityplayer.distanceWalkedModified + f1 * f); + float f3 = entityplayer.field_775_e + (entityplayer.field_774_f - entityplayer.field_775_e) * f; + float f4 = entityplayer.field_9329_Q + (entityplayer.field_9328_R - entityplayer.field_9329_Q) * f; + GL11.glTranslatef(MathHelper.sin(f2 * 3.141593F) * f3 * 0.5F, -Math.abs(MathHelper.cos(f2 * 3.141593F) * f3), 0.0F); + GL11.glRotatef(MathHelper.sin(f2 * 3.141593F) * f3 * 3F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(Math.abs(MathHelper.cos(f2 * 3.141593F - 0.2F) * f3) * 5F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(f4, 1.0F, 0.0F, 0.0F); + return; + } + } + + private void orientCamera(float f) + { + EntityLiving entityliving = mc.field_22009_h; + float f1 = entityliving.yOffset - 1.62F; + double d = entityliving.prevPosX + (entityliving.posX - entityliving.prevPosX) * (double)f; + double d1 = (entityliving.prevPosY + (entityliving.posY - entityliving.prevPosY) * (double)f) - (double)f1; + double d2 = entityliving.prevPosZ + (entityliving.posZ - entityliving.prevPosZ) * (double)f; + GL11.glRotatef(field_22230_A + (field_22220_z - field_22230_A) * f, 0.0F, 0.0F, 1.0F); + if(entityliving.isPlayerSleeping()) + { + f1 = (float)((double)f1 + 1.0D); + GL11.glTranslatef(0.0F, 0.3F, 0.0F); + if(!mc.gameSettings.field_22273_E) + { + int i = mc.theWorld.getBlockId(MathHelper.floor_double(entityliving.posX), MathHelper.floor_double(entityliving.posY), MathHelper.floor_double(entityliving.posZ)); + if(i == Block.field_9262_S.blockID) + { + int j = mc.theWorld.getBlockMetadata(MathHelper.floor_double(entityliving.posX), MathHelper.floor_double(entityliving.posY), MathHelper.floor_double(entityliving.posZ)); + int k = j & 3; + GL11.glRotatef(k * 90, 0.0F, 1.0F, 0.0F); + } + GL11.glRotatef(entityliving.prevRotationYaw + (entityliving.rotationYaw - entityliving.prevRotationYaw) * f + 180F, 0.0F, -1F, 0.0F); + GL11.glRotatef(entityliving.prevRotationPitch + (entityliving.rotationPitch - entityliving.prevRotationPitch) * f, -1F, 0.0F, 0.0F); + } + } else + if(mc.gameSettings.thirdPersonView) + { + double d3 = field_22227_s + (field_22228_r - field_22227_s) * f; + if(mc.gameSettings.field_22273_E) + { + float f2 = field_22225_u + (field_22226_t - field_22225_u) * f; + float f4 = field_22223_w + (field_22224_v - field_22223_w) * f; + GL11.glTranslatef(0.0F, 0.0F, (float)(-d3)); + GL11.glRotatef(f4, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(f2, 0.0F, 1.0F, 0.0F); + } else + { + float f3 = entityliving.rotationYaw; + float f5 = entityliving.rotationPitch; + double d4 = (double)(-MathHelper.sin((f3 / 180F) * 3.141593F) * MathHelper.cos((f5 / 180F) * 3.141593F)) * d3; + double d5 = (double)(MathHelper.cos((f3 / 180F) * 3.141593F) * MathHelper.cos((f5 / 180F) * 3.141593F)) * d3; + double d6 = (double)(-MathHelper.sin((f5 / 180F) * 3.141593F)) * d3; + for(int l = 0; l < 8; l++) + { + float f6 = (l & 1) * 2 - 1; + float f7 = (l >> 1 & 1) * 2 - 1; + float f8 = (l >> 2 & 1) * 2 - 1; + f6 *= 0.1F; + f7 *= 0.1F; + f8 *= 0.1F; + MovingObjectPosition movingobjectposition = mc.theWorld.rayTraceBlocks(Vec3D.createVector(d + (double)f6, d1 + (double)f7, d2 + (double)f8), Vec3D.createVector((d - d4) + (double)f6 + (double)f8, (d1 - d6) + (double)f7, (d2 - d5) + (double)f8)); + if(movingobjectposition == null) + { + continue; + } + double d7 = movingobjectposition.hitVec.distanceTo(Vec3D.createVector(d, d1, d2)); + if(d7 < d3) + { + d3 = d7; + } + } + + GL11.glRotatef(entityliving.rotationPitch - f5, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(entityliving.rotationYaw - f3, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(0.0F, 0.0F, (float)(-d3)); + GL11.glRotatef(f3 - entityliving.rotationYaw, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(f5 - entityliving.rotationPitch, 1.0F, 0.0F, 0.0F); + } + } else + { + GL11.glTranslatef(0.0F, 0.0F, -0.1F); + } + if(!mc.gameSettings.field_22273_E) + { + GL11.glRotatef(entityliving.prevRotationPitch + (entityliving.rotationPitch - entityliving.prevRotationPitch) * f, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(entityliving.prevRotationYaw + (entityliving.rotationYaw - entityliving.prevRotationYaw) * f + 180F, 0.0F, 1.0F, 0.0F); + } + GL11.glTranslatef(0.0F, f1, 0.0F); + } + + public void func_21152_a(double d, double d1, double d2) + { + field_21155_l = d; + field_21154_m = d1; + field_21153_n = d2; + } + + public void func_21151_b() + { + field_21155_l = 1.0D; + } + + private void setupCameraTransform(float f, int i) + { + farPlaneDistance = 256 >> mc.gameSettings.renderDistance; + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + float f1 = 0.07F; + if(mc.gameSettings.anaglyph) + { + GL11.glTranslatef((float)(-(i * 2 - 1)) * f1, 0.0F, 0.0F); + } + if(field_21155_l != 1.0D) + { + GL11.glTranslatef((float)field_21154_m, (float)(-field_21153_n), 0.0F); + GL11.glScaled(field_21155_l, field_21155_l, 1.0D); + GLU.gluPerspective(func_914_d(f), (float)mc.displayWidth / (float)mc.displayHeight, 0.05F, farPlaneDistance); + } else + { + GLU.gluPerspective(func_914_d(f), (float)mc.displayWidth / (float)mc.displayHeight, 0.05F, farPlaneDistance); + } + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + if(mc.gameSettings.anaglyph) + { + GL11.glTranslatef((float)(i * 2 - 1) * 0.1F, 0.0F, 0.0F); + } + hurtCameraEffect(f); + if(mc.gameSettings.viewBobbing) + { + setupViewBobbing(f); + } + float f2 = mc.thePlayer.prevTimeInPortal + (mc.thePlayer.timeInPortal - mc.thePlayer.prevTimeInPortal) * f; + if(f2 > 0.0F) + { + float f3 = 5F / (f2 * f2 + 5F) - f2 * 0.04F; + f3 *= f3; + GL11.glRotatef(f2 * f2 * 1500F, 0.0F, 1.0F, 1.0F); + GL11.glScalef(1.0F / f3, 1.0F, 1.0F); + GL11.glRotatef(-f2 * f2 * 1500F, 0.0F, 1.0F, 1.0F); + } + orientCamera(f); + } + + private void func_4135_b(float f, int i) + { + GL11.glLoadIdentity(); + if(mc.gameSettings.anaglyph) + { + GL11.glTranslatef((float)(i * 2 - 1) * 0.1F, 0.0F, 0.0F); + } + GL11.glPushMatrix(); + hurtCameraEffect(f); + if(mc.gameSettings.viewBobbing) + { + setupViewBobbing(f); + } + if(!mc.gameSettings.thirdPersonView && !mc.field_22009_h.isPlayerSleeping() && !mc.gameSettings.field_22277_y) + { + itemRenderer.renderItemInFirstPerson(f); + } + GL11.glPopMatrix(); + if(!mc.gameSettings.thirdPersonView && !mc.field_22009_h.isPlayerSleeping()) + { + itemRenderer.renderOverlays(f); + hurtCameraEffect(f); + } + if(mc.gameSettings.viewBobbing) + { + setupViewBobbing(f); + } + } + + public void func_4136_b(float f) + { + if(!Display.isActive()) + { + if(System.currentTimeMillis() - field_1384_l > 500L) + { + mc.func_6252_g(); + } + } else + { + field_1384_l = System.currentTimeMillis(); + } + if(mc.field_6289_L) + { + mc.mouseHelper.mouseXYChange(); + float f1 = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F; + float f2 = f1 * f1 * f1 * 8F; + float f3 = (float)mc.mouseHelper.deltaX * f2; + float f4 = (float)mc.mouseHelper.deltaY * f2; + int l = 1; + if(mc.gameSettings.invertMouse) + { + l = -1; + } + if(mc.gameSettings.field_22274_D) + { + f3 = field_22235_l.func_22386_a(f3, 0.05F * f2); + f4 = field_22234_m.func_22386_a(f4, 0.05F * f2); + } + mc.thePlayer.func_346_d(f3, f4 * (float)l); + } + if(mc.field_6307_v) + { + return; + } + ScaledResolution scaledresolution = new ScaledResolution(mc.displayWidth, mc.displayHeight); + int i = scaledresolution.getScaledWidth(); + int j = scaledresolution.getScaledHeight(); + int k = (Mouse.getX() * i) / mc.displayWidth; + int i1 = j - (Mouse.getY() * j) / mc.displayHeight - 1; + if(mc.theWorld != null) + { + renderWorld(f); + if(!mc.gameSettings.field_22277_y || mc.currentScreen != null) + { + mc.ingameGUI.renderGameOverlay(f, mc.currentScreen != null, k, i1); + } + } else + { + GL11.glViewport(0, 0, mc.displayWidth, mc.displayHeight); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + func_905_b(); + } + if(mc.currentScreen != null) + { + GL11.glClear(256); + mc.currentScreen.drawScreen(k, i1, f); + } + } + + public void renderWorld(float f) + { + if(mc.field_22009_h == null) + { + mc.field_22009_h = mc.thePlayer; + } + getMouseOver(f); + EntityLiving entityliving = mc.field_22009_h; + RenderGlobal renderglobal = mc.renderGlobal; + EffectRenderer effectrenderer = mc.effectRenderer; + double d = entityliving.lastTickPosX + (entityliving.posX - entityliving.lastTickPosX) * (double)f; + double d1 = entityliving.lastTickPosY + (entityliving.posY - entityliving.lastTickPosY) * (double)f; + double d2 = entityliving.lastTickPosZ + (entityliving.posZ - entityliving.lastTickPosZ) * (double)f; + IChunkProvider ichunkprovider = mc.theWorld.func_21118_q(); + if(ichunkprovider instanceof ChunkProviderLoadOrGenerate) + { + ChunkProviderLoadOrGenerate chunkproviderloadorgenerate = (ChunkProviderLoadOrGenerate)ichunkprovider; + int j = MathHelper.floor_float((int)d) >> 4; + int k = MathHelper.floor_float((int)d2) >> 4; + chunkproviderloadorgenerate.func_21110_c(j, k); + } + for(int i = 0; i < 2; i++) + { + if(mc.gameSettings.anaglyph) + { + if(i == 0) + { + GL11.glColorMask(false, true, true, false); + } else + { + GL11.glColorMask(true, false, false, false); + } + } + GL11.glViewport(0, 0, mc.displayWidth, mc.displayHeight); + updateFogColor(f); + GL11.glClear(16640); + GL11.glEnable(2884 /*GL_CULL_FACE*/); + setupCameraTransform(f, i); + ClippingHelperImplementation.getInstance(); + if(mc.gameSettings.renderDistance < 2) + { + func_4140_a(-1); + renderglobal.func_4142_a(f); + } + GL11.glEnable(2912 /*GL_FOG*/); + func_4140_a(1); + if(mc.gameSettings.field_22278_j) + { + GL11.glShadeModel(7425 /*GL_SMOOTH*/); + } + Frustrum frustrum = new Frustrum(); + frustrum.setPosition(d, d1, d2); + mc.renderGlobal.func_960_a(frustrum, f); + mc.renderGlobal.updateRenderers(entityliving, false); + func_4140_a(0); + GL11.glEnable(2912 /*GL_FOG*/); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/terrain.png")); + RenderHelper.disableStandardItemLighting(); + renderglobal.func_943_a(entityliving, 0, f); + GL11.glShadeModel(7424 /*GL_FLAT*/); + RenderHelper.enableStandardItemLighting(); + renderglobal.func_951_a(entityliving.getPosition(f), frustrum, f); + effectrenderer.func_1187_b(entityliving, f); + RenderHelper.disableStandardItemLighting(); + func_4140_a(0); + effectrenderer.renderParticles(entityliving, f); + if(mc.objectMouseOver != null && entityliving.isInsideOfMaterial(Material.water) && (entityliving instanceof EntityPlayer)) + { + EntityPlayer entityplayer = (EntityPlayer)entityliving; + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + renderglobal.func_959_a(entityplayer, mc.objectMouseOver, 0, entityplayer.inventory.getCurrentItem(), f); + renderglobal.drawSelectionBox(entityplayer, mc.objectMouseOver, 0, entityplayer.inventory.getCurrentItem(), f); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + } + GL11.glBlendFunc(770, 771); + func_4140_a(0); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glDisable(2884 /*GL_CULL_FACE*/); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/terrain.png")); + if(mc.gameSettings.fancyGraphics) + { + GL11.glColorMask(false, false, false, false); + int l = renderglobal.func_943_a(entityliving, 1, f); + GL11.glColorMask(true, true, true, true); + if(mc.gameSettings.anaglyph) + { + if(i == 0) + { + GL11.glColorMask(false, true, true, false); + } else + { + GL11.glColorMask(true, false, false, false); + } + } + if(l > 0) + { + renderglobal.func_944_a(1, f); + } + } else + { + renderglobal.func_943_a(entityliving, 1, f); + } + GL11.glDepthMask(true); + GL11.glEnable(2884 /*GL_CULL_FACE*/); + GL11.glDisable(3042 /*GL_BLEND*/); + if(field_21155_l == 1.0D && (entityliving instanceof EntityPlayer) && mc.objectMouseOver != null && !entityliving.isInsideOfMaterial(Material.water)) + { + EntityPlayer entityplayer1 = (EntityPlayer)entityliving; + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + renderglobal.func_959_a(entityplayer1, mc.objectMouseOver, 0, entityplayer1.inventory.getCurrentItem(), f); + renderglobal.drawSelectionBox(entityplayer1, mc.objectMouseOver, 0, entityplayer1.inventory.getCurrentItem(), f); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + } + GL11.glDisable(2912 /*GL_FOG*/); + if(field_1385_k == null); + func_4140_a(0); + GL11.glEnable(2912 /*GL_FOG*/); + renderglobal.func_4141_b(f); + GL11.glDisable(2912 /*GL_FOG*/); + func_4140_a(1); + if(field_21155_l == 1.0D) + { + GL11.glClear(256); + func_4135_b(f, i); + } + if(!mc.gameSettings.anaglyph) + { + return; + } + } + + GL11.glColorMask(true, true, true, false); + } + + private void addRainParticles() + { + if(!mc.gameSettings.fancyGraphics) + { + return; + } + EntityLiving entityliving = mc.field_22009_h; + World world = mc.theWorld; + int i = MathHelper.floor_double(entityliving.posX); + int j = MathHelper.floor_double(entityliving.posY); + int k = MathHelper.floor_double(entityliving.posZ); + byte byte0 = 16; + for(int l = 0; l < 150; l++) + { + int i1 = (i + random.nextInt(byte0)) - random.nextInt(byte0); + int j1 = (k + random.nextInt(byte0)) - random.nextInt(byte0); + int k1 = world.func_696_e(i1, j1); + int l1 = world.getBlockId(i1, k1 - 1, j1); + if(k1 > j + byte0 || k1 < j - byte0) + { + continue; + } + float f = random.nextFloat(); + float f1 = random.nextFloat(); + if(l1 > 0) + { + mc.effectRenderer.addEffect(new EntityRainFX(world, (float)i1 + f, (double)((float)k1 + 0.1F) - Block.blocksList[l1].minY, (float)j1 + f1)); + } + } + + } + + public void func_905_b() + { + ScaledResolution scaledresolution = new ScaledResolution(mc.displayWidth, mc.displayHeight); + int i = scaledresolution.getScaledWidth(); + int j = scaledresolution.getScaledHeight(); + GL11.glClear(256); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, i, j, 0.0D, 1000D, 3000D); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -2000F); + } + + private void updateFogColor(float f) + { + World world = mc.theWorld; + EntityLiving entityliving = mc.field_22009_h; + float f1 = 1.0F / (float)(4 - mc.gameSettings.renderDistance); + f1 = 1.0F - (float)Math.pow(f1, 0.25D); + Vec3D vec3d = world.func_4079_a(mc.field_22009_h, f); + float f2 = (float)vec3d.xCoord; + float f3 = (float)vec3d.yCoord; + float f4 = (float)vec3d.zCoord; + Vec3D vec3d1 = world.func_4082_d(f); + fogColorRed = (float)vec3d1.xCoord; + fogColorGreen = (float)vec3d1.yCoord; + fogColorBlue = (float)vec3d1.zCoord; + fogColorRed += (f2 - fogColorRed) * f1; + fogColorGreen += (f3 - fogColorGreen) * f1; + fogColorBlue += (f4 - fogColorBlue) * f1; + if(entityliving.isInsideOfMaterial(Material.water)) + { + fogColorRed = 0.02F; + fogColorGreen = 0.02F; + fogColorBlue = 0.2F; + } else + if(entityliving.isInsideOfMaterial(Material.lava)) + { + fogColorRed = 0.6F; + fogColorGreen = 0.1F; + fogColorBlue = 0.0F; + } + float f5 = field_1382_n + (field_1381_o - field_1382_n) * f; + fogColorRed *= f5; + fogColorGreen *= f5; + fogColorBlue *= f5; + if(mc.gameSettings.anaglyph) + { + float f6 = (fogColorRed * 30F + fogColorGreen * 59F + fogColorBlue * 11F) / 100F; + float f7 = (fogColorRed * 30F + fogColorGreen * 70F) / 100F; + float f8 = (fogColorRed * 30F + fogColorBlue * 70F) / 100F; + fogColorRed = f6; + fogColorGreen = f7; + fogColorBlue = f8; + } + GL11.glClearColor(fogColorRed, fogColorGreen, fogColorBlue, 0.0F); + } + + private void func_4140_a(int i) + { + EntityLiving entityliving = mc.field_22009_h; + GL11.glFog(2918 /*GL_FOG_COLOR*/, func_908_a(fogColorRed, fogColorGreen, fogColorBlue, 1.0F)); + GL11.glNormal3f(0.0F, -1F, 0.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + if(entityliving.isInsideOfMaterial(Material.water)) + { + GL11.glFogi(2917 /*GL_FOG_MODE*/, 2048 /*GL_EXP*/); + GL11.glFogf(2914 /*GL_FOG_DENSITY*/, 0.1F); + float f = 0.4F; + float f2 = 0.4F; + float f4 = 0.9F; + if(mc.gameSettings.anaglyph) + { + float f6 = (f * 30F + f2 * 59F + f4 * 11F) / 100F; + float f8 = (f * 30F + f2 * 70F) / 100F; + float f10 = (f * 30F + f4 * 70F) / 100F; + f = f6; + f2 = f8; + f4 = f10; + } + } else + if(entityliving.isInsideOfMaterial(Material.lava)) + { + GL11.glFogi(2917 /*GL_FOG_MODE*/, 2048 /*GL_EXP*/); + GL11.glFogf(2914 /*GL_FOG_DENSITY*/, 2.0F); + float f1 = 0.4F; + float f3 = 0.3F; + float f5 = 0.3F; + if(mc.gameSettings.anaglyph) + { + float f7 = (f1 * 30F + f3 * 59F + f5 * 11F) / 100F; + float f9 = (f1 * 30F + f3 * 70F) / 100F; + float f11 = (f1 * 30F + f5 * 70F) / 100F; + f1 = f7; + f3 = f9; + f5 = f11; + } + } else + { + GL11.glFogi(2917 /*GL_FOG_MODE*/, 9729 /*GL_LINEAR*/); + GL11.glFogf(2915 /*GL_FOG_START*/, farPlaneDistance * 0.25F); + GL11.glFogf(2916 /*GL_FOG_END*/, farPlaneDistance); + if(i < 0) + { + GL11.glFogf(2915 /*GL_FOG_START*/, 0.0F); + GL11.glFogf(2916 /*GL_FOG_END*/, farPlaneDistance * 0.8F); + } + if(GLContext.getCapabilities().GL_NV_fog_distance) + { + GL11.glFogi(34138, 34139); + } + if(mc.theWorld.worldProvider.field_4220_c) + { + GL11.glFogf(2915 /*GL_FOG_START*/, 0.0F); + } + } + GL11.glEnable(2903 /*GL_COLOR_MATERIAL*/); + GL11.glColorMaterial(1028 /*GL_FRONT*/, 4608 /*GL_AMBIENT*/); + } + + private FloatBuffer func_908_a(float f, float f1, float f2, float f3) + { + field_1392_d.clear(); + field_1392_d.put(f).put(f1).put(f2).put(f3); + field_1392_d.flip(); + return field_1392_d; + } + + private Minecraft mc; + private float farPlaneDistance; + public ItemRenderer itemRenderer; + private int field_1386_j; + private Entity field_1385_k; + private MouseFilter field_22235_l; + private MouseFilter field_22234_m; + private MouseFilter field_22233_n; + private MouseFilter field_22232_o; + private MouseFilter field_22231_p; + private MouseFilter field_22229_q; + private float field_22228_r; + private float field_22227_s; + private float field_22226_t; + private float field_22225_u; + private float field_22224_v; + private float field_22223_w; + private float field_22222_x; + private float field_22221_y; + private float field_22220_z; + private float field_22230_A; + private double field_21155_l; + private double field_21154_m; + private double field_21153_n; + private long field_1384_l; + private Random random; + volatile int field_1394_b; + volatile int field_1393_c; + FloatBuffer field_1392_d; + float fogColorRed; + float fogColorGreen; + float fogColorBlue; + private float field_1382_n; + private float field_1381_o; +} diff --git a/src/main/java/net/minecraft/src/EntitySheep.java b/src/main/java/net/minecraft/src/EntitySheep.java new file mode 100644 index 0000000..d8d1b53 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySheep.java @@ -0,0 +1,149 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntitySheep extends EntityAnimals +{ + + public EntitySheep(World world) + { + super(world); + texture = "/mob/sheep.png"; + setSize(0.9F, 1.3F); + } + + protected void entityInit() + { + super.entityInit(); + dataWatcher.addObject(16, new Byte((byte)0)); + } + + public boolean attackEntityFrom(Entity entity, int i) + { + if(!worldObj.multiplayerWorld && !func_21072_p() && (entity instanceof EntityLiving)) + { + setSheared(true); + int j = 1 + rand.nextInt(3); + for(int k = 0; k < j; k++) + { + EntityItem entityitem = entityDropItem(new ItemStack(Block.cloth.blockID, 1, getFleeceColor()), 1.0F); + entityitem.motionY += rand.nextFloat() * 0.05F; + entityitem.motionX += (rand.nextFloat() - rand.nextFloat()) * 0.1F; + entityitem.motionZ += (rand.nextFloat() - rand.nextFloat()) * 0.1F; + } + + } + return super.attackEntityFrom(entity, i); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setBoolean("Sheared", func_21072_p()); + nbttagcompound.setByte("Color", (byte)getFleeceColor()); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + setSheared(nbttagcompound.getBoolean("Sheared")); + setFleeceColor(nbttagcompound.getByte("Color")); + } + + protected String getLivingSound() + { + return "mob.sheep"; + } + + protected String getHurtSound() + { + return "mob.sheep"; + } + + protected String getDeathSound() + { + return "mob.sheep"; + } + + public int getFleeceColor() + { + return dataWatcher.getWatchableObjectByte(16) & 0xf; + } + + public void setFleeceColor(int i) + { + byte byte0 = dataWatcher.getWatchableObjectByte(16); + dataWatcher.updateObject(16, Byte.valueOf((byte)(byte0 & 0xf0 | i & 0xf))); + } + + public boolean func_21072_p() + { + return (dataWatcher.getWatchableObjectByte(16) & 0x10) != 0; + } + + public void setSheared(boolean flag) + { + byte byte0 = dataWatcher.getWatchableObjectByte(16); + if(flag) + { + dataWatcher.updateObject(16, Byte.valueOf((byte)(byte0 | 0x10))); + } else + { + dataWatcher.updateObject(16, Byte.valueOf((byte)(byte0 & 0xffffffef))); + } + } + + public static int func_21070_a(Random random) + { + int i = random.nextInt(100); + if(i < 5) + { + return 15; + } + if(i < 10) + { + return 7; + } + return i >= 15 ? 0 : 8; + } + + public static final float field_21075_a[][] = { + { + 1.0F, 1.0F, 1.0F + }, { + 0.95F, 0.7F, 0.2F + }, { + 0.9F, 0.5F, 0.85F + }, { + 0.6F, 0.7F, 0.95F + }, { + 0.9F, 0.9F, 0.2F + }, { + 0.5F, 0.8F, 0.1F + }, { + 0.95F, 0.7F, 0.8F + }, { + 0.3F, 0.3F, 0.3F + }, { + 0.6F, 0.6F, 0.6F + }, { + 0.3F, 0.6F, 0.7F + }, { + 0.7F, 0.4F, 0.9F + }, { + 0.2F, 0.4F, 0.8F + }, { + 0.5F, 0.4F, 0.3F + }, { + 0.4F, 0.5F, 0.2F + }, { + 0.8F, 0.3F, 0.3F + }, { + 0.1F, 0.1F, 0.1F + } + }; + +} diff --git a/src/main/java/net/minecraft/src/EntitySkeleton.java b/src/main/java/net/minecraft/src/EntitySkeleton.java new file mode 100644 index 0000000..b04f960 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySkeleton.java @@ -0,0 +1,109 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntitySkeleton extends EntityMobs +{ + + public EntitySkeleton(World world) + { + super(world); + texture = "/mob/skeleton.png"; + } + + protected String getLivingSound() + { + return "mob.skeleton"; + } + + protected String getHurtSound() + { + return "mob.skeletonhurt"; + } + + protected String getDeathSound() + { + return "mob.skeletonhurt"; + } + + public void onLivingUpdate() + { + if(worldObj.isDaytime()) + { + float f = getEntityBrightness(1.0F); + if(f > 0.5F && worldObj.canBlockSeeTheSky(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)) && rand.nextFloat() * 30F < (f - 0.4F) * 2.0F) + { + fire = 300; + } + } + super.onLivingUpdate(); + } + + protected void attackEntity(Entity entity, float f) + { + if(f < 10F) + { + double d = entity.posX - posX; + double d1 = entity.posZ - posZ; + if(attackTime == 0) + { + EntityArrow entityarrow = new EntityArrow(worldObj, this); + entityarrow.posY += 1.3999999761581421D; + double d2 = entity.posY - 0.20000000298023224D - entityarrow.posY; + float f1 = MathHelper.sqrt_double(d * d + d1 * d1) * 0.2F; + worldObj.playSoundAtEntity(this, "random.bow", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); + worldObj.entityJoinedWorld(entityarrow); + entityarrow.setArrowHeading(d, d2 + (double)f1, d1, 0.6F, 12F); + attackTime = 30; + } + rotationYaw = (float)((Math.atan2(d1, d) * 180D) / 3.1415927410125732D) - 90F; + hasAttacked = true; + } + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + protected int getDropItemId() + { + return Item.arrow.shiftedIndex; + } + + protected void func_21066_o() + { + int i = rand.nextInt(3); + for(int j = 0; j < i; j++) + { + dropItem(Item.arrow.shiftedIndex, 1); + } + + i = rand.nextInt(3); + for(int k = 0; k < i; k++) + { + dropItem(Item.bone.shiftedIndex, 1); + } + + } + + public ItemStack getHeldItem() + { + return defaultHeldItem; + } + + private static final ItemStack defaultHeldItem; + + static + { + defaultHeldItem = new ItemStack(Item.bow, 1); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySlime.java b/src/main/java/net/minecraft/src/EntitySlime.java new file mode 100644 index 0000000..d36192a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySlime.java @@ -0,0 +1,163 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntitySlime extends EntityLiving + implements IMobs +{ + + public EntitySlime(World world) + { + super(world); + field_769_d = 0; + slimeSize = 1; + texture = "/mob/slime.png"; + slimeSize = 1 << rand.nextInt(3); + yOffset = 0.0F; + field_769_d = rand.nextInt(20) + 10; + setSlimeSize(slimeSize); + } + + public void setSlimeSize(int i) + { + slimeSize = i; + setSize(0.6F * (float)i, 0.6F * (float)i); + health = i * i; + setPosition(posX, posY, posZ); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setInteger("Size", slimeSize - 1); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + slimeSize = nbttagcompound.getInteger("Size") + 1; + } + + public void onUpdate() + { + field_767_b = field_768_a; + boolean flag = onGround; + super.onUpdate(); + if(onGround && !flag) + { + for(int i = 0; i < slimeSize * 8; i++) + { + float f = rand.nextFloat() * 3.141593F * 2.0F; + float f1 = rand.nextFloat() * 0.5F + 0.5F; + float f2 = MathHelper.sin(f) * (float)slimeSize * 0.5F * f1; + float f3 = MathHelper.cos(f) * (float)slimeSize * 0.5F * f1; + worldObj.spawnParticle("slime", posX + (double)f2, boundingBox.minY, posZ + (double)f3, 0.0D, 0.0D, 0.0D); + } + + if(slimeSize > 2) + { + worldObj.playSoundAtEntity(this, "mob.slime", getSoundVolume(), ((rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F) / 0.8F); + } + field_768_a = -0.5F; + } + field_768_a = field_768_a * 0.6F; + } + + protected void updatePlayerActionState() + { + EntityPlayer entityplayer = worldObj.getClosestPlayerToEntity(this, 16D); + if(entityplayer != null) + { + faceEntity(entityplayer, 10F); + } + if(onGround && field_769_d-- <= 0) + { + field_769_d = rand.nextInt(20) + 10; + if(entityplayer != null) + { + field_769_d /= 3; + } + isJumping = true; + if(slimeSize > 1) + { + worldObj.playSoundAtEntity(this, "mob.slime", getSoundVolume(), ((rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F) * 0.8F); + } + field_768_a = 1.0F; + moveStrafing = 1.0F - rand.nextFloat() * 2.0F; + moveForward = 1 * slimeSize; + } else + { + isJumping = false; + if(onGround) + { + moveStrafing = moveForward = 0.0F; + } + } + } + + public void setEntityDead() + { + if(slimeSize > 1 && health == 0) + { + for(int i = 0; i < 4; i++) + { + float f = (((float)(i % 2) - 0.5F) * (float)slimeSize) / 4F; + float f1 = (((float)(i / 2) - 0.5F) * (float)slimeSize) / 4F; + EntitySlime entityslime = new EntitySlime(worldObj); + entityslime.setSlimeSize(slimeSize / 2); + entityslime.setLocationAndAngles(posX + (double)f, posY + 0.5D, posZ + (double)f1, rand.nextFloat() * 360F, 0.0F); + worldObj.entityJoinedWorld(entityslime); + } + + } + super.setEntityDead(); + } + + public void onCollideWithPlayer(EntityPlayer entityplayer) + { + if(slimeSize > 1 && canEntityBeSeen(entityplayer) && (double)getDistanceToEntity(entityplayer) < 0.59999999999999998D * (double)slimeSize && entityplayer.attackEntityFrom(this, slimeSize)) + { + worldObj.playSoundAtEntity(this, "mob.slimeattack", 1.0F, (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + } + } + + protected String getHurtSound() + { + return "mob.slime"; + } + + protected String getDeathSound() + { + return "mob.slime"; + } + + protected int getDropItemId() + { + if(slimeSize == 1) + { + return Item.slimeBall.shiftedIndex; + } else + { + return 0; + } + } + + public boolean getCanSpawnHere() + { + Chunk chunk = worldObj.getChunkFromBlockCoords(MathHelper.floor_double(posX), MathHelper.floor_double(posZ)); + return (slimeSize == 1 || worldObj.difficultySetting > 0) && rand.nextInt(10) == 0 && chunk.func_997_a(0x3ad8025fL).nextInt(10) == 0 && posY < 16D; + } + + protected float getSoundVolume() + { + return 0.6F; + } + + public float field_768_a; + public float field_767_b; + private int field_769_d; + public int slimeSize; +} diff --git a/src/main/java/net/minecraft/src/EntitySlimeFX.java b/src/main/java/net/minecraft/src/EntitySlimeFX.java new file mode 100644 index 0000000..f016200 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySlimeFX.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntitySlimeFX extends EntityFX +{ + + public EntitySlimeFX(World world, double d, double d1, double d2, + Item item) + { + super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); + particleTextureIndex = item.getIconIndex(null); + particleRed = particleGreen = particleBlue = 1.0F; + particleGravity = Block.blockSnow.blockParticleGravity; + particleScale /= 2.0F; + } + + public int getFXLayer() + { + return 2; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = ((float)(particleTextureIndex % 16) + particleTextureJitterX / 4F) / 16F; + float f7 = f6 + 0.01560938F; + float f8 = ((float)(particleTextureIndex / 16) + particleTextureJitterY / 4F) / 16F; + float f9 = f8 + 0.01560938F; + float f10 = 0.1F * particleScale; + float f11 = (float)((prevPosX + (posX - prevPosX) * (double)f) - interpPosX); + float f12 = (float)((prevPosY + (posY - prevPosY) * (double)f) - interpPosY); + float f13 = (float)((prevPosZ + (posZ - prevPosZ) * (double)f) - interpPosZ); + float f14 = getEntityBrightness(f); + tessellator.setColorOpaque_F(f14 * particleRed, f14 * particleGreen, f14 * particleBlue); + tessellator.addVertexWithUV(f11 - f1 * f10 - f4 * f10, f12 - f2 * f10, f13 - f3 * f10 - f5 * f10, f6, f9); + tessellator.addVertexWithUV((f11 - f1 * f10) + f4 * f10, f12 + f2 * f10, (f13 - f3 * f10) + f5 * f10, f6, f8); + tessellator.addVertexWithUV(f11 + f1 * f10 + f4 * f10, f12 + f2 * f10, f13 + f3 * f10 + f5 * f10, f7, f8); + tessellator.addVertexWithUV((f11 + f1 * f10) - f4 * f10, f12 - f2 * f10, (f13 + f3 * f10) - f5 * f10, f7, f9); + } +} diff --git a/src/main/java/net/minecraft/src/EntitySmokeFX.java b/src/main/java/net/minecraft/src/EntitySmokeFX.java new file mode 100644 index 0000000..0b2e33e --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySmokeFX.java @@ -0,0 +1,78 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntitySmokeFX extends EntityFX +{ + + public EntitySmokeFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + this(world, d, d1, d2, d3, d4, d5, 1.0F); + } + + public EntitySmokeFX(World world, double d, double d1, double d2, + double d3, double d4, double d5, float f) + { + super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); + motionX *= 0.10000000149011612D; + motionY *= 0.10000000149011612D; + motionZ *= 0.10000000149011612D; + motionX += d3; + motionY += d4; + motionZ += d5; + particleRed = particleGreen = particleBlue = (float)(Math.random() * 0.30000001192092896D); + particleScale *= 0.75F; + particleScale *= f; + field_671_a = particleScale; + particleMaxAge = (int)(8D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)); + particleMaxAge *= f; + noClip = false; + } + + public void renderParticle(Tessellator tessellator, float f, float f1, float f2, float f3, float f4, float f5) + { + float f6 = (((float)particleAge + f) / (float)particleMaxAge) * 32F; + if(f6 < 0.0F) + { + f6 = 0.0F; + } + if(f6 > 1.0F) + { + f6 = 1.0F; + } + particleScale = field_671_a * f6; + super.renderParticle(tessellator, f, f1, f2, f3, f4, f5); + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + if(particleAge++ >= particleMaxAge) + { + setEntityDead(); + } + particleTextureIndex = 7 - (particleAge * 8) / particleMaxAge; + motionY += 0.0040000000000000001D; + moveEntity(motionX, motionY, motionZ); + if(posY == prevPosY) + { + motionX *= 1.1000000000000001D; + motionZ *= 1.1000000000000001D; + } + motionX *= 0.95999997854232788D; + motionY *= 0.95999997854232788D; + motionZ *= 0.95999997854232788D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + } + } + + float field_671_a; +} diff --git a/src/main/java/net/minecraft/src/EntitySnowball.java b/src/main/java/net/minecraft/src/EntitySnowball.java new file mode 100644 index 0000000..67917b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySnowball.java @@ -0,0 +1,274 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class EntitySnowball extends Entity +{ + + public EntitySnowball(World world) + { + super(world); + xTileSnowball = -1; + yTileSnowball = -1; + zTileSnowball = -1; + inTileSnowball = 0; + inGroundSnowball = false; + shakeSnowball = 0; + field_809_i = 0; + setSize(0.25F, 0.25F); + } + + protected void entityInit() + { + } + + public boolean isInRangeToRenderDist(double d) + { + double d1 = boundingBox.getAverageEdgeLength() * 4D; + d1 *= 64D; + return d < d1 * d1; + } + + public EntitySnowball(World world, EntityLiving entityliving) + { + super(world); + xTileSnowball = -1; + yTileSnowball = -1; + zTileSnowball = -1; + inTileSnowball = 0; + inGroundSnowball = false; + shakeSnowball = 0; + field_809_i = 0; + field_811_g = entityliving; + setSize(0.25F, 0.25F); + setLocationAndAngles(entityliving.posX, entityliving.posY + (double)entityliving.getEyeHeight(), entityliving.posZ, entityliving.rotationYaw, entityliving.rotationPitch); + posX -= MathHelper.cos((rotationYaw / 180F) * 3.141593F) * 0.16F; + posY -= 0.10000000149011612D; + posZ -= MathHelper.sin((rotationYaw / 180F) * 3.141593F) * 0.16F; + setPosition(posX, posY, posZ); + yOffset = 0.0F; + float f = 0.4F; + motionX = -MathHelper.sin((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f; + motionZ = MathHelper.cos((rotationYaw / 180F) * 3.141593F) * MathHelper.cos((rotationPitch / 180F) * 3.141593F) * f; + motionY = -MathHelper.sin((rotationPitch / 180F) * 3.141593F) * f; + func_467_a(motionX, motionY, motionZ, 1.5F, 1.0F); + } + + public EntitySnowball(World world, double d, double d1, double d2) + { + super(world); + xTileSnowball = -1; + yTileSnowball = -1; + zTileSnowball = -1; + inTileSnowball = 0; + inGroundSnowball = false; + shakeSnowball = 0; + field_809_i = 0; + field_810_h = 0; + setSize(0.25F, 0.25F); + setPosition(d, d1, d2); + yOffset = 0.0F; + } + + public void func_467_a(double d, double d1, double d2, float f, + float f1) + { + float f2 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + d /= f2; + d1 /= f2; + d2 /= f2; + d += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d1 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d2 += rand.nextGaussian() * 0.0074999998323619366D * (double)f1; + d *= f; + d1 *= f; + d2 *= f; + motionX = d; + motionY = d1; + motionZ = d2; + float f3 = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f3) * 180D) / 3.1415927410125732D); + field_810_h = 0; + } + + public void setVelocity(double d, double d1, double d2) + { + motionX = d; + motionY = d1; + motionZ = d2; + if(prevRotationPitch == 0.0F && prevRotationYaw == 0.0F) + { + float f = MathHelper.sqrt_double(d * d + d2 * d2); + prevRotationYaw = rotationYaw = (float)((Math.atan2(d, d2) * 180D) / 3.1415927410125732D); + prevRotationPitch = rotationPitch = (float)((Math.atan2(d1, f) * 180D) / 3.1415927410125732D); + } + } + + public void onUpdate() + { + lastTickPosX = posX; + lastTickPosY = posY; + lastTickPosZ = posZ; + super.onUpdate(); + if(shakeSnowball > 0) + { + shakeSnowball--; + } + if(inGroundSnowball) + { + int i = worldObj.getBlockId(xTileSnowball, yTileSnowball, zTileSnowball); + if(i != inTileSnowball) + { + inGroundSnowball = false; + motionX *= rand.nextFloat() * 0.2F; + motionY *= rand.nextFloat() * 0.2F; + motionZ *= rand.nextFloat() * 0.2F; + field_810_h = 0; + field_809_i = 0; + } else + { + field_810_h++; + if(field_810_h == 1200) + { + setEntityDead(); + } + return; + } + } else + { + field_809_i++; + } + Vec3D vec3d = Vec3D.createVector(posX, posY, posZ); + Vec3D vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d1); + vec3d = Vec3D.createVector(posX, posY, posZ); + vec3d1 = Vec3D.createVector(posX + motionX, posY + motionY, posZ + motionZ); + if(movingobjectposition != null) + { + vec3d1 = Vec3D.createVector(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); + } + if(!worldObj.multiplayerWorld) + { + Entity entity = null; + List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D)); + double d = 0.0D; + for(int l = 0; l < list.size(); l++) + { + Entity entity1 = (Entity)list.get(l); + if(!entity1.canBeCollidedWith() || entity1 == field_811_g && field_809_i < 5) + { + continue; + } + float f4 = 0.3F; + AxisAlignedBB axisalignedbb = entity1.boundingBox.expand(f4, f4, f4); + MovingObjectPosition movingobjectposition1 = axisalignedbb.func_1169_a(vec3d, vec3d1); + if(movingobjectposition1 == null) + { + continue; + } + double d1 = vec3d.distanceTo(movingobjectposition1.hitVec); + if(d1 < d || d == 0.0D) + { + entity = entity1; + d = d1; + } + } + + if(entity != null) + { + movingobjectposition = new MovingObjectPosition(entity); + } + } + if(movingobjectposition != null) + { + if(movingobjectposition.entityHit != null) + { + if(!movingobjectposition.entityHit.attackEntityFrom(field_811_g, 0)); + } + for(int j = 0; j < 8; j++) + { + worldObj.spawnParticle("snowballpoof", posX, posY, posZ, 0.0D, 0.0D, 0.0D); + } + + setEntityDead(); + } + posX += motionX; + posY += motionY; + posZ += motionZ; + float f = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + rotationYaw = (float)((Math.atan2(motionX, motionZ) * 180D) / 3.1415927410125732D); + for(rotationPitch = (float)((Math.atan2(motionY, f) * 180D) / 3.1415927410125732D); rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } + for(; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + for(; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } + for(; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } + rotationPitch = prevRotationPitch + (rotationPitch - prevRotationPitch) * 0.2F; + rotationYaw = prevRotationYaw + (rotationYaw - prevRotationYaw) * 0.2F; + float f1 = 0.99F; + float f2 = 0.03F; + if(handleWaterMovement()) + { + for(int k = 0; k < 4; k++) + { + float f3 = 0.25F; + worldObj.spawnParticle("bubble", posX - motionX * (double)f3, posY - motionY * (double)f3, posZ - motionZ * (double)f3, motionX, motionY, motionZ); + } + + f1 = 0.8F; + } + motionX *= f1; + motionY *= f1; + motionZ *= f1; + motionY -= f2; + setPosition(posX, posY, posZ); + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("xTile", (short)xTileSnowball); + nbttagcompound.setShort("yTile", (short)yTileSnowball); + nbttagcompound.setShort("zTile", (short)zTileSnowball); + nbttagcompound.setByte("inTile", (byte)inTileSnowball); + nbttagcompound.setByte("shake", (byte)shakeSnowball); + nbttagcompound.setByte("inGround", (byte)(inGroundSnowball ? 1 : 0)); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + xTileSnowball = nbttagcompound.getShort("xTile"); + yTileSnowball = nbttagcompound.getShort("yTile"); + zTileSnowball = nbttagcompound.getShort("zTile"); + inTileSnowball = nbttagcompound.getByte("inTile") & 0xff; + shakeSnowball = nbttagcompound.getByte("shake") & 0xff; + inGroundSnowball = nbttagcompound.getByte("inGround") == 1; + } + + public void onCollideWithPlayer(EntityPlayer entityplayer) + { + if(inGroundSnowball && field_811_g == entityplayer && shakeSnowball <= 0 && entityplayer.inventory.addItemStackToInventory(new ItemStack(Item.arrow, 1))) + { + worldObj.playSoundAtEntity(this, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + entityplayer.onItemPickup(this, 1); + setEntityDead(); + } + } + + public float getShadowSize() + { + return 0.0F; + } + + private int xTileSnowball; + private int yTileSnowball; + private int zTileSnowball; + private int inTileSnowball; + private boolean inGroundSnowball; + public int shakeSnowball; + private EntityLiving field_811_g; + private int field_810_h; + private int field_809_i; +} diff --git a/src/main/java/net/minecraft/src/EntitySorter.java b/src/main/java/net/minecraft/src/EntitySorter.java new file mode 100644 index 0000000..3f1ffb6 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySorter.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Comparator; + +public class EntitySorter + implements Comparator +{ + + public EntitySorter(Entity entity) + { + field_1594_a = entity; + } + + public int func_1063_a(WorldRenderer worldrenderer, WorldRenderer worldrenderer1) + { + return worldrenderer.distanceToEntity(field_1594_a) >= worldrenderer1.distanceToEntity(field_1594_a) ? 1 : -1; + } + + public int compare(Object obj, Object obj1) + { + return func_1063_a((WorldRenderer)obj, (WorldRenderer)obj1); + } + + private Entity field_1594_a; +} diff --git a/src/main/java/net/minecraft/src/EntitySpider.java b/src/main/java/net/minecraft/src/EntitySpider.java new file mode 100644 index 0000000..fd85a8f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySpider.java @@ -0,0 +1,96 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntitySpider extends EntityMobs +{ + + public EntitySpider(World world) + { + super(world); + texture = "/mob/spider.png"; + setSize(1.4F, 0.9F); + moveSpeed = 0.8F; + } + + public double getMountedYOffset() + { + return (double)height * 0.75D - 0.5D; + } + + protected Entity findPlayerToAttack() + { + float f = getEntityBrightness(1.0F); + if(f < 0.5F) + { + double d = 16D; + return worldObj.getClosestPlayerToEntity(this, d); + } else + { + return null; + } + } + + protected String getLivingSound() + { + return "mob.spider"; + } + + protected String getHurtSound() + { + return "mob.spider"; + } + + protected String getDeathSound() + { + return "mob.spiderdeath"; + } + + protected void attackEntity(Entity entity, float f) + { + float f1 = getEntityBrightness(1.0F); + if(f1 > 0.5F && rand.nextInt(100) == 0) + { + playerToAttack = null; + return; + } + if(f > 2.0F && f < 6F && rand.nextInt(10) == 0) + { + if(onGround) + { + double d = entity.posX - posX; + double d1 = entity.posZ - posZ; + float f2 = MathHelper.sqrt_double(d * d + d1 * d1); + motionX = (d / (double)f2) * 0.5D * 0.80000001192092896D + motionX * 0.20000000298023224D; + motionZ = (d1 / (double)f2) * 0.5D * 0.80000001192092896D + motionZ * 0.20000000298023224D; + motionY = 0.40000000596046448D; + } + } else + { + super.attackEntity(entity, f); + } + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + protected int getDropItemId() + { + return Item.silk.shiftedIndex; + } + + public boolean isOnLadder() + { + return isCollidedHorizontally; + } +} diff --git a/src/main/java/net/minecraft/src/EntitySplashFX.java b/src/main/java/net/minecraft/src/EntitySplashFX.java new file mode 100644 index 0000000..29407e4 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySplashFX.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntitySplashFX extends EntityRainFX +{ + + public EntitySplashFX(World world, double d, double d1, double d2, + double d3, double d4, double d5) + { + super(world, d, d1, d2); + particleGravity = 0.04F; + particleTextureIndex++; + if(d4 == 0.0D && (d3 != 0.0D || d5 != 0.0D)) + { + motionX = d3; + motionY = d4 + 0.10000000000000001D; + motionZ = d5; + } + } +} diff --git a/src/main/java/net/minecraft/src/EntitySquid.java b/src/main/java/net/minecraft/src/EntitySquid.java new file mode 100644 index 0000000..d9fb54a --- /dev/null +++ b/src/main/java/net/minecraft/src/EntitySquid.java @@ -0,0 +1,179 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntitySquid extends EntityWaterMob +{ + + public EntitySquid(World world) + { + super(world); + field_21089_a = 0.0F; + field_21088_b = 0.0F; + field_21087_c = 0.0F; + field_21086_f = 0.0F; + field_21085_g = 0.0F; + field_21084_h = 0.0F; + field_21083_i = 0.0F; + field_21082_j = 0.0F; + field_21081_k = 0.0F; + field_21080_l = 0.0F; + field_21079_m = 0.0F; + field_21078_n = 0.0F; + field_21077_o = 0.0F; + field_21076_p = 0.0F; + texture = "/mob/squid.png"; + setSize(0.95F, 0.95F); + field_21080_l = (1.0F / (rand.nextFloat() + 1.0F)) * 0.2F; + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + protected String getLivingSound() + { + return null; + } + + protected String getHurtSound() + { + return null; + } + + protected String getDeathSound() + { + return null; + } + + protected float getSoundVolume() + { + return 0.4F; + } + + protected int getDropItemId() + { + return 0; + } + + protected void func_21066_o() + { + int i = rand.nextInt(3) + 1; + for(int j = 0; j < i; j++) + { + entityDropItem(new ItemStack(Item.dyePowder, 1, 0), 0.0F); + } + + } + + public boolean interact(EntityPlayer entityplayer) + { + return false; + } + + public boolean handleWaterMovement() + { + return worldObj.handleMaterialAcceleration(boundingBox.expand(0.0D, -0.60000002384185791D, 0.0D), Material.water, this); + } + + public void onLivingUpdate() + { + super.onLivingUpdate(); + field_21088_b = field_21089_a; + field_21086_f = field_21087_c; + field_21084_h = field_21085_g; + field_21082_j = field_21083_i; + field_21085_g += field_21080_l; + if(field_21085_g > 6.283185F) + { + field_21085_g -= 6.283185F; + if(rand.nextInt(10) == 0) + { + field_21080_l = (1.0F / (rand.nextFloat() + 1.0F)) * 0.2F; + } + } + if(handleWaterMovement()) + { + if(field_21085_g < 3.141593F) + { + float f = field_21085_g / 3.141593F; + field_21083_i = MathHelper.sin(f * f * 3.141593F) * 3.141593F * 0.25F; + if((double)f > 0.75D) + { + field_21081_k = 1.0F; + field_21079_m = 1.0F; + } else + { + field_21079_m = field_21079_m * 0.8F; + } + } else + { + field_21083_i = 0.0F; + field_21081_k = field_21081_k * 0.9F; + field_21079_m = field_21079_m * 0.99F; + } + if(!field_9343_G) + { + motionX = field_21078_n * field_21081_k; + motionY = field_21077_o * field_21081_k; + motionZ = field_21076_p * field_21081_k; + } + float f1 = MathHelper.sqrt_double(motionX * motionX + motionZ * motionZ); + renderYawOffset += ((-(float)Math.atan2(motionX, motionZ) * 180F) / 3.141593F - renderYawOffset) * 0.1F; + rotationYaw = renderYawOffset; + field_21087_c = field_21087_c + 3.141593F * field_21079_m * 1.5F; + field_21089_a += ((-(float)Math.atan2(f1, motionY) * 180F) / 3.141593F - field_21089_a) * 0.1F; + } else + { + field_21083_i = MathHelper.abs(MathHelper.sin(field_21085_g)) * 3.141593F * 0.25F; + if(!field_9343_G) + { + motionX = 0.0D; + motionY -= 0.080000000000000002D; + motionY *= 0.98000001907348633D; + motionZ = 0.0D; + } + field_21089_a += (double)(-90F - field_21089_a) * 0.02D; + } + } + + public void moveEntityWithHeading(float f, float f1) + { + moveEntity(motionX, motionY, motionZ); + } + + protected void updatePlayerActionState() + { + if(rand.nextInt(50) == 0 || !inWater || field_21078_n == 0.0F && field_21077_o == 0.0F && field_21076_p == 0.0F) + { + float f = rand.nextFloat() * 3.141593F * 2.0F; + field_21078_n = MathHelper.cos(f) * 0.2F; + field_21077_o = -0.1F + rand.nextFloat() * 0.2F; + field_21076_p = MathHelper.sin(f) * 0.2F; + } + } + + public float field_21089_a; + public float field_21088_b; + public float field_21087_c; + public float field_21086_f; + public float field_21085_g; + public float field_21084_h; + public float field_21083_i; + public float field_21082_j; + private float field_21081_k; + private float field_21080_l; + private float field_21079_m; + private float field_21078_n; + private float field_21077_o; + private float field_21076_p; +} diff --git a/src/main/java/net/minecraft/src/EntityTNTPrimed.java b/src/main/java/net/minecraft/src/EntityTNTPrimed.java new file mode 100644 index 0000000..0588344 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityTNTPrimed.java @@ -0,0 +1,91 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityTNTPrimed extends Entity +{ + + public EntityTNTPrimed(World world) + { + super(world); + fuse = 0; + preventEntitySpawning = true; + setSize(0.98F, 0.98F); + yOffset = height / 2.0F; + } + + public EntityTNTPrimed(World world, double d, double d1, double d2) + { + this(world); + setPosition(d, d1, d2); + float f = (float)(Math.random() * 3.1415927410125732D * 2D); + motionX = -MathHelper.sin((f * 3.141593F) / 180F) * 0.02F; + motionY = 0.20000000298023224D; + motionZ = -MathHelper.cos((f * 3.141593F) / 180F) * 0.02F; + entityWalks = false; + fuse = 80; + prevPosX = d; + prevPosY = d1; + prevPosZ = d2; + } + + protected void entityInit() + { + } + + public boolean canBeCollidedWith() + { + return !isDead; + } + + public void onUpdate() + { + prevPosX = posX; + prevPosY = posY; + prevPosZ = posZ; + motionY -= 0.039999999105930328D; + moveEntity(motionX, motionY, motionZ); + motionX *= 0.98000001907348633D; + motionY *= 0.98000001907348633D; + motionZ *= 0.98000001907348633D; + if(onGround) + { + motionX *= 0.69999998807907104D; + motionZ *= 0.69999998807907104D; + motionY *= -0.5D; + } + if(fuse-- <= 0) + { + setEntityDead(); + explode(); + } else + { + worldObj.spawnParticle("smoke", posX, posY + 0.5D, posZ, 0.0D, 0.0D, 0.0D); + } + } + + private void explode() + { + float f = 4F; + worldObj.createExplosion(null, posX, posY, posZ, f); + } + + protected void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setByte("Fuse", (byte)fuse); + } + + protected void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + fuse = nbttagcompound.getByte("Fuse"); + } + + public float getShadowSize() + { + return 0.0F; + } + + public int fuse; +} diff --git a/src/main/java/net/minecraft/src/EntityWaterMob.java b/src/main/java/net/minecraft/src/EntityWaterMob.java new file mode 100644 index 0000000..7e57525 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityWaterMob.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityWaterMob extends EntityCreature +{ + + public EntityWaterMob(World world) + { + super(world); + } + + public boolean canBreatheUnderwater() + { + return true; + } + + public void writeEntityToNBT(NBTTagCompound nbttagcompound) + { + super.writeEntityToNBT(nbttagcompound); + } + + public void readEntityFromNBT(NBTTagCompound nbttagcompound) + { + super.readEntityFromNBT(nbttagcompound); + } + + public boolean getCanSpawnHere() + { + return worldObj.checkIfAABBIsClear(boundingBox); + } + + public int func_421_b() + { + return 120; + } +} diff --git a/src/main/java/net/minecraft/src/EntityZombie.java b/src/main/java/net/minecraft/src/EntityZombie.java new file mode 100644 index 0000000..b4d3845 --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityZombie.java @@ -0,0 +1,51 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class EntityZombie extends EntityMobs +{ + + public EntityZombie(World world) + { + super(world); + texture = "/mob/zombie.png"; + moveSpeed = 0.5F; + attackStrength = 5; + } + + public void onLivingUpdate() + { + if(worldObj.isDaytime()) + { + float f = getEntityBrightness(1.0F); + if(f > 0.5F && worldObj.canBlockSeeTheSky(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)) && rand.nextFloat() * 30F < (f - 0.4F) * 2.0F) + { + fire = 300; + } + } + super.onLivingUpdate(); + } + + protected String getLivingSound() + { + return "mob.zombie"; + } + + protected String getHurtSound() + { + return "mob.zombiehurt"; + } + + protected String getDeathSound() + { + return "mob.zombiedeath"; + } + + protected int getDropItemId() + { + return Item.feather.shiftedIndex; + } +} diff --git a/src/main/java/net/minecraft/src/EntityZombieSimple.java b/src/main/java/net/minecraft/src/EntityZombieSimple.java new file mode 100644 index 0000000..36bdf1f --- /dev/null +++ b/src/main/java/net/minecraft/src/EntityZombieSimple.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class EntityZombieSimple extends EntityMobs +{ + + public EntityZombieSimple(World world) + { + super(world); + texture = "/mob/zombie.png"; + moveSpeed = 0.5F; + attackStrength = 50; + health *= 10; + yOffset *= 6F; + setSize(width * 6F, height * 6F); + } + + protected float getBlockPathWeight(int i, int j, int k) + { + return worldObj.getLightBrightness(i, j, k) - 0.5F; + } +} diff --git a/src/main/java/net/minecraft/src/EnumArt.java b/src/main/java/net/minecraft/src/EnumArt.java new file mode 100644 index 0000000..a1fd8bf --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumArt.java @@ -0,0 +1,97 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumArt extends CompatEnum +{ + + public static EnumArt[] values() + { + return (EnumArt[])field_1630_D.clone(); + } + + public static EnumArt valueOf(String s) + { + return (EnumArt)CompatEnum.valueOf(EnumArt.class, s); + } + + private EnumArt(String s, int i, String s1, int j, int k, int l, int i1) + { + super(s, i); + title = s1; + sizeX = j; + sizeY = k; + offsetX = l; + offsetY = i1; + } + + public static final EnumArt Kebab; + public static final EnumArt Aztec; + public static final EnumArt Alban; + public static final EnumArt Aztec2; + public static final EnumArt Bomb; + public static final EnumArt Plant; + public static final EnumArt Wasteland; + public static final EnumArt Pool; + public static final EnumArt Courbet; + public static final EnumArt Sea; + public static final EnumArt Sunset; + public static final EnumArt Creebet; + public static final EnumArt Wanderer; + public static final EnumArt Graham; + public static final EnumArt Match; + public static final EnumArt Bust; + public static final EnumArt Stage; + public static final EnumArt Void; + public static final EnumArt SkullAndRoses; + public static final EnumArt Fighters; + public static final EnumArt Pointer; + public static final EnumArt Pigscene; + public static final EnumArt BurningSkull; + public static final EnumArt Skeleton; + public static final EnumArt DonkeyKong; + public final String title; + public final int sizeX; + public final int sizeY; + public final int offsetX; + public final int offsetY; + private static final EnumArt field_1630_D[]; /* synthetic field */ + + static + { + Kebab = new EnumArt("Kebab", 0, "Kebab", 16, 16, 0, 0); + Aztec = new EnumArt("Aztec", 1, "Aztec", 16, 16, 16, 0); + Alban = new EnumArt("Alban", 2, "Alban", 16, 16, 32, 0); + Aztec2 = new EnumArt("Aztec2", 3, "Aztec2", 16, 16, 48, 0); + Bomb = new EnumArt("Bomb", 4, "Bomb", 16, 16, 64, 0); + Plant = new EnumArt("Plant", 5, "Plant", 16, 16, 80, 0); + Wasteland = new EnumArt("Wasteland", 6, "Wasteland", 16, 16, 96, 0); + Pool = new EnumArt("Pool", 7, "Pool", 32, 16, 0, 32); + Courbet = new EnumArt("Courbet", 8, "Courbet", 32, 16, 32, 32); + Sea = new EnumArt("Sea", 9, "Sea", 32, 16, 64, 32); + Sunset = new EnumArt("Sunset", 10, "Sunset", 32, 16, 96, 32); + Creebet = new EnumArt("Creebet", 11, "Creebet", 32, 16, 128, 32); + Wanderer = new EnumArt("Wanderer", 12, "Wanderer", 16, 32, 0, 64); + Graham = new EnumArt("Graham", 13, "Graham", 16, 32, 16, 64); + Match = new EnumArt("Match", 14, "Match", 32, 32, 0, 128); + Bust = new EnumArt("Bust", 15, "Bust", 32, 32, 32, 128); + Stage = new EnumArt("Stage", 16, "Stage", 32, 32, 64, 128); + Void = new EnumArt("Void", 17, "Void", 32, 32, 96, 128); + SkullAndRoses = new EnumArt("SkullAndRoses", 18, "SkullAndRoses", 32, 32, 128, 128); + Fighters = new EnumArt("Fighters", 19, "Fighters", 64, 32, 0, 96); + Pointer = new EnumArt("Pointer", 20, "Pointer", 64, 64, 0, 192); + Pigscene = new EnumArt("Pigscene", 21, "Pigscene", 64, 64, 64, 192); + BurningSkull = new EnumArt("BurningSkull", 22, "BurningSkull", 64, 64, 128, 192); + Skeleton = new EnumArt("Skeleton", 23, "Skeleton", 64, 48, 192, 64); + DonkeyKong = new EnumArt("DonkeyKong", 24, "DonkeyKong", 64, 48, 192, 112); + field_1630_D = (new EnumArt[] { + Kebab, Aztec, Alban, Aztec2, Bomb, Plant, Wasteland, Pool, Courbet, Sea, + Sunset, Creebet, Wanderer, Graham, Match, Bust, Stage, Void, SkullAndRoses, Fighters, + Pointer, Pigscene, BurningSkull, Skeleton, DonkeyKong + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumCreatureType.java b/src/main/java/net/minecraft/src/EnumCreatureType.java new file mode 100644 index 0000000..2d7e755 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumCreatureType.java @@ -0,0 +1,69 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumCreatureType extends CompatEnum +{ + + public static EnumCreatureType[] values() + { + return (EnumCreatureType[])field_6518_e.clone(); + } + + public static EnumCreatureType valueOf(String s) + { + return (EnumCreatureType)CompatEnum.valueOf(EnumCreatureType.class, s); + } + + private EnumCreatureType(String s, int i, Class class1, int j, Material material, boolean flag) + { + super(s, i); + creatureClass = class1; + maxNumberOfCreature = j; + creatureMaterial = material; + field_21172_g = flag; + } + + public Class getCreatureClass() + { + return creatureClass; + } + + public int getMaxNumberOfCreature() + { + return maxNumberOfCreature; + } + + public Material getCreatureMaterial() + { + return creatureMaterial; + } + + public boolean func_21168_d() + { + return field_21172_g; + } + + public static final EnumCreatureType monster; + public static final EnumCreatureType creature; + public static final EnumCreatureType waterCreature; + private final Class creatureClass; + private final int maxNumberOfCreature; + private final Material creatureMaterial; + private final boolean field_21172_g; + private static final EnumCreatureType field_6518_e[]; /* synthetic field */ + + static + { + monster = new EnumCreatureType("monster", 0, IMobs.class, 70, Material.air, false); + creature = new EnumCreatureType("creature", 1, EntityAnimals.class, 15, Material.air, true); + waterCreature = new EnumCreatureType("waterCreature", 2, EntityWaterMob.class, 5, Material.water, true); + field_6518_e = (new EnumCreatureType[] { + monster, creature, waterCreature + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumMobType.java b/src/main/java/net/minecraft/src/EnumMobType.java new file mode 100644 index 0000000..6508183 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumMobType.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumMobType extends CompatEnum +{ + + public static EnumMobType[] values() + { + return (EnumMobType[])field_1340_d.clone(); + } + + public static EnumMobType valueOf(String s) + { + return (EnumMobType)CompatEnum.valueOf(EnumMobType.class, s); + } + + private EnumMobType(String s, int i) + { + super(s, i); + } + + public static final EnumMobType everything; + public static final EnumMobType mobs; + public static final EnumMobType players; + private static final EnumMobType field_1340_d[]; /* synthetic field */ + + static + { + everything = new EnumMobType("everything", 0); + mobs = new EnumMobType("mobs", 1); + players = new EnumMobType("players", 2); + field_1340_d = (new EnumMobType[] { + everything, mobs, players + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumMovingObjectType.java b/src/main/java/net/minecraft/src/EnumMovingObjectType.java new file mode 100644 index 0000000..6226473 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumMovingObjectType.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumMovingObjectType extends CompatEnum +{ + + public static EnumMovingObjectType[] values() + { + return (EnumMovingObjectType[])field_21178_c.clone(); + } + + public static EnumMovingObjectType valueOf(String s) + { + return (EnumMovingObjectType)CompatEnum.valueOf(EnumMovingObjectType.class, s); + } + + private EnumMovingObjectType(String s, int i) + { + super(s, i); + } + + public static final EnumMovingObjectType TILE; + public static final EnumMovingObjectType ENTITY; + private static final EnumMovingObjectType field_21178_c[]; /* synthetic field */ + + static + { + TILE = new EnumMovingObjectType("TILE", 0); + ENTITY = new EnumMovingObjectType("ENTITY", 1); + field_21178_c = (new EnumMovingObjectType[] { + TILE, ENTITY + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumOS1.java b/src/main/java/net/minecraft/src/EnumOS1.java new file mode 100644 index 0000000..5c57d74 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOS1.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +final class EnumOS1 extends CompatEnum +{ + + public static EnumOS1[] values() + { + return (EnumOS1[])field_6525_f.clone(); + } + + public static EnumOS1 valueOf(String s) + { + return (EnumOS1)CompatEnum.valueOf(EnumOS1.class, s); + } + + private EnumOS1(String s, int i) + { + super(s, i); + } + + public static final EnumOS1 linux; + public static final EnumOS1 solaris; + public static final EnumOS1 windows; + public static final EnumOS1 macos; + public static final EnumOS1 unknown; + private static final EnumOS1 field_6525_f[]; /* synthetic field */ + + static + { + linux = new EnumOS1("linux", 0); + solaris = new EnumOS1("solaris", 1); + windows = new EnumOS1("windows", 2); + macos = new EnumOS1("macos", 3); + unknown = new EnumOS1("unknown", 4); + field_6525_f = (new EnumOS1[] { + linux, solaris, windows, macos, unknown + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumOS2.java b/src/main/java/net/minecraft/src/EnumOS2.java new file mode 100644 index 0000000..80af9ad --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOS2.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.lax1dude.eaglercraft.compat.CompatEnum; +import net.minecraft.client.Minecraft; + +public final class EnumOS2 extends CompatEnum +{ + + public static EnumOS2[] values() + { + return (EnumOS2[])field_6511_f.clone(); + } + + public static EnumOS2 valueOf(String s) + { + return (EnumOS2)CompatEnum.valueOf(EnumOS2.class, s); + } + + private EnumOS2(String s, int i) + { + super(s, i); + } + + public static final EnumOS2 linux; + public static final EnumOS2 solaris; + public static final EnumOS2 windows; + public static final EnumOS2 macos; + public static final EnumOS2 unknown; + private static final EnumOS2 field_6511_f[]; /* synthetic field */ + + static + { + linux = new EnumOS2("linux", 0); + solaris = new EnumOS2("solaris", 1); + windows = new EnumOS2("windows", 2); + macos = new EnumOS2("macos", 3); + unknown = new EnumOS2("unknown", 4); + field_6511_f = (new EnumOS2[] { + linux, solaris, windows, macos, unknown + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumOSMappingHelper.java b/src/main/java/net/minecraft/src/EnumOSMappingHelper.java new file mode 100644 index 0000000..39257ea --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOSMappingHelper.java @@ -0,0 +1,37 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +public class EnumOSMappingHelper +{ + + public static final int enumOSMappingArray[]; /* synthetic field */ + + static + { + enumOSMappingArray = new int[EnumOS2.values().length]; + try + { + enumOSMappingArray[EnumOS2.linux.ordinal()] = 1; + } + catch(NoSuchFieldError nosuchfielderror) { } + try + { + enumOSMappingArray[EnumOS2.solaris.ordinal()] = 2; + } + catch(NoSuchFieldError nosuchfielderror1) { } + try + { + enumOSMappingArray[EnumOS2.windows.ordinal()] = 3; + } + catch(NoSuchFieldError nosuchfielderror2) { } + try + { + enumOSMappingArray[EnumOS2.macos.ordinal()] = 4; + } + catch(NoSuchFieldError nosuchfielderror3) { } + } +} diff --git a/src/main/java/net/minecraft/src/EnumOptions.java b/src/main/java/net/minecraft/src/EnumOptions.java new file mode 100644 index 0000000..0ed0dd5 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOptions.java @@ -0,0 +1,100 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumOptions extends CompatEnum +{ + + public static EnumOptions[] values() + { + return (EnumOptions[])field_20141_n.clone(); + } + + public static EnumOptions valueOf(String s) + { + return (EnumOptions)CompatEnum.valueOf(EnumOptions.class, s); + } + + public static EnumOptions func_20137_a(int i) + { + EnumOptions aenumoptions[] = values(); + int j = aenumoptions.length; + for(int k = 0; k < j; k++) + { + EnumOptions enumoptions = aenumoptions[k]; + if(enumoptions.returnEnumOrdinal() == i) + { + return enumoptions; + } + } + + return null; + } + + private EnumOptions(String s, int i, String s1, boolean flag, boolean flag1) + { + super(s, i); + enumString = s1; + enumFloat = flag; + enumBoolean = flag1; + } + + public boolean getEnumFloat() + { + return enumFloat; + } + + public boolean getEnumBoolean() + { + return enumBoolean; + } + + public int returnEnumOrdinal() + { + return ordinal(); + } + + public String getEnumString() + { + return enumString; + } + + public static final EnumOptions MUSIC; + public static final EnumOptions SOUND; + public static final EnumOptions INVERT_MOUSE; + public static final EnumOptions SENSITIVITY; + public static final EnumOptions RENDER_DISTANCE; + public static final EnumOptions VIEW_BOBBING; + public static final EnumOptions ANAGLYPH; + public static final EnumOptions LIMIT_FRAMERATE; + public static final EnumOptions DIFFICULTY; + public static final EnumOptions GRAPHICS; + public static final EnumOptions AMBIENT_OCCLUSION; + private final boolean enumFloat; + private final boolean enumBoolean; + private final String enumString; + private static final EnumOptions field_20141_n[]; /* synthetic field */ + + static + { + MUSIC = new EnumOptions("MUSIC", 0, "options.music", true, false); + SOUND = new EnumOptions("SOUND", 1, "options.sound", true, false); + INVERT_MOUSE = new EnumOptions("INVERT_MOUSE", 2, "options.invertMouse", false, true); + SENSITIVITY = new EnumOptions("SENSITIVITY", 3, "options.sensitivity", true, false); + RENDER_DISTANCE = new EnumOptions("RENDER_DISTANCE", 4, "options.renderDistance", false, false); + VIEW_BOBBING = new EnumOptions("VIEW_BOBBING", 5, "options.viewBobbing", false, true); + ANAGLYPH = new EnumOptions("ANAGLYPH", 6, "options.anaglyph", false, true); + LIMIT_FRAMERATE = new EnumOptions("LIMIT_FRAMERATE", 7, "options.limitFramerate", false, true); + DIFFICULTY = new EnumOptions("DIFFICULTY", 8, "options.difficulty", false, false); + GRAPHICS = new EnumOptions("GRAPHICS", 9, "options.graphics", false, false); + AMBIENT_OCCLUSION = new EnumOptions("AMBIENT_OCCLUSION", 10, "options.ao", false, true); + field_20141_n = (new EnumOptions[] { + MUSIC, SOUND, INVERT_MOUSE, SENSITIVITY, RENDER_DISTANCE, VIEW_BOBBING, ANAGLYPH, LIMIT_FRAMERATE, DIFFICULTY, GRAPHICS, + AMBIENT_OCCLUSION + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumOptionsMappingHelper.java b/src/main/java/net/minecraft/src/EnumOptionsMappingHelper.java new file mode 100644 index 0000000..4a03026 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumOptionsMappingHelper.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class EnumOptionsMappingHelper +{ + + static final int enumOptionsMappingHelperArray[]; /* synthetic field */ + + static + { + enumOptionsMappingHelperArray = new int[EnumOptions.values().length]; + try + { + enumOptionsMappingHelperArray[EnumOptions.INVERT_MOUSE.ordinal()] = 1; + } + catch(NoSuchFieldError nosuchfielderror) { } + try + { + enumOptionsMappingHelperArray[EnumOptions.VIEW_BOBBING.ordinal()] = 2; + } + catch(NoSuchFieldError nosuchfielderror1) { } + try + { + enumOptionsMappingHelperArray[EnumOptions.ANAGLYPH.ordinal()] = 3; + } + catch(NoSuchFieldError nosuchfielderror2) { } + try + { + enumOptionsMappingHelperArray[EnumOptions.LIMIT_FRAMERATE.ordinal()] = 4; + } + catch(NoSuchFieldError nosuchfielderror3) { } + try + { + enumOptionsMappingHelperArray[EnumOptions.AMBIENT_OCCLUSION.ordinal()] = 5; + } + catch(NoSuchFieldError nosuchfielderror4) { } + } +} diff --git a/src/main/java/net/minecraft/src/EnumSkyBlock.java b/src/main/java/net/minecraft/src/EnumSkyBlock.java new file mode 100644 index 0000000..12029c6 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumSkyBlock.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumSkyBlock extends CompatEnum +{ + + public static EnumSkyBlock[] values() + { + return (EnumSkyBlock[])field_1721_d.clone(); + } + + public static EnumSkyBlock valueOf(String s) + { + return (EnumSkyBlock)CompatEnum.valueOf(EnumSkyBlock.class, s); + } + + private EnumSkyBlock(String s, int i, int j) + { + super(s, i); + field_1722_c = j; + } + + public static final EnumSkyBlock Sky; + public static final EnumSkyBlock Block; + public final int field_1722_c; + private static final EnumSkyBlock field_1721_d[]; /* synthetic field */ + + static + { + Sky = new EnumSkyBlock("Sky", 0, 15); + Block = new EnumSkyBlock("Block", 1, 0); + field_1721_d = (new EnumSkyBlock[] { + Sky, Block + }); + } +} diff --git a/src/main/java/net/minecraft/src/EnumToolMaterial.java b/src/main/java/net/minecraft/src/EnumToolMaterial.java new file mode 100644 index 0000000..b306e62 --- /dev/null +++ b/src/main/java/net/minecraft/src/EnumToolMaterial.java @@ -0,0 +1,73 @@ +package net.minecraft.src; +import net.lax1dude.eaglercraft.compat.CompatEnum; + +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class EnumToolMaterial extends CompatEnum +{ + + public static EnumToolMaterial[] values() + { + return (EnumToolMaterial[])field_21209_j.clone(); + } + + public static EnumToolMaterial valueOf(String s) + { + return (EnumToolMaterial)CompatEnum.valueOf(EnumToolMaterial.class, s); + } + + private EnumToolMaterial(String s, int i, int j, int k, float f, int l) + { + super(s, i); + harvestLevel = j; + maxUses = k; + efficiencyOnProperMaterial = f; + damageVsEntity = l; + } + + public int getMaxUses() + { + return maxUses; + } + + public float getEfficiencyOnProperMaterial() + { + return efficiencyOnProperMaterial; + } + + public int getDamageVsEntity() + { + return damageVsEntity; + } + + public int getHarvestLevel() + { + return harvestLevel; + } + + public static final EnumToolMaterial WOOD; + public static final EnumToolMaterial STONE; + public static final EnumToolMaterial IRON; + public static final EnumToolMaterial EMERALD; + public static final EnumToolMaterial GOLD; + private final int harvestLevel; + private final int maxUses; + private final float efficiencyOnProperMaterial; + private final int damageVsEntity; + private static final EnumToolMaterial field_21209_j[]; /* synthetic field */ + + static + { + WOOD = new EnumToolMaterial("WOOD", 0, 0, 59, 2.0F, 0); + STONE = new EnumToolMaterial("STONE", 1, 1, 131, 4F, 1); + IRON = new EnumToolMaterial("IRON", 2, 2, 250, 6F, 2); + EMERALD = new EnumToolMaterial("EMERALD", 3, 3, 1561, 8F, 3); + GOLD = new EnumToolMaterial("GOLD", 4, 0, 32, 12F, 0); + field_21209_j = (new EnumToolMaterial[] { + WOOD, STONE, IRON, EMERALD, GOLD + }); + } +} diff --git a/src/main/java/net/minecraft/src/Explosion.java b/src/main/java/net/minecraft/src/Explosion.java new file mode 100644 index 0000000..d8351c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/Explosion.java @@ -0,0 +1,186 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class Explosion +{ + + public Explosion(World world, Entity entity, double d, double d1, double d2, float f) + { + field_12257_a = false; + ExplosionRNG = new Random(); + destroyedBlockPositions = new HashSet(); + worldObj = world; + exploder = entity; + explosionSize = f; + explosionX = d; + explosionY = d1; + explosionZ = d2; + } + + public void func_12248_a() + { + float f = explosionSize; + int i = 16; + for(int j = 0; j < i; j++) + { + for(int l = 0; l < i; l++) + { +label0: + for(int j1 = 0; j1 < i; j1++) + { + if(j != 0 && j != i - 1 && l != 0 && l != i - 1 && j1 != 0 && j1 != i - 1) + { + continue; + } + double d = ((float)j / ((float)i - 1.0F)) * 2.0F - 1.0F; + double d1 = ((float)l / ((float)i - 1.0F)) * 2.0F - 1.0F; + double d2 = ((float)j1 / ((float)i - 1.0F)) * 2.0F - 1.0F; + double d3 = Math.sqrt(d * d + d1 * d1 + d2 * d2); + d /= d3; + d1 /= d3; + d2 /= d3; + float f1 = explosionSize * (0.7F + worldObj.rand.nextFloat() * 0.6F); + double d5 = explosionX; + double d7 = explosionY; + double d9 = explosionZ; + float f2 = 0.3F; + do + { + if(f1 <= 0.0F) + { + continue label0; + } + int j4 = MathHelper.floor_double(d5); + int k4 = MathHelper.floor_double(d7); + int l4 = MathHelper.floor_double(d9); + int i5 = worldObj.getBlockId(j4, k4, l4); + if(i5 > 0) + { + f1 -= (Block.blocksList[i5].getExplosionResistance(exploder) + 0.3F) * f2; + } + if(f1 > 0.0F) + { + destroyedBlockPositions.add(new ChunkPosition(j4, k4, l4)); + } + d5 += d * (double)f2; + d7 += d1 * (double)f2; + d9 += d2 * (double)f2; + f1 -= f2 * 0.75F; + } while(true); + } + + } + + } + + explosionSize *= 2.0F; + int k = MathHelper.floor_double(explosionX - (double)explosionSize - 1.0D); + int i1 = MathHelper.floor_double(explosionX + (double)explosionSize + 1.0D); + int k1 = MathHelper.floor_double(explosionY - (double)explosionSize - 1.0D); + int l1 = MathHelper.floor_double(explosionY + (double)explosionSize + 1.0D); + int i2 = MathHelper.floor_double(explosionZ - (double)explosionSize - 1.0D); + int j2 = MathHelper.floor_double(explosionZ + (double)explosionSize + 1.0D); + List list = worldObj.getEntitiesWithinAABBExcludingEntity(exploder, AxisAlignedBB.getBoundingBoxFromPool(k, k1, i2, i1, l1, j2)); + Vec3D vec3d = Vec3D.createVector(explosionX, explosionY, explosionZ); + for(int k2 = 0; k2 < list.size(); k2++) + { + Entity entity = (Entity)list.get(k2); + double d4 = entity.getDistance(explosionX, explosionY, explosionZ) / (double)explosionSize; + if(d4 <= 1.0D) + { + double d6 = entity.posX - explosionX; + double d8 = entity.posY - explosionY; + double d10 = entity.posZ - explosionZ; + double d11 = MathHelper.sqrt_double(d6 * d6 + d8 * d8 + d10 * d10); + d6 /= d11; + d8 /= d11; + d10 /= d11; + double d12 = worldObj.func_675_a(vec3d, entity.boundingBox); + double d13 = (1.0D - d4) * d12; + entity.attackEntityFrom(exploder, (int)(((d13 * d13 + d13) / 2D) * 8D * (double)explosionSize + 1.0D)); + double d14 = d13; + entity.motionX += d6 * d14; + entity.motionY += d8 * d14; + entity.motionZ += d10 * d14; + } + } + + explosionSize = f; + ArrayList arraylist = new ArrayList(); + arraylist.addAll(destroyedBlockPositions); + if(field_12257_a) + { + for(int l2 = arraylist.size() - 1; l2 >= 0; l2--) + { + ChunkPosition chunkposition = (ChunkPosition)arraylist.get(l2); + int i3 = chunkposition.x; + int j3 = chunkposition.y; + int k3 = chunkposition.z; + int l3 = worldObj.getBlockId(i3, j3, k3); + int i4 = worldObj.getBlockId(i3, j3 - 1, k3); + if(l3 == 0 && Block.opaqueCubeLookup[i4] && ExplosionRNG.nextInt(3) == 0) + { + worldObj.setBlockWithNotify(i3, j3, k3, Block.fire.blockID); + } + } + + } + } + + public void func_12247_b() + { + worldObj.playSoundEffect(explosionX, explosionY, explosionZ, "random.explode", 4F, (1.0F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.2F) * 0.7F); + ArrayList arraylist = new ArrayList(); + arraylist.addAll(destroyedBlockPositions); + for(int i = arraylist.size() - 1; i >= 0; i--) + { + ChunkPosition chunkposition = (ChunkPosition)arraylist.get(i); + int j = chunkposition.x; + int k = chunkposition.y; + int l = chunkposition.z; + int i1 = worldObj.getBlockId(j, k, l); + for(int j1 = 0; j1 < 1; j1++) + { + double d = (float)j + worldObj.rand.nextFloat(); + double d1 = (float)k + worldObj.rand.nextFloat(); + double d2 = (float)l + worldObj.rand.nextFloat(); + double d3 = d - explosionX; + double d4 = d1 - explosionY; + double d5 = d2 - explosionZ; + double d6 = MathHelper.sqrt_double(d3 * d3 + d4 * d4 + d5 * d5); + d3 /= d6; + d4 /= d6; + d5 /= d6; + double d7 = 0.5D / (d6 / (double)explosionSize + 0.10000000000000001D); + d7 *= worldObj.rand.nextFloat() * worldObj.rand.nextFloat() + 0.3F; + d3 *= d7; + d4 *= d7; + d5 *= d7; + worldObj.spawnParticle("explode", (d + explosionX * 1.0D) / 2D, (d1 + explosionY * 1.0D) / 2D, (d2 + explosionZ * 1.0D) / 2D, d3, d4, d5); + worldObj.spawnParticle("smoke", d, d1, d2, d3, d4, d5); + } + + if(i1 > 0) + { + Block.blocksList[i1].dropBlockAsItemWithChance(worldObj, j, k, l, worldObj.getBlockMetadata(j, k, l), 0.3F); + worldObj.setBlockWithNotify(j, k, l, 0); + Block.blocksList[i1].onBlockDestroyedByExplosion(worldObj, j, k, l); + } + } + + } + + public boolean field_12257_a; + private Random ExplosionRNG; + private World worldObj; + public double explosionX; + public double explosionY; + public double explosionZ; + public Entity exploder; + public float explosionSize; + public Set destroyedBlockPositions; +} diff --git a/src/main/java/net/minecraft/src/FileMatcher.java b/src/main/java/net/minecraft/src/FileMatcher.java new file mode 100644 index 0000000..226975b --- /dev/null +++ b/src/main/java/net/minecraft/src/FileMatcher.java @@ -0,0 +1,67 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class FileMatcher + implements Comparable +{ + + public FileMatcher(File file) + { + field_22326_a = file; + Matcher matcher = ChunkFilePattern.field_22189_a.matcher(file.getName()); + if(matcher.matches()) + { + field_22325_b = Integer.parseInt(matcher.group(1), 36); + field_22327_c = Integer.parseInt(matcher.group(2), 36); + } else + { + field_22325_b = 0; + field_22327_c = 0; + } + } + + public int func_22322_a(FileMatcher filematcher) + { + int i = field_22325_b >> 5; + int j = filematcher.field_22325_b >> 5; + if(i == j) + { + int k = field_22327_c >> 5; + int l = filematcher.field_22327_c >> 5; + return k - l; + } else + { + return i - j; + } + } + + public File func_22324_a() + { + return field_22326_a; + } + + public int func_22323_b() + { + return field_22325_b; + } + + public int func_22321_c() + { + return field_22327_c; + } + + public int compareTo(Object obj) + { + return func_22322_a((FileMatcher)obj); + } + + private final File field_22326_a; + private final int field_22325_b; + private final int field_22327_c; +} diff --git a/src/main/java/net/minecraft/src/FontAllowedCharacters.java b/src/main/java/net/minecraft/src/FontAllowedCharacters.java new file mode 100644 index 0000000..49bdcdd --- /dev/null +++ b/src/main/java/net/minecraft/src/FontAllowedCharacters.java @@ -0,0 +1,47 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class FontAllowedCharacters +{ + + public FontAllowedCharacters() + { + } + + private static String getAllowedCharacters() + { + String s = ""; + try + { + BufferedReader bufferedreader = new BufferedReader(new InputStreamReader((FontAllowedCharacters.class).getResourceAsStream("/font.txt"), "UTF-8")); + String s1 = ""; + do + { + String s2; + if((s2 = bufferedreader.readLine()) == null) + { + break; + } + if(!s2.startsWith("#")) + { + s = (new StringBuilder()).append(s).append(s2).toString(); + } + } while(true); + bufferedreader.close(); + } + catch(Exception exception) { } + return s; + } + + public static final String allowedCharacters = getAllowedCharacters(); + public static final char field_22286_b[] = { + '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', + '<', '>', '|', '"', ':' + }; + +} diff --git a/src/main/java/net/minecraft/src/FontRenderer.java b/src/main/java/net/minecraft/src/FontRenderer.java new file mode 100644 index 0000000..71729bc --- /dev/null +++ b/src/main/java/net/minecraft/src/FontRenderer.java @@ -0,0 +1,226 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.IntBuffer; +import javax.imageio.ImageIO; +import org.lwjgl.opengl.GL11; + +public class FontRenderer +{ + + public FontRenderer(GameSettings gamesettings, String s, RenderEngine renderengine) + { + charWidth = new int[256]; + fontTextureName = 0; + buffer = GLAllocation.createDirectIntBuffer(1024 /*GL_FRONT_LEFT*/); + BufferedImage bufferedimage; + try + { + bufferedimage = ImageIO.read((RenderEngine.class).getResourceAsStream(s)); + } + catch(IOException ioexception) + { + throw new RuntimeException(ioexception); + } + int i = bufferedimage.getWidth(); + int j = bufferedimage.getHeight(); + int ai[] = new int[i * j]; + bufferedimage.getRGB(0, 0, i, j, ai, 0, i); + for(int k = 0; k < 256; k++) + { + int l = k % 16; + int k1 = k / 16; + int j2 = 7; + do + { + if(j2 < 0) + { + break; + } + int i3 = l * 8 + j2; + boolean flag = true; + for(int l3 = 0; l3 < 8 && flag; l3++) + { + int i4 = (k1 * 8 + l3) * i; + int k4 = ai[i3 + i4] & 0xff; + if(k4 > 0) + { + flag = false; + } + } + + if(!flag) + { + break; + } + j2--; + } while(true); + if(k == 32) + { + j2 = 2; + } + charWidth[k] = j2 + 2; + } + + fontTextureName = renderengine.allocateAndSetupTexture(bufferedimage); + fontDisplayLists = GLAllocation.generateDisplayLists(288); + Tessellator tessellator = Tessellator.instance; + for(int i1 = 0; i1 < 256; i1++) + { + GL11.glNewList(fontDisplayLists + i1, 4864 /*GL_COMPILE*/); + tessellator.startDrawingQuads(); + int l1 = (i1 % 16) * 8; + int k2 = (i1 / 16) * 8; + float f = 7.99F; + float f1 = 0.0F; + float f2 = 0.0F; + tessellator.addVertexWithUV(0.0D, 0.0F + f, 0.0D, (float)l1 / 128F + f1, ((float)k2 + f) / 128F + f2); + tessellator.addVertexWithUV(0.0F + f, 0.0F + f, 0.0D, ((float)l1 + f) / 128F + f1, ((float)k2 + f) / 128F + f2); + tessellator.addVertexWithUV(0.0F + f, 0.0D, 0.0D, ((float)l1 + f) / 128F + f1, (float)k2 / 128F + f2); + tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, (float)l1 / 128F + f1, (float)k2 / 128F + f2); + tessellator.draw(); + GL11.glTranslatef(charWidth[i1], 0.0F, 0.0F); + GL11.glEndList(); + } + + for(int j1 = 0; j1 < 32; j1++) + { + int i2 = (j1 >> 3 & 1) * 85; + int l2 = (j1 >> 2 & 1) * 170 + i2; + int j3 = (j1 >> 1 & 1) * 170 + i2; + int k3 = (j1 >> 0 & 1) * 170 + i2; + if(j1 == 6) + { + l2 += 85; + } + boolean flag1 = j1 >= 16; + if(gamesettings.anaglyph) + { + int j4 = (l2 * 30 + j3 * 59 + k3 * 11) / 100; + int l4 = (l2 * 30 + j3 * 70) / 100; + int i5 = (l2 * 30 + k3 * 70) / 100; + l2 = j4; + j3 = l4; + k3 = i5; + } + if(flag1) + { + l2 /= 4; + j3 /= 4; + k3 /= 4; + } + GL11.glNewList(fontDisplayLists + 256 + j1, 4864 /*GL_COMPILE*/); + GL11.glColor3f((float)l2 / 255F, (float)j3 / 255F, (float)k3 / 255F); + GL11.glEndList(); + } + + } + + public void drawStringWithShadow(String s, int i, int j, int k) + { + renderString(s, i + 1, j + 1, k, true); + drawString(s, i, j, k); + } + + public void drawString(String s, int i, int j, int k) + { + renderString(s, i, j, k, false); + } + + public void renderString(String s, int i, int j, int k, boolean flag) + { + if(s == null) + { + return; + } + if(flag) + { + int l = k & 0xff000000; + k = (k & 0xfcfcfc) >> 2; + k += l; + } + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, fontTextureName); + float f = (float)(k >> 16 & 0xff) / 255F; + float f1 = (float)(k >> 8 & 0xff) / 255F; + float f2 = (float)(k & 0xff) / 255F; + float f3 = (float)(k >> 24 & 0xff) / 255F; + if(f3 == 0.0F) + { + f3 = 1.0F; + } + GL11.glColor4f(f, f1, f2, f3); + buffer.clear(); + GL11.glPushMatrix(); + GL11.glTranslatef(i, j, 0.0F); + for(int i1 = 0; i1 < s.length(); i1++) + { + for(; s.length() > i1 + 1 && s.charAt(i1) == '\247'; i1 += 2) + { + int j1 = "0123456789abcdef".indexOf(s.toLowerCase().charAt(i1 + 1)); + if(j1 < 0 || j1 > 15) + { + j1 = 15; + } + buffer.put(fontDisplayLists + 256 + j1 + (flag ? 16 : 0)); + if(buffer.remaining() == 0) + { + buffer.flip(); + GL11.glCallLists(buffer); + buffer.clear(); + } + } + + if(i1 < s.length()) + { + int k1 = FontAllowedCharacters.allowedCharacters.indexOf(s.charAt(i1)); + if(k1 >= 0) + { + buffer.put(fontDisplayLists + k1 + 32); + } + } + if(buffer.remaining() == 0) + { + buffer.flip(); + GL11.glCallLists(buffer); + buffer.clear(); + } + } + + buffer.flip(); + GL11.glCallLists(buffer); + GL11.glPopMatrix(); + } + + public int getStringWidth(String s) + { + if(s == null) + { + return 0; + } + int i = 0; + for(int j = 0; j < s.length(); j++) + { + if(s.charAt(j) == '\247') + { + j++; + continue; + } + int k = FontAllowedCharacters.allowedCharacters.indexOf(s.charAt(j)); + if(k >= 0) + { + i += charWidth[k + 32]; + } + } + + return i; + } + + private int charWidth[]; + public int fontTextureName; + private int fontDisplayLists; + private IntBuffer buffer; +} diff --git a/src/main/java/net/minecraft/src/Frustrum.java b/src/main/java/net/minecraft/src/Frustrum.java new file mode 100644 index 0000000..9cc9d92 --- /dev/null +++ b/src/main/java/net/minecraft/src/Frustrum.java @@ -0,0 +1,37 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class Frustrum + implements ICamera +{ + + public Frustrum() + { + clippingHelper = ClippingHelperImplementation.getInstance(); + } + + public void setPosition(double d, double d1, double d2) + { + xPosition = d; + yPosition = d1; + zPosition = d2; + } + + public boolean isBoxInFrustum(double d, double d1, double d2, double d3, double d4, double d5) + { + return clippingHelper.isBoxInFrustum(d - xPosition, d1 - yPosition, d2 - zPosition, d3 - xPosition, d4 - yPosition, d5 - zPosition); + } + + public boolean isBoundingBoxInFrustum(AxisAlignedBB axisalignedbb) + { + return isBoxInFrustum(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ, axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + } + + private ClippingHelper clippingHelper; + private double xPosition; + private double yPosition; + private double zPosition; +} diff --git a/src/main/java/net/minecraft/src/FurnaceRecipes.java b/src/main/java/net/minecraft/src/FurnaceRecipes.java new file mode 100644 index 0000000..a2220b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/FurnaceRecipes.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.HashMap; +import java.util.Map; + +public class FurnaceRecipes +{ + + public static final FurnaceRecipes smelting() + { + return smeltingBase; + } + + private FurnaceRecipes() + { + smeltingList = new HashMap(); + addSmelting(Block.oreIron.blockID, new ItemStack(Item.ingotIron)); + addSmelting(Block.oreGold.blockID, new ItemStack(Item.ingotGold)); + addSmelting(Block.oreDiamond.blockID, new ItemStack(Item.diamond)); + addSmelting(Block.sand.blockID, new ItemStack(Block.glass)); + addSmelting(Item.porkRaw.shiftedIndex, new ItemStack(Item.porkCooked)); + addSmelting(Item.fishRaw.shiftedIndex, new ItemStack(Item.fishCooked)); + addSmelting(Block.cobblestone.blockID, new ItemStack(Block.stone)); + addSmelting(Item.clay.shiftedIndex, new ItemStack(Item.brick)); + addSmelting(Block.cactus.blockID, new ItemStack(Item.dyePowder, 1, 2)); + addSmelting(Block.wood.blockID, new ItemStack(Item.coal, 1, 1)); + } + + public void addSmelting(int i, ItemStack itemstack) + { + smeltingList.put(Integer.valueOf(i), itemstack); + } + + public ItemStack getSmeltingResult(int i) + { + return (ItemStack)smeltingList.get(Integer.valueOf(i)); + } + + private static final FurnaceRecipes smeltingBase = new FurnaceRecipes(); + private Map smeltingList; + +} diff --git a/src/main/java/net/minecraft/src/GLAllocation.java b/src/main/java/net/minecraft/src/GLAllocation.java new file mode 100644 index 0000000..715e6ec --- /dev/null +++ b/src/main/java/net/minecraft/src/GLAllocation.java @@ -0,0 +1,76 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.nio.*; +import java.util.ArrayList; +import java.util.List; +import org.lwjgl.opengl.GL11; + +public class GLAllocation +{ + + public GLAllocation() + { + } + + public static synchronized int generateDisplayLists(int i) + { + int j = GL11.glGenLists(i); + displayLists.add(Integer.valueOf(j)); + displayLists.add(Integer.valueOf(i)); + return j; + } + + public static synchronized void generateTextureNames(IntBuffer intbuffer) + { + GL11.glGenTextures(intbuffer); + for(int i = intbuffer.position(); i < intbuffer.limit(); i++) + { + textureNames.add(Integer.valueOf(intbuffer.get(i))); + } + + } + + public static synchronized void deleteTexturesAndDisplayLists() + { + for(int i = 0; i < displayLists.size(); i += 2) + { + GL11.glDeleteLists(((Integer)displayLists.get(i)).intValue(), ((Integer)displayLists.get(i + 1)).intValue()); + } + + IntBuffer intbuffer = createDirectIntBuffer(textureNames.size()); + intbuffer.flip(); + GL11.glDeleteTextures(intbuffer); + for(int j = 0; j < textureNames.size(); j++) + { + intbuffer.put(((Integer)textureNames.get(j)).intValue()); + } + + intbuffer.flip(); + GL11.glDeleteTextures(intbuffer); + displayLists.clear(); + textureNames.clear(); + } + + public static synchronized ByteBuffer createDirectByteBuffer(int i) + { + ByteBuffer bytebuffer = ByteBuffer.allocateDirect(i).order(ByteOrder.nativeOrder()); + return bytebuffer; + } + + public static IntBuffer createDirectIntBuffer(int i) + { + return createDirectByteBuffer(i << 2).asIntBuffer(); + } + + public static FloatBuffer createDirectFloatBuffer(int i) + { + return createDirectByteBuffer(i << 2).asFloatBuffer(); + } + + private static List displayLists = new ArrayList(); + private static List textureNames = new ArrayList(); + +} diff --git a/src/main/java/net/minecraft/src/GameSettings.java b/src/main/java/net/minecraft/src/GameSettings.java new file mode 100644 index 0000000..6882aec --- /dev/null +++ b/src/main/java/net/minecraft/src/GameSettings.java @@ -0,0 +1,443 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Keyboard; + +public class GameSettings +{ + + public GameSettings(Minecraft minecraft, File file) + { + musicVolume = 1.0F; + soundVolume = 1.0F; + mouseSensitivity = 0.5F; + invertMouse = false; + renderDistance = 0; + viewBobbing = true; + anaglyph = false; + limitFramerate = false; + fancyGraphics = true; + field_22278_j = true; + skin = "Default"; + keyBindForward = new KeyBinding("key.forward", 17); + keyBindLeft = new KeyBinding("key.left", 30); + keyBindBack = new KeyBinding("key.back", 31); + keyBindRight = new KeyBinding("key.right", 32); + keyBindJump = new KeyBinding("key.jump", 57); + keyBindInventory = new KeyBinding("key.inventory", 23); + keyBindDrop = new KeyBinding("key.drop", 16); + keyBindChat = new KeyBinding("key.chat", 20); + keyBindToggleFog = new KeyBinding("key.fog", 33); + keyBindSneak = new KeyBinding("key.sneak", 42); + keyBindings = (new KeyBinding[] { + keyBindForward, keyBindLeft, keyBindBack, keyBindRight, keyBindJump, keyBindSneak, keyBindDrop, keyBindInventory, keyBindChat, keyBindToggleFog + }); + difficulty = 2; + field_22277_y = false; + thirdPersonView = false; + showDebugInfo = false; + lastServer = ""; + field_22275_C = false; + field_22274_D = false; + field_22273_E = false; + field_22272_F = 1.0F; + field_22271_G = 1.0F; + mc = minecraft; + optionsFile = new File(file, "options.txt"); + loadOptions(); + } + + public GameSettings() + { + musicVolume = 1.0F; + soundVolume = 1.0F; + mouseSensitivity = 0.5F; + invertMouse = false; + renderDistance = 0; + viewBobbing = true; + anaglyph = false; + limitFramerate = false; + fancyGraphics = true; + field_22278_j = true; + skin = "Default"; + keyBindForward = new KeyBinding("key.forward", 17); + keyBindLeft = new KeyBinding("key.left", 30); + keyBindBack = new KeyBinding("key.back", 31); + keyBindRight = new KeyBinding("key.right", 32); + keyBindJump = new KeyBinding("key.jump", 57); + keyBindInventory = new KeyBinding("key.inventory", 23); + keyBindDrop = new KeyBinding("key.drop", 16); + keyBindChat = new KeyBinding("key.chat", 20); + keyBindToggleFog = new KeyBinding("key.fog", 33); + keyBindSneak = new KeyBinding("key.sneak", 42); + keyBindings = (new KeyBinding[] { + keyBindForward, keyBindLeft, keyBindBack, keyBindRight, keyBindJump, keyBindSneak, keyBindDrop, keyBindInventory, keyBindChat, keyBindToggleFog + }); + difficulty = 2; + field_22277_y = false; + thirdPersonView = false; + showDebugInfo = false; + lastServer = ""; + field_22275_C = false; + field_22274_D = false; + field_22273_E = false; + field_22272_F = 1.0F; + field_22271_G = 1.0F; + } + + public String getKeyBindingDescription(int i) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + return stringtranslate.translateKey(keyBindings[i].keyDescription); + } + + public String getOptionDisplayString(int i) + { + return Keyboard.getKeyName(keyBindings[i].keyCode); + } + + public void setKeyBinding(int i, int j) + { + keyBindings[i].keyCode = j; + saveOptions(); + } + + public void setOptionFloatValue(EnumOptions enumoptions, float f) + { + if(enumoptions == EnumOptions.MUSIC) + { + musicVolume = f; + mc.sndManager.onSoundOptionsChanged(); + } + if(enumoptions == EnumOptions.SOUND) + { + soundVolume = f; + mc.sndManager.onSoundOptionsChanged(); + } + if(enumoptions == EnumOptions.SENSITIVITY) + { + mouseSensitivity = f; + } + } + + public void setOptionValue(EnumOptions enumoptions, int i) + { + if(enumoptions == EnumOptions.INVERT_MOUSE) + { + invertMouse = !invertMouse; + } + if(enumoptions == EnumOptions.RENDER_DISTANCE) + { + renderDistance = renderDistance + i & 3; + } + if(enumoptions == EnumOptions.VIEW_BOBBING) + { + viewBobbing = !viewBobbing; + } + if(enumoptions == EnumOptions.ANAGLYPH) + { + anaglyph = !anaglyph; + mc.renderEngine.refreshTextures(); + } + if(enumoptions == EnumOptions.LIMIT_FRAMERATE) + { + limitFramerate = !limitFramerate; + } + if(enumoptions == EnumOptions.DIFFICULTY) + { + difficulty = difficulty + i & 3; + } + if(enumoptions == EnumOptions.GRAPHICS) + { + fancyGraphics = !fancyGraphics; + mc.renderGlobal.loadRenderers(); + } + if(enumoptions == EnumOptions.AMBIENT_OCCLUSION) + { + field_22278_j = !field_22278_j; + mc.renderGlobal.loadRenderers(); + } + saveOptions(); + } + + public float getOptionFloatValue(EnumOptions enumoptions) + { + if(enumoptions == EnumOptions.MUSIC) + { + return musicVolume; + } + if(enumoptions == EnumOptions.SOUND) + { + return soundVolume; + } + if(enumoptions == EnumOptions.SENSITIVITY) + { + return mouseSensitivity; + } else + { + return 0.0F; + } + } + + public boolean getOptionOrdinalValue(EnumOptions enumoptions) + { + switch(EnumOptionsMappingHelper.enumOptionsMappingHelperArray[enumoptions.ordinal()]) + { + case 1: // '\001' + return invertMouse; + + case 2: // '\002' + return viewBobbing; + + case 3: // '\003' + return anaglyph; + + case 4: // '\004' + return limitFramerate; + + case 5: // '\005' + return field_22278_j; + } + return false; + } + + public String getKeyBinding(EnumOptions enumoptions) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + String s = (new StringBuilder()).append(stringtranslate.translateKey(enumoptions.getEnumString())).append(": ").toString(); + if(enumoptions.getEnumFloat()) + { + float f = getOptionFloatValue(enumoptions); + if(enumoptions == EnumOptions.SENSITIVITY) + { + if(f == 0.0F) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.sensitivity.min")).toString(); + } + if(f == 1.0F) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.sensitivity.max")).toString(); + } else + { + return (new StringBuilder()).append(s).append((int)(f * 200F)).append("%").toString(); + } + } + if(f == 0.0F) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.off")).toString(); + } else + { + return (new StringBuilder()).append(s).append((int)(f * 100F)).append("%").toString(); + } + } + if(enumoptions.getEnumBoolean()) + { + boolean flag = getOptionOrdinalValue(enumoptions); + if(flag) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.on")).toString(); + } else + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.off")).toString(); + } + } + if(enumoptions == EnumOptions.RENDER_DISTANCE) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey(RENDER_DISTANCES[renderDistance])).toString(); + } + if(enumoptions == EnumOptions.DIFFICULTY) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey(DIFFICULTIES[difficulty])).toString(); + } + if(enumoptions == EnumOptions.GRAPHICS) + { + if(fancyGraphics) + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.graphics.fancy")).toString(); + } else + { + return (new StringBuilder()).append(s).append(stringtranslate.translateKey("options.graphics.fast")).toString(); + } + } else + { + return s; + } + } + + public void loadOptions() + { + try + { + if(!optionsFile.exists()) + { + return; + } + BufferedReader bufferedreader = new BufferedReader(new FileReader(optionsFile)); + for(String s = ""; (s = bufferedreader.readLine()) != null;) + { + String as[] = s.split(":"); + if(as[0].equals("music")) + { + musicVolume = parseFloat(as[1]); + } + if(as[0].equals("sound")) + { + soundVolume = parseFloat(as[1]); + } + if(as[0].equals("mouseSensitivity")) + { + mouseSensitivity = parseFloat(as[1]); + } + if(as[0].equals("invertYMouse")) + { + invertMouse = as[1].equals("true"); + } + if(as[0].equals("viewDistance")) + { + renderDistance = Integer.parseInt(as[1]); + } + if(as[0].equals("bobView")) + { + viewBobbing = as[1].equals("true"); + } + if(as[0].equals("anaglyph3d")) + { + anaglyph = as[1].equals("true"); + } + if(as[0].equals("limitFramerate")) + { + limitFramerate = as[1].equals("true"); + } + if(as[0].equals("difficulty")) + { + difficulty = Integer.parseInt(as[1]); + } + if(as[0].equals("fancyGraphics")) + { + fancyGraphics = as[1].equals("true"); + } + if(as[0].equals("ao")) + { + field_22278_j = as[1].equals("true"); + } + if(as[0].equals("skin")) + { + skin = as[1]; + } + if(as[0].equals("lastServer") && as.length >= 2) + { + lastServer = as[1]; + } + int i = 0; + while(i < keyBindings.length) + { + if(as[0].equals((new StringBuilder()).append("key_").append(keyBindings[i].keyDescription).toString())) + { + keyBindings[i].keyCode = Integer.parseInt(as[1]); + } + i++; + } + } + + bufferedreader.close(); + } + catch(Exception exception) + { + System.out.println("Failed to load options"); + exception.printStackTrace(); + } + } + + private float parseFloat(String s) + { + if(s.equals("true")) + { + return 1.0F; + } + if(s.equals("false")) + { + return 0.0F; + } else + { + return Float.parseFloat(s); + } + } + + public void saveOptions() + { + try + { + PrintWriter printwriter = new PrintWriter(new FileWriter(optionsFile)); + printwriter.println((new StringBuilder()).append("music:").append(musicVolume).toString()); + printwriter.println((new StringBuilder()).append("sound:").append(soundVolume).toString()); + printwriter.println((new StringBuilder()).append("invertYMouse:").append(invertMouse).toString()); + printwriter.println((new StringBuilder()).append("mouseSensitivity:").append(mouseSensitivity).toString()); + printwriter.println((new StringBuilder()).append("viewDistance:").append(renderDistance).toString()); + printwriter.println((new StringBuilder()).append("bobView:").append(viewBobbing).toString()); + printwriter.println((new StringBuilder()).append("anaglyph3d:").append(anaglyph).toString()); + printwriter.println((new StringBuilder()).append("limitFramerate:").append(limitFramerate).toString()); + printwriter.println((new StringBuilder()).append("difficulty:").append(difficulty).toString()); + printwriter.println((new StringBuilder()).append("fancyGraphics:").append(fancyGraphics).toString()); + printwriter.println((new StringBuilder()).append("ao:").append(field_22278_j).toString()); + printwriter.println((new StringBuilder()).append("skin:").append(skin).toString()); + printwriter.println((new StringBuilder()).append("lastServer:").append(lastServer).toString()); + for(int i = 0; i < keyBindings.length; i++) + { + printwriter.println((new StringBuilder()).append("key_").append(keyBindings[i].keyDescription).append(":").append(keyBindings[i].keyCode).toString()); + } + + printwriter.close(); + } + catch(Exception exception) + { + System.out.println("Failed to save options"); + exception.printStackTrace(); + } + } + + private static final String RENDER_DISTANCES[] = { + "options.renderDistance.far", "options.renderDistance.normal", "options.renderDistance.short", "options.renderDistance.tiny" + }; + private static final String DIFFICULTIES[] = { + "options.difficulty.peaceful", "options.difficulty.easy", "options.difficulty.normal", "options.difficulty.hard" + }; + public float musicVolume; + public float soundVolume; + public float mouseSensitivity; + public boolean invertMouse; + public int renderDistance; + public boolean viewBobbing; + public boolean anaglyph; + public boolean limitFramerate; + public boolean fancyGraphics; + public boolean field_22278_j; + public String skin; + public KeyBinding keyBindForward; + public KeyBinding keyBindLeft; + public KeyBinding keyBindBack; + public KeyBinding keyBindRight; + public KeyBinding keyBindJump; + public KeyBinding keyBindInventory; + public KeyBinding keyBindDrop; + public KeyBinding keyBindChat; + public KeyBinding keyBindToggleFog; + public KeyBinding keyBindSneak; + public KeyBinding keyBindings[]; + protected Minecraft mc; + private File optionsFile; + public int difficulty; + public boolean field_22277_y; + public boolean thirdPersonView; + public boolean showDebugInfo; + public String lastServer; + public boolean field_22275_C; + public boolean field_22274_D; + public boolean field_22273_E; + public float field_22272_F; + public float field_22271_G; + +} diff --git a/src/main/java/net/minecraft/src/GameWindowListener.java b/src/main/java/net/minecraft/src/GameWindowListener.java new file mode 100644 index 0000000..732239d --- /dev/null +++ b/src/main/java/net/minecraft/src/GameWindowListener.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import net.minecraft.client.Minecraft; + +public final class GameWindowListener extends WindowAdapter +{ + + public GameWindowListener(Minecraft minecraft, Thread thread) + { + mc = minecraft; + mcThread = thread; + } + + public void windowClosing(WindowEvent windowevent) + { + mc.shutdown(); + try + { + mcThread.join(); + } + catch(InterruptedException interruptedexception) + { + interruptedexception.printStackTrace(); + } + System.exit(0); + } + + final Minecraft mc; /* synthetic field */ + final Thread mcThread; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/Gui.java b/src/main/java/net/minecraft/src/Gui.java new file mode 100644 index 0000000..7562342 --- /dev/null +++ b/src/main/java/net/minecraft/src/Gui.java @@ -0,0 +1,91 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class Gui +{ + + public Gui() + { + zLevel = 0.0F; + } + + protected void drawRect(int i, int j, int k, int l, int i1) + { + float f = (float)(i1 >> 24 & 0xff) / 255F; + float f1 = (float)(i1 >> 16 & 0xff) / 255F; + float f2 = (float)(i1 >> 8 & 0xff) / 255F; + float f3 = (float)(i1 & 0xff) / 255F; + Tessellator tessellator = Tessellator.instance; + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(f1, f2, f3, f); + tessellator.startDrawingQuads(); + tessellator.addVertex(i, l, 0.0D); + tessellator.addVertex(k, l, 0.0D); + tessellator.addVertex(k, j, 0.0D); + tessellator.addVertex(i, j, 0.0D); + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(3042 /*GL_BLEND*/); + } + + protected void drawGradientRect(int i, int j, int k, int l, int i1, int j1) + { + float f = (float)(i1 >> 24 & 0xff) / 255F; + float f1 = (float)(i1 >> 16 & 0xff) / 255F; + float f2 = (float)(i1 >> 8 & 0xff) / 255F; + float f3 = (float)(i1 & 0xff) / 255F; + float f4 = (float)(j1 >> 24 & 0xff) / 255F; + float f5 = (float)(j1 >> 16 & 0xff) / 255F; + float f6 = (float)(j1 >> 8 & 0xff) / 255F; + float f7 = (float)(j1 & 0xff) / 255F; + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glBlendFunc(770, 771); + GL11.glShadeModel(7425 /*GL_SMOOTH*/); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_F(f1, f2, f3, f); + tessellator.addVertex(k, j, 0.0D); + tessellator.addVertex(i, j, 0.0D); + tessellator.setColorRGBA_F(f5, f6, f7, f4); + tessellator.addVertex(i, l, 0.0D); + tessellator.addVertex(k, l, 0.0D); + tessellator.draw(); + GL11.glShadeModel(7424 /*GL_FLAT*/); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + + public void drawCenteredString(FontRenderer fontrenderer, String s, int i, int j, int k) + { + fontrenderer.drawStringWithShadow(s, i - fontrenderer.getStringWidth(s) / 2, j, k); + } + + public void drawString(FontRenderer fontrenderer, String s, int i, int j, int k) + { + fontrenderer.drawStringWithShadow(s, i, j, k); + } + + public void drawTexturedModalRect(int i, int j, int k, int l, int i1, int j1) + { + float f = 0.00390625F; + float f1 = 0.00390625F; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(i + 0, j + j1, zLevel, (float)(k + 0) * f, (float)(l + j1) * f1); + tessellator.addVertexWithUV(i + i1, j + j1, zLevel, (float)(k + i1) * f, (float)(l + j1) * f1); + tessellator.addVertexWithUV(i + i1, j + 0, zLevel, (float)(k + i1) * f, (float)(l + 0) * f1); + tessellator.addVertexWithUV(i + 0, j + 0, zLevel, (float)(k + 0) * f, (float)(l + 0) * f1); + tessellator.draw(); + } + + protected float zLevel; +} diff --git a/src/main/java/net/minecraft/src/GuiButton.java b/src/main/java/net/minecraft/src/GuiButton.java new file mode 100644 index 0000000..0abdc84 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiButton.java @@ -0,0 +1,93 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiButton extends Gui +{ + + public GuiButton(int i, int j, int k, String s) + { + this(i, j, k, 200, 20, s); + } + + public GuiButton(int i, int j, int k, int l, int i1, String s) + { + width = 200; + height = 20; + enabled = true; + enabled2 = true; + id = i; + xPosition = j; + yPosition = k; + width = l; + height = i1; + displayString = s; + } + + protected int getHoverState(boolean flag) + { + byte byte0 = 1; + if(!enabled) + { + byte0 = 0; + } else + if(flag) + { + byte0 = 2; + } + return byte0; + } + + public void drawButton(Minecraft minecraft, int i, int j) + { + if(!enabled2) + { + return; + } + FontRenderer fontrenderer = minecraft.fontRenderer; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, minecraft.renderEngine.getTexture("/gui/gui.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + boolean flag = i >= xPosition && j >= yPosition && i < xPosition + width && j < yPosition + height; + int k = getHoverState(flag); + drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height); + drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height); + mouseDragged(minecraft, i, j); + if(!enabled) + { + drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffa0a0a0); + } else + if(flag) + { + drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffffa0); + } else + { + drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xe0e0e0); + } + } + + protected void mouseDragged(Minecraft minecraft, int i, int j) + { + } + + public void mouseReleased(int i, int j) + { + } + + public boolean mousePressed(Minecraft minecraft, int i, int j) + { + return enabled && i >= xPosition && j >= yPosition && i < xPosition + width && j < yPosition + height; + } + + protected int width; + protected int height; + public int xPosition; + public int yPosition; + public String displayString; + public int id; + public boolean enabled; + public boolean enabled2; +} diff --git a/src/main/java/net/minecraft/src/GuiChat.java b/src/main/java/net/minecraft/src/GuiChat.java new file mode 100644 index 0000000..1b4a15f --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiChat.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +// Decompiled with: CFR 0.152 +// Class Version: 5 +import org.lwjgl.input.Keyboard; + +public class GuiChat +extends GuiScreen { + protected String field_985_a = ""; + private int field_986_h = 0; + private static final String field_20082_i = FontAllowedCharacters.allowedCharacters; + + public void initGui() { + Keyboard.enableRepeatEvents(true); + } + + public void onGuiClosed() { + Keyboard.enableRepeatEvents(false); + } + + public void updateScreen() { + ++this.field_986_h; + } + + protected void keyTyped(char c, int n) { + if (n == 1) { + this.mc.displayGuiScreen(null); + return; + } + if (n == 28) { + String string; + String string2 = this.field_985_a.trim(); + if (string2.length() > 0 && !this.mc.func_22003_b(string = this.field_985_a.trim())) { + this.mc.thePlayer.sendChatMessage(string); + } + this.mc.displayGuiScreen(null); + return; + } + if (n == 14 && this.field_985_a.length() > 0) { + this.field_985_a = this.field_985_a.substring(0, this.field_985_a.length() - 1); + } + if (field_20082_i.indexOf(c) >= 0 && this.field_985_a.length() < 100) { + this.field_985_a = this.field_985_a + c; + } + } + + public void drawScreen(int n, int n2, float f) { + this.drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE); + this.drawString(this.fontRenderer, "> " + this.field_985_a + (this.field_986_h / 6 % 2 == 0 ? "_" : ""), 4, this.height - 12, 0xE0E0E0); + super.drawScreen(n, n2, f); + } + + protected void mouseClicked(int n, int n2, int n3) { + if (n3 == 0) { + if (this.mc.ingameGUI.field_933_a != null) { + if (this.field_985_a.length() > 0 && !this.field_985_a.endsWith(" ")) { + this.field_985_a = this.field_985_a + " "; + } + this.field_985_a = this.field_985_a + this.mc.ingameGUI.field_933_a; + int n4 = 100; + if (this.field_985_a.length() > n4) { + this.field_985_a = this.field_985_a.substring(0, n4); + } + } else { + super.mouseClicked(n, n2, n3); + } + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiChest.java b/src/main/java/net/minecraft/src/GuiChest.java new file mode 100644 index 0000000..60cd126 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiChest.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiChest extends GuiContainer +{ + + public GuiChest(IInventory iinventory, IInventory iinventory1) + { + super(new CraftingInventoryChestCB(iinventory, iinventory1)); + inventoryRows = 0; + upperChestInventory = iinventory; + lowerChestInventory = iinventory1; + field_948_f = false; + char c = '\336'; + int i = c - 108; + inventoryRows = iinventory1.getSizeInventory() / 9; + ySize = i + inventoryRows * 18; + } + + protected void drawGuiContainerForegroundLayer() + { + fontRenderer.drawString(lowerChestInventory.getInvName(), 8, 6, 0x404040); + fontRenderer.drawString(upperChestInventory.getInvName(), 8, (ySize - 96) + 2, 0x404040); + } + + protected void drawGuiContainerBackgroundLayer(float f) + { + int i = mc.renderEngine.getTexture("/gui/container.png"); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture(i); + int j = (width - xSize) / 2; + int k = (height - ySize) / 2; + drawTexturedModalRect(j, k, 0, 0, xSize, inventoryRows * 18 + 17); + drawTexturedModalRect(j, k + inventoryRows * 18 + 17, 0, 126, xSize, 96); + } + + private IInventory upperChestInventory; + private IInventory lowerChestInventory; + private int inventoryRows; +} diff --git a/src/main/java/net/minecraft/src/GuiConflictWarning.java b/src/main/java/net/minecraft/src/GuiConflictWarning.java new file mode 100644 index 0000000..de09e64 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiConflictWarning.java @@ -0,0 +1,52 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiConflictWarning extends GuiScreen +{ + + public GuiConflictWarning() + { + updateCounter = 0; + } + + public void updateScreen() + { + updateCounter++; + } + + public void initGui() + { + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 120 + 12, "Back to title screen")); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == 0) + { + mc.displayGuiScreen(new GuiMainMenu()); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, "Level save conflict", width / 2, (height / 4 - 60) + 20, 0xffffff); + drawString(fontRenderer, "Minecraft detected a conflict in the level save data.", width / 2 - 140, (height / 4 - 60) + 60 + 0, 0xa0a0a0); + drawString(fontRenderer, "This could be caused by two copies of the game", width / 2 - 140, (height / 4 - 60) + 60 + 18, 0xa0a0a0); + drawString(fontRenderer, "accessing the same level.", width / 2 - 140, (height / 4 - 60) + 60 + 27, 0xa0a0a0); + drawString(fontRenderer, "To prevent level corruption, the current game has quit.", width / 2 - 140, (height / 4 - 60) + 60 + 45, 0xa0a0a0); + super.drawScreen(i, j, f); + } + + private int updateCounter; +} diff --git a/src/main/java/net/minecraft/src/GuiConnectFailed.java b/src/main/java/net/minecraft/src/GuiConnectFailed.java new file mode 100644 index 0000000..19957e1 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiConnectFailed.java @@ -0,0 +1,58 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiConnectFailed extends GuiScreen +{ + + public GuiConnectFailed(String s, String s1, Object aobj[]) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + errorMessage = stringtranslate.translateKey(s); + if(aobj != null) + { + errorDetail = stringtranslate.translateKeyFormat(s1, aobj); + } else + { + errorDetail = stringtranslate.translateKey(s1); + } + } + + public void updateScreen() + { + } + + protected void keyTyped(char c, int i) + { + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 120 + 12, stringtranslate.translateKey("gui.toMenu"))); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(guibutton.id == 0) + { + mc.displayGuiScreen(new GuiMainMenu()); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, errorMessage, width / 2, height / 2 - 50, 0xffffff); + drawCenteredString(fontRenderer, errorDetail, width / 2, height / 2 - 10, 0xffffff); + super.drawScreen(i, j, f); + } + + private String errorMessage; + private String errorDetail; +} diff --git a/src/main/java/net/minecraft/src/GuiConnecting.java b/src/main/java/net/minecraft/src/GuiConnecting.java new file mode 100644 index 0000000..e5ee2b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiConnecting.java @@ -0,0 +1,84 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiConnecting extends GuiScreen +{ + + public GuiConnecting(Minecraft minecraft, String s, int i) + { + cancelled = false; + minecraft.changeWorld1(null); + (new ThreadConnectToServer(this, minecraft, s, i)).start(); + } + + public void updateScreen() + { + if(clientHandler != null) + { + clientHandler.processReadPackets(); + } + } + + protected void keyTyped(char c, int i) + { + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 120 + 12, stringtranslate.translateKey("gui.cancel"))); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(guibutton.id == 0) + { + cancelled = true; + if(clientHandler != null) + { + clientHandler.disconnect(); + } + mc.displayGuiScreen(new GuiMainMenu()); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + StringTranslate stringtranslate = StringTranslate.getInstance(); + if(clientHandler == null) + { + drawCenteredString(fontRenderer, stringtranslate.translateKey("connect.connecting"), width / 2, height / 2 - 50, 0xffffff); + drawCenteredString(fontRenderer, "", width / 2, height / 2 - 10, 0xffffff); + } else + { + drawCenteredString(fontRenderer, stringtranslate.translateKey("connect.authorizing"), width / 2, height / 2 - 50, 0xffffff); + drawCenteredString(fontRenderer, clientHandler.field_1209_a, width / 2, height / 2 - 10, 0xffffff); + } + super.drawScreen(i, j, f); + } + + static NetClientHandler setNetClientHandler(GuiConnecting guiconnecting, NetClientHandler netclienthandler) + { + return guiconnecting.clientHandler = netclienthandler; + } + + static boolean isCancelled(GuiConnecting guiconnecting) + { + return guiconnecting.cancelled; + } + + static NetClientHandler getNetClientHandler(GuiConnecting guiconnecting) + { + return guiconnecting.clientHandler; + } + + private NetClientHandler clientHandler; + private boolean cancelled; +} diff --git a/src/main/java/net/minecraft/src/GuiContainer.java b/src/main/java/net/minecraft/src/GuiContainer.java new file mode 100644 index 0000000..ad9b70d --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiContainer.java @@ -0,0 +1,196 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public abstract class GuiContainer extends GuiScreen +{ + + public GuiContainer(CraftingInventoryCB craftinginventorycb) + { + xSize = 176; + ySize = 166; + inventorySlots = craftinginventorycb; + } + + public void initGui() + { + super.initGui(); + mc.thePlayer.craftingInventory = inventorySlots; + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + int k = (width - xSize) / 2; + int l = (height - ySize) / 2; + drawGuiContainerBackgroundLayer(f); + GL11.glPushMatrix(); + GL11.glRotatef(180F, 1.0F, 0.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glTranslatef(k, l, 0.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + Slot slot = null; + for(int i1 = 0; i1 < inventorySlots.slots.size(); i1++) + { + Slot slot1 = (Slot)inventorySlots.slots.get(i1); + drawSlotInventory(slot1); + if(func_20081_a(slot1, i, j)) + { + slot = slot1; + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + int j1 = slot1.xDisplayPosition; + int l1 = slot1.yDisplayPosition; + drawGradientRect(j1, l1, j1 + 16, l1 + 16, 0x80ffffff, 0x80ffffff); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + } + } + + InventoryPlayer inventoryplayer = mc.thePlayer.inventory; + if(inventoryplayer.getItemStack() != null) + { + GL11.glTranslatef(0.0F, 0.0F, 32F); + itemRenderer.renderItemIntoGUI(fontRenderer, mc.renderEngine, inventoryplayer.getItemStack(), i - k - 8, j - l - 8); + itemRenderer.renderItemOverlayIntoGUI(fontRenderer, mc.renderEngine, inventoryplayer.getItemStack(), i - k - 8, j - l - 8); + } + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + drawGuiContainerForegroundLayer(); + if(inventoryplayer.getItemStack() == null && slot != null && slot.func_20005_c()) + { + String s = (new StringBuilder()).append("").append(StringTranslate.getInstance().translateNamedKey(slot.getStack().func_20109_f())).toString().trim(); + if(s.length() > 0) + { + int k1 = (i - k) + 12; + int i2 = j - l - 12; + int j2 = fontRenderer.getStringWidth(s); + drawGradientRect(k1 - 3, i2 - 3, k1 + j2 + 3, i2 + 8 + 3, 0xc0000000, 0xc0000000); + fontRenderer.drawStringWithShadow(s, k1, i2, -1); + } + } + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glPopMatrix(); + } + + protected void drawGuiContainerForegroundLayer() + { + } + + protected abstract void drawGuiContainerBackgroundLayer(float f); + + private void drawSlotInventory(Slot slot) + { + int i = slot.xDisplayPosition; + int j = slot.yDisplayPosition; + ItemStack itemstack = slot.getStack(); + if(itemstack == null) + { + int k = slot.func_775_c(); + if(k >= 0) + { + GL11.glDisable(2896 /*GL_LIGHTING*/); + mc.renderEngine.bindTexture(mc.renderEngine.getTexture("/gui/items.png")); + drawTexturedModalRect(i, j, (k % 16) * 16, (k / 16) * 16, 16, 16); + GL11.glEnable(2896 /*GL_LIGHTING*/); + return; + } + } + itemRenderer.renderItemIntoGUI(fontRenderer, mc.renderEngine, itemstack, i, j); + itemRenderer.renderItemOverlayIntoGUI(fontRenderer, mc.renderEngine, itemstack, i, j); + } + + private Slot getSlotAtPosition(int i, int j) + { + for(int k = 0; k < inventorySlots.slots.size(); k++) + { + Slot slot = (Slot)inventorySlots.slots.get(k); + if(func_20081_a(slot, i, j)) + { + return slot; + } + } + + return null; + } + + private boolean func_20081_a(Slot slot, int i, int j) + { + int k = (width - xSize) / 2; + int l = (height - ySize) / 2; + i -= k; + j -= l; + return i >= slot.xDisplayPosition - 1 && i < slot.xDisplayPosition + 16 + 1 && j >= slot.yDisplayPosition - 1 && j < slot.yDisplayPosition + 16 + 1; + } + + protected void mouseClicked(int i, int j, int k) + { + if(k == 0 || k == 1) + { + Slot slot = getSlotAtPosition(i, j); + int l = (width - xSize) / 2; + int i1 = (height - ySize) / 2; + boolean flag = i < l || j < i1 || i >= l + xSize || j >= i1 + ySize; + int j1 = -1; + if(slot != null) + { + j1 = slot.field_20007_a; + } + if(flag) + { + j1 = -999; + } + if(j1 != -1) + { + mc.playerController.func_20085_a(inventorySlots.windowId, j1, k, mc.thePlayer); + } + } + } + + protected void mouseMovedOrUp(int i, int j, int k) + { + if(k != 0); + } + + protected void keyTyped(char c, int i) + { + if(i == 1 || i == mc.gameSettings.keyBindInventory.keyCode) + { + mc.thePlayer.func_20059_m(); + } + } + + public void onGuiClosed() + { + if(mc.thePlayer == null) + { + return; + } else + { + mc.playerController.func_20086_a(inventorySlots.windowId, mc.thePlayer); + return; + } + } + + public boolean doesGuiPauseGame() + { + return false; + } + + private static RenderItem itemRenderer = new RenderItem(); + protected int xSize; + protected int ySize; + public CraftingInventoryCB inventorySlots; + +} diff --git a/src/main/java/net/minecraft/src/GuiControls.java b/src/main/java/net/minecraft/src/GuiControls.java new file mode 100644 index 0000000..119b766 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiControls.java @@ -0,0 +1,85 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiControls extends GuiScreen +{ + + public GuiControls(GuiScreen guiscreen, GameSettings gamesettings) + { + screenTitle = "Controls"; + buttonId = -1; + parentScreen = guiscreen; + options = gamesettings; + } + + private int func_20080_j() + { + return width / 2 - 155; + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + int i = func_20080_j(); + for(int j = 0; j < options.keyBindings.length; j++) + { + controlList.add(new GuiSmallButton(j, i + (j % 2) * 160, height / 6 + 24 * (j >> 1), 70, 20, options.getOptionDisplayString(j))); + } + + controlList.add(new GuiButton(200, width / 2 - 100, height / 6 + 168, stringtranslate.translateKey("gui.done"))); + screenTitle = stringtranslate.translateKey("controls.title"); + } + + protected void actionPerformed(GuiButton guibutton) + { + for(int i = 0; i < options.keyBindings.length; i++) + { + ((GuiButton)controlList.get(i)).displayString = options.getOptionDisplayString(i); + } + + if(guibutton.id == 200) + { + mc.displayGuiScreen(parentScreen); + } else + { + buttonId = guibutton.id; + guibutton.displayString = (new StringBuilder()).append("> ").append(options.getOptionDisplayString(guibutton.id)).append(" <").toString(); + } + } + + protected void keyTyped(char c, int i) + { + if(buttonId >= 0) + { + options.setKeyBinding(buttonId, i); + ((GuiButton)controlList.get(buttonId)).displayString = options.getOptionDisplayString(buttonId); + buttonId = -1; + } else + { + super.keyTyped(c, i); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, screenTitle, width / 2, 20, 0xffffff); + int k = func_20080_j(); + for(int l = 0; l < options.keyBindings.length; l++) + { + drawString(fontRenderer, options.getKeyBindingDescription(l), k + (l % 2) * 160 + 70 + 6, height / 6 + 24 * (l >> 1) + 7, -1); + } + + super.drawScreen(i, j, f); + } + + private GuiScreen parentScreen; + protected String screenTitle; + private GameSettings options; + private int buttonId; +} diff --git a/src/main/java/net/minecraft/src/GuiCrafting.java b/src/main/java/net/minecraft/src/GuiCrafting.java new file mode 100644 index 0000000..25fc9c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiCrafting.java @@ -0,0 +1,38 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiCrafting extends GuiContainer +{ + + public GuiCrafting(InventoryPlayer inventoryplayer, World world, int i, int j, int k) + { + super(new CraftingInventoryWorkbenchCB(inventoryplayer, world, i, j, k)); + } + + public void onGuiClosed() + { + super.onGuiClosed(); + inventorySlots.onCraftGuiClosed(mc.thePlayer); + } + + protected void drawGuiContainerForegroundLayer() + { + fontRenderer.drawString("Crafting", 28, 6, 0x404040); + fontRenderer.drawString("Inventory", 8, (ySize - 96) + 2, 0x404040); + } + + protected void drawGuiContainerBackgroundLayer(float f) + { + int i = mc.renderEngine.getTexture("/gui/crafting.png"); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture(i); + int j = (width - xSize) / 2; + int k = (height - ySize) / 2; + drawTexturedModalRect(j, k, 0, 0, xSize, ySize); + } +} diff --git a/src/main/java/net/minecraft/src/GuiCreateWorld.java b/src/main/java/net/minecraft/src/GuiCreateWorld.java new file mode 100644 index 0000000..5550d21 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiCreateWorld.java @@ -0,0 +1,141 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Keyboard; + +public class GuiCreateWorld extends GuiScreen +{ + + public GuiCreateWorld(GuiScreen guiscreen) + { + field_22131_a = guiscreen; + } + + public void updateScreen() + { + field_22134_h.func_22070_b(); + field_22133_i.func_22070_b(); + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + Keyboard.enableRepeatEvents(true); + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 96 + 12, stringtranslate.translateKey("selectWorld.create"))); + controlList.add(new GuiButton(1, width / 2 - 100, height / 4 + 120 + 12, stringtranslate.translateKey("gui.cancel"))); + field_22134_h = new GuiDisableButton(fontRenderer, width / 2 - 100, 60, 200, 20, stringtranslate.translateKey("selectWorld.newWorld")); + field_22134_h.field_22082_a = true; + field_22134_h.func_22066_a(32); + field_22133_i = new GuiDisableButton(fontRenderer, width / 2 - 100, 116, 200, 20, ""); + func_22129_j(); + } + + private void func_22129_j() + { + field_22132_k = field_22134_h.func_22071_a().trim(); + char ac[] = FontAllowedCharacters.field_22286_b; + int i = ac.length; + for(int j = 0; j < i; j++) + { + char c = ac[j]; + field_22132_k = field_22132_k.replace(c, '_'); + } + + if(MathHelper.func_22282_a(field_22132_k)) + { + field_22132_k = "World"; + } + for(ISaveFormat isaveformat = mc.func_22004_c(); isaveformat.func_22173_b(field_22132_k) != null; field_22132_k = (new StringBuilder()).append(field_22132_k).append("-").toString()) { } + } + + public void onGuiClosed() + { + Keyboard.enableRepeatEvents(false); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == 1) + { + mc.displayGuiScreen(field_22131_a); + } else + if(guibutton.id == 0) + { + mc.displayGuiScreen(null); + if(field_22130_l) + { + return; + } + field_22130_l = true; + long l = (new Random()).nextLong(); + String s = field_22133_i.func_22071_a(); + if(!MathHelper.func_22282_a(s)) + { + try + { + long l1 = Long.parseLong(s); + if(l1 != 0L) + { + l = l1; + } + } + catch(NumberFormatException numberformatexception) + { + l = s.hashCode(); + } + } + mc.playerController = new PlayerControllerSP(mc); + mc.startWorld(field_22132_k, field_22134_h.func_22071_a(), l); + mc.displayGuiScreen(null); + } + } + + protected void keyTyped(char c, int i) + { + field_22134_h.func_22072_a(c, i); + field_22133_i.func_22072_a(c, i); + if(c == '\r') + { + actionPerformed((GuiButton)controlList.get(0)); + } + ((GuiButton)controlList.get(0)).enabled = field_22134_h.func_22071_a().length() > 0; + func_22129_j(); + } + + protected void mouseClicked(int i, int j, int k) + { + super.mouseClicked(i, j, k); + field_22134_h.func_22069_a(i, j, k); + field_22133_i.func_22069_a(i, j, k); + } + + public void drawScreen(int i, int j, float f) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + drawDefaultBackground(); + drawCenteredString(fontRenderer, stringtranslate.translateKey("selectWorld.create"), width / 2, (height / 4 - 60) + 20, 0xffffff); + drawString(fontRenderer, stringtranslate.translateKey("selectWorld.enterName"), width / 2 - 100, 47, 0xa0a0a0); + drawString(fontRenderer, (new StringBuilder()).append(stringtranslate.translateKey("selectWorld.resultFolder")).append(" ").append(field_22132_k).toString(), width / 2 - 100, 85, 0xa0a0a0); + drawString(fontRenderer, stringtranslate.translateKey("selectWorld.enterSeed"), width / 2 - 100, 104, 0xa0a0a0); + drawString(fontRenderer, stringtranslate.translateKey("selectWorld.seedInfo"), width / 2 - 100, 140, 0xa0a0a0); + field_22134_h.func_22067_c(); + field_22133_i.func_22067_c(); + super.drawScreen(i, j, f); + } + + private GuiScreen field_22131_a; + private GuiDisableButton field_22134_h; + private GuiDisableButton field_22133_i; + private String field_22132_k; + private boolean field_22130_l; +} diff --git a/src/main/java/net/minecraft/src/GuiDisableButton.java b/src/main/java/net/minecraft/src/GuiDisableButton.java new file mode 100644 index 0000000..2cf92ec --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiDisableButton.java @@ -0,0 +1,87 @@ +package net.minecraft.src; + +// Decompiled with: CFR 0.152 +// Class Version: 5 +public class GuiDisableButton +extends Gui { + private final FontRenderer field_22080_c; + private final int field_22079_d; + private final int field_22078_e; + private final int field_22077_f; + private final int field_22076_g; + private String field_22075_h; + private int field_22074_i; + private int field_22073_k; + public boolean field_22082_a = false; + public boolean field_22081_b = true; + + public GuiDisableButton(FontRenderer fontRenderer, int n, int n2, int n3, int n4, String string) { + this.field_22080_c = fontRenderer; + this.field_22079_d = n; + this.field_22078_e = n2; + this.field_22077_f = n3; + this.field_22076_g = n4; + this.func_22068_a(string); + } + + public void func_22068_a(String string) { + this.field_22075_h = string; + } + + public String func_22071_a() { + return this.field_22075_h; + } + + public void func_22070_b() { + ++this.field_22073_k; + } + + public void func_22072_a(char c, int n) { + if (!this.field_22081_b || !this.field_22082_a) { + return; + } + if (c == '') { + int n2; + String string = GuiScreen.getClipboardString(); + if (string == null) { + string = ""; + } + if ((n2 = 32 - this.field_22075_h.length()) > string.length()) { + n2 = string.length(); + } + if (n2 > 0) { + this.field_22075_h = this.field_22075_h + string.substring(0, n2); + } + } + if (n == 14 && this.field_22075_h.length() > 0) { + this.field_22075_h = this.field_22075_h.substring(0, this.field_22075_h.length() - 1); + } + if (FontAllowedCharacters.allowedCharacters.indexOf(c) >= 0 && (this.field_22075_h.length() < this.field_22074_i || this.field_22074_i == 0)) { + this.field_22075_h = this.field_22075_h + c; + } + } + + public void func_22069_a(int n, int n2, int n3) { + boolean bl; + boolean bl2 = bl = this.field_22081_b && n >= this.field_22079_d && n < this.field_22079_d + this.field_22077_f && n2 >= this.field_22078_e && n2 < this.field_22078_e + this.field_22076_g; + if (bl && !this.field_22082_a) { + this.field_22073_k = 0; + } + this.field_22082_a = bl; + } + + public void func_22067_c() { + this.drawRect(this.field_22079_d - 1, this.field_22078_e - 1, this.field_22079_d + this.field_22077_f + 1, this.field_22078_e + this.field_22076_g + 1, -6250336); + this.drawRect(this.field_22079_d, this.field_22078_e, this.field_22079_d + this.field_22077_f, this.field_22078_e + this.field_22076_g, -16777216); + if (this.field_22081_b) { + boolean bl = this.field_22082_a && this.field_22073_k / 6 % 2 == 0; + this.drawString(this.field_22080_c, this.field_22075_h + (bl ? "_" : ""), this.field_22079_d + 4, this.field_22078_e + (this.field_22076_g - 8) / 2, 0xE0E0E0); + } else { + this.drawString(this.field_22080_c, this.field_22075_h, this.field_22079_d + 4, this.field_22078_e + (this.field_22076_g - 8) / 2, 0x707070); + } + } + + public void func_22066_a(int n) { + this.field_22074_i = n; + } +} diff --git a/src/main/java/net/minecraft/src/GuiDispenser.java b/src/main/java/net/minecraft/src/GuiDispenser.java new file mode 100644 index 0000000..42e2947 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiDispenser.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiDispenser extends GuiContainer +{ + + public GuiDispenser(InventoryPlayer inventoryplayer, TileEntityDispenser tileentitydispenser) + { + super(new CraftingInventoryDispenserCB(inventoryplayer, tileentitydispenser)); + } + + protected void drawGuiContainerForegroundLayer() + { + fontRenderer.drawString("Dispenser", 60, 6, 0x404040); + fontRenderer.drawString("Inventory", 8, (ySize - 96) + 2, 0x404040); + } + + protected void drawGuiContainerBackgroundLayer(float f) + { + int i = mc.renderEngine.getTexture("/gui/trap.png"); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture(i); + int j = (width - xSize) / 2; + int k = (height - ySize) / 2; + drawTexturedModalRect(j, k, 0, 0, xSize, ySize); + } +} diff --git a/src/main/java/net/minecraft/src/GuiDownloadTerrain.java b/src/main/java/net/minecraft/src/GuiDownloadTerrain.java new file mode 100644 index 0000000..5548c7e --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiDownloadTerrain.java @@ -0,0 +1,53 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public class GuiDownloadTerrain extends GuiScreen +{ + + public GuiDownloadTerrain(NetClientHandler netclienthandler) + { + updateCounter = 0; + netHandler = netclienthandler; + } + + protected void keyTyped(char c, int i) + { + } + + public void initGui() + { + controlList.clear(); + } + + public void updateScreen() + { + updateCounter++; + if(updateCounter % 20 == 0) + { + netHandler.addToSendQueue(new Packet0KeepAlive()); + } + if(netHandler != null) + { + netHandler.processReadPackets(); + } + } + + protected void actionPerformed(GuiButton guibutton) + { + } + + public void drawScreen(int i, int j, float f) + { + drawBackground(0); + StringTranslate stringtranslate = StringTranslate.getInstance(); + drawCenteredString(fontRenderer, stringtranslate.translateKey("multiplayer.downloadingTerrain"), width / 2, height / 2 - 50, 0xffffff); + super.drawScreen(i, j, f); + } + + private NetClientHandler netHandler; + private int updateCounter; +} diff --git a/src/main/java/net/minecraft/src/GuiEditSign.java b/src/main/java/net/minecraft/src/GuiEditSign.java new file mode 100644 index 0000000..3603542 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiEditSign.java @@ -0,0 +1,99 @@ +package net.minecraft.src; + +// Decompiled with: CFR 0.152 +// Class Version: 5 +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +public class GuiEditSign +extends GuiScreen { + protected String field_999_a = "Edit sign message:"; + private TileEntitySign field_1002_h; + private int field_4189_i; + private int field_1000_j = 0; + private static final String field_20083_l = FontAllowedCharacters.allowedCharacters; + + public GuiEditSign(TileEntitySign tileEntitySign) { + this.field_1002_h = tileEntitySign; + } + + public void func_6448_a() { + this.controlList.clear(); + Keyboard.enableRepeatEvents(true); + this.controlList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 120, "Done")); + } + + public void func_6449_h() { + Keyboard.enableRepeatEvents(false); + if (this.mc.theWorld.multiplayerWorld) { + this.mc.func_20001_q().addToSendQueue(new Packet130(this.field_1002_h.xCoord, this.field_1002_h.yCoord, this.field_1002_h.zCoord, this.field_1002_h.signText)); + } + } + + public void func_570_g() { + ++this.field_4189_i; + } + + protected void func_572_a(GuiButton guiButton) { + if (!guiButton.enabled) { + return; + } + if (guiButton.id == 0) { + this.field_1002_h.onInventoryChanged(); + this.mc.displayGuiScreen(null); + } + } + + protected void func_580_a(char c, int n) { + if (n == 200) { + this.field_1000_j = this.field_1000_j - 1 & 3; + } + if (n == 208 || n == 28) { + this.field_1000_j = this.field_1000_j + 1 & 3; + } + if (n == 14 && this.field_1002_h.signText[this.field_1000_j].length() > 0) { + this.field_1002_h.signText[this.field_1000_j] = this.field_1002_h.signText[this.field_1000_j].substring(0, this.field_1002_h.signText[this.field_1000_j].length() - 1); + } + if (field_20083_l.indexOf(c) >= 0 && this.field_1002_h.signText[this.field_1000_j].length() < 15) { + int n2 = this.field_1000_j; + this.field_1002_h.signText[n2] = this.field_1002_h.signText[n2] + c; + } + } + + public void func_571_a(int n, int n2, float f) { + this.drawDefaultBackground(); + this.drawCenteredString(this.fontRenderer, this.field_999_a, this.width / 2, 40, 0xFFFFFF); + GL11.glPushMatrix(); + GL11.glTranslatef(this.width / 2, this.height / 2, 50.0f); + float f2 = 93.75f; + GL11.glScalef(-f2, -f2, -f2); + GL11.glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + Block block = this.field_1002_h.getBlockType(); + if (block == Block.signPost) { + float f3 = (float)(this.field_1002_h.getBlockMetadata() * 360) / 16.0f; + GL11.glRotatef(f3, 0.0f, 1.0f, 0.0f); + GL11.glTranslatef(0.0f, 0.3125f, 0.0f); + } else { + int n3 = this.field_1002_h.getBlockMetadata(); + float f4 = 0.0f; + if (n3 == 2) { + f4 = 180.0f; + } + if (n3 == 4) { + f4 = 90.0f; + } + if (n3 == 5) { + f4 = -90.0f; + } + GL11.glRotatef(f4, 0.0f, 1.0f, 0.0f); + GL11.glTranslatef(0.0f, 0.3125f, 0.0f); + } + if (this.field_4189_i / 6 % 2 == 0) { + this.field_1002_h.lineBeingEdited = this.field_1000_j; + } + TileEntityRenderer.instance.renderTileEntityAt(this.field_1002_h, -0.5, -0.75, -0.5, 0.0f); + this.field_1002_h.lineBeingEdited = -1; + GL11.glPopMatrix(); + super.drawScreen(n, n2, f); + } +} diff --git a/src/main/java/net/minecraft/src/GuiFurnace.java b/src/main/java/net/minecraft/src/GuiFurnace.java new file mode 100644 index 0000000..7908d9c --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiFurnace.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiFurnace extends GuiContainer +{ + + public GuiFurnace(InventoryPlayer inventoryplayer, TileEntityFurnace tileentityfurnace) + { + super(new CraftingInventoryFurnaceCB(inventoryplayer, tileentityfurnace)); + furnaceInventory = tileentityfurnace; + } + + protected void drawGuiContainerForegroundLayer() + { + fontRenderer.drawString("Furnace", 60, 6, 0x404040); + fontRenderer.drawString("Inventory", 8, (ySize - 96) + 2, 0x404040); + } + + protected void drawGuiContainerBackgroundLayer(float f) + { + int i = mc.renderEngine.getTexture("/gui/furnace.png"); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture(i); + int j = (width - xSize) / 2; + int k = (height - ySize) / 2; + drawTexturedModalRect(j, k, 0, 0, xSize, ySize); + if(furnaceInventory.isBurning()) + { + int l = furnaceInventory.getBurnTimeRemainingScaled(12); + drawTexturedModalRect(j + 56, (k + 36 + 12) - l, 176, 12 - l, 14, l + 2); + } + int i1 = furnaceInventory.getCookProgressScaled(24); + drawTexturedModalRect(j + 79, k + 34, 176, 14, i1 + 1, 16); + } + + private TileEntityFurnace furnaceInventory; +} diff --git a/src/main/java/net/minecraft/src/GuiGameOver.java b/src/main/java/net/minecraft/src/GuiGameOver.java new file mode 100644 index 0000000..8a718d6 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiGameOver.java @@ -0,0 +1,62 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiGameOver extends GuiScreen +{ + + public GuiGameOver() + { + } + + public void initGui() + { + controlList.clear(); + controlList.add(new GuiButton(1, width / 2 - 100, height / 4 + 72, "Respawn")); + controlList.add(new GuiButton(2, width / 2 - 100, height / 4 + 96, "Title menu")); + if(mc.session == null) + { + ((GuiButton)controlList.get(1)).enabled = false; + } + } + + protected void keyTyped(char c, int i) + { + } + + protected void actionPerformed(GuiButton guibutton) + { + if(guibutton.id != 0); + if(guibutton.id == 1) + { + mc.thePlayer.respawnPlayer(); + mc.displayGuiScreen(null); + } + if(guibutton.id == 2) + { + mc.changeWorld1(null); + mc.displayGuiScreen(new GuiMainMenu()); + } + } + + public void drawScreen(int i, int j, float f) + { + drawGradientRect(0, 0, width, height, 0x60500000, 0xa0803030); + GL11.glPushMatrix(); + GL11.glScalef(2.0F, 2.0F, 2.0F); + drawCenteredString(fontRenderer, "Game over!", width / 2 / 2, 30, 0xffffff); + GL11.glPopMatrix(); + drawCenteredString(fontRenderer, (new StringBuilder()).append("Score: &e").append(mc.thePlayer.getScore()).toString(), width / 2, 100, 0xffffff); + super.drawScreen(i, j, f); + } + + public boolean doesGuiPauseGame() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/GuiIngame.java b/src/main/java/net/minecraft/src/GuiIngame.java new file mode 100644 index 0000000..436bab4 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiIngame.java @@ -0,0 +1,423 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Random; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiIngame extends Gui +{ + + public GuiIngame(Minecraft minecraft) + { + chatMessageList = new ArrayList(); + rand = new Random(); + field_933_a = null; + updateCounter = 0; + recordPlaying = ""; + recordPlayingUpFor = 0; + field_22065_l = false; + prevVignetteBrightness = 1.0F; + mc = minecraft; + } + + public void renderGameOverlay(float f, boolean flag, int i, int j) + { + ScaledResolution scaledresolution = new ScaledResolution(mc.displayWidth, mc.displayHeight); + int k = scaledresolution.getScaledWidth(); + int l = scaledresolution.getScaledHeight(); + FontRenderer fontrenderer = mc.fontRenderer; + mc.entityRenderer.func_905_b(); + GL11.glEnable(3042 /*GL_BLEND*/); + if(Minecraft.func_22001_u()) + { + renderVignette(mc.thePlayer.getEntityBrightness(f), k, l); + } + ItemStack itemstack = mc.thePlayer.inventory.armorItemInSlot(3); + if(!mc.gameSettings.thirdPersonView && itemstack != null && itemstack.itemID == Block.pumpkin.blockID) + { + renderPumpkinBlur(k, l); + } + float f1 = mc.thePlayer.prevTimeInPortal + (mc.thePlayer.timeInPortal - mc.thePlayer.prevTimeInPortal) * f; + if(f1 > 0.0F) + { + renderPortalOverlay(f1, k, l); + } + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/gui/gui.png")); + InventoryPlayer inventoryplayer = mc.thePlayer.inventory; + zLevel = -90F; + drawTexturedModalRect(k / 2 - 91, l - 22, 0, 0, 182, 22); + drawTexturedModalRect((k / 2 - 91 - 1) + inventoryplayer.currentItem * 20, l - 22 - 1, 0, 22, 24, 22); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/gui/icons.png")); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(775, 769); + drawTexturedModalRect(k / 2 - 7, l / 2 - 7, 0, 0, 16, 16); + GL11.glDisable(3042 /*GL_BLEND*/); + boolean flag1 = (mc.thePlayer.field_9306_bj / 3) % 2 == 1; + if(mc.thePlayer.field_9306_bj < 10) + { + flag1 = false; + } + int i1 = mc.thePlayer.health; + int j1 = mc.thePlayer.prevHealth; + rand.setSeed(updateCounter * 0x4c627); + if(mc.playerController.shouldDrawHUD()) + { + int k1 = mc.thePlayer.getPlayerArmorValue(); + for(int j2 = 0; j2 < 10; j2++) + { + int k3 = l - 32; + if(k1 > 0) + { + int j5 = (k / 2 + 91) - j2 * 8 - 9; + if(j2 * 2 + 1 < k1) + { + drawTexturedModalRect(j5, k3, 34, 9, 9, 9); + } + if(j2 * 2 + 1 == k1) + { + drawTexturedModalRect(j5, k3, 25, 9, 9, 9); + } + if(j2 * 2 + 1 > k1) + { + drawTexturedModalRect(j5, k3, 16, 9, 9, 9); + } + } + int k5 = 0; + if(flag1) + { + k5 = 1; + } + int i6 = (k / 2 - 91) + j2 * 8; + if(i1 <= 4) + { + k3 += rand.nextInt(2); + } + drawTexturedModalRect(i6, k3, 16 + k5 * 9, 0, 9, 9); + if(flag1) + { + if(j2 * 2 + 1 < j1) + { + drawTexturedModalRect(i6, k3, 70, 0, 9, 9); + } + if(j2 * 2 + 1 == j1) + { + drawTexturedModalRect(i6, k3, 79, 0, 9, 9); + } + } + if(j2 * 2 + 1 < i1) + { + drawTexturedModalRect(i6, k3, 52, 0, 9, 9); + } + if(j2 * 2 + 1 == i1) + { + drawTexturedModalRect(i6, k3, 61, 0, 9, 9); + } + } + + if(mc.thePlayer.isInsideOfMaterial(Material.water)) + { + int k2 = (int)Math.ceil(((double)(mc.thePlayer.air - 2) * 10D) / 300D); + int l3 = (int)Math.ceil(((double)mc.thePlayer.air * 10D) / 300D) - k2; + for(int l5 = 0; l5 < k2 + l3; l5++) + { + if(l5 < k2) + { + drawTexturedModalRect((k / 2 - 91) + l5 * 8, l - 32 - 9, 16, 18, 9, 9); + } else + { + drawTexturedModalRect((k / 2 - 91) + l5 * 8, l - 32 - 9, 25, 18, 9, 9); + } + } + + } + } + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPushMatrix(); + GL11.glRotatef(180F, 1.0F, 0.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + GL11.glPopMatrix(); + for(int l1 = 0; l1 < 9; l1++) + { + int i3 = (k / 2 - 90) + l1 * 20 + 2; + int i4 = l - 16 - 3; + renderInventorySlot(l1, i3, i4, f); + } + + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + if(mc.thePlayer.func_22060_M() > 0) + { + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + int i2 = mc.thePlayer.func_22060_M(); + float f3 = (float)i2 / 100F; + if(f3 > 1.0F) + { + f3 = 1.0F - (float)(i2 - 100) / 10F; + } + int j4 = (int)(220F * f3) << 24 | 0x101020; + drawRect(0, 0, k, l, j4); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + } + if(mc.gameSettings.showDebugInfo) + { + fontrenderer.drawStringWithShadow((new StringBuilder()).append("Minecraft Beta 1.3_01 (").append(mc.debug).append(")").toString(), 2, 2, 0xffffff); + fontrenderer.drawStringWithShadow(mc.func_6241_m(), 2, 12, 0xffffff); + fontrenderer.drawStringWithShadow(mc.func_6262_n(), 2, 22, 0xffffff); + fontrenderer.drawStringWithShadow(mc.func_6245_o(), 2, 32, 0xffffff); + fontrenderer.drawStringWithShadow(mc.func_21002_o(), 2, 42, 0xffffff); + long l2 = Runtime.getRuntime().maxMemory(); + long l4 = Runtime.getRuntime().totalMemory(); + long l6 = Runtime.getRuntime().freeMemory(); + long l7 = l4 - l6; + String s = (new StringBuilder()).append("Used memory: ").append((l7 * 100L) / l2).append("% (").append(l7 / 1024L / 1024L).append("MB) of ").append(l2 / 1024L / 1024L).append("MB").toString(); + drawString(fontrenderer, s, k - fontrenderer.getStringWidth(s) - 2, 2, 0xe0e0e0); + s = (new StringBuilder()).append("Allocated memory: ").append((l4 * 100L) / l2).append("% (").append(l4 / 1024L / 1024L).append("MB)").toString(); + drawString(fontrenderer, s, k - fontrenderer.getStringWidth(s) - 2, 12, 0xe0e0e0); + drawString(fontrenderer, (new StringBuilder()).append("x: ").append(mc.thePlayer.posX).toString(), 2, 64, 0xe0e0e0); + drawString(fontrenderer, (new StringBuilder()).append("y: ").append(mc.thePlayer.posY).toString(), 2, 72, 0xe0e0e0); + drawString(fontrenderer, (new StringBuilder()).append("z: ").append(mc.thePlayer.posZ).toString(), 2, 80, 0xe0e0e0); + } else + { + fontrenderer.drawStringWithShadow("Minecraft Beta 1.3_01", 2, 2, 0xffffff); + } + if(recordPlayingUpFor > 0) + { + float f2 = (float)recordPlayingUpFor - f; + int j3 = (int)((f2 * 256F) / 20F); + if(j3 > 255) + { + j3 = 255; + } + if(j3 > 0) + { + GL11.glPushMatrix(); + GL11.glTranslatef(k / 2, l - 48, 0.0F); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + int k4 = 0xffffff; + if(field_22065_l) + { + k4 = Color.HSBtoRGB(f2 / 50F, 0.7F, 0.6F) & 0xffffff; + } + fontrenderer.drawString(recordPlaying, -fontrenderer.getStringWidth(recordPlaying) / 2, -4, k4 + (j3 << 24)); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glPopMatrix(); + } + } + byte byte0 = 10; + boolean flag2 = false; + if(mc.currentScreen instanceof GuiChat) + { + byte0 = 20; + flag2 = true; + } + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, l - 48, 0.0F); + for(int i5 = 0; i5 < chatMessageList.size() && i5 < byte0; i5++) + { + if(((ChatLine)chatMessageList.get(i5)).updateCounter >= 200 && !flag2) + { + continue; + } + double d = (double)((ChatLine)chatMessageList.get(i5)).updateCounter / 200D; + d = 1.0D - d; + d *= 10D; + if(d < 0.0D) + { + d = 0.0D; + } + if(d > 1.0D) + { + d = 1.0D; + } + d *= d; + int j6 = (int)(255D * d); + if(flag2) + { + j6 = 255; + } + if(j6 > 0) + { + byte byte1 = 2; + int k6 = -i5 * 9; + String s1 = ((ChatLine)chatMessageList.get(i5)).message; + drawRect(byte1, k6 - 1, byte1 + 320, k6 + 8, j6 / 2 << 24); + GL11.glEnable(3042 /*GL_BLEND*/); + fontrenderer.drawStringWithShadow(s1, byte1, k6, 0xffffff + (j6 << 24)); + } + } + + GL11.glPopMatrix(); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glDisable(3042 /*GL_BLEND*/); + } + + private void renderPumpkinBlur(int i, int j) + { + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + GL11.glDepthMask(false); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("%blur%/misc/pumpkinblur.png")); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0.0D, j, -90D, 0.0D, 1.0D); + tessellator.addVertexWithUV(i, j, -90D, 1.0D, 1.0D); + tessellator.addVertexWithUV(i, 0.0D, -90D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0.0D, 0.0D, -90D, 0.0D, 0.0D); + tessellator.draw(); + GL11.glDepthMask(true); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + private void renderVignette(float f, int i, int j) + { + f = 1.0F - f; + if(f < 0.0F) + { + f = 0.0F; + } + if(f > 1.0F) + { + f = 1.0F; + } + prevVignetteBrightness += (double)(f - prevVignetteBrightness) * 0.01D; + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + GL11.glDepthMask(false); + GL11.glBlendFunc(0, 769); + GL11.glColor4f(prevVignetteBrightness, prevVignetteBrightness, prevVignetteBrightness, 1.0F); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("%blur%/misc/vignette.png")); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0.0D, j, -90D, 0.0D, 1.0D); + tessellator.addVertexWithUV(i, j, -90D, 1.0D, 1.0D); + tessellator.addVertexWithUV(i, 0.0D, -90D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0.0D, 0.0D, -90D, 0.0D, 0.0D); + tessellator.draw(); + GL11.glDepthMask(true); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glBlendFunc(770, 771); + } + + private void renderPortalOverlay(float f, int i, int j) + { + f *= f; + f *= f; + f = f * 0.8F + 0.2F; + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + GL11.glDepthMask(false); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(1.0F, 1.0F, 1.0F, f); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/terrain.png")); + float f1 = (float)(Block.portal.blockIndexInTexture % 16) / 16F; + float f2 = (float)(Block.portal.blockIndexInTexture / 16) / 16F; + float f3 = (float)(Block.portal.blockIndexInTexture % 16 + 1) / 16F; + float f4 = (float)(Block.portal.blockIndexInTexture / 16 + 1) / 16F; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0.0D, j, -90D, f1, f4); + tessellator.addVertexWithUV(i, j, -90D, f3, f4); + tessellator.addVertexWithUV(i, 0.0D, -90D, f3, f2); + tessellator.addVertexWithUV(0.0D, 0.0D, -90D, f1, f2); + tessellator.draw(); + GL11.glDepthMask(true); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + private void renderInventorySlot(int i, int j, int k, float f) + { + ItemStack itemstack = mc.thePlayer.inventory.mainInventory[i]; + if(itemstack == null) + { + return; + } + float f1 = (float)itemstack.animationsToGo - f; + if(f1 > 0.0F) + { + GL11.glPushMatrix(); + float f2 = 1.0F + f1 / 5F; + GL11.glTranslatef(j + 8, k + 12, 0.0F); + GL11.glScalef(1.0F / f2, (f2 + 1.0F) / 2.0F, 1.0F); + GL11.glTranslatef(-(j + 8), -(k + 12), 0.0F); + } + itemRenderer.renderItemIntoGUI(mc.fontRenderer, mc.renderEngine, itemstack, j, k); + if(f1 > 0.0F) + { + GL11.glPopMatrix(); + } + itemRenderer.renderItemOverlayIntoGUI(mc.fontRenderer, mc.renderEngine, itemstack, j, k); + } + + public void updateTick() + { + if(recordPlayingUpFor > 0) + { + recordPlayingUpFor--; + } + updateCounter++; + for(int i = 0; i < chatMessageList.size(); i++) + { + ((ChatLine)chatMessageList.get(i)).updateCounter++; + } + + } + + public void addChatMessage(String s) + { + int i; + for(; mc.fontRenderer.getStringWidth(s) > 320; s = s.substring(i)) + { + for(i = 1; i < s.length() && mc.fontRenderer.getStringWidth(s.substring(0, i + 1)) <= 320; i++) { } + addChatMessage(s.substring(0, i)); + } + + chatMessageList.add(0, new ChatLine(s)); + for(; chatMessageList.size() > 50; chatMessageList.remove(chatMessageList.size() - 1)) { } + } + + public void setRecordPlayingMessage(String s) + { + recordPlaying = (new StringBuilder()).append("Now playing: ").append(s).toString(); + recordPlayingUpFor = 60; + field_22065_l = true; + } + + public void func_22064_c(String s) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + String s1 = stringtranslate.translateKey(s); + addChatMessage(s1); + } + + private static RenderItem itemRenderer = new RenderItem(); + private java.util.List chatMessageList; + private Random rand; + private Minecraft mc; + public String field_933_a; + private int updateCounter; + private String recordPlaying; + private int recordPlayingUpFor; + private boolean field_22065_l; + public float field_6446_b; + float prevVignetteBrightness; + +} diff --git a/src/main/java/net/minecraft/src/GuiIngameMenu.java b/src/main/java/net/minecraft/src/GuiIngameMenu.java new file mode 100644 index 0000000..4f693a7 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiIngameMenu.java @@ -0,0 +1,76 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiIngameMenu extends GuiScreen +{ + + public GuiIngameMenu() + { + updateCounter2 = 0; + updateCounter = 0; + } + + public void initGui() + { + updateCounter2 = 0; + controlList.clear(); + controlList.add(new GuiButton(1, width / 2 - 100, height / 4 + 48, "Save and quit to title")); + if(mc.isMultiplayerWorld()) + { + ((GuiButton)controlList.get(0)).displayString = "Disconnect"; + } + controlList.add(new GuiButton(4, width / 2 - 100, height / 4 + 24, "Back to game")); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 96, "Options...")); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(guibutton.id == 0) + { + mc.displayGuiScreen(new GuiOptions(this, mc.gameSettings)); + } + if(guibutton.id == 1) + { + if(mc.isMultiplayerWorld()) + { + mc.theWorld.sendQuittingDisconnectingPacket(); + } + mc.changeWorld1(null); + mc.displayGuiScreen(new GuiMainMenu()); + } + if(guibutton.id == 4) + { + mc.displayGuiScreen(null); + mc.func_6259_e(); + } + } + + public void updateScreen() + { + super.updateScreen(); + updateCounter++; + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + boolean flag = !mc.theWorld.func_650_a(updateCounter2++); + if(flag || updateCounter < 20) + { + float f1 = ((float)(updateCounter % 10) + f) / 10F; + f1 = MathHelper.sin(f1 * 3.141593F * 2.0F) * 0.2F + 0.8F; + int k = (int)(255F * f1); + drawString(fontRenderer, "Saving level..", 8, height - 16, k << 16 | k << 8 | k); + } + drawCenteredString(fontRenderer, "Game menu", width / 2, 40, 0xffffff); + super.drawScreen(i, j, f); + } + + private int updateCounter2; + private int updateCounter; +} diff --git a/src/main/java/net/minecraft/src/GuiInventory.java b/src/main/java/net/minecraft/src/GuiInventory.java new file mode 100644 index 0000000..b269484 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiInventory.java @@ -0,0 +1,69 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiInventory extends GuiContainer +{ + + public GuiInventory(EntityPlayer entityplayer) + { + super(entityplayer.inventorySlots); + field_948_f = true; + } + + protected void drawGuiContainerForegroundLayer() + { + fontRenderer.drawString("Crafting", 86, 16, 0x404040); + } + + public void drawScreen(int i, int j, float f) + { + super.drawScreen(i, j, f); + xSize_lo = i; + ySize_lo = j; + } + + protected void drawGuiContainerBackgroundLayer(float f) + { + int i = mc.renderEngine.getTexture("/gui/inventory.png"); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture(i); + int j = (width - xSize) / 2; + int k = (height - ySize) / 2; + drawTexturedModalRect(j, k, 0, 0, xSize, ySize); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glEnable(2903 /*GL_COLOR_MATERIAL*/); + GL11.glPushMatrix(); + GL11.glTranslatef(j + 51, k + 75, 50F); + float f1 = 30F; + GL11.glScalef(-f1, f1, f1); + GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); + float f2 = mc.thePlayer.renderYawOffset; + float f3 = mc.thePlayer.rotationYaw; + float f4 = mc.thePlayer.rotationPitch; + float f5 = (float)(j + 51) - xSize_lo; + float f6 = (float)((k + 75) - 50) - ySize_lo; + GL11.glRotatef(135F, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + GL11.glRotatef(-135F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-(float)Math.atan(f6 / 40F) * 20F, 1.0F, 0.0F, 0.0F); + mc.thePlayer.renderYawOffset = (float)Math.atan(f5 / 40F) * 20F; + mc.thePlayer.rotationYaw = (float)Math.atan(f5 / 40F) * 40F; + mc.thePlayer.rotationPitch = -(float)Math.atan(f6 / 40F) * 20F; + GL11.glTranslatef(0.0F, mc.thePlayer.yOffset, 0.0F); + RenderManager.instance.renderEntityWithPosYaw(mc.thePlayer, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F); + mc.thePlayer.renderYawOffset = f2; + mc.thePlayer.rotationYaw = f3; + mc.thePlayer.rotationPitch = f4; + GL11.glPopMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + } + + private float xSize_lo; + private float ySize_lo; +} diff --git a/src/main/java/net/minecraft/src/GuiMainMenu.java b/src/main/java/net/minecraft/src/GuiMainMenu.java new file mode 100644 index 0000000..d130fa8 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiMainMenu.java @@ -0,0 +1,265 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.*; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +public class GuiMainMenu extends GuiScreen +{ + + public GuiMainMenu() + { + updateCounter = 0.0F; + splashText = "missingno"; + try + { + ArrayList arraylist = new ArrayList(); + BufferedReader bufferedreader = new BufferedReader(new InputStreamReader((GuiMainMenu.class).getResourceAsStream("/title/splashes.txt"), Charset.forName("UTF-8"))); + String s = ""; + do + { + String s1; + if((s1 = bufferedreader.readLine()) == null) + { + break; + } + s1 = s1.trim(); + if(s1.length() > 0) + { + arraylist.add(s1); + } + } while(true); + splashText = (String)arraylist.get(rand.nextInt(arraylist.size())); + } + catch(Exception exception) { } + } + + public void updateScreen() + { + updateCounter++; + if(logoEffects != null) + { + for(int i = 0; i < logoEffects.length; i++) + { + for(int j = 0; j < logoEffects[i].length; j++) + { + logoEffects[i][j].func_875_a(); + } + + } + + } + } + + protected void keyTyped(char c, int i) + { + } + + public void initGui() + { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + if(calendar.get(2) + 1 == 11 && calendar.get(5) == 9) + { + splashText = "Happy birthday, ez!"; + } else + if(calendar.get(2) + 1 == 6 && calendar.get(5) == 1) + { + splashText = "Happy birthday, Notch!"; + } else + if(calendar.get(2) + 1 == 12 && calendar.get(5) == 24) + { + splashText = "Merry X-mas!"; + } else + if(calendar.get(2) + 1 == 1 && calendar.get(5) == 1) + { + splashText = "Happy new year!"; + } + StringTranslate stringtranslate = StringTranslate.getInstance(); + int i = height / 4 + 48; + controlList.add(new GuiButton(1, width / 2 - 100, i, stringtranslate.translateKey("menu.singleplayer"))); + controlList.add(new GuiButton(2, width / 2 - 100, i + 24, stringtranslate.translateKey("menu.multiplayer"))); + controlList.add(new GuiButton(3, width / 2 - 100, i + 48, stringtranslate.translateKey("menu.mods"))); + if(mc.hideQuitButton) + { + controlList.add(new GuiButton(0, width / 2 - 100, i + 72, stringtranslate.translateKey("menu.options"))); + } else + { + controlList.add(new GuiButton(0, width / 2 - 100, i + 72 + 12, 98, 20, stringtranslate.translateKey("menu.options"))); + controlList.add(new GuiButton(4, width / 2 + 2, i + 72 + 12, 98, 20, stringtranslate.translateKey("menu.quit"))); + } + if(mc.session == null) + { + ((GuiButton)controlList.get(1)).enabled = false; + } + } + + protected void actionPerformed(GuiButton guibutton) + { + if(guibutton.id == 0) + { + mc.displayGuiScreen(new GuiOptions(this, mc.gameSettings)); + } + if(guibutton.id == 1) + { + mc.displayGuiScreen(new GuiSelectWorld(this)); + } + if(guibutton.id == 2) + { + mc.displayGuiScreen(new GuiMultiplayer(this)); + } + if(guibutton.id == 3) + { + mc.displayGuiScreen(new GuiTexturePacks(this)); + } + if(guibutton.id == 4) + { + mc.shutdown(); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + Tessellator tessellator = Tessellator.instance; + drawLogo(f); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/gui/logo.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tessellator.setColorOpaque_I(0xffffff); + GL11.glPushMatrix(); + GL11.glTranslatef(width / 2 + 90, 70F, 0.0F); + GL11.glRotatef(-20F, 0.0F, 0.0F, 1.0F); + float f1 = 1.8F - MathHelper.abs(MathHelper.sin(((float)(System.currentTimeMillis() % 1000L) / 1000F) * 3.141593F * 2.0F) * 0.1F); + f1 = (f1 * 100F) / (float)(fontRenderer.getStringWidth(splashText) + 32); + GL11.glScalef(f1, f1, f1); + drawCenteredString(fontRenderer, splashText, 0, -8, 0xffff00); + GL11.glPopMatrix(); + drawString(fontRenderer, "Minecraft Beta 1.3_01", 2, 2, 0x505050); + String s = "Copyright Mojang AB. Do not distribute."; + drawString(fontRenderer, s, width - fontRenderer.getStringWidth(s) - 2, height - 10, 0xffffff); + super.drawScreen(i, j, f); + } + + private void drawLogo(float f) + { + if(logoEffects == null) + { + logoEffects = new LogoEffectRandomizer[minecraftLogo[0].length()][minecraftLogo.length]; + for(int i = 0; i < logoEffects.length; i++) + { + for(int j = 0; j < logoEffects[i].length; j++) + { + logoEffects[i][j] = new LogoEffectRandomizer(this, i, j); + } + + } + + } + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + ScaledResolution scaledresolution = new ScaledResolution(mc.displayWidth, mc.displayHeight); + int k = 120 * scaledresolution.scaleFactor; + GLU.gluPerspective(70F, (float)mc.displayWidth / (float)k, 0.05F, 100F); + GL11.glViewport(0, mc.displayHeight - k, mc.displayWidth, k); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glPushMatrix(); + GL11.glLoadIdentity(); + GL11.glDisable(2884 /*GL_CULL_FACE*/); + GL11.glCullFace(1029 /*GL_BACK*/); + GL11.glDepthMask(true); + RenderBlocks renderblocks = new RenderBlocks(); + for(int l = 0; l < 3; l++) + { + GL11.glPushMatrix(); + GL11.glTranslatef(0.4F, 0.6F, -13F); + if(l == 0) + { + GL11.glClear(256); + GL11.glTranslatef(0.0F, -0.4F, 0.0F); + GL11.glScalef(0.98F, 1.0F, 1.0F); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + } + if(l == 1) + { + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glClear(256); + } + if(l == 2) + { + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(768, 1); + } + GL11.glScalef(1.0F, -1F, 1.0F); + GL11.glRotatef(15F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(0.89F, 1.0F, 0.4F); + GL11.glTranslatef((float)(-minecraftLogo[0].length()) * 0.5F, (float)(-minecraftLogo.length) * 0.5F, 0.0F); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/terrain.png")); + if(l == 0) + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/title/black.png")); + } + for(int i1 = 0; i1 < minecraftLogo.length; i1++) + { + for(int j1 = 0; j1 < minecraftLogo[i1].length(); j1++) + { + char c = minecraftLogo[i1].charAt(j1); + if(c == ' ') + { + continue; + } + GL11.glPushMatrix(); + LogoEffectRandomizer logoeffectrandomizer = logoEffects[j1][i1]; + float f1 = (float)(logoeffectrandomizer.field_1311_b + (logoeffectrandomizer.field_1312_a - logoeffectrandomizer.field_1311_b) * (double)f); + float f2 = 1.0F; + float f3 = 1.0F; + float f4 = 0.0F; + if(l == 0) + { + f2 = f1 * 0.04F + 1.0F; + f3 = 1.0F / f2; + f1 = 0.0F; + } + GL11.glTranslatef(j1, i1, f1); + GL11.glScalef(f2, f2, f2); + GL11.glRotatef(f4, 0.0F, 1.0F, 0.0F); + renderblocks.func_1238_a(Block.stone, f3); + GL11.glPopMatrix(); + } + + } + + GL11.glPopMatrix(); + } + + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glPopMatrix(); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glPopMatrix(); + GL11.glViewport(0, 0, mc.displayWidth, mc.displayHeight); + GL11.glEnable(2884 /*GL_CULL_FACE*/); + } + + static Random getRand() + { + return rand; + } + + private static final Random rand = new Random(); + String minecraftLogo[] = { + " * * * * * *** *** *** *** *** ***", " ** ** * ** * * * * * * * * * ", " * * * * * * * ** * ** *** ** * ", " * * * * ** * * * * * * * * ", " * * * * * *** *** * * * * * * " + }; + private LogoEffectRandomizer logoEffects[][]; + private float updateCounter; + private String splashText; + +} diff --git a/src/main/java/net/minecraft/src/GuiMultiplayer.java b/src/main/java/net/minecraft/src/GuiMultiplayer.java new file mode 100644 index 0000000..ad3a4d3 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiMultiplayer.java @@ -0,0 +1,104 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Keyboard; + +public class GuiMultiplayer extends GuiScreen +{ + + public GuiMultiplayer(GuiScreen guiscreen) + { + parentScreen = guiscreen; + } + + public void updateScreen() + { + field_22111_h.func_22070_b(); + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + Keyboard.enableRepeatEvents(true); + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 96 + 12, stringtranslate.translateKey("multiplayer.connect"))); + controlList.add(new GuiButton(1, width / 2 - 100, height / 4 + 120 + 12, stringtranslate.translateKey("gui.cancel"))); + String s = mc.gameSettings.lastServer.replaceAll("_", ":"); + ((GuiButton)controlList.get(0)).enabled = s.length() > 0; + field_22111_h = new GuiDisableButton(fontRenderer, width / 2 - 100, (height / 4 - 10) + 50 + 18, 200, 20, s); + field_22111_h.field_22082_a = true; + field_22111_h.func_22066_a(32); + } + + public void onGuiClosed() + { + Keyboard.enableRepeatEvents(false); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == 1) + { + mc.displayGuiScreen(parentScreen); + } else + if(guibutton.id == 0) + { + String s = field_22111_h.func_22071_a(); + mc.gameSettings.lastServer = s.replaceAll(":", "_"); + mc.gameSettings.saveOptions(); + String as[] = s.split(":"); + mc.displayGuiScreen(new GuiConnecting(mc, as[0], as.length <= 1 ? 25565 : func_4067_a(as[1], 25565))); + } + } + + private int func_4067_a(String s, int i) + { + try + { + return Integer.parseInt(s.trim()); + } + catch(Exception exception) + { + return i; + } + } + + protected void keyTyped(char c, int i) + { + field_22111_h.func_22072_a(c, i); + if(c == '\r') + { + actionPerformed((GuiButton)controlList.get(0)); + } + ((GuiButton)controlList.get(0)).enabled = field_22111_h.func_22071_a().length() > 0; + } + + protected void mouseClicked(int i, int j, int k) + { + super.mouseClicked(i, j, k); + field_22111_h.func_22069_a(i, j, k); + } + + public void drawScreen(int i, int j, float f) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + drawDefaultBackground(); + drawCenteredString(fontRenderer, stringtranslate.translateKey("multiplayer.title"), width / 2, (height / 4 - 60) + 20, 0xffffff); + drawString(fontRenderer, stringtranslate.translateKey("multiplayer.info1"), width / 2 - 140, (height / 4 - 60) + 60 + 0, 0xa0a0a0); + drawString(fontRenderer, stringtranslate.translateKey("multiplayer.info2"), width / 2 - 140, (height / 4 - 60) + 60 + 9, 0xa0a0a0); + drawString(fontRenderer, stringtranslate.translateKey("multiplayer.ipinfo"), width / 2 - 140, (height / 4 - 60) + 60 + 36, 0xa0a0a0); + field_22111_h.func_22067_c(); + super.drawScreen(i, j, f); + } + + private GuiScreen parentScreen; + private GuiDisableButton field_22111_h; +} diff --git a/src/main/java/net/minecraft/src/GuiOptions.java b/src/main/java/net/minecraft/src/GuiOptions.java new file mode 100644 index 0000000..38cfb12 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiOptions.java @@ -0,0 +1,90 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiOptions extends GuiScreen +{ + + public GuiOptions(GuiScreen guiscreen, GameSettings gamesettings) + { + screenTitle = "Options"; + parentScreen = guiscreen; + options = gamesettings; + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + screenTitle = stringtranslate.translateKey("options.title"); + int i = 0; + EnumOptions aenumoptions[] = field_22135_k; + int j = aenumoptions.length; + for(int k = 0; k < j; k++) + { + EnumOptions enumoptions = aenumoptions[k]; + if(!enumoptions.getEnumFloat()) + { + controlList.add(new GuiSmallButton(enumoptions.returnEnumOrdinal(), (width / 2 - 155) + (i % 2) * 160, height / 6 + 24 * (i >> 1), enumoptions, options.getKeyBinding(enumoptions))); + } else + { + controlList.add(new GuiSlider(enumoptions.returnEnumOrdinal(), (width / 2 - 155) + (i % 2) * 160, height / 6 + 24 * (i >> 1), enumoptions, options.getKeyBinding(enumoptions), options.getOptionFloatValue(enumoptions))); + } + i++; + } + + controlList.add(new GuiButton(101, width / 2 - 100, height / 6 + 96 + 12, stringtranslate.translateKey("options.video"))); + controlList.add(new GuiButton(100, width / 2 - 100, height / 6 + 120 + 12, stringtranslate.translateKey("options.controls"))); + controlList.add(new GuiButton(200, width / 2 - 100, height / 6 + 168, stringtranslate.translateKey("gui.done"))); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id < 100 && (guibutton instanceof GuiSmallButton)) + { + options.setOptionValue(((GuiSmallButton)guibutton).returnEnumOptions(), 1); + guibutton.displayString = options.getKeyBinding(EnumOptions.func_20137_a(guibutton.id)); + } + if(guibutton.id == 101) + { + mc.gameSettings.saveOptions(); + mc.displayGuiScreen(new GuiVideoSettings(this, options)); + } + if(guibutton.id == 100) + { + mc.gameSettings.saveOptions(); + mc.displayGuiScreen(new GuiControls(this, options)); + } + if(guibutton.id == 200) + { + mc.gameSettings.saveOptions(); + mc.displayGuiScreen(parentScreen); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, screenTitle, width / 2, 20, 0xffffff); + super.drawScreen(i, j, f); + } + + private GuiScreen parentScreen; + protected String screenTitle; + private GameSettings options; + private static EnumOptions field_22135_k[]; + + static + { + field_22135_k = (new EnumOptions[] { + EnumOptions.MUSIC, EnumOptions.SOUND, EnumOptions.INVERT_MOUSE, EnumOptions.SENSITIVITY, EnumOptions.DIFFICULTY + }); + } +} diff --git a/src/main/java/net/minecraft/src/GuiRenameWorld.java b/src/main/java/net/minecraft/src/GuiRenameWorld.java new file mode 100644 index 0000000..ffb4aae --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiRenameWorld.java @@ -0,0 +1,91 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Keyboard; + +public class GuiRenameWorld extends GuiScreen +{ + + public GuiRenameWorld(GuiScreen guiscreen, String s) + { + field_22112_a = guiscreen; + field_22113_i = s; + } + + public void updateScreen() + { + field_22114_h.func_22070_b(); + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + Keyboard.enableRepeatEvents(true); + controlList.clear(); + controlList.add(new GuiButton(0, width / 2 - 100, height / 4 + 96 + 12, stringtranslate.translateKey("selectWorld.renameButton"))); + controlList.add(new GuiButton(1, width / 2 - 100, height / 4 + 120 + 12, stringtranslate.translateKey("gui.cancel"))); + ISaveFormat isaveformat = mc.func_22004_c(); + WorldInfo worldinfo = isaveformat.func_22173_b(field_22113_i); + String s = worldinfo.getWorldName(); + field_22114_h = new GuiDisableButton(fontRenderer, width / 2 - 100, 60, 200, 20, s); + field_22114_h.field_22082_a = true; + field_22114_h.func_22066_a(32); + } + + public void onGuiClosed() + { + Keyboard.enableRepeatEvents(false); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == 1) + { + mc.displayGuiScreen(field_22112_a); + } else + if(guibutton.id == 0) + { + ISaveFormat isaveformat = mc.func_22004_c(); + isaveformat.func_22170_a(field_22113_i, field_22114_h.func_22071_a().trim()); + mc.displayGuiScreen(field_22112_a); + } + } + + protected void keyTyped(char c, int i) + { + field_22114_h.func_22072_a(c, i); + ((GuiButton)controlList.get(0)).enabled = field_22114_h.func_22071_a().trim().length() > 0; + if(c == '\r') + { + actionPerformed((GuiButton)controlList.get(0)); + } + } + + protected void mouseClicked(int i, int j, int k) + { + super.mouseClicked(i, j, k); + field_22114_h.func_22069_a(i, j, k); + } + + public void drawScreen(int i, int j, float f) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + drawDefaultBackground(); + drawCenteredString(fontRenderer, stringtranslate.translateKey("selectWorld.renameTitle"), width / 2, (height / 4 - 60) + 20, 0xffffff); + drawString(fontRenderer, stringtranslate.translateKey("selectWorld.enterName"), width / 2 - 100, 47, 0xa0a0a0); + field_22114_h.func_22067_c(); + super.drawScreen(i, j, f); + } + + private GuiScreen field_22112_a; + private GuiDisableButton field_22114_h; + private final String field_22113_i; +} diff --git a/src/main/java/net/minecraft/src/GuiScreen.java b/src/main/java/net/minecraft/src/GuiScreen.java new file mode 100644 index 0000000..ff0b1bd --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiScreen.java @@ -0,0 +1,196 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.util.ArrayList; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +public class GuiScreen extends Gui +{ + + public GuiScreen() + { + controlList = new ArrayList(); + field_948_f = false; + selectedButton = null; + } + + public void drawScreen(int i, int j, float f) + { + for(int k = 0; k < controlList.size(); k++) + { + GuiButton guibutton = (GuiButton)controlList.get(k); + guibutton.drawButton(mc, i, j); + } + + } + + protected void keyTyped(char c, int i) + { + if(i == 1) + { + mc.displayGuiScreen(null); + mc.func_6259_e(); + } + } + + public static String getClipboardString() + { + try + { + Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); + if(transferable != null && transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) + { + String s = (String)transferable.getTransferData(DataFlavor.stringFlavor); + return s; + } + } + catch(Exception exception) { } + return null; + } + + protected void mouseClicked(int i, int j, int k) + { + if(k == 0) + { + for(int l = 0; l < controlList.size(); l++) + { + GuiButton guibutton = (GuiButton)controlList.get(l); + if(guibutton.mousePressed(mc, i, j)) + { + selectedButton = guibutton; + mc.sndManager.func_337_a("random.click", 1.0F, 1.0F); + actionPerformed(guibutton); + } + } + + } + } + + protected void mouseMovedOrUp(int i, int j, int k) + { + if(selectedButton != null && k == 0) + { + selectedButton.mouseReleased(i, j); + selectedButton = null; + } + } + + protected void actionPerformed(GuiButton guibutton) + { + } + + public void setWorldAndResolution(Minecraft minecraft, int i, int j) + { + mc = minecraft; + fontRenderer = minecraft.fontRenderer; + width = i; + height = j; + controlList.clear(); + initGui(); + } + + public void initGui() + { + } + + public void handleInput() + { + for(; Mouse.next(); handleMouseInput()) { } + for(; Keyboard.next(); handleKeyboardInput()) { } + } + + public void handleMouseInput() + { + if(Mouse.getEventButtonState()) + { + int i = (Mouse.getEventX() * width) / mc.displayWidth; + int k = height - (Mouse.getEventY() * height) / mc.displayHeight - 1; + mouseClicked(i, k, Mouse.getEventButton()); + } else + { + int j = (Mouse.getEventX() * width) / mc.displayWidth; + int l = height - (Mouse.getEventY() * height) / mc.displayHeight - 1; + mouseMovedOrUp(j, l, Mouse.getEventButton()); + } + } + + public void handleKeyboardInput() + { + if(Keyboard.getEventKeyState()) + { + if(Keyboard.getEventKey() == 87) + { + mc.toggleFullscreen(); + return; + } + keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); + } + } + + public void updateScreen() + { + } + + public void onGuiClosed() + { + } + + public void drawDefaultBackground() + { + drawWorldBackground(0); + } + + public void drawWorldBackground(int i) + { + if(mc.theWorld != null) + { + drawGradientRect(0, 0, width, height, 0xc0101010, 0xd0101010); + } else + { + drawBackground(i); + } + } + + public void drawBackground(int i) + { + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2912 /*GL_FOG*/); + Tessellator tessellator = Tessellator.instance; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/gui/background.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float f = 32F; + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0x404040); + tessellator.addVertexWithUV(0.0D, height, 0.0D, 0.0D, (float)height / f + (float)i); + tessellator.addVertexWithUV(width, height, 0.0D, (float)width / f, (float)height / f + (float)i); + tessellator.addVertexWithUV(width, 0.0D, 0.0D, (float)width / f, 0 + i); + tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, 0 + i); + tessellator.draw(); + } + + public boolean doesGuiPauseGame() + { + return true; + } + + public void deleteWorld(boolean flag, int i) + { + } + + protected Minecraft mc; + public int width; + public int height; + protected java.util.List controlList; + public boolean field_948_f; + protected FontRenderer fontRenderer; + private GuiButton selectedButton; +} diff --git a/src/main/java/net/minecraft/src/GuiSelectWorld.java b/src/main/java/net/minecraft/src/GuiSelectWorld.java new file mode 100644 index 0000000..939836c --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSelectWorld.java @@ -0,0 +1,212 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiSelectWorld extends GuiScreen +{ + + public GuiSelectWorld(GuiScreen guiscreen) + { + screenTitle = "Select world"; + selected = false; + parentScreen = guiscreen; + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + screenTitle = stringtranslate.translateKey("selectWorld.title"); + field_22098_o = stringtranslate.translateKey("selectWorld.world"); + field_22097_p = stringtranslate.translateKey("selectWorld.conversion"); + func_22084_k(); + field_22099_n = new GuiWorldSlot(this); + field_22099_n.func_22240_a(controlList, 4, 5); + initGui2(); + } + + private void func_22084_k() + { + ISaveFormat isaveformat = mc.func_22004_c(); + field_22100_m = isaveformat.func_22176_b(); + Collections.sort(field_22100_m); + field_22101_l = -1; + } + + protected String func_22091_c(int i) + { + return ((SaveFormatComparator)field_22100_m.get(i)).func_22164_a(); + } + + protected String func_22094_d(int i) + { + String s = ((SaveFormatComparator)field_22100_m.get(i)).func_22162_b(); + if(s == null || MathHelper.func_22282_a(s)) + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + s = (new StringBuilder()).append(stringtranslate.translateKey("selectWorld.world")).append(" ").append(i + 1).toString(); + } + return s; + } + + public void initGui2() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + controlList.add(field_22104_s = new GuiButton(1, width / 2 - 154, height - 52, 150, 20, stringtranslate.translateKey("selectWorld.select"))); + controlList.add(field_22095_r = new GuiButton(6, width / 2 - 154, height - 28, 70, 20, stringtranslate.translateKey("selectWorld.rename"))); + controlList.add(field_22103_t = new GuiButton(2, width / 2 - 74, height - 28, 70, 20, stringtranslate.translateKey("selectWorld.delete"))); + controlList.add(new GuiButton(3, width / 2 + 4, height - 52, 150, 20, stringtranslate.translateKey("selectWorld.create"))); + controlList.add(new GuiButton(0, width / 2 + 4, height - 28, 150, 20, stringtranslate.translateKey("gui.cancel"))); + field_22104_s.enabled = false; + field_22095_r.enabled = false; + field_22103_t.enabled = false; + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == 2) + { + String s = func_22094_d(field_22101_l); + if(s != null) + { + field_22096_q = true; + StringTranslate stringtranslate = StringTranslate.getInstance(); + String s1 = stringtranslate.translateKey("selectWorld.deleteQuestion"); + String s2 = (new StringBuilder()).append("'").append(s).append("' ").append(stringtranslate.translateKey("selectWorld.deleteWarning")).toString(); + String s3 = stringtranslate.translateKey("selectWorld.deleteButton"); + String s4 = stringtranslate.translateKey("gui.cancel"); + GuiYesNo guiyesno = new GuiYesNo(this, s1, s2, s3, s4, field_22101_l); + mc.displayGuiScreen(guiyesno); + } + } else + if(guibutton.id == 1) + { + selectWorld(field_22101_l); + } else + if(guibutton.id == 3) + { + mc.displayGuiScreen(new GuiCreateWorld(this)); + } else + if(guibutton.id == 6) + { + mc.displayGuiScreen(new GuiRenameWorld(this, func_22091_c(field_22101_l))); + } else + if(guibutton.id == 0) + { + mc.displayGuiScreen(parentScreen); + } else + { + field_22099_n.func_22241_a(guibutton); + } + } + + public void selectWorld(int i) + { + mc.displayGuiScreen(null); + if(selected) + { + return; + } + selected = true; + mc.playerController = new PlayerControllerSP(mc); + String s = func_22091_c(i); + if(s == null) + { + s = (new StringBuilder()).append("World").append(i).toString(); + } + mc.startWorld(s, func_22094_d(i), 0L); + mc.displayGuiScreen(null); + } + + public void deleteWorld(boolean flag, int i) + { + if(field_22096_q) + { + field_22096_q = false; + if(flag) + { + ISaveFormat isaveformat = mc.func_22004_c(); + isaveformat.func_22177_c(); + isaveformat.func_22172_c(func_22091_c(i)); + func_22084_k(); + } + mc.displayGuiScreen(this); + } + } + + public void drawScreen(int i, int j, float f) + { + field_22099_n.func_22243_a(i, j, f); + drawCenteredString(fontRenderer, screenTitle, width / 2, 20, 0xffffff); + super.drawScreen(i, j, f); + } + + static List func_22090_a(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22100_m; + } + + static int func_22089_a(GuiSelectWorld guiselectworld, int i) + { + return guiselectworld.field_22101_l = i; + } + + static int func_22086_b(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22101_l; + } + + static GuiButton func_22083_c(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22104_s; + } + + static GuiButton func_22085_d(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22095_r; + } + + static GuiButton func_22092_e(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22103_t; + } + + static String func_22087_f(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22098_o; + } + + static DateFormat func_22093_g(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22102_i; + } + + static String func_22088_h(GuiSelectWorld guiselectworld) + { + return guiselectworld.field_22097_p; + } + + private final DateFormat field_22102_i = new SimpleDateFormat(); + protected GuiScreen parentScreen; + protected String screenTitle; + private boolean selected; + private int field_22101_l; + private List field_22100_m; + private GuiWorldSlot field_22099_n; + private String field_22098_o; + private String field_22097_p; + private boolean field_22096_q; + private GuiButton field_22095_r; + private GuiButton field_22104_s; + private GuiButton field_22103_t; +} diff --git a/src/main/java/net/minecraft/src/GuiSleepMP.java b/src/main/java/net/minecraft/src/GuiSleepMP.java new file mode 100644 index 0000000..404c5a0 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSleepMP.java @@ -0,0 +1,73 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Keyboard; + +public class GuiSleepMP extends GuiChat +{ + + public GuiSleepMP() + { + } + + public void initGui() + { + Keyboard.enableRepeatEvents(true); + StringTranslate stringtranslate = StringTranslate.getInstance(); + controlList.add(new GuiButton(1, width / 2 - 100, height - 40, stringtranslate.translateKey("multiplayer.stopSleeping"))); + } + + public void onGuiClosed() + { + Keyboard.enableRepeatEvents(false); + } + + protected void keyTyped(char c, int i) + { + if(i == 1) + { + func_22115_j(); + } else + if(i == 28) + { + String s = field_985_a.trim(); + if(s.length() > 0) + { + mc.thePlayer.sendChatMessage(field_985_a.trim()); + } + field_985_a = ""; + } else + { + super.keyTyped(c, i); + } + } + + public void drawScreen(int i, int j, float f) + { + super.drawScreen(i, j, f); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(guibutton.id == 1) + { + func_22115_j(); + } else + { + super.actionPerformed(guibutton); + } + } + + private void func_22115_j() + { + if(mc.thePlayer instanceof EntityClientPlayerMP) + { + NetClientHandler netclienthandler = ((EntityClientPlayerMP)mc.thePlayer).sendQueue; + netclienthandler.addToSendQueue(new Packet19(mc.thePlayer, 3)); + } + } +} diff --git a/src/main/java/net/minecraft/src/GuiSlider.java b/src/main/java/net/minecraft/src/GuiSlider.java new file mode 100644 index 0000000..d2a1a2f --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlider.java @@ -0,0 +1,83 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class GuiSlider extends GuiButton +{ + + public GuiSlider(int i, int j, int k, EnumOptions enumoptions, String s, float f) + { + super(i, j, k, 150, 20, s); + sliderValue = 1.0F; + dragging = false; + idFloat = null; + idFloat = enumoptions; + sliderValue = f; + } + + protected int getHoverState(boolean flag) + { + return 0; + } + + protected void mouseDragged(Minecraft minecraft, int i, int j) + { + if(!enabled2) + { + return; + } + if(dragging) + { + sliderValue = (float)(i - (xPosition + 4)) / (float)(width - 8); + if(sliderValue < 0.0F) + { + sliderValue = 0.0F; + } + if(sliderValue > 1.0F) + { + sliderValue = 1.0F; + } + minecraft.gameSettings.setOptionFloatValue(idFloat, sliderValue); + displayString = minecraft.gameSettings.getKeyBinding(idFloat); + } + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + drawTexturedModalRect(xPosition + (int)(sliderValue * (float)(width - 8)), yPosition, 0, 66, 4, 20); + drawTexturedModalRect(xPosition + (int)(sliderValue * (float)(width - 8)) + 4, yPosition, 196, 66, 4, 20); + } + + public boolean mousePressed(Minecraft minecraft, int i, int j) + { + if(super.mousePressed(minecraft, i, j)) + { + sliderValue = (float)(i - (xPosition + 4)) / (float)(width - 8); + if(sliderValue < 0.0F) + { + sliderValue = 0.0F; + } + if(sliderValue > 1.0F) + { + sliderValue = 1.0F; + } + minecraft.gameSettings.setOptionFloatValue(idFloat, sliderValue); + displayString = minecraft.gameSettings.getKeyBinding(idFloat); + dragging = true; + return true; + } else + { + return false; + } + } + + public void mouseReleased(int i, int j) + { + dragging = false; + } + + public float sliderValue; + public boolean dragging; + private EnumOptions idFloat; +} diff --git a/src/main/java/net/minecraft/src/GuiSlot.java b/src/main/java/net/minecraft/src/GuiSlot.java new file mode 100644 index 0000000..d52bc3b --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSlot.java @@ -0,0 +1,284 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +public abstract class GuiSlot +{ + + public GuiSlot(Minecraft minecraft, int i, int j, int k, int l, int i1) + { + field_22254_k = -2F; + field_22251_n = -1; + field_22250_o = 0L; + field_22264_a = minecraft; + field_22263_b = i; + field_22262_c = j; + field_22261_d = k; + field_22260_e = l; + field_22257_h = i1; + field_22259_f = i; + } + + protected abstract int func_22249_a(); + + protected abstract void func_22247_a(int i, boolean flag); + + protected abstract boolean func_22246_a(int i); + + protected abstract int func_22245_b(); + + protected abstract void func_22248_c(); + + protected abstract void func_22242_a(int i, int j, int k, int l, Tessellator tessellator); + + public void func_22240_a(List list, int i, int j) + { + field_22256_i = i; + field_22255_j = j; + } + + private void func_22244_d() + { + int i = func_22245_b() - (field_22260_e - field_22261_d - 4); + if(i < 0) + { + i /= 2; + } + if(field_22252_m < 0.0F) + { + field_22252_m = 0.0F; + } + if(field_22252_m > (float)i) + { + field_22252_m = i; + } + } + + public void func_22241_a(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == field_22256_i) + { + field_22252_m -= (field_22257_h * 2) / 3; + field_22254_k = -2F; + func_22244_d(); + } else + if(guibutton.id == field_22255_j) + { + field_22252_m += (field_22257_h * 2) / 3; + field_22254_k = -2F; + func_22244_d(); + } + } + + public void func_22243_a(int i, int j, float f) + { + func_22248_c(); + int k = func_22249_a(); + int l = field_22263_b / 2 + 124; + int i1 = l + 6; + if(Mouse.isButtonDown(0)) + { + if(field_22254_k == -1F) + { + if(j >= field_22261_d && j <= field_22260_e) + { + int j1 = field_22263_b / 2 - 110; + int k1 = field_22263_b / 2 + 110; + int l1 = (((j - field_22261_d) + (int)field_22252_m) - 2) / field_22257_h; + if(i >= j1 && i <= k1 && l1 >= 0 && l1 < k) + { + boolean flag = l1 == field_22251_n && System.currentTimeMillis() - field_22250_o < 250L; + func_22247_a(l1, flag); + field_22251_n = l1; + field_22250_o = System.currentTimeMillis(); + } + if(i >= l && i <= i1) + { + field_22253_l = -1F; + int j2 = func_22245_b() - (field_22260_e - field_22261_d - 4); + if(j2 < 1) + { + j2 = 1; + } + int i3 = ((field_22260_e - field_22261_d) * (field_22260_e - field_22261_d)) / func_22245_b(); + if(i3 < 32) + { + i3 = 32; + } + if(i3 > field_22260_e - field_22261_d - 8) + { + i3 = field_22260_e - field_22261_d - 8; + } + field_22253_l /= (float)(field_22260_e - field_22261_d - i3) / (float)j2; + } else + { + field_22253_l = 1.0F; + } + field_22254_k = j; + } else + { + field_22254_k = -2F; + } + } else + if(field_22254_k >= 0.0F) + { + field_22252_m -= ((float)j - field_22254_k) * field_22253_l; + field_22254_k = j; + } + } else + { + field_22254_k = -1F; + } + func_22244_d(); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2912 /*GL_FOG*/); + Tessellator tessellator = Tessellator.instance; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, field_22264_a.renderEngine.getTexture("/gui/background.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float f1 = 32F; + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0x202020); + tessellator.addVertexWithUV(field_22258_g, field_22260_e, 0.0D, (float)field_22258_g / f1, (float)(field_22260_e + (int)field_22252_m) / f1); + tessellator.addVertexWithUV(field_22259_f, field_22260_e, 0.0D, (float)field_22259_f / f1, (float)(field_22260_e + (int)field_22252_m) / f1); + tessellator.addVertexWithUV(field_22259_f, field_22261_d, 0.0D, (float)field_22259_f / f1, (float)(field_22261_d + (int)field_22252_m) / f1); + tessellator.addVertexWithUV(field_22258_g, field_22261_d, 0.0D, (float)field_22258_g / f1, (float)(field_22261_d + (int)field_22252_m) / f1); + tessellator.draw(); + for(int i2 = 0; i2 < k; i2++) + { + int k2 = field_22263_b / 2 - 92 - 16; + int j3 = (field_22261_d + 4 + i2 * field_22257_h) - (int)field_22252_m; + byte byte1 = 32; + if(func_22246_a(i2)) + { + int i4 = field_22263_b / 2 - 110; + int j4 = field_22263_b / 2 + 110; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0x808080); + tessellator.addVertexWithUV(i4, j3 + byte1 + 2, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(j4, j3 + byte1 + 2, 0.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV(j4, j3 - 2, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(i4, j3 - 2, 0.0D, 0.0D, 0.0D); + tessellator.setColorOpaque_I(0); + tessellator.addVertexWithUV(i4 + 1, j3 + byte1 + 1, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(j4 - 1, j3 + byte1 + 1, 0.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV(j4 - 1, j3 - 1, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(i4 + 1, j3 - 1, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + func_22242_a(i2, k2, j3, byte1, tessellator); + } + + byte byte0 = 4; + func_22239_a(0, field_22261_d, 255, 255); + func_22239_a(field_22260_e, field_22262_c, 255, 255); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glShadeModel(7425 /*GL_SMOOTH*/); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(field_22258_g, field_22261_d + byte0, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(field_22259_f, field_22261_d + byte0, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(field_22259_f, field_22261_d, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(field_22258_g, field_22261_d, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(field_22258_g, field_22260_e, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(field_22259_f, field_22260_e, 0.0D, 1.0D, 1.0D); + tessellator.setColorRGBA_I(0, 0); + tessellator.addVertexWithUV(field_22259_f, field_22260_e - byte0, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(field_22258_g, field_22260_e - byte0, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + int l2 = func_22245_b() - (field_22260_e - field_22261_d - 4); + if(l2 > 0) + { + int k3 = ((field_22260_e - field_22261_d) * (field_22260_e - field_22261_d)) / func_22245_b(); + if(k3 < 32) + { + k3 = 32; + } + if(k3 > field_22260_e - field_22261_d - 8) + { + k3 = field_22260_e - field_22261_d - 8; + } + int l3 = ((int)field_22252_m * (field_22260_e - field_22261_d - k3)) / l2 + field_22261_d; + if(l3 < field_22261_d) + { + l3 = field_22261_d; + } + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0, 255); + tessellator.addVertexWithUV(l, field_22260_e, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(i1, field_22260_e, 0.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV(i1, field_22261_d, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(l, field_22261_d, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0x808080, 255); + tessellator.addVertexWithUV(l, l3 + k3, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(i1, l3 + k3, 0.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV(i1, l3, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(l, l3, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0xc0c0c0, 255); + tessellator.addVertexWithUV(l, (l3 + k3) - 1, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(i1 - 1, (l3 + k3) - 1, 0.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV(i1 - 1, l3, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(l, l3, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + } + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glShadeModel(7424 /*GL_FLAT*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glDisable(3042 /*GL_BLEND*/); + } + + private void func_22239_a(int i, int j, int k, int l) + { + Tessellator tessellator = Tessellator.instance; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, field_22264_a.renderEngine.getTexture("/gui/background.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + float f = 32F; + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_I(0x404040, l); + tessellator.addVertexWithUV(0.0D, j, 0.0D, 0.0D, (float)j / f); + tessellator.addVertexWithUV(field_22263_b, j, 0.0D, (float)field_22263_b / f, (float)j / f); + tessellator.setColorRGBA_I(0x404040, k); + tessellator.addVertexWithUV(field_22263_b, i, 0.0D, (float)field_22263_b / f, (float)i / f); + tessellator.addVertexWithUV(0.0D, i, 0.0D, 0.0D, (float)i / f); + tessellator.draw(); + } + + private final Minecraft field_22264_a; + private final int field_22263_b; + private final int field_22262_c; + private final int field_22261_d; + private final int field_22260_e; + private final int field_22259_f; + private final int field_22258_g = 0; + private final int field_22257_h; + private int field_22256_i; + private int field_22255_j; + private float field_22254_k; + private float field_22253_l; + private float field_22252_m; + private int field_22251_n; + private long field_22250_o; +} diff --git a/src/main/java/net/minecraft/src/GuiSmallButton.java b/src/main/java/net/minecraft/src/GuiSmallButton.java new file mode 100644 index 0000000..9f41ac3 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiSmallButton.java @@ -0,0 +1,33 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class GuiSmallButton extends GuiButton +{ + + public GuiSmallButton(int i, int j, int k, String s) + { + this(i, j, k, null, s); + } + + public GuiSmallButton(int i, int j, int k, int l, int i1, String s) + { + super(i, j, k, l, i1, s); + enumOptions = null; + } + + public GuiSmallButton(int i, int j, int k, EnumOptions enumoptions, String s) + { + super(i, j, k, 150, 20, s); + enumOptions = enumoptions; + } + + public EnumOptions returnEnumOptions() + { + return enumOptions; + } + + private final EnumOptions enumOptions; +} diff --git a/src/main/java/net/minecraft/src/GuiTexturePackSlot.java b/src/main/java/net/minecraft/src/GuiTexturePackSlot.java new file mode 100644 index 0000000..8ec1ee8 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiTexturePackSlot.java @@ -0,0 +1,66 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +class GuiTexturePackSlot extends GuiSlot +{ + + public GuiTexturePackSlot(GuiTexturePacks guitexturepacks) + { + super(GuiTexturePacks.func_22124_a(guitexturepacks), guitexturepacks.width, guitexturepacks.height, 32, (guitexturepacks.height - 55) + 4, 36); + field_22265_a = guitexturepacks; + } + + protected int func_22249_a() + { + List list = GuiTexturePacks.func_22126_b(field_22265_a).texturePackList.availableTexturePacks(); + return list.size(); + } + + protected void func_22247_a(int i, boolean flag) + { + List list = GuiTexturePacks.func_22119_c(field_22265_a).texturePackList.availableTexturePacks(); + GuiTexturePacks.func_22122_d(field_22265_a).texturePackList.setTexturePack((TexturePackBase)list.get(i)); + GuiTexturePacks.func_22117_e(field_22265_a).renderEngine.refreshTextures(); + } + + protected boolean func_22246_a(int i) + { + List list = GuiTexturePacks.func_22118_f(field_22265_a).texturePackList.availableTexturePacks(); + return GuiTexturePacks.func_22116_g(field_22265_a).texturePackList.selectedTexturePack == list.get(i); + } + + protected int func_22245_b() + { + return func_22249_a() * 36; + } + + protected void func_22248_c() + { + field_22265_a.drawDefaultBackground(); + } + + protected void func_22242_a(int i, int j, int k, int l, Tessellator tessellator) + { + TexturePackBase texturepackbase = (TexturePackBase)GuiTexturePacks.func_22121_h(field_22265_a).texturePackList.availableTexturePacks().get(i); + texturepackbase.func_6483_c(GuiTexturePacks.func_22123_i(field_22265_a)); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0xffffff); + tessellator.addVertexWithUV(j, k + l, 0.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV(j + 32, k + l, 0.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV(j + 32, k, 0.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(j, k, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + field_22265_a.drawString(GuiTexturePacks.func_22127_j(field_22265_a), texturepackbase.texturePackFileName, j + 32 + 2, k + 1, 0xffffff); + field_22265_a.drawString(GuiTexturePacks.func_22120_k(field_22265_a), texturepackbase.firstDescriptionLine, j + 32 + 2, k + 12, 0x808080); + field_22265_a.drawString(GuiTexturePacks.func_22125_l(field_22265_a), texturepackbase.secondDescriptionLine, j + 32 + 2, k + 12 + 10, 0x808080); + } + + final GuiTexturePacks field_22265_a; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/GuiTexturePacks.java b/src/main/java/net/minecraft/src/GuiTexturePacks.java new file mode 100644 index 0000000..df52473 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiTexturePacks.java @@ -0,0 +1,146 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.util.List; +import net.minecraft.client.Minecraft; +import org.lwjgl.Sys; + +public class GuiTexturePacks extends GuiScreen +{ + + public GuiTexturePacks(GuiScreen guiscreen) + { + field_6454_o = -1; + field_6453_p = ""; + field_6461_a = guiscreen; + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + controlList.add(new GuiSmallButton(5, width / 2 - 154, height - 48, stringtranslate.translateKey("texturePack.openFolder"))); + controlList.add(new GuiSmallButton(6, width / 2 + 4, height - 48, stringtranslate.translateKey("gui.done"))); + mc.texturePackList.func_6532_a(); + field_6453_p = (new File(Minecraft.getMinecraftDir(), "texturepacks")).getAbsolutePath(); + field_22128_k = new GuiTexturePackSlot(this); + field_22128_k.func_22240_a(controlList, 7, 8); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id == 5) + { + Sys.openURL((new StringBuilder()).append("file://").append(field_6453_p).toString()); + } else + if(guibutton.id == 6) + { + mc.renderEngine.refreshTextures(); + mc.displayGuiScreen(field_6461_a); + } else + { + field_22128_k.func_22241_a(guibutton); + } + } + + protected void mouseClicked(int i, int j, int k) + { + super.mouseClicked(i, j, k); + } + + protected void mouseMovedOrUp(int i, int j, int k) + { + super.mouseMovedOrUp(i, j, k); + } + + public void drawScreen(int i, int j, float f) + { + field_22128_k.func_22243_a(i, j, f); + if(field_6454_o <= 0) + { + mc.texturePackList.func_6532_a(); + field_6454_o += 20; + } + StringTranslate stringtranslate = StringTranslate.getInstance(); + drawCenteredString(fontRenderer, stringtranslate.translateKey("texturePack.title"), width / 2, 16, 0xffffff); + drawCenteredString(fontRenderer, stringtranslate.translateKey("texturePack.folderInfo"), width / 2 - 77, height - 26, 0x808080); + super.drawScreen(i, j, f); + } + + public void updateScreen() + { + super.updateScreen(); + field_6454_o--; + } + + static Minecraft func_22124_a(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22126_b(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22119_c(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22122_d(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22117_e(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22118_f(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22116_g(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22121_h(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static Minecraft func_22123_i(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.mc; + } + + static FontRenderer func_22127_j(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.fontRenderer; + } + + static FontRenderer func_22120_k(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.fontRenderer; + } + + static FontRenderer func_22125_l(GuiTexturePacks guitexturepacks) + { + return guitexturepacks.fontRenderer; + } + + protected GuiScreen field_6461_a; + private int field_6454_o; + private String field_6453_p; + private GuiTexturePackSlot field_22128_k; +} diff --git a/src/main/java/net/minecraft/src/GuiUnused.java b/src/main/java/net/minecraft/src/GuiUnused.java new file mode 100644 index 0000000..6107b70 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiUnused.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class GuiUnused extends GuiScreen +{ + + public void initGui() + { + } + + public void drawScreen(int i, int j, float f) + { + drawGradientRect(0, 0, width, height, 0xff402020, 0xff501010); + drawCenteredString(fontRenderer, message1, width / 2, 90, 0xffffff); + drawCenteredString(fontRenderer, message2, width / 2, 110, 0xffffff); + super.drawScreen(i, j, f); + } + + protected void keyTyped(char c, int i) + { + } + + private String message1; + private String message2; +} diff --git a/src/main/java/net/minecraft/src/GuiVideoSettings.java b/src/main/java/net/minecraft/src/GuiVideoSettings.java new file mode 100644 index 0000000..b6b122a --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiVideoSettings.java @@ -0,0 +1,78 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import net.minecraft.client.Minecraft; + +public class GuiVideoSettings extends GuiScreen +{ + + public GuiVideoSettings(GuiScreen guiscreen, GameSettings gamesettings) + { + field_22107_a = "Video Settings"; + field_22110_h = guiscreen; + field_22109_i = gamesettings; + } + + public void initGui() + { + StringTranslate stringtranslate = StringTranslate.getInstance(); + field_22107_a = stringtranslate.translateKey("options.videoTitle"); + int i = 0; + EnumOptions aenumoptions[] = field_22108_k; + int j = aenumoptions.length; + for(int k = 0; k < j; k++) + { + EnumOptions enumoptions = aenumoptions[k]; + if(!enumoptions.getEnumFloat()) + { + controlList.add(new GuiSmallButton(enumoptions.returnEnumOrdinal(), (width / 2 - 155) + (i % 2) * 160, height / 6 + 24 * (i >> 1), enumoptions, field_22109_i.getKeyBinding(enumoptions))); + } else + { + controlList.add(new GuiSlider(enumoptions.returnEnumOrdinal(), (width / 2 - 155) + (i % 2) * 160, height / 6 + 24 * (i >> 1), enumoptions, field_22109_i.getKeyBinding(enumoptions), field_22109_i.getOptionFloatValue(enumoptions))); + } + i++; + } + + controlList.add(new GuiButton(200, width / 2 - 100, height / 6 + 168, stringtranslate.translateKey("gui.done"))); + } + + protected void actionPerformed(GuiButton guibutton) + { + if(!guibutton.enabled) + { + return; + } + if(guibutton.id < 100 && (guibutton instanceof GuiSmallButton)) + { + field_22109_i.setOptionValue(((GuiSmallButton)guibutton).returnEnumOptions(), 1); + guibutton.displayString = field_22109_i.getKeyBinding(EnumOptions.func_20137_a(guibutton.id)); + } + if(guibutton.id == 200) + { + mc.gameSettings.saveOptions(); + mc.displayGuiScreen(field_22110_h); + } + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, field_22107_a, width / 2, 20, 0xffffff); + super.drawScreen(i, j, f); + } + + private GuiScreen field_22110_h; + protected String field_22107_a; + private GameSettings field_22109_i; + private static EnumOptions field_22108_k[]; + + static + { + field_22108_k = (new EnumOptions[] { + EnumOptions.GRAPHICS, EnumOptions.RENDER_DISTANCE, EnumOptions.LIMIT_FRAMERATE, EnumOptions.ANAGLYPH, EnumOptions.VIEW_BOBBING, EnumOptions.AMBIENT_OCCLUSION + }); + } +} diff --git a/src/main/java/net/minecraft/src/GuiWorldSlot.java b/src/main/java/net/minecraft/src/GuiWorldSlot.java new file mode 100644 index 0000000..9094a39 --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiWorldSlot.java @@ -0,0 +1,75 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.text.DateFormat; +import java.util.Date; +import java.util.List; + +class GuiWorldSlot extends GuiSlot +{ + + public GuiWorldSlot(GuiSelectWorld guiselectworld) + { + super(guiselectworld.mc, guiselectworld.width, guiselectworld.height, 32, guiselectworld.height - 64, 36); + field_22266_a = guiselectworld; + } + + protected int func_22249_a() + { + return GuiSelectWorld.func_22090_a(field_22266_a).size(); + } + + protected void func_22247_a(int i, boolean flag) + { + GuiSelectWorld.func_22089_a(field_22266_a, i); + boolean flag1 = GuiSelectWorld.func_22086_b(field_22266_a) >= 0 && GuiSelectWorld.func_22086_b(field_22266_a) < func_22249_a(); + GuiSelectWorld.func_22083_c(field_22266_a).enabled = flag1; + GuiSelectWorld.func_22085_d(field_22266_a).enabled = flag1; + GuiSelectWorld.func_22092_e(field_22266_a).enabled = flag1; + if(flag && flag1) + { + field_22266_a.selectWorld(i); + } + } + + protected boolean func_22246_a(int i) + { + return i == GuiSelectWorld.func_22086_b(field_22266_a); + } + + protected int func_22245_b() + { + return GuiSelectWorld.func_22090_a(field_22266_a).size() * 36; + } + + protected void func_22248_c() + { + field_22266_a.drawDefaultBackground(); + } + + protected void func_22242_a(int i, int j, int k, int l, Tessellator tessellator) + { + SaveFormatComparator saveformatcomparator = (SaveFormatComparator)GuiSelectWorld.func_22090_a(field_22266_a).get(i); + String s = saveformatcomparator.func_22162_b(); + if(s == null || MathHelper.func_22282_a(s)) + { + s = (new StringBuilder()).append(GuiSelectWorld.func_22087_f(field_22266_a)).append(" ").append(i + 1).toString(); + } + String s1 = saveformatcomparator.func_22164_a(); + s1 = (new StringBuilder()).append(s1).append(" (").append(GuiSelectWorld.func_22093_g(field_22266_a).format(new Date(saveformatcomparator.func_22163_e()))).toString(); + long l1 = saveformatcomparator.func_22159_c(); + s1 = (new StringBuilder()).append(s1).append(", ").append((float)(((l1 / 1024L) * 100L) / 1024L) / 100F).append(" MB)").toString(); + String s2 = ""; + if(saveformatcomparator.func_22161_d()) + { + s2 = (new StringBuilder()).append(GuiSelectWorld.func_22088_h(field_22266_a)).append(" ").append(s2).toString(); + } + field_22266_a.drawString(field_22266_a.fontRenderer, s, j + 2, k + 1, 0xffffff); + field_22266_a.drawString(field_22266_a.fontRenderer, s1, j + 2, k + 12, 0x808080); + field_22266_a.drawString(field_22266_a.fontRenderer, s2, j + 2, k + 12 + 10, 0x808080); + } + + final GuiSelectWorld field_22266_a; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/GuiYesNo.java b/src/main/java/net/minecraft/src/GuiYesNo.java new file mode 100644 index 0000000..9b0c50c --- /dev/null +++ b/src/main/java/net/minecraft/src/GuiYesNo.java @@ -0,0 +1,46 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public class GuiYesNo extends GuiScreen +{ + + public GuiYesNo(GuiScreen guiscreen, String s, String s1, String s2, String s3, int i) + { + parentScreen = guiscreen; + message1 = s; + message2 = s1; + field_22106_k = s2; + field_22105_l = s3; + worldNumber = i; + } + + public void initGui() + { + controlList.add(new GuiSmallButton(0, (width / 2 - 155) + 0, height / 6 + 96, field_22106_k)); + controlList.add(new GuiSmallButton(1, (width / 2 - 155) + 160, height / 6 + 96, field_22105_l)); + } + + protected void actionPerformed(GuiButton guibutton) + { + parentScreen.deleteWorld(guibutton.id == 0, worldNumber); + } + + public void drawScreen(int i, int j, float f) + { + drawDefaultBackground(); + drawCenteredString(fontRenderer, message1, width / 2, 70, 0xffffff); + drawCenteredString(fontRenderer, message2, width / 2, 90, 0xffffff); + super.drawScreen(i, j, f); + } + + private GuiScreen parentScreen; + private String message1; + private String message2; + private String field_22106_k; + private String field_22105_l; + private int worldNumber; +} diff --git a/src/main/java/net/minecraft/src/HashEntry.java b/src/main/java/net/minecraft/src/HashEntry.java new file mode 100644 index 0000000..b0f41c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/HashEntry.java @@ -0,0 +1,63 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class HashEntry +{ + + HashEntry(int i, int j, Object obj, HashEntry hashentry) + { + valueEntry = obj; + nextEntry = hashentry; + hashEntry = j; + slotHash = i; + } + + public final int getHash() + { + return hashEntry; + } + + public final Object getValue() + { + return valueEntry; + } + + public final boolean equals(Object obj) + { + if(!(obj instanceof HashEntry)) + { + return false; + } + HashEntry hashentry = (HashEntry)obj; + Integer integer = Integer.valueOf(getHash()); + Integer integer1 = Integer.valueOf(hashentry.getHash()); + if(integer == integer1 || integer != null && integer.equals(integer1)) + { + Object obj1 = getValue(); + Object obj2 = hashentry.getValue(); + if(obj1 == obj2 || obj1 != null && obj1.equals(obj2)) + { + return true; + } + } + return false; + } + + public final int hashCode() + { + return MCHashTable.getHash(hashEntry); + } + + public final String toString() + { + return (new StringBuilder()).append(getHash()).append("=").append(getValue()).toString(); + } + + final int hashEntry; + Object valueEntry; + HashEntry nextEntry; + final int slotHash; +} diff --git a/src/main/java/net/minecraft/src/IBlockAccess.java b/src/main/java/net/minecraft/src/IBlockAccess.java new file mode 100644 index 0000000..45dd35c --- /dev/null +++ b/src/main/java/net/minecraft/src/IBlockAccess.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IBlockAccess +{ + + public abstract int getBlockId(int i, int j, int k); + + public abstract TileEntity getBlockTileEntity(int i, int j, int k); + + public abstract float getLightBrightness(int i, int j, int k); + + public abstract int getBlockMetadata(int i, int j, int k); + + public abstract Material getBlockMaterial(int i, int j, int k); + + public abstract boolean isBlockOpaqueCube(int i, int j, int k); + + public abstract WorldChunkManager getWorldChunkManager(); +} diff --git a/src/main/java/net/minecraft/src/ICamera.java b/src/main/java/net/minecraft/src/ICamera.java new file mode 100644 index 0000000..818fff8 --- /dev/null +++ b/src/main/java/net/minecraft/src/ICamera.java @@ -0,0 +1,13 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface ICamera +{ + + public abstract boolean isBoundingBoxInFrustum(AxisAlignedBB axisalignedbb); + + public abstract void setPosition(double d, double d1, double d2); +} diff --git a/src/main/java/net/minecraft/src/IChunkLoader.java b/src/main/java/net/minecraft/src/IChunkLoader.java new file mode 100644 index 0000000..b511f26 --- /dev/null +++ b/src/main/java/net/minecraft/src/IChunkLoader.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.IOException; + +public interface IChunkLoader +{ + + public abstract Chunk loadChunk(World world, int i, int j); + + public abstract void saveChunk(World world, Chunk chunk); + + public abstract void saveExtraChunkData(World world, Chunk chunk); + + public abstract void func_814_a(); + + public abstract void saveExtraData(); +} diff --git a/src/main/java/net/minecraft/src/IChunkProvider.java b/src/main/java/net/minecraft/src/IChunkProvider.java new file mode 100644 index 0000000..babda77 --- /dev/null +++ b/src/main/java/net/minecraft/src/IChunkProvider.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IChunkProvider +{ + + public abstract boolean chunkExists(int i, int j); + + public abstract Chunk provideChunk(int i, int j); + + public abstract void populate(IChunkProvider ichunkprovider, int i, int j); + + public abstract boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate); + + public abstract boolean func_532_a(); + + public abstract boolean func_536_b(); + + public abstract String toString(); +} diff --git a/src/main/java/net/minecraft/src/ICrafting.java b/src/main/java/net/minecraft/src/ICrafting.java new file mode 100644 index 0000000..bbe374a --- /dev/null +++ b/src/main/java/net/minecraft/src/ICrafting.java @@ -0,0 +1,13 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface ICrafting +{ + + public abstract void func_20159_a(CraftingInventoryCB craftinginventorycb, int i, ItemStack itemstack); + + public abstract void func_20158_a(CraftingInventoryCB craftinginventorycb, int i, int j); +} diff --git a/src/main/java/net/minecraft/src/IInvBasic.java b/src/main/java/net/minecraft/src/IInvBasic.java new file mode 100644 index 0000000..937b8cd --- /dev/null +++ b/src/main/java/net/minecraft/src/IInvBasic.java @@ -0,0 +1,11 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IInvBasic +{ + + public abstract void func_20134_a(InventoryBasic inventorybasic); +} diff --git a/src/main/java/net/minecraft/src/IInventory.java b/src/main/java/net/minecraft/src/IInventory.java new file mode 100644 index 0000000..b99578a --- /dev/null +++ b/src/main/java/net/minecraft/src/IInventory.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IInventory +{ + + public abstract int getSizeInventory(); + + public abstract ItemStack getStackInSlot(int i); + + public abstract ItemStack decrStackSize(int i, int j); + + public abstract void setInventorySlotContents(int i, ItemStack itemstack); + + public abstract String getInvName(); + + public abstract int getInventoryStackLimit(); + + public abstract void onInventoryChanged(); + + public abstract boolean canInteractWith(EntityPlayer entityplayer); +} diff --git a/src/main/java/net/minecraft/src/IMobs.java b/src/main/java/net/minecraft/src/IMobs.java new file mode 100644 index 0000000..7a344cd --- /dev/null +++ b/src/main/java/net/minecraft/src/IMobs.java @@ -0,0 +1,9 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IMobs +{ +} diff --git a/src/main/java/net/minecraft/src/IProgressUpdate.java b/src/main/java/net/minecraft/src/IProgressUpdate.java new file mode 100644 index 0000000..180d13a --- /dev/null +++ b/src/main/java/net/minecraft/src/IProgressUpdate.java @@ -0,0 +1,15 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IProgressUpdate +{ + + public abstract void func_594_b(String s); + + public abstract void displayLoadingString(String s); + + public abstract void setLoadingProgress(int i); +} diff --git a/src/main/java/net/minecraft/src/IRecipe.java b/src/main/java/net/minecraft/src/IRecipe.java new file mode 100644 index 0000000..c7b1741 --- /dev/null +++ b/src/main/java/net/minecraft/src/IRecipe.java @@ -0,0 +1,15 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IRecipe +{ + + public abstract boolean func_21135_a(InventoryCrafting inventorycrafting); + + public abstract ItemStack func_21136_b(InventoryCrafting inventorycrafting); + + public abstract int getRecipeSize(); +} diff --git a/src/main/java/net/minecraft/src/ISaveFormat.java b/src/main/java/net/minecraft/src/ISaveFormat.java new file mode 100644 index 0000000..7fb9ef8 --- /dev/null +++ b/src/main/java/net/minecraft/src/ISaveFormat.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public interface ISaveFormat +{ + + public abstract String func_22178_a(); + + public abstract ISaveHandler func_22174_a(String s, boolean flag); + + public abstract List func_22176_b(); + + public abstract void func_22177_c(); + + public abstract WorldInfo func_22173_b(String s); + + public abstract void func_22172_c(String s); + + public abstract void func_22170_a(String s, String s1); + + public abstract boolean func_22175_a(String s); + + public abstract boolean func_22171_a(String s, IProgressUpdate iprogressupdate); +} diff --git a/src/main/java/net/minecraft/src/ISaveHandler.java b/src/main/java/net/minecraft/src/ISaveHandler.java new file mode 100644 index 0000000..bd294d2 --- /dev/null +++ b/src/main/java/net/minecraft/src/ISaveHandler.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public interface ISaveHandler +{ + + public abstract WorldInfo func_22151_c(); + + public abstract void func_22150_b(); + + public abstract IChunkLoader func_22149_a(WorldProvider worldprovider); + + public abstract void func_22148_a(WorldInfo worldinfo, List list); + + public abstract void func_22152_a(WorldInfo worldinfo); +} diff --git a/src/main/java/net/minecraft/src/IWorldAccess.java b/src/main/java/net/minecraft/src/IWorldAccess.java new file mode 100644 index 0000000..1fbe985 --- /dev/null +++ b/src/main/java/net/minecraft/src/IWorldAccess.java @@ -0,0 +1,29 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public interface IWorldAccess +{ + + public abstract void func_934_a(int i, int j, int k); + + public abstract void markBlockRangeNeedsUpdate(int i, int j, int k, int l, int i1, int j1); + + public abstract void playSound(String s, double d, double d1, double d2, + float f, float f1); + + public abstract void spawnParticle(String s, double d, double d1, double d2, + double d3, double d4, double d5); + + public abstract void obtainEntitySkin(Entity entity); + + public abstract void releaseEntitySkin(Entity entity); + + public abstract void updateAllRenderers(); + + public abstract void playRecord(String s, int i, int j, int k); + + public abstract void doNothingWithTileEntity(int i, int j, int k, TileEntity tileentity); +} diff --git a/src/main/java/net/minecraft/src/ImageBuffer.java b/src/main/java/net/minecraft/src/ImageBuffer.java new file mode 100644 index 0000000..480f50e --- /dev/null +++ b/src/main/java/net/minecraft/src/ImageBuffer.java @@ -0,0 +1,12 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; + +public interface ImageBuffer +{ + + public abstract BufferedImage parseUserSkin(BufferedImage bufferedimage); +} diff --git a/src/main/java/net/minecraft/src/ImageBufferDownload.java b/src/main/java/net/minecraft/src/ImageBufferDownload.java new file mode 100644 index 0000000..3a67d01 --- /dev/null +++ b/src/main/java/net/minecraft/src/ImageBufferDownload.java @@ -0,0 +1,118 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.Graphics; +import java.awt.image.*; + +public class ImageBufferDownload + implements ImageBuffer +{ + + public ImageBufferDownload() + { + } + + public BufferedImage parseUserSkin(BufferedImage bufferedimage) + { + if(bufferedimage == null) + { + return null; + } + imageWidth = 64; + imageHeight = 32; + BufferedImage bufferedimage1 = new BufferedImage(imageWidth, imageHeight, 2); + Graphics g = bufferedimage1.getGraphics(); + g.drawImage(bufferedimage, 0, 0, null); + g.dispose(); + imageData = ((DataBufferInt)bufferedimage1.getRaster().getDataBuffer()).getData(); + func_884_b(0, 0, 32, 16); + func_885_a(32, 0, 64, 32); + func_884_b(0, 16, 64, 32); + boolean flag = false; + for(int i = 32; i < 64; i++) + { + for(int k = 0; k < 16; k++) + { + int i1 = imageData[i + k * 64]; + if((i1 >> 24 & 0xff) < 128) + { + flag = true; + } + } + + } + + if(!flag) + { + for(int j = 32; j < 64; j++) + { + for(int l = 0; l < 16; l++) + { + int j1 = imageData[j + l * 64]; + boolean flag1; + if((j1 >> 24 & 0xff) < 128) + { + flag1 = true; + } + } + + } + + } + return bufferedimage1; + } + + private void func_885_a(int i, int j, int k, int l) + { + if(func_886_c(i, j, k, l)) + { + return; + } + for(int i1 = i; i1 < k; i1++) + { + for(int j1 = j; j1 < l; j1++) + { + imageData[i1 + j1 * imageWidth] &= 0xffffff; + } + + } + + } + + private void func_884_b(int i, int j, int k, int l) + { + for(int i1 = i; i1 < k; i1++) + { + for(int j1 = j; j1 < l; j1++) + { + imageData[i1 + j1 * imageWidth] |= 0xff000000; + } + + } + + } + + private boolean func_886_c(int i, int j, int k, int l) + { + for(int i1 = i; i1 < k; i1++) + { + for(int j1 = j; j1 < l; j1++) + { + int k1 = imageData[i1 + j1 * imageWidth]; + if((k1 >> 24 & 0xff) < 128) + { + return true; + } + } + + } + + return false; + } + + private int imageData[]; + private int imageWidth; + private int imageHeight; +} diff --git a/src/main/java/net/minecraft/src/InventoryBasic.java b/src/main/java/net/minecraft/src/InventoryBasic.java new file mode 100644 index 0000000..9d6fc8e --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryBasic.java @@ -0,0 +1,94 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public class InventoryBasic + implements IInventory +{ + + public InventoryBasic(String s, int i) + { + inventoryTitle = s; + slotsCount = i; + inventoryContents = new ItemStack[i]; + } + + public ItemStack getStackInSlot(int i) + { + return inventoryContents[i]; + } + + public ItemStack decrStackSize(int i, int j) + { + if(inventoryContents[i] != null) + { + if(inventoryContents[i].stackSize <= j) + { + ItemStack itemstack = inventoryContents[i]; + inventoryContents[i] = null; + onInventoryChanged(); + return itemstack; + } + ItemStack itemstack1 = inventoryContents[i].splitStack(j); + if(inventoryContents[i].stackSize == 0) + { + inventoryContents[i] = null; + } + onInventoryChanged(); + return itemstack1; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + inventoryContents[i] = itemstack; + if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + { + itemstack.stackSize = getInventoryStackLimit(); + } + onInventoryChanged(); + } + + public int getSizeInventory() + { + return slotsCount; + } + + public String getInvName() + { + return inventoryTitle; + } + + public int getInventoryStackLimit() + { + return 64; + } + + public void onInventoryChanged() + { + if(field_20073_d != null) + { + for(int i = 0; i < field_20073_d.size(); i++) + { + ((IInvBasic)field_20073_d.get(i)).func_20134_a(this); + } + + } + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + return true; + } + + private String inventoryTitle; + private int slotsCount; + private ItemStack inventoryContents[]; + private List field_20073_d; +} diff --git a/src/main/java/net/minecraft/src/InventoryCraftResult.java b/src/main/java/net/minecraft/src/InventoryCraftResult.java new file mode 100644 index 0000000..dea43fd --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryCraftResult.java @@ -0,0 +1,64 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class InventoryCraftResult + implements IInventory +{ + + public InventoryCraftResult() + { + stackResult = new ItemStack[1]; + } + + public int getSizeInventory() + { + return 1; + } + + public ItemStack getStackInSlot(int i) + { + return stackResult[i]; + } + + public String getInvName() + { + return "Result"; + } + + public ItemStack decrStackSize(int i, int j) + { + if(stackResult[i] != null) + { + ItemStack itemstack = stackResult[i]; + stackResult[i] = null; + return itemstack; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + stackResult[i] = itemstack; + } + + public int getInventoryStackLimit() + { + return 64; + } + + public void onInventoryChanged() + { + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + return true; + } + + private ItemStack stackResult[]; +} diff --git a/src/main/java/net/minecraft/src/InventoryCrafting.java b/src/main/java/net/minecraft/src/InventoryCrafting.java new file mode 100644 index 0000000..5fde7df --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryCrafting.java @@ -0,0 +1,99 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class InventoryCrafting + implements IInventory +{ + + public InventoryCrafting(CraftingInventoryCB craftinginventorycb, int i, int j) + { + int k = i * j; + stackList = new ItemStack[k]; + eventHandler = craftinginventorycb; + field_21104_b = i; + } + + public int getSizeInventory() + { + return stackList.length; + } + + public ItemStack getStackInSlot(int i) + { + if(i >= getSizeInventory()) + { + return null; + } else + { + return stackList[i]; + } + } + + public ItemStack func_21103_b(int i, int j) + { + if(i < 0 || i >= field_21104_b) + { + return null; + } else + { + int k = i + j * field_21104_b; + return getStackInSlot(k); + } + } + + public String getInvName() + { + return "Crafting"; + } + + public ItemStack decrStackSize(int i, int j) + { + if(stackList[i] != null) + { + if(stackList[i].stackSize <= j) + { + ItemStack itemstack = stackList[i]; + stackList[i] = null; + eventHandler.onCraftMatrixChanged(this); + return itemstack; + } + ItemStack itemstack1 = stackList[i].splitStack(j); + if(stackList[i].stackSize == 0) + { + stackList[i] = null; + } + eventHandler.onCraftMatrixChanged(this); + return itemstack1; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + stackList[i] = itemstack; + eventHandler.onCraftMatrixChanged(this); + } + + public int getInventoryStackLimit() + { + return 64; + } + + public void onInventoryChanged() + { + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + return true; + } + + private ItemStack stackList[]; + private int field_21104_b; + private CraftingInventoryCB eventHandler; +} diff --git a/src/main/java/net/minecraft/src/InventoryLargeChest.java b/src/main/java/net/minecraft/src/InventoryLargeChest.java new file mode 100644 index 0000000..38a3833 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryLargeChest.java @@ -0,0 +1,80 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class InventoryLargeChest + implements IInventory +{ + + public InventoryLargeChest(String s, IInventory iinventory, IInventory iinventory1) + { + name = s; + upperChest = iinventory; + lowerChest = iinventory1; + } + + public int getSizeInventory() + { + return upperChest.getSizeInventory() + lowerChest.getSizeInventory(); + } + + public String getInvName() + { + return name; + } + + public ItemStack getStackInSlot(int i) + { + if(i >= upperChest.getSizeInventory()) + { + return lowerChest.getStackInSlot(i - upperChest.getSizeInventory()); + } else + { + return upperChest.getStackInSlot(i); + } + } + + public ItemStack decrStackSize(int i, int j) + { + if(i >= upperChest.getSizeInventory()) + { + return lowerChest.decrStackSize(i - upperChest.getSizeInventory(), j); + } else + { + return upperChest.decrStackSize(i, j); + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + if(i >= upperChest.getSizeInventory()) + { + lowerChest.setInventorySlotContents(i - upperChest.getSizeInventory(), itemstack); + } else + { + upperChest.setInventorySlotContents(i, itemstack); + } + } + + public int getInventoryStackLimit() + { + return upperChest.getInventoryStackLimit(); + } + + public void onInventoryChanged() + { + upperChest.onInventoryChanged(); + lowerChest.onInventoryChanged(); + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + return upperChest.canInteractWith(entityplayer) && lowerChest.canInteractWith(entityplayer); + } + + private String name; + private IInventory upperChest; + private IInventory lowerChest; +} diff --git a/src/main/java/net/minecraft/src/InventoryPlayer.java b/src/main/java/net/minecraft/src/InventoryPlayer.java new file mode 100644 index 0000000..4480569 --- /dev/null +++ b/src/main/java/net/minecraft/src/InventoryPlayer.java @@ -0,0 +1,436 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class InventoryPlayer + implements IInventory +{ + + public InventoryPlayer(EntityPlayer entityplayer) + { + mainInventory = new ItemStack[36]; + armorInventory = new ItemStack[4]; + currentItem = 0; + inventoryChanged = false; + player = entityplayer; + } + + public ItemStack getCurrentItem() + { + return mainInventory[currentItem]; + } + + private int getInventorySlotContainItem(int i) + { + for(int j = 0; j < mainInventory.length; j++) + { + if(mainInventory[j] != null && mainInventory[j].itemID == i) + { + return j; + } + } + + return -1; + } + + private int storeItemStack(ItemStack itemstack) + { + for(int i = 0; i < mainInventory.length; i++) + { + if(mainInventory[i] != null && mainInventory[i].itemID == itemstack.itemID && mainInventory[i].func_21180_d() && mainInventory[i].stackSize < mainInventory[i].getMaxStackSize() && mainInventory[i].stackSize < getInventoryStackLimit() && (!mainInventory[i].getHasSubtypes() || mainInventory[i].getItemDamage() == itemstack.getItemDamage())) + { + return i; + } + } + + return -1; + } + + private int getFirstEmptyStack() + { + for(int i = 0; i < mainInventory.length; i++) + { + if(mainInventory[i] == null) + { + return i; + } + } + + return -1; + } + + public void setCurrentItem(int i, boolean flag) + { + int j = getInventorySlotContainItem(i); + if(j >= 0 && j < 9) + { + currentItem = j; + return; + } else + { + return; + } + } + + public void changeCurrentItem(int i) + { + if(i > 0) + { + i = 1; + } + if(i < 0) + { + i = -1; + } + for(currentItem -= i; currentItem < 0; currentItem += 9) { } + for(; currentItem >= 9; currentItem -= 9) { } + } + + private int func_21106_d(ItemStack itemstack) + { + int i = itemstack.itemID; + int j = itemstack.stackSize; + int k = storeItemStack(itemstack); + if(k < 0) + { + k = getFirstEmptyStack(); + } + if(k < 0) + { + return j; + } + if(mainInventory[k] == null) + { + mainInventory[k] = new ItemStack(i, 0, itemstack.getItemDamage()); + } + int l = j; + if(l > mainInventory[k].getMaxStackSize() - mainInventory[k].stackSize) + { + l = mainInventory[k].getMaxStackSize() - mainInventory[k].stackSize; + } + if(l > getInventoryStackLimit() - mainInventory[k].stackSize) + { + l = getInventoryStackLimit() - mainInventory[k].stackSize; + } + if(l == 0) + { + return j; + } else + { + j -= l; + mainInventory[k].stackSize += l; + mainInventory[k].animationsToGo = 5; + return j; + } + } + + public void decrementAnimations() + { + for(int i = 0; i < mainInventory.length; i++) + { + if(mainInventory[i] != null && mainInventory[i].animationsToGo > 0) + { + mainInventory[i].animationsToGo--; + } + } + + } + + public boolean consumeInventoryItem(int i) + { + int j = getInventorySlotContainItem(i); + if(j < 0) + { + return false; + } + if(--mainInventory[j].stackSize <= 0) + { + mainInventory[j] = null; + } + return true; + } + + public boolean addItemStackToInventory(ItemStack itemstack) + { + if(!itemstack.isItemDamaged()) + { + itemstack.stackSize = func_21106_d(itemstack); + if(itemstack.stackSize == 0) + { + return true; + } + } + int i = getFirstEmptyStack(); + if(i >= 0) + { + mainInventory[i] = itemstack; + mainInventory[i].animationsToGo = 5; + return true; + } else + { + return false; + } + } + + public ItemStack decrStackSize(int i, int j) + { + ItemStack aitemstack[] = mainInventory; + if(i >= mainInventory.length) + { + aitemstack = armorInventory; + i -= mainInventory.length; + } + if(aitemstack[i] != null) + { + if(aitemstack[i].stackSize <= j) + { + ItemStack itemstack = aitemstack[i]; + aitemstack[i] = null; + return itemstack; + } + ItemStack itemstack1 = aitemstack[i].splitStack(j); + if(aitemstack[i].stackSize == 0) + { + aitemstack[i] = null; + } + return itemstack1; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + ItemStack aitemstack[] = mainInventory; + if(i >= aitemstack.length) + { + i -= aitemstack.length; + aitemstack = armorInventory; + } + aitemstack[i] = itemstack; + } + + public float getStrVsBlock(Block block) + { + float f = 1.0F; + if(mainInventory[currentItem] != null) + { + f *= mainInventory[currentItem].getStrVsBlock(block); + } + return f; + } + + public NBTTagList writeToNBT(NBTTagList nbttaglist) + { + for(int i = 0; i < mainInventory.length; i++) + { + if(mainInventory[i] != null) + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + nbttagcompound.setByte("Slot", (byte)i); + mainInventory[i].writeToNBT(nbttagcompound); + nbttaglist.setTag(nbttagcompound); + } + } + + for(int j = 0; j < armorInventory.length; j++) + { + if(armorInventory[j] != null) + { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte)(j + 100)); + armorInventory[j].writeToNBT(nbttagcompound1); + nbttaglist.setTag(nbttagcompound1); + } + } + + return nbttaglist; + } + + public void readFromNBT(NBTTagList nbttaglist) + { + mainInventory = new ItemStack[36]; + armorInventory = new ItemStack[4]; + for(int i = 0; i < nbttaglist.tagCount(); i++) + { + NBTTagCompound nbttagcompound = (NBTTagCompound)nbttaglist.tagAt(i); + int j = nbttagcompound.getByte("Slot") & 0xff; + ItemStack itemstack = new ItemStack(nbttagcompound); + if(itemstack.getItem() == null) + { + continue; + } + if(j >= 0 && j < mainInventory.length) + { + mainInventory[j] = itemstack; + } + if(j >= 100 && j < armorInventory.length + 100) + { + armorInventory[j - 100] = itemstack; + } + } + + } + + public int getSizeInventory() + { + return mainInventory.length + 4; + } + + public ItemStack getStackInSlot(int i) + { + ItemStack aitemstack[] = mainInventory; + if(i >= aitemstack.length) + { + i -= aitemstack.length; + aitemstack = armorInventory; + } + return aitemstack[i]; + } + + public String getInvName() + { + return "Inventory"; + } + + public int getInventoryStackLimit() + { + return 64; + } + + public int getDamageVsEntity(Entity entity) + { + ItemStack itemstack = getStackInSlot(currentItem); + if(itemstack != null) + { + return itemstack.getDamageVsEntity(entity); + } else + { + return 1; + } + } + + public boolean canHarvestBlock(Block block) + { + if(block.blockMaterial != Material.rock && block.blockMaterial != Material.iron && block.blockMaterial != Material.builtSnow && block.blockMaterial != Material.snow) + { + return true; + } + ItemStack itemstack = getStackInSlot(currentItem); + if(itemstack != null) + { + return itemstack.canHarvestBlock(block); + } else + { + return false; + } + } + + public ItemStack armorItemInSlot(int i) + { + return armorInventory[i]; + } + + public int getTotalArmorValue() + { + int i = 0; + int j = 0; + int k = 0; + for(int l = 0; l < armorInventory.length; l++) + { + if(armorInventory[l] != null && (armorInventory[l].getItem() instanceof ItemArmor)) + { + int i1 = armorInventory[l].getMaxDamage(); + int j1 = armorInventory[l].getItemDamageForDisplay(); + int k1 = i1 - j1; + j += k1; + k += i1; + int l1 = ((ItemArmor)armorInventory[l].getItem()).damageReduceAmount; + i += l1; + } + } + + if(k == 0) + { + return 0; + } else + { + return ((i - 1) * j) / k + 1; + } + } + + public void damageArmor(int i) + { + for(int j = 0; j < armorInventory.length; j++) + { + if(armorInventory[j] == null || !(armorInventory[j].getItem() instanceof ItemArmor)) + { + continue; + } + armorInventory[j].damageItem(i); + if(armorInventory[j].stackSize == 0) + { + armorInventory[j].func_1097_a(player); + armorInventory[j] = null; + } + } + + } + + public void dropAllItems() + { + for(int i = 0; i < mainInventory.length; i++) + { + if(mainInventory[i] != null) + { + player.dropPlayerItemWithRandomChoice(mainInventory[i], true); + mainInventory[i] = null; + } + } + + for(int j = 0; j < armorInventory.length; j++) + { + if(armorInventory[j] != null) + { + player.dropPlayerItemWithRandomChoice(armorInventory[j], true); + armorInventory[j] = null; + } + } + + } + + public void onInventoryChanged() + { + inventoryChanged = true; + } + + public void setItemStack(ItemStack itemstack) + { + itemStack = itemstack; + player.onItemStackChanged(itemstack); + } + + public ItemStack getItemStack() + { + return itemStack; + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + if(player.isDead) + { + return false; + } + return entityplayer.getDistanceSqToEntity(player) <= 64D; + } + + public ItemStack mainInventory[]; + public ItemStack armorInventory[]; + public int currentItem; + private EntityPlayer player; + private ItemStack itemStack; + public boolean inventoryChanged; +} diff --git a/src/main/java/net/minecraft/src/IsoImageBuffer.java b/src/main/java/net/minecraft/src/IsoImageBuffer.java new file mode 100644 index 0000000..c0101ef --- /dev/null +++ b/src/main/java/net/minecraft/src/IsoImageBuffer.java @@ -0,0 +1,44 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; + +public class IsoImageBuffer +{ + + public IsoImageBuffer(World world, int i, int j) + { + field_1352_e = false; + field_1351_f = false; + field_1350_g = 0; + field_1349_h = false; + worldObj = world; + func_889_a(i, j); + } + + public void func_889_a(int i, int j) + { + field_1352_e = false; + field_1354_c = i; + field_1353_d = j; + field_1350_g = 0; + field_1349_h = false; + } + + public void func_888_a(World world, int i, int j) + { + worldObj = world; + func_889_a(i, j); + } + + public BufferedImage field_1348_a; + public World worldObj; + public int field_1354_c; + public int field_1353_d; + public boolean field_1352_e; + public boolean field_1351_f; + public int field_1350_g; + public boolean field_1349_h; +} diff --git a/src/main/java/net/minecraft/src/Item.java b/src/main/java/net/minecraft/src/Item.java new file mode 100644 index 0000000..a9904e8 --- /dev/null +++ b/src/main/java/net/minecraft/src/Item.java @@ -0,0 +1,325 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.Random; + +public class Item +{ + + protected Item(int i) + { + maxStackSize = 64; + maxDamage = 32; + bFull3D = false; + hasSubtypes = false; + containerItem = null; + shiftedIndex = 256 + i; + if(itemsList[256 + i] != null) + { + System.out.println((new StringBuilder()).append("CONFLICT @ ").append(i).toString()); + } + itemsList[256 + i] = this; + } + + public Item setIconIndex(int i) + { + iconIndex = i; + return this; + } + + public Item setMaxStackSize(int i) + { + maxStackSize = i; + return this; + } + + public Item setIconCoord(int i, int j) + { + iconIndex = i + j * 16; + return this; + } + + public int getIconIndex(ItemStack itemstack) + { + return iconIndex; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + return false; + } + + public float getStrVsBlock(ItemStack itemstack, Block block) + { + return 1.0F; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + return itemstack; + } + + public int getItemStackLimit() + { + return maxStackSize; + } + + public int func_21012_a(int i) + { + return 0; + } + + public boolean getHasSubtypes() + { + return hasSubtypes; + } + + protected Item setHasSubtypes(boolean flag) + { + hasSubtypes = flag; + return this; + } + + public int getMaxDamage() + { + return maxDamage; + } + + protected Item setMaxDamage(int i) + { + maxDamage = i; + return this; + } + + public void hitEntity(ItemStack itemstack, EntityLiving entityliving) + { + } + + public void hitBlock(ItemStack itemstack, int i, int j, int k, int l) + { + } + + public int getDamageVsEntity(Entity entity) + { + return 1; + } + + public boolean canHarvestBlock(Block block) + { + return false; + } + + public void saddleEntity(ItemStack itemstack, EntityLiving entityliving) + { + } + + public Item setFull3D() + { + bFull3D = true; + return this; + } + + public boolean isFull3D() + { + return bFull3D; + } + + public boolean shouldRotateAroundWhenRendering() + { + return false; + } + + public Item setItemName(String s) + { + itemName = (new StringBuilder()).append("item.").append(s).toString(); + return this; + } + + public String getItemName() + { + return itemName; + } + + public String getItemNameIS(ItemStack itemstack) + { + return itemName; + } + + public Item setContainerItem(Item item) + { + if(maxStackSize > 1) + { + throw new IllegalArgumentException("Max stack size must be 1 for items with crafting results"); + } else + { + containerItem = item; + return this; + } + } + + public Item getContainerItem() + { + return containerItem; + } + + public boolean func_21014_i() + { + return containerItem != null; + } + + protected static Random itemRand = new Random(); + public static Item itemsList[] = new Item[32000]; + public static Item shovelSteel; + public static Item pickaxeSteel; + public static Item axeSteel; + public static Item flintAndSteel = (new ItemFlintAndSteel(3)).setIconCoord(5, 0).setItemName("flintAndSteel"); + public static Item appleRed = (new ItemFood(4, 4)).setIconCoord(10, 0).setItemName("apple"); + public static Item bow = (new ItemBow(5)).setIconCoord(5, 1).setItemName("bow"); + public static Item arrow = (new Item(6)).setIconCoord(5, 2).setItemName("arrow"); + public static Item coal = (new ItemCoal(7)).setIconCoord(7, 0).setItemName("coal"); + public static Item diamond = (new Item(8)).setIconCoord(7, 3).setItemName("emerald"); + public static Item ingotIron = (new Item(9)).setIconCoord(7, 1).setItemName("ingotIron"); + public static Item ingotGold = (new Item(10)).setIconCoord(7, 2).setItemName("ingotGold"); + public static Item swordSteel; + public static Item swordWood; + public static Item shovelWood; + public static Item pickaxeWood; + public static Item axeWood; + public static Item swordStone; + public static Item shovelStone; + public static Item pickaxeStone; + public static Item axeStone; + public static Item swordDiamond; + public static Item shovelDiamond; + public static Item pickaxeDiamond; + public static Item axeDiamond; + public static Item stick = (new Item(24)).setIconCoord(5, 3).setFull3D().setItemName("stick"); + public static Item bowlEmpty = (new Item(25)).setIconCoord(7, 4).setItemName("bowl"); + public static Item bowlSoup = (new ItemSoup(26, 10)).setIconCoord(8, 4).setItemName("mushroomStew"); + public static Item swordGold; + public static Item shovelGold; + public static Item pickaxeGold; + public static Item axeGold; + public static Item silk = (new Item(31)).setIconCoord(8, 0).setItemName("string"); + public static Item feather = (new Item(32)).setIconCoord(8, 1).setItemName("feather"); + public static Item gunpowder = (new Item(33)).setIconCoord(8, 2).setItemName("sulphur"); + public static Item hoeWood; + public static Item hoeStone; + public static Item hoeSteel; + public static Item hoeDiamond; + public static Item hoeGold; + public static Item seeds; + public static Item wheat = (new Item(40)).setIconCoord(9, 1).setItemName("wheat"); + public static Item bread = (new ItemFood(41, 5)).setIconCoord(9, 2).setItemName("bread"); + public static Item helmetLeather = (new ItemArmor(42, 0, 0, 0)).setIconCoord(0, 0).setItemName("helmetCloth"); + public static Item plateLeather = (new ItemArmor(43, 0, 0, 1)).setIconCoord(0, 1).setItemName("chestplateCloth"); + public static Item legsLeather = (new ItemArmor(44, 0, 0, 2)).setIconCoord(0, 2).setItemName("leggingsCloth"); + public static Item bootsLeather = (new ItemArmor(45, 0, 0, 3)).setIconCoord(0, 3).setItemName("bootsCloth"); + public static Item helmetChain = (new ItemArmor(46, 1, 1, 0)).setIconCoord(1, 0).setItemName("helmetChain"); + public static Item plateChain = (new ItemArmor(47, 1, 1, 1)).setIconCoord(1, 1).setItemName("chestplateChain"); + public static Item legsChain = (new ItemArmor(48, 1, 1, 2)).setIconCoord(1, 2).setItemName("leggingsChain"); + public static Item bootsChain = (new ItemArmor(49, 1, 1, 3)).setIconCoord(1, 3).setItemName("bootsChain"); + public static Item helmetSteel = (new ItemArmor(50, 2, 2, 0)).setIconCoord(2, 0).setItemName("helmetIron"); + public static Item plateSteel = (new ItemArmor(51, 2, 2, 1)).setIconCoord(2, 1).setItemName("chestplateIron"); + public static Item legsSteel = (new ItemArmor(52, 2, 2, 2)).setIconCoord(2, 2).setItemName("leggingsIron"); + public static Item bootsSteel = (new ItemArmor(53, 2, 2, 3)).setIconCoord(2, 3).setItemName("bootsIron"); + public static Item helmetDiamond = (new ItemArmor(54, 3, 3, 0)).setIconCoord(3, 0).setItemName("helmetDiamond"); + public static Item plateDiamond = (new ItemArmor(55, 3, 3, 1)).setIconCoord(3, 1).setItemName("chestplateDiamond"); + public static Item legsDiamond = (new ItemArmor(56, 3, 3, 2)).setIconCoord(3, 2).setItemName("leggingsDiamond"); + public static Item bootsDiamond = (new ItemArmor(57, 3, 3, 3)).setIconCoord(3, 3).setItemName("bootsDiamond"); + public static Item helmetGold = (new ItemArmor(58, 1, 4, 0)).setIconCoord(4, 0).setItemName("helmetGold"); + public static Item plateGold = (new ItemArmor(59, 1, 4, 1)).setIconCoord(4, 1).setItemName("chestplateGold"); + public static Item legsGold = (new ItemArmor(60, 1, 4, 2)).setIconCoord(4, 2).setItemName("leggingsGold"); + public static Item bootsGold = (new ItemArmor(61, 1, 4, 3)).setIconCoord(4, 3).setItemName("bootsGold"); + public static Item flint = (new Item(62)).setIconCoord(6, 0).setItemName("flint"); + public static Item porkRaw = (new ItemFood(63, 3)).setIconCoord(7, 5).setItemName("porkchopRaw"); + public static Item porkCooked = (new ItemFood(64, 8)).setIconCoord(8, 5).setItemName("porkchopCooked"); + public static Item painting = (new ItemPainting(65)).setIconCoord(10, 1).setItemName("painting"); + public static Item appleGold = (new ItemFood(66, 42)).setIconCoord(11, 0).setItemName("appleGold"); + public static Item sign = (new ItemSign(67)).setIconCoord(10, 2).setItemName("sign"); + public static Item doorWood; + public static Item bucketEmpty; + public static Item bucketWater; + public static Item bucketLava; + public static Item minecartEmpty = (new ItemMinecart(72, 0)).setIconCoord(7, 8).setItemName("minecart"); + public static Item saddle = (new ItemSaddle(73)).setIconCoord(8, 6).setItemName("saddle"); + public static Item doorSteel; + public static Item redstone = (new ItemRedstone(75)).setIconCoord(8, 3).setItemName("redstone"); + public static Item snowball = (new ItemSnowball(76)).setIconCoord(14, 0).setItemName("snowball"); + public static Item boat = (new ItemBoat(77)).setIconCoord(8, 8).setItemName("boat"); + public static Item leather = (new Item(78)).setIconCoord(7, 6).setItemName("leather"); + public static Item bucketMilk; + public static Item brick = (new Item(80)).setIconCoord(6, 1).setItemName("brick"); + public static Item clay = (new Item(81)).setIconCoord(9, 3).setItemName("clay"); + public static Item reed; + public static Item paper = (new Item(83)).setIconCoord(10, 3).setItemName("paper"); + public static Item book = (new Item(84)).setIconCoord(11, 3).setItemName("book"); + public static Item slimeBall = (new Item(85)).setIconCoord(14, 1).setItemName("slimeball"); + public static Item minecartCrate = (new ItemMinecart(86, 1)).setIconCoord(7, 9).setItemName("minecartChest"); + public static Item minecartPowered = (new ItemMinecart(87, 2)).setIconCoord(7, 10).setItemName("minecartFurnace"); + public static Item egg = (new ItemEgg(88)).setIconCoord(12, 0).setItemName("egg"); + public static Item compass = (new Item(89)).setIconCoord(6, 3).setItemName("compass"); + public static Item fishingRod = (new ItemFishingRod(90)).setIconCoord(5, 4).setItemName("fishingRod"); + public static Item pocketSundial = (new Item(91)).setIconCoord(6, 4).setItemName("clock"); + public static Item lightStoneDust = (new Item(92)).setIconCoord(9, 4).setItemName("yellowDust"); + public static Item fishRaw = (new ItemFood(93, 2)).setIconCoord(9, 5).setItemName("fishRaw"); + public static Item fishCooked = (new ItemFood(94, 5)).setIconCoord(10, 5).setItemName("fishCooked"); + public static Item dyePowder = (new ItemDye(95)).setIconCoord(14, 4).setItemName("dyePowder"); + public static Item bone = (new Item(96)).setIconCoord(12, 1).setItemName("bone").setFull3D(); + public static Item sugar = (new Item(97)).setIconCoord(13, 0).setItemName("sugar").setFull3D(); + public static Item cake; + public static Item field_22019_aY = (new ItemBed(99)).setMaxStackSize(1).setIconCoord(13, 2).setItemName("bed"); + public static Item field_22018_aZ; + public static Item record13 = (new ItemRecord(2000, "13")).setIconCoord(0, 15).setItemName("record"); + public static Item recordCat = (new ItemRecord(2001, "cat")).setIconCoord(1, 15).setItemName("record"); + public final int shiftedIndex; + protected int maxStackSize; + protected int maxDamage; + protected int iconIndex; + protected boolean bFull3D; + protected boolean hasSubtypes; + private Item containerItem; + private String itemName; + + static + { + shovelSteel = (new ItemSpade(0, EnumToolMaterial.IRON)).setIconCoord(2, 5).setItemName("shovelIron"); + pickaxeSteel = (new ItemPickaxe(1, EnumToolMaterial.IRON)).setIconCoord(2, 6).setItemName("pickaxeIron"); + axeSteel = (new ItemAxe(2, EnumToolMaterial.IRON)).setIconCoord(2, 7).setItemName("hatchetIron"); + swordSteel = (new ItemSword(11, EnumToolMaterial.IRON)).setIconCoord(2, 4).setItemName("swordIron"); + swordWood = (new ItemSword(12, EnumToolMaterial.WOOD)).setIconCoord(0, 4).setItemName("swordWood"); + shovelWood = (new ItemSpade(13, EnumToolMaterial.WOOD)).setIconCoord(0, 5).setItemName("shovelWood"); + pickaxeWood = (new ItemPickaxe(14, EnumToolMaterial.WOOD)).setIconCoord(0, 6).setItemName("pickaxeWood"); + axeWood = (new ItemAxe(15, EnumToolMaterial.WOOD)).setIconCoord(0, 7).setItemName("hatchetWood"); + swordStone = (new ItemSword(16, EnumToolMaterial.STONE)).setIconCoord(1, 4).setItemName("swordStone"); + shovelStone = (new ItemSpade(17, EnumToolMaterial.STONE)).setIconCoord(1, 5).setItemName("shovelStone"); + pickaxeStone = (new ItemPickaxe(18, EnumToolMaterial.STONE)).setIconCoord(1, 6).setItemName("pickaxeStone"); + axeStone = (new ItemAxe(19, EnumToolMaterial.STONE)).setIconCoord(1, 7).setItemName("hatchetStone"); + swordDiamond = (new ItemSword(20, EnumToolMaterial.EMERALD)).setIconCoord(3, 4).setItemName("swordDiamond"); + shovelDiamond = (new ItemSpade(21, EnumToolMaterial.EMERALD)).setIconCoord(3, 5).setItemName("shovelDiamond"); + pickaxeDiamond = (new ItemPickaxe(22, EnumToolMaterial.EMERALD)).setIconCoord(3, 6).setItemName("pickaxeDiamond"); + axeDiamond = (new ItemAxe(23, EnumToolMaterial.EMERALD)).setIconCoord(3, 7).setItemName("hatchetDiamond"); + swordGold = (new ItemSword(27, EnumToolMaterial.GOLD)).setIconCoord(4, 4).setItemName("swordGold"); + shovelGold = (new ItemSpade(28, EnumToolMaterial.GOLD)).setIconCoord(4, 5).setItemName("shovelGold"); + pickaxeGold = (new ItemPickaxe(29, EnumToolMaterial.GOLD)).setIconCoord(4, 6).setItemName("pickaxeGold"); + axeGold = (new ItemAxe(30, EnumToolMaterial.GOLD)).setIconCoord(4, 7).setItemName("hatchetGold"); + hoeWood = (new ItemHoe(34, EnumToolMaterial.WOOD)).setIconCoord(0, 8).setItemName("hoeWood"); + hoeStone = (new ItemHoe(35, EnumToolMaterial.STONE)).setIconCoord(1, 8).setItemName("hoeStone"); + hoeSteel = (new ItemHoe(36, EnumToolMaterial.IRON)).setIconCoord(2, 8).setItemName("hoeIron"); + hoeDiamond = (new ItemHoe(37, EnumToolMaterial.EMERALD)).setIconCoord(3, 8).setItemName("hoeDiamond"); + hoeGold = (new ItemHoe(38, EnumToolMaterial.GOLD)).setIconCoord(4, 8).setItemName("hoeGold"); + seeds = (new ItemSeeds(39, Block.crops.blockID)).setIconCoord(9, 0).setItemName("seeds"); + doorWood = (new ItemDoor(68, Material.wood)).setIconCoord(11, 2).setItemName("doorWood"); + bucketEmpty = (new ItemBucket(69, 0)).setIconCoord(10, 4).setItemName("bucket"); + bucketWater = (new ItemBucket(70, Block.waterStill.blockID)).setIconCoord(11, 4).setItemName("bucketWater").setContainerItem(bucketEmpty); + bucketLava = (new ItemBucket(71, Block.lavaStill.blockID)).setIconCoord(12, 4).setItemName("bucketLava").setContainerItem(bucketEmpty); + doorSteel = (new ItemDoor(74, Material.iron)).setIconCoord(12, 2).setItemName("doorIron"); + bucketMilk = (new ItemBucket(79, -1)).setIconCoord(13, 4).setItemName("milk").setContainerItem(bucketEmpty); + reed = (new ItemReed(82, Block.reed)).setIconCoord(11, 1).setItemName("reeds"); + cake = (new ItemReed(98, Block.cake)).setMaxStackSize(1).setIconCoord(13, 1).setItemName("cake"); + field_22018_aZ = (new ItemReed(100, Block.field_22021_bh)).setIconCoord(6, 5).setItemName("diode"); + } +} diff --git a/src/main/java/net/minecraft/src/ItemArmor.java b/src/main/java/net/minecraft/src/ItemArmor.java new file mode 100644 index 0000000..7121618 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemArmor.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemArmor extends Item +{ + + public ItemArmor(int i, int j, int k, int l) + { + super(i); + armorLevel = j; + armorType = l; + renderIndex = k; + damageReduceAmount = damageReduceAmountArray[l]; + maxDamage = maxDamageArray[l] * 3 << j; + maxStackSize = 1; + } + + private static final int damageReduceAmountArray[] = { + 3, 8, 6, 3 + }; + private static final int maxDamageArray[] = { + 11, 16, 15, 13 + }; + public final int armorLevel; + public final int armorType; + public final int damageReduceAmount; + public final int renderIndex; + +} diff --git a/src/main/java/net/minecraft/src/ItemAxe.java b/src/main/java/net/minecraft/src/ItemAxe.java new file mode 100644 index 0000000..4dfe0e6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemAxe.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemAxe extends ItemTool +{ + + protected ItemAxe(int i, EnumToolMaterial enumtoolmaterial) + { + super(i, 3, enumtoolmaterial, blocksEffectiveAgainst); + } + + private static Block blocksEffectiveAgainst[]; + + static + { + blocksEffectiveAgainst = (new Block[] { + Block.planks, Block.bookShelf, Block.wood, Block.crate + }); + } +} diff --git a/src/main/java/net/minecraft/src/ItemBed.java b/src/main/java/net/minecraft/src/ItemBed.java new file mode 100644 index 0000000..9100007 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBed.java @@ -0,0 +1,53 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemBed extends Item +{ + + public ItemBed(int i) + { + super(i); + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l != 1) + { + return false; + } + j++; + BlockBed blockbed = (BlockBed)Block.field_9262_S; + int i1 = MathHelper.floor_double((double)((entityplayer.rotationYaw * 4F) / 360F) + 0.5D) & 3; + byte byte0 = 0; + byte byte1 = 0; + if(i1 == 0) + { + byte1 = 1; + } + if(i1 == 1) + { + byte0 = -1; + } + if(i1 == 2) + { + byte1 = -1; + } + if(i1 == 3) + { + byte0 = 1; + } + if(world.isAirBlock(i, j, k) && world.isAirBlock(i + byte0, j, k + byte1) && world.isBlockOpaqueCube(i, j - 1, k) && world.isBlockOpaqueCube(i + byte0, j - 1, k + byte1)) + { + world.setBlockAndMetadataWithNotify(i, j, k, blockbed.blockID, i1); + world.setBlockAndMetadataWithNotify(i + byte0, j, k + byte1, blockbed.blockID, i1 + 8); + itemstack.stackSize--; + return true; + } else + { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemBlock.java b/src/main/java/net/minecraft/src/ItemBlock.java new file mode 100644 index 0000000..bccef2a --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBlock.java @@ -0,0 +1,78 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemBlock extends Item +{ + + public ItemBlock(int i) + { + super(i); + blockID = i + 256; + setIconIndex(Block.blocksList[i + 256].getBlockTextureFromSide(2)); + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(world.getBlockId(i, j, k) == Block.snow.blockID) + { + l = 0; + } else + { + if(l == 0) + { + j--; + } + if(l == 1) + { + j++; + } + if(l == 2) + { + k--; + } + if(l == 3) + { + k++; + } + if(l == 4) + { + i--; + } + if(l == 5) + { + i++; + } + } + if(itemstack.stackSize == 0) + { + return false; + } + if(world.canBlockBePlacedAt(blockID, i, j, k, false)) + { + Block block = Block.blocksList[blockID]; + if(world.setBlockAndMetadataWithNotify(i, j, k, blockID, func_21012_a(itemstack.getItemDamage()))) + { + Block.blocksList[blockID].onBlockPlaced(world, i, j, k, l); + Block.blocksList[blockID].onBlockPlacedBy(world, i, j, k, entityplayer); + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, block.stepSound.func_1145_d(), (block.stepSound.func_1147_b() + 1.0F) / 2.0F, block.stepSound.func_1144_c() * 0.8F); + itemstack.stackSize--; + } + } + return true; + } + + public String getItemNameIS(ItemStack itemstack) + { + return Block.blocksList[blockID].getBlockName(); + } + + public String getItemName() + { + return Block.blocksList[blockID].getBlockName(); + } + + private int blockID; +} diff --git a/src/main/java/net/minecraft/src/ItemBoat.java b/src/main/java/net/minecraft/src/ItemBoat.java new file mode 100644 index 0000000..af69bee --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBoat.java @@ -0,0 +1,52 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemBoat extends Item +{ + + public ItemBoat(int i) + { + super(i); + maxStackSize = 1; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + float f = 1.0F; + float f1 = entityplayer.prevRotationPitch + (entityplayer.rotationPitch - entityplayer.prevRotationPitch) * f; + float f2 = entityplayer.prevRotationYaw + (entityplayer.rotationYaw - entityplayer.prevRotationYaw) * f; + double d = entityplayer.prevPosX + (entityplayer.posX - entityplayer.prevPosX) * (double)f; + double d1 = (entityplayer.prevPosY + (entityplayer.posY - entityplayer.prevPosY) * (double)f + 1.6200000000000001D) - (double)entityplayer.yOffset; + double d2 = entityplayer.prevPosZ + (entityplayer.posZ - entityplayer.prevPosZ) * (double)f; + Vec3D vec3d = Vec3D.createVector(d, d1, d2); + float f3 = MathHelper.cos(-f2 * 0.01745329F - 3.141593F); + float f4 = MathHelper.sin(-f2 * 0.01745329F - 3.141593F); + float f5 = -MathHelper.cos(-f1 * 0.01745329F); + float f6 = MathHelper.sin(-f1 * 0.01745329F); + float f7 = f4 * f5; + float f8 = f6; + float f9 = f3 * f5; + double d3 = 5D; + Vec3D vec3d1 = vec3d.addVector((double)f7 * d3, (double)f8 * d3, (double)f9 * d3); + MovingObjectPosition movingobjectposition = world.rayTraceBlocks_do(vec3d, vec3d1, true); + if(movingobjectposition == null) + { + return itemstack; + } + if(movingobjectposition.typeOfHit == EnumMovingObjectType.TILE) + { + int i = movingobjectposition.blockX; + int j = movingobjectposition.blockY; + int k = movingobjectposition.blockZ; + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(new EntityBoat(world, (float)i + 0.5F, (float)j + 1.5F, (float)k + 0.5F)); + } + itemstack.stackSize--; + } + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemBow.java b/src/main/java/net/minecraft/src/ItemBow.java new file mode 100644 index 0000000..81b4131 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBow.java @@ -0,0 +1,29 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemBow extends Item +{ + + public ItemBow(int i) + { + super(i); + maxStackSize = 1; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + if(entityplayer.inventory.consumeInventoryItem(Item.arrow.shiftedIndex)) + { + world.playSoundAtEntity(entityplayer, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 0.8F)); + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(new EntityArrow(world, entityplayer)); + } + } + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemBucket.java b/src/main/java/net/minecraft/src/ItemBucket.java new file mode 100644 index 0000000..b693fb7 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemBucket.java @@ -0,0 +1,119 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemBucket extends Item +{ + + public ItemBucket(int i, int j) + { + super(i); + maxStackSize = 1; + maxDamage = 64; + isFull = j; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + float f = 1.0F; + float f1 = entityplayer.prevRotationPitch + (entityplayer.rotationPitch - entityplayer.prevRotationPitch) * f; + float f2 = entityplayer.prevRotationYaw + (entityplayer.rotationYaw - entityplayer.prevRotationYaw) * f; + double d = entityplayer.prevPosX + (entityplayer.posX - entityplayer.prevPosX) * (double)f; + double d1 = (entityplayer.prevPosY + (entityplayer.posY - entityplayer.prevPosY) * (double)f + 1.6200000000000001D) - (double)entityplayer.yOffset; + double d2 = entityplayer.prevPosZ + (entityplayer.posZ - entityplayer.prevPosZ) * (double)f; + Vec3D vec3d = Vec3D.createVector(d, d1, d2); + float f3 = MathHelper.cos(-f2 * 0.01745329F - 3.141593F); + float f4 = MathHelper.sin(-f2 * 0.01745329F - 3.141593F); + float f5 = -MathHelper.cos(-f1 * 0.01745329F); + float f6 = MathHelper.sin(-f1 * 0.01745329F); + float f7 = f4 * f5; + float f8 = f6; + float f9 = f3 * f5; + double d3 = 5D; + Vec3D vec3d1 = vec3d.addVector((double)f7 * d3, (double)f8 * d3, (double)f9 * d3); + MovingObjectPosition movingobjectposition = world.rayTraceBlocks_do(vec3d, vec3d1, isFull == 0); + if(movingobjectposition == null) + { + return itemstack; + } + if(movingobjectposition.typeOfHit == EnumMovingObjectType.TILE) + { + int i = movingobjectposition.blockX; + int j = movingobjectposition.blockY; + int k = movingobjectposition.blockZ; + if(!world.func_6466_a(entityplayer, i, j, k)) + { + return itemstack; + } + if(isFull == 0) + { + if(world.getBlockMaterial(i, j, k) == Material.water && world.getBlockMetadata(i, j, k) == 0) + { + world.setBlockWithNotify(i, j, k, 0); + return new ItemStack(Item.bucketWater); + } + if(world.getBlockMaterial(i, j, k) == Material.lava && world.getBlockMetadata(i, j, k) == 0) + { + world.setBlockWithNotify(i, j, k, 0); + return new ItemStack(Item.bucketLava); + } + } else + { + if(isFull < 0) + { + return new ItemStack(Item.bucketEmpty); + } + if(movingobjectposition.sideHit == 0) + { + j--; + } + if(movingobjectposition.sideHit == 1) + { + j++; + } + if(movingobjectposition.sideHit == 2) + { + k--; + } + if(movingobjectposition.sideHit == 3) + { + k++; + } + if(movingobjectposition.sideHit == 4) + { + i--; + } + if(movingobjectposition.sideHit == 5) + { + i++; + } + if(world.isAirBlock(i, j, k) || !world.getBlockMaterial(i, j, k).isSolid()) + { + if(world.worldProvider.isHellWorld && isFull == Block.waterStill.blockID) + { + world.playSoundEffect(d + 0.5D, d1 + 0.5D, d2 + 0.5D, "random.fizz", 0.5F, 2.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.8F); + for(int l = 0; l < 8; l++) + { + world.spawnParticle("largesmoke", (double)i + Math.random(), (double)j + Math.random(), (double)k + Math.random(), 0.0D, 0.0D, 0.0D); + } + + } else + { + world.setBlockAndMetadataWithNotify(i, j, k, isFull, 0); + } + return new ItemStack(Item.bucketEmpty); + } + } + } else + if(isFull == 0 && (movingobjectposition.entityHit instanceof EntityCow)) + { + return new ItemStack(Item.bucketMilk); + } + return itemstack; + } + + private int isFull; +} diff --git a/src/main/java/net/minecraft/src/ItemCloth.java b/src/main/java/net/minecraft/src/ItemCloth.java new file mode 100644 index 0000000..45ee9b3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemCloth.java @@ -0,0 +1,31 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemCloth extends ItemBlock +{ + + public ItemCloth(int i) + { + super(i); + setMaxDamage(0); + setHasSubtypes(true); + } + + public int getIconIndex(ItemStack itemstack) + { + return Block.cloth.getBlockTextureFromSideAndMetadata(2, BlockCloth.func_21034_c(itemstack.getItemDamage())); + } + + public int func_21012_a(int i) + { + return i; + } + + public String getItemNameIS(ItemStack itemstack) + { + return (new StringBuilder()).append(super.getItemName()).append(".").append(ItemDye.dyeColors[BlockCloth.func_21034_c(itemstack.getItemDamage())]).toString(); + } +} diff --git a/src/main/java/net/minecraft/src/ItemCoal.java b/src/main/java/net/minecraft/src/ItemCoal.java new file mode 100644 index 0000000..3fdf565 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemCoal.java @@ -0,0 +1,27 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemCoal extends Item +{ + + public ItemCoal(int i) + { + super(i); + setHasSubtypes(true); + setMaxDamage(0); + } + + public String getItemNameIS(ItemStack itemstack) + { + if(itemstack.getItemDamage() == 1) + { + return "item.charcoal"; + } else + { + return "item.coal"; + } + } +} diff --git a/src/main/java/net/minecraft/src/ItemDoor.java b/src/main/java/net/minecraft/src/ItemDoor.java new file mode 100644 index 0000000..79dce3f --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemDoor.java @@ -0,0 +1,83 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemDoor extends Item +{ + + public ItemDoor(int i, Material material) + { + super(i); + field_321_a = material; + maxDamage = 64; + maxStackSize = 1; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l != 1) + { + return false; + } + j++; + Block block; + if(field_321_a == Material.wood) + { + block = Block.doorWood; + } else + { + block = Block.doorSteel; + } + if(!block.canPlaceBlockAt(world, i, j, k)) + { + return false; + } + int i1 = MathHelper.floor_double((double)(((entityplayer.rotationYaw + 180F) * 4F) / 360F) - 0.5D) & 3; + byte byte0 = 0; + byte byte1 = 0; + if(i1 == 0) + { + byte1 = 1; + } + if(i1 == 1) + { + byte0 = -1; + } + if(i1 == 2) + { + byte1 = -1; + } + if(i1 == 3) + { + byte0 = 1; + } + int j1 = (world.isBlockOpaqueCube(i - byte0, j, k - byte1) ? 1 : 0) + (world.isBlockOpaqueCube(i - byte0, j + 1, k - byte1) ? 1 : 0); + int k1 = (world.isBlockOpaqueCube(i + byte0, j, k + byte1) ? 1 : 0) + (world.isBlockOpaqueCube(i + byte0, j + 1, k + byte1) ? 1 : 0); + boolean flag = world.getBlockId(i - byte0, j, k - byte1) == block.blockID || world.getBlockId(i - byte0, j + 1, k - byte1) == block.blockID; + boolean flag1 = world.getBlockId(i + byte0, j, k + byte1) == block.blockID || world.getBlockId(i + byte0, j + 1, k + byte1) == block.blockID; + boolean flag2 = false; + if(flag && !flag1) + { + flag2 = true; + } else + if(k1 > j1) + { + flag2 = true; + } + if(flag2) + { + i1 = i1 - 1 & 3; + i1 += 4; + } + world.setBlockWithNotify(i, j, k, block.blockID); + world.setBlockMetadataWithNotify(i, j, k, i1); + world.setBlockWithNotify(i, j + 1, k, block.blockID); + world.setBlockMetadataWithNotify(i, j + 1, k, i1 + 8); + itemstack.stackSize--; + return true; + } + + private Material field_321_a; +} diff --git a/src/main/java/net/minecraft/src/ItemDye.java b/src/main/java/net/minecraft/src/ItemDye.java new file mode 100644 index 0000000..32c51f1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemDye.java @@ -0,0 +1,68 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemDye extends Item +{ + + public ItemDye(int i) + { + super(i); + setHasSubtypes(true); + setMaxDamage(0); + } + + public int getIconIndex(ItemStack itemstack) + { + int i = itemstack.getItemDamage(); + return iconIndex + (i % 8) * 16 + i / 8; + } + + public String getItemNameIS(ItemStack itemstack) + { + return (new StringBuilder()).append(super.getItemName()).append(".").append(dyeColors[itemstack.getItemDamage()]).toString(); + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(itemstack.getItemDamage() == 15) + { + int i1 = world.getBlockId(i, j, k); + if(i1 == Block.sapling.blockID) + { + ((BlockSapling)Block.sapling).growTree(world, i, j, k, world.rand); + itemstack.stackSize--; + return true; + } + if(i1 == Block.crops.blockID) + { + ((BlockCrops)Block.crops).func_21027_c_(world, i, j, k); + itemstack.stackSize--; + return true; + } + } + return false; + } + + public void saddleEntity(ItemStack itemstack, EntityLiving entityliving) + { + if(entityliving instanceof EntitySheep) + { + EntitySheep entitysheep = (EntitySheep)entityliving; + int i = BlockCloth.func_21034_c(itemstack.getItemDamage()); + if(!entitysheep.func_21072_p() && entitysheep.getFleeceColor() != i) + { + entitysheep.setFleeceColor(i); + itemstack.stackSize--; + } + } + } + + public static final String dyeColors[] = { + "black", "red", "green", "brown", "blue", "purple", "cyan", "silver", "gray", "pink", + "lime", "yellow", "lightBlue", "magenta", "orange", "white" + }; + +} diff --git a/src/main/java/net/minecraft/src/ItemEgg.java b/src/main/java/net/minecraft/src/ItemEgg.java new file mode 100644 index 0000000..2c67cec --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemEgg.java @@ -0,0 +1,27 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemEgg extends Item +{ + + public ItemEgg(int i) + { + super(i); + maxStackSize = 16; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + itemstack.stackSize--; + world.playSoundAtEntity(entityplayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(new EntityEgg(world, entityplayer)); + } + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemFishingRod.java b/src/main/java/net/minecraft/src/ItemFishingRod.java new file mode 100644 index 0000000..51b267b --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFishingRod.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemFishingRod extends Item +{ + + public ItemFishingRod(int i) + { + super(i); + maxDamage = 64; + } + + public boolean isFull3D() + { + return true; + } + + public boolean shouldRotateAroundWhenRendering() + { + return true; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + if(entityplayer.fishEntity != null) + { + int i = entityplayer.fishEntity.catchFish(); + itemstack.damageItem(i); + entityplayer.swingItem(); + } else + { + world.playSoundAtEntity(entityplayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(new EntityFish(world, entityplayer)); + } + entityplayer.swingItem(); + } + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemFlintAndSteel.java b/src/main/java/net/minecraft/src/ItemFlintAndSteel.java new file mode 100644 index 0000000..a835c92 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFlintAndSteel.java @@ -0,0 +1,53 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemFlintAndSteel extends Item +{ + + public ItemFlintAndSteel(int i) + { + super(i); + maxStackSize = 1; + maxDamage = 64; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l == 0) + { + j--; + } + if(l == 1) + { + j++; + } + if(l == 2) + { + k--; + } + if(l == 3) + { + k++; + } + if(l == 4) + { + i--; + } + if(l == 5) + { + i++; + } + int i1 = world.getBlockId(i, j, k); + if(i1 == 0) + { + world.playSoundEffect((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + world.setBlockWithNotify(i, j, k, Block.fire.blockID); + } + itemstack.damageItem(1); + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemFood.java b/src/main/java/net/minecraft/src/ItemFood.java new file mode 100644 index 0000000..54c74ee --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemFood.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemFood extends Item +{ + + public ItemFood(int i, int j) + { + super(i); + healAmount = j; + maxStackSize = 1; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + itemstack.stackSize--; + entityplayer.heal(healAmount); + return itemstack; + } + + private int healAmount; +} diff --git a/src/main/java/net/minecraft/src/ItemHoe.java b/src/main/java/net/minecraft/src/ItemHoe.java new file mode 100644 index 0000000..acb1699 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemHoe.java @@ -0,0 +1,58 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemHoe extends Item +{ + + public ItemHoe(int i, EnumToolMaterial enumtoolmaterial) + { + super(i); + maxStackSize = 1; + maxDamage = enumtoolmaterial.getMaxUses(); + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + int i1 = world.getBlockId(i, j, k); + Material material = world.getBlockMaterial(i, j + 1, k); + if(!material.isSolid() && i1 == Block.grass.blockID || i1 == Block.dirt.blockID) + { + Block block = Block.tilledField; + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, block.stepSound.func_1145_d(), (block.stepSound.func_1147_b() + 1.0F) / 2.0F, block.stepSound.func_1144_c() * 0.8F); + if(world.multiplayerWorld) + { + return true; + } + world.setBlockWithNotify(i, j, k, block.blockID); + itemstack.damageItem(1); + if(world.rand.nextInt(8) == 0 && i1 == Block.grass.blockID) + { + int j1 = 1; + for(int k1 = 0; k1 < j1; k1++) + { + float f = 0.7F; + float f1 = world.rand.nextFloat() * f + (1.0F - f) * 0.5F; + float f2 = 1.2F; + float f3 = world.rand.nextFloat() * f + (1.0F - f) * 0.5F; + EntityItem entityitem = new EntityItem(world, (float)i + f1, (float)j + f2, (float)k + f3, new ItemStack(Item.seeds)); + entityitem.delayBeforeCanPickup = 10; + world.entityJoinedWorld(entityitem); + } + + } + return true; + } else + { + return false; + } + } + + public boolean isFull3D() + { + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemLog.java b/src/main/java/net/minecraft/src/ItemLog.java new file mode 100644 index 0000000..b062107 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemLog.java @@ -0,0 +1,26 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemLog extends ItemBlock +{ + + public ItemLog(int i) + { + super(i); + setMaxDamage(0); + setHasSubtypes(true); + } + + public int getIconIndex(ItemStack itemstack) + { + return Block.wood.getBlockTextureFromSideAndMetadata(2, itemstack.getItemDamage()); + } + + public int func_21012_a(int i) + { + return i; + } +} diff --git a/src/main/java/net/minecraft/src/ItemMinecart.java b/src/main/java/net/minecraft/src/ItemMinecart.java new file mode 100644 index 0000000..477349e --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemMinecart.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemMinecart extends Item +{ + + public ItemMinecart(int i, int j) + { + super(i); + maxStackSize = 1; + minecartType = j; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + int i1 = world.getBlockId(i, j, k); + if(i1 == Block.minecartTrack.blockID) + { + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(new EntityMinecart(world, (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, minecartType)); + } + itemstack.stackSize--; + return true; + } else + { + return false; + } + } + + public int minecartType; +} diff --git a/src/main/java/net/minecraft/src/ItemPainting.java b/src/main/java/net/minecraft/src/ItemPainting.java new file mode 100644 index 0000000..70082e0 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemPainting.java @@ -0,0 +1,50 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemPainting extends Item +{ + + public ItemPainting(int i) + { + super(i); + maxDamage = 64; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l == 0) + { + return false; + } + if(l == 1) + { + return false; + } + byte byte0 = 0; + if(l == 4) + { + byte0 = 1; + } + if(l == 3) + { + byte0 = 2; + } + if(l == 5) + { + byte0 = 3; + } + EntityPainting entitypainting = new EntityPainting(world, i, j, k, byte0); + if(entitypainting.func_410_i()) + { + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(entitypainting); + } + itemstack.stackSize--; + } + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemPickaxe.java b/src/main/java/net/minecraft/src/ItemPickaxe.java new file mode 100644 index 0000000..6612267 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemPickaxe.java @@ -0,0 +1,57 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemPickaxe extends ItemTool +{ + + protected ItemPickaxe(int i, EnumToolMaterial enumtoolmaterial) + { + super(i, 2, enumtoolmaterial, blocksEffectiveAgainst); + } + + public boolean canHarvestBlock(Block block) + { + if(block == Block.obsidian) + { + return toolMaterial.getHarvestLevel() == 3; + } + if(block == Block.blockDiamond || block == Block.oreDiamond) + { + return toolMaterial.getHarvestLevel() >= 2; + } + if(block == Block.blockGold || block == Block.oreGold) + { + return toolMaterial.getHarvestLevel() >= 2; + } + if(block == Block.blockSteel || block == Block.oreIron) + { + return toolMaterial.getHarvestLevel() >= 1; + } + if(block == Block.blockLapis || block == Block.oreLapis) + { + return toolMaterial.getHarvestLevel() >= 1; + } + if(block == Block.oreRedstone || block == Block.oreRedstoneGlowing) + { + return toolMaterial.getHarvestLevel() >= 2; + } + if(block.blockMaterial == Material.rock) + { + return true; + } + return block.blockMaterial == Material.iron; + } + + private static Block blocksEffectiveAgainst[]; + + static + { + blocksEffectiveAgainst = (new Block[] { + Block.cobblestone, Block.stairDouble, Block.stairSingle, Block.stone, Block.sandStone, Block.cobblestoneMossy, Block.oreIron, Block.blockSteel, Block.oreCoal, Block.blockGold, + Block.oreGold, Block.oreDiamond, Block.blockDiamond, Block.ice, Block.bloodStone, Block.oreLapis, Block.blockLapis + }); + } +} diff --git a/src/main/java/net/minecraft/src/ItemRecord.java b/src/main/java/net/minecraft/src/ItemRecord.java new file mode 100644 index 0000000..5bea65f --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemRecord.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemRecord extends Item +{ + + protected ItemRecord(int i, String s) + { + super(i); + recordName = s; + maxStackSize = 1; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(world.getBlockId(i, j, k) == Block.jukebox.blockID && world.getBlockMetadata(i, j, k) == 0) + { + world.setBlockMetadataWithNotify(i, j, k, (shiftedIndex - Item.record13.shiftedIndex) + 1); + world.playRecord(recordName, i, j, k); + itemstack.stackSize--; + return true; + } else + { + return false; + } + } + + private String recordName; +} diff --git a/src/main/java/net/minecraft/src/ItemRedstone.java b/src/main/java/net/minecraft/src/ItemRedstone.java new file mode 100644 index 0000000..2b8c543 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemRedstone.java @@ -0,0 +1,52 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemRedstone extends Item +{ + + public ItemRedstone(int i) + { + super(i); + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l == 0) + { + j--; + } + if(l == 1) + { + j++; + } + if(l == 2) + { + k--; + } + if(l == 3) + { + k++; + } + if(l == 4) + { + i--; + } + if(l == 5) + { + i++; + } + if(!world.isAirBlock(i, j, k)) + { + return false; + } + if(Block.redstoneWire.canPlaceBlockAt(world, i, j, k)) + { + itemstack.stackSize--; + world.setBlockWithNotify(i, j, k, Block.redstoneWire.blockID); + } + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemReed.java b/src/main/java/net/minecraft/src/ItemReed.java new file mode 100644 index 0000000..ee03b95 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemReed.java @@ -0,0 +1,67 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemReed extends Item +{ + + public ItemReed(int i, Block block) + { + super(i); + field_320_a = block.blockID; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(world.getBlockId(i, j, k) == Block.snow.blockID) + { + l = 0; + } else + { + if(l == 0) + { + j--; + } + if(l == 1) + { + j++; + } + if(l == 2) + { + k--; + } + if(l == 3) + { + k++; + } + if(l == 4) + { + i--; + } + if(l == 5) + { + i++; + } + } + if(itemstack.stackSize == 0) + { + return false; + } + if(world.canBlockBePlacedAt(field_320_a, i, j, k, false)) + { + Block block = Block.blocksList[field_320_a]; + if(world.setBlockWithNotify(i, j, k, field_320_a)) + { + Block.blocksList[field_320_a].onBlockPlaced(world, i, j, k, l); + Block.blocksList[field_320_a].onBlockPlacedBy(world, i, j, k, entityplayer); + world.playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, block.stepSound.func_1145_d(), (block.stepSound.func_1147_b() + 1.0F) / 2.0F, block.stepSound.func_1144_c() * 0.8F); + itemstack.stackSize--; + } + } + return true; + } + + private int field_320_a; +} diff --git a/src/main/java/net/minecraft/src/ItemRenderer.java b/src/main/java/net/minecraft/src/ItemRenderer.java new file mode 100644 index 0000000..98bf4af --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemRenderer.java @@ -0,0 +1,377 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class ItemRenderer +{ + + public ItemRenderer(Minecraft minecraft) + { + itemToRender = null; + equippedProgress = 0.0F; + prevEquippedProgress = 0.0F; + field_1357_e = new RenderBlocks(); + field_20099_f = -1; + mc = minecraft; + } + + public void renderItem(ItemStack itemstack) + { + GL11.glPushMatrix(); + if(itemstack.itemID < 256 && RenderBlocks.func_1219_a(Block.blocksList[itemstack.itemID].getRenderType())) + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/terrain.png")); + field_1357_e.func_1227_a(Block.blocksList[itemstack.itemID], itemstack.getItemDamage()); + } else + { + if(itemstack.itemID < 256) + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/terrain.png")); + } else + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture("/gui/items.png")); + } + Tessellator tessellator = Tessellator.instance; + float f = ((float)((itemstack.getIconIndex() % 16) * 16) + 0.0F) / 256F; + float f1 = ((float)((itemstack.getIconIndex() % 16) * 16) + 15.99F) / 256F; + float f2 = ((float)((itemstack.getIconIndex() / 16) * 16) + 0.0F) / 256F; + float f3 = ((float)((itemstack.getIconIndex() / 16) * 16) + 15.99F) / 256F; + float f4 = 1.0F; + float f5 = 0.0F; + float f6 = 0.3F; + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glTranslatef(-f5, -f6, 0.0F); + float f7 = 1.5F; + GL11.glScalef(f7, f7, f7); + GL11.glRotatef(50F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(335F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(-0.9375F, -0.0625F, 0.0F); + float f8 = 0.0625F; + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, f1, f3); + tessellator.addVertexWithUV(f4, 0.0D, 0.0D, f, f3); + tessellator.addVertexWithUV(f4, 1.0D, 0.0D, f, f2); + tessellator.addVertexWithUV(0.0D, 1.0D, 0.0D, f1, f2); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + tessellator.addVertexWithUV(0.0D, 1.0D, 0.0F - f8, f1, f2); + tessellator.addVertexWithUV(f4, 1.0D, 0.0F - f8, f, f2); + tessellator.addVertexWithUV(f4, 0.0D, 0.0F - f8, f, f3); + tessellator.addVertexWithUV(0.0D, 0.0D, 0.0F - f8, f1, f3); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1F, 0.0F, 0.0F); + for(int i = 0; i < 16; i++) + { + float f9 = (float)i / 16F; + float f13 = (f1 + (f - f1) * f9) - 0.001953125F; + float f17 = f4 * f9; + tessellator.addVertexWithUV(f17, 0.0D, 0.0F - f8, f13, f3); + tessellator.addVertexWithUV(f17, 0.0D, 0.0D, f13, f3); + tessellator.addVertexWithUV(f17, 1.0D, 0.0D, f13, f2); + tessellator.addVertexWithUV(f17, 1.0D, 0.0F - f8, f13, f2); + } + + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + for(int j = 0; j < 16; j++) + { + float f10 = (float)j / 16F; + float f14 = (f1 + (f - f1) * f10) - 0.001953125F; + float f18 = f4 * f10 + 0.0625F; + tessellator.addVertexWithUV(f18, 1.0D, 0.0F - f8, f14, f2); + tessellator.addVertexWithUV(f18, 1.0D, 0.0D, f14, f2); + tessellator.addVertexWithUV(f18, 0.0D, 0.0D, f14, f3); + tessellator.addVertexWithUV(f18, 0.0D, 0.0F - f8, f14, f3); + } + + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + for(int k = 0; k < 16; k++) + { + float f11 = (float)k / 16F; + float f15 = (f3 + (f2 - f3) * f11) - 0.001953125F; + float f19 = f4 * f11 + 0.0625F; + tessellator.addVertexWithUV(0.0D, f19, 0.0D, f1, f15); + tessellator.addVertexWithUV(f4, f19, 0.0D, f, f15); + tessellator.addVertexWithUV(f4, f19, 0.0F - f8, f, f15); + tessellator.addVertexWithUV(0.0D, f19, 0.0F - f8, f1, f15); + } + + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + for(int l = 0; l < 16; l++) + { + float f12 = (float)l / 16F; + float f16 = (f3 + (f2 - f3) * f12) - 0.001953125F; + float f20 = f4 * f12; + tessellator.addVertexWithUV(f4, f20, 0.0D, f, f16); + tessellator.addVertexWithUV(0.0D, f20, 0.0D, f1, f16); + tessellator.addVertexWithUV(0.0D, f20, 0.0F - f8, f1, f16); + tessellator.addVertexWithUV(f4, f20, 0.0F - f8, f, f16); + } + + tessellator.draw(); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + } + GL11.glPopMatrix(); + } + + public void renderItemInFirstPerson(float f) + { + float f1 = prevEquippedProgress + (equippedProgress - prevEquippedProgress) * f; + EntityPlayerSP entityplayersp = mc.thePlayer; + GL11.glPushMatrix(); + GL11.glRotatef(((EntityPlayer) (entityplayersp)).prevRotationPitch + (((EntityPlayer) (entityplayersp)).rotationPitch - ((EntityPlayer) (entityplayersp)).prevRotationPitch) * f, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(((EntityPlayer) (entityplayersp)).prevRotationYaw + (((EntityPlayer) (entityplayersp)).rotationYaw - ((EntityPlayer) (entityplayersp)).prevRotationYaw) * f, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + GL11.glPopMatrix(); + float f2 = mc.theWorld.getLightBrightness(MathHelper.floor_double(((EntityPlayer) (entityplayersp)).posX), MathHelper.floor_double(((EntityPlayer) (entityplayersp)).posY), MathHelper.floor_double(((EntityPlayer) (entityplayersp)).posZ)); + GL11.glColor4f(f2, f2, f2, 1.0F); + ItemStack itemstack = itemToRender; + if(((EntityPlayer) (entityplayersp)).fishEntity != null) + { + itemstack = new ItemStack(Item.stick); + } + if(itemstack != null) + { + GL11.glPushMatrix(); + float f3 = 0.8F; + float f5 = entityplayersp.getSwingProgress(f); + float f7 = MathHelper.sin(f5 * 3.141593F); + float f9 = MathHelper.sin(MathHelper.sqrt_float(f5) * 3.141593F); + GL11.glTranslatef(-f9 * 0.4F, MathHelper.sin(MathHelper.sqrt_float(f5) * 3.141593F * 2.0F) * 0.2F, -f7 * 0.2F); + GL11.glTranslatef(0.7F * f3, -0.65F * f3 - (1.0F - f1) * 0.6F, -0.9F * f3); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + f5 = entityplayersp.getSwingProgress(f); + f7 = MathHelper.sin(f5 * f5 * 3.141593F); + f9 = MathHelper.sin(MathHelper.sqrt_float(f5) * 3.141593F); + GL11.glRotatef(-f7 * 20F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-f9 * 20F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-f9 * 80F, 1.0F, 0.0F, 0.0F); + f5 = 0.4F; + GL11.glScalef(f5, f5, f5); + if(itemstack.getItem().shouldRotateAroundWhenRendering()) + { + GL11.glRotatef(180F, 0.0F, 1.0F, 0.0F); + } + renderItem(itemstack); + GL11.glPopMatrix(); + } else + { + GL11.glPushMatrix(); + float f4 = 0.8F; + float f6 = entityplayersp.getSwingProgress(f); + float f8 = MathHelper.sin(f6 * 3.141593F); + float f10 = MathHelper.sin(MathHelper.sqrt_float(f6) * 3.141593F); + GL11.glTranslatef(-f10 * 0.3F, MathHelper.sin(MathHelper.sqrt_float(f6) * 3.141593F * 2.0F) * 0.4F, -f8 * 0.4F); + GL11.glTranslatef(0.8F * f4, -0.75F * f4 - (1.0F - f1) * 0.6F, -0.9F * f4); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + f6 = entityplayersp.getSwingProgress(f); + f8 = MathHelper.sin(f6 * f6 * 3.141593F); + f10 = MathHelper.sin(MathHelper.sqrt_float(f6) * 3.141593F); + GL11.glRotatef(f10 * 70F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-f8 * 20F, 0.0F, 0.0F, 1.0F); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTextureForDownloadableImage(mc.thePlayer.skinUrl, mc.thePlayer.getEntityTexture())); + GL11.glTranslatef(-1F, 3.6F, 3.5F); + GL11.glRotatef(120F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(200F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(-135F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(1.0F, 1.0F, 1.0F); + GL11.glTranslatef(5.6F, 0.0F, 0.0F); + Render render = RenderManager.instance.getEntityRenderObject(mc.thePlayer); + RenderPlayer renderplayer = (RenderPlayer)render; + f10 = 1.0F; + GL11.glScalef(f10, f10, f10); + renderplayer.drawFirstPersonHand(); + GL11.glPopMatrix(); + } + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + RenderHelper.disableStandardItemLighting(); + } + + public void renderOverlays(float f) + { + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + if(mc.thePlayer.func_21062_U()) + { + int i = mc.renderEngine.getTexture("/terrain.png"); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, i); + renderFireInFirstPerson(f); + } + if(mc.thePlayer.func_345_I()) + { + int j = MathHelper.floor_double(mc.thePlayer.posX); + int l = MathHelper.floor_double(mc.thePlayer.posY); + int i1 = MathHelper.floor_double(mc.thePlayer.posZ); + int j1 = mc.renderEngine.getTexture("/terrain.png"); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, j1); + int k1 = mc.theWorld.getBlockId(j, l, i1); + if(Block.blocksList[k1] != null) + { + renderInsideOfBlock(f, Block.blocksList[k1].getBlockTextureFromSide(2)); + } + } + if(mc.thePlayer.isInsideOfMaterial(Material.water)) + { + int k = mc.renderEngine.getTexture("/misc/water.png"); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, k); + renderWarpedTextureOverlay(f); + } + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + } + + private void renderInsideOfBlock(float f, int i) + { + Tessellator tessellator = Tessellator.instance; + float f1 = mc.thePlayer.getEntityBrightness(f); + f1 = 0.1F; + GL11.glColor4f(f1, f1, f1, 0.5F); + GL11.glPushMatrix(); + float f2 = -1F; + float f3 = 1.0F; + float f4 = -1F; + float f5 = 1.0F; + float f6 = -0.5F; + float f7 = 0.0078125F; + float f8 = (float)(i % 16) / 256F - f7; + float f9 = ((float)(i % 16) + 15.99F) / 256F + f7; + float f10 = (float)(i / 16) / 256F - f7; + float f11 = ((float)(i / 16) + 15.99F) / 256F + f7; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(f2, f4, f6, f9, f11); + tessellator.addVertexWithUV(f3, f4, f6, f8, f11); + tessellator.addVertexWithUV(f3, f5, f6, f8, f10); + tessellator.addVertexWithUV(f2, f5, f6, f9, f10); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + private void renderWarpedTextureOverlay(float f) + { + Tessellator tessellator = Tessellator.instance; + float f1 = mc.thePlayer.getEntityBrightness(f); + GL11.glColor4f(f1, f1, f1, 0.5F); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + GL11.glPushMatrix(); + float f2 = 4F; + float f3 = -1F; + float f4 = 1.0F; + float f5 = -1F; + float f6 = 1.0F; + float f7 = -0.5F; + float f8 = -mc.thePlayer.rotationYaw / 64F; + float f9 = mc.thePlayer.rotationPitch / 64F; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(f3, f5, f7, f2 + f8, f2 + f9); + tessellator.addVertexWithUV(f4, f5, f7, 0.0F + f8, f2 + f9); + tessellator.addVertexWithUV(f4, f6, f7, 0.0F + f8, 0.0F + f9); + tessellator.addVertexWithUV(f3, f6, f7, f2 + f8, 0.0F + f9); + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + } + + private void renderFireInFirstPerson(float f) + { + Tessellator tessellator = Tessellator.instance; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.9F); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + float f1 = 1.0F; + for(int i = 0; i < 2; i++) + { + GL11.glPushMatrix(); + int j = Block.fire.blockIndexInTexture + i * 16; + int k = (j & 0xf) << 4; + int l = j & 0xf0; + float f2 = (float)k / 256F; + float f3 = ((float)k + 15.99F) / 256F; + float f4 = (float)l / 256F; + float f5 = ((float)l + 15.99F) / 256F; + float f6 = (0.0F - f1) / 2.0F; + float f7 = f6 + f1; + float f8 = 0.0F - f1 / 2.0F; + float f9 = f8 + f1; + float f10 = -0.5F; + GL11.glTranslatef((float)(-(i * 2 - 1)) * 0.24F, -0.3F, 0.0F); + GL11.glRotatef((float)(i * 2 - 1) * 10F, 0.0F, 1.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(f6, f8, f10, f3, f5); + tessellator.addVertexWithUV(f7, f8, f10, f2, f5); + tessellator.addVertexWithUV(f7, f9, f10, f2, f4); + tessellator.addVertexWithUV(f6, f9, f10, f3, f4); + tessellator.draw(); + GL11.glPopMatrix(); + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + } + + public void updateEquippedItem() + { + prevEquippedProgress = equippedProgress; + EntityPlayerSP entityplayersp = mc.thePlayer; + ItemStack itemstack = ((EntityPlayer) (entityplayersp)).inventory.getCurrentItem(); + ItemStack itemstack1 = itemstack; + boolean flag = field_20099_f == ((EntityPlayer) (entityplayersp)).inventory.currentItem && itemstack1 == itemToRender; + if(itemToRender == null && itemstack1 == null) + { + flag = true; + } + if(itemstack1 != null && itemToRender != null && itemstack1 != itemToRender && itemstack1.itemID == itemToRender.itemID) + { + itemToRender = itemstack1; + flag = true; + } + float f = 0.4F; + float f1 = flag ? 1.0F : 0.0F; + float f2 = f1 - equippedProgress; + if(f2 < -f) + { + f2 = -f; + } + if(f2 > f) + { + f2 = f; + } + equippedProgress += f2; + if(equippedProgress < 0.1F) + { + itemToRender = itemstack1; + field_20099_f = ((EntityPlayer) (entityplayersp)).inventory.currentItem; + } + } + + public void func_9449_b() + { + equippedProgress = 0.0F; + } + + public void func_9450_c() + { + equippedProgress = 0.0F; + } + + private Minecraft mc; + private ItemStack itemToRender; + private float equippedProgress; + private float prevEquippedProgress; + private RenderBlocks field_1357_e; + private int field_20099_f; +} diff --git a/src/main/java/net/minecraft/src/ItemSaddle.java b/src/main/java/net/minecraft/src/ItemSaddle.java new file mode 100644 index 0000000..c6e73b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSaddle.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSaddle extends Item +{ + + public ItemSaddle(int i) + { + super(i); + maxStackSize = 1; + maxDamage = 64; + } + + public void saddleEntity(ItemStack itemstack, EntityLiving entityliving) + { + if(entityliving instanceof EntityPig) + { + EntityPig entitypig = (EntityPig)entityliving; + if(!entitypig.func_21068_q()) + { + entitypig.func_21069_a(true); + itemstack.stackSize--; + } + } + } + + public void hitEntity(ItemStack itemstack, EntityLiving entityliving) + { + saddleEntity(itemstack, entityliving); + } +} diff --git a/src/main/java/net/minecraft/src/ItemSeeds.java b/src/main/java/net/minecraft/src/ItemSeeds.java new file mode 100644 index 0000000..582a1e3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSeeds.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSeeds extends Item +{ + + public ItemSeeds(int i, int j) + { + super(i); + field_318_a = j; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l != 1) + { + return false; + } + int i1 = world.getBlockId(i, j, k); + if(i1 == Block.tilledField.blockID && world.isAirBlock(i, j + 1, k)) + { + world.setBlockWithNotify(i, j + 1, k, field_318_a); + itemstack.stackSize--; + return true; + } else + { + return false; + } + } + + private int field_318_a; +} diff --git a/src/main/java/net/minecraft/src/ItemSign.java b/src/main/java/net/minecraft/src/ItemSign.java new file mode 100644 index 0000000..021238c --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSign.java @@ -0,0 +1,66 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSign extends Item +{ + + public ItemSign(int i) + { + super(i); + maxDamage = 64; + maxStackSize = 1; + } + + public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + if(l == 0) + { + return false; + } + if(!world.getBlockMaterial(i, j, k).isSolid()) + { + return false; + } + if(l == 1) + { + j++; + } + if(l == 2) + { + k--; + } + if(l == 3) + { + k++; + } + if(l == 4) + { + i--; + } + if(l == 5) + { + i++; + } + if(!Block.signPost.canPlaceBlockAt(world, i, j, k)) + { + return false; + } + if(l == 1) + { + world.setBlockAndMetadataWithNotify(i, j, k, Block.signPost.blockID, MathHelper.floor_double((double)(((entityplayer.rotationYaw + 180F) * 16F) / 360F) + 0.5D) & 0xf); + } else + { + world.setBlockAndMetadataWithNotify(i, j, k, Block.signWall.blockID, l); + } + itemstack.stackSize--; + TileEntitySign tileentitysign = (TileEntitySign)world.getBlockTileEntity(i, j, k); + if(tileentitysign != null) + { + entityplayer.displayGUIEditSign(tileentitysign); + } + return true; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSlab.java b/src/main/java/net/minecraft/src/ItemSlab.java new file mode 100644 index 0000000..f11488c --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSlab.java @@ -0,0 +1,31 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSlab extends ItemBlock +{ + + public ItemSlab(int i) + { + super(i); + setMaxDamage(0); + setHasSubtypes(true); + } + + public int getIconIndex(ItemStack itemstack) + { + return Block.stairSingle.getBlockTextureFromSideAndMetadata(2, itemstack.getItemDamage()); + } + + public int func_21012_a(int i) + { + return i; + } + + public String getItemNameIS(ItemStack itemstack) + { + return (new StringBuilder()).append(super.getItemName()).append(".").append(BlockStep.field_22037_a[itemstack.getItemDamage()]).toString(); + } +} diff --git a/src/main/java/net/minecraft/src/ItemSnowball.java b/src/main/java/net/minecraft/src/ItemSnowball.java new file mode 100644 index 0000000..5ae57c5 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSnowball.java @@ -0,0 +1,27 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ItemSnowball extends Item +{ + + public ItemSnowball(int i) + { + super(i); + maxStackSize = 16; + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + itemstack.stackSize--; + world.playSoundAtEntity(entityplayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + if(!world.multiplayerWorld) + { + world.entityJoinedWorld(new EntitySnowball(world, entityplayer)); + } + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/src/ItemSoup.java b/src/main/java/net/minecraft/src/ItemSoup.java new file mode 100644 index 0000000..49721a3 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSoup.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSoup extends ItemFood +{ + + public ItemSoup(int i, int j) + { + super(i, j); + } + + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + super.onItemRightClick(itemstack, world, entityplayer); + return new ItemStack(Item.bowlEmpty); + } +} diff --git a/src/main/java/net/minecraft/src/ItemSpade.java b/src/main/java/net/minecraft/src/ItemSpade.java new file mode 100644 index 0000000..f7866b0 --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSpade.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSpade extends ItemTool +{ + + public ItemSpade(int i, EnumToolMaterial enumtoolmaterial) + { + super(i, 1, enumtoolmaterial, blocksEffectiveAgainst); + } + + public boolean canHarvestBlock(Block block) + { + if(block == Block.snow) + { + return true; + } + return block == Block.blockSnow; + } + + private static Block blocksEffectiveAgainst[]; + + static + { + blocksEffectiveAgainst = (new Block[] { + Block.grass, Block.dirt, Block.sand, Block.gravel, Block.snow, Block.blockSnow, Block.blockClay + }); + } +} diff --git a/src/main/java/net/minecraft/src/ItemStack.java b/src/main/java/net/minecraft/src/ItemStack.java new file mode 100644 index 0000000..14c677c --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemStack.java @@ -0,0 +1,239 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public final class ItemStack +{ + + public ItemStack(Block block) + { + this(block, 1); + } + + public ItemStack(Block block, int i) + { + this(block.blockID, i, 0); + } + + public ItemStack(Block block, int i, int j) + { + this(block.blockID, i, j); + } + + public ItemStack(Item item) + { + this(item.shiftedIndex, 1, 0); + } + + public ItemStack(Item item, int i) + { + this(item.shiftedIndex, i, 0); + } + + public ItemStack(Item item, int i, int j) + { + this(item.shiftedIndex, i, j); + } + + public ItemStack(int i, int j, int k) + { + stackSize = 0; + itemID = i; + stackSize = j; + itemDamage = k; + } + + public ItemStack(NBTTagCompound nbttagcompound) + { + stackSize = 0; + readFromNBT(nbttagcompound); + } + + public ItemStack splitStack(int i) + { + stackSize -= i; + return new ItemStack(itemID, i, itemDamage); + } + + public Item getItem() + { + return Item.itemsList[itemID]; + } + + public int getIconIndex() + { + return getItem().getIconIndex(this); + } + + public boolean useItem(EntityPlayer entityplayer, World world, int i, int j, int k, int l) + { + return getItem().onItemUse(this, entityplayer, world, i, j, k, l); + } + + public float getStrVsBlock(Block block) + { + return getItem().getStrVsBlock(this, block); + } + + public ItemStack useItemRightClick(World world, EntityPlayer entityplayer) + { + return getItem().onItemRightClick(this, world, entityplayer); + } + + public NBTTagCompound writeToNBT(NBTTagCompound nbttagcompound) + { + nbttagcompound.setShort("id", (short)itemID); + nbttagcompound.setByte("Count", (byte)stackSize); + nbttagcompound.setShort("Damage", (short)itemDamage); + return nbttagcompound; + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + itemID = nbttagcompound.getShort("id"); + stackSize = nbttagcompound.getByte("Count"); + itemDamage = nbttagcompound.getShort("Damage"); + } + + public int getMaxStackSize() + { + return getItem().getItemStackLimit(); + } + + public boolean func_21180_d() + { + return getMaxStackSize() > 1 && (!isItemStackDamageable() || !isItemDamaged()); + } + + public boolean isItemStackDamageable() + { + return Item.itemsList[itemID].getMaxDamage() > 0; + } + + public boolean getHasSubtypes() + { + return Item.itemsList[itemID].getHasSubtypes(); + } + + public boolean isItemDamaged() + { + return isItemStackDamageable() && itemDamage > 0; + } + + public int getItemDamageForDisplay() + { + return itemDamage; + } + + public int getItemDamage() + { + return itemDamage; + } + + public int getMaxDamage() + { + return Item.itemsList[itemID].getMaxDamage(); + } + + public void damageItem(int i) + { + if(!isItemStackDamageable()) + { + return; + } + itemDamage += i; + if(itemDamage > getMaxDamage()) + { + stackSize--; + if(stackSize < 0) + { + stackSize = 0; + } + itemDamage = 0; + } + } + + public void hitEntity(EntityLiving entityliving) + { + Item.itemsList[itemID].hitEntity(this, entityliving); + } + + public void hitBlock(int i, int j, int k, int l) + { + Item.itemsList[itemID].hitBlock(this, i, j, k, l); + } + + public int getDamageVsEntity(Entity entity) + { + return Item.itemsList[itemID].getDamageVsEntity(entity); + } + + public boolean canHarvestBlock(Block block) + { + return Item.itemsList[itemID].canHarvestBlock(block); + } + + public void func_1097_a(EntityPlayer entityplayer) + { + } + + public void useItemOnEntity(EntityLiving entityliving) + { + Item.itemsList[itemID].saddleEntity(this, entityliving); + } + + public ItemStack copy() + { + return new ItemStack(itemID, stackSize, itemDamage); + } + + public static boolean areItemStacksEqual(ItemStack itemstack, ItemStack itemstack1) + { + if(itemstack == null && itemstack1 == null) + { + return true; + } + if(itemstack == null || itemstack1 == null) + { + return false; + } else + { + return itemstack.isItemStackEqual(itemstack1); + } + } + + private boolean isItemStackEqual(ItemStack itemstack) + { + if(stackSize != itemstack.stackSize) + { + return false; + } + if(itemID != itemstack.itemID) + { + return false; + } + return itemDamage == itemstack.itemDamage; + } + + public boolean isItemEqual(ItemStack itemstack) + { + return itemID == itemstack.itemID && itemDamage == itemstack.itemDamage; + } + + public String func_20109_f() + { + return Item.itemsList[itemID].getItemNameIS(this); + } + + public String toString() + { + return (new StringBuilder()).append(stackSize).append("x").append(Item.itemsList[itemID].getItemName()).append("@").append(itemDamage).toString(); + } + + public int stackSize; + public int animationsToGo; + public int itemID; + private int itemDamage; +} diff --git a/src/main/java/net/minecraft/src/ItemSword.java b/src/main/java/net/minecraft/src/ItemSword.java new file mode 100644 index 0000000..a3f6d0b --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemSword.java @@ -0,0 +1,44 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemSword extends Item +{ + + public ItemSword(int i, EnumToolMaterial enumtoolmaterial) + { + super(i); + maxStackSize = 1; + maxDamage = enumtoolmaterial.getMaxUses(); + weaponDamage = 4 + enumtoolmaterial.getDamageVsEntity() * 2; + } + + public float getStrVsBlock(ItemStack itemstack, Block block) + { + return 1.5F; + } + + public void hitEntity(ItemStack itemstack, EntityLiving entityliving) + { + itemstack.damageItem(1); + } + + public void hitBlock(ItemStack itemstack, int i, int j, int k, int l) + { + itemstack.damageItem(2); + } + + public int getDamageVsEntity(Entity entity) + { + return weaponDamage; + } + + public boolean isFull3D() + { + return true; + } + + private int weaponDamage; +} diff --git a/src/main/java/net/minecraft/src/ItemTool.java b/src/main/java/net/minecraft/src/ItemTool.java new file mode 100644 index 0000000..fbed7dc --- /dev/null +++ b/src/main/java/net/minecraft/src/ItemTool.java @@ -0,0 +1,59 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ItemTool extends Item +{ + + protected ItemTool(int i, int j, EnumToolMaterial enumtoolmaterial, Block ablock[]) + { + super(i); + efficiencyOnProperMaterial = 4F; + toolMaterial = enumtoolmaterial; + blocksEffectiveAgainst = ablock; + maxStackSize = 1; + maxDamage = enumtoolmaterial.getMaxUses(); + efficiencyOnProperMaterial = enumtoolmaterial.getEfficiencyOnProperMaterial(); + damageVsEntity = j + enumtoolmaterial.getDamageVsEntity(); + } + + public float getStrVsBlock(ItemStack itemstack, Block block) + { + for(int i = 0; i < blocksEffectiveAgainst.length; i++) + { + if(blocksEffectiveAgainst[i] == block) + { + return efficiencyOnProperMaterial; + } + } + + return 1.0F; + } + + public void hitEntity(ItemStack itemstack, EntityLiving entityliving) + { + itemstack.damageItem(2); + } + + public void hitBlock(ItemStack itemstack, int i, int j, int k, int l) + { + itemstack.damageItem(1); + } + + public int getDamageVsEntity(Entity entity) + { + return damageVsEntity; + } + + public boolean isFull3D() + { + return true; + } + + private Block blocksEffectiveAgainst[]; + private float efficiencyOnProperMaterial; + private int damageVsEntity; + protected EnumToolMaterial toolMaterial; +} diff --git a/src/main/java/net/minecraft/src/KeyBinding.java b/src/main/java/net/minecraft/src/KeyBinding.java new file mode 100644 index 0000000..ccc58eb --- /dev/null +++ b/src/main/java/net/minecraft/src/KeyBinding.java @@ -0,0 +1,18 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class KeyBinding +{ + + public KeyBinding(String s, int i) + { + keyDescription = s; + keyCode = i; + } + + public String keyDescription; + public int keyCode; +} diff --git a/src/main/java/net/minecraft/src/LoadingScreenRenderer.java b/src/main/java/net/minecraft/src/LoadingScreenRenderer.java new file mode 100644 index 0000000..c16c703 --- /dev/null +++ b/src/main/java/net/minecraft/src/LoadingScreenRenderer.java @@ -0,0 +1,160 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.GL11; + +public class LoadingScreenRenderer + implements IProgressUpdate +{ + + public LoadingScreenRenderer(Minecraft minecraft) + { + field_1004_a = ""; + field_1007_c = ""; + field_1006_d = System.currentTimeMillis(); + field_1005_e = false; + mc = minecraft; + } + + public void printText(String s) + { + field_1005_e = false; + func_597_c(s); + } + + public void func_594_b(String s) + { + field_1005_e = true; + func_597_c(field_1007_c); + } + + public void func_597_c(String s) + { + if(!mc.running) + { + if(field_1005_e) + { + return; + } else + { + throw new MinecraftError(); + } + } else + { + field_1007_c = s; + ScaledResolution scaledresolution = new ScaledResolution(mc.displayWidth, mc.displayHeight); + int i = scaledresolution.getScaledWidth(); + int j = scaledresolution.getScaledHeight(); + GL11.glClear(256); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, i, j, 0.0D, 100D, 300D); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -200F); + return; + } + } + + public void displayLoadingString(String s) + { + if(!mc.running) + { + if(field_1005_e) + { + return; + } else + { + throw new MinecraftError(); + } + } else + { + field_1006_d = 0L; + field_1004_a = s; + setLoadingProgress(-1); + field_1006_d = 0L; + return; + } + } + + public void setLoadingProgress(int i) + { + if(!mc.running) + { + if(field_1005_e) + { + return; + } else + { + throw new MinecraftError(); + } + } + long l = System.currentTimeMillis(); + if(l - field_1006_d < 20L) + { + return; + } + field_1006_d = l; + ScaledResolution scaledresolution = new ScaledResolution(mc.displayWidth, mc.displayHeight); + int j = scaledresolution.getScaledWidth(); + int k = scaledresolution.getScaledHeight(); + GL11.glClear(256); + GL11.glMatrixMode(5889 /*GL_PROJECTION*/); + GL11.glLoadIdentity(); + GL11.glOrtho(0.0D, j, k, 0.0D, 100D, 300D); + GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/); + GL11.glLoadIdentity(); + GL11.glTranslatef(0.0F, 0.0F, -200F); + GL11.glClear(16640); + Tessellator tessellator = Tessellator.instance; + int i1 = mc.renderEngine.getTexture("/gui/background.png"); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, i1); + float f = 32F; + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0x404040); + tessellator.addVertexWithUV(0.0D, k, 0.0D, 0.0D, (float)k / f); + tessellator.addVertexWithUV(j, k, 0.0D, (float)j / f, (float)k / f); + tessellator.addVertexWithUV(j, 0.0D, 0.0D, (float)j / f, 0.0D); + tessellator.addVertexWithUV(0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + tessellator.draw(); + if(i >= 0) + { + byte byte0 = 100; + byte byte1 = 2; + int j1 = j / 2 - byte0 / 2; + int k1 = k / 2 + 16; + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(0x808080); + tessellator.addVertex(j1, k1, 0.0D); + tessellator.addVertex(j1, k1 + byte1, 0.0D); + tessellator.addVertex(j1 + byte0, k1 + byte1, 0.0D); + tessellator.addVertex(j1 + byte0, k1, 0.0D); + tessellator.setColorOpaque_I(0x80ff80); + tessellator.addVertex(j1, k1, 0.0D); + tessellator.addVertex(j1, k1 + byte1, 0.0D); + tessellator.addVertex(j1 + i, k1 + byte1, 0.0D); + tessellator.addVertex(j1 + i, k1, 0.0D); + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + mc.fontRenderer.drawStringWithShadow(field_1007_c, (j - mc.fontRenderer.getStringWidth(field_1007_c)) / 2, k / 2 - 4 - 16, 0xffffff); + mc.fontRenderer.drawStringWithShadow(field_1004_a, (j - mc.fontRenderer.getStringWidth(field_1004_a)) / 2, (k / 2 - 4) + 8, 0xffffff); + Display.update(); + try + { + Thread.yield(); + } + catch(Exception exception) { } + } + + private String field_1004_a; + private Minecraft mc; + private String field_1007_c; + private long field_1006_d; + private boolean field_1005_e; +} diff --git a/src/main/java/net/minecraft/src/LogoEffectRandomizer.java b/src/main/java/net/minecraft/src/LogoEffectRandomizer.java new file mode 100644 index 0000000..08094df --- /dev/null +++ b/src/main/java/net/minecraft/src/LogoEffectRandomizer.java @@ -0,0 +1,37 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +class LogoEffectRandomizer +{ + + public LogoEffectRandomizer(GuiMainMenu guimainmenu, int i, int j) + { + mainMenu = guimainmenu; + field_1312_a = field_1311_b = (double)(10 + j) + GuiMainMenu.getRand().nextDouble() * 32D + (double)i; + } + + public void func_875_a() + { + field_1311_b = field_1312_a; + if(field_1312_a > 0.0D) + { + field_1314_c -= 0.59999999999999998D; + } + field_1312_a += field_1314_c; + field_1314_c *= 0.90000000000000002D; + if(field_1312_a < 0.0D) + { + field_1312_a = 0.0D; + field_1314_c = 0.0D; + } + } + + public double field_1312_a; + public double field_1311_b; + public double field_1314_c; + final GuiMainMenu mainMenu; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/MCHashTable.java b/src/main/java/net/minecraft/src/MCHashTable.java new file mode 100644 index 0000000..16d0d71 --- /dev/null +++ b/src/main/java/net/minecraft/src/MCHashTable.java @@ -0,0 +1,166 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MCHashTable +{ + + public MCHashTable() + { + threshold = 12; + slots = new HashEntry[16]; + } + + private static int computeHash(int i) + { + i ^= i >>> 20 ^ i >>> 12; + return i ^ i >>> 7 ^ i >>> 4; + } + + private static int getSlotIndex(int i, int j) + { + return i & j - 1; + } + + public Object lookup(int i) + { + int j = computeHash(i); + for(HashEntry hashentry = slots[getSlotIndex(j, slots.length)]; hashentry != null; hashentry = hashentry.nextEntry) + { + if(hashentry.hashEntry == i) + { + return hashentry.valueEntry; + } + } + + return null; + } + + public void addKey(int i, Object obj) + { + int j = computeHash(i); + int k = getSlotIndex(j, slots.length); + for(HashEntry hashentry = slots[k]; hashentry != null; hashentry = hashentry.nextEntry) + { + if(hashentry.hashEntry == i) + { + hashentry.valueEntry = obj; + } + } + + versionStamp++; + insert(j, i, obj, k); + } + + private void grow(int i) + { + HashEntry ahashentry[] = slots; + int j = ahashentry.length; + if(j == 0x40000000) + { + threshold = 0x7fffffff; + return; + } else + { + HashEntry ahashentry1[] = new HashEntry[i]; + copyTo(ahashentry1); + slots = ahashentry1; + threshold = (int)((float)i * growFactor); + return; + } + } + + private void copyTo(HashEntry ahashentry[]) + { + HashEntry ahashentry1[] = slots; + int i = ahashentry.length; + for(int j = 0; j < ahashentry1.length; j++) + { + HashEntry hashentry = ahashentry1[j]; + if(hashentry == null) + { + continue; + } + ahashentry1[j] = null; + do + { + HashEntry hashentry1 = hashentry.nextEntry; + int k = getSlotIndex(hashentry.slotHash, i); + hashentry.nextEntry = ahashentry[k]; + ahashentry[k] = hashentry; + hashentry = hashentry1; + } while(hashentry != null); + } + + } + + public Object removeObject(int i) + { + HashEntry hashentry = removeEntry(i); + return hashentry != null ? hashentry.valueEntry : null; + } + + final HashEntry removeEntry(int i) + { + int j = computeHash(i); + int k = getSlotIndex(j, slots.length); + HashEntry hashentry = slots[k]; + HashEntry hashentry1; + HashEntry hashentry2; + for(hashentry1 = hashentry; hashentry1 != null; hashentry1 = hashentry2) + { + hashentry2 = hashentry1.nextEntry; + if(hashentry1.hashEntry == i) + { + versionStamp++; + count--; + if(hashentry == hashentry1) + { + slots[k] = hashentry2; + } else + { + hashentry.nextEntry = hashentry2; + } + return hashentry1; + } + hashentry = hashentry1; + } + + return hashentry1; + } + + public void clearMap() + { + versionStamp++; + HashEntry ahashentry[] = slots; + for(int i = 0; i < ahashentry.length; i++) + { + ahashentry[i] = null; + } + + count = 0; + } + + private void insert(int i, int j, Object obj, int k) + { + HashEntry hashentry = slots[k]; + slots[k] = new HashEntry(i, j, obj, hashentry); + if(count++ >= threshold) + { + grow(2 * slots.length); + } + } + + static int getHash(int i) + { + return computeHash(i); + } + + private transient HashEntry slots[]; + private transient int count; + private int threshold; + private final float growFactor = 0.75F; + private volatile transient int versionStamp; +} diff --git a/src/main/java/net/minecraft/src/MapGenBase.java b/src/main/java/net/minecraft/src/MapGenBase.java new file mode 100644 index 0000000..cb46616 --- /dev/null +++ b/src/main/java/net/minecraft/src/MapGenBase.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class MapGenBase +{ + + public MapGenBase() + { + field_1306_a = 8; + rand = new Random(); + } + + public void func_867_a(IChunkProvider ichunkprovider, World world, int i, int j, byte abyte0[]) + { + int k = field_1306_a; + rand.setSeed(world.func_22138_q()); + long l = (rand.nextLong() / 2L) * 2L + 1L; + long l1 = (rand.nextLong() / 2L) * 2L + 1L; + for(int i1 = i - k; i1 <= i + k; i1++) + { + for(int j1 = j - k; j1 <= j + k; j1++) + { + rand.setSeed((long)i1 * l + (long)j1 * l1 ^ world.func_22138_q()); + func_868_a(world, i1, j1, i, j, abyte0); + } + + } + + } + + protected void func_868_a(World world, int i, int j, int k, int l, byte abyte0[]) + { + } + + protected int field_1306_a; + protected Random rand; +} diff --git a/src/main/java/net/minecraft/src/MapGenCaves.java b/src/main/java/net/minecraft/src/MapGenCaves.java new file mode 100644 index 0000000..508736e --- /dev/null +++ b/src/main/java/net/minecraft/src/MapGenCaves.java @@ -0,0 +1,234 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class MapGenCaves extends MapGenBase +{ + + public MapGenCaves() + { + } + + protected void func_870_a(int i, int j, byte abyte0[], double d, double d1, + double d2) + { + releaseEntitySkin(i, j, abyte0, d, d1, d2, 1.0F + rand.nextFloat() * 6F, 0.0F, 0.0F, -1, -1, 0.5D); + } + + protected void releaseEntitySkin(int i, int j, byte abyte0[], double d, double d1, + double d2, float f, float f1, float f2, int k, int l, + double d3) + { + double d4 = i * 16 + 8; + double d5 = j * 16 + 8; + float f3 = 0.0F; + float f4 = 0.0F; + Random random = new Random(rand.nextLong()); + if(l <= 0) + { + int i1 = field_1306_a * 16 - 16; + l = i1 - random.nextInt(i1 / 4); + } + boolean flag = false; + if(k == -1) + { + k = l / 2; + flag = true; + } + int j1 = random.nextInt(l / 2) + l / 4; + boolean flag1 = random.nextInt(6) == 0; + for(; k < l; k++) + { + double d6 = 1.5D + (double)(MathHelper.sin(((float)k * 3.141593F) / (float)l) * f * 1.0F); + double d7 = d6 * d3; + float f5 = MathHelper.cos(f2); + float f6 = MathHelper.sin(f2); + d += MathHelper.cos(f1) * f5; + d1 += f6; + d2 += MathHelper.sin(f1) * f5; + if(flag1) + { + f2 *= 0.92F; + } else + { + f2 *= 0.7F; + } + f2 += f4 * 0.1F; + f1 += f3 * 0.1F; + f4 *= 0.9F; + f3 *= 0.75F; + f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F; + f3 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4F; + if(!flag && k == j1 && f > 1.0F) + { + releaseEntitySkin(i, j, abyte0, d, d1, d2, random.nextFloat() * 0.5F + 0.5F, f1 - 1.570796F, f2 / 3F, k, l, 1.0D); + releaseEntitySkin(i, j, abyte0, d, d1, d2, random.nextFloat() * 0.5F + 0.5F, f1 + 1.570796F, f2 / 3F, k, l, 1.0D); + return; + } + if(!flag && random.nextInt(4) == 0) + { + continue; + } + double d8 = d - d4; + double d9 = d2 - d5; + double d10 = l - k; + double d11 = f + 2.0F + 16F; + if((d8 * d8 + d9 * d9) - d10 * d10 > d11 * d11) + { + return; + } + if(d < d4 - 16D - d6 * 2D || d2 < d5 - 16D - d6 * 2D || d > d4 + 16D + d6 * 2D || d2 > d5 + 16D + d6 * 2D) + { + continue; + } + d8 = MathHelper.floor_double(d - d6) - i * 16 - 1; + int k1 = (MathHelper.floor_double(d + d6) - i * 16) + 1; + d9 = MathHelper.floor_double(d1 - d7) - 1; + int l1 = MathHelper.floor_double(d1 + d7) + 1; + d10 = MathHelper.floor_double(d2 - d6) - j * 16 - 1; + int i2 = (MathHelper.floor_double(d2 + d6) - j * 16) + 1; + if(d8 < 0) + { + d8 = 0; + } + if(k1 > 16) + { + k1 = 16; + } + if(d9 < 1) + { + d9 = 1; + } + if(l1 > 120) + { + l1 = 120; + } + if(d10 < 0) + { + d10 = 0; + } + if(i2 > 16) + { + i2 = 16; + } + boolean flag2 = false; + for(int j2 = (int)d8; !flag2 && j2 < k1; j2++) + { + for(int l2 = (int)d10; !flag2 && l2 < i2; l2++) + { + for(int i3 = l1 + 1; !flag2 && i3 >= d9 - 1; i3--) + { + int j3 = (j2 * 16 + l2) * 128 + i3; + if(i3 < 0 || i3 >= 128) + { + continue; + } + if(abyte0[j3] == Block.waterStill.blockID || abyte0[j3] == Block.waterMoving.blockID) + { + flag2 = true; + } + if(i3 != d9 - 1 && j2 != d8 && j2 != k1 - 1 && l2 != d10 && l2 != i2 - 1) + { + i3 = (int)d9; + } + } + + } + + } + + if(flag2) + { + continue; + } + for(int k2 = (int)d8; k2 < k1; k2++) + { + double d12 = (((double)(k2 + i * 16) + 0.5D) - d) / d6; +label0: + for(int k3 = (int)d10; k3 < i2; k3++) + { + double d13 = (((double)(k3 + j * 16) + 0.5D) - d2) / d6; + int l3 = (k2 * 16 + k3) * 128 + l1; + boolean flag3 = false; + if(d12 * d12 + d13 * d13 >= 1.0D) + { + continue; + } + int i4 = l1 - 1; + do + { + if(i4 < d9) + { + continue label0; + } + double d14 = (((double)i4 + 0.5D) - d1) / d7; + if(d14 > -0.69999999999999996D && d12 * d12 + d14 * d14 + d13 * d13 < 1.0D) + { + byte byte0 = abyte0[l3]; + if(byte0 == Block.grass.blockID) + { + flag3 = true; + } + if(byte0 == Block.stone.blockID || byte0 == Block.dirt.blockID || byte0 == Block.grass.blockID) + { + if(i4 < 10) + { + abyte0[l3] = (byte)Block.lavaStill.blockID; + } else + { + abyte0[l3] = 0; + if(flag3 && abyte0[l3 - 1] == Block.dirt.blockID) + { + abyte0[l3 - 1] = (byte)Block.grass.blockID; + } + } + } + } + l3--; + i4--; + } while(true); + } + + } + + if(flag) + { + break; + } + } + + } + + protected void func_868_a(World world, int i, int j, int k, int l, byte abyte0[]) + { + int i1 = rand.nextInt(rand.nextInt(rand.nextInt(40) + 1) + 1); + if(rand.nextInt(15) != 0) + { + i1 = 0; + } + for(int j1 = 0; j1 < i1; j1++) + { + double d = i * 16 + rand.nextInt(16); + double d1 = rand.nextInt(rand.nextInt(120) + 8); + double d2 = j * 16 + rand.nextInt(16); + int k1 = 1; + if(rand.nextInt(4) == 0) + { + func_870_a(k, l, abyte0, d, d1, d2); + k1 += rand.nextInt(4); + } + for(int l1 = 0; l1 < k1; l1++) + { + float f = rand.nextFloat() * 3.141593F * 2.0F; + float f1 = ((rand.nextFloat() - 0.5F) * 2.0F) / 8F; + float f2 = rand.nextFloat() * 2.0F + rand.nextFloat(); + releaseEntitySkin(k, l, abyte0, d, d1, d2, f2, f, f1, 0, 0, 1.0D); + } + + } + + } +} diff --git a/src/main/java/net/minecraft/src/MapGenCavesHell.java b/src/main/java/net/minecraft/src/MapGenCavesHell.java new file mode 100644 index 0000000..1c8d1cc --- /dev/null +++ b/src/main/java/net/minecraft/src/MapGenCavesHell.java @@ -0,0 +1,209 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class MapGenCavesHell extends MapGenBase +{ + + public MapGenCavesHell() + { + } + + protected void func_4129_a(int i, int j, byte abyte0[], double d, double d1, + double d2) + { + func_4128_a(i, j, abyte0, d, d1, d2, 1.0F + rand.nextFloat() * 6F, 0.0F, 0.0F, -1, -1, 0.5D); + } + + protected void func_4128_a(int i, int j, byte abyte0[], double d, double d1, + double d2, float f, float f1, float f2, int k, int l, + double d3) + { + double d4 = i * 16 + 8; + double d5 = j * 16 + 8; + float f3 = 0.0F; + float f4 = 0.0F; + Random random = new Random(rand.nextLong()); + if(l <= 0) + { + int i1 = field_1306_a * 16 - 16; + l = i1 - random.nextInt(i1 / 4); + } + boolean flag = false; + if(k == -1) + { + k = l / 2; + flag = true; + } + int j1 = random.nextInt(l / 2) + l / 4; + boolean flag1 = random.nextInt(6) == 0; + for(; k < l; k++) + { + double d6 = 1.5D + (double)(MathHelper.sin(((float)k * 3.141593F) / (float)l) * f * 1.0F); + double d7 = d6 * d3; + float f5 = MathHelper.cos(f2); + float f6 = MathHelper.sin(f2); + d += MathHelper.cos(f1) * f5; + d1 += f6; + d2 += MathHelper.sin(f1) * f5; + if(flag1) + { + f2 *= 0.92F; + } else + { + f2 *= 0.7F; + } + f2 += f4 * 0.1F; + f1 += f3 * 0.1F; + f4 *= 0.9F; + f3 *= 0.75F; + f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F; + f3 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4F; + if(!flag && k == j1 && f > 1.0F) + { + func_4128_a(i, j, abyte0, d, d1, d2, random.nextFloat() * 0.5F + 0.5F, f1 - 1.570796F, f2 / 3F, k, l, 1.0D); + func_4128_a(i, j, abyte0, d, d1, d2, random.nextFloat() * 0.5F + 0.5F, f1 + 1.570796F, f2 / 3F, k, l, 1.0D); + return; + } + if(!flag && random.nextInt(4) == 0) + { + continue; + } + double d8 = d - d4; + double d9 = d2 - d5; + double d10 = l - k; + double d11 = f + 2.0F + 16F; + if((d8 * d8 + d9 * d9) - d10 * d10 > d11 * d11) + { + return; + } + if(d < d4 - 16D - d6 * 2D || d2 < d5 - 16D - d6 * 2D || d > d4 + 16D + d6 * 2D || d2 > d5 + 16D + d6 * 2D) + { + continue; + } + d8 = MathHelper.floor_double(d - d6) - i * 16 - 1; + int k1 = (MathHelper.floor_double(d + d6) - i * 16) + 1; + d9 = MathHelper.floor_double(d1 - d7) - 1; + int l1 = MathHelper.floor_double(d1 + d7) + 1; + d10 = MathHelper.floor_double(d2 - d6) - j * 16 - 1; + int i2 = (MathHelper.floor_double(d2 + d6) - j * 16) + 1; + if(d8 < 0) + { + d8 = 0; + } + if(k1 > 16) + { + k1 = 16; + } + if(d9 < 1) + { + d9 = 1; + } + if(l1 > 120) + { + l1 = 120; + } + if(d10 < 0) + { + d10 = 0; + } + if(i2 > 16) + { + i2 = 16; + } + boolean flag2 = false; + for(int j2 = (int)d8; !flag2 && j2 < k1; j2++) + { + for(int l2 = (int)d10; !flag2 && l2 < i2; l2++) + { + for(int i3 = l1 + 1; !flag2 && i3 >= d9 - 1; i3--) + { + int j3 = (j2 * 16 + l2) * 128 + i3; + if(i3 < 0 || i3 >= 128) + { + continue; + } + if(abyte0[j3] == Block.lavaStill.blockID || abyte0[j3] == Block.lavaMoving.blockID) + { + flag2 = true; + } + if(i3 != d9 - 1 && j2 != d8 && j2 != k1 - 1 && l2 != d10 && l2 != i2 - 1) + { + i3 = (int)d9; + } + } + + } + + } + + if(flag2) + { + continue; + } + for(int k2 = (int)d8; k2 < k1; k2++) + { + double d12 = (((double)(k2 + i * 16) + 0.5D) - d) / d6; + for(int k3 = (int)d10; k3 < i2; k3++) + { + double d13 = (((double)(k3 + j * 16) + 0.5D) - d2) / d6; + int l3 = (k2 * 16 + k3) * 128 + l1; + for(int i4 = l1 - 1; i4 >= d9; i4--) + { + double d14 = (((double)i4 + 0.5D) - d1) / d7; + if(d14 > -0.69999999999999996D && d12 * d12 + d14 * d14 + d13 * d13 < 1.0D) + { + byte byte0 = abyte0[l3]; + if(byte0 == Block.bloodStone.blockID || byte0 == Block.dirt.blockID || byte0 == Block.grass.blockID) + { + abyte0[l3] = 0; + } + } + l3--; + } + + } + + } + + if(flag) + { + break; + } + } + + } + + protected void func_868_a(World world, int i, int j, int k, int l, byte abyte0[]) + { + int i1 = rand.nextInt(rand.nextInt(rand.nextInt(10) + 1) + 1); + if(rand.nextInt(5) != 0) + { + i1 = 0; + } + for(int j1 = 0; j1 < i1; j1++) + { + double d = i * 16 + rand.nextInt(16); + double d1 = rand.nextInt(128); + double d2 = j * 16 + rand.nextInt(16); + int k1 = 1; + if(rand.nextInt(4) == 0) + { + func_4129_a(k, l, abyte0, d, d1, d2); + k1 += rand.nextInt(4); + } + for(int l1 = 0; l1 < k1; l1++) + { + float f = rand.nextFloat() * 3.141593F * 2.0F; + float f1 = ((rand.nextFloat() - 0.5F) * 2.0F) / 8F; + float f2 = rand.nextFloat() * 2.0F + rand.nextFloat(); + func_4128_a(k, l, abyte0, d, d1, d2, f2 * 2.0F, f, f1, 0, 0, 0.5D); + } + + } + + } +} diff --git a/src/main/java/net/minecraft/src/Material.java b/src/main/java/net/minecraft/src/Material.java new file mode 100644 index 0000000..48e99a5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Material.java @@ -0,0 +1,72 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class Material +{ + + public Material() + { + } + + public boolean getIsLiquid() + { + return false; + } + + public boolean isSolid() + { + return true; + } + + public boolean getCanBlockGrass() + { + return true; + } + + public boolean getIsSolid() + { + return true; + } + + private Material setBurning() + { + canBurn = true; + return this; + } + + public boolean getBurning() + { + return canBurn; + } + + public static final Material air = new MaterialTransparent(); + public static final Material ground = new Material(); + public static final Material wood = (new Material()).setBurning(); + public static final Material rock = new Material(); + public static final Material iron = new Material(); + public static final Material water = new MaterialLiquid(); + public static final Material lava = new MaterialLiquid(); + public static final Material leaves = (new Material()).setBurning(); + public static final Material plants = new MaterialLogic(); + public static final Material sponge = new Material(); + public static final Material cloth = (new Material()).setBurning(); + public static final Material fire = new MaterialTransparent(); + public static final Material sand = new Material(); + public static final Material circuits = new MaterialLogic(); + public static final Material glass = new Material(); + public static final Material tnt = (new Material()).setBurning(); + public static final Material field_4262_q = new Material(); + public static final Material ice = new Material(); + public static final Material snow = new MaterialLogic(); + public static final Material builtSnow = new Material(); + public static final Material cactus = new Material(); + public static final Material clay = new Material(); + public static final Material pumpkin = new Material(); + public static final Material portal = new Material(); + public static final Material field_21150_y = new Material(); + private boolean canBurn; + +} diff --git a/src/main/java/net/minecraft/src/MaterialLiquid.java b/src/main/java/net/minecraft/src/MaterialLiquid.java new file mode 100644 index 0000000..4ebc977 --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialLiquid.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MaterialLiquid extends Material +{ + + public MaterialLiquid() + { + } + + public boolean getIsLiquid() + { + return true; + } + + public boolean getIsSolid() + { + return false; + } + + public boolean isSolid() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialLogic.java b/src/main/java/net/minecraft/src/MaterialLogic.java new file mode 100644 index 0000000..a9ef78c --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialLogic.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MaterialLogic extends Material +{ + + public MaterialLogic() + { + } + + public boolean isSolid() + { + return false; + } + + public boolean getCanBlockGrass() + { + return false; + } + + public boolean getIsSolid() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MaterialTransparent.java b/src/main/java/net/minecraft/src/MaterialTransparent.java new file mode 100644 index 0000000..14ddc7a --- /dev/null +++ b/src/main/java/net/minecraft/src/MaterialTransparent.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MaterialTransparent extends Material +{ + + public MaterialTransparent() + { + } + + public boolean isSolid() + { + return false; + } + + public boolean getCanBlockGrass() + { + return false; + } + + public boolean getIsSolid() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/MathHelper.java b/src/main/java/net/minecraft/src/MathHelper.java new file mode 100644 index 0000000..c885435 --- /dev/null +++ b/src/main/java/net/minecraft/src/MathHelper.java @@ -0,0 +1,91 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MathHelper +{ + + public MathHelper() + { + } + + public static final float sin(float f) + { + return SIN_TABLE[(int)(f * 10430.38F) & 0xffff]; + } + + public static final float cos(float f) + { + return SIN_TABLE[(int)(f * 10430.38F + 16384F) & 0xffff]; + } + + public static final float sqrt_float(float f) + { + return (float)Math.sqrt(f); + } + + public static final float sqrt_double(double d) + { + return (float)Math.sqrt(d); + } + + public static int floor_float(float f) + { + int i = (int)f; + return f >= (float)i ? i : i - 1; + } + + public static int floor_double(double d) + { + int i = (int)d; + return d >= (double)i ? i : i - 1; + } + + public static float abs(float f) + { + return f < 0.0F ? -f : f; + } + + public static double abs_max(double d, double d1) + { + if(d < 0.0D) + { + d = -d; + } + if(d1 < 0.0D) + { + d1 = -d1; + } + return d <= d1 ? d1 : d; + } + + public static int bucketInt(int i, int j) + { + if(i < 0) + { + return -((-i - 1) / j) - 1; + } else + { + return i / j; + } + } + + public static boolean func_22282_a(String s) + { + return s == null || s.length() == 0; + } + + private static float SIN_TABLE[]; + + static + { + SIN_TABLE = new float[0x10000]; + for(int i = 0; i < 0x10000; i++) + { + SIN_TABLE[i] = (float)Math.sin(((double)i * 3.1415926535897931D * 2D) / 65536D); + } + + } +} diff --git a/src/main/java/net/minecraft/src/McRegionChunkLoader.java b/src/main/java/net/minecraft/src/McRegionChunkLoader.java new file mode 100644 index 0000000..4d26ee6 --- /dev/null +++ b/src/main/java/net/minecraft/src/McRegionChunkLoader.java @@ -0,0 +1,88 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class McRegionChunkLoader + implements IChunkLoader +{ + + public McRegionChunkLoader(File file) + { + field_22184_a = file; + } + + public Chunk loadChunk(World world, int i, int j) + { + java.io.DataInputStream datainputstream = RegionFileCache.func_22194_c(field_22184_a, i, j); + NBTTagCompound nbttagcompound; + if(datainputstream != null) + { + try { + nbttagcompound = CompressedStreamTools.func_1141_a(datainputstream); + }catch(IOException e) { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is corrupt:").append(e.toString()).toString()); + return null; + } + } else + { + return null; + } + if(!nbttagcompound.hasKey("Level")) + { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is missing level data, skipping").toString()); + return null; + } + if(!nbttagcompound.getCompoundTag("Level").hasKey("Blocks")) + { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is missing block data, skipping").toString()); + return null; + } + Chunk chunk = ChunkLoader.loadChunkIntoWorldFromCompound(world, nbttagcompound.getCompoundTag("Level")); + if(!chunk.isAtLocation(i, j)) + { + System.out.println((new StringBuilder()).append("Chunk file at ").append(i).append(",").append(j).append(" is in the wrong location; relocating. (Expected ").append(i).append(", ").append(j).append(", got ").append(chunk.xPosition).append(", ").append(chunk.zPosition).append(")").toString()); + nbttagcompound.setInteger("xPos", i); + nbttagcompound.setInteger("zPos", j); + chunk = ChunkLoader.loadChunkIntoWorldFromCompound(world, nbttagcompound.getCompoundTag("Level")); + } + return chunk; + } + + public void saveChunk(World world, Chunk chunk) + { + world.checkSessionLock(); + try + { + DataOutputStream dataoutputstream = RegionFileCache.func_22190_d(field_22184_a, chunk.xPosition, chunk.zPosition); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound.setTag("Level", nbttagcompound1); + ChunkLoader.storeChunkInCompound(chunk, world, nbttagcompound1); + CompressedStreamTools.func_1139_a(nbttagcompound, dataoutputstream); + dataoutputstream.close(); + WorldInfo worldinfo = world.func_22144_v(); + worldinfo.func_22297_b(worldinfo.func_22306_g() + (long)RegionFileCache.func_22191_b(field_22184_a, chunk.xPosition, chunk.zPosition)); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + public void saveExtraChunkData(World world, Chunk chunk) + { + } + + public void func_814_a() + { + } + + public void saveExtraData() + { + } + + private final File field_22184_a; +} diff --git a/src/main/java/net/minecraft/src/MetadataChunkBlock.java b/src/main/java/net/minecraft/src/MetadataChunkBlock.java new file mode 100644 index 0000000..611a230 --- /dev/null +++ b/src/main/java/net/minecraft/src/MetadataChunkBlock.java @@ -0,0 +1,233 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; + +public class MetadataChunkBlock +{ + + public MetadataChunkBlock(EnumSkyBlock enumskyblock, int i, int j, int k, int l, int i1, int j1) + { + field_1299_a = enumskyblock; + field_1298_b = i; + field_1304_c = j; + field_1303_d = k; + field_1302_e = l; + field_1301_f = i1; + field_1300_g = j1; + } + + public void func_4127_a(World world) + { + int i = (field_1302_e - field_1298_b) + 1; + int j = (field_1301_f - field_1304_c) + 1; + int k = (field_1300_g - field_1303_d) + 1; + int l = i * j * k; + if(l > 32768) + { + System.out.println("Light too large, skipping!"); + return; + } + int i1 = 0; + int j1 = 0; + boolean flag = false; + boolean flag1 = false; + for(int k1 = field_1298_b; k1 <= field_1302_e; k1++) + { + for(int l1 = field_1303_d; l1 <= field_1300_g; l1++) + { + int i2 = k1 >> 4; + int j2 = l1 >> 4; + boolean flag2 = false; + if(flag && i2 == i1 && j2 == j1) + { + flag2 = flag1; + } else + { + flag2 = world.doChunksNearChunkExist(k1, 0, l1, 1); + if(flag2) + { + Chunk chunk = world.getChunkFromChunkCoords(k1 >> 4, l1 >> 4); + if(chunk.func_21167_h()) + { + flag2 = false; + } + } + flag1 = flag2; + i1 = i2; + j1 = j2; + } + if(!flag2) + { + continue; + } + if(field_1304_c < 0) + { + field_1304_c = 0; + } + if(field_1301_f >= 128) + { + field_1301_f = 127; + } + for(int k2 = field_1304_c; k2 <= field_1301_f; k2++) + { + int l2 = world.getSavedLightValue(field_1299_a, k1, k2, l1); + int i3 = 0; + int j3 = world.getBlockId(k1, k2, l1); + int k3 = Block.lightOpacity[j3]; + if(k3 == 0) + { + k3 = 1; + } + int l3 = 0; + if(field_1299_a == EnumSkyBlock.Sky) + { + if(world.canExistingBlockSeeTheSky(k1, k2, l1)) + { + l3 = 15; + } + } else + if(field_1299_a == EnumSkyBlock.Block) + { + l3 = Block.lightValue[j3]; + } + if(k3 >= 15 && l3 == 0) + { + i3 = 0; + } else + { + int i4 = world.getSavedLightValue(field_1299_a, k1 - 1, k2, l1); + int k4 = world.getSavedLightValue(field_1299_a, k1 + 1, k2, l1); + int l4 = world.getSavedLightValue(field_1299_a, k1, k2 - 1, l1); + int i5 = world.getSavedLightValue(field_1299_a, k1, k2 + 1, l1); + int j5 = world.getSavedLightValue(field_1299_a, k1, k2, l1 - 1); + int k5 = world.getSavedLightValue(field_1299_a, k1, k2, l1 + 1); + i3 = i4; + if(k4 > i3) + { + i3 = k4; + } + if(l4 > i3) + { + i3 = l4; + } + if(i5 > i3) + { + i3 = i5; + } + if(j5 > i3) + { + i3 = j5; + } + if(k5 > i3) + { + i3 = k5; + } + i3 -= k3; + if(i3 < 0) + { + i3 = 0; + } + if(l3 > i3) + { + i3 = l3; + } + } + if(l2 == i3) + { + continue; + } + world.setLightValue(field_1299_a, k1, k2, l1, i3); + int j4 = i3 - 1; + if(j4 < 0) + { + j4 = 0; + } + world.neighborLightPropagationChanged(field_1299_a, k1 - 1, k2, l1, j4); + world.neighborLightPropagationChanged(field_1299_a, k1, k2 - 1, l1, j4); + world.neighborLightPropagationChanged(field_1299_a, k1, k2, l1 - 1, j4); + if(k1 + 1 >= field_1302_e) + { + world.neighborLightPropagationChanged(field_1299_a, k1 + 1, k2, l1, j4); + } + if(k2 + 1 >= field_1301_f) + { + world.neighborLightPropagationChanged(field_1299_a, k1, k2 + 1, l1, j4); + } + if(l1 + 1 >= field_1300_g) + { + world.neighborLightPropagationChanged(field_1299_a, k1, k2, l1 + 1, j4); + } + } + + } + + } + + } + + public boolean func_866_a(int i, int j, int k, int l, int i1, int j1) + { + if(i >= field_1298_b && j >= field_1304_c && k >= field_1303_d && l <= field_1302_e && i1 <= field_1301_f && j1 <= field_1300_g) + { + return true; + } + int k1 = 1; + if(i >= field_1298_b - k1 && j >= field_1304_c - k1 && k >= field_1303_d - k1 && l <= field_1302_e + k1 && i1 <= field_1301_f + k1 && j1 <= field_1300_g + k1) + { + int l1 = field_1302_e - field_1298_b; + int i2 = field_1301_f - field_1304_c; + int j2 = field_1300_g - field_1303_d; + if(i > field_1298_b) + { + i = field_1298_b; + } + if(j > field_1304_c) + { + j = field_1304_c; + } + if(k > field_1303_d) + { + k = field_1303_d; + } + if(l < field_1302_e) + { + l = field_1302_e; + } + if(i1 < field_1301_f) + { + i1 = field_1301_f; + } + if(j1 < field_1300_g) + { + j1 = field_1300_g; + } + int k2 = l - i; + int l2 = i1 - j; + int i3 = j1 - k; + int j3 = l1 * i2 * j2; + int k3 = k2 * l2 * i3; + if(k3 - j3 <= 2) + { + field_1298_b = i; + field_1304_c = j; + field_1303_d = k; + field_1302_e = l; + field_1301_f = i1; + field_1300_g = j1; + return true; + } + } + return false; + } + + public final EnumSkyBlock field_1299_a; + public int field_1298_b; + public int field_1304_c; + public int field_1303_d; + public int field_1302_e; + public int field_1301_f; + public int field_1300_g; +} diff --git a/src/main/java/net/minecraft/src/MinecartTrackLogic.java b/src/main/java/net/minecraft/src/MinecartTrackLogic.java new file mode 100644 index 0000000..9bd8478 --- /dev/null +++ b/src/main/java/net/minecraft/src/MinecartTrackLogic.java @@ -0,0 +1,405 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.ArrayList; +import java.util.List; + +class MinecartTrackLogic +{ + + public MinecartTrackLogic(BlockMinecartTrack blockminecarttrack, World world, int i, int j, int k) + { + minecartTrack = blockminecarttrack; + connectedTracks = new ArrayList(); + worldObj = world; + trackX = i; + trackY = j; + trackZ = k; + trackMetadata = world.getBlockMetadata(i, j, k); + calculateConnectedTracks(); + } + + private void calculateConnectedTracks() + { + connectedTracks.clear(); + if(trackMetadata == 0) + { + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ - 1)); + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ + 1)); + } else + if(trackMetadata == 1) + { + connectedTracks.add(new ChunkPosition(trackX - 1, trackY, trackZ)); + connectedTracks.add(new ChunkPosition(trackX + 1, trackY, trackZ)); + } else + if(trackMetadata == 2) + { + connectedTracks.add(new ChunkPosition(trackX - 1, trackY, trackZ)); + connectedTracks.add(new ChunkPosition(trackX + 1, trackY + 1, trackZ)); + } else + if(trackMetadata == 3) + { + connectedTracks.add(new ChunkPosition(trackX - 1, trackY + 1, trackZ)); + connectedTracks.add(new ChunkPosition(trackX + 1, trackY, trackZ)); + } else + if(trackMetadata == 4) + { + connectedTracks.add(new ChunkPosition(trackX, trackY + 1, trackZ - 1)); + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ + 1)); + } else + if(trackMetadata == 5) + { + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ - 1)); + connectedTracks.add(new ChunkPosition(trackX, trackY + 1, trackZ + 1)); + } else + if(trackMetadata == 6) + { + connectedTracks.add(new ChunkPosition(trackX + 1, trackY, trackZ)); + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ + 1)); + } else + if(trackMetadata == 7) + { + connectedTracks.add(new ChunkPosition(trackX - 1, trackY, trackZ)); + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ + 1)); + } else + if(trackMetadata == 8) + { + connectedTracks.add(new ChunkPosition(trackX - 1, trackY, trackZ)); + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ - 1)); + } else + if(trackMetadata == 9) + { + connectedTracks.add(new ChunkPosition(trackX + 1, trackY, trackZ)); + connectedTracks.add(new ChunkPosition(trackX, trackY, trackZ - 1)); + } + } + + private void func_785_b() + { + for(int i = 0; i < connectedTracks.size(); i++) + { + MinecartTrackLogic minecarttracklogic = getMinecartTrackLogic((ChunkPosition)connectedTracks.get(i)); + if(minecarttracklogic == null || !minecarttracklogic.isConnectedTo(this)) + { + connectedTracks.remove(i--); + } else + { + connectedTracks.set(i, new ChunkPosition(minecarttracklogic.trackX, minecarttracklogic.trackY, minecarttracklogic.trackZ)); + } + } + + } + + private boolean isMinecartTrack(int i, int j, int k) + { + if(worldObj.getBlockId(i, j, k) == minecartTrack.blockID) + { + return true; + } + if(worldObj.getBlockId(i, j + 1, k) == minecartTrack.blockID) + { + return true; + } + return worldObj.getBlockId(i, j - 1, k) == minecartTrack.blockID; + } + + private MinecartTrackLogic getMinecartTrackLogic(ChunkPosition chunkposition) + { + if(worldObj.getBlockId(chunkposition.x, chunkposition.y, chunkposition.z) == minecartTrack.blockID) + { + return new MinecartTrackLogic(minecartTrack, worldObj, chunkposition.x, chunkposition.y, chunkposition.z); + } + if(worldObj.getBlockId(chunkposition.x, chunkposition.y + 1, chunkposition.z) == minecartTrack.blockID) + { + return new MinecartTrackLogic(minecartTrack, worldObj, chunkposition.x, chunkposition.y + 1, chunkposition.z); + } + if(worldObj.getBlockId(chunkposition.x, chunkposition.y - 1, chunkposition.z) == minecartTrack.blockID) + { + return new MinecartTrackLogic(minecartTrack, worldObj, chunkposition.x, chunkposition.y - 1, chunkposition.z); + } else + { + return null; + } + } + + private boolean isConnectedTo(MinecartTrackLogic minecarttracklogic) + { + for(int i = 0; i < connectedTracks.size(); i++) + { + ChunkPosition chunkposition = (ChunkPosition)connectedTracks.get(i); + if(chunkposition.x == minecarttracklogic.trackX && chunkposition.z == minecarttracklogic.trackZ) + { + return true; + } + } + + return false; + } + + private boolean func_794_b(int i, int j, int k) + { + for(int l = 0; l < connectedTracks.size(); l++) + { + ChunkPosition chunkposition = (ChunkPosition)connectedTracks.get(l); + if(chunkposition.x == i && chunkposition.z == k) + { + return true; + } + } + + return false; + } + + private int getAdjacentTracks() + { + int i = 0; + if(isMinecartTrack(trackX, trackY, trackZ - 1)) + { + i++; + } + if(isMinecartTrack(trackX, trackY, trackZ + 1)) + { + i++; + } + if(isMinecartTrack(trackX - 1, trackY, trackZ)) + { + i++; + } + if(isMinecartTrack(trackX + 1, trackY, trackZ)) + { + i++; + } + return i; + } + + private boolean handleKeyPress(MinecartTrackLogic minecarttracklogic) + { + if(isConnectedTo(minecarttracklogic)) + { + return true; + } + if(connectedTracks.size() == 2) + { + return false; + } + if(connectedTracks.size() == 0) + { + return true; + } + ChunkPosition chunkposition = (ChunkPosition)connectedTracks.get(0); + return minecarttracklogic.trackY != trackY || chunkposition.y != trackY ? true : true; + } + + private void func_788_d(MinecartTrackLogic minecarttracklogic) + { + connectedTracks.add(new ChunkPosition(minecarttracklogic.trackX, minecarttracklogic.trackY, minecarttracklogic.trackZ)); + boolean flag = func_794_b(trackX, trackY, trackZ - 1); + boolean flag1 = func_794_b(trackX, trackY, trackZ + 1); + boolean flag2 = func_794_b(trackX - 1, trackY, trackZ); + boolean flag3 = func_794_b(trackX + 1, trackY, trackZ); + byte byte0 = -1; + if(flag || flag1) + { + byte0 = 0; + } + if(flag2 || flag3) + { + byte0 = 1; + } + if(flag1 && flag3 && !flag && !flag2) + { + byte0 = 6; + } + if(flag1 && flag2 && !flag && !flag3) + { + byte0 = 7; + } + if(flag && flag2 && !flag1 && !flag3) + { + byte0 = 8; + } + if(flag && flag3 && !flag1 && !flag2) + { + byte0 = 9; + } + if(byte0 == 0) + { + if(worldObj.getBlockId(trackX, trackY + 1, trackZ - 1) == minecartTrack.blockID) + { + byte0 = 4; + } + if(worldObj.getBlockId(trackX, trackY + 1, trackZ + 1) == minecartTrack.blockID) + { + byte0 = 5; + } + } + if(byte0 == 1) + { + if(worldObj.getBlockId(trackX + 1, trackY + 1, trackZ) == minecartTrack.blockID) + { + byte0 = 2; + } + if(worldObj.getBlockId(trackX - 1, trackY + 1, trackZ) == minecartTrack.blockID) + { + byte0 = 3; + } + } + if(byte0 < 0) + { + byte0 = 0; + } + worldObj.setBlockMetadataWithNotify(trackX, trackY, trackZ, byte0); + } + + private boolean func_786_c(int i, int j, int k) + { + MinecartTrackLogic minecarttracklogic = getMinecartTrackLogic(new ChunkPosition(i, j, k)); + if(minecarttracklogic == null) + { + return false; + } else + { + minecarttracklogic.func_785_b(); + return minecarttracklogic.handleKeyPress(this); + } + } + + public void func_792_a(boolean flag) + { + boolean flag1 = func_786_c(trackX, trackY, trackZ - 1); + boolean flag2 = func_786_c(trackX, trackY, trackZ + 1); + boolean flag3 = func_786_c(trackX - 1, trackY, trackZ); + boolean flag4 = func_786_c(trackX + 1, trackY, trackZ); + int i = -1; + if((flag1 || flag2) && !flag3 && !flag4) + { + i = 0; + } + if((flag3 || flag4) && !flag1 && !flag2) + { + i = 1; + } + if(flag2 && flag4 && !flag1 && !flag3) + { + i = 6; + } + if(flag2 && flag3 && !flag1 && !flag4) + { + i = 7; + } + if(flag1 && flag3 && !flag2 && !flag4) + { + i = 8; + } + if(flag1 && flag4 && !flag2 && !flag3) + { + i = 9; + } + if(i == -1) + { + if(flag1 || flag2) + { + i = 0; + } + if(flag3 || flag4) + { + i = 1; + } + if(flag) + { + if(flag2 && flag4) + { + i = 6; + } + if(flag3 && flag2) + { + i = 7; + } + if(flag4 && flag1) + { + i = 9; + } + if(flag1 && flag3) + { + i = 8; + } + } else + { + if(flag1 && flag3) + { + i = 8; + } + if(flag4 && flag1) + { + i = 9; + } + if(flag3 && flag2) + { + i = 7; + } + if(flag2 && flag4) + { + i = 6; + } + } + } + if(i == 0) + { + if(worldObj.getBlockId(trackX, trackY + 1, trackZ - 1) == minecartTrack.blockID) + { + i = 4; + } + if(worldObj.getBlockId(trackX, trackY + 1, trackZ + 1) == minecartTrack.blockID) + { + i = 5; + } + } + if(i == 1) + { + if(worldObj.getBlockId(trackX + 1, trackY + 1, trackZ) == minecartTrack.blockID) + { + i = 2; + } + if(worldObj.getBlockId(trackX - 1, trackY + 1, trackZ) == minecartTrack.blockID) + { + i = 3; + } + } + if(i < 0) + { + i = 0; + } + trackMetadata = i; + calculateConnectedTracks(); + worldObj.setBlockMetadataWithNotify(trackX, trackY, trackZ, i); + for(int j = 0; j < connectedTracks.size(); j++) + { + MinecartTrackLogic minecarttracklogic = getMinecartTrackLogic((ChunkPosition)connectedTracks.get(j)); + if(minecarttracklogic == null) + { + continue; + } + minecarttracklogic.func_785_b(); + if(minecarttracklogic.handleKeyPress(this)) + { + minecarttracklogic.func_788_d(this); + } + } + + } + + static int getNAdjacentTracks(MinecartTrackLogic minecarttracklogic) + { + return minecarttracklogic.getAdjacentTracks(); + } + + private World worldObj; + private int trackX; + private int trackY; + private int trackZ; + private int trackMetadata; + private List connectedTracks; + final BlockMinecartTrack minecartTrack; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/MinecraftError.java b/src/main/java/net/minecraft/src/MinecraftError.java new file mode 100644 index 0000000..6974ef5 --- /dev/null +++ b/src/main/java/net/minecraft/src/MinecraftError.java @@ -0,0 +1,13 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MinecraftError extends Error +{ + + public MinecraftError() + { + } +} diff --git a/src/main/java/net/minecraft/src/MinecraftException.java b/src/main/java/net/minecraft/src/MinecraftException.java new file mode 100644 index 0000000..57f3591 --- /dev/null +++ b/src/main/java/net/minecraft/src/MinecraftException.java @@ -0,0 +1,14 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MinecraftException extends RuntimeException +{ + + public MinecraftException(String s) + { + super(s); + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerBase.java b/src/main/java/net/minecraft/src/MobSpawnerBase.java new file mode 100644 index 0000000..86b4f2f --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerBase.java @@ -0,0 +1,195 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.Color; +import java.util.Random; + +public class MobSpawnerBase +{ + + public MobSpawnerBase() + { + topBlock = (byte)Block.grass.blockID; + fillerBlock = (byte)Block.dirt.blockID; + field_6502_q = 0x4ee031; + biomeMonsters = (new Class[] { + EntitySpider.class, EntityZombie.class, EntitySkeleton.class, EntityCreeper.class, EntitySlime.class + }); + biomeCreatures = (new Class[] { + EntitySheep.class, EntityPig.class, EntityChicken.class, EntityCow.class + }); + biomeWaterCreatures = (new Class[] { + EntitySquid.class + }); + } + + public static void generateBiomeLookup() + { + for(int i = 0; i < 64; i++) + { + for(int j = 0; j < 64; j++) + { + biomeLookupTable[i + j * 64] = getBiome((float)i / 63F, (float)j / 63F); + } + + } + + desert.topBlock = desert.fillerBlock = (byte)Block.sand.blockID; + iceDesert.topBlock = iceDesert.fillerBlock = (byte)Block.sand.blockID; + } + + public WorldGenerator getRandomWorldGenForTrees(Random random) + { + if(random.nextInt(10) == 0) + { + return new WorldGenBigTree(); + } else + { + return new WorldGenTrees(); + } + } + + protected MobSpawnerBase doesNothingForMobSpawnerBase() + { + return this; + } + + protected MobSpawnerBase setBiomeName(String s) + { + biomeName = s; + return this; + } + + protected MobSpawnerBase func_4124_a(int i) + { + field_6502_q = i; + return this; + } + + protected MobSpawnerBase setColor(int i) + { + color = i; + return this; + } + + public static MobSpawnerBase getBiomeFromLookup(double d, double d1) + { + int i = (int)(d * 63D); + int j = (int)(d1 * 63D); + return biomeLookupTable[i + j * 64]; + } + + public static MobSpawnerBase getBiome(float f, float f1) + { + f1 *= f; + if(f < 0.1F) + { + return tundra; + } + if(f1 < 0.2F) + { + if(f < 0.5F) + { + return tundra; + } + if(f < 0.95F) + { + return savanna; + } else + { + return desert; + } + } + if(f1 > 0.5F && f < 0.7F) + { + return swampland; + } + if(f < 0.5F) + { + return taiga; + } + if(f < 0.97F) + { + if(f1 < 0.35F) + { + return shrubland; + } else + { + return forest; + } + } + if(f1 < 0.45F) + { + return plains; + } + if(f1 < 0.9F) + { + return seasonalForest; + } else + { + return rainforest; + } + } + + public int getSkyColorByTemp(float f) + { + f /= 3F; + if(f < -1F) + { + f = -1F; + } + if(f > 1.0F) + { + f = 1.0F; + } + return Color.getHSBColor(0.6222222F - f * 0.05F, 0.5F + f * 0.1F, 1.0F).getRGB(); + } + + public Class[] getEntitiesForType(EnumCreatureType enumcreaturetype) + { + if(enumcreaturetype == EnumCreatureType.monster) + { + return biomeMonsters; + } + if(enumcreaturetype == EnumCreatureType.creature) + { + return biomeCreatures; + } + if(enumcreaturetype == EnumCreatureType.waterCreature) + { + return biomeWaterCreatures; + } else + { + return null; + } + } + + public static final MobSpawnerBase rainforest = (new MobSpawnerRainforest()).setColor(0x8fa36).setBiomeName("Rainforest").func_4124_a(0x1ff458); + public static final MobSpawnerBase swampland = (new MobSpawnerSwamp()).setColor(0x7f9b2).setBiomeName("Swampland").func_4124_a(0x8baf48); + public static final MobSpawnerBase seasonalForest = (new MobSpawnerBase()).setColor(0x9be023).setBiomeName("Seasonal Forest"); + public static final MobSpawnerBase forest = (new MobSpawnerForest()).setColor(0x56621).setBiomeName("Forest").func_4124_a(0x4eba31); + public static final MobSpawnerBase savanna = (new MobSpawnerDesert()).setColor(0xd9e023).setBiomeName("Savanna"); + public static final MobSpawnerBase shrubland = (new MobSpawnerBase()).setColor(0xa1ad20).setBiomeName("Shrubland"); + public static final MobSpawnerBase taiga = (new MobSpawnerTaiga()).setColor(0x2eb153).setBiomeName("Taiga").doesNothingForMobSpawnerBase().func_4124_a(0x7bb731); + public static final MobSpawnerBase desert = (new MobSpawnerDesert()).setColor(0xfa9418).setBiomeName("Desert"); + public static final MobSpawnerBase plains = (new MobSpawnerDesert()).setColor(0xffd910).setBiomeName("Plains"); + public static final MobSpawnerBase iceDesert = (new MobSpawnerDesert()).setColor(0xffed93).setBiomeName("Ice Desert").doesNothingForMobSpawnerBase().func_4124_a(0xc4d339); + public static final MobSpawnerBase tundra = (new MobSpawnerBase()).setColor(0x57ebf9).setBiomeName("Tundra").doesNothingForMobSpawnerBase().func_4124_a(0xc4d339); + public static final MobSpawnerBase hell = (new MobSpawnerHell()).setColor(0xff0000).setBiomeName("Hell"); + public String biomeName; + public int color; + public byte topBlock; + public byte fillerBlock; + public int field_6502_q; + protected Class biomeMonsters[]; + protected Class biomeCreatures[]; + protected Class biomeWaterCreatures[]; + private static MobSpawnerBase biomeLookupTable[] = new MobSpawnerBase[4096]; + + static + { + generateBiomeLookup(); + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerDesert.java b/src/main/java/net/minecraft/src/MobSpawnerDesert.java new file mode 100644 index 0000000..e3fefd4 --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerDesert.java @@ -0,0 +1,13 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MobSpawnerDesert extends MobSpawnerBase +{ + + public MobSpawnerDesert() + { + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerForest.java b/src/main/java/net/minecraft/src/MobSpawnerForest.java new file mode 100644 index 0000000..6cb0488 --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerForest.java @@ -0,0 +1,29 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class MobSpawnerForest extends MobSpawnerBase +{ + + public MobSpawnerForest() + { + } + + public WorldGenerator getRandomWorldGenForTrees(Random random) + { + if(random.nextInt(5) == 0) + { + return new WorldGenForest(); + } + if(random.nextInt(3) == 0) + { + return new WorldGenBigTree(); + } else + { + return new WorldGenTrees(); + } + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerHell.java b/src/main/java/net/minecraft/src/MobSpawnerHell.java new file mode 100644 index 0000000..1173d2f --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerHell.java @@ -0,0 +1,17 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MobSpawnerHell extends MobSpawnerBase +{ + + public MobSpawnerHell() + { + biomeMonsters = (new Class[] { + EntityGhast.class, EntityPigZombie.class + }); + biomeCreatures = new Class[0]; + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerRainforest.java b/src/main/java/net/minecraft/src/MobSpawnerRainforest.java new file mode 100644 index 0000000..44ff55c --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerRainforest.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class MobSpawnerRainforest extends MobSpawnerBase +{ + + public MobSpawnerRainforest() + { + } + + public WorldGenerator getRandomWorldGenForTrees(Random random) + { + if(random.nextInt(3) == 0) + { + return new WorldGenBigTree(); + } else + { + return new WorldGenTrees(); + } + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerSwamp.java b/src/main/java/net/minecraft/src/MobSpawnerSwamp.java new file mode 100644 index 0000000..6795370 --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerSwamp.java @@ -0,0 +1,13 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MobSpawnerSwamp extends MobSpawnerBase +{ + + public MobSpawnerSwamp() + { + } +} diff --git a/src/main/java/net/minecraft/src/MobSpawnerTaiga.java b/src/main/java/net/minecraft/src/MobSpawnerTaiga.java new file mode 100644 index 0000000..da2d949 --- /dev/null +++ b/src/main/java/net/minecraft/src/MobSpawnerTaiga.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class MobSpawnerTaiga extends MobSpawnerBase +{ + + public MobSpawnerTaiga() + { + } + + public WorldGenerator getRandomWorldGenForTrees(Random random) + { + if(random.nextInt(3) == 0) + { + return new WorldGenTaiga1(); + } else + { + return new WorldGenTaiga2(); + } + } +} diff --git a/src/main/java/net/minecraft/src/ModelBase.java b/src/main/java/net/minecraft/src/ModelBase.java new file mode 100644 index 0000000..5d92817 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBase.java @@ -0,0 +1,25 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public abstract class ModelBase +{ + + public ModelBase() + { + isRiding = false; + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + } + + public float onGround; + public boolean isRiding; +} diff --git a/src/main/java/net/minecraft/src/ModelBed.java b/src/main/java/net/minecraft/src/ModelBed.java new file mode 100644 index 0000000..06b9471 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBed.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelBed +{ + + public ModelBed() + { + } + + public static final int field_22280_a[] = { + 3, 4, 2, 5 + }; + public static final int field_22279_b[] = { + 2, 3, 0, 1 + }; + public static final int field_22281_c[][] = { + { + 1, 0, 3, 2, 5, 4 + }, { + 1, 0, 5, 4, 2, 3 + }, { + 1, 0, 2, 3, 4, 5 + }, { + 1, 0, 4, 5, 3, 2 + } + }; + +} diff --git a/src/main/java/net/minecraft/src/ModelBiped.java b/src/main/java/net/minecraft/src/ModelBiped.java new file mode 100644 index 0000000..2d16abd --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBiped.java @@ -0,0 +1,173 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelBiped extends ModelBase +{ + + public ModelBiped() + { + this(0.0F); + } + + public ModelBiped(float f) + { + this(f, 0.0F); + } + + public ModelBiped(float f, float f1) + { + field_1279_h = false; + field_1278_i = false; + isSneak = false; + bipedCloak = new ModelRenderer(0, 0); + bipedCloak.addBox(-5F, 0.0F, -1F, 10, 16, 1, f); + bipedEars = new ModelRenderer(24, 0); + bipedEars.addBox(-3F, -6F, -1F, 6, 6, 1, f); + bipedHead = new ModelRenderer(0, 0); + bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8, f); + bipedHead.setPosition(0.0F, 0.0F + f1, 0.0F); + bipedHeadwear = new ModelRenderer(32, 0); + bipedHeadwear.addBox(-4F, -8F, -4F, 8, 8, 8, f + 0.5F); + bipedHeadwear.setPosition(0.0F, 0.0F + f1, 0.0F); + bipedBody = new ModelRenderer(16, 16); + bipedBody.addBox(-4F, 0.0F, -2F, 8, 12, 4, f); + bipedBody.setPosition(0.0F, 0.0F + f1, 0.0F); + bipedRightArm = new ModelRenderer(40, 16); + bipedRightArm.addBox(-3F, -2F, -2F, 4, 12, 4, f); + bipedRightArm.setPosition(-5F, 2.0F + f1, 0.0F); + bipedLeftArm = new ModelRenderer(40, 16); + bipedLeftArm.mirror = true; + bipedLeftArm.addBox(-1F, -2F, -2F, 4, 12, 4, f); + bipedLeftArm.setPosition(5F, 2.0F + f1, 0.0F); + bipedRightLeg = new ModelRenderer(0, 16); + bipedRightLeg.addBox(-2F, 0.0F, -2F, 4, 12, 4, f); + bipedRightLeg.setPosition(-2F, 12F + f1, 0.0F); + bipedLeftLeg = new ModelRenderer(0, 16); + bipedLeftLeg.mirror = true; + bipedLeftLeg.addBox(-2F, 0.0F, -2F, 4, 12, 4, f); + bipedLeftLeg.setPosition(2.0F, 12F + f1, 0.0F); + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + bipedHead.render(f5); + bipedBody.render(f5); + bipedRightArm.render(f5); + bipedLeftArm.render(f5); + bipedRightLeg.render(f5); + bipedLeftLeg.render(f5); + bipedHeadwear.render(f5); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + bipedHead.rotateAngleY = f3 / 57.29578F; + bipedHead.rotateAngleX = f4 / 57.29578F; + bipedHeadwear.rotateAngleY = bipedHead.rotateAngleY; + bipedHeadwear.rotateAngleX = bipedHead.rotateAngleX; + bipedRightArm.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 2.0F * f1 * 0.5F; + bipedLeftArm.rotateAngleX = MathHelper.cos(f * 0.6662F) * 2.0F * f1 * 0.5F; + bipedRightArm.rotateAngleZ = 0.0F; + bipedLeftArm.rotateAngleZ = 0.0F; + bipedRightLeg.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; + bipedLeftLeg.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; + bipedRightLeg.rotateAngleY = 0.0F; + bipedLeftLeg.rotateAngleY = 0.0F; + if(isRiding) + { + bipedRightArm.rotateAngleX += -0.6283185F; + bipedLeftArm.rotateAngleX += -0.6283185F; + bipedRightLeg.rotateAngleX = -1.256637F; + bipedLeftLeg.rotateAngleX = -1.256637F; + bipedRightLeg.rotateAngleY = 0.3141593F; + bipedLeftLeg.rotateAngleY = -0.3141593F; + } + if(field_1279_h) + { + bipedLeftArm.rotateAngleX = bipedLeftArm.rotateAngleX * 0.5F - 0.3141593F; + } + if(field_1278_i) + { + bipedRightArm.rotateAngleX = bipedRightArm.rotateAngleX * 0.5F - 0.3141593F; + } + bipedRightArm.rotateAngleY = 0.0F; + bipedLeftArm.rotateAngleY = 0.0F; + if(onGround > -9990F) + { + float f6 = onGround; + bipedBody.rotateAngleY = MathHelper.sin(MathHelper.sqrt_float(f6) * 3.141593F * 2.0F) * 0.2F; + bipedRightArm.offsetZ = MathHelper.sin(bipedBody.rotateAngleY) * 5F; + bipedRightArm.offsetX = -MathHelper.cos(bipedBody.rotateAngleY) * 5F; + bipedLeftArm.offsetZ = -MathHelper.sin(bipedBody.rotateAngleY) * 5F; + bipedLeftArm.offsetX = MathHelper.cos(bipedBody.rotateAngleY) * 5F; + bipedRightArm.rotateAngleY += bipedBody.rotateAngleY; + bipedLeftArm.rotateAngleY += bipedBody.rotateAngleY; + bipedLeftArm.rotateAngleX += bipedBody.rotateAngleY; + f6 = 1.0F - onGround; + f6 *= f6; + f6 *= f6; + f6 = 1.0F - f6; + float f7 = MathHelper.sin(f6 * 3.141593F); + float f8 = MathHelper.sin(onGround * 3.141593F) * -(bipedHead.rotateAngleX - 0.7F) * 0.75F; + bipedRightArm.rotateAngleX -= (double)f7 * 1.2D + (double)f8; + bipedRightArm.rotateAngleY += bipedBody.rotateAngleY * 2.0F; + bipedRightArm.rotateAngleZ = MathHelper.sin(onGround * 3.141593F) * -0.4F; + } + if(isSneak) + { + bipedBody.rotateAngleX = 0.5F; + bipedRightLeg.rotateAngleX -= 0.0F; + bipedLeftLeg.rotateAngleX -= 0.0F; + bipedRightArm.rotateAngleX += 0.4F; + bipedLeftArm.rotateAngleX += 0.4F; + bipedRightLeg.offsetZ = 4F; + bipedLeftLeg.offsetZ = 4F; + bipedRightLeg.offsetY = 9F; + bipedLeftLeg.offsetY = 9F; + bipedHead.offsetY = 1.0F; + } else + { + bipedBody.rotateAngleX = 0.0F; + bipedRightLeg.offsetZ = 0.0F; + bipedLeftLeg.offsetZ = 0.0F; + bipedRightLeg.offsetY = 12F; + bipedLeftLeg.offsetY = 12F; + bipedHead.offsetY = 0.0F; + } + bipedRightArm.rotateAngleZ += MathHelper.cos(f2 * 0.09F) * 0.05F + 0.05F; + bipedLeftArm.rotateAngleZ -= MathHelper.cos(f2 * 0.09F) * 0.05F + 0.05F; + bipedRightArm.rotateAngleX += MathHelper.sin(f2 * 0.067F) * 0.05F; + bipedLeftArm.rotateAngleX -= MathHelper.sin(f2 * 0.067F) * 0.05F; + } + + public void renderEars(float f) + { + bipedEars.rotateAngleY = bipedHead.rotateAngleY; + bipedEars.rotateAngleX = bipedHead.rotateAngleX; + bipedEars.offsetX = 0.0F; + bipedEars.offsetY = 0.0F; + bipedEars.render(f); + } + + public void renderCloak(float f) + { + bipedCloak.render(f); + } + + public ModelRenderer bipedHead; + public ModelRenderer bipedHeadwear; + public ModelRenderer bipedBody; + public ModelRenderer bipedRightArm; + public ModelRenderer bipedLeftArm; + public ModelRenderer bipedRightLeg; + public ModelRenderer bipedLeftLeg; + public ModelRenderer bipedEars; + public ModelRenderer bipedCloak; + public boolean field_1279_h; + public boolean field_1278_i; + public boolean isSneak; +} diff --git a/src/main/java/net/minecraft/src/ModelBoat.java b/src/main/java/net/minecraft/src/ModelBoat.java new file mode 100644 index 0000000..338a630 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelBoat.java @@ -0,0 +1,52 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelBoat extends ModelBase +{ + + public ModelBoat() + { + boatSides = new ModelRenderer[5]; + boatSides[0] = new ModelRenderer(0, 8); + boatSides[1] = new ModelRenderer(0, 0); + boatSides[2] = new ModelRenderer(0, 0); + boatSides[3] = new ModelRenderer(0, 0); + boatSides[4] = new ModelRenderer(0, 0); + byte byte0 = 24; + byte byte1 = 6; + byte byte2 = 20; + byte byte3 = 4; + boatSides[0].addBox(-byte0 / 2, -byte2 / 2 + 2, -3F, byte0, byte2 - 4, 4, 0.0F); + boatSides[0].setPosition(0.0F, 0 + byte3, 0.0F); + boatSides[1].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + boatSides[1].setPosition(-byte0 / 2 + 1, 0 + byte3, 0.0F); + boatSides[2].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + boatSides[2].setPosition(byte0 / 2 - 1, 0 + byte3, 0.0F); + boatSides[3].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + boatSides[3].setPosition(0.0F, 0 + byte3, -byte2 / 2 + 1); + boatSides[4].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + boatSides[4].setPosition(0.0F, 0 + byte3, byte2 / 2 - 1); + boatSides[0].rotateAngleX = 1.570796F; + boatSides[1].rotateAngleY = 4.712389F; + boatSides[2].rotateAngleY = 1.570796F; + boatSides[3].rotateAngleY = 3.141593F; + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + for(int i = 0; i < 5; i++) + { + boatSides[i].render(f5); + } + + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + } + + public ModelRenderer boatSides[]; +} diff --git a/src/main/java/net/minecraft/src/ModelChicken.java b/src/main/java/net/minecraft/src/ModelChicken.java new file mode 100644 index 0000000..29a7a26 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelChicken.java @@ -0,0 +1,75 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelChicken extends ModelBase +{ + + public ModelChicken() + { + byte byte0 = 16; + field_1289_a = new ModelRenderer(0, 0); + field_1289_a.addBox(-2F, -6F, -2F, 4, 6, 3, 0.0F); + field_1289_a.setPosition(0.0F, -1 + byte0, -4F); + field_1291_g = new ModelRenderer(14, 0); + field_1291_g.addBox(-2F, -4F, -4F, 4, 2, 2, 0.0F); + field_1291_g.setPosition(0.0F, -1 + byte0, -4F); + field_1290_h = new ModelRenderer(14, 4); + field_1290_h.addBox(-1F, -2F, -3F, 2, 2, 2, 0.0F); + field_1290_h.setPosition(0.0F, -1 + byte0, -4F); + field_1288_b = new ModelRenderer(0, 9); + field_1288_b.addBox(-3F, -4F, -3F, 6, 8, 6, 0.0F); + field_1288_b.setPosition(0.0F, 0 + byte0, 0.0F); + field_1295_c = new ModelRenderer(26, 0); + field_1295_c.addBox(-1F, 0.0F, -3F, 3, 5, 3); + field_1295_c.setPosition(-2F, 3 + byte0, 1.0F); + field_1294_d = new ModelRenderer(26, 0); + field_1294_d.addBox(-1F, 0.0F, -3F, 3, 5, 3); + field_1294_d.setPosition(1.0F, 3 + byte0, 1.0F); + field_1293_e = new ModelRenderer(24, 13); + field_1293_e.addBox(0.0F, 0.0F, -3F, 1, 4, 6); + field_1293_e.setPosition(-4F, -3 + byte0, 0.0F); + field_1292_f = new ModelRenderer(24, 13); + field_1292_f.addBox(-1F, 0.0F, -3F, 1, 4, 6); + field_1292_f.setPosition(4F, -3 + byte0, 0.0F); + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + field_1289_a.render(f5); + field_1291_g.render(f5); + field_1290_h.render(f5); + field_1288_b.render(f5); + field_1295_c.render(f5); + field_1294_d.render(f5); + field_1293_e.render(f5); + field_1292_f.render(f5); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + field_1289_a.rotateAngleX = -(f4 / 57.29578F); + field_1289_a.rotateAngleY = f3 / 57.29578F; + field_1291_g.rotateAngleX = field_1289_a.rotateAngleX; + field_1291_g.rotateAngleY = field_1289_a.rotateAngleY; + field_1290_h.rotateAngleX = field_1289_a.rotateAngleX; + field_1290_h.rotateAngleY = field_1289_a.rotateAngleY; + field_1288_b.rotateAngleX = 1.570796F; + field_1295_c.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; + field_1294_d.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; + field_1293_e.rotateAngleZ = f2; + field_1292_f.rotateAngleZ = -f2; + } + + public ModelRenderer field_1289_a; + public ModelRenderer field_1288_b; + public ModelRenderer field_1295_c; + public ModelRenderer field_1294_d; + public ModelRenderer field_1293_e; + public ModelRenderer field_1292_f; + public ModelRenderer field_1291_g; + public ModelRenderer field_1290_h; +} diff --git a/src/main/java/net/minecraft/src/ModelCow.java b/src/main/java/net/minecraft/src/ModelCow.java new file mode 100644 index 0000000..34505da --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelCow.java @@ -0,0 +1,59 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelCow extends ModelQuadraped +{ + + public ModelCow() + { + super(12, 0.0F); + head = new ModelRenderer(0, 0); + head.addBox(-4F, -4F, -6F, 8, 8, 6, 0.0F); + head.setPosition(0.0F, 4F, -8F); + horn1 = new ModelRenderer(22, 0); + horn1.addBox(-4F, -5F, -4F, 1, 3, 1, 0.0F); + horn1.setPosition(0.0F, 3F, -7F); + horn2 = new ModelRenderer(22, 0); + horn2.addBox(3F, -5F, -4F, 1, 3, 1, 0.0F); + horn2.setPosition(0.0F, 3F, -7F); + udders = new ModelRenderer(52, 0); + udders.addBox(-2F, -3F, 0.0F, 4, 6, 2, 0.0F); + udders.setPosition(0.0F, 14F, 6F); + udders.rotateAngleX = 1.570796F; + body = new ModelRenderer(18, 4); + body.addBox(-6F, -10F, -7F, 12, 18, 10, 0.0F); + body.setPosition(0.0F, 5F, 2.0F); + leg1.offsetX--; + leg2.offsetX++; + leg1.offsetZ += 0.0F; + leg2.offsetZ += 0.0F; + leg3.offsetX--; + leg4.offsetX++; + leg3.offsetZ--; + leg4.offsetZ--; + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + super.render(f, f1, f2, f3, f4, f5); + horn1.render(f5); + horn2.render(f5); + udders.render(f5); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + super.setRotationAngles(f, f1, f2, f3, f4, f5); + horn1.rotateAngleY = head.rotateAngleY; + horn1.rotateAngleX = head.rotateAngleX; + horn2.rotateAngleY = head.rotateAngleY; + horn2.rotateAngleX = head.rotateAngleX; + } + + ModelRenderer udders; + ModelRenderer horn1; + ModelRenderer horn2; +} diff --git a/src/main/java/net/minecraft/src/ModelCreeper.java b/src/main/java/net/minecraft/src/ModelCreeper.java new file mode 100644 index 0000000..c273237 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelCreeper.java @@ -0,0 +1,65 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelCreeper extends ModelBase +{ + + public ModelCreeper() + { + float f = 0.0F; + int i = 4; + head = new ModelRenderer(0, 0); + head.addBox(-4F, -8F, -4F, 8, 8, 8, f); + head.setPosition(0.0F, i, 0.0F); + field_1270_b = new ModelRenderer(32, 0); + field_1270_b.addBox(-4F, -8F, -4F, 8, 8, 8, f + 0.5F); + field_1270_b.setPosition(0.0F, i, 0.0F); + body = new ModelRenderer(16, 16); + body.addBox(-4F, 0.0F, -2F, 8, 12, 4, f); + body.setPosition(0.0F, i, 0.0F); + leg1 = new ModelRenderer(0, 16); + leg1.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg1.setPosition(-2F, 12 + i, 4F); + leg2 = new ModelRenderer(0, 16); + leg2.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg2.setPosition(2.0F, 12 + i, 4F); + leg3 = new ModelRenderer(0, 16); + leg3.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg3.setPosition(-2F, 12 + i, -4F); + leg4 = new ModelRenderer(0, 16); + leg4.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg4.setPosition(2.0F, 12 + i, -4F); + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + head.render(f5); + body.render(f5); + leg1.render(f5); + leg2.render(f5); + leg3.render(f5); + leg4.render(f5); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + head.rotateAngleY = f3 / 57.29578F; + head.rotateAngleX = f4 / 57.29578F; + leg1.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; + leg2.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; + leg3.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; + leg4.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; + } + + public ModelRenderer head; + public ModelRenderer field_1270_b; + public ModelRenderer body; + public ModelRenderer leg1; + public ModelRenderer leg2; + public ModelRenderer leg3; + public ModelRenderer leg4; +} diff --git a/src/main/java/net/minecraft/src/ModelGhast.java b/src/main/java/net/minecraft/src/ModelGhast.java new file mode 100644 index 0000000..9ee6556 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelGhast.java @@ -0,0 +1,55 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class ModelGhast extends ModelBase +{ + + public ModelGhast() + { + tentacles = new ModelRenderer[9]; + byte byte0 = -16; + body = new ModelRenderer(0, 0); + body.addBox(-8F, -8F, -8F, 16, 16, 16); + body.offsetY += 24 + byte0; + Random random = new Random(1660L); + for(int i = 0; i < tentacles.length; i++) + { + tentacles[i] = new ModelRenderer(0, 0); + float f = (((((float)(i % 3) - (float)((i / 3) % 2) * 0.5F) + 0.25F) / 2.0F) * 2.0F - 1.0F) * 5F; + float f1 = (((float)(i / 3) / 2.0F) * 2.0F - 1.0F) * 5F; + int j = random.nextInt(7) + 8; + tentacles[i].addBox(-1F, 0.0F, -1F, 2, j, 2); + tentacles[i].offsetX = f; + tentacles[i].offsetZ = f1; + tentacles[i].offsetY = 31 + byte0; + } + + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + for(int i = 0; i < tentacles.length; i++) + { + tentacles[i].rotateAngleX = 0.2F * MathHelper.sin(f2 * 0.3F + (float)i) + 0.4F; + } + + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + body.render(f5); + for(int i = 0; i < tentacles.length; i++) + { + tentacles[i].render(f5); + } + + } + + ModelRenderer body; + ModelRenderer tentacles[]; +} diff --git a/src/main/java/net/minecraft/src/ModelMinecart.java b/src/main/java/net/minecraft/src/ModelMinecart.java new file mode 100644 index 0000000..2ba3712 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelMinecart.java @@ -0,0 +1,57 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelMinecart extends ModelBase +{ + + public ModelMinecart() + { + sideModels = new ModelRenderer[7]; + sideModels[0] = new ModelRenderer(0, 10); + sideModels[1] = new ModelRenderer(0, 0); + sideModels[2] = new ModelRenderer(0, 0); + sideModels[3] = new ModelRenderer(0, 0); + sideModels[4] = new ModelRenderer(0, 0); + sideModels[5] = new ModelRenderer(44, 10); + byte byte0 = 20; + byte byte1 = 8; + byte byte2 = 16; + byte byte3 = 4; + sideModels[0].addBox(-byte0 / 2, -byte2 / 2, -1F, byte0, byte2, 2, 0.0F); + sideModels[0].setPosition(0.0F, 0 + byte3, 0.0F); + sideModels[5].addBox(-byte0 / 2 + 1, -byte2 / 2 + 1, -1F, byte0 - 2, byte2 - 2, 1, 0.0F); + sideModels[5].setPosition(0.0F, 0 + byte3, 0.0F); + sideModels[1].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + sideModels[1].setPosition(-byte0 / 2 + 1, 0 + byte3, 0.0F); + sideModels[2].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + sideModels[2].setPosition(byte0 / 2 - 1, 0 + byte3, 0.0F); + sideModels[3].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + sideModels[3].setPosition(0.0F, 0 + byte3, -byte2 / 2 + 1); + sideModels[4].addBox(-byte0 / 2 + 2, -byte1 - 1, -1F, byte0 - 4, byte1, 2, 0.0F); + sideModels[4].setPosition(0.0F, 0 + byte3, byte2 / 2 - 1); + sideModels[0].rotateAngleX = 1.570796F; + sideModels[1].rotateAngleY = 4.712389F; + sideModels[2].rotateAngleY = 1.570796F; + sideModels[3].rotateAngleY = 3.141593F; + sideModels[5].rotateAngleX = -1.570796F; + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + sideModels[5].offsetY = 4F - f2; + for(int i = 0; i < 6; i++) + { + sideModels[i].render(f5); + } + + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + } + + public ModelRenderer sideModels[]; +} diff --git a/src/main/java/net/minecraft/src/ModelPig.java b/src/main/java/net/minecraft/src/ModelPig.java new file mode 100644 index 0000000..9982f4e --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelPig.java @@ -0,0 +1,19 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelPig extends ModelQuadraped +{ + + public ModelPig() + { + super(6, 0.0F); + } + + public ModelPig(float f) + { + super(6, f); + } +} diff --git a/src/main/java/net/minecraft/src/ModelQuadraped.java b/src/main/java/net/minecraft/src/ModelQuadraped.java new file mode 100644 index 0000000..d080880 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelQuadraped.java @@ -0,0 +1,60 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelQuadraped extends ModelBase +{ + + public ModelQuadraped(int i, float f) + { + head = new ModelRenderer(0, 0); + head.addBox(-4F, -4F, -8F, 8, 8, 8, f); + head.setPosition(0.0F, 18 - i, -6F); + body = new ModelRenderer(28, 8); + body.addBox(-5F, -10F, -7F, 10, 16, 8, f); + body.setPosition(0.0F, 17 - i, 2.0F); + leg1 = new ModelRenderer(0, 16); + leg1.addBox(-2F, 0.0F, -2F, 4, i, 4, f); + leg1.setPosition(-3F, 24 - i, 7F); + leg2 = new ModelRenderer(0, 16); + leg2.addBox(-2F, 0.0F, -2F, 4, i, 4, f); + leg2.setPosition(3F, 24 - i, 7F); + leg3 = new ModelRenderer(0, 16); + leg3.addBox(-2F, 0.0F, -2F, 4, i, 4, f); + leg3.setPosition(-3F, 24 - i, -5F); + leg4 = new ModelRenderer(0, 16); + leg4.addBox(-2F, 0.0F, -2F, 4, i, 4, f); + leg4.setPosition(3F, 24 - i, -5F); + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + head.render(f5); + body.render(f5); + leg1.render(f5); + leg2.render(f5); + leg3.render(f5); + leg4.render(f5); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + head.rotateAngleX = -(f4 / 57.29578F); + head.rotateAngleY = f3 / 57.29578F; + body.rotateAngleX = 1.570796F; + leg1.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; + leg2.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; + leg3.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; + leg4.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; + } + + public ModelRenderer head; + public ModelRenderer body; + public ModelRenderer leg1; + public ModelRenderer leg2; + public ModelRenderer leg3; + public ModelRenderer leg4; +} diff --git a/src/main/java/net/minecraft/src/ModelRenderer.java b/src/main/java/net/minecraft/src/ModelRenderer.java new file mode 100644 index 0000000..b2943df --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelRenderer.java @@ -0,0 +1,206 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class ModelRenderer +{ + + public ModelRenderer(int i, int j) + { + compiled = false; + displayList = 0; + mirror = false; + showModel = true; + field_1402_i = false; + textureOffsetX = i; + textureOffsetY = j; + } + + public void addBox(float f, float f1, float f2, int i, int j, int k) + { + addBox(f, f1, f2, i, j, k, 0.0F); + } + + public void addBox(float f, float f1, float f2, int i, int j, int k, float f3) + { + corners = new PositionTexureVertex[8]; + faces = new TexturedQuad[6]; + float f4 = f + (float)i; + float f5 = f1 + (float)j; + float f6 = f2 + (float)k; + f -= f3; + f1 -= f3; + f2 -= f3; + f4 += f3; + f5 += f3; + f6 += f3; + if(mirror) + { + float f7 = f4; + f4 = f; + f = f7; + } + PositionTexureVertex positiontexurevertex = new PositionTexureVertex(f, f1, f2, 0.0F, 0.0F); + PositionTexureVertex positiontexurevertex1 = new PositionTexureVertex(f4, f1, f2, 0.0F, 8F); + PositionTexureVertex positiontexurevertex2 = new PositionTexureVertex(f4, f5, f2, 8F, 8F); + PositionTexureVertex positiontexurevertex3 = new PositionTexureVertex(f, f5, f2, 8F, 0.0F); + PositionTexureVertex positiontexurevertex4 = new PositionTexureVertex(f, f1, f6, 0.0F, 0.0F); + PositionTexureVertex positiontexurevertex5 = new PositionTexureVertex(f4, f1, f6, 0.0F, 8F); + PositionTexureVertex positiontexurevertex6 = new PositionTexureVertex(f4, f5, f6, 8F, 8F); + PositionTexureVertex positiontexurevertex7 = new PositionTexureVertex(f, f5, f6, 8F, 0.0F); + corners[0] = positiontexurevertex; + corners[1] = positiontexurevertex1; + corners[2] = positiontexurevertex2; + corners[3] = positiontexurevertex3; + corners[4] = positiontexurevertex4; + corners[5] = positiontexurevertex5; + corners[6] = positiontexurevertex6; + corners[7] = positiontexurevertex7; + faces[0] = new TexturedQuad(new PositionTexureVertex[] { + positiontexurevertex5, positiontexurevertex1, positiontexurevertex2, positiontexurevertex6 + }, textureOffsetX + k + i, textureOffsetY + k, textureOffsetX + k + i + k, textureOffsetY + k + j); + faces[1] = new TexturedQuad(new PositionTexureVertex[] { + positiontexurevertex, positiontexurevertex4, positiontexurevertex7, positiontexurevertex3 + }, textureOffsetX + 0, textureOffsetY + k, textureOffsetX + k, textureOffsetY + k + j); + faces[2] = new TexturedQuad(new PositionTexureVertex[] { + positiontexurevertex5, positiontexurevertex4, positiontexurevertex, positiontexurevertex1 + }, textureOffsetX + k, textureOffsetY + 0, textureOffsetX + k + i, textureOffsetY + k); + faces[3] = new TexturedQuad(new PositionTexureVertex[] { + positiontexurevertex2, positiontexurevertex3, positiontexurevertex7, positiontexurevertex6 + }, textureOffsetX + k + i, textureOffsetY + 0, textureOffsetX + k + i + i, textureOffsetY + k); + faces[4] = new TexturedQuad(new PositionTexureVertex[] { + positiontexurevertex1, positiontexurevertex, positiontexurevertex3, positiontexurevertex2 + }, textureOffsetX + k, textureOffsetY + k, textureOffsetX + k + i, textureOffsetY + k + j); + faces[5] = new TexturedQuad(new PositionTexureVertex[] { + positiontexurevertex4, positiontexurevertex5, positiontexurevertex6, positiontexurevertex7 + }, textureOffsetX + k + i + k, textureOffsetY + k, textureOffsetX + k + i + k + i, textureOffsetY + k + j); + if(mirror) + { + for(int l = 0; l < faces.length; l++) + { + faces[l].flipFace(); + } + + } + } + + public void setPosition(float f, float f1, float f2) + { + offsetX = f; + offsetY = f1; + offsetZ = f2; + } + + public void render(float f) + { + if(field_1402_i) + { + return; + } + if(!showModel) + { + return; + } + if(!compiled) + { + compileDisplayList(f); + } + if(rotateAngleX != 0.0F || rotateAngleY != 0.0F || rotateAngleZ != 0.0F) + { + GL11.glPushMatrix(); + GL11.glTranslatef(offsetX * f, offsetY * f, offsetZ * f); + if(rotateAngleZ != 0.0F) + { + GL11.glRotatef(rotateAngleZ * 57.29578F, 0.0F, 0.0F, 1.0F); + } + if(rotateAngleY != 0.0F) + { + GL11.glRotatef(rotateAngleY * 57.29578F, 0.0F, 1.0F, 0.0F); + } + if(rotateAngleX != 0.0F) + { + GL11.glRotatef(rotateAngleX * 57.29578F, 1.0F, 0.0F, 0.0F); + } + GL11.glCallList(displayList); + GL11.glPopMatrix(); + } else + if(offsetX != 0.0F || offsetY != 0.0F || offsetZ != 0.0F) + { + GL11.glTranslatef(offsetX * f, offsetY * f, offsetZ * f); + GL11.glCallList(displayList); + GL11.glTranslatef(-offsetX * f, -offsetY * f, -offsetZ * f); + } else + { + GL11.glCallList(displayList); + } + } + + public void func_926_b(float f) + { + if(field_1402_i) + { + return; + } + if(!showModel) + { + return; + } + if(!compiled) + { + compileDisplayList(f); + } + if(rotateAngleX != 0.0F || rotateAngleY != 0.0F || rotateAngleZ != 0.0F) + { + GL11.glTranslatef(offsetX * f, offsetY * f, offsetZ * f); + if(rotateAngleZ != 0.0F) + { + GL11.glRotatef(rotateAngleZ * 57.29578F, 0.0F, 0.0F, 1.0F); + } + if(rotateAngleY != 0.0F) + { + GL11.glRotatef(rotateAngleY * 57.29578F, 0.0F, 1.0F, 0.0F); + } + if(rotateAngleX != 0.0F) + { + GL11.glRotatef(rotateAngleX * 57.29578F, 1.0F, 0.0F, 0.0F); + } + } else + if(offsetX != 0.0F || offsetY != 0.0F || offsetZ != 0.0F) + { + GL11.glTranslatef(offsetX * f, offsetY * f, offsetZ * f); + } + } + + private void compileDisplayList(float f) + { + displayList = GLAllocation.generateDisplayLists(1); + GL11.glNewList(displayList, 4864 /*GL_COMPILE*/); + Tessellator tessellator = Tessellator.instance; + for(int i = 0; i < faces.length; i++) + { + faces[i].draw(tessellator, f); + } + + GL11.glEndList(); + compiled = true; + } + + private PositionTexureVertex corners[]; + private TexturedQuad faces[]; + private int textureOffsetX; + private int textureOffsetY; + public float offsetX; + public float offsetY; + public float offsetZ; + public float rotateAngleX; + public float rotateAngleY; + public float rotateAngleZ; + private boolean compiled; + private int displayList; + public boolean mirror; + public boolean showModel; + public boolean field_1402_i; +} diff --git a/src/main/java/net/minecraft/src/ModelSheep1.java b/src/main/java/net/minecraft/src/ModelSheep1.java new file mode 100644 index 0000000..6deb6e8 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSheep1.java @@ -0,0 +1,33 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelSheep1 extends ModelQuadraped +{ + + public ModelSheep1() + { + super(12, 0.0F); + head = new ModelRenderer(0, 0); + head.addBox(-3F, -4F, -4F, 6, 6, 6, 0.6F); + head.setPosition(0.0F, 6F, -8F); + body = new ModelRenderer(28, 8); + body.addBox(-4F, -10F, -7F, 8, 16, 6, 1.75F); + body.setPosition(0.0F, 5F, 2.0F); + float f = 0.5F; + leg1 = new ModelRenderer(0, 16); + leg1.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg1.setPosition(-3F, 12F, 7F); + leg2 = new ModelRenderer(0, 16); + leg2.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg2.setPosition(3F, 12F, 7F); + leg3 = new ModelRenderer(0, 16); + leg3.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg3.setPosition(-3F, 12F, -5F); + leg4 = new ModelRenderer(0, 16); + leg4.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg4.setPosition(3F, 12F, -5F); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSheep2.java b/src/main/java/net/minecraft/src/ModelSheep2.java new file mode 100644 index 0000000..0806cbf --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSheep2.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelSheep2 extends ModelQuadraped +{ + + public ModelSheep2() + { + super(12, 0.0F); + head = new ModelRenderer(0, 0); + head.addBox(-3F, -4F, -6F, 6, 6, 8, 0.0F); + head.setPosition(0.0F, 6F, -8F); + body = new ModelRenderer(28, 8); + body.addBox(-4F, -10F, -7F, 8, 16, 6, 0.0F); + body.setPosition(0.0F, 5F, 2.0F); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSkeleton.java b/src/main/java/net/minecraft/src/ModelSkeleton.java new file mode 100644 index 0000000..441dca6 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSkeleton.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelSkeleton extends ModelZombie +{ + + public ModelSkeleton() + { + float f = 0.0F; + bipedRightArm = new ModelRenderer(40, 16); + bipedRightArm.addBox(-1F, -2F, -1F, 2, 12, 2, f); + bipedRightArm.setPosition(-5F, 2.0F, 0.0F); + bipedLeftArm = new ModelRenderer(40, 16); + bipedLeftArm.mirror = true; + bipedLeftArm.addBox(-1F, -2F, -1F, 2, 12, 2, f); + bipedLeftArm.setPosition(5F, 2.0F, 0.0F); + bipedRightLeg = new ModelRenderer(0, 16); + bipedRightLeg.addBox(-1F, 0.0F, -1F, 2, 12, 2, f); + bipedRightLeg.setPosition(-2F, 12F, 0.0F); + bipedLeftLeg = new ModelRenderer(0, 16); + bipedLeftLeg.mirror = true; + bipedLeftLeg.addBox(-1F, 0.0F, -1F, 2, 12, 2, f); + bipedLeftLeg.setPosition(2.0F, 12F, 0.0F); + } +} diff --git a/src/main/java/net/minecraft/src/ModelSlime.java b/src/main/java/net/minecraft/src/ModelSlime.java new file mode 100644 index 0000000..4daae47 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSlime.java @@ -0,0 +1,47 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelSlime extends ModelBase +{ + + public ModelSlime(int i) + { + field_1258_a = new ModelRenderer(0, i); + field_1258_a.addBox(-4F, 16F, -4F, 8, 8, 8); + if(i > 0) + { + field_1258_a = new ModelRenderer(0, i); + field_1258_a.addBox(-3F, 17F, -3F, 6, 6, 6); + field_1257_b = new ModelRenderer(32, 0); + field_1257_b.addBox(-3.25F, 18F, -3.5F, 2, 2, 2); + field_1260_c = new ModelRenderer(32, 4); + field_1260_c.addBox(1.25F, 18F, -3.5F, 2, 2, 2); + field_1259_d = new ModelRenderer(32, 8); + field_1259_d.addBox(0.0F, 21F, -3.5F, 1, 1, 1); + } + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + field_1258_a.render(f5); + if(field_1257_b != null) + { + field_1257_b.render(f5); + field_1260_c.render(f5); + field_1259_d.render(f5); + } + } + + ModelRenderer field_1258_a; + ModelRenderer field_1257_b; + ModelRenderer field_1260_c; + ModelRenderer field_1259_d; +} diff --git a/src/main/java/net/minecraft/src/ModelSpider.java b/src/main/java/net/minecraft/src/ModelSpider.java new file mode 100644 index 0000000..b8e9519 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSpider.java @@ -0,0 +1,125 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelSpider extends ModelBase +{ + + public ModelSpider() + { + float f = 0.0F; + int i = 15; + field_1255_a = new ModelRenderer(32, 4); + field_1255_a.addBox(-4F, -4F, -8F, 8, 8, 8, f); + field_1255_a.setPosition(0.0F, 0 + i, -3F); + field_1254_b = new ModelRenderer(0, 0); + field_1254_b.addBox(-3F, -3F, -3F, 6, 6, 6, f); + field_1254_b.setPosition(0.0F, i, 0.0F); + field_1253_c = new ModelRenderer(0, 12); + field_1253_c.addBox(-5F, -4F, -6F, 10, 8, 12, f); + field_1253_c.setPosition(0.0F, 0 + i, 9F); + field_1252_d = new ModelRenderer(18, 0); + field_1252_d.addBox(-15F, -1F, -1F, 16, 2, 2, f); + field_1252_d.setPosition(-4F, 0 + i, 2.0F); + field_1251_e = new ModelRenderer(18, 0); + field_1251_e.addBox(-1F, -1F, -1F, 16, 2, 2, f); + field_1251_e.setPosition(4F, 0 + i, 2.0F); + field_1250_f = new ModelRenderer(18, 0); + field_1250_f.addBox(-15F, -1F, -1F, 16, 2, 2, f); + field_1250_f.setPosition(-4F, 0 + i, 1.0F); + field_1249_g = new ModelRenderer(18, 0); + field_1249_g.addBox(-1F, -1F, -1F, 16, 2, 2, f); + field_1249_g.setPosition(4F, 0 + i, 1.0F); + field_1248_h = new ModelRenderer(18, 0); + field_1248_h.addBox(-15F, -1F, -1F, 16, 2, 2, f); + field_1248_h.setPosition(-4F, 0 + i, 0.0F); + field_1247_i = new ModelRenderer(18, 0); + field_1247_i.addBox(-1F, -1F, -1F, 16, 2, 2, f); + field_1247_i.setPosition(4F, 0 + i, 0.0F); + field_1246_j = new ModelRenderer(18, 0); + field_1246_j.addBox(-15F, -1F, -1F, 16, 2, 2, f); + field_1246_j.setPosition(-4F, 0 + i, -1F); + field_1245_m = new ModelRenderer(18, 0); + field_1245_m.addBox(-1F, -1F, -1F, 16, 2, 2, f); + field_1245_m.setPosition(4F, 0 + i, -1F); + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + field_1255_a.render(f5); + field_1254_b.render(f5); + field_1253_c.render(f5); + field_1252_d.render(f5); + field_1251_e.render(f5); + field_1250_f.render(f5); + field_1249_g.render(f5); + field_1248_h.render(f5); + field_1247_i.render(f5); + field_1246_j.render(f5); + field_1245_m.render(f5); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + field_1255_a.rotateAngleY = f3 / 57.29578F; + field_1255_a.rotateAngleX = f4 / 57.29578F; + float f6 = 0.7853982F; + field_1252_d.rotateAngleZ = -f6; + field_1251_e.rotateAngleZ = f6; + field_1250_f.rotateAngleZ = -f6 * 0.74F; + field_1249_g.rotateAngleZ = f6 * 0.74F; + field_1248_h.rotateAngleZ = -f6 * 0.74F; + field_1247_i.rotateAngleZ = f6 * 0.74F; + field_1246_j.rotateAngleZ = -f6; + field_1245_m.rotateAngleZ = f6; + float f7 = -0F; + float f8 = 0.3926991F; + field_1252_d.rotateAngleY = f8 * 2.0F + f7; + field_1251_e.rotateAngleY = -f8 * 2.0F - f7; + field_1250_f.rotateAngleY = f8 * 1.0F + f7; + field_1249_g.rotateAngleY = -f8 * 1.0F - f7; + field_1248_h.rotateAngleY = -f8 * 1.0F + f7; + field_1247_i.rotateAngleY = f8 * 1.0F - f7; + field_1246_j.rotateAngleY = -f8 * 2.0F + f7; + field_1245_m.rotateAngleY = f8 * 2.0F - f7; + float f9 = -(MathHelper.cos(f * 0.6662F * 2.0F + 0.0F) * 0.4F) * f1; + float f10 = -(MathHelper.cos(f * 0.6662F * 2.0F + 3.141593F) * 0.4F) * f1; + float f11 = -(MathHelper.cos(f * 0.6662F * 2.0F + 1.570796F) * 0.4F) * f1; + float f12 = -(MathHelper.cos(f * 0.6662F * 2.0F + 4.712389F) * 0.4F) * f1; + float f13 = Math.abs(MathHelper.sin(f * 0.6662F + 0.0F) * 0.4F) * f1; + float f14 = Math.abs(MathHelper.sin(f * 0.6662F + 3.141593F) * 0.4F) * f1; + float f15 = Math.abs(MathHelper.sin(f * 0.6662F + 1.570796F) * 0.4F) * f1; + float f16 = Math.abs(MathHelper.sin(f * 0.6662F + 4.712389F) * 0.4F) * f1; + field_1252_d.rotateAngleY += f9; + field_1251_e.rotateAngleY += -f9; + field_1250_f.rotateAngleY += f10; + field_1249_g.rotateAngleY += -f10; + field_1248_h.rotateAngleY += f11; + field_1247_i.rotateAngleY += -f11; + field_1246_j.rotateAngleY += f12; + field_1245_m.rotateAngleY += -f12; + field_1252_d.rotateAngleZ += f13; + field_1251_e.rotateAngleZ += -f13; + field_1250_f.rotateAngleZ += f14; + field_1249_g.rotateAngleZ += -f14; + field_1248_h.rotateAngleZ += f15; + field_1247_i.rotateAngleZ += -f15; + field_1246_j.rotateAngleZ += f16; + field_1245_m.rotateAngleZ += -f16; + } + + public ModelRenderer field_1255_a; + public ModelRenderer field_1254_b; + public ModelRenderer field_1253_c; + public ModelRenderer field_1252_d; + public ModelRenderer field_1251_e; + public ModelRenderer field_1250_f; + public ModelRenderer field_1249_g; + public ModelRenderer field_1248_h; + public ModelRenderer field_1247_i; + public ModelRenderer field_1246_j; + public ModelRenderer field_1245_m; +} diff --git a/src/main/java/net/minecraft/src/ModelSquid.java b/src/main/java/net/minecraft/src/ModelSquid.java new file mode 100644 index 0000000..5396ae9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelSquid.java @@ -0,0 +1,55 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelSquid extends ModelBase +{ + + public ModelSquid() + { + field_21122_b = new ModelRenderer[8]; + byte byte0 = -16; + field_21123_a = new ModelRenderer(0, 0); + field_21123_a.addBox(-6F, -8F, -6F, 12, 16, 12); + field_21123_a.offsetY += 24 + byte0; + for(int i = 0; i < field_21122_b.length; i++) + { + field_21122_b[i] = new ModelRenderer(48, 0); + double d = ((double)i * 3.1415926535897931D * 2D) / (double)field_21122_b.length; + float f = (float)Math.cos(d) * 5F; + float f1 = (float)Math.sin(d) * 5F; + field_21122_b[i].addBox(-1F, 0.0F, -1F, 2, 18, 2); + field_21122_b[i].offsetX = f; + field_21122_b[i].offsetZ = f1; + field_21122_b[i].offsetY = 31 + byte0; + d = ((double)i * 3.1415926535897931D * -2D) / (double)field_21122_b.length + 1.5707963267948966D; + field_21122_b[i].rotateAngleY = (float)d; + } + + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + for(int i = 0; i < field_21122_b.length; i++) + { + field_21122_b[i].rotateAngleX = f2; + } + + } + + public void render(float f, float f1, float f2, float f3, float f4, float f5) + { + setRotationAngles(f, f1, f2, f3, f4, f5); + field_21123_a.render(f5); + for(int i = 0; i < field_21122_b.length; i++) + { + field_21122_b[i].render(f5); + } + + } + + ModelRenderer field_21123_a; + ModelRenderer field_21122_b[]; +} diff --git a/src/main/java/net/minecraft/src/ModelZombie.java b/src/main/java/net/minecraft/src/ModelZombie.java new file mode 100644 index 0000000..26a18da --- /dev/null +++ b/src/main/java/net/minecraft/src/ModelZombie.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ModelZombie extends ModelBiped +{ + + public ModelZombie() + { + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) + { + super.setRotationAngles(f, f1, f2, f3, f4, f5); + float f6 = MathHelper.sin(onGround * 3.141593F); + float f7 = MathHelper.sin((1.0F - (1.0F - onGround) * (1.0F - onGround)) * 3.141593F); + bipedRightArm.rotateAngleZ = 0.0F; + bipedLeftArm.rotateAngleZ = 0.0F; + bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); + bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; + bipedRightArm.rotateAngleX = -1.570796F; + bipedLeftArm.rotateAngleX = -1.570796F; + bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + bipedRightArm.rotateAngleZ += MathHelper.cos(f2 * 0.09F) * 0.05F + 0.05F; + bipedLeftArm.rotateAngleZ -= MathHelper.cos(f2 * 0.09F) * 0.05F + 0.05F; + bipedRightArm.rotateAngleX += MathHelper.sin(f2 * 0.067F) * 0.05F; + bipedLeftArm.rotateAngleX -= MathHelper.sin(f2 * 0.067F) * 0.05F; + } +} diff --git a/src/main/java/net/minecraft/src/MouseFilter.java b/src/main/java/net/minecraft/src/MouseFilter.java new file mode 100644 index 0000000..cc465c3 --- /dev/null +++ b/src/main/java/net/minecraft/src/MouseFilter.java @@ -0,0 +1,30 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MouseFilter +{ + + public MouseFilter() + { + } + + public float func_22386_a(float f, float f1) + { + field_22388_a += f; + f = (field_22388_a - field_22387_b) * f1; + field_22389_c = field_22389_c + (f - field_22389_c) * 0.5F; + if(f > 0.0F && f > field_22389_c || f < 0.0F && f < field_22389_c) + { + f = field_22389_c; + } + field_22387_b += f; + return f; + } + + private float field_22388_a; + private float field_22387_b; + private float field_22389_c; +} diff --git a/src/main/java/net/minecraft/src/MouseHelper.java b/src/main/java/net/minecraft/src/MouseHelper.java new file mode 100644 index 0000000..ca012bf --- /dev/null +++ b/src/main/java/net/minecraft/src/MouseHelper.java @@ -0,0 +1,57 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.Component; +import java.nio.IntBuffer; +import org.lwjgl.LWJGLException; +import org.lwjgl.input.Cursor; +import org.lwjgl.input.Mouse; + +public class MouseHelper +{ + + public MouseHelper(Component component) + { + field_1115_e = 10; + field_1117_c = component; + IntBuffer intbuffer = GLAllocation.createDirectIntBuffer(1); + intbuffer.put(0); + intbuffer.flip(); + IntBuffer intbuffer1 = GLAllocation.createDirectIntBuffer(1024); + try + { + field_1116_d = new Cursor(32, 32, 16, 16, 1, intbuffer1, intbuffer); + } + catch(LWJGLException lwjglexception) + { + lwjglexception.printStackTrace(); + } + } + + public void func_774_a() + { + Mouse.setGrabbed(true); + deltaX = 0; + deltaY = 0; + } + + public void func_773_b() + { + Mouse.setCursorPosition(field_1117_c.getWidth() / 2, field_1117_c.getHeight() / 2); + Mouse.setGrabbed(false); + } + + public void mouseXYChange() + { + deltaX = Mouse.getDX(); + deltaY = Mouse.getDY(); + } + + private Component field_1117_c; + private Cursor field_1116_d; + public int deltaX; + public int deltaY; + private int field_1115_e; +} diff --git a/src/main/java/net/minecraft/src/MovementInput.java b/src/main/java/net/minecraft/src/MovementInput.java new file mode 100644 index 0000000..5dde70a --- /dev/null +++ b/src/main/java/net/minecraft/src/MovementInput.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MovementInput +{ + + public MovementInput() + { + moveStrafe = 0.0F; + moveForward = 0.0F; + field_1177_c = false; + jump = false; + sneak = false; + } + + public void updatePlayerMoveState(EntityPlayer entityplayer) + { + } + + public void resetKeyState() + { + } + + public void checkKeyForMovementInput(int i, boolean flag) + { + } + + public float moveStrafe; + public float moveForward; + public boolean field_1177_c; + public boolean jump; + public boolean sneak; +} diff --git a/src/main/java/net/minecraft/src/MovementInputFromOptions.java b/src/main/java/net/minecraft/src/MovementInputFromOptions.java new file mode 100644 index 0000000..fe4afa0 --- /dev/null +++ b/src/main/java/net/minecraft/src/MovementInputFromOptions.java @@ -0,0 +1,89 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MovementInputFromOptions extends MovementInput +{ + + public MovementInputFromOptions(GameSettings gamesettings) + { + movementKeyStates = new boolean[10]; + gameSettings = gamesettings; + } + + public void checkKeyForMovementInput(int i, boolean flag) + { + byte byte0 = -1; + if(i == gameSettings.keyBindForward.keyCode) + { + byte0 = 0; + } + if(i == gameSettings.keyBindBack.keyCode) + { + byte0 = 1; + } + if(i == gameSettings.keyBindLeft.keyCode) + { + byte0 = 2; + } + if(i == gameSettings.keyBindRight.keyCode) + { + byte0 = 3; + } + if(i == gameSettings.keyBindJump.keyCode) + { + byte0 = 4; + } + if(i == gameSettings.keyBindSneak.keyCode) + { + byte0 = 5; + } + if(byte0 >= 0) + { + movementKeyStates[byte0] = flag; + } + } + + public void resetKeyState() + { + for(int i = 0; i < 10; i++) + { + movementKeyStates[i] = false; + } + + } + + public void updatePlayerMoveState(EntityPlayer entityplayer) + { + moveStrafe = 0.0F; + moveForward = 0.0F; + if(movementKeyStates[0]) + { + moveForward++; + } + if(movementKeyStates[1]) + { + moveForward--; + } + if(movementKeyStates[2]) + { + moveStrafe++; + } + if(movementKeyStates[3]) + { + moveStrafe--; + } + jump = movementKeyStates[4]; + sneak = movementKeyStates[5]; + if(sneak) + { + moveStrafe *= 0.29999999999999999D; + moveForward *= 0.29999999999999999D; + } + } + + private boolean movementKeyStates[]; + private GameSettings gameSettings; +} diff --git a/src/main/java/net/minecraft/src/MovingObjectPosition.java b/src/main/java/net/minecraft/src/MovingObjectPosition.java new file mode 100644 index 0000000..0fe0ba0 --- /dev/null +++ b/src/main/java/net/minecraft/src/MovingObjectPosition.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class MovingObjectPosition +{ + + public MovingObjectPosition(int i, int j, int k, int l, Vec3D vec3d) + { + typeOfHit = EnumMovingObjectType.TILE; + blockX = i; + blockY = j; + blockZ = k; + sideHit = l; + hitVec = Vec3D.createVector(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord); + } + + public MovingObjectPosition(Entity entity) + { + typeOfHit = EnumMovingObjectType.ENTITY; + entityHit = entity; + hitVec = Vec3D.createVector(entity.posX, entity.posY, entity.posZ); + } + + public EnumMovingObjectType typeOfHit; + public int blockX; + public int blockY; + public int blockZ; + public int sideHit; + public Vec3D hitVec; + public Entity entityHit; +} diff --git a/src/main/java/net/minecraft/src/NBTBase.java b/src/main/java/net/minecraft/src/NBTBase.java new file mode 100644 index 0000000..1b1d588 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTBase.java @@ -0,0 +1,149 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public abstract class NBTBase +{ + + public NBTBase() + { + key = null; + } + + abstract void writeTagContents(DataOutput dataoutput) throws IOException; + + abstract void readTagContents(DataInput datainput) throws IOException; + + public abstract byte getType(); + + public String getKey() + { + if(key == null) + { + return ""; + } else + { + return key; + } + } + + public NBTBase setKey(String s) + { + key = s; + return this; + } + + public static NBTBase readTag(DataInput datainput) throws IOException + { + byte byte0 = datainput.readByte(); + if(byte0 == 0) + { + return new NBTTagEnd(); + } else + { + NBTBase nbtbase = createTagOfType(byte0); + nbtbase.key = datainput.readUTF(); + nbtbase.readTagContents(datainput); + return nbtbase; + } + } + + public static void writeTag(NBTBase nbtbase, DataOutput dataoutput) throws IOException + { + dataoutput.writeByte(nbtbase.getType()); + if(nbtbase.getType() == 0) + { + return; + } else + { + dataoutput.writeUTF(nbtbase.getKey()); + nbtbase.writeTagContents(dataoutput); + return; + } + } + + public static NBTBase createTagOfType(byte byte0) + { + switch(byte0) + { + case 0: // '\0' + return new NBTTagEnd(); + + case 1: // '\001' + return new NBTTagByte(); + + case 2: // '\002' + return new NBTTagShort(); + + case 3: // '\003' + return new NBTTagInt(); + + case 4: // '\004' + return new NBTTagLong(); + + case 5: // '\005' + return new NBTTagFloat(); + + case 6: // '\006' + return new NBTTagDouble(); + + case 7: // '\007' + return new NBTTagByteArray(); + + case 8: // '\b' + return new NBTTagString(); + + case 9: // '\t' + return new NBTTagList(); + + case 10: // '\n' + return new NBTTagCompound(); + } + return null; + } + + public static String getTagName(byte byte0) + { + switch(byte0) + { + case 0: // '\0' + return "TAG_End"; + + case 1: // '\001' + return "TAG_Byte"; + + case 2: // '\002' + return "TAG_Short"; + + case 3: // '\003' + return "TAG_Int"; + + case 4: // '\004' + return "TAG_Long"; + + case 5: // '\005' + return "TAG_Float"; + + case 6: // '\006' + return "TAG_Double"; + + case 7: // '\007' + return "TAG_Byte_Array"; + + case 8: // '\b' + return "TAG_String"; + + case 9: // '\t' + return "TAG_List"; + + case 10: // '\n' + return "TAG_Compound"; + } + return "UNKNOWN"; + } + + private String key; +} diff --git a/src/main/java/net/minecraft/src/NBTTagByte.java b/src/main/java/net/minecraft/src/NBTTagByte.java new file mode 100644 index 0000000..60512ae --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagByte.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagByte extends NBTBase +{ + + public NBTTagByte() + { + } + + public NBTTagByte(byte byte0) + { + byteValue = byte0; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeByte(byteValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + byteValue = datainput.readByte(); + } + + public byte getType() + { + return 1; + } + + public String toString() + { + return (new StringBuilder()).append("").append(byteValue).toString(); + } + + public byte byteValue; +} diff --git a/src/main/java/net/minecraft/src/NBTTagByteArray.java b/src/main/java/net/minecraft/src/NBTTagByteArray.java new file mode 100644 index 0000000..f6f212f --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagByteArray.java @@ -0,0 +1,44 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagByteArray extends NBTBase +{ + + public NBTTagByteArray() + { + } + + public NBTTagByteArray(byte abyte0[]) + { + byteArray = abyte0; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeInt(byteArray.length); + dataoutput.write(byteArray); + } + + void readTagContents(DataInput datainput) throws IOException + { + int i = datainput.readInt(); + byteArray = new byte[i]; + datainput.readFully(byteArray); + } + + public byte getType() + { + return 7; + } + + public String toString() + { + return (new StringBuilder()).append("[").append(byteArray.length).append(" bytes]").toString(); + } + + public byte byteArray[]; +} diff --git a/src/main/java/net/minecraft/src/NBTTagCompound.java b/src/main/java/net/minecraft/src/NBTTagCompound.java new file mode 100644 index 0000000..9eeecd6 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagCompound.java @@ -0,0 +1,221 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.*; + +public class NBTTagCompound extends NBTBase +{ + + public NBTTagCompound() + { + tagMap = new HashMap(); + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + NBTBase nbtbase; + for(Iterator iterator = tagMap.values().iterator(); iterator.hasNext(); NBTBase.writeTag(nbtbase, dataoutput)) + { + nbtbase = (NBTBase)iterator.next(); + } + + dataoutput.writeByte(0); + } + + void readTagContents(DataInput datainput) throws IOException + { + tagMap.clear(); + NBTBase nbtbase; + for(; (nbtbase = NBTBase.readTag(datainput)).getType() != 0; tagMap.put(nbtbase.getKey(), nbtbase)) { } + } + + public byte getType() + { + return 10; + } + + public void setTag(String s, NBTBase nbtbase) + { + tagMap.put(s, nbtbase.setKey(s)); + } + + public void setByte(String s, byte byte0) + { + tagMap.put(s, (new NBTTagByte(byte0)).setKey(s)); + } + + public void setShort(String s, short word0) + { + tagMap.put(s, (new NBTTagShort(word0)).setKey(s)); + } + + public void setInteger(String s, int i) + { + tagMap.put(s, (new NBTTagInt(i)).setKey(s)); + } + + public void setLong(String s, long l) + { + tagMap.put(s, (new NBTTagLong(l)).setKey(s)); + } + + public void setFloat(String s, float f) + { + tagMap.put(s, (new NBTTagFloat(f)).setKey(s)); + } + + public void setDouble(String s, double d) + { + tagMap.put(s, (new NBTTagDouble(d)).setKey(s)); + } + + public void setString(String s, String s1) + { + tagMap.put(s, (new NBTTagString(s1)).setKey(s)); + } + + public void setByteArray(String s, byte abyte0[]) + { + tagMap.put(s, (new NBTTagByteArray(abyte0)).setKey(s)); + } + + public void setCompoundTag(String s, NBTTagCompound nbttagcompound) + { + tagMap.put(s, nbttagcompound.setKey(s)); + } + + public void setBoolean(String s, boolean flag) + { + setByte(s, ((byte)(flag ? 1 : 0))); + } + + public boolean hasKey(String s) + { + return tagMap.containsKey(s); + } + + public byte getByte(String s) + { + if(!tagMap.containsKey(s)) + { + return 0; + } else + { + return ((NBTTagByte)tagMap.get(s)).byteValue; + } + } + + public short getShort(String s) + { + if(!tagMap.containsKey(s)) + { + return 0; + } else + { + return ((NBTTagShort)tagMap.get(s)).shortValue; + } + } + + public int getInteger(String s) + { + if(!tagMap.containsKey(s)) + { + return 0; + } else + { + return ((NBTTagInt)tagMap.get(s)).intValue; + } + } + + public long getLong(String s) + { + if(!tagMap.containsKey(s)) + { + return 0L; + } else + { + return ((NBTTagLong)tagMap.get(s)).longValue; + } + } + + public float getFloat(String s) + { + if(!tagMap.containsKey(s)) + { + return 0.0F; + } else + { + return ((NBTTagFloat)tagMap.get(s)).floatValue; + } + } + + public double getDouble(String s) + { + if(!tagMap.containsKey(s)) + { + return 0.0D; + } else + { + return ((NBTTagDouble)tagMap.get(s)).doubleValue; + } + } + + public String getString(String s) + { + if(!tagMap.containsKey(s)) + { + return ""; + } else + { + return ((NBTTagString)tagMap.get(s)).stringValue; + } + } + + public byte[] getByteArray(String s) + { + if(!tagMap.containsKey(s)) + { + return new byte[0]; + } else + { + return ((NBTTagByteArray)tagMap.get(s)).byteArray; + } + } + + public NBTTagCompound getCompoundTag(String s) + { + if(!tagMap.containsKey(s)) + { + return new NBTTagCompound(); + } else + { + return (NBTTagCompound)tagMap.get(s); + } + } + + public NBTTagList getTagList(String s) + { + if(!tagMap.containsKey(s)) + { + return new NBTTagList(); + } else + { + return (NBTTagList)tagMap.get(s); + } + } + + public boolean getBoolean(String s) + { + return getByte(s) != 0; + } + + public String toString() + { + return (new StringBuilder()).append("").append(tagMap.size()).append(" entries").toString(); + } + + private Map tagMap; +} diff --git a/src/main/java/net/minecraft/src/NBTTagDouble.java b/src/main/java/net/minecraft/src/NBTTagDouble.java new file mode 100644 index 0000000..fda1fc4 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagDouble.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagDouble extends NBTBase +{ + + public NBTTagDouble() + { + } + + public NBTTagDouble(double d) + { + doubleValue = d; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeDouble(doubleValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + doubleValue = datainput.readDouble(); + } + + public byte getType() + { + return 6; + } + + public String toString() + { + return (new StringBuilder()).append("").append(doubleValue).toString(); + } + + public double doubleValue; +} diff --git a/src/main/java/net/minecraft/src/NBTTagEnd.java b/src/main/java/net/minecraft/src/NBTTagEnd.java new file mode 100644 index 0000000..1afa371 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagEnd.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagEnd extends NBTBase +{ + + public NBTTagEnd() + { + } + + void readTagContents(DataInput datainput) throws IOException + { + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + } + + public byte getType() + { + return 0; + } + + public String toString() + { + return "END"; + } +} diff --git a/src/main/java/net/minecraft/src/NBTTagFloat.java b/src/main/java/net/minecraft/src/NBTTagFloat.java new file mode 100644 index 0000000..22b9f89 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagFloat.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagFloat extends NBTBase +{ + + public NBTTagFloat() + { + } + + public NBTTagFloat(float f) + { + floatValue = f; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeFloat(floatValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + floatValue = datainput.readFloat(); + } + + public byte getType() + { + return 5; + } + + public String toString() + { + return (new StringBuilder()).append("").append(floatValue).toString(); + } + + public float floatValue; +} diff --git a/src/main/java/net/minecraft/src/NBTTagInt.java b/src/main/java/net/minecraft/src/NBTTagInt.java new file mode 100644 index 0000000..c884a3c --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagInt.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagInt extends NBTBase +{ + + public NBTTagInt() + { + } + + public NBTTagInt(int i) + { + intValue = i; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeInt(intValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + intValue = datainput.readInt(); + } + + public byte getType() + { + return 3; + } + + public String toString() + { + return (new StringBuilder()).append("").append(intValue).toString(); + } + + public int intValue; +} diff --git a/src/main/java/net/minecraft/src/NBTTagList.java b/src/main/java/net/minecraft/src/NBTTagList.java new file mode 100644 index 0000000..2d2af8f --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagList.java @@ -0,0 +1,78 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class NBTTagList extends NBTBase +{ + + public NBTTagList() + { + tagList = new ArrayList(); + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + if(tagList.size() > 0) + { + tagType = ((NBTBase)tagList.get(0)).getType(); + } else + { + tagType = 1; + } + dataoutput.writeByte(tagType); + dataoutput.writeInt(tagList.size()); + for(int i = 0; i < tagList.size(); i++) + { + ((NBTBase)tagList.get(i)).writeTagContents(dataoutput); + } + + } + + void readTagContents(DataInput datainput) throws IOException + { + tagType = datainput.readByte(); + int i = datainput.readInt(); + tagList = new ArrayList(); + for(int j = 0; j < i; j++) + { + NBTBase nbtbase = NBTBase.createTagOfType(tagType); + nbtbase.readTagContents(datainput); + tagList.add(nbtbase); + } + + } + + public byte getType() + { + return 9; + } + + public String toString() + { + return (new StringBuilder()).append("").append(tagList.size()).append(" entries of type ").append(NBTBase.getTagName(tagType)).toString(); + } + + public void setTag(NBTBase nbtbase) + { + tagType = nbtbase.getType(); + tagList.add(nbtbase); + } + + public NBTBase tagAt(int i) + { + return (NBTBase)tagList.get(i); + } + + public int tagCount() + { + return tagList.size(); + } + + private List tagList; + private byte tagType; +} diff --git a/src/main/java/net/minecraft/src/NBTTagLong.java b/src/main/java/net/minecraft/src/NBTTagLong.java new file mode 100644 index 0000000..652cf61 --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagLong.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagLong extends NBTBase +{ + + public NBTTagLong() + { + } + + public NBTTagLong(long l) + { + longValue = l; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeLong(longValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + longValue = datainput.readLong(); + } + + public byte getType() + { + return 4; + } + + public String toString() + { + return (new StringBuilder()).append("").append(longValue).toString(); + } + + public long longValue; +} diff --git a/src/main/java/net/minecraft/src/NBTTagShort.java b/src/main/java/net/minecraft/src/NBTTagShort.java new file mode 100644 index 0000000..a4796aa --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagShort.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagShort extends NBTBase +{ + + public NBTTagShort() + { + } + + public NBTTagShort(short word0) + { + shortValue = word0; + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeShort(shortValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + shortValue = datainput.readShort(); + } + + public byte getType() + { + return 2; + } + + public String toString() + { + return (new StringBuilder()).append("").append(shortValue).toString(); + } + + public short shortValue; +} diff --git a/src/main/java/net/minecraft/src/NBTTagString.java b/src/main/java/net/minecraft/src/NBTTagString.java new file mode 100644 index 0000000..d53c56f --- /dev/null +++ b/src/main/java/net/minecraft/src/NBTTagString.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class NBTTagString extends NBTBase +{ + + public NBTTagString() + { + } + + public NBTTagString(String s) + { + stringValue = s; + if(s == null) + { + throw new IllegalArgumentException("Empty string not allowed"); + } else + { + return; + } + } + + void writeTagContents(DataOutput dataoutput) throws IOException + { + dataoutput.writeUTF(stringValue); + } + + void readTagContents(DataInput datainput) throws IOException + { + stringValue = datainput.readUTF(); + } + + public byte getType() + { + return 8; + } + + public String toString() + { + return (new StringBuilder()).append("").append(stringValue).toString(); + } + + public String stringValue; +} diff --git a/src/main/java/net/minecraft/src/NetClientHandler.java b/src/main/java/net/minecraft/src/NetClientHandler.java new file mode 100644 index 0000000..d3efbb7 --- /dev/null +++ b/src/main/java/net/minecraft/src/NetClientHandler.java @@ -0,0 +1,659 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.net.*; +import java.util.Random; + +import net.lax1dude.eaglercraft.compat.UnexpectedThrowable; +import net.minecraft.client.Minecraft; + +public class NetClientHandler extends NetHandler +{ + + public NetClientHandler(Minecraft minecraft, String s, int i) + { + disconnected = false; + field_1210_g = false; + rand = new Random(); + mc = minecraft; + Socket socket; + try { + socket = new Socket(InetAddress.getByName(s), i); + }catch(IOException e) { + throw new UnexpectedThrowable(e); + } + netManager = new NetworkManager(socket, "Client", this); + } + + public void processReadPackets() + { + if(disconnected) + { + return; + } else + { + netManager.processReadPackets(); + return; + } + } + + public void handleLogin(Packet1Login packet1login) + { + mc.playerController = new PlayerControllerMP(mc, this); + worldClient = new WorldClient(this, packet1login.mapSeed, packet1login.dimension); + worldClient.multiplayerWorld = true; + mc.changeWorld1(worldClient); + mc.displayGuiScreen(new GuiDownloadTerrain(this)); + mc.thePlayer.entityId = packet1login.protocolVersion; + } + + public void handlePickupSpawn(Packet21PickupSpawn packet21pickupspawn) + { + double d = (double)packet21pickupspawn.xPosition / 32D; + double d1 = (double)packet21pickupspawn.yPosition / 32D; + double d2 = (double)packet21pickupspawn.zPosition / 32D; + EntityItem entityitem = new EntityItem(worldClient, d, d1, d2, new ItemStack(packet21pickupspawn.itemID, packet21pickupspawn.count, packet21pickupspawn.itemDamage)); + entityitem.motionX = (double)packet21pickupspawn.rotation / 128D; + entityitem.motionY = (double)packet21pickupspawn.pitch / 128D; + entityitem.motionZ = (double)packet21pickupspawn.roll / 128D; + entityitem.serverPosX = packet21pickupspawn.xPosition; + entityitem.serverPosY = packet21pickupspawn.yPosition; + entityitem.serverPosZ = packet21pickupspawn.zPosition; + worldClient.func_712_a(packet21pickupspawn.entityId, entityitem); + } + + public void handleVehicleSpawn(Packet23VehicleSpawn packet23vehiclespawn) + { + double d = (double)packet23vehiclespawn.xPosition / 32D; + double d1 = (double)packet23vehiclespawn.yPosition / 32D; + double d2 = (double)packet23vehiclespawn.zPosition / 32D; + Entity obj = null; + if(packet23vehiclespawn.type == 10) + { + obj = new EntityMinecart(worldClient, d, d1, d2, 0); + } + if(packet23vehiclespawn.type == 11) + { + obj = new EntityMinecart(worldClient, d, d1, d2, 1); + } + if(packet23vehiclespawn.type == 12) + { + obj = new EntityMinecart(worldClient, d, d1, d2, 2); + } + if(packet23vehiclespawn.type == 90) + { + obj = new EntityFish(worldClient, d, d1, d2); + } + if(packet23vehiclespawn.type == 60) + { + obj = new EntityArrow(worldClient, d, d1, d2); + } + if(packet23vehiclespawn.type == 61) + { + obj = new EntitySnowball(worldClient, d, d1, d2); + } + if(packet23vehiclespawn.type == 62) + { + obj = new EntityEgg(worldClient, d, d1, d2); + } + if(packet23vehiclespawn.type == 1) + { + obj = new EntityBoat(worldClient, d, d1, d2); + } + if(packet23vehiclespawn.type == 50) + { + obj = new EntityTNTPrimed(worldClient, d, d1, d2); + } + if(packet23vehiclespawn.type == 70) + { + obj = new EntityFallingSand(worldClient, d, d1, d2, Block.sand.blockID); + } + if(packet23vehiclespawn.type == 71) + { + obj = new EntityFallingSand(worldClient, d, d1, d2, Block.gravel.blockID); + } + if(obj != null) + { + obj.serverPosX = packet23vehiclespawn.xPosition; + obj.serverPosY = packet23vehiclespawn.yPosition; + obj.serverPosZ = packet23vehiclespawn.zPosition; + obj.rotationYaw = 0.0F; + obj.rotationPitch = 0.0F; + obj.entityId = packet23vehiclespawn.entityId; + worldClient.func_712_a(packet23vehiclespawn.entityId, ((Entity) (obj))); + } + } + + public void func_21146_a(Packet25 packet25) + { + EntityPainting entitypainting = new EntityPainting(worldClient, packet25.xPosition, packet25.yPosition, packet25.zPosition, packet25.direction, packet25.title); + worldClient.func_712_a(packet25.entityId, entitypainting); + } + + public void func_6498_a(Packet28 packet28) + { + Entity entity = getEntityByID(packet28.entityId); + if(entity == null) + { + return; + } else + { + entity.setVelocity((double)packet28.motionX / 8000D, (double)packet28.motionY / 8000D, (double)packet28.motionZ / 8000D); + return; + } + } + + public void func_21148_a(Packet40 packet40) + { + Entity entity = getEntityByID(packet40.entityId); + if(entity != null && packet40.func_21047_b() != null) + { + entity.getDataWatcher().updateWatchedObjectsFromList(packet40.func_21047_b()); + } + } + + public void handleNamedEntitySpawn(Packet20NamedEntitySpawn packet20namedentityspawn) + { + double d = (double)packet20namedentityspawn.xPosition / 32D; + double d1 = (double)packet20namedentityspawn.yPosition / 32D; + double d2 = (double)packet20namedentityspawn.zPosition / 32D; + float f = (float)(packet20namedentityspawn.rotation * 360) / 256F; + float f1 = (float)(packet20namedentityspawn.pitch * 360) / 256F; + EntityOtherPlayerMP entityotherplayermp = new EntityOtherPlayerMP(mc.theWorld, packet20namedentityspawn.name); + entityotherplayermp.serverPosX = packet20namedentityspawn.xPosition; + entityotherplayermp.serverPosY = packet20namedentityspawn.yPosition; + entityotherplayermp.serverPosZ = packet20namedentityspawn.zPosition; + int i = packet20namedentityspawn.currentItem; + if(i == 0) + { + entityotherplayermp.inventory.mainInventory[entityotherplayermp.inventory.currentItem] = null; + } else + { + entityotherplayermp.inventory.mainInventory[entityotherplayermp.inventory.currentItem] = new ItemStack(i, 1, 0); + } + entityotherplayermp.setPositionAndRotation(d, d1, d2, f, f1); + worldClient.func_712_a(packet20namedentityspawn.entityId, entityotherplayermp); + } + + public void handleEntityTeleport(Packet34EntityTeleport packet34entityteleport) + { + Entity entity = getEntityByID(packet34entityteleport.entityId); + if(entity == null) + { + return; + } else + { + entity.serverPosX = packet34entityteleport.xPosition; + entity.serverPosY = packet34entityteleport.yPosition; + entity.serverPosZ = packet34entityteleport.zPosition; + double d = (double)entity.serverPosX / 32D; + double d1 = (double)entity.serverPosY / 32D + 0.015625D; + double d2 = (double)entity.serverPosZ / 32D; + float f = (float)(packet34entityteleport.yaw * 360) / 256F; + float f1 = (float)(packet34entityteleport.pitch * 360) / 256F; + entity.setPositionAndRotation2(d, d1, d2, f, f1, 3); + return; + } + } + + public void handleEntity(Packet30Entity packet30entity) + { + Entity entity = getEntityByID(packet30entity.entityId); + if(entity == null) + { + return; + } else + { + entity.serverPosX += packet30entity.xPosition; + entity.serverPosY += packet30entity.yPosition; + entity.serverPosZ += packet30entity.zPosition; + double d = (double)entity.serverPosX / 32D; + double d1 = (double)entity.serverPosY / 32D + 0.015625D; + double d2 = (double)entity.serverPosZ / 32D; + float f = packet30entity.rotating ? (float)(packet30entity.yaw * 360) / 256F : entity.rotationYaw; + float f1 = packet30entity.rotating ? (float)(packet30entity.pitch * 360) / 256F : entity.rotationPitch; + entity.setPositionAndRotation2(d, d1, d2, f, f1, 3); + return; + } + } + + public void handleDestroyEntity(Packet29DestroyEntity packet29destroyentity) + { + worldClient.removeEntityFromWorld(packet29destroyentity.entityId); + } + + public void handleFlying(Packet10Flying packet10flying) + { + EntityPlayerSP entityplayersp = mc.thePlayer; + double d = ((EntityPlayer) (entityplayersp)).posX; + double d1 = ((EntityPlayer) (entityplayersp)).posY; + double d2 = ((EntityPlayer) (entityplayersp)).posZ; + float f = ((EntityPlayer) (entityplayersp)).rotationYaw; + float f1 = ((EntityPlayer) (entityplayersp)).rotationPitch; + if(packet10flying.moving) + { + d = packet10flying.xPosition; + d1 = packet10flying.yPosition; + d2 = packet10flying.zPosition; + } + if(packet10flying.rotating) + { + f = packet10flying.yaw; + f1 = packet10flying.pitch; + } + entityplayersp.ySize = 0.0F; + entityplayersp.motionX = entityplayersp.motionY = entityplayersp.motionZ = 0.0D; + entityplayersp.setPositionAndRotation(d, d1, d2, f, f1); + packet10flying.xPosition = ((EntityPlayer) (entityplayersp)).posX; + packet10flying.yPosition = ((EntityPlayer) (entityplayersp)).boundingBox.minY; + packet10flying.zPosition = ((EntityPlayer) (entityplayersp)).posZ; + packet10flying.stance = ((EntityPlayer) (entityplayersp)).posY; + netManager.addToSendQueue(packet10flying); + if(!field_1210_g) + { + mc.thePlayer.prevPosX = mc.thePlayer.posX; + mc.thePlayer.prevPosY = mc.thePlayer.posY; + mc.thePlayer.prevPosZ = mc.thePlayer.posZ; + field_1210_g = true; + mc.displayGuiScreen(null); + } + } + + public void handlePreChunk(Packet50PreChunk packet50prechunk) + { + worldClient.func_713_a(packet50prechunk.xPosition, packet50prechunk.yPosition, packet50prechunk.mode); + } + + public void handleMultiBlockChange(Packet52MultiBlockChange packet52multiblockchange) + { + Chunk chunk = worldClient.getChunkFromChunkCoords(packet52multiblockchange.xPosition, packet52multiblockchange.zPosition); + int i = packet52multiblockchange.xPosition * 16; + int j = packet52multiblockchange.zPosition * 16; + for(int k = 0; k < packet52multiblockchange.size; k++) + { + short word0 = packet52multiblockchange.coordinateArray[k]; + int l = packet52multiblockchange.typeArray[k] & 0xff; + byte byte0 = packet52multiblockchange.metadataArray[k]; + int i1 = word0 >> 12 & 0xf; + int j1 = word0 >> 8 & 0xf; + int k1 = word0 & 0xff; + chunk.setBlockIDWithMetadata(i1, k1, j1, l, byte0); + worldClient.func_711_c(i1 + i, k1, j1 + j, i1 + i, k1, j1 + j); + worldClient.markBlocksDirty(i1 + i, k1, j1 + j, i1 + i, k1, j1 + j); + } + + } + + public void handleMapChunk(Packet51MapChunk packet51mapchunk) + { + worldClient.func_711_c(packet51mapchunk.xPosition, packet51mapchunk.yPosition, packet51mapchunk.zPosition, (packet51mapchunk.xPosition + packet51mapchunk.xSize) - 1, (packet51mapchunk.yPosition + packet51mapchunk.ySize) - 1, (packet51mapchunk.zPosition + packet51mapchunk.zSize) - 1); + worldClient.setChunkData(packet51mapchunk.xPosition, packet51mapchunk.yPosition, packet51mapchunk.zPosition, packet51mapchunk.xSize, packet51mapchunk.ySize, packet51mapchunk.zSize, packet51mapchunk.chunk); + } + + public void handleBlockChange(Packet53BlockChange packet53blockchange) + { + worldClient.func_714_c(packet53blockchange.xPosition, packet53blockchange.yPosition, packet53blockchange.zPosition, packet53blockchange.type, packet53blockchange.metadata); + } + + public void handleKickDisconnect(Packet255KickDisconnect packet255kickdisconnect) + { + netManager.networkShutdown("disconnect.kicked", new Object[0]); + disconnected = true; + mc.changeWorld1(null); + mc.displayGuiScreen(new GuiConnectFailed("disconnect.disconnected", "disconnect.genericReason", new Object[] { + packet255kickdisconnect.reason + })); + } + + public void handleErrorMessage(String s, Object aobj[]) + { + if(disconnected) + { + return; + } else + { + disconnected = true; + mc.changeWorld1(null); + mc.displayGuiScreen(new GuiConnectFailed("disconnect.lost", s, aobj)); + return; + } + } + + public void addToSendQueue(Packet packet) + { + if(disconnected) + { + return; + } else + { + netManager.addToSendQueue(packet); + return; + } + } + + public void handleCollect(Packet22Collect packet22collect) + { + Entity entity = getEntityByID(packet22collect.collectedEntityId); + Object obj = (EntityLiving)getEntityByID(packet22collect.collectorEntityId); + if(obj == null) + { + obj = mc.thePlayer; + } + if(entity != null) + { + worldClient.playSoundAtEntity(entity, "random.pop", 0.2F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + mc.effectRenderer.addEffect(new EntityPickupFX(mc.theWorld, entity, ((Entity) (obj)), -0.5F)); + worldClient.removeEntityFromWorld(packet22collect.collectedEntityId); + } + } + + public void handleChat(Packet3Chat packet3chat) + { + mc.ingameGUI.addChatMessage(packet3chat.message); + } + + public void handleArmAnimation(Packet18ArmAnimation packet18armanimation) + { + Entity entity = getEntityByID(packet18armanimation.entityId); + if(entity == null) + { + return; + } + if(packet18armanimation.animate == 1) + { + EntityPlayer entityplayer = (EntityPlayer)entity; + entityplayer.swingItem(); + } else + if(packet18armanimation.animate == 2) + { + entity.performHurtAnimation(); + } else + if(packet18armanimation.animate == 3) + { + EntityPlayer entityplayer1 = (EntityPlayer)entity; + entityplayer1.func_22056_a(false, false); + } else + if(packet18armanimation.animate == 4) + { + EntityPlayer entityplayer2 = (EntityPlayer)entity; + entityplayer2.func_6420_o(); + } + } + + public void func_22186_a(Packet17Sleep packet17sleep) + { + Entity entity = getEntityByID(packet17sleep.field_22045_a); + if(entity == null) + { + return; + } + if(packet17sleep.field_22046_e == 0) + { + EntityPlayer entityplayer = (EntityPlayer)entity; + entityplayer.func_22053_b(packet17sleep.field_22044_b, packet17sleep.field_22048_c, packet17sleep.field_22047_d); + } + } + + public void handleHandshake(Packet2Handshake packet2handshake) + { + if(packet2handshake.username.equals("-")) + { + addToSendQueue(new Packet1Login(mc.session.username, "Password", 9)); + } else + { + try + { + URL url = new URL((new StringBuilder()).append("http://www.minecraft.net/game/joinserver.jsp?user=").append(mc.session.username).append("&sessionId=").append(mc.session.sessionId).append("&serverId=").append(packet2handshake.username).toString()); + BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(url.openStream())); + String s = bufferedreader.readLine(); + bufferedreader.close(); + if(s.equalsIgnoreCase("ok")) + { + addToSendQueue(new Packet1Login(mc.session.username, "Password", 9)); + } else + { + netManager.networkShutdown("disconnect.loginFailedInfo", new Object[] { + s + }); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + netManager.networkShutdown("disconnect.genericReason", new Object[] { + (new StringBuilder()).append("Internal client error: ").append(exception.toString()).toString() + }); + } + } + } + + public void disconnect() + { + disconnected = true; + netManager.networkShutdown("disconnect.closed", new Object[0]); + } + + public void handleMobSpawn(Packet24MobSpawn packet24mobspawn) + { + double d = (double)packet24mobspawn.xPosition / 32D; + double d1 = (double)packet24mobspawn.yPosition / 32D; + double d2 = (double)packet24mobspawn.zPosition / 32D; + float f = (float)(packet24mobspawn.yaw * 360) / 256F; + float f1 = (float)(packet24mobspawn.pitch * 360) / 256F; + EntityLiving entityliving = (EntityLiving)EntityList.createEntity(packet24mobspawn.type, mc.theWorld); + entityliving.serverPosX = packet24mobspawn.xPosition; + entityliving.serverPosY = packet24mobspawn.yPosition; + entityliving.serverPosZ = packet24mobspawn.zPosition; + entityliving.entityId = packet24mobspawn.entityId; + entityliving.setPositionAndRotation(d, d1, d2, f, f1); + entityliving.field_9343_G = true; + worldClient.func_712_a(packet24mobspawn.entityId, entityliving); + java.util.List list = packet24mobspawn.getMetadata(); + if(list != null) + { + entityliving.getDataWatcher().updateWatchedObjectsFromList(list); + } + } + + public void handleUpdateTime(Packet4UpdateTime packet4updatetime) + { + mc.theWorld.setWorldTime(packet4updatetime.time); + } + + public void handleSpawnPosition(Packet6SpawnPosition packet6spawnposition) + { + worldClient.func_22143_a(new ChunkCoordinates(packet6spawnposition.xPosition, packet6spawnposition.yPosition, packet6spawnposition.zPosition)); + } + + public void func_6497_a(Packet39 packet39) + { + Object obj = getEntityByID(packet39.entityId); + Entity entity = getEntityByID(packet39.vehicleEntityId); + if(packet39.entityId == mc.thePlayer.entityId) + { + obj = mc.thePlayer; + } + if(obj == null) + { + return; + } else + { + ((Entity) (obj)).mountEntity(entity); + return; + } + } + + public void func_9447_a(Packet38 packet38) + { + Entity entity = getEntityByID(packet38.entityId); + if(entity != null) + { + entity.handleHealthUpdate(packet38.entityStatus); + } + } + + private Entity getEntityByID(int i) + { + if(i == mc.thePlayer.entityId) + { + return mc.thePlayer; + } else + { + return worldClient.func_709_b(i); + } + } + + public void handleHealth(Packet8 packet8) + { + mc.thePlayer.setHealth(packet8.healthMP); + } + + public void func_9448_a(Packet9 packet9) + { + mc.respawn(); + } + + public void func_12245_a(Packet60 packet60) + { + Explosion explosion = new Explosion(mc.theWorld, null, packet60.explosionX, packet60.explosionY, packet60.explosionZ, packet60.explosionSize); + explosion.destroyedBlockPositions = packet60.destroyedBlockPositions; + explosion.func_12247_b(); + } + + public void func_20087_a(Packet100 packet100) + { + if(packet100.inventoryType == 0) + { + InventoryBasic inventorybasic = new InventoryBasic(packet100.windowTitle, packet100.slotsCount); + mc.thePlayer.displayGUIChest(inventorybasic); + mc.thePlayer.craftingInventory.windowId = packet100.windowId; + } else + if(packet100.inventoryType == 2) + { + TileEntityFurnace tileentityfurnace = new TileEntityFurnace(); + mc.thePlayer.displayGUIFurnace(tileentityfurnace); + mc.thePlayer.craftingInventory.windowId = packet100.windowId; + } else + if(packet100.inventoryType == 3) + { + TileEntityDispenser tileentitydispenser = new TileEntityDispenser(); + mc.thePlayer.displayGUIDispenser(tileentitydispenser); + mc.thePlayer.craftingInventory.windowId = packet100.windowId; + } else + if(packet100.inventoryType == 1) + { + EntityPlayerSP entityplayersp = mc.thePlayer; + mc.thePlayer.displayWorkbenchGUI(MathHelper.floor_double(((EntityPlayer) (entityplayersp)).posX), MathHelper.floor_double(((EntityPlayer) (entityplayersp)).posY), MathHelper.floor_double(((EntityPlayer) (entityplayersp)).posZ)); + mc.thePlayer.craftingInventory.windowId = packet100.windowId; + } + } + + public void func_20088_a(Packet103 packet103) + { + if(packet103.windowId == -1) + { + mc.thePlayer.inventory.setItemStack(packet103.myItemStack); + } else + if(packet103.windowId == 0) + { + mc.thePlayer.inventorySlots.putStackInSlot(packet103.itemSlot, packet103.myItemStack); + } else + if(packet103.windowId == mc.thePlayer.craftingInventory.windowId) + { + mc.thePlayer.craftingInventory.putStackInSlot(packet103.itemSlot, packet103.myItemStack); + } + } + + public void func_20089_a(Packet106 packet106) + { + CraftingInventoryCB craftinginventorycb = null; + if(packet106.windowId == 0) + { + craftinginventorycb = mc.thePlayer.inventorySlots; + } else + if(packet106.windowId == mc.thePlayer.craftingInventory.windowId) + { + craftinginventorycb = mc.thePlayer.craftingInventory; + } + if(craftinginventorycb != null) + { + if(packet106.field_20030_c) + { + craftinginventorycb.func_20113_a(packet106.field_20028_b); + } else + { + craftinginventorycb.func_20110_b(packet106.field_20028_b); + addToSendQueue(new Packet106(packet106.windowId, packet106.field_20028_b, true)); + } + } + } + + public void func_20094_a(Packet104 packet104) + { + if(packet104.windowId == 0) + { + mc.thePlayer.inventorySlots.putStacksInSlots(packet104.itemStack); + } else + if(packet104.windowId == mc.thePlayer.craftingInventory.windowId) + { + mc.thePlayer.craftingInventory.putStacksInSlots(packet104.itemStack); + } + } + + public void func_20093_a(Packet130 packet130) + { + if(mc.theWorld.blockExists(packet130.xPosition, packet130.yPosition, packet130.zPosition)) + { + TileEntity tileentity = mc.theWorld.getBlockTileEntity(packet130.xPosition, packet130.yPosition, packet130.zPosition); + if(tileentity instanceof TileEntitySign) + { + TileEntitySign tileentitysign = (TileEntitySign)tileentity; + for(int i = 0; i < 4; i++) + { + tileentitysign.signText[i] = packet130.signLines[i]; + } + + tileentitysign.onInventoryChanged(); + } + } + } + + public void func_20090_a(Packet105 packet105) + { + registerPacket(packet105); + if(mc.thePlayer.craftingInventory != null && mc.thePlayer.craftingInventory.windowId == packet105.windowId) + { + mc.thePlayer.craftingInventory.func_20112_a(packet105.progressBar, packet105.progressBarValue); + } + } + + public void handlePlayerInventory(Packet5PlayerInventory packet5playerinventory) + { + Entity entity = getEntityByID(packet5playerinventory.entityID); + if(entity != null) + { + entity.outfitWithItem(packet5playerinventory.slot, packet5playerinventory.itemID, packet5playerinventory.itemDamage); + } + } + + public void func_20092_a(Packet101 packet101) + { + mc.thePlayer.func_20059_m(); + } + + public void func_21145_a(Packet54 packet54) + { + mc.theWorld.playNoteAt(packet54.xLocation, packet54.yLocation, packet54.zLocation, packet54.instrumentType, packet54.pitch); + } + + private boolean disconnected; + private NetworkManager netManager; + public String field_1209_a; + private Minecraft mc; + private WorldClient worldClient; + private boolean field_1210_g; + Random rand; +} diff --git a/src/main/java/net/minecraft/src/NetHandler.java b/src/main/java/net/minecraft/src/NetHandler.java new file mode 100644 index 0000000..3fa067e --- /dev/null +++ b/src/main/java/net/minecraft/src/NetHandler.java @@ -0,0 +1,243 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class NetHandler +{ + + public NetHandler() + { + } + + public void handleMapChunk(Packet51MapChunk packet51mapchunk) + { + } + + public void registerPacket(Packet packet) + { + } + + public void handleErrorMessage(String s, Object aobj[]) + { + } + + public void handleKickDisconnect(Packet255KickDisconnect packet255kickdisconnect) + { + registerPacket(packet255kickdisconnect); + } + + public void handleLogin(Packet1Login packet1login) + { + registerPacket(packet1login); + } + + public void handleFlying(Packet10Flying packet10flying) + { + registerPacket(packet10flying); + } + + public void handleMultiBlockChange(Packet52MultiBlockChange packet52multiblockchange) + { + registerPacket(packet52multiblockchange); + } + + public void handleBlockDig(Packet14BlockDig packet14blockdig) + { + registerPacket(packet14blockdig); + } + + public void handleBlockChange(Packet53BlockChange packet53blockchange) + { + registerPacket(packet53blockchange); + } + + public void handlePreChunk(Packet50PreChunk packet50prechunk) + { + registerPacket(packet50prechunk); + } + + public void handleNamedEntitySpawn(Packet20NamedEntitySpawn packet20namedentityspawn) + { + registerPacket(packet20namedentityspawn); + } + + public void handleEntity(Packet30Entity packet30entity) + { + registerPacket(packet30entity); + } + + public void handleEntityTeleport(Packet34EntityTeleport packet34entityteleport) + { + registerPacket(packet34entityteleport); + } + + public void handlePlace(Packet15Place packet15place) + { + registerPacket(packet15place); + } + + public void handleBlockItemSwitch(Packet16BlockItemSwitch packet16blockitemswitch) + { + registerPacket(packet16blockitemswitch); + } + + public void handleDestroyEntity(Packet29DestroyEntity packet29destroyentity) + { + registerPacket(packet29destroyentity); + } + + public void handlePickupSpawn(Packet21PickupSpawn packet21pickupspawn) + { + registerPacket(packet21pickupspawn); + } + + public void handleCollect(Packet22Collect packet22collect) + { + registerPacket(packet22collect); + } + + public void handleChat(Packet3Chat packet3chat) + { + registerPacket(packet3chat); + } + + public void handleVehicleSpawn(Packet23VehicleSpawn packet23vehiclespawn) + { + registerPacket(packet23vehiclespawn); + } + + public void handleArmAnimation(Packet18ArmAnimation packet18armanimation) + { + registerPacket(packet18armanimation); + } + + public void func_21147_a(Packet19 packet19) + { + registerPacket(packet19); + } + + public void handleHandshake(Packet2Handshake packet2handshake) + { + registerPacket(packet2handshake); + } + + public void handleMobSpawn(Packet24MobSpawn packet24mobspawn) + { + registerPacket(packet24mobspawn); + } + + public void handleUpdateTime(Packet4UpdateTime packet4updatetime) + { + registerPacket(packet4updatetime); + } + + public void handleSpawnPosition(Packet6SpawnPosition packet6spawnposition) + { + registerPacket(packet6spawnposition); + } + + public void func_6498_a(Packet28 packet28) + { + registerPacket(packet28); + } + + public void func_21148_a(Packet40 packet40) + { + registerPacket(packet40); + } + + public void func_6497_a(Packet39 packet39) + { + registerPacket(packet39); + } + + public void func_6499_a(Packet7 packet7) + { + registerPacket(packet7); + } + + public void func_9447_a(Packet38 packet38) + { + registerPacket(packet38); + } + + public void handleHealth(Packet8 packet8) + { + registerPacket(packet8); + } + + public void func_9448_a(Packet9 packet9) + { + registerPacket(packet9); + } + + public void func_12245_a(Packet60 packet60) + { + registerPacket(packet60); + } + + public void func_20087_a(Packet100 packet100) + { + registerPacket(packet100); + } + + public void func_20092_a(Packet101 packet101) + { + registerPacket(packet101); + } + + public void func_20091_a(Packet102 packet102) + { + registerPacket(packet102); + } + + public void func_20088_a(Packet103 packet103) + { + registerPacket(packet103); + } + + public void func_20094_a(Packet104 packet104) + { + registerPacket(packet104); + } + + public void func_20093_a(Packet130 packet130) + { + registerPacket(packet130); + } + + public void func_20090_a(Packet105 packet105) + { + registerPacket(packet105); + } + + public void handlePlayerInventory(Packet5PlayerInventory packet5playerinventory) + { + registerPacket(packet5playerinventory); + } + + public void func_20089_a(Packet106 packet106) + { + registerPacket(packet106); + } + + public void func_21146_a(Packet25 packet25) + { + registerPacket(packet25); + } + + public void func_21145_a(Packet54 packet54) + { + registerPacket(packet54); + } + + public void func_22186_a(Packet17Sleep packet17sleep) + { + } + + public void func_22185_a(Packet27 packet27) + { + } +} diff --git a/src/main/java/net/minecraft/src/NetworkManager.java b/src/main/java/net/minecraft/src/NetworkManager.java new file mode 100644 index 0000000..2933f9f --- /dev/null +++ b/src/main/java/net/minecraft/src/NetworkManager.java @@ -0,0 +1,251 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.net.Socket; +import java.net.SocketAddress; +import java.util.*; + +import net.lax1dude.eaglercraft.compat.UnexpectedThrowable; + +public class NetworkManager +{ + + public NetworkManager(Socket socket, String s, NetHandler nethandler) + { + sendQueueLock = new Object(); + isRunning = true; + readPackets = Collections.synchronizedList(new ArrayList()); + dataPackets = Collections.synchronizedList(new ArrayList()); + chunkDataPackets = Collections.synchronizedList(new ArrayList()); + isServerTerminating = false; + isTerminating = false; + terminationReason = ""; + timeSinceLastRead = 0; + sendQueueByteLength = 0; + chunkDataSendCounter = 0; + field_20100_w = 50; + networkSocket = socket; + remoteSocketAddress = socket.getRemoteSocketAddress(); + netHandler = nethandler; + try { + socket.setTrafficClass(24); + socketInputStream = new DataInputStream(socket.getInputStream()); + socketOutputStream = new DataOutputStream(socket.getOutputStream()); + }catch(IOException e) { + throw new UnexpectedThrowable(e); + } + readThread = new NetworkReaderThread(this, (new StringBuilder()).append(s).append(" read thread").toString()); + writeThread = new NetworkWriterThread(this, (new StringBuilder()).append(s).append(" write thread").toString()); + readThread.start(); + writeThread.start(); + } + + public void addToSendQueue(Packet packet) + { + if(isServerTerminating) + { + return; + } + synchronized(sendQueueLock) + { + sendQueueByteLength += packet.getPacketSize() + 1; + if(packet.isChunkDataPacket) + { + chunkDataPackets.add(packet); + } else + { + dataPackets.add(packet); + } + } + } + + private void sendPacket() + { + try + { + boolean flag = true; + if(!dataPackets.isEmpty() && (chunkDataSendCounter == 0 || System.currentTimeMillis() - ((Packet)dataPackets.get(0)).creationTimeMillis >= (long)chunkDataSendCounter)) + { + flag = false; + Packet packet; + synchronized(sendQueueLock) + { + packet = (Packet)dataPackets.remove(0); + sendQueueByteLength -= packet.getPacketSize() + 1; + } + Packet.writePacket(packet, socketOutputStream); + } + if((flag || field_20100_w-- <= 0) && !chunkDataPackets.isEmpty() && (chunkDataSendCounter == 0 || System.currentTimeMillis() - ((Packet)chunkDataPackets.get(0)).creationTimeMillis >= (long)chunkDataSendCounter)) + { + flag = false; + Packet packet1; + synchronized(sendQueueLock) + { + packet1 = (Packet)chunkDataPackets.remove(0); + sendQueueByteLength -= packet1.getPacketSize() + 1; + } + Packet.writePacket(packet1, socketOutputStream); + field_20100_w = 50; + } + if(flag) + { + Thread.sleep(10L); + } + } + catch(InterruptedException interruptedexception) { } + catch(Exception exception) + { + if(!isTerminating) + { + onNetworkError(exception); + } + } + } + + private void readPacket() + { + try + { + Packet packet = Packet.readPacket(socketInputStream); + if(packet != null) + { + readPackets.add(packet); + } else + { + networkShutdown("disconnect.endOfStream", new Object[0]); + } + } + catch(Exception exception) + { + if(!isTerminating) + { + onNetworkError(exception); + } + } + } + + private void onNetworkError(Exception exception) + { + exception.printStackTrace(); + networkShutdown("disconnect.genericReason", new Object[] { + (new StringBuilder()).append("Internal exception: ").append(exception.toString()).toString() + }); + } + + public void networkShutdown(String s, Object aobj[]) + { + if(!isRunning) + { + return; + } + isTerminating = true; + terminationReason = s; + field_20101_t = aobj; + (new NetworkMasterThread(this)).start(); + isRunning = false; + try + { + socketInputStream.close(); + socketInputStream = null; + } + catch(Throwable throwable) { } + try + { + socketOutputStream.close(); + socketOutputStream = null; + } + catch(Throwable throwable1) { } + try + { + networkSocket.close(); + networkSocket = null; + } + catch(Throwable throwable2) { } + } + + public void processReadPackets() + { + if(sendQueueByteLength > 0x100000) + { + networkShutdown("disconnect.overflow", new Object[0]); + } + if(readPackets.isEmpty()) + { + if(timeSinceLastRead++ == 1200) + { + networkShutdown("disconnect.timeout", new Object[0]); + } + } else + { + timeSinceLastRead = 0; + } + Packet packet; + for(int i = 100; !readPackets.isEmpty() && i-- >= 0; packet.processPacket(netHandler)) + { + packet = (Packet)readPackets.remove(0); + } + + if(isTerminating && readPackets.isEmpty()) + { + netHandler.handleErrorMessage(terminationReason, field_20101_t); + } + } + + static boolean isRunning(NetworkManager networkmanager) + { + return networkmanager.isRunning; + } + + static boolean isServerTerminating(NetworkManager networkmanager) + { + return networkmanager.isServerTerminating; + } + + static void readNetworkPacket(NetworkManager networkmanager) + { + networkmanager.readPacket(); + } + + static void sendNetworkPacket(NetworkManager networkmanager) + { + networkmanager.sendPacket(); + } + + static Thread getReadThread(NetworkManager networkmanager) + { + return networkmanager.readThread; + } + + static Thread getWriteThread(NetworkManager networkmanager) + { + return networkmanager.writeThread; + } + + public static final Object threadSyncObject = new Object(); + public static int numReadThreads; + public static int numWriteThreads; + private Object sendQueueLock; + private Socket networkSocket; + private final SocketAddress remoteSocketAddress; + private DataInputStream socketInputStream; + private DataOutputStream socketOutputStream; + private boolean isRunning; + private List readPackets; + private List dataPackets; + private List chunkDataPackets; + private NetHandler netHandler; + private boolean isServerTerminating; + private Thread writeThread; + private Thread readThread; + private boolean isTerminating; + private String terminationReason; + private Object field_20101_t[]; + private int timeSinceLastRead; + private int sendQueueByteLength; + public int chunkDataSendCounter; + private int field_20100_w; + +} diff --git a/src/main/java/net/minecraft/src/NetworkMasterThread.java b/src/main/java/net/minecraft/src/NetworkMasterThread.java new file mode 100644 index 0000000..1aab9cf --- /dev/null +++ b/src/main/java/net/minecraft/src/NetworkMasterThread.java @@ -0,0 +1,44 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class NetworkMasterThread extends Thread +{ + + NetworkMasterThread(NetworkManager networkmanager) + { + netManager = networkmanager; + } + + public void run() + { + try + { + Thread.sleep(5000L); + if(NetworkManager.getReadThread(netManager).isAlive()) + { + try + { + NetworkManager.getReadThread(netManager).stop(); + } + catch(Throwable throwable) { } + } + if(NetworkManager.getWriteThread(netManager).isAlive()) + { + try + { + NetworkManager.getWriteThread(netManager).stop(); + } + catch(Throwable throwable1) { } + } + } + catch(InterruptedException interruptedexception) + { + interruptedexception.printStackTrace(); + } + } + + final NetworkManager netManager; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/NetworkReaderThread.java b/src/main/java/net/minecraft/src/NetworkReaderThread.java new file mode 100644 index 0000000..13bc9cc --- /dev/null +++ b/src/main/java/net/minecraft/src/NetworkReaderThread.java @@ -0,0 +1,38 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class NetworkReaderThread extends Thread +{ + + NetworkReaderThread(NetworkManager networkmanager, String s) + { + super(s); + netManager = networkmanager; + } + + public void run() + { + synchronized(NetworkManager.threadSyncObject) + { + NetworkManager.numReadThreads++; + } + while(NetworkManager.isRunning(netManager) && !NetworkManager.isServerTerminating(netManager)) + { + NetworkManager.readNetworkPacket(netManager); + try + { + sleep(0L); + } + catch(InterruptedException interruptedexception) { } + } + synchronized(NetworkManager.threadSyncObject) + { + NetworkManager.numReadThreads--; + } + } + + final NetworkManager netManager; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/NetworkWriterThread.java b/src/main/java/net/minecraft/src/NetworkWriterThread.java new file mode 100644 index 0000000..d4355f8 --- /dev/null +++ b/src/main/java/net/minecraft/src/NetworkWriterThread.java @@ -0,0 +1,30 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class NetworkWriterThread extends Thread +{ + + NetworkWriterThread(NetworkManager networkmanager, String s) + { + super(s); + netManager = networkmanager; + } + + public void run() + { + synchronized(NetworkManager.threadSyncObject) + { + NetworkManager.numWriteThreads++; + } + for(; NetworkManager.isRunning(netManager); NetworkManager.sendNetworkPacket(netManager)) { } + synchronized(NetworkManager.threadSyncObject) + { + NetworkManager.numWriteThreads--; + } + } + + final NetworkManager netManager; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/NextTickListEntry.java b/src/main/java/net/minecraft/src/NextTickListEntry.java new file mode 100644 index 0000000..1494fde --- /dev/null +++ b/src/main/java/net/minecraft/src/NextTickListEntry.java @@ -0,0 +1,73 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class NextTickListEntry + implements Comparable +{ + + public NextTickListEntry(int i, int j, int k, int l) + { + tickEntryID = nextTickEntryID++; + xCoord = i; + yCoord = j; + zCoord = k; + blockID = l; + } + + public boolean equals(Object obj) + { + if(obj instanceof NextTickListEntry) + { + NextTickListEntry nextticklistentry = (NextTickListEntry)obj; + return xCoord == nextticklistentry.xCoord && yCoord == nextticklistentry.yCoord && zCoord == nextticklistentry.zCoord && blockID == nextticklistentry.blockID; + } else + { + return false; + } + } + + public int hashCode() + { + return (xCoord * 128 * 1024 + zCoord * 128 + yCoord) * 256 + blockID; + } + + public NextTickListEntry setScheduledTime(long l) + { + scheduledTime = l; + return this; + } + + public int comparer(NextTickListEntry nextticklistentry) + { + if(scheduledTime < nextticklistentry.scheduledTime) + { + return -1; + } + if(scheduledTime > nextticklistentry.scheduledTime) + { + return 1; + } + if(tickEntryID < nextticklistentry.tickEntryID) + { + return -1; + } + return tickEntryID <= nextticklistentry.tickEntryID ? 0 : 1; + } + + public int compareTo(Object obj) + { + return comparer((NextTickListEntry)obj); + } + + private static long nextTickEntryID = 0L; + public int xCoord; + public int yCoord; + public int zCoord; + public int blockID; + public long scheduledTime; + private long tickEntryID; + +} diff --git a/src/main/java/net/minecraft/src/NibbleArray.java b/src/main/java/net/minecraft/src/NibbleArray.java new file mode 100644 index 0000000..e9c8c4a --- /dev/null +++ b/src/main/java/net/minecraft/src/NibbleArray.java @@ -0,0 +1,54 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class NibbleArray +{ + + public NibbleArray(int i) + { + data = new byte[i >> 1]; + } + + public NibbleArray(byte abyte0[]) + { + data = abyte0; + } + + public int getNibble(int i, int j, int k) + { + int l = i << 11 | k << 7 | j; + int i1 = l >> 1; + int j1 = l & 1; + if(j1 == 0) + { + return data[i1] & 0xf; + } else + { + return data[i1] >> 4 & 0xf; + } + } + + public void setNibble(int i, int j, int k, int l) + { + int i1 = i << 11 | k << 7 | j; + int j1 = i1 >> 1; + int k1 = i1 & 1; + if(k1 == 0) + { + data[j1] = (byte)(data[j1] & 0xf0 | l & 0xf); + } else + { + data[j1] = (byte)(data[j1] & 0xf | (l & 0xf) << 4); + } + } + + public boolean isValid() + { + return data != null; + } + + public final byte data[]; +} diff --git a/src/main/java/net/minecraft/src/NoiseGenerator.java b/src/main/java/net/minecraft/src/NoiseGenerator.java new file mode 100644 index 0000000..1bc8825 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGenerator.java @@ -0,0 +1,13 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public abstract class NoiseGenerator +{ + + public NoiseGenerator() + { + } +} diff --git a/src/main/java/net/minecraft/src/NoiseGenerator2.java b/src/main/java/net/minecraft/src/NoiseGenerator2.java new file mode 100644 index 0000000..bb957a1 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGenerator2.java @@ -0,0 +1,157 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class NoiseGenerator2 +{ + + public NoiseGenerator2() + { + this(new Random()); + } + + public NoiseGenerator2(Random random) + { + field_4295_e = new int[512]; + field_4292_a = random.nextDouble() * 256D; + field_4291_b = random.nextDouble() * 256D; + field_4297_c = random.nextDouble() * 256D; + for(int i = 0; i < 256; i++) + { + field_4295_e[i] = i; + } + + for(int j = 0; j < 256; j++) + { + int k = random.nextInt(256 - j) + j; + int l = field_4295_e[j]; + field_4295_e[j] = field_4295_e[k]; + field_4295_e[k] = l; + field_4295_e[j + 256] = field_4295_e[j]; + } + + } + + private static int wrap(double d) + { + return d <= 0.0D ? (int)d - 1 : (int)d; + } + + private static double func_4156_a(int ai[], double d, double d1) + { + return (double)ai[0] * d + (double)ai[1] * d1; + } + + public void func_4157_a(double ad[], double d, double d1, int i, int j, + double d2, double d3, double d4) + { + int k = 0; + for(int l = 0; l < i; l++) + { + double d5 = (d + (double)l) * d2 + field_4292_a; + for(int i1 = 0; i1 < j; i1++) + { + double d6 = (d1 + (double)i1) * d3 + field_4291_b; + double d10 = (d5 + d6) * field_4294_f; + int j1 = wrap(d5 + d10); + int k1 = wrap(d6 + d10); + double d11 = (double)(j1 + k1) * field_4293_g; + double d12 = (double)j1 - d11; + double d13 = (double)k1 - d11; + double d14 = d5 - d12; + double d15 = d6 - d13; + int l1; + int i2; + if(d14 > d15) + { + l1 = 1; + i2 = 0; + } else + { + l1 = 0; + i2 = 1; + } + double d16 = (d14 - (double)l1) + field_4293_g; + double d17 = (d15 - (double)i2) + field_4293_g; + double d18 = (d14 - 1.0D) + 2D * field_4293_g; + double d19 = (d15 - 1.0D) + 2D * field_4293_g; + int j2 = j1 & 0xff; + int k2 = k1 & 0xff; + int l2 = field_4295_e[j2 + field_4295_e[k2]] % 12; + int i3 = field_4295_e[j2 + l1 + field_4295_e[k2 + i2]] % 12; + int j3 = field_4295_e[j2 + 1 + field_4295_e[k2 + 1]] % 12; + double d20 = 0.5D - d14 * d14 - d15 * d15; + double d7; + if(d20 < 0.0D) + { + d7 = 0.0D; + } else + { + d20 *= d20; + d7 = d20 * d20 * func_4156_a(field_4296_d[l2], d14, d15); + } + double d21 = 0.5D - d16 * d16 - d17 * d17; + double d8; + if(d21 < 0.0D) + { + d8 = 0.0D; + } else + { + d21 *= d21; + d8 = d21 * d21 * func_4156_a(field_4296_d[i3], d16, d17); + } + double d22 = 0.5D - d18 * d18 - d19 * d19; + double d9; + if(d22 < 0.0D) + { + d9 = 0.0D; + } else + { + d22 *= d22; + d9 = d22 * d22 * func_4156_a(field_4296_d[j3], d18, d19); + } + ad[k++] += 70D * (d7 + d8 + d9) * d4; + } + + } + + } + + private static int field_4296_d[][] = { + { + 1, 1, 0 + }, { + -1, 1, 0 + }, { + 1, -1, 0 + }, { + -1, -1, 0 + }, { + 1, 0, 1 + }, { + -1, 0, 1 + }, { + 1, 0, -1 + }, { + -1, 0, -1 + }, { + 0, 1, 1 + }, { + 0, -1, 1 + }, { + 0, 1, -1 + }, { + 0, -1, -1 + } + }; + private int field_4295_e[]; + public double field_4292_a; + public double field_4291_b; + public double field_4297_c; + private static final double field_4294_f = 0.5D * (Math.sqrt(3D) - 1.0D); + private static final double field_4293_g = (3D - Math.sqrt(3D)) / 6D; + +} diff --git a/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java b/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java new file mode 100644 index 0000000..7727313 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java @@ -0,0 +1,68 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class NoiseGeneratorOctaves extends NoiseGenerator +{ + + public NoiseGeneratorOctaves(Random random, int i) + { + field_1191_b = i; + generatorCollection = new NoiseGeneratorPerlin[i]; + for(int j = 0; j < i; j++) + { + generatorCollection[j] = new NoiseGeneratorPerlin(random); + } + + } + + public double func_806_a(double d, double d1) + { + double d2 = 0.0D; + double d3 = 1.0D; + for(int i = 0; i < field_1191_b; i++) + { + d2 += generatorCollection[i].func_801_a(d * d3, d1 * d3) / d3; + d3 /= 2D; + } + + return d2; + } + + public double[] generateNoiseOctaves(double ad[], double d, double d1, double d2, + int i, int j, int k, double d3, double d4, + double d5) + { + if(ad == null) + { + ad = new double[i * j * k]; + } else + { + for(int l = 0; l < ad.length; l++) + { + ad[l] = 0.0D; + } + + } + double d6 = 1.0D; + for(int i1 = 0; i1 < field_1191_b; i1++) + { + generatorCollection[i1].func_805_a(ad, d, d1, d2, i, j, k, d3 * d6, d4 * d6, d5 * d6, d6); + d6 /= 2D; + } + + return ad; + } + + public double[] func_4109_a(double ad[], int i, int j, int k, int l, double d, + double d1, double d2) + { + return generateNoiseOctaves(ad, i, 10D, j, k, 1, l, d, 1.0D, d1); + } + + private NoiseGeneratorPerlin generatorCollection[]; + private int field_1191_b; +} diff --git a/src/main/java/net/minecraft/src/NoiseGeneratorOctaves2.java b/src/main/java/net/minecraft/src/NoiseGeneratorOctaves2.java new file mode 100644 index 0000000..7f3b8a1 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGeneratorOctaves2.java @@ -0,0 +1,58 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class NoiseGeneratorOctaves2 extends NoiseGenerator +{ + + public NoiseGeneratorOctaves2(Random random, int i) + { + field_4233_b = i; + field_4234_a = new NoiseGenerator2[i]; + for(int j = 0; j < i; j++) + { + field_4234_a[j] = new NoiseGenerator2(random); + } + + } + + public double[] func_4112_a(double ad[], double d, double d1, int i, int j, + double d2, double d3, double d4) + { + return func_4111_a(ad, d, d1, i, j, d2, d3, d4, 0.5D); + } + + public double[] func_4111_a(double ad[], double d, double d1, int i, int j, + double d2, double d3, double d4, double d5) + { + d2 /= 1.5D; + d3 /= 1.5D; + if(ad == null || ad.length < i * j) + { + ad = new double[i * j]; + } else + { + for(int k = 0; k < ad.length; k++) + { + ad[k] = 0.0D; + } + + } + double d6 = 1.0D; + double d7 = 1.0D; + for(int l = 0; l < field_4233_b; l++) + { + field_4234_a[l].func_4157_a(ad, d, d1, i, j, d2 * d7, d3 * d7, 0.55000000000000004D / d6); + d7 *= d4; + d6 *= d5; + } + + return ad; + } + + private NoiseGenerator2 field_4234_a[]; + private int field_4233_b; +} diff --git a/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java b/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java new file mode 100644 index 0000000..cb8e9b1 --- /dev/null +++ b/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java @@ -0,0 +1,228 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class NoiseGeneratorPerlin extends NoiseGenerator +{ + + public NoiseGeneratorPerlin() + { + this(new Random()); + } + + public NoiseGeneratorPerlin(Random random) + { + permutations = new int[512]; + xCoord = random.nextDouble() * 256D; + yCoord = random.nextDouble() * 256D; + zCoord = random.nextDouble() * 256D; + for(int i = 0; i < 256; i++) + { + permutations[i] = i; + } + + for(int j = 0; j < 256; j++) + { + int k = random.nextInt(256 - j) + j; + int l = permutations[j]; + permutations[j] = permutations[k]; + permutations[k] = l; + permutations[j + 256] = permutations[j]; + } + + } + + public double generateNoise(double d, double d1, double d2) + { + double d3 = d + xCoord; + double d4 = d1 + yCoord; + double d5 = d2 + zCoord; + int i = (int)d3; + int j = (int)d4; + int k = (int)d5; + if(d3 < (double)i) + { + i--; + } + if(d4 < (double)j) + { + j--; + } + if(d5 < (double)k) + { + k--; + } + int l = i & 0xff; + int i1 = j & 0xff; + int j1 = k & 0xff; + d3 -= i; + d4 -= j; + d5 -= k; + double d6 = d3 * d3 * d3 * (d3 * (d3 * 6D - 15D) + 10D); + double d7 = d4 * d4 * d4 * (d4 * (d4 * 6D - 15D) + 10D); + double d8 = d5 * d5 * d5 * (d5 * (d5 * 6D - 15D) + 10D); + int k1 = permutations[l] + i1; + int l1 = permutations[k1] + j1; + int i2 = permutations[k1 + 1] + j1; + int j2 = permutations[l + 1] + i1; + int k2 = permutations[j2] + j1; + int l2 = permutations[j2 + 1] + j1; + return lerp(d8, lerp(d7, lerp(d6, grad(permutations[l1], d3, d4, d5), grad(permutations[k2], d3 - 1.0D, d4, d5)), lerp(d6, grad(permutations[i2], d3, d4 - 1.0D, d5), grad(permutations[l2], d3 - 1.0D, d4 - 1.0D, d5))), lerp(d7, lerp(d6, grad(permutations[l1 + 1], d3, d4, d5 - 1.0D), grad(permutations[k2 + 1], d3 - 1.0D, d4, d5 - 1.0D)), lerp(d6, grad(permutations[i2 + 1], d3, d4 - 1.0D, d5 - 1.0D), grad(permutations[l2 + 1], d3 - 1.0D, d4 - 1.0D, d5 - 1.0D)))); + } + + public final double lerp(double d, double d1, double d2) + { + return d1 + d * (d2 - d1); + } + + public final double func_4110_a(int i, double d, double d1) + { + int j = i & 0xf; + double d2 = (double)(1 - ((j & 8) >> 3)) * d; + double d3 = j >= 4 ? j != 12 && j != 14 ? d1 : d : 0.0D; + return ((j & 1) != 0 ? -d2 : d2) + ((j & 2) != 0 ? -d3 : d3); + } + + public final double grad(int i, double d, double d1, double d2) + { + int j = i & 0xf; + double d3 = j >= 8 ? d1 : d; + double d4 = j >= 4 ? j != 12 && j != 14 ? d2 : d : d1; + return ((j & 1) != 0 ? -d3 : d3) + ((j & 2) != 0 ? -d4 : d4); + } + + public double func_801_a(double d, double d1) + { + return generateNoise(d, d1, 0.0D); + } + + public void func_805_a(double ad[], double d, double d1, double d2, + int i, int j, int k, double d3, double d4, + double d5, double d6) + { + if(j == 1) + { + boolean flag = false; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + double d8 = 0.0D; + double d10 = 0.0D; + int j3 = 0; + double d12 = 1.0D / d6; + for(int i4 = 0; i4 < i; i4++) + { + double d14 = (d + (double)i4) * d3 + xCoord; + int j4 = (int)d14; + if(d14 < (double)j4) + { + j4--; + } + int k4 = j4 & 0xff; + d14 -= j4; + double d17 = d14 * d14 * d14 * (d14 * (d14 * 6D - 15D) + 10D); + for(int l4 = 0; l4 < k; l4++) + { + double d19 = (d2 + (double)l4) * d5 + zCoord; + int j5 = (int)d19; + if(d19 < (double)j5) + { + j5--; + } + int l5 = j5 & 0xff; + d19 -= j5; + double d21 = d19 * d19 * d19 * (d19 * (d19 * 6D - 15D) + 10D); + int l = permutations[k4] + 0; + int j1 = permutations[l] + l5; + int k1 = permutations[k4 + 1] + 0; + int l1 = permutations[k1] + l5; + double d9 = lerp(d17, func_4110_a(permutations[j1], d14, d19), grad(permutations[l1], d14 - 1.0D, 0.0D, d19)); + double d11 = lerp(d17, grad(permutations[j1 + 1], d14, 0.0D, d19 - 1.0D), grad(permutations[l1 + 1], d14 - 1.0D, 0.0D, d19 - 1.0D)); + double d23 = lerp(d21, d9, d11); + ad[j3++] += d23 * d12; + } + + } + + return; + } + int i1 = 0; + double d7 = 1.0D / d6; + int i2 = -1; + boolean flag4 = false; + boolean flag5 = false; + boolean flag6 = false; + boolean flag7 = false; + boolean flag8 = false; + boolean flag9 = false; + double d13 = 0.0D; + double d15 = 0.0D; + double d16 = 0.0D; + double d18 = 0.0D; + for(int i5 = 0; i5 < i; i5++) + { + double d20 = (d + (double)i5) * d3 + xCoord; + int k5 = (int)d20; + if(d20 < (double)k5) + { + k5--; + } + int i6 = k5 & 0xff; + d20 -= k5; + double d22 = d20 * d20 * d20 * (d20 * (d20 * 6D - 15D) + 10D); + for(int j6 = 0; j6 < k; j6++) + { + double d24 = (d2 + (double)j6) * d5 + zCoord; + int k6 = (int)d24; + if(d24 < (double)k6) + { + k6--; + } + int l6 = k6 & 0xff; + d24 -= k6; + double d25 = d24 * d24 * d24 * (d24 * (d24 * 6D - 15D) + 10D); + for(int i7 = 0; i7 < j; i7++) + { + double d26 = (d1 + (double)i7) * d4 + yCoord; + int j7 = (int)d26; + if(d26 < (double)j7) + { + j7--; + } + int k7 = j7 & 0xff; + d26 -= j7; + double d27 = d26 * d26 * d26 * (d26 * (d26 * 6D - 15D) + 10D); + if(i7 == 0 || k7 != i2) + { + i2 = k7; + int j2 = permutations[i6] + k7; + int k2 = permutations[j2] + l6; + int l2 = permutations[j2 + 1] + l6; + int i3 = permutations[i6 + 1] + k7; + int k3 = permutations[i3] + l6; + int l3 = permutations[i3 + 1] + l6; + d13 = lerp(d22, grad(permutations[k2], d20, d26, d24), grad(permutations[k3], d20 - 1.0D, d26, d24)); + d15 = lerp(d22, grad(permutations[l2], d20, d26 - 1.0D, d24), grad(permutations[l3], d20 - 1.0D, d26 - 1.0D, d24)); + d16 = lerp(d22, grad(permutations[k2 + 1], d20, d26, d24 - 1.0D), grad(permutations[k3 + 1], d20 - 1.0D, d26, d24 - 1.0D)); + d18 = lerp(d22, grad(permutations[l2 + 1], d20, d26 - 1.0D, d24 - 1.0D), grad(permutations[l3 + 1], d20 - 1.0D, d26 - 1.0D, d24 - 1.0D)); + } + double d28 = lerp(d27, d13, d15); + double d29 = lerp(d27, d16, d18); + double d30 = lerp(d25, d28, d29); + ad[i1++] += d30 * d7; + } + + } + + } + + } + + private int permutations[]; + public double xCoord; + public double yCoord; + public double zCoord; +} diff --git a/src/main/java/net/minecraft/src/OpenGlCapsChecker.java b/src/main/java/net/minecraft/src/OpenGlCapsChecker.java new file mode 100644 index 0000000..86442e5 --- /dev/null +++ b/src/main/java/net/minecraft/src/OpenGlCapsChecker.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.ContextCapabilities; +import org.lwjgl.opengl.GLContext; + +public class OpenGlCapsChecker +{ + + public OpenGlCapsChecker() + { + } + + public boolean checkARBOcclusion() + { + return tryCheckOcclusionCapable && GLContext.getCapabilities().GL_ARB_occlusion_query; + } + + private static boolean tryCheckOcclusionCapable = false; + +} diff --git a/src/main/java/net/minecraft/src/OsMap.java b/src/main/java/net/minecraft/src/OsMap.java new file mode 100644 index 0000000..8a64d7f --- /dev/null +++ b/src/main/java/net/minecraft/src/OsMap.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class OsMap +{ + + static final int field_1193_a[]; /* synthetic field */ + + static + { + field_1193_a = new int[EnumOS1.values().length]; + try + { + field_1193_a[EnumOS1.linux.ordinal()] = 1; + } + catch(NoSuchFieldError nosuchfielderror) { } + try + { + field_1193_a[EnumOS1.solaris.ordinal()] = 2; + } + catch(NoSuchFieldError nosuchfielderror1) { } + try + { + field_1193_a[EnumOS1.windows.ordinal()] = 3; + } + catch(NoSuchFieldError nosuchfielderror2) { } + try + { + field_1193_a[EnumOS1.macos.ordinal()] = 4; + } + catch(NoSuchFieldError nosuchfielderror3) { } + } +} diff --git a/src/main/java/net/minecraft/src/Packet.java b/src/main/java/net/minecraft/src/Packet.java new file mode 100644 index 0000000..a85bb9f --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet.java @@ -0,0 +1,186 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.HashMap; +import java.util.Map; + +public abstract class Packet +{ + + public Packet() + { + isChunkDataPacket = false; + } + + static void addIdClassMapping(int i, Class class1) + { + if(packetIdToClassMap.containsKey(Integer.valueOf(i))) + { + throw new IllegalArgumentException((new StringBuilder()).append("Duplicate packet id:").append(i).toString()); + } + if(packetClassToIdMap.containsKey(class1)) + { + throw new IllegalArgumentException((new StringBuilder()).append("Duplicate packet class:").append(class1).toString()); + } else + { + packetIdToClassMap.put(Integer.valueOf(i), class1); + packetClassToIdMap.put(class1, Integer.valueOf(i)); + return; + } + } + + public static Packet getNewPacket(int i) + { + try + { + Class class1 = (Class)packetIdToClassMap.get(Integer.valueOf(i)); + if(class1 == null) + { + return null; + } else + { + return (Packet)class1.newInstance(); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + System.out.println((new StringBuilder()).append("Skipping packet with id ").append(i).toString()); + return null; + } + + public final int getPacketId() + { + return ((Integer)packetClassToIdMap.get(getClass())).intValue(); + } + + public static Packet readPacket(DataInputStream datainputstream) throws IOException + { + int i = 0; + Packet packet = null; + datainputstream.mark(16384); + try + { + i = datainputstream.read(); + if(i == -1) + { + return null; + } + packet = getNewPacket(i); + if(packet == null) + { + throw new IOException((new StringBuilder()).append("Bad packet id ").append(i).toString()); + } + packet.readPacketData(datainputstream); + } + catch(EOFException eofexception) + { + System.out.println("Reached end of stream"); + datainputstream.reset(); + return null; + } + PacketCounter packetcounter = (PacketCounter)field_21906_c.get(Integer.valueOf(i)); + if(packetcounter == null) + { + packetcounter = new PacketCounter(null); + field_21906_c.put(Integer.valueOf(i), packetcounter); + } + packetcounter.func_22236_a(packet.getPacketSize()); + field_21905_d++; + if(field_21905_d % 1000 != 0); + return packet; + } + + public static void writePacket(Packet packet, DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.write(packet.getPacketId()); + packet.writePacketData(dataoutputstream); + } + + public abstract void readPacketData(DataInputStream datainputstream) throws IOException; + + public abstract void writePacketData(DataOutputStream dataoutputstream) throws IOException; + + public abstract void processPacket(NetHandler nethandler); + + public abstract int getPacketSize(); + + static Class _mthclass$(String s) + { + try + { + return Class.forName(s); + } + catch(ClassNotFoundException classnotfoundexception) + { + throw new NoClassDefFoundError(classnotfoundexception.getMessage()); + } + } + + private static Map packetIdToClassMap = new HashMap(); + private static Map packetClassToIdMap = new HashMap(); + public final long creationTimeMillis = System.currentTimeMillis(); + public boolean isChunkDataPacket; + private static HashMap field_21906_c = new HashMap(); + private static int field_21905_d = 0; + + static + { + addIdClassMapping(0, Packet0KeepAlive.class); + addIdClassMapping(1, Packet1Login.class); + addIdClassMapping(2, Packet2Handshake.class); + addIdClassMapping(3, Packet3Chat.class); + addIdClassMapping(4, Packet4UpdateTime.class); + addIdClassMapping(5, Packet5PlayerInventory.class); + addIdClassMapping(6, Packet6SpawnPosition.class); + addIdClassMapping(7, Packet7.class); + addIdClassMapping(8, Packet8.class); + addIdClassMapping(9, Packet9.class); + addIdClassMapping(10, Packet10Flying.class); + addIdClassMapping(11, Packet11PlayerPosition.class); + addIdClassMapping(12, Packet12PlayerLook.class); + addIdClassMapping(13, Packet13PlayerLookMove.class); + addIdClassMapping(14, Packet14BlockDig.class); + addIdClassMapping(15, Packet15Place.class); + addIdClassMapping(16, Packet16BlockItemSwitch.class); + addIdClassMapping(17, Packet17Sleep.class); + addIdClassMapping(18, Packet18ArmAnimation.class); + addIdClassMapping(19, Packet19.class); + addIdClassMapping(20, Packet20NamedEntitySpawn.class); + addIdClassMapping(21, Packet21PickupSpawn.class); + addIdClassMapping(22, Packet22Collect.class); + addIdClassMapping(23, Packet23VehicleSpawn.class); + addIdClassMapping(24, Packet24MobSpawn.class); + addIdClassMapping(25, Packet25.class); + addIdClassMapping(27, Packet27.class); + addIdClassMapping(28, Packet28.class); + addIdClassMapping(29, Packet29DestroyEntity.class); + addIdClassMapping(30, Packet30Entity.class); + addIdClassMapping(31, Packet31RelEntityMove.class); + addIdClassMapping(32, Packet32EntityLook.class); + addIdClassMapping(33, Packet33RelEntityMoveLook.class); + addIdClassMapping(34, Packet34EntityTeleport.class); + addIdClassMapping(38, Packet38.class); + addIdClassMapping(39, Packet39.class); + addIdClassMapping(40, Packet40.class); + addIdClassMapping(50, Packet50PreChunk.class); + addIdClassMapping(51, Packet51MapChunk.class); + addIdClassMapping(52, Packet52MultiBlockChange.class); + addIdClassMapping(53, Packet53BlockChange.class); + addIdClassMapping(54, Packet54.class); + addIdClassMapping(60, Packet60.class); + addIdClassMapping(100, Packet100.class); + addIdClassMapping(101, Packet101.class); + addIdClassMapping(102, Packet102.class); + addIdClassMapping(103, Packet103.class); + addIdClassMapping(104, Packet104.class); + addIdClassMapping(105, Packet105.class); + addIdClassMapping(106, Packet106.class); + addIdClassMapping(130, Packet130.class); + addIdClassMapping(255, Packet255KickDisconnect.class); + } +} diff --git a/src/main/java/net/minecraft/src/Packet0KeepAlive.java b/src/main/java/net/minecraft/src/Packet0KeepAlive.java new file mode 100644 index 0000000..18098be --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet0KeepAlive.java @@ -0,0 +1,31 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet0KeepAlive extends Packet +{ + + public Packet0KeepAlive() + { + } + + public void processPacket(NetHandler nethandler) + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + } + + public int getPacketSize() + { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/Packet100.java b/src/main/java/net/minecraft/src/Packet100.java new file mode 100644 index 0000000..bd00144 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet100.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet100 extends Packet +{ + + public Packet100() + { + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20087_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + windowId = datainputstream.readByte(); + inventoryType = datainputstream.readByte(); + windowTitle = datainputstream.readUTF(); + slotsCount = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(windowId); + dataoutputstream.writeByte(inventoryType); + dataoutputstream.writeUTF(windowTitle); + dataoutputstream.writeByte(slotsCount); + } + + public int getPacketSize() + { + return 3 + windowTitle.length(); + } + + public int windowId; + public int inventoryType; + public String windowTitle; + public int slotsCount; +} diff --git a/src/main/java/net/minecraft/src/Packet101.java b/src/main/java/net/minecraft/src/Packet101.java new file mode 100644 index 0000000..6c4f1e7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet101.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet101 extends Packet +{ + + public Packet101() + { + } + + public Packet101(int i) + { + windowId = i; + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20092_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + windowId = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(windowId); + } + + public int getPacketSize() + { + return 1; + } + + public int windowId; +} diff --git a/src/main/java/net/minecraft/src/Packet102.java b/src/main/java/net/minecraft/src/Packet102.java new file mode 100644 index 0000000..b70f141 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet102.java @@ -0,0 +1,74 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet102 extends Packet +{ + + public Packet102() + { + } + + public Packet102(int i, int j, int k, ItemStack itemstack, short word0) + { + window_Id = i; + inventorySlot = j; + mouseClick = k; + itemStack = itemstack; + action = word0; + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20091_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + window_Id = datainputstream.readByte(); + inventorySlot = datainputstream.readShort(); + mouseClick = datainputstream.readByte(); + action = datainputstream.readShort(); + short word0 = datainputstream.readShort(); + if(word0 >= 0) + { + byte byte0 = datainputstream.readByte(); + short word1 = datainputstream.readShort(); + itemStack = new ItemStack(word0, byte0, word1); + } else + { + itemStack = null; + } + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(window_Id); + dataoutputstream.writeShort(inventorySlot); + dataoutputstream.writeByte(mouseClick); + dataoutputstream.writeShort(action); + if(itemStack == null) + { + dataoutputstream.writeShort(-1); + } else + { + dataoutputstream.writeShort(itemStack.itemID); + dataoutputstream.writeByte(itemStack.stackSize); + dataoutputstream.writeShort(itemStack.getItemDamage()); + } + } + + public int getPacketSize() + { + return 11; + } + + public int window_Id; + public int inventorySlot; + public int mouseClick; + public short action; + public ItemStack itemStack; +} diff --git a/src/main/java/net/minecraft/src/Packet103.java b/src/main/java/net/minecraft/src/Packet103.java new file mode 100644 index 0000000..335aef5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet103.java @@ -0,0 +1,59 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet103 extends Packet +{ + + public Packet103() + { + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20088_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + windowId = datainputstream.readByte(); + itemSlot = datainputstream.readShort(); + short word0 = datainputstream.readShort(); + if(word0 >= 0) + { + byte byte0 = datainputstream.readByte(); + short word1 = datainputstream.readShort(); + myItemStack = new ItemStack(word0, byte0, word1); + } else + { + myItemStack = null; + } + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(windowId); + dataoutputstream.writeShort(itemSlot); + if(myItemStack == null) + { + dataoutputstream.writeShort(-1); + } else + { + dataoutputstream.writeShort(myItemStack.itemID); + dataoutputstream.writeByte(myItemStack.stackSize); + dataoutputstream.writeShort(myItemStack.getItemDamage()); + } + } + + public int getPacketSize() + { + return 8; + } + + public int windowId; + public int itemSlot; + public ItemStack myItemStack; +} diff --git a/src/main/java/net/minecraft/src/Packet104.java b/src/main/java/net/minecraft/src/Packet104.java new file mode 100644 index 0000000..14b463f --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet104.java @@ -0,0 +1,64 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet104 extends Packet +{ + + public Packet104() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + windowId = datainputstream.readByte(); + short word0 = datainputstream.readShort(); + itemStack = new ItemStack[word0]; + for(int i = 0; i < word0; i++) + { + short word1 = datainputstream.readShort(); + if(word1 >= 0) + { + byte byte0 = datainputstream.readByte(); + short word2 = datainputstream.readShort(); + itemStack[i] = new ItemStack(word1, byte0, word2); + } + } + + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(windowId); + dataoutputstream.writeShort(itemStack.length); + for(int i = 0; i < itemStack.length; i++) + { + if(itemStack[i] == null) + { + dataoutputstream.writeShort(-1); + } else + { + dataoutputstream.writeShort((short)itemStack[i].itemID); + dataoutputstream.writeByte((byte)itemStack[i].stackSize); + dataoutputstream.writeShort((short)itemStack[i].getItemDamage()); + } + } + + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20094_a(this); + } + + public int getPacketSize() + { + return 3 + itemStack.length * 5; + } + + public int windowId; + public ItemStack itemStack[]; +} diff --git a/src/main/java/net/minecraft/src/Packet105.java b/src/main/java/net/minecraft/src/Packet105.java new file mode 100644 index 0000000..6508920 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet105.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet105 extends Packet +{ + + public Packet105() + { + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20090_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + windowId = datainputstream.readByte(); + progressBar = datainputstream.readShort(); + progressBarValue = datainputstream.readShort(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(windowId); + dataoutputstream.writeShort(progressBar); + dataoutputstream.writeShort(progressBarValue); + } + + public int getPacketSize() + { + return 5; + } + + public int windowId; + public int progressBar; + public int progressBarValue; +} diff --git a/src/main/java/net/minecraft/src/Packet106.java b/src/main/java/net/minecraft/src/Packet106.java new file mode 100644 index 0000000..da42468 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet106.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet106 extends Packet +{ + + public Packet106() + { + } + + public Packet106(int i, short word0, boolean flag) + { + windowId = i; + field_20028_b = word0; + field_20030_c = flag; + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20089_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + windowId = datainputstream.readByte(); + field_20028_b = datainputstream.readShort(); + field_20030_c = datainputstream.readByte() != 0; + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeByte(windowId); + dataoutputstream.writeShort(field_20028_b); + dataoutputstream.writeByte(field_20030_c ? 1 : 0); + } + + public int getPacketSize() + { + return 4; + } + + public int windowId; + public short field_20028_b; + public boolean field_20030_c; +} diff --git a/src/main/java/net/minecraft/src/Packet10Flying.java b/src/main/java/net/minecraft/src/Packet10Flying.java new file mode 100644 index 0000000..00516b5 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet10Flying.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet10Flying extends Packet +{ + + public Packet10Flying() + { + } + + public Packet10Flying(boolean flag) + { + onGround = flag; + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleFlying(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + onGround = datainputstream.read() != 0; + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.write(onGround ? 1 : 0); + } + + public int getPacketSize() + { + return 1; + } + + public double xPosition; + public double yPosition; + public double zPosition; + public double stance; + public float yaw; + public float pitch; + public boolean onGround; + public boolean moving; + public boolean rotating; +} diff --git a/src/main/java/net/minecraft/src/Packet11PlayerPosition.java b/src/main/java/net/minecraft/src/Packet11PlayerPosition.java new file mode 100644 index 0000000..ca2c15d --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet11PlayerPosition.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet11PlayerPosition extends Packet10Flying +{ + + public Packet11PlayerPosition() + { + moving = true; + } + + public Packet11PlayerPosition(double d, double d1, double d2, double d3, boolean flag) + { + xPosition = d; + yPosition = d1; + stance = d2; + zPosition = d3; + onGround = flag; + moving = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readDouble(); + yPosition = datainputstream.readDouble(); + stance = datainputstream.readDouble(); + zPosition = datainputstream.readDouble(); + super.readPacketData(datainputstream); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeDouble(xPosition); + dataoutputstream.writeDouble(yPosition); + dataoutputstream.writeDouble(stance); + dataoutputstream.writeDouble(zPosition); + super.writePacketData(dataoutputstream); + } + + public int getPacketSize() + { + return 33; + } +} diff --git a/src/main/java/net/minecraft/src/Packet12PlayerLook.java b/src/main/java/net/minecraft/src/Packet12PlayerLook.java new file mode 100644 index 0000000..a938179 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet12PlayerLook.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet12PlayerLook extends Packet10Flying +{ + + public Packet12PlayerLook() + { + rotating = true; + } + + public Packet12PlayerLook(float f, float f1, boolean flag) + { + yaw = f; + pitch = f1; + onGround = flag; + rotating = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + yaw = datainputstream.readFloat(); + pitch = datainputstream.readFloat(); + super.readPacketData(datainputstream); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeFloat(yaw); + dataoutputstream.writeFloat(pitch); + super.writePacketData(dataoutputstream); + } + + public int getPacketSize() + { + return 9; + } +} diff --git a/src/main/java/net/minecraft/src/Packet130.java b/src/main/java/net/minecraft/src/Packet130.java new file mode 100644 index 0000000..370827e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet130.java @@ -0,0 +1,70 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet130 extends Packet +{ + + public Packet130() + { + isChunkDataPacket = true; + } + + public Packet130(int i, int j, int k, String as[]) + { + isChunkDataPacket = true; + xPosition = i; + yPosition = j; + zPosition = k; + signLines = as; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readShort(); + zPosition = datainputstream.readInt(); + signLines = new String[4]; + for(int i = 0; i < 4; i++) + { + signLines[i] = datainputstream.readUTF(); + } + + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeShort(yPosition); + dataoutputstream.writeInt(zPosition); + for(int i = 0; i < 4; i++) + { + dataoutputstream.writeUTF(signLines[i]); + } + + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_20093_a(this); + } + + public int getPacketSize() + { + int i = 0; + for(int j = 0; j < 4; j++) + { + i += signLines[j].length(); + } + + return i; + } + + public int xPosition; + public int yPosition; + public int zPosition; + public String signLines[]; +} diff --git a/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java b/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java new file mode 100644 index 0000000..bbceeec --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java @@ -0,0 +1,56 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet13PlayerLookMove extends Packet10Flying +{ + + public Packet13PlayerLookMove() + { + rotating = true; + moving = true; + } + + public Packet13PlayerLookMove(double d, double d1, double d2, double d3, float f, float f1, boolean flag) + { + xPosition = d; + yPosition = d1; + stance = d2; + zPosition = d3; + yaw = f; + pitch = f1; + onGround = flag; + rotating = true; + moving = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readDouble(); + yPosition = datainputstream.readDouble(); + stance = datainputstream.readDouble(); + zPosition = datainputstream.readDouble(); + yaw = datainputstream.readFloat(); + pitch = datainputstream.readFloat(); + super.readPacketData(datainputstream); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeDouble(xPosition); + dataoutputstream.writeDouble(yPosition); + dataoutputstream.writeDouble(stance); + dataoutputstream.writeDouble(zPosition); + dataoutputstream.writeFloat(yaw); + dataoutputstream.writeFloat(pitch); + super.writePacketData(dataoutputstream); + } + + public int getPacketSize() + { + return 41; + } +} diff --git a/src/main/java/net/minecraft/src/Packet14BlockDig.java b/src/main/java/net/minecraft/src/Packet14BlockDig.java new file mode 100644 index 0000000..4ed5667 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet14BlockDig.java @@ -0,0 +1,57 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet14BlockDig extends Packet +{ + + public Packet14BlockDig() + { + } + + public Packet14BlockDig(int i, int j, int k, int l, int i1) + { + status = i; + xPosition = j; + yPosition = k; + zPosition = l; + face = i1; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + status = datainputstream.read(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.read(); + zPosition = datainputstream.readInt(); + face = datainputstream.read(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.write(status); + dataoutputstream.writeInt(xPosition); + dataoutputstream.write(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.write(face); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleBlockDig(this); + } + + public int getPacketSize() + { + return 11; + } + + public int xPosition; + public int yPosition; + public int zPosition; + public int face; + public int status; +} diff --git a/src/main/java/net/minecraft/src/Packet15Place.java b/src/main/java/net/minecraft/src/Packet15Place.java new file mode 100644 index 0000000..265400b --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet15Place.java @@ -0,0 +1,74 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet15Place extends Packet +{ + + public Packet15Place() + { + } + + public Packet15Place(int i, int j, int k, int l, ItemStack itemstack) + { + xPosition = i; + yPosition = j; + zPosition = k; + direction = l; + itemStack = itemstack; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + yPosition = datainputstream.read(); + zPosition = datainputstream.readInt(); + direction = datainputstream.read(); + short word0 = datainputstream.readShort(); + if(word0 >= 0) + { + byte byte0 = datainputstream.readByte(); + short word1 = datainputstream.readShort(); + itemStack = new ItemStack(word0, byte0, word1); + } else + { + itemStack = null; + } + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.write(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.write(direction); + if(itemStack == null) + { + dataoutputstream.writeShort(-1); + } else + { + dataoutputstream.writeShort(itemStack.itemID); + dataoutputstream.writeByte(itemStack.stackSize); + dataoutputstream.writeShort(itemStack.getItemDamage()); + } + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handlePlace(this); + } + + public int getPacketSize() + { + return 15; + } + + public int xPosition; + public int yPosition; + public int zPosition; + public int direction; + public ItemStack itemStack; +} diff --git a/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java b/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java new file mode 100644 index 0000000..808a4c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet16BlockItemSwitch extends Packet +{ + + public Packet16BlockItemSwitch() + { + } + + public Packet16BlockItemSwitch(int i) + { + id = i; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + id = datainputstream.readShort(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeShort(id); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleBlockItemSwitch(this); + } + + public int getPacketSize() + { + return 2; + } + + public int id; +} diff --git a/src/main/java/net/minecraft/src/Packet17Sleep.java b/src/main/java/net/minecraft/src/Packet17Sleep.java new file mode 100644 index 0000000..30f8654 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet17Sleep.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet17Sleep extends Packet +{ + + public Packet17Sleep() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + field_22045_a = datainputstream.readInt(); + field_22046_e = datainputstream.readByte(); + field_22044_b = datainputstream.readInt(); + field_22048_c = datainputstream.readByte(); + field_22047_d = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(field_22045_a); + dataoutputstream.writeByte(field_22046_e); + dataoutputstream.writeInt(field_22044_b); + dataoutputstream.writeByte(field_22048_c); + dataoutputstream.writeInt(field_22047_d); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_22186_a(this); + } + + public int getPacketSize() + { + return 14; + } + + public int field_22045_a; + public int field_22044_b; + public int field_22048_c; + public int field_22047_d; + public int field_22046_e; +} diff --git a/src/main/java/net/minecraft/src/Packet18ArmAnimation.java b/src/main/java/net/minecraft/src/Packet18ArmAnimation.java new file mode 100644 index 0000000..5f6376f --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet18ArmAnimation.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet18ArmAnimation extends Packet +{ + + public Packet18ArmAnimation() + { + } + + public Packet18ArmAnimation(Entity entity, int i) + { + entityId = entity.entityId; + animate = i; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + animate = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeByte(animate); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleArmAnimation(this); + } + + public int getPacketSize() + { + return 5; + } + + public int entityId; + public int animate; +} diff --git a/src/main/java/net/minecraft/src/Packet19.java b/src/main/java/net/minecraft/src/Packet19.java new file mode 100644 index 0000000..45b4633 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet19.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet19 extends Packet +{ + + public Packet19() + { + } + + public Packet19(Entity entity, int i) + { + entityId = entity.entityId; + state = i; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + state = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeByte(state); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_21147_a(this); + } + + public int getPacketSize() + { + return 5; + } + + public int entityId; + public int state; +} diff --git a/src/main/java/net/minecraft/src/Packet1Login.java b/src/main/java/net/minecraft/src/Packet1Login.java new file mode 100644 index 0000000..9d0074c --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet1Login.java @@ -0,0 +1,55 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet1Login extends Packet +{ + + public Packet1Login() + { + } + + public Packet1Login(String s, String s1, int i) + { + username = s; + password = s1; + protocolVersion = i; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + protocolVersion = datainputstream.readInt(); + username = datainputstream.readUTF(); + password = datainputstream.readUTF(); + mapSeed = datainputstream.readLong(); + dimension = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(protocolVersion); + dataoutputstream.writeUTF(username); + dataoutputstream.writeUTF(password); + dataoutputstream.writeLong(mapSeed); + dataoutputstream.writeByte(dimension); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleLogin(this); + } + + public int getPacketSize() + { + return 4 + username.length() + password.length() + 4 + 5; + } + + public int protocolVersion; + public String username; + public String password; + public long mapSeed; + public byte dimension; +} diff --git a/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java b/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java new file mode 100644 index 0000000..a3ce314 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java @@ -0,0 +1,70 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet20NamedEntitySpawn extends Packet +{ + + public Packet20NamedEntitySpawn() + { + } + + public Packet20NamedEntitySpawn(EntityPlayer entityplayer) + { + entityId = entityplayer.entityId; + name = entityplayer.username; + xPosition = MathHelper.floor_double(entityplayer.posX * 32D); + yPosition = MathHelper.floor_double(entityplayer.posY * 32D); + zPosition = MathHelper.floor_double(entityplayer.posZ * 32D); + rotation = (byte)(int)((entityplayer.rotationYaw * 256F) / 360F); + pitch = (byte)(int)((entityplayer.rotationPitch * 256F) / 360F); + ItemStack itemstack = entityplayer.inventory.getCurrentItem(); + currentItem = itemstack != null ? itemstack.itemID : 0; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + name = datainputstream.readUTF(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + rotation = datainputstream.readByte(); + pitch = datainputstream.readByte(); + currentItem = datainputstream.readShort(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeUTF(name); + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.writeByte(rotation); + dataoutputstream.writeByte(pitch); + dataoutputstream.writeShort(currentItem); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleNamedEntitySpawn(this); + } + + public int getPacketSize() + { + return 28; + } + + public int entityId; + public String name; + public int xPosition; + public int yPosition; + public int zPosition; + public byte rotation; + public byte pitch; + public int currentItem; +} diff --git a/src/main/java/net/minecraft/src/Packet21PickupSpawn.java b/src/main/java/net/minecraft/src/Packet21PickupSpawn.java new file mode 100644 index 0000000..e8e2c4e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet21PickupSpawn.java @@ -0,0 +1,77 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet21PickupSpawn extends Packet +{ + + public Packet21PickupSpawn() + { + } + + public Packet21PickupSpawn(EntityItem entityitem) + { + entityId = entityitem.entityId; + itemID = entityitem.item.itemID; + count = entityitem.item.stackSize; + itemDamage = entityitem.item.getItemDamage(); + xPosition = MathHelper.floor_double(entityitem.posX * 32D); + yPosition = MathHelper.floor_double(entityitem.posY * 32D); + zPosition = MathHelper.floor_double(entityitem.posZ * 32D); + rotation = (byte)(int)(entityitem.motionX * 128D); + pitch = (byte)(int)(entityitem.motionY * 128D); + roll = (byte)(int)(entityitem.motionZ * 128D); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + itemID = datainputstream.readShort(); + count = datainputstream.readByte(); + itemDamage = datainputstream.readShort(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + rotation = datainputstream.readByte(); + pitch = datainputstream.readByte(); + roll = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeShort(itemID); + dataoutputstream.writeByte(count); + dataoutputstream.writeShort(itemDamage); + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.writeByte(rotation); + dataoutputstream.writeByte(pitch); + dataoutputstream.writeByte(roll); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handlePickupSpawn(this); + } + + public int getPacketSize() + { + return 24; + } + + public int entityId; + public int xPosition; + public int yPosition; + public int zPosition; + public byte rotation; + public byte pitch; + public byte roll; + public int itemID; + public int count; + public int itemDamage; +} diff --git a/src/main/java/net/minecraft/src/Packet22Collect.java b/src/main/java/net/minecraft/src/Packet22Collect.java new file mode 100644 index 0000000..5cfde9a --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet22Collect.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet22Collect extends Packet +{ + + public Packet22Collect() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + collectedEntityId = datainputstream.readInt(); + collectorEntityId = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(collectedEntityId); + dataoutputstream.writeInt(collectorEntityId); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleCollect(this); + } + + public int getPacketSize() + { + return 8; + } + + public int collectedEntityId; + public int collectorEntityId; +} diff --git a/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java b/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java new file mode 100644 index 0000000..247f189 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet23VehicleSpawn extends Packet +{ + + public Packet23VehicleSpawn() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + type = datainputstream.readByte(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeByte(type); + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleVehicleSpawn(this); + } + + public int getPacketSize() + { + return 17; + } + + public int entityId; + public int xPosition; + public int yPosition; + public int zPosition; + public int type; +} diff --git a/src/main/java/net/minecraft/src/Packet24MobSpawn.java b/src/main/java/net/minecraft/src/Packet24MobSpawn.java new file mode 100644 index 0000000..54bd0fd --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet24MobSpawn.java @@ -0,0 +1,76 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.List; + +public class Packet24MobSpawn extends Packet +{ + + public Packet24MobSpawn() + { + } + + public Packet24MobSpawn(EntityLiving entityliving) + { + entityId = entityliving.entityId; + type = (byte)EntityList.getEntityID(entityliving); + xPosition = MathHelper.floor_double(entityliving.posX * 32D); + yPosition = MathHelper.floor_double(entityliving.posY * 32D); + zPosition = MathHelper.floor_double(entityliving.posZ * 32D); + yaw = (byte)(int)((entityliving.rotationYaw * 256F) / 360F); + pitch = (byte)(int)((entityliving.rotationPitch * 256F) / 360F); + metaData = entityliving.getDataWatcher(); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + type = datainputstream.readByte(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + yaw = datainputstream.readByte(); + pitch = datainputstream.readByte(); + receivedMetadata = DataWatcher.readWatchableObjects(datainputstream); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeByte(type); + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.writeByte(yaw); + dataoutputstream.writeByte(pitch); + metaData.writeWatchableObjects(dataoutputstream); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleMobSpawn(this); + } + + public int getPacketSize() + { + return 20; + } + + public List getMetadata() + { + return receivedMetadata; + } + + public int entityId; + public byte type; + public int xPosition; + public int yPosition; + public int zPosition; + public byte yaw; + public byte pitch; + private DataWatcher metaData; + private List receivedMetadata; +} diff --git a/src/main/java/net/minecraft/src/Packet25.java b/src/main/java/net/minecraft/src/Packet25.java new file mode 100644 index 0000000..8e4c548 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet25.java @@ -0,0 +1,61 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet25 extends Packet +{ + + public Packet25() + { + } + + public Packet25(EntityPainting entitypainting) + { + entityId = entitypainting.entityId; + xPosition = entitypainting.xPosition; + yPosition = entitypainting.yPosition; + zPosition = entitypainting.zPosition; + direction = entitypainting.direction; + title = entitypainting.art.title; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + title = datainputstream.readUTF(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + direction = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeUTF(title); + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.writeInt(direction); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_21146_a(this); + } + + public int getPacketSize() + { + return 24; + } + + public int entityId; + public int xPosition; + public int yPosition; + public int zPosition; + public int direction; + public String title; +} diff --git a/src/main/java/net/minecraft/src/Packet255KickDisconnect.java b/src/main/java/net/minecraft/src/Packet255KickDisconnect.java new file mode 100644 index 0000000..314837c --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet255KickDisconnect.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet255KickDisconnect extends Packet +{ + + public Packet255KickDisconnect() + { + } + + public Packet255KickDisconnect(String s) + { + reason = s; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + reason = datainputstream.readUTF(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeUTF(reason); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleKickDisconnect(this); + } + + public int getPacketSize() + { + return reason.length(); + } + + public String reason; +} diff --git a/src/main/java/net/minecraft/src/Packet27.java b/src/main/java/net/minecraft/src/Packet27.java new file mode 100644 index 0000000..3711e39 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet27.java @@ -0,0 +1,51 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet27 extends Packet +{ + + public Packet27() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + field_22039_a = datainputstream.readFloat(); + field_22038_b = datainputstream.readFloat(); + field_22041_e = datainputstream.readFloat(); + field_22040_f = datainputstream.readFloat(); + field_22043_c = datainputstream.readBoolean(); + field_22042_d = datainputstream.readBoolean(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeFloat(field_22039_a); + dataoutputstream.writeFloat(field_22038_b); + dataoutputstream.writeFloat(field_22041_e); + dataoutputstream.writeFloat(field_22040_f); + dataoutputstream.writeBoolean(field_22043_c); + dataoutputstream.writeBoolean(field_22042_d); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_22185_a(this); + } + + public int getPacketSize() + { + return 18; + } + + private float field_22039_a; + private float field_22038_b; + private boolean field_22043_c; + private boolean field_22042_d; + private float field_22041_e; + private float field_22040_f; +} diff --git a/src/main/java/net/minecraft/src/Packet28.java b/src/main/java/net/minecraft/src/Packet28.java new file mode 100644 index 0000000..9a638c4 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet28.java @@ -0,0 +1,83 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet28 extends Packet +{ + + public Packet28() + { + } + + public Packet28(Entity entity) + { + this(entity.entityId, entity.motionX, entity.motionY, entity.motionZ); + } + + public Packet28(int i, double d, double d1, double d2) + { + entityId = i; + double d3 = 3.8999999999999999D; + if(d < -d3) + { + d = -d3; + } + if(d1 < -d3) + { + d1 = -d3; + } + if(d2 < -d3) + { + d2 = -d3; + } + if(d > d3) + { + d = d3; + } + if(d1 > d3) + { + d1 = d3; + } + if(d2 > d3) + { + d2 = d3; + } + motionX = (int)(d * 8000D); + motionY = (int)(d1 * 8000D); + motionZ = (int)(d2 * 8000D); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + motionX = datainputstream.readShort(); + motionY = datainputstream.readShort(); + motionZ = datainputstream.readShort(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeShort(motionX); + dataoutputstream.writeShort(motionY); + dataoutputstream.writeShort(motionZ); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_6498_a(this); + } + + public int getPacketSize() + { + return 10; + } + + public int entityId; + public int motionX; + public int motionY; + public int motionZ; +} diff --git a/src/main/java/net/minecraft/src/Packet29DestroyEntity.java b/src/main/java/net/minecraft/src/Packet29DestroyEntity.java new file mode 100644 index 0000000..aef595d --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet29DestroyEntity.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet29DestroyEntity extends Packet +{ + + public Packet29DestroyEntity() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleDestroyEntity(this); + } + + public int getPacketSize() + { + return 4; + } + + public int entityId; +} diff --git a/src/main/java/net/minecraft/src/Packet2Handshake.java b/src/main/java/net/minecraft/src/Packet2Handshake.java new file mode 100644 index 0000000..8e396d0 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet2Handshake.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet2Handshake extends Packet +{ + + public Packet2Handshake() + { + } + + public Packet2Handshake(String s) + { + username = s; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + username = datainputstream.readUTF(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeUTF(username); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleHandshake(this); + } + + public int getPacketSize() + { + return 4 + username.length() + 4; + } + + public String username; +} diff --git a/src/main/java/net/minecraft/src/Packet30Entity.java b/src/main/java/net/minecraft/src/Packet30Entity.java new file mode 100644 index 0000000..832afa3 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet30Entity.java @@ -0,0 +1,43 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet30Entity extends Packet +{ + + public Packet30Entity() + { + rotating = false; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleEntity(this); + } + + public int getPacketSize() + { + return 4; + } + + public int entityId; + public byte xPosition; + public byte yPosition; + public byte zPosition; + public byte yaw; + public byte pitch; + public boolean rotating; +} diff --git a/src/main/java/net/minecraft/src/Packet31RelEntityMove.java b/src/main/java/net/minecraft/src/Packet31RelEntityMove.java new file mode 100644 index 0000000..26f42cb --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet31RelEntityMove.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet31RelEntityMove extends Packet30Entity +{ + + public Packet31RelEntityMove() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + super.readPacketData(datainputstream); + xPosition = datainputstream.readByte(); + yPosition = datainputstream.readByte(); + zPosition = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + super.writePacketData(dataoutputstream); + dataoutputstream.writeByte(xPosition); + dataoutputstream.writeByte(yPosition); + dataoutputstream.writeByte(zPosition); + } + + public int getPacketSize() + { + return 7; + } +} diff --git a/src/main/java/net/minecraft/src/Packet32EntityLook.java b/src/main/java/net/minecraft/src/Packet32EntityLook.java new file mode 100644 index 0000000..0a74827 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet32EntityLook.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet32EntityLook extends Packet30Entity +{ + + public Packet32EntityLook() + { + rotating = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + super.readPacketData(datainputstream); + yaw = datainputstream.readByte(); + pitch = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + super.writePacketData(dataoutputstream); + dataoutputstream.writeByte(yaw); + dataoutputstream.writeByte(pitch); + } + + public int getPacketSize() + { + return 6; + } +} diff --git a/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java b/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java new file mode 100644 index 0000000..34aa238 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java @@ -0,0 +1,40 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet33RelEntityMoveLook extends Packet30Entity +{ + + public Packet33RelEntityMoveLook() + { + rotating = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + super.readPacketData(datainputstream); + xPosition = datainputstream.readByte(); + yPosition = datainputstream.readByte(); + zPosition = datainputstream.readByte(); + yaw = datainputstream.readByte(); + pitch = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + super.writePacketData(dataoutputstream); + dataoutputstream.writeByte(xPosition); + dataoutputstream.writeByte(yPosition); + dataoutputstream.writeByte(zPosition); + dataoutputstream.writeByte(yaw); + dataoutputstream.writeByte(pitch); + } + + public int getPacketSize() + { + return 9; + } +} diff --git a/src/main/java/net/minecraft/src/Packet34EntityTeleport.java b/src/main/java/net/minecraft/src/Packet34EntityTeleport.java new file mode 100644 index 0000000..81d495c --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet34EntityTeleport.java @@ -0,0 +1,61 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet34EntityTeleport extends Packet +{ + + public Packet34EntityTeleport() + { + } + + public Packet34EntityTeleport(Entity entity) + { + entityId = entity.entityId; + xPosition = MathHelper.floor_double(entity.posX * 32D); + yPosition = MathHelper.floor_double(entity.posY * 32D); + zPosition = MathHelper.floor_double(entity.posZ * 32D); + yaw = (byte)(int)((entity.rotationYaw * 256F) / 360F); + pitch = (byte)(int)((entity.rotationPitch * 256F) / 360F); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + yaw = (byte)datainputstream.read(); + pitch = (byte)datainputstream.read(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.write(yaw); + dataoutputstream.write(pitch); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleEntityTeleport(this); + } + + public int getPacketSize() + { + return 34; + } + + public int entityId; + public int xPosition; + public int yPosition; + public int zPosition; + public byte yaw; + public byte pitch; +} diff --git a/src/main/java/net/minecraft/src/Packet38.java b/src/main/java/net/minecraft/src/Packet38.java new file mode 100644 index 0000000..f897412 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet38.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet38 extends Packet +{ + + public Packet38() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + entityStatus = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeByte(entityStatus); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_9447_a(this); + } + + public int getPacketSize() + { + return 5; + } + + public int entityId; + public byte entityStatus; +} diff --git a/src/main/java/net/minecraft/src/Packet39.java b/src/main/java/net/minecraft/src/Packet39.java new file mode 100644 index 0000000..65eac01 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet39.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet39 extends Packet +{ + + public Packet39() + { + } + + public int getPacketSize() + { + return 8; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + vehicleEntityId = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + dataoutputstream.writeInt(vehicleEntityId); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_6497_a(this); + } + + public int entityId; + public int vehicleEntityId; +} diff --git a/src/main/java/net/minecraft/src/Packet3Chat.java b/src/main/java/net/minecraft/src/Packet3Chat.java new file mode 100644 index 0000000..fb51d49 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet3Chat.java @@ -0,0 +1,41 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet3Chat extends Packet +{ + + public Packet3Chat() + { + } + + public Packet3Chat(String s) + { + message = s; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + message = datainputstream.readUTF(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeUTF(message); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleChat(this); + } + + public int getPacketSize() + { + return message.length(); + } + + public String message; +} diff --git a/src/main/java/net/minecraft/src/Packet40.java b/src/main/java/net/minecraft/src/Packet40.java new file mode 100644 index 0000000..6f0ed0e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet40.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.List; + +public class Packet40 extends Packet +{ + + public Packet40() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityId = datainputstream.readInt(); + field_21048_b = DataWatcher.readWatchableObjects(datainputstream); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityId); + DataWatcher.writeObjectsInListToStream(field_21048_b, dataoutputstream); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_21148_a(this); + } + + public int getPacketSize() + { + return 5; + } + + public List func_21047_b() + { + return field_21048_b; + } + + public int entityId; + private List field_21048_b; +} diff --git a/src/main/java/net/minecraft/src/Packet4UpdateTime.java b/src/main/java/net/minecraft/src/Packet4UpdateTime.java new file mode 100644 index 0000000..22033f7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet4UpdateTime.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet4UpdateTime extends Packet +{ + + public Packet4UpdateTime() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + time = datainputstream.readLong(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeLong(time); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleUpdateTime(this); + } + + public int getPacketSize() + { + return 8; + } + + public long time; +} diff --git a/src/main/java/net/minecraft/src/Packet50PreChunk.java b/src/main/java/net/minecraft/src/Packet50PreChunk.java new file mode 100644 index 0000000..52f2aa0 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet50PreChunk.java @@ -0,0 +1,43 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet50PreChunk extends Packet +{ + + public Packet50PreChunk() + { + isChunkDataPacket = false; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + mode = datainputstream.read() != 0; + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.write(mode ? 1 : 0); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handlePreChunk(this); + } + + public int getPacketSize() + { + return 9; + } + + public int xPosition; + public int yPosition; + public boolean mode; +} diff --git a/src/main/java/net/minecraft/src/Packet51MapChunk.java b/src/main/java/net/minecraft/src/Packet51MapChunk.java new file mode 100644 index 0000000..92052ee --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet51MapChunk.java @@ -0,0 +1,76 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +public class Packet51MapChunk extends Packet +{ + + public Packet51MapChunk() + { + isChunkDataPacket = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readShort(); + zPosition = datainputstream.readInt(); + xSize = datainputstream.read() + 1; + ySize = datainputstream.read() + 1; + zSize = datainputstream.read() + 1; + chunkSize = datainputstream.readInt(); + byte abyte0[] = new byte[chunkSize]; + datainputstream.readFully(abyte0); + chunk = new byte[(xSize * ySize * zSize * 5) / 2]; + Inflater inflater = new Inflater(); + inflater.setInput(abyte0); + try + { + inflater.inflate(chunk); + } + catch(DataFormatException dataformatexception) + { + throw new IOException("Bad compressed data format"); + } + finally + { + inflater.end(); + } + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeShort(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.write(xSize - 1); + dataoutputstream.write(ySize - 1); + dataoutputstream.write(zSize - 1); + dataoutputstream.writeInt(chunkSize); + dataoutputstream.write(chunk, 0, chunkSize); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleMapChunk(this); + } + + public int getPacketSize() + { + return 17 + chunkSize; + } + + public int xPosition; + public int yPosition; + public int zPosition; + public int xSize; + public int ySize; + public int zSize; + public byte chunk[]; + private int chunkSize; +} diff --git a/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java b/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java new file mode 100644 index 0000000..59ac800 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java @@ -0,0 +1,63 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet52MultiBlockChange extends Packet +{ + + public Packet52MultiBlockChange() + { + isChunkDataPacket = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + size = datainputstream.readShort() & 0xffff; + coordinateArray = new short[size]; + typeArray = new byte[size]; + metadataArray = new byte[size]; + for(int i = 0; i < size; i++) + { + coordinateArray[i] = datainputstream.readShort(); + } + + datainputstream.readFully(typeArray); + datainputstream.readFully(metadataArray); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.writeShort((short)size); + for(int i = 0; i < size; i++) + { + dataoutputstream.writeShort(coordinateArray[i]); + } + + dataoutputstream.write(typeArray); + dataoutputstream.write(metadataArray); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleMultiBlockChange(this); + } + + public int getPacketSize() + { + return 10 + size * 4; + } + + public int xPosition; + public int zPosition; + public short coordinateArray[]; + public byte typeArray[]; + public byte metadataArray[]; + public int size; +} diff --git a/src/main/java/net/minecraft/src/Packet53BlockChange.java b/src/main/java/net/minecraft/src/Packet53BlockChange.java new file mode 100644 index 0000000..6232b5f --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet53BlockChange.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet53BlockChange extends Packet +{ + + public Packet53BlockChange() + { + isChunkDataPacket = true; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + yPosition = datainputstream.read(); + zPosition = datainputstream.readInt(); + type = datainputstream.read(); + metadata = datainputstream.read(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.write(yPosition); + dataoutputstream.writeInt(zPosition); + dataoutputstream.write(type); + dataoutputstream.write(metadata); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleBlockChange(this); + } + + public int getPacketSize() + { + return 11; + } + + public int xPosition; + public int yPosition; + public int zPosition; + public int type; + public int metadata; +} diff --git a/src/main/java/net/minecraft/src/Packet54.java b/src/main/java/net/minecraft/src/Packet54.java new file mode 100644 index 0000000..9d6b04e --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet54.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet54 extends Packet +{ + + public Packet54() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xLocation = datainputstream.readInt(); + yLocation = datainputstream.readShort(); + zLocation = datainputstream.readInt(); + instrumentType = datainputstream.read(); + pitch = datainputstream.read(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xLocation); + dataoutputstream.writeShort(yLocation); + dataoutputstream.writeInt(zLocation); + dataoutputstream.write(instrumentType); + dataoutputstream.write(pitch); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_21145_a(this); + } + + public int getPacketSize() + { + return 12; + } + + public int xLocation; + public int yLocation; + public int zLocation; + public int instrumentType; + public int pitch; +} diff --git a/src/main/java/net/minecraft/src/Packet5PlayerInventory.java b/src/main/java/net/minecraft/src/Packet5PlayerInventory.java new file mode 100644 index 0000000..f9cddaa --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet5PlayerInventory.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet5PlayerInventory extends Packet +{ + + public Packet5PlayerInventory() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + entityID = datainputstream.readInt(); + slot = datainputstream.readShort(); + itemID = datainputstream.readShort(); + itemDamage = datainputstream.readShort(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(entityID); + dataoutputstream.writeShort(slot); + dataoutputstream.writeShort(itemID); + dataoutputstream.writeShort(itemDamage); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handlePlayerInventory(this); + } + + public int getPacketSize() + { + return 8; + } + + public int entityID; + public int slot; + public int itemID; + public int itemDamage; +} diff --git a/src/main/java/net/minecraft/src/Packet60.java b/src/main/java/net/minecraft/src/Packet60.java new file mode 100644 index 0000000..66bcae7 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet60.java @@ -0,0 +1,75 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.*; + +public class Packet60 extends Packet +{ + + public Packet60() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + explosionX = datainputstream.readDouble(); + explosionY = datainputstream.readDouble(); + explosionZ = datainputstream.readDouble(); + explosionSize = datainputstream.readFloat(); + int i = datainputstream.readInt(); + destroyedBlockPositions = new HashSet(); + int j = (int)explosionX; + int k = (int)explosionY; + int l = (int)explosionZ; + for(int i1 = 0; i1 < i; i1++) + { + int j1 = datainputstream.readByte() + j; + int k1 = datainputstream.readByte() + k; + int l1 = datainputstream.readByte() + l; + destroyedBlockPositions.add(new ChunkPosition(j1, k1, l1)); + } + + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeDouble(explosionX); + dataoutputstream.writeDouble(explosionY); + dataoutputstream.writeDouble(explosionZ); + dataoutputstream.writeFloat(explosionSize); + dataoutputstream.writeInt(destroyedBlockPositions.size()); + int i = (int)explosionX; + int j = (int)explosionY; + int k = (int)explosionZ; + int j1; + for(Iterator iterator = destroyedBlockPositions.iterator(); iterator.hasNext(); dataoutputstream.writeByte(j1)) + { + ChunkPosition chunkposition = (ChunkPosition)iterator.next(); + int l = chunkposition.x - i; + int i1 = chunkposition.y - j; + j1 = chunkposition.z - k; + dataoutputstream.writeByte(l); + dataoutputstream.writeByte(i1); + } + + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_12245_a(this); + } + + public int getPacketSize() + { + return 32 + destroyedBlockPositions.size() * 3; + } + + public double explosionX; + public double explosionY; + public double explosionZ; + public float explosionSize; + public Set destroyedBlockPositions; +} diff --git a/src/main/java/net/minecraft/src/Packet6SpawnPosition.java b/src/main/java/net/minecraft/src/Packet6SpawnPosition.java new file mode 100644 index 0000000..2b615b6 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet6SpawnPosition.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet6SpawnPosition extends Packet +{ + + public Packet6SpawnPosition() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + xPosition = datainputstream.readInt(); + yPosition = datainputstream.readInt(); + zPosition = datainputstream.readInt(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(xPosition); + dataoutputstream.writeInt(yPosition); + dataoutputstream.writeInt(zPosition); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleSpawnPosition(this); + } + + public int getPacketSize() + { + return 12; + } + + public int xPosition; + public int yPosition; + public int zPosition; +} diff --git a/src/main/java/net/minecraft/src/Packet7.java b/src/main/java/net/minecraft/src/Packet7.java new file mode 100644 index 0000000..82303da --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet7.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet7 extends Packet +{ + + public Packet7() + { + } + + public Packet7(int i, int j, int k) + { + playerEntityId = i; + targetEntity = j; + isLeftClick = k; + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + playerEntityId = datainputstream.readInt(); + targetEntity = datainputstream.readInt(); + isLeftClick = datainputstream.readByte(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeInt(playerEntityId); + dataoutputstream.writeInt(targetEntity); + dataoutputstream.writeByte(isLeftClick); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_6499_a(this); + } + + public int getPacketSize() + { + return 9; + } + + public int playerEntityId; + public int targetEntity; + public int isLeftClick; +} diff --git a/src/main/java/net/minecraft/src/Packet8.java b/src/main/java/net/minecraft/src/Packet8.java new file mode 100644 index 0000000..ea7af33 --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet8.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet8 extends Packet +{ + + public Packet8() + { + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + healthMP = datainputstream.readShort(); + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + dataoutputstream.writeShort(healthMP); + } + + public void processPacket(NetHandler nethandler) + { + nethandler.handleHealth(this); + } + + public int getPacketSize() + { + return 2; + } + + public int healthMP; +} diff --git a/src/main/java/net/minecraft/src/Packet9.java b/src/main/java/net/minecraft/src/Packet9.java new file mode 100644 index 0000000..614be8a --- /dev/null +++ b/src/main/java/net/minecraft/src/Packet9.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; + +public class Packet9 extends Packet +{ + + public Packet9() + { + } + + public void processPacket(NetHandler nethandler) + { + nethandler.func_9448_a(this); + } + + public void readPacketData(DataInputStream datainputstream) throws IOException + { + } + + public void writePacketData(DataOutputStream dataoutputstream) throws IOException + { + } + + public int getPacketSize() + { + return 0; + } +} diff --git a/src/main/java/net/minecraft/src/PacketCounter.java b/src/main/java/net/minecraft/src/PacketCounter.java new file mode 100644 index 0000000..1512329 --- /dev/null +++ b/src/main/java/net/minecraft/src/PacketCounter.java @@ -0,0 +1,27 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class PacketCounter +{ + + private PacketCounter() + { + } + + public void func_22236_a(int i) + { + field_22238_a++; + field_22237_b += i; + } + + PacketCounter(Empty1 empty1) + { + this(); + } + + private int field_22238_a; + private long field_22237_b; +} diff --git a/src/main/java/net/minecraft/src/Path.java b/src/main/java/net/minecraft/src/Path.java new file mode 100644 index 0000000..46ce092 --- /dev/null +++ b/src/main/java/net/minecraft/src/Path.java @@ -0,0 +1,144 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class Path +{ + + public Path() + { + pathPoints = new PathPoint[1024]; + count = 0; + } + + public PathPoint addPoint(PathPoint pathpoint) + { + if(pathpoint.index >= 0) + { + throw new IllegalStateException("OW KNOWS!"); + } + if(count == pathPoints.length) + { + PathPoint apathpoint[] = new PathPoint[count << 1]; + System.arraycopy(pathPoints, 0, apathpoint, 0, count); + pathPoints = apathpoint; + } + pathPoints[count] = pathpoint; + pathpoint.index = count; + sortBack(count++); + return pathpoint; + } + + public void clearPath() + { + count = 0; + } + + public PathPoint dequeue() + { + PathPoint pathpoint = pathPoints[0]; + pathPoints[0] = pathPoints[--count]; + pathPoints[count] = null; + if(count > 0) + { + sortForward(0); + } + pathpoint.index = -1; + return pathpoint; + } + + public void changeDistance(PathPoint pathpoint, float f) + { + float f1 = pathpoint.distanceToTarget; + pathpoint.distanceToTarget = f; + if(f < f1) + { + sortBack(pathpoint.index); + } else + { + sortForward(pathpoint.index); + } + } + + private void sortBack(int i) + { + PathPoint pathpoint = pathPoints[i]; + float f = pathpoint.distanceToTarget; + do + { + if(i <= 0) + { + break; + } + int j = i - 1 >> 1; + PathPoint pathpoint1 = pathPoints[j]; + if(f >= pathpoint1.distanceToTarget) + { + break; + } + pathPoints[i] = pathpoint1; + pathpoint1.index = i; + i = j; + } while(true); + pathPoints[i] = pathpoint; + pathpoint.index = i; + } + + private void sortForward(int i) + { + PathPoint pathpoint = pathPoints[i]; + float f = pathpoint.distanceToTarget; + do + { + int j = 1 + (i << 1); + int k = j + 1; + if(j >= count) + { + break; + } + PathPoint pathpoint1 = pathPoints[j]; + float f1 = pathpoint1.distanceToTarget; + PathPoint pathpoint2; + float f2; + if(k >= count) + { + pathpoint2 = null; + f2 = (1.0F / 0.0F); + } else + { + pathpoint2 = pathPoints[k]; + f2 = pathpoint2.distanceToTarget; + } + if(f1 < f2) + { + if(f1 >= f) + { + break; + } + pathPoints[i] = pathpoint1; + pathpoint1.index = i; + i = j; + continue; + } + if(f2 >= f) + { + break; + } + pathPoints[i] = pathpoint2; + pathpoint2.index = i; + i = k; + } while(true); + pathPoints[i] = pathpoint; + pathpoint.index = i; + } + + public boolean isPathEmpty() + { + return count == 0; + } + + private PathPoint pathPoints[]; + private int count; +} diff --git a/src/main/java/net/minecraft/src/PathEntity.java b/src/main/java/net/minecraft/src/PathEntity.java new file mode 100644 index 0000000..0e9561b --- /dev/null +++ b/src/main/java/net/minecraft/src/PathEntity.java @@ -0,0 +1,48 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class PathEntity +{ + + public PathEntity(PathPoint apathpoint[]) + { + points = apathpoint; + pathLength = apathpoint.length; + } + + public void incrementPathIndex() + { + pathIndex++; + } + + public boolean isFinished() + { + return pathIndex >= points.length; + } + + public PathPoint func_22328_c() + { + if(pathLength > 0) + { + return points[pathLength - 1]; + } else + { + return null; + } + } + + public Vec3D getPosition(Entity entity) + { + double d = (double)points[pathIndex].xCoord + (double)(int)(entity.width + 1.0F) * 0.5D; + double d1 = points[pathIndex].yCoord; + double d2 = (double)points[pathIndex].zCoord + (double)(int)(entity.width + 1.0F) * 0.5D; + return Vec3D.createVector(d, d1, d2); + } + + private final PathPoint points[]; + public final int pathLength; + private int pathIndex; +} diff --git a/src/main/java/net/minecraft/src/PathPoint.java b/src/main/java/net/minecraft/src/PathPoint.java new file mode 100644 index 0000000..fcce1cd --- /dev/null +++ b/src/main/java/net/minecraft/src/PathPoint.java @@ -0,0 +1,70 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class PathPoint +{ + + public PathPoint(int i, int j, int k) + { + index = -1; + isFirst = false; + xCoord = i; + yCoord = j; + zCoord = k; + hash = func_22329_a(i, j, k); + } + + public static int func_22329_a(int i, int j, int k) + { + return j & 0xff | (i & 0x7fff) << 8 | (k & 0x7fff) << 24 | (i >= 0 ? 0 : 0x80000000) | (k >= 0 ? 0 : 0x8000); + } + + public float distanceTo(PathPoint pathpoint) + { + float f = pathpoint.xCoord - xCoord; + float f1 = pathpoint.yCoord - yCoord; + float f2 = pathpoint.zCoord - zCoord; + return MathHelper.sqrt_float(f * f + f1 * f1 + f2 * f2); + } + + public boolean equals(Object obj) + { + if(obj instanceof PathPoint) + { + PathPoint pathpoint = (PathPoint)obj; + return hash == pathpoint.hash && xCoord == pathpoint.xCoord && yCoord == pathpoint.yCoord && zCoord == pathpoint.zCoord; + } else + { + return false; + } + } + + public int hashCode() + { + return hash; + } + + public boolean isAssigned() + { + return index >= 0; + } + + public String toString() + { + return (new StringBuilder()).append(xCoord).append(", ").append(yCoord).append(", ").append(zCoord).toString(); + } + + public final int xCoord; + public final int yCoord; + public final int zCoord; + private final int hash; + int index; + float totalPathDistance; + float distanceToNext; + float distanceToTarget; + PathPoint previous; + public boolean isFirst; +} diff --git a/src/main/java/net/minecraft/src/Pathfinder.java b/src/main/java/net/minecraft/src/Pathfinder.java new file mode 100644 index 0000000..d2d0978 --- /dev/null +++ b/src/main/java/net/minecraft/src/Pathfinder.java @@ -0,0 +1,218 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class Pathfinder +{ + + public Pathfinder(IBlockAccess iblockaccess) + { + path = new Path(); + pointMap = new MCHashTable(); + pathOptions = new PathPoint[32]; + worldMap = iblockaccess; + } + + public PathEntity createEntityPathTo(Entity entity, Entity entity1, float f) + { + return createEntityPathTo(entity, entity1.posX, entity1.boundingBox.minY, entity1.posZ, f); + } + + public PathEntity createEntityPathTo(Entity entity, int i, int j, int k, float f) + { + return createEntityPathTo(entity, (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, f); + } + + private PathEntity createEntityPathTo(Entity entity, double d, double d1, double d2, + float f) + { + path.clearPath(); + pointMap.clearMap(); + PathPoint pathpoint = openPoint(MathHelper.floor_double(entity.boundingBox.minX), MathHelper.floor_double(entity.boundingBox.minY), MathHelper.floor_double(entity.boundingBox.minZ)); + PathPoint pathpoint1 = openPoint(MathHelper.floor_double(d - (double)(entity.width / 2.0F)), MathHelper.floor_double(d1), MathHelper.floor_double(d2 - (double)(entity.width / 2.0F))); + PathPoint pathpoint2 = new PathPoint(MathHelper.floor_float(entity.width + 1.0F), MathHelper.floor_float(entity.height + 1.0F), MathHelper.floor_float(entity.width + 1.0F)); + PathEntity pathentity = addToPath(entity, pathpoint, pathpoint1, pathpoint2, f); + return pathentity; + } + + private PathEntity addToPath(Entity entity, PathPoint pathpoint, PathPoint pathpoint1, PathPoint pathpoint2, float f) + { + pathpoint.totalPathDistance = 0.0F; + pathpoint.distanceToNext = pathpoint.distanceTo(pathpoint1); + pathpoint.distanceToTarget = pathpoint.distanceToNext; + path.clearPath(); + path.addPoint(pathpoint); + PathPoint pathpoint3 = pathpoint; + while(!path.isPathEmpty()) + { + PathPoint pathpoint4 = path.dequeue(); + if(pathpoint4.equals(pathpoint1)) + { + return createEntityPath(pathpoint, pathpoint1); + } + if(pathpoint4.distanceTo(pathpoint1) < pathpoint3.distanceTo(pathpoint1)) + { + pathpoint3 = pathpoint4; + } + pathpoint4.isFirst = true; + int i = findPathOptions(entity, pathpoint4, pathpoint2, pathpoint1, f); + int j = 0; + while(j < i) + { + PathPoint pathpoint5 = pathOptions[j]; + float f1 = pathpoint4.totalPathDistance + pathpoint4.distanceTo(pathpoint5); + if(!pathpoint5.isAssigned() || f1 < pathpoint5.totalPathDistance) + { + pathpoint5.previous = pathpoint4; + pathpoint5.totalPathDistance = f1; + pathpoint5.distanceToNext = pathpoint5.distanceTo(pathpoint1); + if(pathpoint5.isAssigned()) + { + path.changeDistance(pathpoint5, pathpoint5.totalPathDistance + pathpoint5.distanceToNext); + } else + { + pathpoint5.distanceToTarget = pathpoint5.totalPathDistance + pathpoint5.distanceToNext; + path.addPoint(pathpoint5); + } + } + j++; + } + } + if(pathpoint3 == pathpoint) + { + return null; + } else + { + return createEntityPath(pathpoint, pathpoint3); + } + } + + private int findPathOptions(Entity entity, PathPoint pathpoint, PathPoint pathpoint1, PathPoint pathpoint2, float f) + { + int i = 0; + int j = 0; + if(getVerticalOffset(entity, pathpoint.xCoord, pathpoint.yCoord + 1, pathpoint.zCoord, pathpoint1) > 0) + { + j = 1; + } + PathPoint pathpoint3 = getSafePoint(entity, pathpoint.xCoord, pathpoint.yCoord, pathpoint.zCoord + 1, pathpoint1, j); + PathPoint pathpoint4 = getSafePoint(entity, pathpoint.xCoord - 1, pathpoint.yCoord, pathpoint.zCoord, pathpoint1, j); + PathPoint pathpoint5 = getSafePoint(entity, pathpoint.xCoord + 1, pathpoint.yCoord, pathpoint.zCoord, pathpoint1, j); + PathPoint pathpoint6 = getSafePoint(entity, pathpoint.xCoord, pathpoint.yCoord, pathpoint.zCoord - 1, pathpoint1, j); + if(pathpoint3 != null && !pathpoint3.isFirst && pathpoint3.distanceTo(pathpoint2) < f) + { + pathOptions[i++] = pathpoint3; + } + if(pathpoint4 != null && !pathpoint4.isFirst && pathpoint4.distanceTo(pathpoint2) < f) + { + pathOptions[i++] = pathpoint4; + } + if(pathpoint5 != null && !pathpoint5.isFirst && pathpoint5.distanceTo(pathpoint2) < f) + { + pathOptions[i++] = pathpoint5; + } + if(pathpoint6 != null && !pathpoint6.isFirst && pathpoint6.distanceTo(pathpoint2) < f) + { + pathOptions[i++] = pathpoint6; + } + return i; + } + + private PathPoint getSafePoint(Entity entity, int i, int j, int k, PathPoint pathpoint, int l) + { + PathPoint pathpoint1 = null; + if(getVerticalOffset(entity, i, j, k, pathpoint) > 0) + { + pathpoint1 = openPoint(i, j, k); + } + if(pathpoint1 == null && l > 0 && getVerticalOffset(entity, i, j + l, k, pathpoint) > 0) + { + pathpoint1 = openPoint(i, j + l, k); + j += l; + } + if(pathpoint1 != null) + { + int i1 = 0; + for(int j1 = 0; j > 0 && (j1 = getVerticalOffset(entity, i, j - 1, k, pathpoint)) > 0; j--) + { + if(j1 < 0) + { + return null; + } + if(++i1 >= 4) + { + return null; + } + } + + if(j > 0) + { + pathpoint1 = openPoint(i, j, k); + } + } + return pathpoint1; + } + + private final PathPoint openPoint(int i, int j, int k) + { + int l = PathPoint.func_22329_a(i, j, k); + PathPoint pathpoint = (PathPoint)pointMap.lookup(l); + if(pathpoint == null) + { + pathpoint = new PathPoint(i, j, k); + pointMap.addKey(l, pathpoint); + } + return pathpoint; + } + + private int getVerticalOffset(Entity entity, int i, int j, int k, PathPoint pathpoint) + { + for(int l = i; l < i + pathpoint.xCoord; l++) + { + for(int i1 = j; i1 < j + pathpoint.yCoord; i1++) + { + for(int j1 = k; j1 < k + pathpoint.zCoord; j1++) + { + Material material = worldMap.getBlockMaterial(l, i1, j1); + if(material.getIsSolid()) + { + return 0; + } + if(material == Material.water || material == Material.lava) + { + return -1; + } + } + + } + + } + + return 1; + } + + private PathEntity createEntityPath(PathPoint pathpoint, PathPoint pathpoint1) + { + int i = 1; + for(PathPoint pathpoint2 = pathpoint1; pathpoint2.previous != null; pathpoint2 = pathpoint2.previous) + { + i++; + } + + PathPoint apathpoint[] = new PathPoint[i]; + PathPoint pathpoint3 = pathpoint1; + for(apathpoint[--i] = pathpoint3; pathpoint3.previous != null; apathpoint[--i] = pathpoint3) + { + pathpoint3 = pathpoint3.previous; + } + + return new PathEntity(apathpoint); + } + + private IBlockAccess worldMap; + private Path path; + private MCHashTable pointMap; + private PathPoint pathOptions[]; +} diff --git a/src/main/java/net/minecraft/src/PlayerController.java b/src/main/java/net/minecraft/src/PlayerController.java new file mode 100644 index 0000000..bc3b36e --- /dev/null +++ b/src/main/java/net/minecraft/src/PlayerController.java @@ -0,0 +1,137 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +public class PlayerController +{ + + public PlayerController(Minecraft minecraft) + { + field_1064_b = false; + mc = minecraft; + } + + public void func_717_a(World world) + { + } + + public void clickBlock(int i, int j, int k, int l) + { + sendBlockRemoved(i, j, k, l); + } + + public boolean sendBlockRemoved(int i, int j, int k, int l) + { + mc.effectRenderer.addBlockDestroyEffects(i, j, k); + World world = mc.theWorld; + Block block = Block.blocksList[world.getBlockId(i, j, k)]; + int i1 = world.getBlockMetadata(i, j, k); + boolean flag = world.setBlockWithNotify(i, j, k, 0); + if(block != null && flag) + { + mc.sndManager.playSound(block.stepSound.func_1146_a(), (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, (block.stepSound.func_1147_b() + 1.0F) / 2.0F, block.stepSound.func_1144_c() * 0.8F); + block.onBlockDestroyedByPlayer(world, i, j, k, i1); + } + return flag; + } + + public void sendBlockRemoving(int i, int j, int k, int l) + { + } + + public void func_6468_a() + { + } + + public void setPartialTime(float f) + { + } + + public float getBlockReachDistance() + { + return 5F; + } + + public boolean sendUseItem(EntityPlayer entityplayer, World world, ItemStack itemstack) + { + int i = itemstack.stackSize; + ItemStack itemstack1 = itemstack.useItemRightClick(world, entityplayer); + if(itemstack1 != itemstack || itemstack1 != null && itemstack1.stackSize != i) + { + entityplayer.inventory.mainInventory[entityplayer.inventory.currentItem] = itemstack1; + if(itemstack1.stackSize == 0) + { + entityplayer.inventory.mainInventory[entityplayer.inventory.currentItem] = null; + } + return true; + } else + { + return false; + } + } + + public void flipPlayer(EntityPlayer entityplayer) + { + } + + public void updateController() + { + } + + public boolean shouldDrawHUD() + { + return true; + } + + public void func_6473_b(EntityPlayer entityplayer) + { + } + + public boolean sendPlaceBlock(EntityPlayer entityplayer, World world, ItemStack itemstack, int i, int j, int k, int l) + { + int i1 = world.getBlockId(i, j, k); + if(i1 > 0 && Block.blocksList[i1].blockActivated(world, i, j, k, entityplayer)) + { + return true; + } + if(itemstack == null) + { + return false; + } else + { + return itemstack.useItem(entityplayer, world, i, j, k, l); + } + } + + public EntityPlayer func_4087_b(World world) + { + return new EntityPlayerSP(mc, world, mc.session, world.worldProvider.worldType); + } + + public void func_6475_a(EntityPlayer entityplayer, Entity entity) + { + entityplayer.useCurrentItemOnEntity(entity); + } + + public void func_6472_b(EntityPlayer entityplayer, Entity entity) + { + entityplayer.attackTargetEntityWithCurrentItem(entity); + } + + public ItemStack func_20085_a(int i, int j, int k, EntityPlayer entityplayer) + { + return entityplayer.craftingInventory.func_20116_a(j, k, entityplayer); + } + + public void func_20086_a(int i, EntityPlayer entityplayer) + { + entityplayer.craftingInventory.onCraftGuiClosed(entityplayer); + entityplayer.craftingInventory = entityplayer.inventorySlots; + } + + protected final Minecraft mc; + public boolean field_1064_b; +} diff --git a/src/main/java/net/minecraft/src/PlayerControllerMP.java b/src/main/java/net/minecraft/src/PlayerControllerMP.java new file mode 100644 index 0000000..6a5eb4c --- /dev/null +++ b/src/main/java/net/minecraft/src/PlayerControllerMP.java @@ -0,0 +1,228 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +public class PlayerControllerMP extends PlayerController +{ + + public PlayerControllerMP(Minecraft minecraft, NetClientHandler netclienthandler) + { + super(minecraft); + field_9445_c = -1; + field_9444_d = -1; + field_9443_e = -1; + field_9442_f = 0.0F; + field_1080_g = 0.0F; + field_9441_h = 0.0F; + field_9440_i = 0; + field_9439_j = false; + field_1075_l = 0; + field_9438_k = netclienthandler; + } + + public void flipPlayer(EntityPlayer entityplayer) + { + entityplayer.rotationYaw = -180F; + } + + public boolean sendBlockRemoved(int i, int j, int k, int l) + { + int i1 = mc.theWorld.getBlockId(i, j, k); + boolean flag = super.sendBlockRemoved(i, j, k, l); + ItemStack itemstack = mc.thePlayer.getCurrentEquippedItem(); + if(itemstack != null) + { + itemstack.hitBlock(i1, i, j, k); + if(itemstack.stackSize == 0) + { + itemstack.func_1097_a(mc.thePlayer); + mc.thePlayer.destroyCurrentEquippedItem(); + } + } + return flag; + } + + public void clickBlock(int i, int j, int k, int l) + { + if(!field_9439_j || i != field_9445_c || j != field_9444_d || k != field_9443_e) + { + field_9438_k.addToSendQueue(new Packet14BlockDig(0, i, j, k, l)); + int i1 = mc.theWorld.getBlockId(i, j, k); + if(i1 > 0 && field_9442_f == 0.0F) + { + Block.blocksList[i1].onBlockClicked(mc.theWorld, i, j, k, mc.thePlayer); + } + if(i1 > 0 && Block.blocksList[i1].blockStrength(mc.thePlayer) >= 1.0F) + { + sendBlockRemoved(i, j, k, l); + } else + { + field_9439_j = true; + field_9445_c = i; + field_9444_d = j; + field_9443_e = k; + field_9442_f = 0.0F; + field_1080_g = 0.0F; + field_9441_h = 0.0F; + } + } + } + + public void func_6468_a() + { + field_9442_f = 0.0F; + field_9439_j = false; + } + + public void sendBlockRemoving(int i, int j, int k, int l) + { + if(!field_9439_j) + { + return; + } + func_730_e(); + if(field_9440_i > 0) + { + field_9440_i--; + return; + } + if(i == field_9445_c && j == field_9444_d && k == field_9443_e) + { + int i1 = mc.theWorld.getBlockId(i, j, k); + if(i1 == 0) + { + field_9439_j = false; + return; + } + Block block = Block.blocksList[i1]; + field_9442_f += block.blockStrength(mc.thePlayer); + if(field_9441_h % 4F == 0.0F && block != null) + { + mc.sndManager.playSound(block.stepSound.func_1145_d(), (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, (block.stepSound.func_1147_b() + 1.0F) / 8F, block.stepSound.func_1144_c() * 0.5F); + } + field_9441_h++; + if(field_9442_f >= 1.0F) + { + field_9439_j = false; + field_9438_k.addToSendQueue(new Packet14BlockDig(2, i, j, k, l)); + sendBlockRemoved(i, j, k, l); + field_9442_f = 0.0F; + field_1080_g = 0.0F; + field_9441_h = 0.0F; + field_9440_i = 5; + } + } else + { + clickBlock(i, j, k, l); + } + } + + public void setPartialTime(float f) + { + if(field_9442_f <= 0.0F) + { + mc.ingameGUI.field_6446_b = 0.0F; + mc.renderGlobal.field_1450_i = 0.0F; + } else + { + float f1 = field_1080_g + (field_9442_f - field_1080_g) * f; + mc.ingameGUI.field_6446_b = f1; + mc.renderGlobal.field_1450_i = f1; + } + } + + public float getBlockReachDistance() + { + return 4F; + } + + public void func_717_a(World world) + { + super.func_717_a(world); + } + + public void updateController() + { + func_730_e(); + field_1080_g = field_9442_f; + mc.sndManager.playRandomMusicIfReady(); + } + + private void func_730_e() + { + int i = mc.thePlayer.inventory.currentItem; + if(i != field_1075_l) + { + field_1075_l = i; + field_9438_k.addToSendQueue(new Packet16BlockItemSwitch(field_1075_l)); + } + } + + public boolean sendPlaceBlock(EntityPlayer entityplayer, World world, ItemStack itemstack, int i, int j, int k, int l) + { + func_730_e(); + field_9438_k.addToSendQueue(new Packet15Place(i, j, k, l, entityplayer.inventory.getCurrentItem())); + boolean flag = super.sendPlaceBlock(entityplayer, world, itemstack, i, j, k, l); + return flag; + } + + public boolean sendUseItem(EntityPlayer entityplayer, World world, ItemStack itemstack) + { + func_730_e(); + field_9438_k.addToSendQueue(new Packet15Place(-1, -1, -1, 255, entityplayer.inventory.getCurrentItem())); + boolean flag = super.sendUseItem(entityplayer, world, itemstack); + return flag; + } + + public EntityPlayer func_4087_b(World world) + { + return new EntityClientPlayerMP(mc, world, mc.session, field_9438_k); + } + + public void func_6472_b(EntityPlayer entityplayer, Entity entity) + { + func_730_e(); + field_9438_k.addToSendQueue(new Packet7(entityplayer.entityId, entity.entityId, 1)); + entityplayer.attackTargetEntityWithCurrentItem(entity); + } + + public void func_6475_a(EntityPlayer entityplayer, Entity entity) + { + func_730_e(); + field_9438_k.addToSendQueue(new Packet7(entityplayer.entityId, entity.entityId, 0)); + entityplayer.useCurrentItemOnEntity(entity); + } + + public ItemStack func_20085_a(int i, int j, int k, EntityPlayer entityplayer) + { + short word0 = entityplayer.craftingInventory.func_20111_a(entityplayer.inventory); + ItemStack itemstack = super.func_20085_a(i, j, k, entityplayer); + field_9438_k.addToSendQueue(new Packet102(i, j, k, itemstack, word0)); + return itemstack; + } + + public void func_20086_a(int i, EntityPlayer entityplayer) + { + if(i == -9999) + { + return; + } else + { + return; + } + } + + private int field_9445_c; + private int field_9444_d; + private int field_9443_e; + private float field_9442_f; + private float field_1080_g; + private float field_9441_h; + private int field_9440_i; + private boolean field_9439_j; + private NetClientHandler field_9438_k; + private int field_1075_l; +} diff --git a/src/main/java/net/minecraft/src/PlayerControllerSP.java b/src/main/java/net/minecraft/src/PlayerControllerSP.java new file mode 100644 index 0000000..699ca14 --- /dev/null +++ b/src/main/java/net/minecraft/src/PlayerControllerSP.java @@ -0,0 +1,147 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +public class PlayerControllerSP extends PlayerController +{ + + public PlayerControllerSP(Minecraft minecraft) + { + super(minecraft); + field_1074_c = -1; + field_1073_d = -1; + field_1072_e = -1; + curBlockDamage = 0.0F; + prevBlockDamage = 0.0F; + field_1069_h = 0.0F; + field_1068_i = 0; + } + + public void flipPlayer(EntityPlayer entityplayer) + { + entityplayer.rotationYaw = -180F; + } + + public boolean sendBlockRemoved(int i, int j, int k, int l) + { + int i1 = mc.theWorld.getBlockId(i, j, k); + int j1 = mc.theWorld.getBlockMetadata(i, j, k); + boolean flag = super.sendBlockRemoved(i, j, k, l); + ItemStack itemstack = mc.thePlayer.getCurrentEquippedItem(); + boolean flag1 = mc.thePlayer.canHarvestBlock(Block.blocksList[i1]); + if(itemstack != null) + { + itemstack.hitBlock(i1, i, j, k); + if(itemstack.stackSize == 0) + { + itemstack.func_1097_a(mc.thePlayer); + mc.thePlayer.destroyCurrentEquippedItem(); + } + } + if(flag && flag1) + { + Block.blocksList[i1].harvestBlock(mc.theWorld, i, j, k, j1); + } + return flag; + } + + public void clickBlock(int i, int j, int k, int l) + { + int i1 = mc.theWorld.getBlockId(i, j, k); + if(i1 > 0 && curBlockDamage == 0.0F) + { + Block.blocksList[i1].onBlockClicked(mc.theWorld, i, j, k, mc.thePlayer); + } + if(i1 > 0 && Block.blocksList[i1].blockStrength(mc.thePlayer) >= 1.0F) + { + sendBlockRemoved(i, j, k, l); + } + } + + public void func_6468_a() + { + curBlockDamage = 0.0F; + field_1068_i = 0; + } + + public void sendBlockRemoving(int i, int j, int k, int l) + { + if(field_1068_i > 0) + { + field_1068_i--; + return; + } + if(i == field_1074_c && j == field_1073_d && k == field_1072_e) + { + int i1 = mc.theWorld.getBlockId(i, j, k); + if(i1 == 0) + { + return; + } + Block block = Block.blocksList[i1]; + curBlockDamage += block.blockStrength(mc.thePlayer); + if(field_1069_h % 4F == 0.0F && block != null) + { + mc.sndManager.playSound(block.stepSound.func_1145_d(), (float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, (block.stepSound.func_1147_b() + 1.0F) / 8F, block.stepSound.func_1144_c() * 0.5F); + } + field_1069_h++; + if(curBlockDamage >= 1.0F) + { + sendBlockRemoved(i, j, k, l); + curBlockDamage = 0.0F; + prevBlockDamage = 0.0F; + field_1069_h = 0.0F; + field_1068_i = 5; + } + } else + { + curBlockDamage = 0.0F; + prevBlockDamage = 0.0F; + field_1069_h = 0.0F; + field_1074_c = i; + field_1073_d = j; + field_1072_e = k; + } + } + + public void setPartialTime(float f) + { + if(curBlockDamage <= 0.0F) + { + mc.ingameGUI.field_6446_b = 0.0F; + mc.renderGlobal.field_1450_i = 0.0F; + } else + { + float f1 = prevBlockDamage + (curBlockDamage - prevBlockDamage) * f; + mc.ingameGUI.field_6446_b = f1; + mc.renderGlobal.field_1450_i = f1; + } + } + + public float getBlockReachDistance() + { + return 4F; + } + + public void func_717_a(World world) + { + super.func_717_a(world); + } + + public void updateController() + { + prevBlockDamage = curBlockDamage; + mc.sndManager.playRandomMusicIfReady(); + } + + private int field_1074_c; + private int field_1073_d; + private int field_1072_e; + private float curBlockDamage; + private float prevBlockDamage; + private float field_1069_h; + private int field_1068_i; +} diff --git a/src/main/java/net/minecraft/src/PositionTexureVertex.java b/src/main/java/net/minecraft/src/PositionTexureVertex.java new file mode 100644 index 0000000..447fb80 --- /dev/null +++ b/src/main/java/net/minecraft/src/PositionTexureVertex.java @@ -0,0 +1,37 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class PositionTexureVertex +{ + + public PositionTexureVertex(float f, float f1, float f2, float f3, float f4) + { + this(Vec3D.createVectorHelper(f, f1, f2), f3, f4); + } + + public PositionTexureVertex setTexturePosition(float f, float f1) + { + return new PositionTexureVertex(this, f, f1); + } + + public PositionTexureVertex(PositionTexureVertex positiontexurevertex, float f, float f1) + { + vector3D = positiontexurevertex.vector3D; + texturePositionX = f; + texturePositionY = f1; + } + + public PositionTexureVertex(Vec3D vec3d, float f, float f1) + { + vector3D = vec3d; + texturePositionX = f; + texturePositionY = f1; + } + + public Vec3D vector3D; + public float texturePositionX; + public float texturePositionY; +} diff --git a/src/main/java/net/minecraft/src/RecipeSorter.java b/src/main/java/net/minecraft/src/RecipeSorter.java new file mode 100644 index 0000000..0cc11f1 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipeSorter.java @@ -0,0 +1,40 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Comparator; + +class RecipeSorter + implements Comparator +{ + + RecipeSorter(CraftingManager craftingmanager) + { + craftingManager = craftingmanager; + } + + public int compareRecipes(IRecipe irecipe, IRecipe irecipe1) + { + if((irecipe instanceof ShapelessRecipes) && (irecipe1 instanceof ShapedRecipes)) + { + return 1; + } + if((irecipe1 instanceof ShapelessRecipes) && (irecipe instanceof ShapedRecipes)) + { + return -1; + } + if(irecipe1.getRecipeSize() < irecipe.getRecipeSize()) + { + return -1; + } + return irecipe1.getRecipeSize() <= irecipe.getRecipeSize() ? 0 : 1; + } + + public int compare(Object obj, Object obj1) + { + return compareRecipes((IRecipe)obj, (IRecipe)obj1); + } + + final CraftingManager craftingManager; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/RecipesArmor.java b/src/main/java/net/minecraft/src/RecipesArmor.java new file mode 100644 index 0000000..ec13166 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesArmor.java @@ -0,0 +1,56 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesArmor +{ + + public RecipesArmor() + { + recipeItems = (new Object[][] { + new Object[] { + Item.leather, Block.fire, Item.ingotIron, Item.diamond, Item.ingotGold + }, new Object[] { + Item.helmetLeather, Item.helmetChain, Item.helmetSteel, Item.helmetDiamond, Item.helmetGold + }, new Object[] { + Item.plateLeather, Item.plateChain, Item.plateSteel, Item.plateDiamond, Item.plateGold + }, new Object[] { + Item.legsLeather, Item.legsChain, Item.legsSteel, Item.legsDiamond, Item.legsGold + }, new Object[] { + Item.bootsLeather, Item.bootsChain, Item.bootsSteel, Item.bootsDiamond, Item.bootsGold + } + }); + } + + public void addRecipes(CraftingManager craftingmanager) + { + for(int i = 0; i < recipeItems[0].length; i++) + { + Object obj = recipeItems[0][i]; + for(int j = 0; j < recipeItems.length - 1; j++) + { + Item item = (Item)recipeItems[j + 1][i]; + craftingmanager.addRecipe(new ItemStack(item), new Object[] { + recipePatterns[j], Character.valueOf('X'), obj + }); + } + + } + + } + + private String recipePatterns[][] = { + { + "XXX", "X X" + }, { + "X X", "XXX", "XXX" + }, { + "XXX", "X X", "X X" + }, { + "X X", "X X" + } + }; + private Object recipeItems[][]; +} diff --git a/src/main/java/net/minecraft/src/RecipesCrafting.java b/src/main/java/net/minecraft/src/RecipesCrafting.java new file mode 100644 index 0000000..800adf2 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesCrafting.java @@ -0,0 +1,29 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesCrafting +{ + + public RecipesCrafting() + { + } + + public void addRecipes(CraftingManager craftingmanager) + { + craftingmanager.addRecipe(new ItemStack(Block.crate), new Object[] { + "###", "# #", "###", Character.valueOf('#'), Block.planks + }); + craftingmanager.addRecipe(new ItemStack(Block.stoneOvenIdle), new Object[] { + "###", "# #", "###", Character.valueOf('#'), Block.cobblestone + }); + craftingmanager.addRecipe(new ItemStack(Block.workbench), new Object[] { + "##", "##", Character.valueOf('#'), Block.planks + }); + craftingmanager.addRecipe(new ItemStack(Block.sandStone), new Object[] { + "##", "##", Character.valueOf('#'), Block.sand + }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesDyes.java b/src/main/java/net/minecraft/src/RecipesDyes.java new file mode 100644 index 0000000..39b904a --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesDyes.java @@ -0,0 +1,69 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesDyes +{ + + public RecipesDyes() + { + } + + public void addRecipes(CraftingManager craftingmanager) + { + for(int i = 0; i < 16; i++) + { + craftingmanager.addShapelessRecipe(new ItemStack(Block.cloth, 1, BlockCloth.func_21035_d(i)), new Object[] { + new ItemStack(Item.dyePowder, 1, i), new ItemStack(Item.itemsList[Block.cloth.blockID], 1, 0) + }); + } + + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 11), new Object[] { + Block.plantYellow + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 1), new Object[] { + Block.plantRed + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 15), new Object[] { + Item.bone + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 9), new Object[] { + new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 15) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 14), new Object[] { + new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 11) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 10), new Object[] { + new ItemStack(Item.dyePowder, 1, 2), new ItemStack(Item.dyePowder, 1, 15) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 8), new Object[] { + new ItemStack(Item.dyePowder, 1, 0), new ItemStack(Item.dyePowder, 1, 15) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 7), new Object[] { + new ItemStack(Item.dyePowder, 1, 8), new ItemStack(Item.dyePowder, 1, 15) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 7), new Object[] { + new ItemStack(Item.dyePowder, 1, 0), new ItemStack(Item.dyePowder, 1, 15), new ItemStack(Item.dyePowder, 1, 15) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 12), new Object[] { + new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 15) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 6), new Object[] { + new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 2) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 5), new Object[] { + new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 13), new Object[] { + new ItemStack(Item.dyePowder, 1, 5), new ItemStack(Item.dyePowder, 1, 9) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 13), new Object[] { + new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 9) + }); + craftingmanager.addShapelessRecipe(new ItemStack(Item.dyePowder, 4, 13), new Object[] { + new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 15) + }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesFood.java b/src/main/java/net/minecraft/src/RecipesFood.java new file mode 100644 index 0000000..e7d7617 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesFood.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesFood +{ + + public RecipesFood() + { + } + + public void addRecipes(CraftingManager craftingmanager) + { + craftingmanager.addRecipe(new ItemStack(Item.bowlSoup), new Object[] { + "Y", "X", "#", Character.valueOf('X'), Block.mushroomBrown, Character.valueOf('Y'), Block.mushroomRed, Character.valueOf('#'), Item.bowlEmpty + }); + craftingmanager.addRecipe(new ItemStack(Item.bowlSoup), new Object[] { + "Y", "X", "#", Character.valueOf('X'), Block.mushroomRed, Character.valueOf('Y'), Block.mushroomBrown, Character.valueOf('#'), Item.bowlEmpty + }); + } +} diff --git a/src/main/java/net/minecraft/src/RecipesIngots.java b/src/main/java/net/minecraft/src/RecipesIngots.java new file mode 100644 index 0000000..5ea97cf --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesIngots.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesIngots +{ + + public RecipesIngots() + { + recipeItems = (new Object[][] { + new Object[] { + Block.blockGold, new ItemStack(Item.ingotGold, 9) + }, new Object[] { + Block.blockSteel, new ItemStack(Item.ingotIron, 9) + }, new Object[] { + Block.blockDiamond, new ItemStack(Item.diamond, 9) + }, new Object[] { + Block.blockLapis, new ItemStack(Item.dyePowder, 9, 4) + } + }); + } + + public void addRecipes(CraftingManager craftingmanager) + { + for(int i = 0; i < recipeItems.length; i++) + { + Block block = (Block)recipeItems[i][0]; + ItemStack itemstack = (ItemStack)recipeItems[i][1]; + craftingmanager.addRecipe(new ItemStack(block), new Object[] { + "###", "###", "###", Character.valueOf('#'), itemstack + }); + craftingmanager.addRecipe(itemstack, new Object[] { + "#", Character.valueOf('#'), block + }); + } + + } + + private Object recipeItems[][]; +} diff --git a/src/main/java/net/minecraft/src/RecipesTools.java b/src/main/java/net/minecraft/src/RecipesTools.java new file mode 100644 index 0000000..0b44775 --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesTools.java @@ -0,0 +1,56 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesTools +{ + + public RecipesTools() + { + recipeItems = (new Object[][] { + new Object[] { + Block.planks, Block.cobblestone, Item.ingotIron, Item.diamond, Item.ingotGold + }, new Object[] { + Item.pickaxeWood, Item.pickaxeStone, Item.pickaxeSteel, Item.pickaxeDiamond, Item.pickaxeGold + }, new Object[] { + Item.shovelWood, Item.shovelStone, Item.shovelSteel, Item.shovelDiamond, Item.shovelGold + }, new Object[] { + Item.axeWood, Item.axeStone, Item.axeSteel, Item.axeDiamond, Item.axeGold + }, new Object[] { + Item.hoeWood, Item.hoeStone, Item.hoeSteel, Item.hoeDiamond, Item.hoeGold + } + }); + } + + public void addRecipes(CraftingManager craftingmanager) + { + for(int i = 0; i < recipeItems[0].length; i++) + { + Object obj = recipeItems[0][i]; + for(int j = 0; j < recipeItems.length - 1; j++) + { + Item item = (Item)recipeItems[j + 1][i]; + craftingmanager.addRecipe(new ItemStack(item), new Object[] { + recipePatterns[j], Character.valueOf('#'), Item.stick, Character.valueOf('X'), obj + }); + } + + } + + } + + private String recipePatterns[][] = { + { + "XXX", " # ", " # " + }, { + "X", "#", "#" + }, { + "XX", "X#", " #" + }, { + "XX", " #", " #" + } + }; + private Object recipeItems[][]; +} diff --git a/src/main/java/net/minecraft/src/RecipesWeapons.java b/src/main/java/net/minecraft/src/RecipesWeapons.java new file mode 100644 index 0000000..298e02f --- /dev/null +++ b/src/main/java/net/minecraft/src/RecipesWeapons.java @@ -0,0 +1,50 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RecipesWeapons +{ + + public RecipesWeapons() + { + recipeItems = (new Object[][] { + new Object[] { + Block.planks, Block.cobblestone, Item.ingotIron, Item.diamond, Item.ingotGold + }, new Object[] { + Item.swordWood, Item.swordStone, Item.swordSteel, Item.swordDiamond, Item.swordGold + } + }); + } + + public void addRecipes(CraftingManager craftingmanager) + { + for(int i = 0; i < recipeItems[0].length; i++) + { + Object obj = recipeItems[0][i]; + for(int j = 0; j < recipeItems.length - 1; j++) + { + Item item = (Item)recipeItems[j + 1][i]; + craftingmanager.addRecipe(new ItemStack(item), new Object[] { + recipePatterns[j], Character.valueOf('#'), Item.stick, Character.valueOf('X'), obj + }); + } + + } + + craftingmanager.addRecipe(new ItemStack(Item.bow, 1), new Object[] { + " #X", "# X", " #X", Character.valueOf('X'), Item.silk, Character.valueOf('#'), Item.stick + }); + craftingmanager.addRecipe(new ItemStack(Item.arrow, 4), new Object[] { + "X", "#", "Y", Character.valueOf('Y'), Item.feather, Character.valueOf('X'), Item.flint, Character.valueOf('#'), Item.stick + }); + } + + private String recipePatterns[][] = { + { + "X", "X", "#" + } + }; + private Object recipeItems[][]; +} diff --git a/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java b/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java new file mode 100644 index 0000000..6ad6de1 --- /dev/null +++ b/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java @@ -0,0 +1,22 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class RedstoneUpdateInfo +{ + + public RedstoneUpdateInfo(int i, int j, int k, long l) + { + x = i; + y = j; + z = k; + updateTime = l; + } + + int x; + int y; + int z; + long updateTime; +} diff --git a/src/main/java/net/minecraft/src/RegionFile.java b/src/main/java/net/minecraft/src/RegionFile.java new file mode 100644 index 0000000..612611f --- /dev/null +++ b/src/main/java/net/minecraft/src/RegionFile.java @@ -0,0 +1,326 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.ArrayList; +import java.util.zip.*; + +public class RegionFile +{ + + public RegionFile(File file) + { + field_22214_h = 0L; + field_22212_b = file; + func_22204_b((new StringBuilder()).append("REGION LOAD ").append(field_22212_b).toString()); + field_22215_g = 0; + try + { + if(file.exists()) + { + field_22214_h = file.lastModified(); + } + field_22219_c = new RandomAccessFile(file, "rw"); + if(field_22219_c.length() < 4096L) + { + for(int i = 0; i < 1024; i++) + { + field_22219_c.writeInt(0); + } + + for(int j = 0; j < 1024; j++) + { + field_22219_c.writeInt(0); + } + + field_22215_g += 8192; + } + if((field_22219_c.length() & 4095L) != 0L) + { + for(int k = 0; (long)k < (field_22219_c.length() & 4095L); k++) + { + field_22219_c.write(0); + } + + } + int l = (int)field_22219_c.length() / 4096; + field_22216_f = new ArrayList(l); + for(int i1 = 0; i1 < l; i1++) + { + field_22216_f.add(Boolean.valueOf(true)); + } + + field_22216_f.set(0, Boolean.valueOf(false)); + field_22216_f.set(1, Boolean.valueOf(false)); + field_22219_c.seek(0L); + for(int j1 = 0; j1 < 1024; j1++) + { + int l1 = field_22219_c.readInt(); + field_22218_d[j1] = l1; + if(l1 == 0 || (l1 >> 8) + (l1 & 0xff) > field_22216_f.size()) + { + continue; + } + for(int j2 = 0; j2 < (l1 & 0xff); j2++) + { + field_22216_f.set((l1 >> 8) + j2, Boolean.valueOf(false)); + } + + } + + for(int k1 = 0; k1 < 1024; k1++) + { + int i2 = field_22219_c.readInt(); + field_22217_e[k1] = i2; + } + + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + public synchronized int func_22209_a() + { + int i = field_22215_g; + field_22215_g = 0; + return i; + } + + private void func_22211_a(String s) + { + } + + private void func_22204_b(String s) + { + func_22211_a((new StringBuilder()).append(s).append("\n").toString()); + } + + private void func_22199_a(String s, int i, int j, String s1) + { + func_22211_a((new StringBuilder()).append("REGION ").append(s).append(" ").append(field_22212_b.getName()).append("[").append(i).append(",").append(j).append("] = ").append(s1).toString()); + } + + private void func_22197_a(String s, int i, int j, int k, String s1) + { + func_22211_a((new StringBuilder()).append("REGION ").append(s).append(" ").append(field_22212_b.getName()).append("[").append(i).append(",").append(j).append("] ").append(k).append("B = ").append(s1).toString()); + } + + private void func_22201_b(String s, int i, int j, String s1) + { + func_22199_a(s, i, j, (new StringBuilder()).append(s1).append("\n").toString()); + } + + public synchronized DataInputStream func_22210_a(int i, int j) + { + if(func_22206_d(i, j)) + { + func_22201_b("READ", i, j, "out of bounds"); + return null; + } + try + { + int k = func_22207_e(i, j); + if(k == 0) + { + return null; + } + int l = k >> 8; + int i1 = k & 0xff; + if(l + i1 > field_22216_f.size()) + { + func_22201_b("READ", i, j, "invalid sector"); + return null; + } + field_22219_c.seek(l * 4096); + int j1 = field_22219_c.readInt(); + if(j1 > 4096 * i1) + { + func_22201_b("READ", i, j, (new StringBuilder()).append("invalid length: ").append(j1).append(" > 4096 * ").append(i1).toString()); + return null; + } + byte byte0 = field_22219_c.readByte(); + if(byte0 == 1) + { + byte abyte0[] = new byte[j1 - 1]; + field_22219_c.read(abyte0); + DataInputStream datainputstream = new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte0))); + return datainputstream; + } + if(byte0 == 2) + { + byte abyte1[] = new byte[j1 - 1]; + field_22219_c.read(abyte1); + DataInputStream datainputstream1 = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte1))); + return datainputstream1; + } else + { + func_22201_b("READ", i, j, (new StringBuilder()).append("unknown version ").append(byte0).toString()); + return null; + } + } + catch(IOException ioexception) + { + func_22201_b("READ", i, j, "exception"); + } + return null; + } + + public DataOutputStream func_22205_b(int i, int j) + { + if(func_22206_d(i, j)) + { + return null; + } else + { + return new DataOutputStream(new DeflaterOutputStream(new RegionFileChunkBuffer(this, i, j))); + } + } + + protected synchronized void func_22203_a(int i, int j, byte abyte0[], int k) + { + try + { + int l = func_22207_e(i, j); + int i1 = l >> 8; + int l1 = l & 0xff; + int i2 = (k + 5) / 4096 + 1; + if(i2 >= 256) + { + return; + } + if(i1 != 0 && l1 == i2) + { + func_22197_a("SAVE", i, j, k, "rewrite"); + func_22200_a(i1, abyte0, k); + } else + { + for(int j2 = 0; j2 < l1; j2++) + { + field_22216_f.set(i1 + j2, Boolean.valueOf(true)); + } + + int k2 = field_22216_f.indexOf(Boolean.valueOf(true)); + int l2 = 0; + if(k2 != -1) + { + int i3 = k2; + do + { + if(i3 >= field_22216_f.size()) + { + break; + } + if(l2 != 0) + { + if(((Boolean)field_22216_f.get(i3)).booleanValue()) + { + l2++; + } else + { + l2 = 0; + } + } else + if(((Boolean)field_22216_f.get(i3)).booleanValue()) + { + k2 = i3; + l2 = 1; + } + if(l2 >= i2) + { + break; + } + i3++; + } while(true); + } + if(l2 >= i2) + { + func_22197_a("SAVE", i, j, k, "reuse"); + int j1 = k2; + func_22198_a(i, j, j1 << 8 | i2); + for(int j3 = 0; j3 < i2; j3++) + { + field_22216_f.set(j1 + j3, Boolean.valueOf(false)); + } + + func_22200_a(j1, abyte0, k); + } else + { + func_22197_a("SAVE", i, j, k, "grow"); + field_22219_c.seek(field_22219_c.length()); + int k1 = field_22216_f.size(); + for(int k3 = 0; k3 < i2; k3++) + { + field_22219_c.write(field_22213_a); + field_22216_f.add(Boolean.valueOf(false)); + } + + field_22215_g += 4096 * i2; + func_22200_a(k1, abyte0, k); + func_22198_a(i, j, k1 << 8 | i2); + } + } + func_22208_b(i, j, (int)(System.currentTimeMillis() / 1000L)); + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + private void func_22200_a(int i, byte abyte0[], int j) throws IOException + { + func_22204_b((new StringBuilder()).append(" ").append(i).toString()); + field_22219_c.seek(i * 4096); + field_22219_c.writeInt(j + 1); + field_22219_c.writeByte(2); + field_22219_c.write(abyte0, 0, j); + } + + private boolean func_22206_d(int i, int j) + { + return i < 0 || i >= 32 || j < 0 || j >= 32; + } + + private int func_22207_e(int i, int j) + { + return field_22218_d[i + j * 32]; + } + + public boolean func_22202_c(int i, int j) + { + return func_22207_e(i, j) != 0; + } + + private void func_22198_a(int i, int j, int k) throws IOException + { + field_22218_d[i + j * 32] = k; + field_22219_c.seek((i + j * 32) * 4); + field_22219_c.writeInt(k); + } + + private void func_22208_b(int i, int j, int k) throws IOException + { + field_22217_e[i + j * 32] = k; + field_22219_c.seek(4096 + (i + j * 32) * 4); + field_22219_c.writeInt(k); + } + + public void func_22196_b() throws IOException + { + field_22219_c.close(); + } + + private static final byte field_22213_a[] = new byte[4096]; + private final File field_22212_b; + private RandomAccessFile field_22219_c; + private final int field_22218_d[] = new int[1024]; + private final int field_22217_e[] = new int[1024]; + private ArrayList field_22216_f; + private int field_22215_g; + private long field_22214_h; + +} diff --git a/src/main/java/net/minecraft/src/RegionFileCache.java b/src/main/java/net/minecraft/src/RegionFileCache.java new file mode 100644 index 0000000..8b5ee2a --- /dev/null +++ b/src/main/java/net/minecraft/src/RegionFileCache.java @@ -0,0 +1,90 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.util.*; + +public class RegionFileCache +{ + + private RegionFileCache() + { + } + + public static synchronized RegionFile func_22193_a(File file, int i, int j) + { + File file1 = new File(file, "region"); + File file2 = new File(file1, (new StringBuilder()).append("r.").append(i >> 5).append(".").append(j >> 5).append(".mcr").toString()); + Reference reference = (Reference)field_22195_a.get(file2); + if(reference != null) + { + RegionFile regionfile = (RegionFile)reference.get(); + if(regionfile != null) + { + return regionfile; + } + } + if(!file1.exists()) + { + file1.mkdirs(); + } + if(field_22195_a.size() >= 256) + { + func_22192_a(); + } + RegionFile regionfile1 = new RegionFile(file2); + field_22195_a.put(file2, new SoftReference(regionfile1)); + return regionfile1; + } + + public static synchronized void func_22192_a() + { + Iterator iterator = field_22195_a.values().iterator(); + do + { + if(!iterator.hasNext()) + { + break; + } + Reference reference = (Reference)iterator.next(); + try + { + RegionFile regionfile = (RegionFile)reference.get(); + if(regionfile != null) + { + regionfile.func_22196_b(); + } + } + catch(Throwable ioexception) + { + ioexception.printStackTrace(); + } + } while(true); + field_22195_a.clear(); + } + + public static int func_22191_b(File file, int i, int j) + { + RegionFile regionfile = func_22193_a(file, i, j); + return regionfile.func_22209_a(); + } + + public static DataInputStream func_22194_c(File file, int i, int j) + { + RegionFile regionfile = func_22193_a(file, i, j); + return regionfile.func_22210_a(i & 0x1f, j & 0x1f); + } + + public static DataOutputStream func_22190_d(File file, int i, int j) + { + RegionFile regionfile = func_22193_a(file, i, j); + return regionfile.func_22205_b(i & 0x1f, j & 0x1f); + } + + private static final Map field_22195_a = new HashMap(); + +} diff --git a/src/main/java/net/minecraft/src/RegionFileChunkBuffer.java b/src/main/java/net/minecraft/src/RegionFileChunkBuffer.java new file mode 100644 index 0000000..16beb5f --- /dev/null +++ b/src/main/java/net/minecraft/src/RegionFileChunkBuffer.java @@ -0,0 +1,27 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.ByteArrayOutputStream; + +class RegionFileChunkBuffer extends ByteArrayOutputStream +{ + + public RegionFileChunkBuffer(RegionFile regionfile, int i, int j) + { + super(8096); + field_22284_a = regionfile; + field_22283_b = i; + field_22285_c = j; + } + + public void close() + { + field_22284_a.func_22203_a(field_22283_b, field_22285_c, buf, count); + } + + private int field_22283_b; + private int field_22285_c; + final RegionFile field_22284_a; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/Render.java b/src/main/java/net/minecraft/src/Render.java new file mode 100644 index 0000000..d5a402c --- /dev/null +++ b/src/main/java/net/minecraft/src/Render.java @@ -0,0 +1,275 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public abstract class Render +{ + + public Render() + { + field_195_d = new ModelBiped(); + field_203_d = new RenderBlocks(); + shadowSize = 0.0F; + field_194_c = 1.0F; + } + + public abstract void doRender(Entity entity, double d, double d1, double d2, + float f, float f1); + + protected void loadTexture(String s) + { + RenderEngine renderengine = renderManager.renderEngine; + renderengine.bindTexture(renderengine.getTexture(s)); + } + + protected boolean loadDownloadableImageTexture(String s, String s1) + { + RenderEngine renderengine = renderManager.renderEngine; + int i = renderengine.getTextureForDownloadableImage(s, s1); + if(i >= 0) + { + renderengine.bindTexture(i); + return true; + } else + { + return false; + } + } + + private void renderEntityOnFire(Entity entity, double d, double d1, double d2, + float f) + { + GL11.glDisable(2896 /*GL_LIGHTING*/); + int i = Block.fire.blockIndexInTexture; + int j = (i & 0xf) << 4; + int k = i & 0xf0; + float f1 = (float)j / 256F; + float f2 = ((float)j + 15.99F) / 256F; + float f3 = (float)k / 256F; + float f4 = ((float)k + 15.99F) / 256F; + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + float f5 = entity.width * 1.4F; + GL11.glScalef(f5, f5, f5); + loadTexture("/terrain.png"); + Tessellator tessellator = Tessellator.instance; + float f6 = 1.0F; + float f7 = 0.5F; + float f8 = 0.0F; + float f9 = entity.height / entity.width; + GL11.glRotatef(-renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(0.0F, 0.0F, -0.4F + (float)(int)f9 * 0.02F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tessellator.startDrawingQuads(); + while(f9 > 0.0F) + { + tessellator.addVertexWithUV(f6 - f7, 0.0F - f8, 0.0D, f2, f4); + tessellator.addVertexWithUV(0.0F - f7, 0.0F - f8, 0.0D, f1, f4); + tessellator.addVertexWithUV(0.0F - f7, 1.4F - f8, 0.0D, f1, f3); + tessellator.addVertexWithUV(f6 - f7, 1.4F - f8, 0.0D, f2, f3); + f9--; + f8--; + f6 *= 0.9F; + GL11.glTranslatef(0.0F, 0.0F, -0.04F); + } + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glEnable(2896 /*GL_LIGHTING*/); + } + + private void renderShadow(Entity entity, double d, double d1, double d2, + float f, float f1) + { + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + RenderEngine renderengine = renderManager.renderEngine; + renderengine.bindTexture(renderengine.getTexture("%clamp%/misc/shadow.png")); + World world = getWorldFromRenderManager(); + GL11.glDepthMask(false); + float f2 = shadowSize; + double d3 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)f1; + double d4 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)f1 + (double)entity.getShadowSize(); + double d5 = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double)f1; + int i = MathHelper.floor_double(d3 - (double)f2); + int j = MathHelper.floor_double(d3 + (double)f2); + int k = MathHelper.floor_double(d4 - (double)f2); + int l = MathHelper.floor_double(d4); + int i1 = MathHelper.floor_double(d5 - (double)f2); + int j1 = MathHelper.floor_double(d5 + (double)f2); + double d6 = d - d3; + double d7 = d1 - d4; + double d8 = d2 - d5; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + for(int k1 = i; k1 <= j; k1++) + { + for(int l1 = k; l1 <= l; l1++) + { + for(int i2 = i1; i2 <= j1; i2++) + { + int j2 = world.getBlockId(k1, l1 - 1, i2); + if(j2 > 0 && world.getBlockLightValue(k1, l1, i2) > 3) + { + renderShadowOnBlock(Block.blocksList[j2], d, d1 + (double)entity.getShadowSize(), d2, k1, l1, i2, f, f2, d6, d7 + (double)entity.getShadowSize(), d8); + } + } + + } + + } + + tessellator.draw(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glDepthMask(true); + } + + private World getWorldFromRenderManager() + { + return renderManager.worldObj; + } + + private void renderShadowOnBlock(Block block, double d, double d1, double d2, + int i, int j, int k, float f, float f1, double d3, + double d4, double d5) + { + Tessellator tessellator = Tessellator.instance; + if(!block.renderAsNormalBlock()) + { + return; + } + double d6 = ((double)f - (d1 - ((double)j + d4)) / 2D) * 0.5D * (double)getWorldFromRenderManager().getLightBrightness(i, j, k); + if(d6 < 0.0D) + { + return; + } + if(d6 > 1.0D) + { + d6 = 1.0D; + } + tessellator.setColorRGBA_F(1.0F, 1.0F, 1.0F, (float)d6); + double d7 = (double)i + block.minX + d3; + double d8 = (double)i + block.maxX + d3; + double d9 = (double)j + block.minY + d4 + 0.015625D; + double d10 = (double)k + block.minZ + d5; + double d11 = (double)k + block.maxZ + d5; + float f2 = (float)((d - d7) / 2D / (double)f1 + 0.5D); + float f3 = (float)((d - d8) / 2D / (double)f1 + 0.5D); + float f4 = (float)((d2 - d10) / 2D / (double)f1 + 0.5D); + float f5 = (float)((d2 - d11) / 2D / (double)f1 + 0.5D); + tessellator.addVertexWithUV(d7, d9, d10, f2, f4); + tessellator.addVertexWithUV(d7, d9, d11, f2, f5); + tessellator.addVertexWithUV(d8, d9, d11, f3, f5); + tessellator.addVertexWithUV(d8, d9, d10, f3, f4); + } + + public static void renderOffsetAABB(AxisAlignedBB axisalignedbb, double d, double d1, double d2) + { + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + Tessellator tessellator = Tessellator.instance; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + tessellator.startDrawingQuads(); + tessellator.setTranslationD(d, d1, d2); + tessellator.setNormal(0.0F, 0.0F, -1F); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.setNormal(0.0F, -1F, 0.0F); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.setNormal(-1F, 0.0F, 0.0F); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.setTranslationD(0.0D, 0.0D, 0.0D); + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + + public static void renderAABB(AxisAlignedBB axisalignedbb) + { + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.draw(); + } + + public void setRenderManager(RenderManager rendermanager) + { + renderManager = rendermanager; + } + + public void doRenderShadowAndFire(Entity entity, double d, double d1, double d2, + float f, float f1) + { + if(renderManager.options.fancyGraphics && shadowSize > 0.0F) + { + double d3 = renderManager.func_851_a(entity.posX, entity.posY, entity.posZ); + float f2 = (float)((1.0D - d3 / 256D) * (double)field_194_c); + if(f2 > 0.0F) + { + renderShadow(entity, d, d1, d2, f2, f1); + } + } + if(entity.func_21062_U()) + { + renderEntityOnFire(entity, d, d1, d2, f1); + } + } + + public FontRenderer getFontRendererFromRenderManager() + { + return renderManager.getFontRenderer(); + } + + protected RenderManager renderManager; + private ModelBase field_195_d; + private RenderBlocks field_203_d; + protected float shadowSize; + protected float field_194_c; +} diff --git a/src/main/java/net/minecraft/src/RenderArrow.java b/src/main/java/net/minecraft/src/RenderArrow.java new file mode 100644 index 0000000..58f1acd --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderArrow.java @@ -0,0 +1,79 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderArrow extends Render +{ + + public RenderArrow() + { + } + + public void func_154_a(EntityArrow entityarrow, double d, double d1, double d2, + float f, float f1) + { + loadTexture("/item/arrows.png"); + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glRotatef((entityarrow.prevRotationYaw + (entityarrow.rotationYaw - entityarrow.prevRotationYaw) * f1) - 90F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(entityarrow.prevRotationPitch + (entityarrow.rotationPitch - entityarrow.prevRotationPitch) * f1, 0.0F, 0.0F, 1.0F); + Tessellator tessellator = Tessellator.instance; + int i = 0; + float f2 = 0.0F; + float f3 = 0.5F; + float f4 = (float)(0 + i * 10) / 32F; + float f5 = (float)(5 + i * 10) / 32F; + float f6 = 0.0F; + float f7 = 0.15625F; + float f8 = (float)(5 + i * 10) / 32F; + float f9 = (float)(10 + i * 10) / 32F; + float f10 = 0.05625F; + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + float f11 = (float)entityarrow.arrowShake - f1; + if(f11 > 0.0F) + { + float f12 = -MathHelper.sin(f11 * 3F) * f11; + GL11.glRotatef(f12, 0.0F, 0.0F, 1.0F); + } + GL11.glRotatef(45F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(f10, f10, f10); + GL11.glTranslatef(-4F, 0.0F, 0.0F); + GL11.glNormal3f(f10, 0.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-7D, -2D, -2D, f6, f8); + tessellator.addVertexWithUV(-7D, -2D, 2D, f7, f8); + tessellator.addVertexWithUV(-7D, 2D, 2D, f7, f9); + tessellator.addVertexWithUV(-7D, 2D, -2D, f6, f9); + tessellator.draw(); + GL11.glNormal3f(-f10, 0.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-7D, 2D, -2D, f6, f8); + tessellator.addVertexWithUV(-7D, 2D, 2D, f7, f8); + tessellator.addVertexWithUV(-7D, -2D, 2D, f7, f9); + tessellator.addVertexWithUV(-7D, -2D, -2D, f6, f9); + tessellator.draw(); + for(int j = 0; j < 4; j++) + { + GL11.glRotatef(90F, 1.0F, 0.0F, 0.0F); + GL11.glNormal3f(0.0F, 0.0F, f10); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-8D, -2D, 0.0D, f2, f4); + tessellator.addVertexWithUV(8D, -2D, 0.0D, f3, f4); + tessellator.addVertexWithUV(8D, 2D, 0.0D, f3, f5); + tessellator.addVertexWithUV(-8D, 2D, 0.0D, f2, f5); + tessellator.draw(); + } + + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_154_a((EntityArrow)entity, d, d1, d2, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderBiped.java b/src/main/java/net/minecraft/src/RenderBiped.java new file mode 100644 index 0000000..d7bac4c --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderBiped.java @@ -0,0 +1,56 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderBiped extends RenderLiving +{ + + public RenderBiped(ModelBiped modelbiped, float f) + { + super(modelbiped, f); + modelBipedMain = modelbiped; + } + + protected void renderEquippedItems(EntityLiving entityliving, float f) + { + ItemStack itemstack = entityliving.getHeldItem(); + if(itemstack != null) + { + GL11.glPushMatrix(); + modelBipedMain.bipedRightArm.func_926_b(0.0625F); + GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F); + if(itemstack.itemID < 256 && RenderBlocks.func_1219_a(Block.blocksList[itemstack.itemID].getRenderType())) + { + float f1 = 0.5F; + GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); + f1 *= 0.75F; + GL11.glRotatef(20F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f1, -f1, f1); + } else + if(Item.itemsList[itemstack.itemID].isFull3D()) + { + float f2 = 0.625F; + GL11.glTranslatef(0.0F, 0.1875F, 0.0F); + GL11.glScalef(f2, -f2, f2); + GL11.glRotatef(-100F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + } else + { + float f3 = 0.375F; + GL11.glTranslatef(0.25F, 0.1875F, -0.1875F); + GL11.glScalef(f3, f3, f3); + GL11.glRotatef(60F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-90F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(20F, 0.0F, 0.0F, 1.0F); + } + renderManager.itemRenderer.renderItem(itemstack); + GL11.glPopMatrix(); + } + } + + protected ModelBiped modelBipedMain; +} diff --git a/src/main/java/net/minecraft/src/RenderBlocks.java b/src/main/java/net/minecraft/src/RenderBlocks.java new file mode 100644 index 0000000..6a5a8a3 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderBlocks.java @@ -0,0 +1,2938 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class RenderBlocks +{ + + public RenderBlocks(IBlockAccess iblockaccess) + { + overrideBlockTexture = -1; + flipTexture = false; + renderAllFaces = false; + field_22352_G = 1; + blockAccess = iblockaccess; + } + + public RenderBlocks() + { + overrideBlockTexture = -1; + flipTexture = false; + renderAllFaces = false; + field_22352_G = 1; + } + + public void renderBlockUsingTexture(Block block, int i, int j, int k, int l) + { + overrideBlockTexture = l; + renderBlockByRenderType(block, i, j, k); + overrideBlockTexture = -1; + } + + public boolean renderBlockByRenderType(Block block, int i, int j, int k) + { + int l = block.getRenderType(); + block.setBlockBoundsBasedOnState(blockAccess, i, j, k); + if(l == 0) + { + return renderStandardBlock(block, i, j, k); + } + if(l == 4) + { + return renderBlockFluids(block, i, j, k); + } + if(l == 13) + { + return renderBlockCactus(block, i, j, k); + } + if(l == 1) + { + return renderBlockReed(block, i, j, k); + } + if(l == 6) + { + return renderBlockCrops(block, i, j, k); + } + if(l == 2) + { + return renderBlockTorch(block, i, j, k); + } + if(l == 3) + { + return renderBlockFire(block, i, j, k); + } + if(l == 5) + { + return renderBlockRedstoneWire(block, i, j, k); + } + if(l == 8) + { + return renderBlockLadder(block, i, j, k); + } + if(l == 7) + { + return renderBlockDoor(block, i, j, k); + } + if(l == 9) + { + return renderBlockMinecartTrack(block, i, j, k); + } + if(l == 10) + { + return renderBlockStairs(block, i, j, k); + } + if(l == 11) + { + return renderBlockFence(block, i, j, k); + } + if(l == 12) + { + return renderBlockLever(block, i, j, k); + } + if(l == 14) + { + return renderBlockBed(block, i, j, k); + } + if(l == 15) + { + return renderBlockRepeater(block, i, j, k); + } else + { + return false; + } + } + + private boolean renderBlockBed(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + int l = blockAccess.getBlockMetadata(i, j, k); + int i1 = BlockBed.func_22030_c(l); + boolean flag = BlockBed.func_22032_d(l); + float f = 0.5F; + float f1 = 1.0F; + float f2 = 0.8F; + float f3 = 0.6F; + float f4 = f1; + float f5 = f1; + float f6 = f1; + float f7 = f; + float f8 = f2; + float f9 = f3; + float f10 = f; + float f11 = f2; + float f12 = f3; + float f13 = f; + float f14 = f2; + float f15 = f3; + float f16 = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f7 * f16, f10 * f16, f13 * f16); + int f17 = block.getBlockTexture(blockAccess, i, j, k, 0); + int j1 = (f17 & 0xf) << 4; + int k1 = f17 & 0xf0; + double d = (float)j1 / 256F; + double d2 = ((double)(j1 + 16) - 0.01D) / 256D; + double d4 = (float)k1 / 256F; + double d6 = ((double)(k1 + 16) - 0.01D) / 256D; + double d8 = (double)i + block.minX; + double d10 = (double)i + block.maxX; + double d12 = (double)j + block.minY + 0.1875D; + double d14 = (double)k + block.minZ; + double d16 = (double)k + block.maxZ; + tessellator.addVertexWithUV(d8, d12, d16, d, d6); + tessellator.addVertexWithUV(d8, d12, d14, d, d4); + tessellator.addVertexWithUV(d10, d12, d14, d2, d4); + tessellator.addVertexWithUV(d10, d12, d16, d2, d6); + float ff17 = block.getBlockBrightness(blockAccess, i, j + 1, k); + tessellator.setColorOpaque_F(f4 * ff17, f5 * ff17, f6 * ff17); + j1 = block.getBlockTexture(blockAccess, i, j, k, 1); + k1 = (j1 & 0xf) << 4; + d = j1 & 0xf0; + double d1 = (float)k1 / 256F; + double d3 = ((double)(k1 + 16) - 0.01D) / 256D; + double d5 = (float)d / 256F; + double d7 = ((double)(d + 16) - 0.01D) / 256D; + double d9 = d1; + double d11 = d3; + double d13 = d5; + double d15 = d5; + double d17 = d1; + double d18 = d3; + double d19 = d7; + double d20 = d7; + if(i1 == 0) + { + d11 = d1; + d13 = d7; + d17 = d3; + d20 = d5; + } else + if(i1 == 2) + { + d9 = d3; + d15 = d7; + d18 = d1; + d19 = d5; + } else + if(i1 == 3) + { + d9 = d3; + d15 = d7; + d18 = d1; + d19 = d5; + d11 = d1; + d13 = d7; + d17 = d3; + d20 = d5; + } + double d21 = (double)i + block.minX; + double d22 = (double)i + block.maxX; + double d23 = (double)j + block.maxY; + double d24 = (double)k + block.minZ; + double d25 = (double)k + block.maxZ; + tessellator.addVertexWithUV(d22, d23, d25, d17, d19); + tessellator.addVertexWithUV(d22, d23, d24, d9, d13); + tessellator.addVertexWithUV(d21, d23, d24, d11, d15); + tessellator.addVertexWithUV(d21, d23, d25, d18, d20); + f17 = ModelBed.field_22280_a[i1]; + if(flag) + { + f17 = ModelBed.field_22280_a[ModelBed.field_22279_b[i1]]; + } + j1 = 4; + switch(i1) + { + case 0: // '\0' + j1 = 5; + break; + + case 3: // '\003' + j1 = 2; + break; + + case 1: // '\001' + j1 = 3; + break; + } + if(f17 != 2 && (renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k - 1, 2))) + { + float f18 = block.getBlockBrightness(blockAccess, i, j, k - 1); + if(block.minZ > 0.0D) + { + f18 = f16; + } + tessellator.setColorOpaque_F(f8 * f18, f11 * f18, f14 * f18); + flipTexture = j1 == 2; + renderEastFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 2)); + } + if(f17 != 3 && (renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k + 1, 3))) + { + float f19 = block.getBlockBrightness(blockAccess, i, j, k + 1); + if(block.maxZ < 1.0D) + { + f19 = f16; + } + tessellator.setColorOpaque_F(f8 * f19, f11 * f19, f14 * f19); + flipTexture = j1 == 3; + renderWestFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 3)); + } + if(f17 != 4 && (renderAllFaces || block.shouldSideBeRendered(blockAccess, i - 1, j, k, 4))) + { + float f20 = block.getBlockBrightness(blockAccess, i - 1, j, k); + if(block.minX > 0.0D) + { + f20 = f16; + } + tessellator.setColorOpaque_F(f9 * f20, f12 * f20, f15 * f20); + flipTexture = j1 == 4; + renderNorthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 4)); + } + if(f17 != 5 && (renderAllFaces || block.shouldSideBeRendered(blockAccess, i + 1, j, k, 5))) + { + float f21 = block.getBlockBrightness(blockAccess, i + 1, j, k); + if(block.maxX < 1.0D) + { + f21 = f16; + } + tessellator.setColorOpaque_F(f9 * f21, f12 * f21, f15 * f21); + flipTexture = j1 == 5; + renderSouthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 5)); + } + flipTexture = false; + return true; + } + + public boolean renderBlockTorch(Block block, int i, int j, int k) + { + int l = blockAccess.getBlockMetadata(i, j, k); + Tessellator tessellator = Tessellator.instance; + float f = block.getBlockBrightness(blockAccess, i, j, k); + if(Block.lightValue[block.blockID] > 0) + { + f = 1.0F; + } + tessellator.setColorOpaque_F(f, f, f); + double d = 0.40000000596046448D; + double d1 = 0.5D - d; + double d2 = 0.20000000298023224D; + if(l == 1) + { + renderTorchAtAngle(block, (double)i - d1, (double)j + d2, k, -d, 0.0D); + } else + if(l == 2) + { + renderTorchAtAngle(block, (double)i + d1, (double)j + d2, k, d, 0.0D); + } else + if(l == 3) + { + renderTorchAtAngle(block, i, (double)j + d2, (double)k - d1, 0.0D, -d); + } else + if(l == 4) + { + renderTorchAtAngle(block, i, (double)j + d2, (double)k + d1, 0.0D, d); + } else + { + renderTorchAtAngle(block, i, j, k, 0.0D, 0.0D); + } + return true; + } + + private boolean renderBlockRepeater(Block block, int i, int j, int k) + { + int l = blockAccess.getBlockMetadata(i, j, k); + int i1 = l & 3; + int j1 = (l & 0xc) >> 2; + renderStandardBlock(block, i, j, k); + Tessellator tessellator = Tessellator.instance; + float f = block.getBlockBrightness(blockAccess, i, j, k); + if(Block.lightValue[block.blockID] > 0) + { + f = (f + 1.0F) * 0.5F; + } + tessellator.setColorOpaque_F(f, f, f); + double d = -0.1875D; + double d1 = 0.0D; + double d2 = 0.0D; + double d3 = 0.0D; + double d4 = 0.0D; + switch(i1) + { + case 0: // '\0' + d4 = -0.3125D; + d2 = BlockRedstoneRepeater.field_22024_a[j1]; + break; + + case 2: // '\002' + d4 = 0.3125D; + d2 = -BlockRedstoneRepeater.field_22024_a[j1]; + break; + + case 3: // '\003' + d3 = -0.3125D; + d1 = BlockRedstoneRepeater.field_22024_a[j1]; + break; + + case 1: // '\001' + d3 = 0.3125D; + d1 = -BlockRedstoneRepeater.field_22024_a[j1]; + break; + } + renderTorchAtAngle(block, (double)i + d1, (double)j + d, (double)k + d2, 0.0D, 0.0D); + renderTorchAtAngle(block, (double)i + d3, (double)j + d, (double)k + d4, 0.0D, 0.0D); + int k1 = block.getBlockTextureFromSide(1); + int l1 = (k1 & 0xf) << 4; + int i2 = k1 & 0xf0; + double d5 = (float)l1 / 256F; + double d6 = ((float)l1 + 15.99F) / 256F; + double d7 = (float)i2 / 256F; + double d8 = ((float)i2 + 15.99F) / 256F; + float f1 = 0.125F; + float f2 = i + 1; + float f3 = i + 1; + float f4 = i + 0; + float f5 = i + 0; + float f6 = k + 0; + float f7 = k + 1; + float f8 = k + 1; + float f9 = k + 0; + float f10 = (float)j + f1; + if(i1 == 2) + { + f2 = f3 = i + 0; + f4 = f5 = i + 1; + f6 = f9 = k + 1; + f7 = f8 = k + 0; + } else + if(i1 == 3) + { + f2 = f5 = i + 0; + f3 = f4 = i + 1; + f6 = f7 = k + 0; + f8 = f9 = k + 1; + } else + if(i1 == 1) + { + f2 = f5 = i + 1; + f3 = f4 = i + 0; + f6 = f7 = k + 1; + f8 = f9 = k + 0; + } + tessellator.addVertexWithUV(f5, f10, f9, d5, d7); + tessellator.addVertexWithUV(f4, f10, f8, d5, d8); + tessellator.addVertexWithUV(f3, f10, f7, d6, d8); + tessellator.addVertexWithUV(f2, f10, f6, d6, d7); + return true; + } + + public boolean renderBlockLever(Block block, int i, int j, int k) + { + int l = blockAccess.getBlockMetadata(i, j, k); + int i1 = l & 7; + boolean flag = (l & 8) > 0; + Tessellator tessellator = Tessellator.instance; + boolean flag1 = overrideBlockTexture >= 0; + if(!flag1) + { + overrideBlockTexture = Block.cobblestone.blockIndexInTexture; + } + float f = 0.25F; + float f1 = 0.1875F; + float f2 = 0.1875F; + if(i1 == 5) + { + block.setBlockBounds(0.5F - f1, 0.0F, 0.5F - f, 0.5F + f1, f2, 0.5F + f); + } else + if(i1 == 6) + { + block.setBlockBounds(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, f2, 0.5F + f1); + } else + if(i1 == 4) + { + block.setBlockBounds(0.5F - f1, 0.5F - f, 1.0F - f2, 0.5F + f1, 0.5F + f, 1.0F); + } else + if(i1 == 3) + { + block.setBlockBounds(0.5F - f1, 0.5F - f, 0.0F, 0.5F + f1, 0.5F + f, f2); + } else + if(i1 == 2) + { + block.setBlockBounds(1.0F - f2, 0.5F - f, 0.5F - f1, 1.0F, 0.5F + f, 0.5F + f1); + } else + if(i1 == 1) + { + block.setBlockBounds(0.0F, 0.5F - f, 0.5F - f1, f2, 0.5F + f, 0.5F + f1); + } + renderStandardBlock(block, i, j, k); + if(!flag1) + { + overrideBlockTexture = -1; + } + float f3 = block.getBlockBrightness(blockAccess, i, j, k); + if(Block.lightValue[block.blockID] > 0) + { + f3 = 1.0F; + } + tessellator.setColorOpaque_F(f3, f3, f3); + int j1 = block.getBlockTextureFromSide(0); + if(overrideBlockTexture >= 0) + { + j1 = overrideBlockTexture; + } + int k1 = (j1 & 0xf) << 4; + int l1 = j1 & 0xf0; + float f4 = (float)k1 / 256F; + float f5 = ((float)k1 + 15.99F) / 256F; + float f6 = (float)l1 / 256F; + float f7 = ((float)l1 + 15.99F) / 256F; + Vec3D avec3d[] = new Vec3D[8]; + float f8 = 0.0625F; + float f9 = 0.0625F; + float f10 = 0.625F; + avec3d[0] = Vec3D.createVector(-f8, 0.0D, -f9); + avec3d[1] = Vec3D.createVector(f8, 0.0D, -f9); + avec3d[2] = Vec3D.createVector(f8, 0.0D, f9); + avec3d[3] = Vec3D.createVector(-f8, 0.0D, f9); + avec3d[4] = Vec3D.createVector(-f8, f10, -f9); + avec3d[5] = Vec3D.createVector(f8, f10, -f9); + avec3d[6] = Vec3D.createVector(f8, f10, f9); + avec3d[7] = Vec3D.createVector(-f8, f10, f9); + for(int i2 = 0; i2 < 8; i2++) + { + if(flag) + { + avec3d[i2].zCoord -= 0.0625D; + avec3d[i2].rotateAroundX(0.6981317F); + } else + { + avec3d[i2].zCoord += 0.0625D; + avec3d[i2].rotateAroundX(-0.6981317F); + } + if(i1 == 6) + { + avec3d[i2].rotateAroundY(1.570796F); + } + if(i1 < 5) + { + avec3d[i2].yCoord -= 0.375D; + avec3d[i2].rotateAroundX(1.570796F); + if(i1 == 4) + { + avec3d[i2].rotateAroundY(0.0F); + } + if(i1 == 3) + { + avec3d[i2].rotateAroundY(3.141593F); + } + if(i1 == 2) + { + avec3d[i2].rotateAroundY(1.570796F); + } + if(i1 == 1) + { + avec3d[i2].rotateAroundY(-1.570796F); + } + avec3d[i2].xCoord += (double)i + 0.5D; + avec3d[i2].yCoord += (float)j + 0.5F; + avec3d[i2].zCoord += (double)k + 0.5D; + } else + { + avec3d[i2].xCoord += (double)i + 0.5D; + avec3d[i2].yCoord += (float)j + 0.125F; + avec3d[i2].zCoord += (double)k + 0.5D; + } + } + + Vec3D vec3d = null; + Vec3D vec3d1 = null; + Vec3D vec3d2 = null; + Vec3D vec3d3 = null; + for(int j2 = 0; j2 < 6; j2++) + { + if(j2 == 0) + { + f4 = (float)(k1 + 7) / 256F; + f5 = ((float)(k1 + 9) - 0.01F) / 256F; + f6 = (float)(l1 + 6) / 256F; + f7 = ((float)(l1 + 8) - 0.01F) / 256F; + } else + if(j2 == 2) + { + f4 = (float)(k1 + 7) / 256F; + f5 = ((float)(k1 + 9) - 0.01F) / 256F; + f6 = (float)(l1 + 6) / 256F; + f7 = ((float)(l1 + 16) - 0.01F) / 256F; + } + if(j2 == 0) + { + vec3d = avec3d[0]; + vec3d1 = avec3d[1]; + vec3d2 = avec3d[2]; + vec3d3 = avec3d[3]; + } else + if(j2 == 1) + { + vec3d = avec3d[7]; + vec3d1 = avec3d[6]; + vec3d2 = avec3d[5]; + vec3d3 = avec3d[4]; + } else + if(j2 == 2) + { + vec3d = avec3d[1]; + vec3d1 = avec3d[0]; + vec3d2 = avec3d[4]; + vec3d3 = avec3d[5]; + } else + if(j2 == 3) + { + vec3d = avec3d[2]; + vec3d1 = avec3d[1]; + vec3d2 = avec3d[5]; + vec3d3 = avec3d[6]; + } else + if(j2 == 4) + { + vec3d = avec3d[3]; + vec3d1 = avec3d[2]; + vec3d2 = avec3d[6]; + vec3d3 = avec3d[7]; + } else + if(j2 == 5) + { + vec3d = avec3d[0]; + vec3d1 = avec3d[3]; + vec3d2 = avec3d[7]; + vec3d3 = avec3d[4]; + } + tessellator.addVertexWithUV(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord, f4, f7); + tessellator.addVertexWithUV(vec3d1.xCoord, vec3d1.yCoord, vec3d1.zCoord, f5, f7); + tessellator.addVertexWithUV(vec3d2.xCoord, vec3d2.yCoord, vec3d2.zCoord, f5, f6); + tessellator.addVertexWithUV(vec3d3.xCoord, vec3d3.yCoord, vec3d3.zCoord, f4, f6); + } + + return true; + } + + public boolean renderBlockFire(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + int l = block.getBlockTextureFromSide(0); + if(overrideBlockTexture >= 0) + { + l = overrideBlockTexture; + } + float f = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f, f, f); + int i1 = (l & 0xf) << 4; + int j1 = l & 0xf0; + double d = (float)i1 / 256F; + double d2 = ((float)i1 + 15.99F) / 256F; + double d4 = (float)j1 / 256F; + double d6 = ((float)j1 + 15.99F) / 256F; + float f1 = 1.4F; + if(blockAccess.isBlockOpaqueCube(i, j - 1, k) || Block.fire.canBlockCatchFire(blockAccess, i, j - 1, k)) + { + double d8 = (double)i + 0.5D + 0.20000000000000001D; + double d9 = ((double)i + 0.5D) - 0.20000000000000001D; + double d12 = (double)k + 0.5D + 0.20000000000000001D; + double d14 = ((double)k + 0.5D) - 0.20000000000000001D; + double d16 = ((double)i + 0.5D) - 0.29999999999999999D; + double d18 = (double)i + 0.5D + 0.29999999999999999D; + double d20 = ((double)k + 0.5D) - 0.29999999999999999D; + double d22 = (double)k + 0.5D + 0.29999999999999999D; + tessellator.addVertexWithUV(d16, (float)j + f1, k + 1, d2, d4); + tessellator.addVertexWithUV(d8, j + 0, k + 1, d2, d6); + tessellator.addVertexWithUV(d8, j + 0, k + 0, d, d6); + tessellator.addVertexWithUV(d16, (float)j + f1, k + 0, d, d4); + tessellator.addVertexWithUV(d18, (float)j + f1, k + 0, d2, d4); + tessellator.addVertexWithUV(d9, j + 0, k + 0, d2, d6); + tessellator.addVertexWithUV(d9, j + 0, k + 1, d, d6); + tessellator.addVertexWithUV(d18, (float)j + f1, k + 1, d, d4); + d = (float)i1 / 256F; + d2 = ((float)i1 + 15.99F) / 256F; + d4 = (float)(j1 + 16) / 256F; + d6 = ((float)j1 + 15.99F + 16F) / 256F; + tessellator.addVertexWithUV(i + 1, (float)j + f1, d22, d2, d4); + tessellator.addVertexWithUV(i + 1, j + 0, d14, d2, d6); + tessellator.addVertexWithUV(i + 0, j + 0, d14, d, d6); + tessellator.addVertexWithUV(i + 0, (float)j + f1, d22, d, d4); + tessellator.addVertexWithUV(i + 0, (float)j + f1, d20, d2, d4); + tessellator.addVertexWithUV(i + 0, j + 0, d12, d2, d6); + tessellator.addVertexWithUV(i + 1, j + 0, d12, d, d6); + tessellator.addVertexWithUV(i + 1, (float)j + f1, d20, d, d4); + d8 = ((double)i + 0.5D) - 0.5D; + d9 = (double)i + 0.5D + 0.5D; + d12 = ((double)k + 0.5D) - 0.5D; + d14 = (double)k + 0.5D + 0.5D; + d16 = ((double)i + 0.5D) - 0.40000000000000002D; + d18 = (double)i + 0.5D + 0.40000000000000002D; + d20 = ((double)k + 0.5D) - 0.40000000000000002D; + d22 = (double)k + 0.5D + 0.40000000000000002D; + tessellator.addVertexWithUV(d16, (float)j + f1, k + 0, d, d4); + tessellator.addVertexWithUV(d8, j + 0, k + 0, d, d6); + tessellator.addVertexWithUV(d8, j + 0, k + 1, d2, d6); + tessellator.addVertexWithUV(d16, (float)j + f1, k + 1, d2, d4); + tessellator.addVertexWithUV(d18, (float)j + f1, k + 1, d, d4); + tessellator.addVertexWithUV(d9, j + 0, k + 1, d, d6); + tessellator.addVertexWithUV(d9, j + 0, k + 0, d2, d6); + tessellator.addVertexWithUV(d18, (float)j + f1, k + 0, d2, d4); + d = (float)i1 / 256F; + d2 = ((float)i1 + 15.99F) / 256F; + d4 = (float)j1 / 256F; + d6 = ((float)j1 + 15.99F) / 256F; + tessellator.addVertexWithUV(i + 0, (float)j + f1, d22, d, d4); + tessellator.addVertexWithUV(i + 0, j + 0, d14, d, d6); + tessellator.addVertexWithUV(i + 1, j + 0, d14, d2, d6); + tessellator.addVertexWithUV(i + 1, (float)j + f1, d22, d2, d4); + tessellator.addVertexWithUV(i + 1, (float)j + f1, d20, d, d4); + tessellator.addVertexWithUV(i + 1, j + 0, d12, d, d6); + tessellator.addVertexWithUV(i + 0, j + 0, d12, d2, d6); + tessellator.addVertexWithUV(i + 0, (float)j + f1, d20, d2, d4); + } else + { + float f3 = 0.2F; + float f4 = 0.0625F; + if((i + j + k & 1) == 1) + { + d = (float)i1 / 256F; + d2 = ((float)i1 + 15.99F) / 256F; + d4 = (float)(j1 + 16) / 256F; + d6 = ((float)j1 + 15.99F + 16F) / 256F; + } + if((i / 2 + j / 2 + k / 2 & 1) == 1) + { + double d10 = d2; + d2 = d; + d = d10; + } + if(Block.fire.canBlockCatchFire(blockAccess, i - 1, j, k)) + { + tessellator.addVertexWithUV((float)i + f3, (float)j + f1 + f4, k + 1, d2, d4); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, k + 1, d2, d6); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, k + 0, d, d6); + tessellator.addVertexWithUV((float)i + f3, (float)j + f1 + f4, k + 0, d, d4); + tessellator.addVertexWithUV((float)i + f3, (float)j + f1 + f4, k + 0, d, d4); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, k + 0, d, d6); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, k + 1, d2, d6); + tessellator.addVertexWithUV((float)i + f3, (float)j + f1 + f4, k + 1, d2, d4); + } + if(Block.fire.canBlockCatchFire(blockAccess, i + 1, j, k)) + { + tessellator.addVertexWithUV((float)(i + 1) - f3, (float)j + f1 + f4, k + 0, d, d4); + tessellator.addVertexWithUV((i + 1) - 0, (float)(j + 0) + f4, k + 0, d, d6); + tessellator.addVertexWithUV((i + 1) - 0, (float)(j + 0) + f4, k + 1, d2, d6); + tessellator.addVertexWithUV((float)(i + 1) - f3, (float)j + f1 + f4, k + 1, d2, d4); + tessellator.addVertexWithUV((float)(i + 1) - f3, (float)j + f1 + f4, k + 1, d2, d4); + tessellator.addVertexWithUV((i + 1) - 0, (float)(j + 0) + f4, k + 1, d2, d6); + tessellator.addVertexWithUV((i + 1) - 0, (float)(j + 0) + f4, k + 0, d, d6); + tessellator.addVertexWithUV((float)(i + 1) - f3, (float)j + f1 + f4, k + 0, d, d4); + } + if(Block.fire.canBlockCatchFire(blockAccess, i, j, k - 1)) + { + tessellator.addVertexWithUV(i + 0, (float)j + f1 + f4, (float)k + f3, d2, d4); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, k + 0, d2, d6); + tessellator.addVertexWithUV(i + 1, (float)(j + 0) + f4, k + 0, d, d6); + tessellator.addVertexWithUV(i + 1, (float)j + f1 + f4, (float)k + f3, d, d4); + tessellator.addVertexWithUV(i + 1, (float)j + f1 + f4, (float)k + f3, d, d4); + tessellator.addVertexWithUV(i + 1, (float)(j + 0) + f4, k + 0, d, d6); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, k + 0, d2, d6); + tessellator.addVertexWithUV(i + 0, (float)j + f1 + f4, (float)k + f3, d2, d4); + } + if(Block.fire.canBlockCatchFire(blockAccess, i, j, k + 1)) + { + tessellator.addVertexWithUV(i + 1, (float)j + f1 + f4, (float)(k + 1) - f3, d, d4); + tessellator.addVertexWithUV(i + 1, (float)(j + 0) + f4, (k + 1) - 0, d, d6); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, (k + 1) - 0, d2, d6); + tessellator.addVertexWithUV(i + 0, (float)j + f1 + f4, (float)(k + 1) - f3, d2, d4); + tessellator.addVertexWithUV(i + 0, (float)j + f1 + f4, (float)(k + 1) - f3, d2, d4); + tessellator.addVertexWithUV(i + 0, (float)(j + 0) + f4, (k + 1) - 0, d2, d6); + tessellator.addVertexWithUV(i + 1, (float)(j + 0) + f4, (k + 1) - 0, d, d6); + tessellator.addVertexWithUV(i + 1, (float)j + f1 + f4, (float)(k + 1) - f3, d, d4); + } + if(Block.fire.canBlockCatchFire(blockAccess, i, j + 1, k)) + { + double d11 = (double)i + 0.5D + 0.5D; + double d13 = ((double)i + 0.5D) - 0.5D; + double d15 = (double)k + 0.5D + 0.5D; + double d17 = ((double)k + 0.5D) - 0.5D; + double d19 = ((double)i + 0.5D) - 0.5D; + double d21 = (double)i + 0.5D + 0.5D; + double d23 = ((double)k + 0.5D) - 0.5D; + double d24 = (double)k + 0.5D + 0.5D; + double d1 = (float)i1 / 256F; + double d3 = ((float)i1 + 15.99F) / 256F; + double d5 = (float)j1 / 256F; + double d7 = ((float)j1 + 15.99F) / 256F; + j++; + float f2 = -0.2F; + if((i + j + k & 1) == 0) + { + tessellator.addVertexWithUV(d19, (float)j + f2, k + 0, d3, d5); + tessellator.addVertexWithUV(d11, j + 0, k + 0, d3, d7); + tessellator.addVertexWithUV(d11, j + 0, k + 1, d1, d7); + tessellator.addVertexWithUV(d19, (float)j + f2, k + 1, d1, d5); + d1 = (float)i1 / 256F; + d3 = ((float)i1 + 15.99F) / 256F; + d5 = (float)(j1 + 16) / 256F; + d7 = ((float)j1 + 15.99F + 16F) / 256F; + tessellator.addVertexWithUV(d21, (float)j + f2, k + 1, d3, d5); + tessellator.addVertexWithUV(d13, j + 0, k + 1, d3, d7); + tessellator.addVertexWithUV(d13, j + 0, k + 0, d1, d7); + tessellator.addVertexWithUV(d21, (float)j + f2, k + 0, d1, d5); + } else + { + tessellator.addVertexWithUV(i + 0, (float)j + f2, d24, d3, d5); + tessellator.addVertexWithUV(i + 0, j + 0, d17, d3, d7); + tessellator.addVertexWithUV(i + 1, j + 0, d17, d1, d7); + tessellator.addVertexWithUV(i + 1, (float)j + f2, d24, d1, d5); + d1 = (float)i1 / 256F; + d3 = ((float)i1 + 15.99F) / 256F; + d5 = (float)(j1 + 16) / 256F; + d7 = ((float)j1 + 15.99F + 16F) / 256F; + tessellator.addVertexWithUV(i + 1, (float)j + f2, d23, d3, d5); + tessellator.addVertexWithUV(i + 1, j + 0, d15, d3, d7); + tessellator.addVertexWithUV(i + 0, j + 0, d15, d1, d7); + tessellator.addVertexWithUV(i + 0, (float)j + f2, d23, d1, d5); + } + } + } + return true; + } + + public boolean renderBlockRedstoneWire(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + int l = blockAccess.getBlockMetadata(i, j, k); + int i1 = block.getBlockTextureFromSideAndMetadata(1, l); + if(overrideBlockTexture >= 0) + { + i1 = overrideBlockTexture; + } + float f = block.getBlockBrightness(blockAccess, i, j, k); + float f1 = (float)l / 15F; + float f2 = f1 * 0.6F + 0.4F; + if(l == 0) + { + f2 = 0.0F; + } + float f3 = f1 * f1 * 0.7F - 0.5F; + float f4 = f1 * f1 * 0.6F - 0.7F; + if(f3 < 0.0F) + { + f3 = 0.0F; + } + if(f4 < 0.0F) + { + f4 = 0.0F; + } + tessellator.setColorOpaque_F(f * f2, f * f3, f * f4); + int j1 = (i1 & 0xf) << 4; + int k1 = i1 & 0xf0; + double d = (float)j1 / 256F; + double d1 = ((float)j1 + 15.99F) / 256F; + double d2 = (float)k1 / 256F; + double d3 = ((float)k1 + 15.99F) / 256F; + float f5 = 0.0F; + float f6 = 0.03125F; + boolean flag = BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i - 1, j, k) || !blockAccess.isBlockOpaqueCube(i - 1, j, k) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i - 1, j - 1, k); + boolean flag1 = BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i + 1, j, k) || !blockAccess.isBlockOpaqueCube(i + 1, j, k) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i + 1, j - 1, k); + boolean flag2 = BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i, j, k - 1) || !blockAccess.isBlockOpaqueCube(i, j, k - 1) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i, j - 1, k - 1); + boolean flag3 = BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i, j, k + 1) || !blockAccess.isBlockOpaqueCube(i, j, k + 1) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i, j - 1, k + 1); + if(!blockAccess.isBlockOpaqueCube(i, j + 1, k)) + { + if(blockAccess.isBlockOpaqueCube(i - 1, j, k) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i - 1, j + 1, k)) + { + flag = true; + } + if(blockAccess.isBlockOpaqueCube(i + 1, j, k) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i + 1, j + 1, k)) + { + flag1 = true; + } + if(blockAccess.isBlockOpaqueCube(i, j, k - 1) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i, j + 1, k - 1)) + { + flag2 = true; + } + if(blockAccess.isBlockOpaqueCube(i, j, k + 1) && BlockRedstoneWire.isPowerProviderOrWire(blockAccess, i, j + 1, k + 1)) + { + flag3 = true; + } + } + float f7 = 0.3125F; + float f8 = i + 0; + float f9 = i + 1; + float f10 = k + 0; + float f11 = k + 1; + byte byte0 = 0; + if((flag || flag1) && !flag2 && !flag3) + { + byte0 = 1; + } + if((flag2 || flag3) && !flag1 && !flag) + { + byte0 = 2; + } + if(byte0 != 0) + { + d = (float)(j1 + 16) / 256F; + d1 = ((float)(j1 + 16) + 15.99F) / 256F; + d2 = (float)k1 / 256F; + d3 = ((float)k1 + 15.99F) / 256F; + } + if(byte0 == 0) + { + if(flag1 || flag2 || flag3 || flag) + { + if(!flag) + { + f8 += f7; + } + if(!flag) + { + d += f7 / 16F; + } + if(!flag1) + { + f9 -= f7; + } + if(!flag1) + { + d1 -= f7 / 16F; + } + if(!flag2) + { + f10 += f7; + } + if(!flag2) + { + d2 += f7 / 16F; + } + if(!flag3) + { + f11 -= f7; + } + if(!flag3) + { + d3 -= f7 / 16F; + } + } + tessellator.addVertexWithUV(f9 + f5, (float)j + f6, f11 + f5, d1, d3); + tessellator.addVertexWithUV(f9 + f5, (float)j + f6, f10 - f5, d1, d2); + tessellator.addVertexWithUV(f8 - f5, (float)j + f6, f10 - f5, d, d2); + tessellator.addVertexWithUV(f8 - f5, (float)j + f6, f11 + f5, d, d3); + } + if(byte0 == 1) + { + tessellator.addVertexWithUV(f9 + f5, (float)j + f6, f11 + f5, d1, d3); + tessellator.addVertexWithUV(f9 + f5, (float)j + f6, f10 - f5, d1, d2); + tessellator.addVertexWithUV(f8 - f5, (float)j + f6, f10 - f5, d, d2); + tessellator.addVertexWithUV(f8 - f5, (float)j + f6, f11 + f5, d, d3); + } + if(byte0 == 2) + { + tessellator.addVertexWithUV(f9 + f5, (float)j + f6, f11 + f5, d1, d3); + tessellator.addVertexWithUV(f9 + f5, (float)j + f6, f10 - f5, d, d3); + tessellator.addVertexWithUV(f8 - f5, (float)j + f6, f10 - f5, d, d2); + tessellator.addVertexWithUV(f8 - f5, (float)j + f6, f11 + f5, d1, d2); + } + d = (float)(j1 + 16) / 256F; + d1 = ((float)(j1 + 16) + 15.99F) / 256F; + d2 = (float)k1 / 256F; + d3 = ((float)k1 + 15.99F) / 256F; + if(!blockAccess.isBlockOpaqueCube(i, j + 1, k)) + { + if(blockAccess.isBlockOpaqueCube(i - 1, j, k) && blockAccess.getBlockId(i - 1, j + 1, k) == Block.redstoneWire.blockID) + { + tessellator.addVertexWithUV((float)i + f6, (float)(j + 1) + f5, (float)(k + 1) + f5, d1, d2); + tessellator.addVertexWithUV((float)i + f6, (float)(j + 0) - f5, (float)(k + 1) + f5, d, d2); + tessellator.addVertexWithUV((float)i + f6, (float)(j + 0) - f5, (float)(k + 0) - f5, d, d3); + tessellator.addVertexWithUV((float)i + f6, (float)(j + 1) + f5, (float)(k + 0) - f5, d1, d3); + } + if(blockAccess.isBlockOpaqueCube(i + 1, j, k) && blockAccess.getBlockId(i + 1, j + 1, k) == Block.redstoneWire.blockID) + { + tessellator.addVertexWithUV((float)(i + 1) - f6, (float)(j + 0) - f5, (float)(k + 1) + f5, d, d3); + tessellator.addVertexWithUV((float)(i + 1) - f6, (float)(j + 1) + f5, (float)(k + 1) + f5, d1, d3); + tessellator.addVertexWithUV((float)(i + 1) - f6, (float)(j + 1) + f5, (float)(k + 0) - f5, d1, d2); + tessellator.addVertexWithUV((float)(i + 1) - f6, (float)(j + 0) - f5, (float)(k + 0) - f5, d, d2); + } + if(blockAccess.isBlockOpaqueCube(i, j, k - 1) && blockAccess.getBlockId(i, j + 1, k - 1) == Block.redstoneWire.blockID) + { + tessellator.addVertexWithUV((float)(i + 1) + f5, (float)(j + 0) - f5, (float)k + f6, d, d3); + tessellator.addVertexWithUV((float)(i + 1) + f5, (float)(j + 1) + f5, (float)k + f6, d1, d3); + tessellator.addVertexWithUV((float)(i + 0) - f5, (float)(j + 1) + f5, (float)k + f6, d1, d2); + tessellator.addVertexWithUV((float)(i + 0) - f5, (float)(j + 0) - f5, (float)k + f6, d, d2); + } + if(blockAccess.isBlockOpaqueCube(i, j, k + 1) && blockAccess.getBlockId(i, j + 1, k + 1) == Block.redstoneWire.blockID) + { + tessellator.addVertexWithUV((float)(i + 1) + f5, (float)(j + 1) + f5, (float)(k + 1) - f6, d1, d2); + tessellator.addVertexWithUV((float)(i + 1) + f5, (float)(j + 0) - f5, (float)(k + 1) - f6, d, d2); + tessellator.addVertexWithUV((float)(i + 0) - f5, (float)(j + 0) - f5, (float)(k + 1) - f6, d, d3); + tessellator.addVertexWithUV((float)(i + 0) - f5, (float)(j + 1) + f5, (float)(k + 1) - f6, d1, d3); + } + } + return true; + } + + public boolean renderBlockMinecartTrack(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + int l = blockAccess.getBlockMetadata(i, j, k); + int i1 = block.getBlockTextureFromSideAndMetadata(0, l); + if(overrideBlockTexture >= 0) + { + i1 = overrideBlockTexture; + } + float f = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f, f, f); + int j1 = (i1 & 0xf) << 4; + int k1 = i1 & 0xf0; + double d = (float)j1 / 256F; + double d1 = ((float)j1 + 15.99F) / 256F; + double d2 = (float)k1 / 256F; + double d3 = ((float)k1 + 15.99F) / 256F; + float f1 = 0.0625F; + float f2 = i + 1; + float f3 = i + 1; + float f4 = i + 0; + float f5 = i + 0; + float f6 = k + 0; + float f7 = k + 1; + float f8 = k + 1; + float f9 = k + 0; + float f10 = (float)j + f1; + float f11 = (float)j + f1; + float f12 = (float)j + f1; + float f13 = (float)j + f1; + if(l == 1 || l == 2 || l == 3 || l == 7) + { + f2 = f5 = i + 1; + f3 = f4 = i + 0; + f6 = f7 = k + 1; + f8 = f9 = k + 0; + } else + if(l == 8) + { + f2 = f3 = i + 0; + f4 = f5 = i + 1; + f6 = f9 = k + 1; + f7 = f8 = k + 0; + } else + if(l == 9) + { + f2 = f5 = i + 0; + f3 = f4 = i + 1; + f6 = f7 = k + 0; + f8 = f9 = k + 1; + } + if(l == 2 || l == 4) + { + f10++; + f13++; + } else + if(l == 3 || l == 5) + { + f11++; + f12++; + } + tessellator.addVertexWithUV(f2, f10, f6, d1, d2); + tessellator.addVertexWithUV(f3, f11, f7, d1, d3); + tessellator.addVertexWithUV(f4, f12, f8, d, d3); + tessellator.addVertexWithUV(f5, f13, f9, d, d2); + tessellator.addVertexWithUV(f5, f13, f9, d, d2); + tessellator.addVertexWithUV(f4, f12, f8, d, d3); + tessellator.addVertexWithUV(f3, f11, f7, d1, d3); + tessellator.addVertexWithUV(f2, f10, f6, d1, d2); + return true; + } + + public boolean renderBlockLadder(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + int l = block.getBlockTextureFromSide(0); + if(overrideBlockTexture >= 0) + { + l = overrideBlockTexture; + } + float f = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f, f, f); + int i1 = (l & 0xf) << 4; + int j1 = l & 0xf0; + double d = (float)i1 / 256F; + double d1 = ((float)i1 + 15.99F) / 256F; + double d2 = (float)j1 / 256F; + double d3 = ((float)j1 + 15.99F) / 256F; + int k1 = blockAccess.getBlockMetadata(i, j, k); + float f1 = 0.0F; + float f2 = 0.05F; + if(k1 == 5) + { + tessellator.addVertexWithUV((float)i + f2, (float)(j + 1) + f1, (float)(k + 1) + f1, d, d2); + tessellator.addVertexWithUV((float)i + f2, (float)(j + 0) - f1, (float)(k + 1) + f1, d, d3); + tessellator.addVertexWithUV((float)i + f2, (float)(j + 0) - f1, (float)(k + 0) - f1, d1, d3); + tessellator.addVertexWithUV((float)i + f2, (float)(j + 1) + f1, (float)(k + 0) - f1, d1, d2); + } + if(k1 == 4) + { + tessellator.addVertexWithUV((float)(i + 1) - f2, (float)(j + 0) - f1, (float)(k + 1) + f1, d1, d3); + tessellator.addVertexWithUV((float)(i + 1) - f2, (float)(j + 1) + f1, (float)(k + 1) + f1, d1, d2); + tessellator.addVertexWithUV((float)(i + 1) - f2, (float)(j + 1) + f1, (float)(k + 0) - f1, d, d2); + tessellator.addVertexWithUV((float)(i + 1) - f2, (float)(j + 0) - f1, (float)(k + 0) - f1, d, d3); + } + if(k1 == 3) + { + tessellator.addVertexWithUV((float)(i + 1) + f1, (float)(j + 0) - f1, (float)k + f2, d1, d3); + tessellator.addVertexWithUV((float)(i + 1) + f1, (float)(j + 1) + f1, (float)k + f2, d1, d2); + tessellator.addVertexWithUV((float)(i + 0) - f1, (float)(j + 1) + f1, (float)k + f2, d, d2); + tessellator.addVertexWithUV((float)(i + 0) - f1, (float)(j + 0) - f1, (float)k + f2, d, d3); + } + if(k1 == 2) + { + tessellator.addVertexWithUV((float)(i + 1) + f1, (float)(j + 1) + f1, (float)(k + 1) - f2, d, d2); + tessellator.addVertexWithUV((float)(i + 1) + f1, (float)(j + 0) - f1, (float)(k + 1) - f2, d, d3); + tessellator.addVertexWithUV((float)(i + 0) - f1, (float)(j + 0) - f1, (float)(k + 1) - f2, d1, d3); + tessellator.addVertexWithUV((float)(i + 0) - f1, (float)(j + 1) + f1, (float)(k + 1) - f2, d1, d2); + } + return true; + } + + public boolean renderBlockReed(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + float f = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f, f, f); + func_1239_a(block, blockAccess.getBlockMetadata(i, j, k), i, j, k); + return true; + } + + public boolean renderBlockCrops(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + float f = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f, f, f); + func_1245_b(block, blockAccess.getBlockMetadata(i, j, k), i, (float)j - 0.0625F, k); + return true; + } + + public void renderTorchAtAngle(Block block, double d, double d1, double d2, + double d3, double d4) + { + Tessellator tessellator = Tessellator.instance; + int i = block.getBlockTextureFromSide(0); + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + float f = (float)j / 256F; + float f1 = ((float)j + 15.99F) / 256F; + float f2 = (float)k / 256F; + float f3 = ((float)k + 15.99F) / 256F; + double d5 = (double)f + 0.02734375D; + double d6 = (double)f2 + 0.0234375D; + double d7 = (double)f + 0.03515625D; + double d8 = (double)f2 + 0.03125D; + d += 0.5D; + d2 += 0.5D; + double d9 = d - 0.5D; + double d10 = d + 0.5D; + double d11 = d2 - 0.5D; + double d12 = d2 + 0.5D; + double d13 = 0.0625D; + double d14 = 0.625D; + tessellator.addVertexWithUV((d + d3 * (1.0D - d14)) - d13, d1 + d14, (d2 + d4 * (1.0D - d14)) - d13, d5, d6); + tessellator.addVertexWithUV((d + d3 * (1.0D - d14)) - d13, d1 + d14, d2 + d4 * (1.0D - d14) + d13, d5, d8); + tessellator.addVertexWithUV(d + d3 * (1.0D - d14) + d13, d1 + d14, d2 + d4 * (1.0D - d14) + d13, d7, d8); + tessellator.addVertexWithUV(d + d3 * (1.0D - d14) + d13, d1 + d14, (d2 + d4 * (1.0D - d14)) - d13, d7, d6); + tessellator.addVertexWithUV(d - d13, d1 + 1.0D, d11, f, f2); + tessellator.addVertexWithUV((d - d13) + d3, d1 + 0.0D, d11 + d4, f, f3); + tessellator.addVertexWithUV((d - d13) + d3, d1 + 0.0D, d12 + d4, f1, f3); + tessellator.addVertexWithUV(d - d13, d1 + 1.0D, d12, f1, f2); + tessellator.addVertexWithUV(d + d13, d1 + 1.0D, d12, f, f2); + tessellator.addVertexWithUV(d + d3 + d13, d1 + 0.0D, d12 + d4, f, f3); + tessellator.addVertexWithUV(d + d3 + d13, d1 + 0.0D, d11 + d4, f1, f3); + tessellator.addVertexWithUV(d + d13, d1 + 1.0D, d11, f1, f2); + tessellator.addVertexWithUV(d9, d1 + 1.0D, d2 + d13, f, f2); + tessellator.addVertexWithUV(d9 + d3, d1 + 0.0D, d2 + d13 + d4, f, f3); + tessellator.addVertexWithUV(d10 + d3, d1 + 0.0D, d2 + d13 + d4, f1, f3); + tessellator.addVertexWithUV(d10, d1 + 1.0D, d2 + d13, f1, f2); + tessellator.addVertexWithUV(d10, d1 + 1.0D, d2 - d13, f, f2); + tessellator.addVertexWithUV(d10 + d3, d1 + 0.0D, (d2 - d13) + d4, f, f3); + tessellator.addVertexWithUV(d9 + d3, d1 + 0.0D, (d2 - d13) + d4, f1, f3); + tessellator.addVertexWithUV(d9, d1 + 1.0D, d2 - d13, f1, f2); + } + + public void func_1239_a(Block block, int i, double d, double d1, double d2) + { + Tessellator tessellator = Tessellator.instance; + int j = block.getBlockTextureFromSideAndMetadata(0, i); + if(overrideBlockTexture >= 0) + { + j = overrideBlockTexture; + } + int k = (j & 0xf) << 4; + int l = j & 0xf0; + double d3 = (float)k / 256F; + double d4 = ((float)k + 15.99F) / 256F; + double d5 = (float)l / 256F; + double d6 = ((float)l + 15.99F) / 256F; + double d7 = (d + 0.5D) - 0.44999998807907104D; + double d8 = d + 0.5D + 0.44999998807907104D; + double d9 = (d2 + 0.5D) - 0.44999998807907104D; + double d10 = d2 + 0.5D + 0.44999998807907104D; + tessellator.addVertexWithUV(d7, d1 + 1.0D, d9, d3, d5); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d9, d3, d6); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d10, d4, d6); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d10, d4, d5); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d10, d3, d5); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d10, d3, d6); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d9, d4, d6); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d9, d4, d5); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d10, d3, d5); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d10, d3, d6); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d9, d4, d6); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d9, d4, d5); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d9, d3, d5); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d9, d3, d6); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d10, d4, d6); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d10, d4, d5); + } + + public void func_1245_b(Block block, int i, double d, double d1, double d2) + { + Tessellator tessellator = Tessellator.instance; + int j = block.getBlockTextureFromSideAndMetadata(0, i); + if(overrideBlockTexture >= 0) + { + j = overrideBlockTexture; + } + int k = (j & 0xf) << 4; + int l = j & 0xf0; + double d3 = (float)k / 256F; + double d4 = ((float)k + 15.99F) / 256F; + double d5 = (float)l / 256F; + double d6 = ((float)l + 15.99F) / 256F; + double d7 = (d + 0.5D) - 0.25D; + double d8 = d + 0.5D + 0.25D; + double d9 = (d2 + 0.5D) - 0.5D; + double d10 = d2 + 0.5D + 0.5D; + tessellator.addVertexWithUV(d7, d1 + 1.0D, d9, d3, d5); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d9, d3, d6); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d10, d4, d6); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d10, d4, d5); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d10, d3, d5); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d10, d3, d6); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d9, d4, d6); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d9, d4, d5); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d10, d3, d5); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d10, d3, d6); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d9, d4, d6); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d9, d4, d5); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d9, d3, d5); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d9, d3, d6); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d10, d4, d6); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d10, d4, d5); + d7 = (d + 0.5D) - 0.5D; + d8 = d + 0.5D + 0.5D; + d9 = (d2 + 0.5D) - 0.25D; + d10 = d2 + 0.5D + 0.25D; + tessellator.addVertexWithUV(d7, d1 + 1.0D, d9, d3, d5); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d9, d3, d6); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d9, d4, d6); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d9, d4, d5); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d9, d3, d5); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d9, d3, d6); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d9, d4, d6); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d9, d4, d5); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d10, d3, d5); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d10, d3, d6); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d10, d4, d6); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d10, d4, d5); + tessellator.addVertexWithUV(d7, d1 + 1.0D, d10, d3, d5); + tessellator.addVertexWithUV(d7, d1 + 0.0D, d10, d3, d6); + tessellator.addVertexWithUV(d8, d1 + 0.0D, d10, d4, d6); + tessellator.addVertexWithUV(d8, d1 + 1.0D, d10, d4, d5); + } + + public boolean renderBlockFluids(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + boolean flag = block.shouldSideBeRendered(blockAccess, i, j + 1, k, 1); + boolean flag1 = block.shouldSideBeRendered(blockAccess, i, j - 1, k, 0); + boolean aflag[] = new boolean[4]; + aflag[0] = block.shouldSideBeRendered(blockAccess, i, j, k - 1, 2); + aflag[1] = block.shouldSideBeRendered(blockAccess, i, j, k + 1, 3); + aflag[2] = block.shouldSideBeRendered(blockAccess, i - 1, j, k, 4); + aflag[3] = block.shouldSideBeRendered(blockAccess, i + 1, j, k, 5); + if(!flag && !flag1 && !aflag[0] && !aflag[1] && !aflag[2] && !aflag[3]) + { + return false; + } + boolean flag2 = false; + float f = 0.5F; + float f1 = 1.0F; + float f2 = 0.8F; + float f3 = 0.6F; + double d = 0.0D; + double d1 = 1.0D; + Material material = block.blockMaterial; + int l = blockAccess.getBlockMetadata(i, j, k); + float f4 = func_1224_a(i, j, k, material); + float f5 = func_1224_a(i, j, k + 1, material); + float f6 = func_1224_a(i + 1, j, k + 1, material); + float f7 = func_1224_a(i + 1, j, k, material); + if(renderAllFaces || flag) + { + flag2 = true; + int i1 = block.getBlockTextureFromSideAndMetadata(1, l); + float f9 = (float)BlockFluids.func_293_a(blockAccess, i, j, k, material); + if(f9 > -999F) + { + i1 = block.getBlockTextureFromSideAndMetadata(2, l); + } + int l1 = (i1 & 0xf) << 4; + int j2 = i1 & 0xf0; + double d2 = ((double)l1 + 8D) / 256D; + double d3 = ((double)j2 + 8D) / 256D; + if(f9 < -999F) + { + f9 = 0.0F; + } else + { + d2 = (float)(l1 + 16) / 256F; + d3 = (float)(j2 + 16) / 256F; + } + float f11 = (MathHelper.sin(f9) * 8F) / 256F; + float f13 = (MathHelper.cos(f9) * 8F) / 256F; + float f15 = block.getBlockBrightness(blockAccess, i, j, k); + tessellator.setColorOpaque_F(f1 * f15, f1 * f15, f1 * f15); + tessellator.addVertexWithUV(i + 0, (float)j + f4, k + 0, d2 - (double)f13 - (double)f11, (d3 - (double)f13) + (double)f11); + tessellator.addVertexWithUV(i + 0, (float)j + f5, k + 1, (d2 - (double)f13) + (double)f11, d3 + (double)f13 + (double)f11); + tessellator.addVertexWithUV(i + 1, (float)j + f6, k + 1, d2 + (double)f13 + (double)f11, (d3 + (double)f13) - (double)f11); + tessellator.addVertexWithUV(i + 1, (float)j + f7, k + 0, (d2 + (double)f13) - (double)f11, d3 - (double)f13 - (double)f11); + } + if(renderAllFaces || flag1) + { + float f8 = block.getBlockBrightness(blockAccess, i, j - 1, k); + tessellator.setColorOpaque_F(f * f8, f * f8, f * f8); + renderBottomFace(block, i, j, k, block.getBlockTextureFromSide(0)); + flag2 = true; + } + for(int j1 = 0; j1 < 4; j1++) + { + int k1 = i; + int i2 = j; + int k2 = k; + if(j1 == 0) + { + k2--; + } + if(j1 == 1) + { + k2++; + } + if(j1 == 2) + { + k1--; + } + if(j1 == 3) + { + k1++; + } + int l2 = block.getBlockTextureFromSideAndMetadata(j1 + 2, l); + int i3 = (l2 & 0xf) << 4; + int j3 = l2 & 0xf0; + if(!renderAllFaces && !aflag[j1]) + { + continue; + } + float f10; + float f12; + float f14; + float f16; + float f17; + float f18; + if(j1 == 0) + { + f10 = f4; + f12 = f7; + f14 = i; + f17 = i + 1; + f16 = k; + f18 = k; + } else + if(j1 == 1) + { + f10 = f6; + f12 = f5; + f14 = i + 1; + f17 = i; + f16 = k + 1; + f18 = k + 1; + } else + if(j1 == 2) + { + f10 = f5; + f12 = f4; + f14 = i; + f17 = i; + f16 = k + 1; + f18 = k; + } else + { + f10 = f7; + f12 = f6; + f14 = i + 1; + f17 = i + 1; + f16 = k; + f18 = k + 1; + } + flag2 = true; + double d4 = (float)(i3 + 0) / 256F; + double d5 = ((double)(i3 + 16) - 0.01D) / 256D; + double d6 = ((float)j3 + (1.0F - f10) * 16F) / 256F; + double d7 = ((float)j3 + (1.0F - f12) * 16F) / 256F; + double d8 = ((double)(j3 + 16) - 0.01D) / 256D; + float f19 = block.getBlockBrightness(blockAccess, k1, i2, k2); + if(j1 < 2) + { + f19 *= f2; + } else + { + f19 *= f3; + } + tessellator.setColorOpaque_F(f1 * f19, f1 * f19, f1 * f19); + tessellator.addVertexWithUV(f14, (float)j + f10, f16, d4, d6); + tessellator.addVertexWithUV(f17, (float)j + f12, f18, d5, d7); + tessellator.addVertexWithUV(f17, j + 0, f18, d5, d8); + tessellator.addVertexWithUV(f14, j + 0, f16, d4, d8); + } + + block.minY = d; + block.maxY = d1; + return flag2; + } + + private float func_1224_a(int i, int j, int k, Material material) + { + int l = 0; + float f = 0.0F; + for(int i1 = 0; i1 < 4; i1++) + { + int j1 = i - (i1 & 1); + int k1 = j; + int l1 = k - (i1 >> 1 & 1); + if(blockAccess.getBlockMaterial(j1, k1 + 1, l1) == material) + { + return 1.0F; + } + Material material1 = blockAccess.getBlockMaterial(j1, k1, l1); + if(material1 == material) + { + int i2 = blockAccess.getBlockMetadata(j1, k1, l1); + if(i2 >= 8 || i2 == 0) + { + f += BlockFluids.setFluidHeight(i2) * 10F; + l += 10; + } + f += BlockFluids.setFluidHeight(i2); + l++; + continue; + } + if(!material1.isSolid()) + { + f++; + l++; + } + } + + return 1.0F - f / (float)l; + } + + public void renderBlockFallingSand(Block block, World world, int i, int j, int k) + { + float f = 0.5F; + float f1 = 1.0F; + float f2 = 0.8F; + float f3 = 0.6F; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + float f4 = block.getBlockBrightness(world, i, j, k); + float f5 = block.getBlockBrightness(world, i, j - 1, k); + if(f5 < f4) + { + f5 = f4; + } + tessellator.setColorOpaque_F(f * f5, f * f5, f * f5); + renderBottomFace(block, -0.5D, -0.5D, -0.5D, block.getBlockTextureFromSide(0)); + f5 = block.getBlockBrightness(world, i, j + 1, k); + if(f5 < f4) + { + f5 = f4; + } + tessellator.setColorOpaque_F(f1 * f5, f1 * f5, f1 * f5); + renderTopFace(block, -0.5D, -0.5D, -0.5D, block.getBlockTextureFromSide(1)); + f5 = block.getBlockBrightness(world, i, j, k - 1); + if(f5 < f4) + { + f5 = f4; + } + tessellator.setColorOpaque_F(f2 * f5, f2 * f5, f2 * f5); + renderEastFace(block, -0.5D, -0.5D, -0.5D, block.getBlockTextureFromSide(2)); + f5 = block.getBlockBrightness(world, i, j, k + 1); + if(f5 < f4) + { + f5 = f4; + } + tessellator.setColorOpaque_F(f2 * f5, f2 * f5, f2 * f5); + renderWestFace(block, -0.5D, -0.5D, -0.5D, block.getBlockTextureFromSide(3)); + f5 = block.getBlockBrightness(world, i - 1, j, k); + if(f5 < f4) + { + f5 = f4; + } + tessellator.setColorOpaque_F(f3 * f5, f3 * f5, f3 * f5); + renderNorthFace(block, -0.5D, -0.5D, -0.5D, block.getBlockTextureFromSide(4)); + f5 = block.getBlockBrightness(world, i + 1, j, k); + if(f5 < f4) + { + f5 = f4; + } + tessellator.setColorOpaque_F(f3 * f5, f3 * f5, f3 * f5); + renderSouthFace(block, -0.5D, -0.5D, -0.5D, block.getBlockTextureFromSide(5)); + tessellator.draw(); + } + + public boolean renderStandardBlock(Block block, int i, int j, int k) + { + int l = block.colorMultiplier(blockAccess, i, j, k); + float f = (float)(l >> 16 & 0xff) / 255F; + float f1 = (float)(l >> 8 & 0xff) / 255F; + float f2 = (float)(l & 0xff) / 255F; + if(Minecraft.func_22005_v()) + { + return func_22330_a(block, i, j, k, f, f1, f2); + } else + { + return renderStandardBlockWithColorMultiplier(block, i, j, k, f, f1, f2); + } + } + + public boolean func_22330_a(Block block, int i, int j, int k, float f, float f1, float f2) + { + field_22385_e = true; + boolean flag = false; + float f3 = field_22384_f; + float f10 = field_22384_f; + float f17 = field_22384_f; + float f24 = field_22384_f; + boolean flag1 = true; + boolean flag2 = true; + boolean flag3 = true; + boolean flag4 = true; + boolean flag5 = true; + boolean flag6 = true; + field_22384_f = block.getBlockBrightness(blockAccess, i, j, k); + field_22383_g = block.getBlockBrightness(blockAccess, i - 1, j, k); + field_22382_h = block.getBlockBrightness(blockAccess, i, j - 1, k); + field_22381_i = block.getBlockBrightness(blockAccess, i, j, k - 1); + field_22380_j = block.getBlockBrightness(blockAccess, i + 1, j, k); + field_22379_k = block.getBlockBrightness(blockAccess, i, j + 1, k); + field_22378_l = block.getBlockBrightness(blockAccess, i, j, k + 1); + field_22338_U = Block.field_340_s[blockAccess.getBlockId(i + 1, j + 1, k)]; + field_22359_ac = Block.field_340_s[blockAccess.getBlockId(i + 1, j - 1, k)]; + field_22334_Y = Block.field_340_s[blockAccess.getBlockId(i + 1, j, k + 1)]; + field_22363_aa = Block.field_340_s[blockAccess.getBlockId(i + 1, j, k - 1)]; + field_22337_V = Block.field_340_s[blockAccess.getBlockId(i - 1, j + 1, k)]; + field_22357_ad = Block.field_340_s[blockAccess.getBlockId(i - 1, j - 1, k)]; + field_22335_X = Block.field_340_s[blockAccess.getBlockId(i - 1, j, k - 1)]; + field_22333_Z = Block.field_340_s[blockAccess.getBlockId(i - 1, j, k + 1)]; + field_22336_W = Block.field_340_s[blockAccess.getBlockId(i, j + 1, k + 1)]; + field_22339_T = Block.field_340_s[blockAccess.getBlockId(i, j + 1, k - 1)]; + field_22355_ae = Block.field_340_s[blockAccess.getBlockId(i, j - 1, k + 1)]; + field_22361_ab = Block.field_340_s[blockAccess.getBlockId(i, j - 1, k - 1)]; + if(block.blockIndexInTexture == 3) + { + flag1 = flag3 = flag4 = flag5 = flag6 = false; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j - 1, k, 0)) + { + float f4; + float f11; + float f18; + float f25; + if(field_22352_G > 0) + { + j--; + field_22376_n = block.getBlockBrightness(blockAccess, i - 1, j, k); + field_22374_p = block.getBlockBrightness(blockAccess, i, j, k - 1); + field_22373_q = block.getBlockBrightness(blockAccess, i, j, k + 1); + field_22371_s = block.getBlockBrightness(blockAccess, i + 1, j, k); + if(field_22361_ab || field_22357_ad) + { + field_22377_m = block.getBlockBrightness(blockAccess, i - 1, j, k - 1); + } else + { + field_22377_m = field_22376_n; + } + if(field_22355_ae || field_22357_ad) + { + field_22375_o = block.getBlockBrightness(blockAccess, i - 1, j, k + 1); + } else + { + field_22375_o = field_22376_n; + } + if(field_22361_ab || field_22359_ac) + { + field_22372_r = block.getBlockBrightness(blockAccess, i + 1, j, k - 1); + } else + { + field_22372_r = field_22371_s; + } + if(field_22355_ae || field_22359_ac) + { + field_22370_t = block.getBlockBrightness(blockAccess, i + 1, j, k + 1); + } else + { + field_22370_t = field_22371_s; + } + j++; + f4 = (field_22375_o + field_22376_n + field_22373_q + field_22382_h) / 4F; + f25 = (field_22373_q + field_22382_h + field_22370_t + field_22371_s) / 4F; + f18 = (field_22382_h + field_22374_p + field_22371_s + field_22372_r) / 4F; + f11 = (field_22376_n + field_22377_m + field_22382_h + field_22374_p) / 4F; + } else + { + f4 = f11 = f18 = f25 = field_22382_h; + } + field_22351_H = field_22350_I = field_22349_J = field_22348_K = (flag1 ? f : 1.0F) * 0.5F; + field_22347_L = field_22346_M = field_22345_N = field_22344_O = (flag1 ? f1 : 1.0F) * 0.5F; + field_22343_P = field_22342_Q = field_22341_R = field_22340_S = (flag1 ? f2 : 1.0F) * 0.5F; + field_22351_H *= f4; + field_22347_L *= f4; + field_22343_P *= f4; + field_22350_I *= f11; + field_22346_M *= f11; + field_22342_Q *= f11; + field_22349_J *= f18; + field_22345_N *= f18; + field_22341_R *= f18; + field_22348_K *= f25; + field_22344_O *= f25; + field_22340_S *= f25; + renderBottomFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 0)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j + 1, k, 1)) + { + float f5; + float f12; + float f19; + float f26; + if(field_22352_G > 0) + { + j++; + field_22368_v = block.getBlockBrightness(blockAccess, i - 1, j, k); + field_22364_z = block.getBlockBrightness(blockAccess, i + 1, j, k); + field_22366_x = block.getBlockBrightness(blockAccess, i, j, k - 1); + field_22362_A = block.getBlockBrightness(blockAccess, i, j, k + 1); + if(field_22339_T || field_22337_V) + { + field_22369_u = block.getBlockBrightness(blockAccess, i - 1, j, k - 1); + } else + { + field_22369_u = field_22368_v; + } + if(field_22339_T || field_22338_U) + { + field_22365_y = block.getBlockBrightness(blockAccess, i + 1, j, k - 1); + } else + { + field_22365_y = field_22364_z; + } + if(field_22336_W || field_22337_V) + { + field_22367_w = block.getBlockBrightness(blockAccess, i - 1, j, k + 1); + } else + { + field_22367_w = field_22368_v; + } + if(field_22336_W || field_22338_U) + { + field_22360_B = block.getBlockBrightness(blockAccess, i + 1, j, k + 1); + } else + { + field_22360_B = field_22364_z; + } + j--; + f26 = (field_22367_w + field_22368_v + field_22362_A + field_22379_k) / 4F; + f5 = (field_22362_A + field_22379_k + field_22360_B + field_22364_z) / 4F; + f12 = (field_22379_k + field_22366_x + field_22364_z + field_22365_y) / 4F; + f19 = (field_22368_v + field_22369_u + field_22379_k + field_22366_x) / 4F; + } else + { + f5 = f12 = f19 = f26 = field_22379_k; + } + field_22351_H = field_22350_I = field_22349_J = field_22348_K = flag2 ? f : 1.0F; + field_22347_L = field_22346_M = field_22345_N = field_22344_O = flag2 ? f1 : 1.0F; + field_22343_P = field_22342_Q = field_22341_R = field_22340_S = flag2 ? f2 : 1.0F; + field_22351_H *= f5; + field_22347_L *= f5; + field_22343_P *= f5; + field_22350_I *= f12; + field_22346_M *= f12; + field_22342_Q *= f12; + field_22349_J *= f19; + field_22345_N *= f19; + field_22341_R *= f19; + field_22348_K *= f26; + field_22344_O *= f26; + field_22340_S *= f26; + renderTopFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 1)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k - 1, 2)) + { + float f6; + float f13; + float f20; + float f27; + if(field_22352_G > 0) + { + k--; + field_22358_C = block.getBlockBrightness(blockAccess, i - 1, j, k); + field_22374_p = block.getBlockBrightness(blockAccess, i, j - 1, k); + field_22366_x = block.getBlockBrightness(blockAccess, i, j + 1, k); + field_22356_D = block.getBlockBrightness(blockAccess, i + 1, j, k); + if(field_22335_X || field_22361_ab) + { + field_22377_m = block.getBlockBrightness(blockAccess, i - 1, j - 1, k); + } else + { + field_22377_m = field_22358_C; + } + if(field_22335_X || field_22339_T) + { + field_22369_u = block.getBlockBrightness(blockAccess, i - 1, j + 1, k); + } else + { + field_22369_u = field_22358_C; + } + if(field_22363_aa || field_22361_ab) + { + field_22372_r = block.getBlockBrightness(blockAccess, i + 1, j - 1, k); + } else + { + field_22372_r = field_22356_D; + } + if(field_22363_aa || field_22339_T) + { + field_22365_y = block.getBlockBrightness(blockAccess, i + 1, j + 1, k); + } else + { + field_22365_y = field_22356_D; + } + k++; + f6 = (field_22358_C + field_22369_u + field_22381_i + field_22366_x) / 4F; + f13 = (field_22381_i + field_22366_x + field_22356_D + field_22365_y) / 4F; + f20 = (field_22374_p + field_22381_i + field_22372_r + field_22356_D) / 4F; + f27 = (field_22377_m + field_22358_C + field_22374_p + field_22381_i) / 4F; + } else + { + f6 = f13 = f20 = f27 = field_22381_i; + } + field_22351_H = field_22350_I = field_22349_J = field_22348_K = (flag3 ? f : 1.0F) * 0.8F; + field_22347_L = field_22346_M = field_22345_N = field_22344_O = (flag3 ? f1 : 1.0F) * 0.8F; + field_22343_P = field_22342_Q = field_22341_R = field_22340_S = (flag3 ? f2 : 1.0F) * 0.8F; + field_22351_H *= f6; + field_22347_L *= f6; + field_22343_P *= f6; + field_22350_I *= f13; + field_22346_M *= f13; + field_22342_Q *= f13; + field_22349_J *= f20; + field_22345_N *= f20; + field_22341_R *= f20; + field_22348_K *= f27; + field_22344_O *= f27; + field_22340_S *= f27; + renderEastFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 2)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k + 1, 3)) + { + float f7; + float f14; + float f21; + float f28; + if(field_22352_G > 0) + { + k++; + field_22354_E = block.getBlockBrightness(blockAccess, i - 1, j, k); + field_22353_F = block.getBlockBrightness(blockAccess, i + 1, j, k); + field_22373_q = block.getBlockBrightness(blockAccess, i, j - 1, k); + field_22362_A = block.getBlockBrightness(blockAccess, i, j + 1, k); + if(field_22333_Z || field_22355_ae) + { + field_22375_o = block.getBlockBrightness(blockAccess, i - 1, j - 1, k); + } else + { + field_22375_o = field_22354_E; + } + if(field_22333_Z || field_22336_W) + { + field_22367_w = block.getBlockBrightness(blockAccess, i - 1, j + 1, k); + } else + { + field_22367_w = field_22354_E; + } + if(field_22334_Y || field_22355_ae) + { + field_22370_t = block.getBlockBrightness(blockAccess, i + 1, j - 1, k); + } else + { + field_22370_t = field_22353_F; + } + if(field_22334_Y || field_22336_W) + { + field_22360_B = block.getBlockBrightness(blockAccess, i + 1, j + 1, k); + } else + { + field_22360_B = field_22353_F; + } + k--; + f7 = (field_22354_E + field_22367_w + field_22378_l + field_22362_A) / 4F; + f28 = (field_22378_l + field_22362_A + field_22353_F + field_22360_B) / 4F; + f21 = (field_22373_q + field_22378_l + field_22370_t + field_22353_F) / 4F; + f14 = (field_22375_o + field_22354_E + field_22373_q + field_22378_l) / 4F; + } else + { + f7 = f14 = f21 = f28 = field_22378_l; + } + field_22351_H = field_22350_I = field_22349_J = field_22348_K = (flag4 ? f : 1.0F) * 0.8F; + field_22347_L = field_22346_M = field_22345_N = field_22344_O = (flag4 ? f1 : 1.0F) * 0.8F; + field_22343_P = field_22342_Q = field_22341_R = field_22340_S = (flag4 ? f2 : 1.0F) * 0.8F; + field_22351_H *= f7; + field_22347_L *= f7; + field_22343_P *= f7; + field_22350_I *= f14; + field_22346_M *= f14; + field_22342_Q *= f14; + field_22349_J *= f21; + field_22345_N *= f21; + field_22341_R *= f21; + field_22348_K *= f28; + field_22344_O *= f28; + field_22340_S *= f28; + renderWestFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 3)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i - 1, j, k, 4)) + { + float f8; + float f15; + float f22; + float f29; + if(field_22352_G > 0) + { + i--; + field_22376_n = block.getBlockBrightness(blockAccess, i, j - 1, k); + field_22358_C = block.getBlockBrightness(blockAccess, i, j, k - 1); + field_22354_E = block.getBlockBrightness(blockAccess, i, j, k + 1); + field_22368_v = block.getBlockBrightness(blockAccess, i, j + 1, k); + if(field_22335_X || field_22357_ad) + { + field_22377_m = block.getBlockBrightness(blockAccess, i, j - 1, k - 1); + } else + { + field_22377_m = field_22358_C; + } + if(field_22333_Z || field_22357_ad) + { + field_22375_o = block.getBlockBrightness(blockAccess, i, j - 1, k + 1); + } else + { + field_22375_o = field_22354_E; + } + if(field_22335_X || field_22337_V) + { + field_22369_u = block.getBlockBrightness(blockAccess, i, j + 1, k - 1); + } else + { + field_22369_u = field_22358_C; + } + if(field_22333_Z || field_22337_V) + { + field_22367_w = block.getBlockBrightness(blockAccess, i, j + 1, k + 1); + } else + { + field_22367_w = field_22354_E; + } + i++; + f29 = (field_22376_n + field_22375_o + field_22383_g + field_22354_E) / 4F; + f8 = (field_22383_g + field_22354_E + field_22368_v + field_22367_w) / 4F; + f15 = (field_22358_C + field_22383_g + field_22369_u + field_22368_v) / 4F; + f22 = (field_22377_m + field_22376_n + field_22358_C + field_22383_g) / 4F; + } else + { + f8 = f15 = f22 = f29 = field_22383_g; + } + field_22351_H = field_22350_I = field_22349_J = field_22348_K = (flag5 ? f : 1.0F) * 0.6F; + field_22347_L = field_22346_M = field_22345_N = field_22344_O = (flag5 ? f1 : 1.0F) * 0.6F; + field_22343_P = field_22342_Q = field_22341_R = field_22340_S = (flag5 ? f2 : 1.0F) * 0.6F; + field_22351_H *= f8; + field_22347_L *= f8; + field_22343_P *= f8; + field_22350_I *= f15; + field_22346_M *= f15; + field_22342_Q *= f15; + field_22349_J *= f22; + field_22345_N *= f22; + field_22341_R *= f22; + field_22348_K *= f29; + field_22344_O *= f29; + field_22340_S *= f29; + renderNorthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 4)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i + 1, j, k, 5)) + { + float f9; + float f16; + float f23; + float f30; + if(field_22352_G > 0) + { + i++; + field_22371_s = block.getBlockBrightness(blockAccess, i, j - 1, k); + field_22356_D = block.getBlockBrightness(blockAccess, i, j, k - 1); + field_22353_F = block.getBlockBrightness(blockAccess, i, j, k + 1); + field_22364_z = block.getBlockBrightness(blockAccess, i, j + 1, k); + if(field_22359_ac || field_22363_aa) + { + field_22372_r = block.getBlockBrightness(blockAccess, i, j - 1, k - 1); + } else + { + field_22372_r = field_22356_D; + } + if(field_22359_ac || field_22334_Y) + { + field_22370_t = block.getBlockBrightness(blockAccess, i, j - 1, k + 1); + } else + { + field_22370_t = field_22353_F; + } + if(field_22338_U || field_22363_aa) + { + field_22365_y = block.getBlockBrightness(blockAccess, i, j + 1, k - 1); + } else + { + field_22365_y = field_22356_D; + } + if(field_22338_U || field_22334_Y) + { + field_22360_B = block.getBlockBrightness(blockAccess, i, j + 1, k + 1); + } else + { + field_22360_B = field_22353_F; + } + i--; + f9 = (field_22371_s + field_22370_t + field_22380_j + field_22353_F) / 4F; + f30 = (field_22380_j + field_22353_F + field_22364_z + field_22360_B) / 4F; + f23 = (field_22356_D + field_22380_j + field_22365_y + field_22364_z) / 4F; + f16 = (field_22372_r + field_22371_s + field_22356_D + field_22380_j) / 4F; + } else + { + f9 = f16 = f23 = f30 = field_22380_j; + } + field_22351_H = field_22350_I = field_22349_J = field_22348_K = (flag6 ? f : 1.0F) * 0.6F; + field_22347_L = field_22346_M = field_22345_N = field_22344_O = (flag6 ? f1 : 1.0F) * 0.6F; + field_22343_P = field_22342_Q = field_22341_R = field_22340_S = (flag6 ? f2 : 1.0F) * 0.6F; + field_22351_H *= f9; + field_22347_L *= f9; + field_22343_P *= f9; + field_22350_I *= f16; + field_22346_M *= f16; + field_22342_Q *= f16; + field_22349_J *= f23; + field_22345_N *= f23; + field_22341_R *= f23; + field_22348_K *= f30; + field_22344_O *= f30; + field_22340_S *= f30; + renderSouthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 5)); + flag = true; + } + field_22385_e = false; + return flag; + } + + public boolean renderStandardBlockWithColorMultiplier(Block block, int i, int j, int k, float f, float f1, float f2) + { + field_22385_e = false; + Tessellator tessellator = Tessellator.instance; + boolean flag = false; + float f3 = 0.5F; + float f4 = 1.0F; + float f5 = 0.8F; + float f6 = 0.6F; + float f7 = f4 * f; + float f8 = f4 * f1; + float f9 = f4 * f2; + if(block == Block.grass) + { + f = f1 = f2 = 1.0F; + } + float f10 = f3 * f; + float f11 = f5 * f; + float f12 = f6 * f; + float f13 = f3 * f1; + float f14 = f5 * f1; + float f15 = f6 * f1; + float f16 = f3 * f2; + float f17 = f5 * f2; + float f18 = f6 * f2; + float f19 = block.getBlockBrightness(blockAccess, i, j, k); + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j - 1, k, 0)) + { + float f20 = block.getBlockBrightness(blockAccess, i, j - 1, k); + tessellator.setColorOpaque_F(f10 * f20, f13 * f20, f16 * f20); + renderBottomFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 0)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j + 1, k, 1)) + { + float f21 = block.getBlockBrightness(blockAccess, i, j + 1, k); + if(block.maxY != 1.0D && !block.blockMaterial.getIsLiquid()) + { + f21 = f19; + } + tessellator.setColorOpaque_F(f7 * f21, f8 * f21, f9 * f21); + renderTopFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 1)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k - 1, 2)) + { + float f22 = block.getBlockBrightness(blockAccess, i, j, k - 1); + if(block.minZ > 0.0D) + { + f22 = f19; + } + tessellator.setColorOpaque_F(f11 * f22, f14 * f22, f17 * f22); + renderEastFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 2)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k + 1, 3)) + { + float f23 = block.getBlockBrightness(blockAccess, i, j, k + 1); + if(block.maxZ < 1.0D) + { + f23 = f19; + } + tessellator.setColorOpaque_F(f11 * f23, f14 * f23, f17 * f23); + renderWestFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 3)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i - 1, j, k, 4)) + { + float f24 = block.getBlockBrightness(blockAccess, i - 1, j, k); + if(block.minX > 0.0D) + { + f24 = f19; + } + tessellator.setColorOpaque_F(f12 * f24, f15 * f24, f18 * f24); + renderNorthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 4)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i + 1, j, k, 5)) + { + float f25 = block.getBlockBrightness(blockAccess, i + 1, j, k); + if(block.maxX < 1.0D) + { + f25 = f19; + } + tessellator.setColorOpaque_F(f12 * f25, f15 * f25, f18 * f25); + renderSouthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 5)); + flag = true; + } + return flag; + } + + public boolean renderBlockCactus(Block block, int i, int j, int k) + { + int l = block.colorMultiplier(blockAccess, i, j, k); + float f = (float)(l >> 16 & 0xff) / 255F; + float f1 = (float)(l >> 8 & 0xff) / 255F; + float f2 = (float)(l & 0xff) / 255F; + return func_1230_b(block, i, j, k, f, f1, f2); + } + + public boolean func_1230_b(Block block, int i, int j, int k, float f, float f1, float f2) + { + Tessellator tessellator = Tessellator.instance; + boolean flag = false; + float f3 = 0.5F; + float f4 = 1.0F; + float f5 = 0.8F; + float f6 = 0.6F; + float f7 = f3 * f; + float f8 = f4 * f; + float f9 = f5 * f; + float f10 = f6 * f; + float f11 = f3 * f1; + float f12 = f4 * f1; + float f13 = f5 * f1; + float f14 = f6 * f1; + float f15 = f3 * f2; + float f16 = f4 * f2; + float f17 = f5 * f2; + float f18 = f6 * f2; + float f19 = 0.0625F; + float f20 = block.getBlockBrightness(blockAccess, i, j, k); + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j - 1, k, 0)) + { + float f21 = block.getBlockBrightness(blockAccess, i, j - 1, k); + tessellator.setColorOpaque_F(f7 * f21, f11 * f21, f15 * f21); + renderBottomFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 0)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j + 1, k, 1)) + { + float f22 = block.getBlockBrightness(blockAccess, i, j + 1, k); + if(block.maxY != 1.0D && !block.blockMaterial.getIsLiquid()) + { + f22 = f20; + } + tessellator.setColorOpaque_F(f8 * f22, f12 * f22, f16 * f22); + renderTopFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 1)); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k - 1, 2)) + { + float f23 = block.getBlockBrightness(blockAccess, i, j, k - 1); + if(block.minZ > 0.0D) + { + f23 = f20; + } + tessellator.setColorOpaque_F(f9 * f23, f13 * f23, f17 * f23); + tessellator.setTranslationF(0.0F, 0.0F, f19); + renderEastFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 2)); + tessellator.setTranslationF(0.0F, 0.0F, -f19); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i, j, k + 1, 3)) + { + float f24 = block.getBlockBrightness(blockAccess, i, j, k + 1); + if(block.maxZ < 1.0D) + { + f24 = f20; + } + tessellator.setColorOpaque_F(f9 * f24, f13 * f24, f17 * f24); + tessellator.setTranslationF(0.0F, 0.0F, -f19); + renderWestFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 3)); + tessellator.setTranslationF(0.0F, 0.0F, f19); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i - 1, j, k, 4)) + { + float f25 = block.getBlockBrightness(blockAccess, i - 1, j, k); + if(block.minX > 0.0D) + { + f25 = f20; + } + tessellator.setColorOpaque_F(f10 * f25, f14 * f25, f18 * f25); + tessellator.setTranslationF(f19, 0.0F, 0.0F); + renderNorthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 4)); + tessellator.setTranslationF(-f19, 0.0F, 0.0F); + flag = true; + } + if(renderAllFaces || block.shouldSideBeRendered(blockAccess, i + 1, j, k, 5)) + { + float f26 = block.getBlockBrightness(blockAccess, i + 1, j, k); + if(block.maxX < 1.0D) + { + f26 = f20; + } + tessellator.setColorOpaque_F(f10 * f26, f14 * f26, f18 * f26); + tessellator.setTranslationF(-f19, 0.0F, 0.0F); + renderSouthFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 5)); + tessellator.setTranslationF(f19, 0.0F, 0.0F); + flag = true; + } + return flag; + } + + public boolean renderBlockFence(Block block, int i, int j, int k) + { + boolean flag = false; + float f = 0.375F; + float f1 = 0.625F; + block.setBlockBounds(f, 0.0F, f, f1, 1.0F, f1); + renderStandardBlock(block, i, j, k); + boolean flag1 = false; + boolean flag2 = false; + if(blockAccess.getBlockId(i - 1, j, k) == block.blockID || blockAccess.getBlockId(i + 1, j, k) == block.blockID) + { + flag1 = true; + } + if(blockAccess.getBlockId(i, j, k - 1) == block.blockID || blockAccess.getBlockId(i, j, k + 1) == block.blockID) + { + flag2 = true; + } + boolean flag3 = blockAccess.getBlockId(i - 1, j, k) == block.blockID; + boolean flag4 = blockAccess.getBlockId(i + 1, j, k) == block.blockID; + boolean flag5 = blockAccess.getBlockId(i, j, k - 1) == block.blockID; + boolean flag6 = blockAccess.getBlockId(i, j, k + 1) == block.blockID; + if(!flag1 && !flag2) + { + flag1 = true; + } + f = 0.4375F; + f1 = 0.5625F; + float f2 = 0.75F; + float f3 = 0.9375F; + float f4 = flag3 ? 0.0F : f; + float f5 = flag4 ? 1.0F : f1; + float f6 = flag5 ? 0.0F : f; + float f7 = flag6 ? 1.0F : f1; + if(flag1) + { + block.setBlockBounds(f4, f2, f, f5, f3, f1); + renderStandardBlock(block, i, j, k); + } + if(flag2) + { + block.setBlockBounds(f, f2, f6, f1, f3, f7); + renderStandardBlock(block, i, j, k); + } + f2 = 0.375F; + f3 = 0.5625F; + if(flag1) + { + block.setBlockBounds(f4, f2, f, f5, f3, f1); + renderStandardBlock(block, i, j, k); + } + if(flag2) + { + block.setBlockBounds(f, f2, f6, f1, f3, f7); + renderStandardBlock(block, i, j, k); + } + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + return flag; + } + + public boolean renderBlockStairs(Block block, int i, int j, int k) + { + boolean flag = false; + int l = blockAccess.getBlockMetadata(i, j, k); + if(l == 0) + { + block.setBlockBounds(0.0F, 0.0F, 0.0F, 0.5F, 0.5F, 1.0F); + renderStandardBlock(block, i, j, k); + block.setBlockBounds(0.5F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + renderStandardBlock(block, i, j, k); + } else + if(l == 1) + { + block.setBlockBounds(0.0F, 0.0F, 0.0F, 0.5F, 1.0F, 1.0F); + renderStandardBlock(block, i, j, k); + block.setBlockBounds(0.5F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + renderStandardBlock(block, i, j, k); + } else + if(l == 2) + { + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 0.5F); + renderStandardBlock(block, i, j, k); + block.setBlockBounds(0.0F, 0.0F, 0.5F, 1.0F, 1.0F, 1.0F); + renderStandardBlock(block, i, j, k); + } else + if(l == 3) + { + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F); + renderStandardBlock(block, i, j, k); + block.setBlockBounds(0.0F, 0.0F, 0.5F, 1.0F, 0.5F, 1.0F); + renderStandardBlock(block, i, j, k); + } + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + return flag; + } + + public boolean renderBlockDoor(Block block, int i, int j, int k) + { + Tessellator tessellator = Tessellator.instance; + BlockDoor blockdoor = (BlockDoor)block; + boolean flag = false; + float f = 0.5F; + float f1 = 1.0F; + float f2 = 0.8F; + float f3 = 0.6F; + float f4 = block.getBlockBrightness(blockAccess, i, j, k); + float f5 = block.getBlockBrightness(blockAccess, i, j - 1, k); + if(blockdoor.minY > 0.0D) + { + f5 = f4; + } + if(Block.lightValue[block.blockID] > 0) + { + f5 = 1.0F; + } + tessellator.setColorOpaque_F(f * f5, f * f5, f * f5); + renderBottomFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 0)); + flag = true; + f5 = block.getBlockBrightness(blockAccess, i, j + 1, k); + if(blockdoor.maxY < 1.0D) + { + f5 = f4; + } + if(Block.lightValue[block.blockID] > 0) + { + f5 = 1.0F; + } + tessellator.setColorOpaque_F(f1 * f5, f1 * f5, f1 * f5); + renderTopFace(block, i, j, k, block.getBlockTexture(blockAccess, i, j, k, 1)); + flag = true; + f5 = block.getBlockBrightness(blockAccess, i, j, k - 1); + if(blockdoor.minZ > 0.0D) + { + f5 = f4; + } + if(Block.lightValue[block.blockID] > 0) + { + f5 = 1.0F; + } + tessellator.setColorOpaque_F(f2 * f5, f2 * f5, f2 * f5); + int l = block.getBlockTexture(blockAccess, i, j, k, 2); + if(l < 0) + { + flipTexture = true; + l = -l; + } + renderEastFace(block, i, j, k, l); + flag = true; + flipTexture = false; + f5 = block.getBlockBrightness(blockAccess, i, j, k + 1); + if(blockdoor.maxZ < 1.0D) + { + f5 = f4; + } + if(Block.lightValue[block.blockID] > 0) + { + f5 = 1.0F; + } + tessellator.setColorOpaque_F(f2 * f5, f2 * f5, f2 * f5); + l = block.getBlockTexture(blockAccess, i, j, k, 3); + if(l < 0) + { + flipTexture = true; + l = -l; + } + renderWestFace(block, i, j, k, l); + flag = true; + flipTexture = false; + f5 = block.getBlockBrightness(blockAccess, i - 1, j, k); + if(blockdoor.minX > 0.0D) + { + f5 = f4; + } + if(Block.lightValue[block.blockID] > 0) + { + f5 = 1.0F; + } + tessellator.setColorOpaque_F(f3 * f5, f3 * f5, f3 * f5); + l = block.getBlockTexture(blockAccess, i, j, k, 4); + if(l < 0) + { + flipTexture = true; + l = -l; + } + renderNorthFace(block, i, j, k, l); + flag = true; + flipTexture = false; + f5 = block.getBlockBrightness(blockAccess, i + 1, j, k); + if(blockdoor.maxX < 1.0D) + { + f5 = f4; + } + if(Block.lightValue[block.blockID] > 0) + { + f5 = 1.0F; + } + tessellator.setColorOpaque_F(f3 * f5, f3 * f5, f3 * f5); + l = block.getBlockTexture(blockAccess, i, j, k, 5); + if(l < 0) + { + flipTexture = true; + l = -l; + } + renderSouthFace(block, i, j, k, l); + flag = true; + flipTexture = false; + return flag; + } + + public void renderBottomFace(Block block, double d, double d1, double d2, + int i) + { + Tessellator tessellator = Tessellator.instance; + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + double d3 = ((double)j + block.minX * 16D) / 256D; + double d4 = (((double)j + block.maxX * 16D) - 0.01D) / 256D; + double d5 = ((double)k + block.minZ * 16D) / 256D; + double d6 = (((double)k + block.maxZ * 16D) - 0.01D) / 256D; + if(block.minX < 0.0D || block.maxX > 1.0D) + { + d3 = ((float)j + 0.0F) / 256F; + d4 = ((float)j + 15.99F) / 256F; + } + if(block.minZ < 0.0D || block.maxZ > 1.0D) + { + d5 = ((float)k + 0.0F) / 256F; + d6 = ((float)k + 15.99F) / 256F; + } + double d7 = d + block.minX; + double d8 = d + block.maxX; + double d9 = d1 + block.minY; + double d10 = d2 + block.minZ; + double d11 = d2 + block.maxZ; + if(field_22385_e) + { + tessellator.setColorOpaque_F(field_22351_H, field_22347_L, field_22343_P); + tessellator.addVertexWithUV(d7, d9, d11, d3, d6); + tessellator.setColorOpaque_F(field_22350_I, field_22346_M, field_22342_Q); + tessellator.addVertexWithUV(d7, d9, d10, d3, d5); + tessellator.setColorOpaque_F(field_22349_J, field_22345_N, field_22341_R); + tessellator.addVertexWithUV(d8, d9, d10, d4, d5); + tessellator.setColorOpaque_F(field_22348_K, field_22344_O, field_22340_S); + tessellator.addVertexWithUV(d8, d9, d11, d4, d6); + } else + { + tessellator.addVertexWithUV(d7, d9, d11, d3, d6); + tessellator.addVertexWithUV(d7, d9, d10, d3, d5); + tessellator.addVertexWithUV(d8, d9, d10, d4, d5); + tessellator.addVertexWithUV(d8, d9, d11, d4, d6); + } + } + + public void renderTopFace(Block block, double d, double d1, double d2, + int i) + { + Tessellator tessellator = Tessellator.instance; + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + double d3 = ((double)j + block.minX * 16D) / 256D; + double d4 = (((double)j + block.maxX * 16D) - 0.01D) / 256D; + double d5 = ((double)k + block.minZ * 16D) / 256D; + double d6 = (((double)k + block.maxZ * 16D) - 0.01D) / 256D; + if(block.minX < 0.0D || block.maxX > 1.0D) + { + d3 = ((float)j + 0.0F) / 256F; + d4 = ((float)j + 15.99F) / 256F; + } + if(block.minZ < 0.0D || block.maxZ > 1.0D) + { + d5 = ((float)k + 0.0F) / 256F; + d6 = ((float)k + 15.99F) / 256F; + } + double d7 = d + block.minX; + double d8 = d + block.maxX; + double d9 = d1 + block.maxY; + double d10 = d2 + block.minZ; + double d11 = d2 + block.maxZ; + if(field_22385_e) + { + tessellator.setColorOpaque_F(field_22351_H, field_22347_L, field_22343_P); + tessellator.addVertexWithUV(d8, d9, d11, d4, d6); + tessellator.setColorOpaque_F(field_22350_I, field_22346_M, field_22342_Q); + tessellator.addVertexWithUV(d8, d9, d10, d4, d5); + tessellator.setColorOpaque_F(field_22349_J, field_22345_N, field_22341_R); + tessellator.addVertexWithUV(d7, d9, d10, d3, d5); + tessellator.setColorOpaque_F(field_22348_K, field_22344_O, field_22340_S); + tessellator.addVertexWithUV(d7, d9, d11, d3, d6); + } else + { + tessellator.addVertexWithUV(d8, d9, d11, d4, d6); + tessellator.addVertexWithUV(d8, d9, d10, d4, d5); + tessellator.addVertexWithUV(d7, d9, d10, d3, d5); + tessellator.addVertexWithUV(d7, d9, d11, d3, d6); + } + } + + public void renderEastFace(Block block, double d, double d1, double d2, + int i) + { + Tessellator tessellator = Tessellator.instance; + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + double d3 = ((double)j + block.minX * 16D) / 256D; + double d4 = (((double)j + block.maxX * 16D) - 0.01D) / 256D; + double d5 = ((double)k + block.minY * 16D) / 256D; + double d6 = (((double)k + block.maxY * 16D) - 0.01D) / 256D; + if(flipTexture) + { + double d7 = d3; + d3 = d4; + d4 = d7; + } + if(block.minX < 0.0D || block.maxX > 1.0D) + { + d3 = ((float)j + 0.0F) / 256F; + d4 = ((float)j + 15.99F) / 256F; + } + if(block.minY < 0.0D || block.maxY > 1.0D) + { + d5 = ((float)k + 0.0F) / 256F; + d6 = ((float)k + 15.99F) / 256F; + } + double d8 = d + block.minX; + double d9 = d + block.maxX; + double d10 = d1 + block.minY; + double d11 = d1 + block.maxY; + double d12 = d2 + block.minZ; + if(field_22385_e) + { + tessellator.setColorOpaque_F(field_22351_H, field_22347_L, field_22343_P); + tessellator.addVertexWithUV(d8, d11, d12, d4, d5); + tessellator.setColorOpaque_F(field_22350_I, field_22346_M, field_22342_Q); + tessellator.addVertexWithUV(d9, d11, d12, d3, d5); + tessellator.setColorOpaque_F(field_22349_J, field_22345_N, field_22341_R); + tessellator.addVertexWithUV(d9, d10, d12, d3, d6); + tessellator.setColorOpaque_F(field_22348_K, field_22344_O, field_22340_S); + tessellator.addVertexWithUV(d8, d10, d12, d4, d6); + } else + { + tessellator.addVertexWithUV(d8, d11, d12, d4, d5); + tessellator.addVertexWithUV(d9, d11, d12, d3, d5); + tessellator.addVertexWithUV(d9, d10, d12, d3, d6); + tessellator.addVertexWithUV(d8, d10, d12, d4, d6); + } + } + + public void renderWestFace(Block block, double d, double d1, double d2, + int i) + { + Tessellator tessellator = Tessellator.instance; + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + double d3 = ((double)j + block.minX * 16D) / 256D; + double d4 = (((double)j + block.maxX * 16D) - 0.01D) / 256D; + double d5 = ((double)k + block.minY * 16D) / 256D; + double d6 = (((double)k + block.maxY * 16D) - 0.01D) / 256D; + if(flipTexture) + { + double d7 = d3; + d3 = d4; + d4 = d7; + } + if(block.minX < 0.0D || block.maxX > 1.0D) + { + d3 = ((float)j + 0.0F) / 256F; + d4 = ((float)j + 15.99F) / 256F; + } + if(block.minY < 0.0D || block.maxY > 1.0D) + { + d5 = ((float)k + 0.0F) / 256F; + d6 = ((float)k + 15.99F) / 256F; + } + double d8 = d + block.minX; + double d9 = d + block.maxX; + double d10 = d1 + block.minY; + double d11 = d1 + block.maxY; + double d12 = d2 + block.maxZ; + if(field_22385_e) + { + tessellator.setColorOpaque_F(field_22351_H, field_22347_L, field_22343_P); + tessellator.addVertexWithUV(d8, d11, d12, d3, d5); + tessellator.setColorOpaque_F(field_22350_I, field_22346_M, field_22342_Q); + tessellator.addVertexWithUV(d8, d10, d12, d3, d6); + tessellator.setColorOpaque_F(field_22349_J, field_22345_N, field_22341_R); + tessellator.addVertexWithUV(d9, d10, d12, d4, d6); + tessellator.setColorOpaque_F(field_22348_K, field_22344_O, field_22340_S); + tessellator.addVertexWithUV(d9, d11, d12, d4, d5); + } else + { + tessellator.addVertexWithUV(d8, d11, d12, d3, d5); + tessellator.addVertexWithUV(d8, d10, d12, d3, d6); + tessellator.addVertexWithUV(d9, d10, d12, d4, d6); + tessellator.addVertexWithUV(d9, d11, d12, d4, d5); + } + } + + public void renderNorthFace(Block block, double d, double d1, double d2, + int i) + { + Tessellator tessellator = Tessellator.instance; + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + double d3 = ((double)j + block.minZ * 16D) / 256D; + double d4 = (((double)j + block.maxZ * 16D) - 0.01D) / 256D; + double d5 = ((double)k + block.minY * 16D) / 256D; + double d6 = (((double)k + block.maxY * 16D) - 0.01D) / 256D; + if(flipTexture) + { + double d7 = d3; + d3 = d4; + d4 = d7; + } + if(block.minZ < 0.0D || block.maxZ > 1.0D) + { + d3 = ((float)j + 0.0F) / 256F; + d4 = ((float)j + 15.99F) / 256F; + } + if(block.minY < 0.0D || block.maxY > 1.0D) + { + d5 = ((float)k + 0.0F) / 256F; + d6 = ((float)k + 15.99F) / 256F; + } + double d8 = d + block.minX; + double d9 = d1 + block.minY; + double d10 = d1 + block.maxY; + double d11 = d2 + block.minZ; + double d12 = d2 + block.maxZ; + if(field_22385_e) + { + tessellator.setColorOpaque_F(field_22351_H, field_22347_L, field_22343_P); + tessellator.addVertexWithUV(d8, d10, d12, d4, d5); + tessellator.setColorOpaque_F(field_22350_I, field_22346_M, field_22342_Q); + tessellator.addVertexWithUV(d8, d10, d11, d3, d5); + tessellator.setColorOpaque_F(field_22349_J, field_22345_N, field_22341_R); + tessellator.addVertexWithUV(d8, d9, d11, d3, d6); + tessellator.setColorOpaque_F(field_22348_K, field_22344_O, field_22340_S); + tessellator.addVertexWithUV(d8, d9, d12, d4, d6); + } else + { + tessellator.addVertexWithUV(d8, d10, d12, d4, d5); + tessellator.addVertexWithUV(d8, d10, d11, d3, d5); + tessellator.addVertexWithUV(d8, d9, d11, d3, d6); + tessellator.addVertexWithUV(d8, d9, d12, d4, d6); + } + } + + public void renderSouthFace(Block block, double d, double d1, double d2, + int i) + { + Tessellator tessellator = Tessellator.instance; + if(overrideBlockTexture >= 0) + { + i = overrideBlockTexture; + } + int j = (i & 0xf) << 4; + int k = i & 0xf0; + double d3 = ((double)j + block.minZ * 16D) / 256D; + double d4 = (((double)j + block.maxZ * 16D) - 0.01D) / 256D; + double d5 = ((double)k + block.minY * 16D) / 256D; + double d6 = (((double)k + block.maxY * 16D) - 0.01D) / 256D; + if(flipTexture) + { + double d7 = d3; + d3 = d4; + d4 = d7; + } + if(block.minZ < 0.0D || block.maxZ > 1.0D) + { + d3 = ((float)j + 0.0F) / 256F; + d4 = ((float)j + 15.99F) / 256F; + } + if(block.minY < 0.0D || block.maxY > 1.0D) + { + d5 = ((float)k + 0.0F) / 256F; + d6 = ((float)k + 15.99F) / 256F; + } + double d8 = d + block.maxX; + double d9 = d1 + block.minY; + double d10 = d1 + block.maxY; + double d11 = d2 + block.minZ; + double d12 = d2 + block.maxZ; + if(field_22385_e) + { + tessellator.setColorOpaque_F(field_22351_H, field_22347_L, field_22343_P); + tessellator.addVertexWithUV(d8, d9, d12, d3, d6); + tessellator.setColorOpaque_F(field_22350_I, field_22346_M, field_22342_Q); + tessellator.addVertexWithUV(d8, d9, d11, d4, d6); + tessellator.setColorOpaque_F(field_22349_J, field_22345_N, field_22341_R); + tessellator.addVertexWithUV(d8, d10, d11, d4, d5); + tessellator.setColorOpaque_F(field_22348_K, field_22344_O, field_22340_S); + tessellator.addVertexWithUV(d8, d10, d12, d3, d5); + } else + { + tessellator.addVertexWithUV(d8, d9, d12, d3, d6); + tessellator.addVertexWithUV(d8, d9, d11, d4, d6); + tessellator.addVertexWithUV(d8, d10, d11, d4, d5); + tessellator.addVertexWithUV(d8, d10, d12, d3, d5); + } + } + + public void func_1238_a(Block block, float f) + { + int i = block.getRenderType(); + Tessellator tessellator = Tessellator.instance; + if(i == 0) + { + block.func_237_e(); + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + float f1 = 0.5F; + float f2 = 1.0F; + float f3 = 0.8F; + float f4 = 0.6F; + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_F(f2, f2, f2, f); + renderBottomFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(0)); + tessellator.setColorRGBA_F(f1, f1, f1, f); + renderTopFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(1)); + tessellator.setColorRGBA_F(f3, f3, f3, f); + renderEastFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(2)); + renderWestFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(3)); + tessellator.setColorRGBA_F(f4, f4, f4, f); + renderNorthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(4)); + renderSouthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(5)); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } + } + + public void func_1227_a(Block block, int i) + { + Tessellator tessellator = Tessellator.instance; + int j = block.getRenderType(); + if(j == 0) + { + block.func_237_e(); + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + renderBottomFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(0, i)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + renderTopFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(1, i)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + renderEastFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(2, i)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + renderWestFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(3, i)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1F, 0.0F, 0.0F); + renderNorthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(4, i)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + renderSouthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSideAndMetadata(5, i)); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } else + if(j == 1) + { + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + func_1239_a(block, i, -0.5D, -0.5D, -0.5D); + tessellator.draw(); + } else + if(j == 13) + { + block.func_237_e(); + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + float f = 0.0625F; + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + renderBottomFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(0)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + renderTopFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(1)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + tessellator.setTranslationF(0.0F, 0.0F, f); + renderEastFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(2)); + tessellator.setTranslationF(0.0F, 0.0F, -f); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + tessellator.setTranslationF(0.0F, 0.0F, -f); + renderWestFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(3)); + tessellator.setTranslationF(0.0F, 0.0F, f); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1F, 0.0F, 0.0F); + tessellator.setTranslationF(f, 0.0F, 0.0F); + renderNorthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(4)); + tessellator.setTranslationF(-f, 0.0F, 0.0F); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + tessellator.setTranslationF(-f, 0.0F, 0.0F); + renderSouthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(5)); + tessellator.setTranslationF(f, 0.0F, 0.0F); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } else + if(j == 6) + { + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + func_1245_b(block, i, -0.5D, -0.5D, -0.5D); + tessellator.draw(); + } else + if(j == 2) + { + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + renderTorchAtAngle(block, -0.5D, -0.5D, -0.5D, 0.0D, 0.0D); + tessellator.draw(); + } else + if(j == 10) + { + for(int k = 0; k < 2; k++) + { + if(k == 0) + { + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.5F); + } + if(k == 1) + { + block.setBlockBounds(0.0F, 0.0F, 0.5F, 1.0F, 0.5F, 1.0F); + } + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + renderBottomFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(0)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + renderTopFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(1)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + renderEastFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(2)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + renderWestFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(3)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1F, 0.0F, 0.0F); + renderNorthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(4)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + renderSouthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(5)); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } + + } else + if(j == 11) + { + for(int l = 0; l < 4; l++) + { + float f1 = 0.125F; + if(l == 0) + { + block.setBlockBounds(0.5F - f1, 0.0F, 0.0F, 0.5F + f1, 1.0F, f1 * 2.0F); + } + if(l == 1) + { + block.setBlockBounds(0.5F - f1, 0.0F, 1.0F - f1 * 2.0F, 0.5F + f1, 1.0F, 1.0F); + } + f1 = 0.0625F; + if(l == 2) + { + block.setBlockBounds(0.5F - f1, 1.0F - f1 * 3F, -f1 * 2.0F, 0.5F + f1, 1.0F - f1, 1.0F + f1 * 2.0F); + } + if(l == 3) + { + block.setBlockBounds(0.5F - f1, 0.5F - f1 * 3F, -f1 * 2.0F, 0.5F + f1, 0.5F - f1, 1.0F + f1 * 2.0F); + } + GL11.glTranslatef(-0.5F, -0.5F, -0.5F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, -1F, 0.0F); + renderBottomFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(0)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + renderTopFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(1)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + renderEastFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(2)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + renderWestFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(3)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(-1F, 0.0F, 0.0F); + renderNorthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(4)); + tessellator.draw(); + tessellator.startDrawingQuads(); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + renderSouthFace(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(5)); + tessellator.draw(); + GL11.glTranslatef(0.5F, 0.5F, 0.5F); + } + + block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + public static boolean func_1219_a(int i) + { + if(i == 0) + { + return true; + } + if(i == 13) + { + return true; + } + if(i == 10) + { + return true; + } + return i == 11; + } + + private IBlockAccess blockAccess; + private int overrideBlockTexture; + private boolean flipTexture; + private boolean renderAllFaces; + private boolean field_22385_e; + private float field_22384_f; + private float field_22383_g; + private float field_22382_h; + private float field_22381_i; + private float field_22380_j; + private float field_22379_k; + private float field_22378_l; + private float field_22377_m; + private float field_22376_n; + private float field_22375_o; + private float field_22374_p; + private float field_22373_q; + private float field_22372_r; + private float field_22371_s; + private float field_22370_t; + private float field_22369_u; + private float field_22368_v; + private float field_22367_w; + private float field_22366_x; + private float field_22365_y; + private float field_22364_z; + private float field_22362_A; + private float field_22360_B; + private float field_22358_C; + private float field_22356_D; + private float field_22354_E; + private float field_22353_F; + private int field_22352_G; + private float field_22351_H; + private float field_22350_I; + private float field_22349_J; + private float field_22348_K; + private float field_22347_L; + private float field_22346_M; + private float field_22345_N; + private float field_22344_O; + private float field_22343_P; + private float field_22342_Q; + private float field_22341_R; + private float field_22340_S; + private boolean field_22339_T; + private boolean field_22338_U; + private boolean field_22337_V; + private boolean field_22336_W; + private boolean field_22335_X; + private boolean field_22334_Y; + private boolean field_22333_Z; + private boolean field_22363_aa; + private boolean field_22361_ab; + private boolean field_22359_ac; + private boolean field_22357_ad; + private boolean field_22355_ae; +} diff --git a/src/main/java/net/minecraft/src/RenderBoat.java b/src/main/java/net/minecraft/src/RenderBoat.java new file mode 100644 index 0000000..af91a70 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderBoat.java @@ -0,0 +1,50 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderBoat extends Render +{ + + public RenderBoat() + { + shadowSize = 0.5F; + modelBoat = new ModelBoat(); + } + + public void func_157_a(EntityBoat entityboat, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glRotatef(180F - f, 0.0F, 1.0F, 0.0F); + float f2 = (float)entityboat.field_806_b - f1; + float f3 = (float)entityboat.field_807_a - f1; + if(f3 < 0.0F) + { + f3 = 0.0F; + } + if(f2 > 0.0F) + { + GL11.glRotatef(((MathHelper.sin(f2) * f2 * f3) / 10F) * (float)entityboat.field_808_c, 1.0F, 0.0F, 0.0F); + } + loadTexture("/terrain.png"); + float f4 = 0.75F; + GL11.glScalef(f4, f4, f4); + GL11.glScalef(1.0F / f4, 1.0F / f4, 1.0F / f4); + loadTexture("/item/boat.png"); + GL11.glScalef(-1F, -1F, 1.0F); + modelBoat.render(0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_157_a((EntityBoat)entity, d, d1, d2, f, f1); + } + + protected ModelBase modelBoat; +} diff --git a/src/main/java/net/minecraft/src/RenderChicken.java b/src/main/java/net/minecraft/src/RenderChicken.java new file mode 100644 index 0000000..265fc0e --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderChicken.java @@ -0,0 +1,44 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RenderChicken extends RenderLiving +{ + + public RenderChicken(ModelBase modelbase, float f) + { + super(modelbase, f); + } + + public void func_181_a(EntityChicken entitychicken, double d, double d1, double d2, + float f, float f1) + { + super.doRenderLiving(entitychicken, d, d1, d2, f, f1); + } + + protected float func_182_a(EntityChicken entitychicken, float f) + { + float f1 = entitychicken.field_756_e + (entitychicken.field_752_b - entitychicken.field_756_e) * f; + float f2 = entitychicken.field_757_d + (entitychicken.field_758_c - entitychicken.field_757_d) * f; + return (MathHelper.sin(f1) + 1.0F) * f2; + } + + protected float func_170_d(EntityLiving entityliving, float f) + { + return func_182_a((EntityChicken)entityliving, f); + } + + public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, + float f, float f1) + { + func_181_a((EntityChicken)entityliving, d, d1, d2, f, f1); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_181_a((EntityChicken)entity, d, d1, d2, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderCow.java b/src/main/java/net/minecraft/src/RenderCow.java new file mode 100644 index 0000000..bcddc0b --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderCow.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RenderCow extends RenderLiving +{ + + public RenderCow(ModelBase modelbase, float f) + { + super(modelbase, f); + } + + public void func_177_a(EntityCow entitycow, double d, double d1, double d2, + float f, float f1) + { + super.doRenderLiving(entitycow, d, d1, d2, f, f1); + } + + public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, + float f, float f1) + { + func_177_a((EntityCow)entityliving, d, d1, d2, f, f1); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_177_a((EntityCow)entity, d, d1, d2, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderCreeper.java b/src/main/java/net/minecraft/src/RenderCreeper.java new file mode 100644 index 0000000..5f9f7e4 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderCreeper.java @@ -0,0 +1,68 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderCreeper extends RenderLiving +{ + + public RenderCreeper() + { + super(new ModelCreeper(), 0.5F); + } + + protected void updateCreeperScale(EntityCreeper entitycreeper, float f) + { + EntityCreeper entitycreeper1 = entitycreeper; + float f1 = entitycreeper1.func_440_b(f); + float f2 = 1.0F + MathHelper.sin(f1 * 100F) * f1 * 0.01F; + if(f1 < 0.0F) + { + f1 = 0.0F; + } + if(f1 > 1.0F) + { + f1 = 1.0F; + } + f1 *= f1; + f1 *= f1; + float f3 = (1.0F + f1 * 0.4F) * f2; + float f4 = (1.0F + f1 * 0.1F) / f2; + GL11.glScalef(f3, f4, f3); + } + + protected int updateCreeperColorMultiplier(EntityCreeper entitycreeper, float f, float f1) + { + EntityCreeper entitycreeper1 = entitycreeper; + float f2 = entitycreeper1.func_440_b(f1); + if((int)(f2 * 10F) % 2 == 0) + { + return 0; + } + int i = (int)(f2 * 0.2F * 255F); + if(i < 0) + { + i = 0; + } + if(i > 255) + { + i = 255; + } + char c = '\377'; + char c1 = '\377'; + char c2 = '\377'; + return i << 24 | c << 16 | c1 << 8 | c2; + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + updateCreeperScale((EntityCreeper)entityliving, f); + } + + protected int getColorMultiplier(EntityLiving entityliving, float f, float f1) + { + return updateCreeperColorMultiplier((EntityCreeper)entityliving, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderEngine.java b/src/main/java/net/minecraft/src/RenderEngine.java new file mode 100644 index 0000000..25790eb --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderEngine.java @@ -0,0 +1,475 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import javax.imageio.ImageIO; +import org.lwjgl.opengl.GL11; + +public class RenderEngine +{ + + public RenderEngine(TexturePackList texturepacklist, GameSettings gamesettings) + { + textureMap = new HashMap(); + textureNameToImageMap = new HashMap(); + singleIntBuffer = GLAllocation.createDirectIntBuffer(1); + imageData = GLAllocation.createDirectByteBuffer(0x100000); + textureList = new ArrayList(); + urlToImageDataMap = new HashMap(); + clampTexture = false; + blurTexture = false; + field_6527_k = texturepacklist; + options = gamesettings; + } + + public int getTexture(String s) + { + TexturePackBase texturepackbase = field_6527_k.selectedTexturePack; + Integer integer = (Integer)textureMap.get(s); + if(integer != null) + { + return integer.intValue(); + } + try + { + singleIntBuffer.clear(); + GLAllocation.generateTextureNames(singleIntBuffer); + int i = singleIntBuffer.get(0); + if(s.startsWith("##")) + { + setupTexture(unwrapImageByColumns(readTextureImage(texturepackbase.func_6481_a(s.substring(2)))), i); + } else + if(s.startsWith("%clamp%")) + { + clampTexture = true; + setupTexture(readTextureImage(texturepackbase.func_6481_a(s.substring(7))), i); + clampTexture = false; + } else + if(s.startsWith("%blur%")) + { + blurTexture = true; + setupTexture(readTextureImage(texturepackbase.func_6481_a(s.substring(6))), i); + blurTexture = false; + } else + { + setupTexture(readTextureImage(texturepackbase.func_6481_a(s)), i); + } + textureMap.put(s, Integer.valueOf(i)); + return i; + } + catch(IOException ioexception) + { + throw new RuntimeException("!!"); + } + } + + private BufferedImage unwrapImageByColumns(BufferedImage bufferedimage) + { + int i = bufferedimage.getWidth() / 16; + BufferedImage bufferedimage1 = new BufferedImage(16, bufferedimage.getHeight() * i, 2); + Graphics g = bufferedimage1.getGraphics(); + for(int j = 0; j < i; j++) + { + g.drawImage(bufferedimage, -j * 16, j * bufferedimage.getHeight(), null); + } + + g.dispose(); + return bufferedimage1; + } + + public int allocateAndSetupTexture(BufferedImage bufferedimage) + { + singleIntBuffer.clear(); + GLAllocation.generateTextureNames(singleIntBuffer); + int i = singleIntBuffer.get(0); + setupTexture(bufferedimage, i); + textureNameToImageMap.put(Integer.valueOf(i), bufferedimage); + return i; + } + + public void setupTexture(BufferedImage bufferedimage, int i) + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, i); + if(useMipmaps) + { + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10241 /*GL_TEXTURE_MIN_FILTER*/, 9987 /*GL_LINEAR_MIPMAP_LINEAR*/); + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10240 /*GL_TEXTURE_MAG_FILTER*/, 9729 /*GL_LINEAR*/); + } else + { + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10241 /*GL_TEXTURE_MIN_FILTER*/, 9728 /*GL_NEAREST*/); + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10240 /*GL_TEXTURE_MAG_FILTER*/, 9728 /*GL_NEAREST*/); + } + if(blurTexture) + { + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10241 /*GL_TEXTURE_MIN_FILTER*/, 9729 /*GL_LINEAR*/); + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10240 /*GL_TEXTURE_MAG_FILTER*/, 9729 /*GL_LINEAR*/); + } + if(clampTexture) + { + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10242 /*GL_TEXTURE_WRAP_S*/, 10496 /*GL_CLAMP*/); + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10243 /*GL_TEXTURE_WRAP_T*/, 10496 /*GL_CLAMP*/); + } else + { + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10242 /*GL_TEXTURE_WRAP_S*/, 10497 /*GL_REPEAT*/); + GL11.glTexParameteri(3553 /*GL_TEXTURE_2D*/, 10243 /*GL_TEXTURE_WRAP_T*/, 10497 /*GL_REPEAT*/); + } + int j = bufferedimage.getWidth(); + int k = bufferedimage.getHeight(); + int ai[] = new int[j * k]; + byte abyte0[] = new byte[j * k * 4]; + bufferedimage.getRGB(0, 0, j, k, ai, 0, j); + for(int l = 0; l < ai.length; l++) + { + int j1 = ai[l] >> 24 & 0xff; + int l1 = ai[l] >> 16 & 0xff; + int j2 = ai[l] >> 8 & 0xff; + int l2 = ai[l] & 0xff; + if(options != null && options.anaglyph) + { + int j3 = (l1 * 30 + j2 * 59 + l2 * 11) / 100; + int l3 = (l1 * 30 + j2 * 70) / 100; + int j4 = (l1 * 30 + l2 * 70) / 100; + l1 = j3; + j2 = l3; + l2 = j4; + } + abyte0[l * 4 + 0] = (byte)l1; + abyte0[l * 4 + 1] = (byte)j2; + abyte0[l * 4 + 2] = (byte)l2; + abyte0[l * 4 + 3] = (byte)j1; + } + + imageData.clear(); + imageData.put(abyte0); + imageData.position(0).limit(abyte0.length); + GL11.glTexImage2D(3553 /*GL_TEXTURE_2D*/, 0, 6408 /*GL_RGBA*/, j, k, 0, 6408 /*GL_RGBA*/, 5121 /*GL_UNSIGNED_BYTE*/, imageData); + if(useMipmaps) + { + for(int i1 = 1; i1 <= 4; i1++) + { + int k1 = j >> i1 - 1; + int i2 = j >> i1; + int k2 = k >> i1; + for(int i3 = 0; i3 < i2; i3++) + { + for(int k3 = 0; k3 < k2; k3++) + { + int i4 = imageData.getInt((i3 * 2 + 0 + (k3 * 2 + 0) * k1) * 4); + int k4 = imageData.getInt((i3 * 2 + 1 + (k3 * 2 + 0) * k1) * 4); + int l4 = imageData.getInt((i3 * 2 + 1 + (k3 * 2 + 1) * k1) * 4); + int i5 = imageData.getInt((i3 * 2 + 0 + (k3 * 2 + 1) * k1) * 4); + int j5 = weightedAverageColor(weightedAverageColor(i4, k4), weightedAverageColor(l4, i5)); + imageData.putInt((i3 + k3 * i2) * 4, j5); + } + + } + + GL11.glTexImage2D(3553 /*GL_TEXTURE_2D*/, i1, 6408 /*GL_RGBA*/, i2, k2, 0, 6408 /*GL_RGBA*/, 5121 /*GL_UNSIGNED_BYTE*/, imageData); + } + + } + } + + public void deleteTexture(int i) + { + textureNameToImageMap.remove(Integer.valueOf(i)); + singleIntBuffer.clear(); + singleIntBuffer.put(i); + singleIntBuffer.flip(); + GL11.glDeleteTextures(singleIntBuffer); + } + + public int getTextureForDownloadableImage(String s, String s1) + { + ThreadDownloadImageData threaddownloadimagedata = (ThreadDownloadImageData)urlToImageDataMap.get(s); + if(threaddownloadimagedata != null && threaddownloadimagedata.image != null && !threaddownloadimagedata.textureSetupComplete) + { + if(threaddownloadimagedata.textureName < 0) + { + threaddownloadimagedata.textureName = allocateAndSetupTexture(threaddownloadimagedata.image); + } else + { + setupTexture(threaddownloadimagedata.image, threaddownloadimagedata.textureName); + } + threaddownloadimagedata.textureSetupComplete = true; + } + if(threaddownloadimagedata == null || threaddownloadimagedata.textureName < 0) + { + if(s1 == null) + { + return -1; + } else + { + return getTexture(s1); + } + } else + { + return threaddownloadimagedata.textureName; + } + } + + public ThreadDownloadImageData obtainImageData(String s, ImageBuffer imagebuffer) + { + ThreadDownloadImageData threaddownloadimagedata = (ThreadDownloadImageData)urlToImageDataMap.get(s); + if(threaddownloadimagedata == null) + { + urlToImageDataMap.put(s, new ThreadDownloadImageData(s, imagebuffer)); + } else + { + threaddownloadimagedata.referenceCount++; + } + return threaddownloadimagedata; + } + + public void releaseImageData(String s) + { + ThreadDownloadImageData threaddownloadimagedata = (ThreadDownloadImageData)urlToImageDataMap.get(s); + if(threaddownloadimagedata != null) + { + threaddownloadimagedata.referenceCount--; + if(threaddownloadimagedata.referenceCount == 0) + { + if(threaddownloadimagedata.textureName >= 0) + { + deleteTexture(threaddownloadimagedata.textureName); + } + urlToImageDataMap.remove(s); + } + } + } + + public void registerTextureFX(TextureFX texturefx) + { + textureList.add(texturefx); + texturefx.onTick(); + } + + public void func_1067_a() + { + for(int i = 0; i < textureList.size(); i++) + { + TextureFX texturefx = (TextureFX)textureList.get(i); + texturefx.anaglyphEnabled = options.anaglyph; + texturefx.onTick(); + imageData.clear(); + imageData.put(texturefx.imageData); + imageData.position(0).limit(texturefx.imageData.length); + texturefx.bindImage(this); + for(int k = 0; k < texturefx.tileSize; k++) + { +label0: + for(int i1 = 0; i1 < texturefx.tileSize; i1++) + { + GL11.glTexSubImage2D(3553 /*GL_TEXTURE_2D*/, 0, (texturefx.iconIndex % 16) * 16 + k * 16, (texturefx.iconIndex / 16) * 16 + i1 * 16, 16, 16, 6408 /*GL_RGBA*/, 5121 /*GL_UNSIGNED_BYTE*/, imageData); + if(!useMipmaps) + { + continue; + } + int k1 = 1; + do + { + if(k1 > 4) + { + continue label0; + } + int i2 = 16 >> k1 - 1; + int k2 = 16 >> k1; + for(int i3 = 0; i3 < k2; i3++) + { + for(int k3 = 0; k3 < k2; k3++) + { + int i4 = imageData.getInt((i3 * 2 + 0 + (k3 * 2 + 0) * i2) * 4); + int k4 = imageData.getInt((i3 * 2 + 1 + (k3 * 2 + 0) * i2) * 4); + int i5 = imageData.getInt((i3 * 2 + 1 + (k3 * 2 + 1) * i2) * 4); + int k5 = imageData.getInt((i3 * 2 + 0 + (k3 * 2 + 1) * i2) * 4); + int l5 = averageColor(averageColor(i4, k4), averageColor(i5, k5)); + imageData.putInt((i3 + k3 * k2) * 4, l5); + } + + } + + GL11.glTexSubImage2D(3553 /*GL_TEXTURE_2D*/, k1, (texturefx.iconIndex % 16) * k2, (texturefx.iconIndex / 16) * k2, k2, k2, 6408 /*GL_RGBA*/, 5121 /*GL_UNSIGNED_BYTE*/, imageData); + k1++; + } while(true); + } + + } + + } + +label1: + for(int j = 0; j < textureList.size(); j++) + { + TextureFX texturefx1 = (TextureFX)textureList.get(j); + if(texturefx1.field_1130_d <= 0) + { + continue; + } + imageData.clear(); + imageData.put(texturefx1.imageData); + imageData.position(0).limit(texturefx1.imageData.length); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, texturefx1.field_1130_d); + GL11.glTexSubImage2D(3553 /*GL_TEXTURE_2D*/, 0, 0, 0, 16, 16, 6408 /*GL_RGBA*/, 5121 /*GL_UNSIGNED_BYTE*/, imageData); + if(!useMipmaps) + { + continue; + } + int l = 1; + do + { + if(l > 4) + { + continue label1; + } + int j1 = 16 >> l - 1; + int l1 = 16 >> l; + for(int j2 = 0; j2 < l1; j2++) + { + for(int l2 = 0; l2 < l1; l2++) + { + int j3 = imageData.getInt((j2 * 2 + 0 + (l2 * 2 + 0) * j1) * 4); + int l3 = imageData.getInt((j2 * 2 + 1 + (l2 * 2 + 0) * j1) * 4); + int j4 = imageData.getInt((j2 * 2 + 1 + (l2 * 2 + 1) * j1) * 4); + int l4 = imageData.getInt((j2 * 2 + 0 + (l2 * 2 + 1) * j1) * 4); + int j5 = averageColor(averageColor(j3, l3), averageColor(j4, l4)); + imageData.putInt((j2 + l2 * l1) * 4, j5); + } + + } + + GL11.glTexSubImage2D(3553 /*GL_TEXTURE_2D*/, l, 0, 0, l1, l1, 6408 /*GL_RGBA*/, 5121 /*GL_UNSIGNED_BYTE*/, imageData); + l++; + } while(true); + } + + } + + private int averageColor(int i, int j) + { + int k = (i & 0xff000000) >> 24 & 0xff; + int l = (j & 0xff000000) >> 24 & 0xff; + return ((k + l >> 1) << 24) + ((i & 0xfefefe) + (j & 0xfefefe) >> 1); + } + + private int weightedAverageColor(int i, int j) + { + int k = (i & 0xff000000) >> 24 & 0xff; + int l = (j & 0xff000000) >> 24 & 0xff; + char c = '\377'; + if(k + l == 0) + { + k = 1; + l = 1; + c = '\0'; + } + int i1 = (i >> 16 & 0xff) * k; + int j1 = (i >> 8 & 0xff) * k; + int k1 = (i & 0xff) * k; + int l1 = (j >> 16 & 0xff) * l; + int i2 = (j >> 8 & 0xff) * l; + int j2 = (j & 0xff) * l; + int k2 = (i1 + l1) / (k + l); + int l2 = (j1 + i2) / (k + l); + int i3 = (k1 + j2) / (k + l); + return c << 24 | k2 << 16 | l2 << 8 | i3; + } + + public void refreshTextures() + { + TexturePackBase texturepackbase = field_6527_k.selectedTexturePack; + int i; + BufferedImage bufferedimage; + for(Iterator iterator = textureNameToImageMap.keySet().iterator(); iterator.hasNext(); setupTexture(bufferedimage, i)) + { + i = ((Integer)iterator.next()).intValue(); + bufferedimage = (BufferedImage)textureNameToImageMap.get(Integer.valueOf(i)); + } + + for(Iterator iterator1 = urlToImageDataMap.values().iterator(); iterator1.hasNext();) + { + ThreadDownloadImageData threaddownloadimagedata = (ThreadDownloadImageData)iterator1.next(); + threaddownloadimagedata.textureSetupComplete = false; + } + + for(Iterator iterator2 = textureMap.keySet().iterator(); iterator2.hasNext();) + { + String s = (String)iterator2.next(); + try + { + BufferedImage bufferedimage1; + if(s.startsWith("##")) + { + bufferedimage1 = unwrapImageByColumns(readTextureImage(texturepackbase.func_6481_a(s.substring(2)))); + } else + if(s.startsWith("%clamp%")) + { + clampTexture = true; + bufferedimage1 = readTextureImage(texturepackbase.func_6481_a(s.substring(7))); + } else + if(s.startsWith("%blur%")) + { + blurTexture = true; + bufferedimage1 = readTextureImage(texturepackbase.func_6481_a(s.substring(6))); + } else + { + bufferedimage1 = readTextureImage(texturepackbase.func_6481_a(s)); + } + int j = ((Integer)textureMap.get(s)).intValue(); + setupTexture(bufferedimage1, j); + blurTexture = false; + clampTexture = false; + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + } + + private BufferedImage readTextureImage(InputStream inputstream) throws IOException + { + BufferedImage bufferedimage = ImageIO.read(inputstream); + inputstream.close(); + return bufferedimage; + } + + public void bindTexture(int i) + { + if(i < 0) + { + return; + } else + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, i); + return; + } + } + + public static boolean useMipmaps = false; + private HashMap textureMap; + private HashMap textureNameToImageMap; + private IntBuffer singleIntBuffer; + private ByteBuffer imageData; + private java.util.List textureList; + private Map urlToImageDataMap; + private GameSettings options; + private boolean clampTexture; + private boolean blurTexture; + private TexturePackList field_6527_k; + +} diff --git a/src/main/java/net/minecraft/src/RenderEntity.java b/src/main/java/net/minecraft/src/RenderEntity.java new file mode 100644 index 0000000..7ba1830 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderEntity.java @@ -0,0 +1,22 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderEntity extends Render +{ + + public RenderEntity() + { + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + renderOffsetAABB(entity.boundingBox, d - entity.lastTickPosX, d1 - entity.lastTickPosY, d2 - entity.lastTickPosZ); + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/net/minecraft/src/RenderFallingSand.java b/src/main/java/net/minecraft/src/RenderFallingSand.java new file mode 100644 index 0000000..79cafde --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderFallingSand.java @@ -0,0 +1,38 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderFallingSand extends Render +{ + + public RenderFallingSand() + { + field_197_d = new RenderBlocks(); + shadowSize = 0.5F; + } + + public void func_156_a(EntityFallingSand entityfallingsand, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + loadTexture("/terrain.png"); + Block block = Block.blocksList[entityfallingsand.blockID]; + World world = entityfallingsand.func_465_i(); + GL11.glDisable(2896 /*GL_LIGHTING*/); + field_197_d.renderBlockFallingSand(block, world, MathHelper.floor_double(entityfallingsand.posX), MathHelper.floor_double(entityfallingsand.posY), MathHelper.floor_double(entityfallingsand.posZ)); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_156_a((EntityFallingSand)entity, d, d1, d2, f, f1); + } + + private RenderBlocks field_197_d; +} diff --git a/src/main/java/net/minecraft/src/RenderFireball.java b/src/main/java/net/minecraft/src/RenderFireball.java new file mode 100644 index 0000000..7710538 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderFireball.java @@ -0,0 +1,51 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderFireball extends Render +{ + + public RenderFireball() + { + } + + public void func_4012_a(EntityFireball entityfireball, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + float f2 = 2.0F; + GL11.glScalef(f2 / 1.0F, f2 / 1.0F, f2 / 1.0F); + int i = Item.snowball.getIconIndex(null); + loadTexture("/gui/items.png"); + Tessellator tessellator = Tessellator.instance; + float f3 = (float)((i % 16) * 16 + 0) / 256F; + float f4 = (float)((i % 16) * 16 + 16) / 256F; + float f5 = (float)((i / 16) * 16 + 0) / 256F; + float f6 = (float)((i / 16) * 16 + 16) / 256F; + float f7 = 1.0F; + float f8 = 0.5F; + float f9 = 0.25F; + GL11.glRotatef(180F - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-renderManager.playerViewX, 1.0F, 0.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV(0.0F - f8, 0.0F - f9, 0.0D, f3, f6); + tessellator.addVertexWithUV(f7 - f8, 0.0F - f9, 0.0D, f4, f6); + tessellator.addVertexWithUV(f7 - f8, 1.0F - f9, 0.0D, f4, f5); + tessellator.addVertexWithUV(0.0F - f8, 1.0F - f9, 0.0D, f3, f5); + tessellator.draw(); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_4012_a((EntityFireball)entity, d, d1, d2, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderFish.java b/src/main/java/net/minecraft/src/RenderFish.java new file mode 100644 index 0000000..6206df5 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderFish.java @@ -0,0 +1,92 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderFish extends Render +{ + + public RenderFish() + { + } + + public void func_4011_a(EntityFish entityfish, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glScalef(0.5F, 0.5F, 0.5F); + int i = 1; + byte byte0 = 2; + loadTexture("/particles.png"); + Tessellator tessellator = Tessellator.instance; + float f2 = (float)(i * 8 + 0) / 128F; + float f3 = (float)(i * 8 + 8) / 128F; + float f4 = (float)(byte0 * 8 + 0) / 128F; + float f5 = (float)(byte0 * 8 + 8) / 128F; + float f6 = 1.0F; + float f7 = 0.5F; + float f8 = 0.5F; + GL11.glRotatef(180F - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-renderManager.playerViewX, 1.0F, 0.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV(0.0F - f7, 0.0F - f8, 0.0D, f2, f5); + tessellator.addVertexWithUV(f6 - f7, 0.0F - f8, 0.0D, f3, f5); + tessellator.addVertexWithUV(f6 - f7, 1.0F - f8, 0.0D, f3, f4); + tessellator.addVertexWithUV(0.0F - f7, 1.0F - f8, 0.0D, f2, f4); + tessellator.draw(); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPopMatrix(); + if(entityfish.angler != null) + { + float f9 = ((entityfish.angler.prevRotationYaw + (entityfish.angler.rotationYaw - entityfish.angler.prevRotationYaw) * f1) * 3.141593F) / 180F; + float f11 = ((entityfish.angler.prevRotationPitch + (entityfish.angler.rotationPitch - entityfish.angler.prevRotationPitch) * f1) * 3.141593F) / 180F; + double d3 = MathHelper.sin(f9); + double d5 = MathHelper.cos(f9); + double d7 = MathHelper.sin(f11); + double d8 = MathHelper.cos(f11); + double d9 = (entityfish.angler.prevPosX + (entityfish.angler.posX - entityfish.angler.prevPosX) * (double)f1) - d5 * 0.69999999999999996D - d3 * 0.5D * d8; + double d10 = (entityfish.angler.prevPosY + (entityfish.angler.posY - entityfish.angler.prevPosY) * (double)f1) - d7 * 0.5D; + double d11 = ((entityfish.angler.prevPosZ + (entityfish.angler.posZ - entityfish.angler.prevPosZ) * (double)f1) - d3 * 0.69999999999999996D) + d5 * 0.5D * d8; + if(renderManager.options.thirdPersonView) + { + float f10 = ((entityfish.angler.prevRenderYawOffset + (entityfish.angler.renderYawOffset - entityfish.angler.prevRenderYawOffset) * f1) * 3.141593F) / 180F; + double d4 = MathHelper.sin(f10); + double d6 = MathHelper.cos(f10); + d9 = (entityfish.angler.prevPosX + (entityfish.angler.posX - entityfish.angler.prevPosX) * (double)f1) - d6 * 0.34999999999999998D - d4 * 0.84999999999999998D; + d10 = (entityfish.angler.prevPosY + (entityfish.angler.posY - entityfish.angler.prevPosY) * (double)f1) - 0.45000000000000001D; + d11 = ((entityfish.angler.prevPosZ + (entityfish.angler.posZ - entityfish.angler.prevPosZ) * (double)f1) - d4 * 0.34999999999999998D) + d6 * 0.84999999999999998D; + } + double d12 = entityfish.prevPosX + (entityfish.posX - entityfish.prevPosX) * (double)f1; + double d13 = entityfish.prevPosY + (entityfish.posY - entityfish.prevPosY) * (double)f1 + 0.25D; + double d14 = entityfish.prevPosZ + (entityfish.posZ - entityfish.prevPosZ) * (double)f1; + double d15 = (float)(d9 - d12); + double d16 = (float)(d10 - d13); + double d17 = (float)(d11 - d14); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(2896 /*GL_LIGHTING*/); + tessellator.startDrawing(3); + tessellator.setColorOpaque_I(0); + int j = 16; + for(int k = 0; k <= j; k++) + { + float f12 = (float)k / (float)j; + tessellator.addVertex(d + d15 * (double)f12, d1 + d16 * (double)(f12 * f12 + f12) * 0.5D + 0.25D, d2 + d17 * (double)f12); + } + + tessellator.draw(); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_4011_a((EntityFish)entity, d, d1, d2, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderGhast.java b/src/main/java/net/minecraft/src/RenderGhast.java new file mode 100644 index 0000000..7f41e1b --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderGhast.java @@ -0,0 +1,35 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderGhast extends RenderLiving +{ + + public RenderGhast() + { + super(new ModelGhast(), 0.5F); + } + + protected void func_4014_a(EntityGhast entityghast, float f) + { + EntityGhast entityghast1 = entityghast; + float f1 = ((float)entityghast1.prevAttackCounter + (float)(entityghast1.attackCounter - entityghast1.prevAttackCounter) * f) / 20F; + if(f1 < 0.0F) + { + f1 = 0.0F; + } + f1 = 1.0F / (f1 * f1 * f1 * f1 * f1 * 2.0F + 1.0F); + float f2 = (8F + f1) / 2.0F; + float f3 = (8F + 1.0F / f1) / 2.0F; + GL11.glScalef(f3, f2, f3); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + func_4014_a((EntityGhast)entityliving, f); + } +} diff --git a/src/main/java/net/minecraft/src/RenderGlobal.java b/src/main/java/net/minecraft/src/RenderGlobal.java new file mode 100644 index 0000000..e475791 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderGlobal.java @@ -0,0 +1,1408 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.nio.IntBuffer; +import java.util.*; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.ARBOcclusionQuery; +import org.lwjgl.opengl.GL11; + +public class RenderGlobal + implements IWorldAccess +{ + + public RenderGlobal(Minecraft minecraft, RenderEngine renderengine) + { + tileEntities = new ArrayList(); + worldRenderersToUpdate = new ArrayList(); + field_1436_w = false; + field_1435_x = 0; + renderDistance = -1; + field_1424_I = 2; + field_1457_b = new int[50000]; + field_1456_c = GLAllocation.createDirectIntBuffer(64); + field_1415_R = new ArrayList(); + field_1455_d = 0; + field_1454_e = GLAllocation.generateDisplayLists(1); + field_1453_f = -9999D; + field_1452_g = -9999D; + field_1451_h = -9999D; + field_1449_j = 0; + mc = minecraft; + renderEngine = renderengine; + byte byte0 = 64; + field_1440_s = GLAllocation.generateDisplayLists(byte0 * byte0 * byte0 * 3); + field_1436_w = minecraft.func_6251_l().checkARBOcclusion(); + if(field_1436_w) + { + field_1456_c.clear(); + field_1437_v = GLAllocation.createDirectIntBuffer(byte0 * byte0 * byte0); + field_1437_v.clear(); + field_1437_v.position(0); + field_1437_v.limit(byte0 * byte0 * byte0); + ARBOcclusionQuery.glGenQueriesARB(field_1437_v); + } + field_1434_y = GLAllocation.generateDisplayLists(3); + GL11.glPushMatrix(); + GL11.glNewList(field_1434_y, 4864 /*GL_COMPILE*/); + func_950_f(); + GL11.glEndList(); + GL11.glPopMatrix(); + Tessellator tessellator = Tessellator.instance; + field_1433_z = field_1434_y + 1; + GL11.glNewList(field_1433_z, 4864 /*GL_COMPILE*/); + byte byte1 = 64; + int i = 256 / byte1 + 2; + float f = 16F; + for(int j = -byte1 * i; j <= byte1 * i; j += byte1) + { + for(int l = -byte1 * i; l <= byte1 * i; l += byte1) + { + tessellator.startDrawingQuads(); + tessellator.addVertex(j + 0, f, l + 0); + tessellator.addVertex(j + byte1, f, l + 0); + tessellator.addVertex(j + byte1, f, l + byte1); + tessellator.addVertex(j + 0, f, l + byte1); + tessellator.draw(); + } + + } + + GL11.glEndList(); + field_1432_A = field_1434_y + 2; + GL11.glNewList(field_1432_A, 4864 /*GL_COMPILE*/); + f = -16F; + tessellator.startDrawingQuads(); + for(int k = -byte1 * i; k <= byte1 * i; k += byte1) + { + for(int i1 = -byte1 * i; i1 <= byte1 * i; i1 += byte1) + { + tessellator.addVertex(k + byte1, f, i1 + 0); + tessellator.addVertex(k + 0, f, i1 + 0); + tessellator.addVertex(k + 0, f, i1 + byte1); + tessellator.addVertex(k + byte1, f, i1 + byte1); + } + + } + + tessellator.draw(); + GL11.glEndList(); + } + + private void func_950_f() + { + Random random = new Random(10842L); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + for(int i = 0; i < 1500; i++) + { + double d = random.nextFloat() * 2.0F - 1.0F; + double d1 = random.nextFloat() * 2.0F - 1.0F; + double d2 = random.nextFloat() * 2.0F - 1.0F; + double d3 = 0.25F + random.nextFloat() * 0.25F; + double d4 = d * d + d1 * d1 + d2 * d2; + if(d4 >= 1.0D || d4 <= 0.01D) + { + continue; + } + d4 = 1.0D / Math.sqrt(d4); + d *= d4; + d1 *= d4; + d2 *= d4; + double d5 = d * 100D; + double d6 = d1 * 100D; + double d7 = d2 * 100D; + double d8 = Math.atan2(d, d2); + double d9 = Math.sin(d8); + double d10 = Math.cos(d8); + double d11 = Math.atan2(Math.sqrt(d * d + d2 * d2), d1); + double d12 = Math.sin(d11); + double d13 = Math.cos(d11); + double d14 = random.nextDouble() * 3.1415926535897931D * 2D; + double d15 = Math.sin(d14); + double d16 = Math.cos(d14); + for(int j = 0; j < 4; j++) + { + double d17 = 0.0D; + double d18 = (double)((j & 2) - 1) * d3; + double d19 = (double)((j + 1 & 2) - 1) * d3; + double d20 = d17; + double d21 = d18 * d16 - d19 * d15; + double d22 = d19 * d16 + d18 * d15; + double d23 = d22; + double d24 = d21 * d12 + d20 * d13; + double d25 = d20 * d12 - d21 * d13; + double d26 = d25 * d9 - d23 * d10; + double d27 = d24; + double d28 = d23 * d9 + d25 * d10; + tessellator.addVertex(d5 + d26, d6 + d27, d7 + d28); + } + + } + + tessellator.draw(); + } + + public void func_946_a(World world) + { + if(worldObj != null) + { + worldObj.removeWorldAccess(this); + } + field_1453_f = -9999D; + field_1452_g = -9999D; + field_1451_h = -9999D; + RenderManager.instance.func_852_a(world); + worldObj = world; + field_1438_u = new RenderBlocks(world); + if(world != null) + { + world.addWorldAccess(this); + loadRenderers(); + } + } + + public void loadRenderers() + { + Block.leaves.setGraphicsLevel(mc.gameSettings.fancyGraphics); + renderDistance = mc.gameSettings.renderDistance; + if(worldRenderers != null) + { + for(int i = 0; i < worldRenderers.length; i++) + { + worldRenderers[i].func_1204_c(); + } + + } + int j = 64 << 3 - renderDistance; + if(j > 400) + { + j = 400; + } + renderChunksWide = j / 16 + 1; + renderChunksTall = 8; + renderChunksDeep = j / 16 + 1; + worldRenderers = new WorldRenderer[renderChunksWide * renderChunksTall * renderChunksDeep]; + sortedWorldRenderers = new WorldRenderer[renderChunksWide * renderChunksTall * renderChunksDeep]; + int k = 0; + int l = 0; + field_1431_B = 0; + field_1430_C = 0; + field_1429_D = 0; + field_1428_E = renderChunksWide; + field_1427_F = renderChunksTall; + field_1426_G = renderChunksDeep; + for(int i1 = 0; i1 < worldRenderersToUpdate.size(); i1++) + { + ((WorldRenderer)worldRenderersToUpdate.get(i1)).needsUpdate = false; + } + + worldRenderersToUpdate.clear(); + tileEntities.clear(); + for(int j1 = 0; j1 < renderChunksWide; j1++) + { + for(int k1 = 0; k1 < renderChunksTall; k1++) + { + for(int l1 = 0; l1 < renderChunksDeep; l1++) + { + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1] = new WorldRenderer(worldObj, tileEntities, j1 * 16, k1 * 16, l1 * 16, 16, field_1440_s + k); + if(field_1436_w) + { + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1].field_1732_z = field_1437_v.get(l); + } + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1].isWaitingOnOcclusionQuery = false; + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1].isVisible = true; + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1].isInFrustum = true; + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1].field_1735_w = l++; + worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1].markDirty(); + sortedWorldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1] = worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1]; + worldRenderersToUpdate.add(worldRenderers[(l1 * renderChunksTall + k1) * renderChunksWide + j1]); + k += 3; + } + + } + + } + + if(worldObj != null) + { + EntityLiving entityliving = mc.field_22009_h; + if(entityliving != null) + { + func_956_b(MathHelper.floor_double(((Entity) (entityliving)).posX), MathHelper.floor_double(((Entity) (entityliving)).posY), MathHelper.floor_double(((Entity) (entityliving)).posZ)); + Arrays.sort(sortedWorldRenderers, new EntitySorter(entityliving)); + } + } + field_1424_I = 2; + } + + public void func_951_a(Vec3D vec3d, ICamera icamera, float f) + { + if(field_1424_I > 0) + { + field_1424_I--; + return; + } + TileEntityRenderer.instance.func_22267_a(worldObj, renderEngine, mc.fontRenderer, mc.field_22009_h, f); + RenderManager.instance.func_22187_a(worldObj, renderEngine, mc.fontRenderer, mc.field_22009_h, mc.gameSettings, f); + field_1423_J = 0; + field_1422_K = 0; + field_1421_L = 0; + EntityLiving entityliving = mc.field_22009_h; + RenderManager.renderPosX = ((Entity) (entityliving)).lastTickPosX + (((Entity) (entityliving)).posX - ((Entity) (entityliving)).lastTickPosX) * (double)f; + RenderManager.renderPosY = ((Entity) (entityliving)).lastTickPosY + (((Entity) (entityliving)).posY - ((Entity) (entityliving)).lastTickPosY) * (double)f; + RenderManager.renderPosZ = ((Entity) (entityliving)).lastTickPosZ + (((Entity) (entityliving)).posZ - ((Entity) (entityliving)).lastTickPosZ) * (double)f; + TileEntityRenderer.staticPlayerX = ((Entity) (entityliving)).lastTickPosX + (((Entity) (entityliving)).posX - ((Entity) (entityliving)).lastTickPosX) * (double)f; + TileEntityRenderer.staticPlayerY = ((Entity) (entityliving)).lastTickPosY + (((Entity) (entityliving)).posY - ((Entity) (entityliving)).lastTickPosY) * (double)f; + TileEntityRenderer.staticPlayerZ = ((Entity) (entityliving)).lastTickPosZ + (((Entity) (entityliving)).posZ - ((Entity) (entityliving)).lastTickPosZ) * (double)f; + List list = worldObj.getLoadedEntityList(); + field_1423_J = list.size(); + for(int i = 0; i < list.size(); i++) + { + Entity entity = (Entity)list.get(i); + if(entity.isInRangeToRenderVec3D(vec3d) && icamera.isBoundingBoxInFrustum(entity.boundingBox) && (entity != mc.field_22009_h || mc.gameSettings.thirdPersonView || mc.field_22009_h.isPlayerSleeping()) && worldObj.blockExists(MathHelper.floor_double(entity.posX), MathHelper.floor_double(entity.posY), MathHelper.floor_double(entity.posZ))) + { + field_1422_K++; + RenderManager.instance.renderEntity(entity, f); + } + } + + for(int j = 0; j < tileEntities.size(); j++) + { + TileEntityRenderer.instance.renderTileEntity((TileEntity)tileEntities.get(j), f); + } + + } + + public String func_953_b() + { + return (new StringBuilder()).append("C: ").append(field_1417_P).append("/").append(field_1420_M).append(". F: ").append(field_1419_N).append(", O: ").append(field_1418_O).append(", E: ").append(field_1416_Q).toString(); + } + + public String func_957_c() + { + return (new StringBuilder()).append("E: ").append(field_1422_K).append("/").append(field_1423_J).append(". B: ").append(field_1421_L).append(", I: ").append(field_1423_J - field_1421_L - field_1422_K).toString(); + } + + private void func_956_b(int i, int j, int k) + { + i -= 8; + j -= 8; + k -= 8; + field_1431_B = 0x7fffffff; + field_1430_C = 0x7fffffff; + field_1429_D = 0x7fffffff; + field_1428_E = 0x80000000; + field_1427_F = 0x80000000; + field_1426_G = 0x80000000; + int l = renderChunksWide * 16; + int i1 = l / 2; + for(int j1 = 0; j1 < renderChunksWide; j1++) + { + int k1 = j1 * 16; + int l1 = (k1 + i1) - i; + if(l1 < 0) + { + l1 -= l - 1; + } + l1 /= l; + k1 -= l1 * l; + if(k1 < field_1431_B) + { + field_1431_B = k1; + } + if(k1 > field_1428_E) + { + field_1428_E = k1; + } + for(int i2 = 0; i2 < renderChunksDeep; i2++) + { + int j2 = i2 * 16; + int k2 = (j2 + i1) - k; + if(k2 < 0) + { + k2 -= l - 1; + } + k2 /= l; + j2 -= k2 * l; + if(j2 < field_1429_D) + { + field_1429_D = j2; + } + if(j2 > field_1426_G) + { + field_1426_G = j2; + } + for(int l2 = 0; l2 < renderChunksTall; l2++) + { + int i3 = l2 * 16; + if(i3 < field_1430_C) + { + field_1430_C = i3; + } + if(i3 > field_1427_F) + { + field_1427_F = i3; + } + WorldRenderer worldrenderer = worldRenderers[(i2 * renderChunksTall + l2) * renderChunksWide + j1]; + boolean flag = worldrenderer.needsUpdate; + worldrenderer.func_1197_a(k1, i3, j2); + if(!flag && worldrenderer.needsUpdate) + { + worldRenderersToUpdate.add(worldrenderer); + } + } + + } + + } + + } + + public int func_943_a(EntityLiving entityliving, int i, double d) + { + for(int j = 0; j < 10; j++) + { + field_21156_R = (field_21156_R + 1) % worldRenderers.length; + WorldRenderer worldrenderer = worldRenderers[field_21156_R]; + if(worldrenderer.needsUpdate && !worldRenderersToUpdate.contains(worldrenderer)) + { + worldRenderersToUpdate.add(worldrenderer); + } + } + + if(mc.gameSettings.renderDistance != renderDistance) + { + loadRenderers(); + } + if(i == 0) + { + field_1420_M = 0; + field_1419_N = 0; + field_1418_O = 0; + field_1417_P = 0; + field_1416_Q = 0; + } + double d1 = entityliving.lastTickPosX + (entityliving.posX - entityliving.lastTickPosX) * d; + double d2 = entityliving.lastTickPosY + (entityliving.posY - entityliving.lastTickPosY) * d; + double d3 = entityliving.lastTickPosZ + (entityliving.posZ - entityliving.lastTickPosZ) * d; + double d4 = entityliving.posX - field_1453_f; + double d5 = entityliving.posY - field_1452_g; + double d6 = entityliving.posZ - field_1451_h; + if(d4 * d4 + d5 * d5 + d6 * d6 > 16D) + { + field_1453_f = entityliving.posX; + field_1452_g = entityliving.posY; + field_1451_h = entityliving.posZ; + func_956_b(MathHelper.floor_double(entityliving.posX), MathHelper.floor_double(entityliving.posY), MathHelper.floor_double(entityliving.posZ)); + Arrays.sort(sortedWorldRenderers, new EntitySorter(entityliving)); + } + int k = 0; + if(field_1436_w && !mc.gameSettings.anaglyph && i == 0) + { + int l = 0; + int i1 = 16; + func_962_a(l, i1); + for(int j1 = l; j1 < i1; j1++) + { + sortedWorldRenderers[j1].isVisible = true; + } + + k += func_952_a(l, i1, i, d); + do + { + int byte0 = i1; + i1 *= 2; + if(i1 > sortedWorldRenderers.length) + { + i1 = sortedWorldRenderers.length; + } + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glDisable(2912 /*GL_FOG*/); + GL11.glColorMask(false, false, false, false); + GL11.glDepthMask(false); + func_962_a(byte0, i1); + GL11.glPushMatrix(); + float f = 0.0F; + float f1 = 0.0F; + float f2 = 0.0F; + for(int k1 = byte0; k1 < i1; k1++) + { + if(sortedWorldRenderers[k1].canRender()) + { + sortedWorldRenderers[k1].isInFrustum = false; + continue; + } + if(!sortedWorldRenderers[k1].isInFrustum) + { + sortedWorldRenderers[k1].isVisible = true; + } + if(!sortedWorldRenderers[k1].isInFrustum || sortedWorldRenderers[k1].isWaitingOnOcclusionQuery) + { + continue; + } + float f3 = MathHelper.sqrt_float(sortedWorldRenderers[k1].distanceToEntity(entityliving)); + int l1 = (int)(1.0F + f3 / 128F); + if(field_1435_x % l1 != k1 % l1) + { + continue; + } + WorldRenderer worldrenderer1 = sortedWorldRenderers[k1]; + float f4 = (float)((double)worldrenderer1.field_1755_i - d1); + float f5 = (float)((double)worldrenderer1.field_1754_j - d2); + float f6 = (float)((double)worldrenderer1.field_1753_k - d3); + float f7 = f4 - f; + float f8 = f5 - f1; + float f9 = f6 - f2; + if(f7 != 0.0F || f8 != 0.0F || f9 != 0.0F) + { + GL11.glTranslatef(f7, f8, f9); + f += f7; + f1 += f8; + f2 += f9; + } + ARBOcclusionQuery.glBeginQueryARB(35092 /*GL_SAMPLES_PASSED_ARB*/, sortedWorldRenderers[k1].field_1732_z); + sortedWorldRenderers[k1].callOcclusionQueryList(); + ARBOcclusionQuery.glEndQueryARB(35092 /*GL_SAMPLES_PASSED_ARB*/); + sortedWorldRenderers[k1].isWaitingOnOcclusionQuery = true; + } + + GL11.glPopMatrix(); + GL11.glColorMask(true, true, true, true); + GL11.glDepthMask(true); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(2912 /*GL_FOG*/); + k += func_952_a(byte0, i1, i, d); + } while(i1 < sortedWorldRenderers.length); + } else + { + k += func_952_a(0, sortedWorldRenderers.length, i, d); + } + return k; + } + + private void func_962_a(int i, int j) + { + for(int k = i; k < j; k++) + { + if(!sortedWorldRenderers[k].isWaitingOnOcclusionQuery) + { + continue; + } + field_1456_c.clear(); + ARBOcclusionQuery.glGetQueryObjectuARB(sortedWorldRenderers[k].field_1732_z, 34919 /*GL_QUERY_RESULT_AVAILABLE_ARB*/, field_1456_c); + if(field_1456_c.get(0) != 0) + { + sortedWorldRenderers[k].isWaitingOnOcclusionQuery = false; + field_1456_c.clear(); + ARBOcclusionQuery.glGetQueryObjectuARB(sortedWorldRenderers[k].field_1732_z, 34918 /*GL_QUERY_RESULT_ARB*/, field_1456_c); + sortedWorldRenderers[k].isVisible = field_1456_c.get(0) != 0; + } + } + + } + + private int func_952_a(int i, int j, int k, double d) + { + field_1415_R.clear(); + int l = 0; + for(int i1 = i; i1 < j; i1++) + { + if(k == 0) + { + field_1420_M++; + if(sortedWorldRenderers[i1].skipRenderPass[k]) + { + field_1416_Q++; + } else + if(!sortedWorldRenderers[i1].isInFrustum) + { + field_1419_N++; + } else + if(field_1436_w && !sortedWorldRenderers[i1].isVisible) + { + field_1418_O++; + } else + { + field_1417_P++; + } + } + if(sortedWorldRenderers[i1].skipRenderPass[k] || !sortedWorldRenderers[i1].isInFrustum || !sortedWorldRenderers[i1].isVisible) + { + continue; + } + int j1 = sortedWorldRenderers[i1].getGLCallListForPass(k); + if(j1 >= 0) + { + field_1415_R.add(sortedWorldRenderers[i1]); + l++; + } + } + + EntityLiving entityliving = mc.field_22009_h; + double d1 = entityliving.lastTickPosX + (entityliving.posX - entityliving.lastTickPosX) * d; + double d2 = entityliving.lastTickPosY + (entityliving.posY - entityliving.lastTickPosY) * d; + double d3 = entityliving.lastTickPosZ + (entityliving.posZ - entityliving.lastTickPosZ) * d; + int k1 = 0; + for(int l1 = 0; l1 < field_1414_S.length; l1++) + { + field_1414_S[l1].func_859_b(); + } + + for(int i2 = 0; i2 < field_1415_R.size(); i2++) + { + WorldRenderer worldrenderer = (WorldRenderer)field_1415_R.get(i2); + int j2 = -1; + for(int k2 = 0; k2 < k1; k2++) + { + if(field_1414_S[k2].func_862_a(worldrenderer.field_1755_i, worldrenderer.field_1754_j, worldrenderer.field_1753_k)) + { + j2 = k2; + } + } + + if(j2 < 0) + { + j2 = k1++; + field_1414_S[j2].func_861_a(worldrenderer.field_1755_i, worldrenderer.field_1754_j, worldrenderer.field_1753_k, d1, d2, d3); + } + field_1414_S[j2].func_858_a(worldrenderer.getGLCallListForPass(k)); + } + + func_944_a(k, d); + return l; + } + + public void func_944_a(int i, double d) + { + for(int j = 0; j < field_1414_S.length; j++) + { + field_1414_S[j].func_860_a(); + } + + } + + public void func_945_d() + { + field_1435_x++; + } + + public void func_4142_a(float f) + { + if(mc.theWorld.worldProvider.field_4220_c) + { + return; + } + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + Vec3D vec3d = worldObj.func_4079_a(mc.field_22009_h, f); + float f1 = (float)vec3d.xCoord; + float f2 = (float)vec3d.yCoord; + float f3 = (float)vec3d.zCoord; + if(mc.gameSettings.anaglyph) + { + float f4 = (f1 * 30F + f2 * 59F + f3 * 11F) / 100F; + float f5 = (f1 * 30F + f2 * 70F) / 100F; + float f7 = (f1 * 30F + f3 * 70F) / 100F; + f1 = f4; + f2 = f5; + f3 = f7; + } + GL11.glColor3f(f1, f2, f3); + Tessellator tessellator = Tessellator.instance; + GL11.glDepthMask(false); + GL11.glEnable(2912 /*GL_FOG*/); + GL11.glColor3f(f1, f2, f3); + GL11.glCallList(field_1433_z); + GL11.glDisable(2912 /*GL_FOG*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + float af[] = worldObj.worldProvider.func_4097_b(worldObj.getCelestialAngle(f), f); + if(af != null) + { + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glShadeModel(7425 /*GL_SMOOTH*/); + GL11.glPushMatrix(); + GL11.glRotatef(90F, 1.0F, 0.0F, 0.0F); + float f8 = worldObj.getCelestialAngle(f); + GL11.glRotatef(f8 <= 0.5F ? 0.0F : 180F, 0.0F, 0.0F, 1.0F); + tessellator.startDrawing(6); + tessellator.setColorRGBA_F(af[0], af[1], af[2], af[3]); + tessellator.addVertex(0.0D, 100D, 0.0D); + int i = 16; + tessellator.setColorRGBA_F(af[0], af[1], af[2], 0.0F); + for(int j = 0; j <= i; j++) + { + float f12 = ((float)j * 3.141593F * 2.0F) / (float)i; + float f14 = MathHelper.sin(f12); + float f15 = MathHelper.cos(f12); + tessellator.addVertex(f14 * 120F, f15 * 120F, -f15 * 40F * af[3]); + } + + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glShadeModel(7424 /*GL_FLAT*/); + } + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glBlendFunc(1, 1); + GL11.glPushMatrix(); + float f6 = 0.0F; + float f9 = 0.0F; + float f10 = 0.0F; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glTranslatef(f6, f9, f10); + GL11.glRotatef(0.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(worldObj.getCelestialAngle(f) * 360F, 1.0F, 0.0F, 0.0F); + float f11 = 30F; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/terrain/sun.png")); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-f11, 100D, -f11, 0.0D, 0.0D); + tessellator.addVertexWithUV(f11, 100D, -f11, 1.0D, 0.0D); + tessellator.addVertexWithUV(f11, 100D, f11, 1.0D, 1.0D); + tessellator.addVertexWithUV(-f11, 100D, f11, 0.0D, 1.0D); + tessellator.draw(); + f11 = 20F; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/terrain/moon.png")); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-f11, -100D, f11, 1.0D, 1.0D); + tessellator.addVertexWithUV(f11, -100D, f11, 0.0D, 1.0D); + tessellator.addVertexWithUV(f11, -100D, -f11, 0.0D, 0.0D); + tessellator.addVertexWithUV(-f11, -100D, -f11, 1.0D, 0.0D); + tessellator.draw(); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + float f13 = worldObj.func_679_f(f); + if(f13 > 0.0F) + { + GL11.glColor4f(f13, f13, f13, f13); + GL11.glCallList(field_1434_y); + } + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(2912 /*GL_FOG*/); + GL11.glPopMatrix(); + GL11.glColor3f(f1 * 0.2F + 0.04F, f2 * 0.2F + 0.04F, f3 * 0.6F + 0.1F); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glCallList(field_1432_A); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glDepthMask(true); + } + + public void func_4141_b(float f) + { + if(mc.theWorld.worldProvider.field_4220_c) + { + return; + } + if(mc.gameSettings.fancyGraphics) + { + func_6510_c(f); + return; + } + GL11.glDisable(2884 /*GL_CULL_FACE*/); + float f1 = (float)(mc.field_22009_h.lastTickPosY + (mc.field_22009_h.posY - mc.field_22009_h.lastTickPosY) * (double)f); + byte byte0 = 32; + int i = 256 / byte0; + Tessellator tessellator = Tessellator.instance; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/environment/clouds.png")); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + Vec3D vec3d = worldObj.func_628_d(f); + float f2 = (float)vec3d.xCoord; + float f3 = (float)vec3d.yCoord; + float f4 = (float)vec3d.zCoord; + if(mc.gameSettings.anaglyph) + { + float f5 = (f2 * 30F + f3 * 59F + f4 * 11F) / 100F; + float f7 = (f2 * 30F + f3 * 70F) / 100F; + float f8 = (f2 * 30F + f4 * 70F) / 100F; + f2 = f5; + f3 = f7; + f4 = f8; + } + float f6 = 0.0004882813F; + double d = mc.field_22009_h.prevPosX + (mc.field_22009_h.posX - mc.field_22009_h.prevPosX) * (double)f + (double)(((float)field_1435_x + f) * 0.03F); + double d1 = mc.field_22009_h.prevPosZ + (mc.field_22009_h.posZ - mc.field_22009_h.prevPosZ) * (double)f; + int j = MathHelper.floor_double(d / 2048D); + int k = MathHelper.floor_double(d1 / 2048D); + d -= j * 2048 /*GL_EXP*/; + d1 -= k * 2048 /*GL_EXP*/; + float f9 = (120F - f1) + 0.33F; + float f10 = (float)(d * (double)f6); + float f11 = (float)(d1 * (double)f6); + tessellator.startDrawingQuads(); + tessellator.setColorRGBA_F(f2, f3, f4, 0.8F); + for(int l = -byte0 * i; l < byte0 * i; l += byte0) + { + for(int i1 = -byte0 * i; i1 < byte0 * i; i1 += byte0) + { + tessellator.addVertexWithUV(l + 0, f9, i1 + byte0, (float)(l + 0) * f6 + f10, (float)(i1 + byte0) * f6 + f11); + tessellator.addVertexWithUV(l + byte0, f9, i1 + byte0, (float)(l + byte0) * f6 + f10, (float)(i1 + byte0) * f6 + f11); + tessellator.addVertexWithUV(l + byte0, f9, i1 + 0, (float)(l + byte0) * f6 + f10, (float)(i1 + 0) * f6 + f11); + tessellator.addVertexWithUV(l + 0, f9, i1 + 0, (float)(l + 0) * f6 + f10, (float)(i1 + 0) * f6 + f11); + } + + } + + tessellator.draw(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(2884 /*GL_CULL_FACE*/); + } + + public void func_6510_c(float f) + { + GL11.glDisable(2884 /*GL_CULL_FACE*/); + float f1 = (float)(mc.field_22009_h.lastTickPosY + (mc.field_22009_h.posY - mc.field_22009_h.lastTickPosY) * (double)f); + Tessellator tessellator = Tessellator.instance; + float f2 = 12F; + float f3 = 4F; + double d = (mc.field_22009_h.prevPosX + (mc.field_22009_h.posX - mc.field_22009_h.prevPosX) * (double)f + (double)(((float)field_1435_x + f) * 0.03F)) / (double)f2; + double d1 = (mc.field_22009_h.prevPosZ + (mc.field_22009_h.posZ - mc.field_22009_h.prevPosZ) * (double)f) / (double)f2 + 0.33000001311302185D; + float f4 = (108F - f1) + 0.33F; + int i = MathHelper.floor_double(d / 2048D); + int j = MathHelper.floor_double(d1 / 2048D); + d -= i * 2048 /*GL_EXP*/; + d1 -= j * 2048 /*GL_EXP*/; + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/environment/clouds.png")); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + Vec3D vec3d = worldObj.func_628_d(f); + float f5 = (float)vec3d.xCoord; + float f6 = (float)vec3d.yCoord; + float f7 = (float)vec3d.zCoord; + if(mc.gameSettings.anaglyph) + { + float f8 = (f5 * 30F + f6 * 59F + f7 * 11F) / 100F; + float f10 = (f5 * 30F + f6 * 70F) / 100F; + float f12 = (f5 * 30F + f7 * 70F) / 100F; + f5 = f8; + f6 = f10; + f7 = f12; + } + float f9 = (float)(d * 0.0D); + float f11 = (float)(d1 * 0.0D); + float f13 = 0.00390625F; + f9 = (float)MathHelper.floor_double(d) * f13; + f11 = (float)MathHelper.floor_double(d1) * f13; + float f14 = (float)(d - (double)MathHelper.floor_double(d)); + float f15 = (float)(d1 - (double)MathHelper.floor_double(d1)); + int k = 8; + byte byte0 = 3; + float f16 = 0.0009765625F; + GL11.glScalef(f2, 1.0F, f2); + for(int l = 0; l < 2; l++) + { + if(l == 0) + { + GL11.glColorMask(false, false, false, false); + } else + { + GL11.glColorMask(true, true, true, true); + } + for(int i1 = -byte0 + 1; i1 <= byte0; i1++) + { + for(int j1 = -byte0 + 1; j1 <= byte0; j1++) + { + tessellator.startDrawingQuads(); + float f17 = i1 * k; + float f18 = j1 * k; + float f19 = f17 - f14; + float f20 = f18 - f15; + if(f4 > -f3 - 1.0F) + { + tessellator.setColorRGBA_F(f5 * 0.7F, f6 * 0.7F, f7 * 0.7F, 0.8F); + tessellator.setNormal(0.0F, -1F, 0.0F); + tessellator.addVertexWithUV(f19 + 0.0F, f4 + 0.0F, f20 + (float)k, (f17 + 0.0F) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, f4 + 0.0F, f20 + (float)k, (f17 + (float)k) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, f4 + 0.0F, f20 + 0.0F, (f17 + (float)k) * f13 + f9, (f18 + 0.0F) * f13 + f11); + tessellator.addVertexWithUV(f19 + 0.0F, f4 + 0.0F, f20 + 0.0F, (f17 + 0.0F) * f13 + f9, (f18 + 0.0F) * f13 + f11); + } + if(f4 <= f3 + 1.0F) + { + tessellator.setColorRGBA_F(f5, f6, f7, 0.8F); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV(f19 + 0.0F, (f4 + f3) - f16, f20 + (float)k, (f17 + 0.0F) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, (f4 + f3) - f16, f20 + (float)k, (f17 + (float)k) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, (f4 + f3) - f16, f20 + 0.0F, (f17 + (float)k) * f13 + f9, (f18 + 0.0F) * f13 + f11); + tessellator.addVertexWithUV(f19 + 0.0F, (f4 + f3) - f16, f20 + 0.0F, (f17 + 0.0F) * f13 + f9, (f18 + 0.0F) * f13 + f11); + } + tessellator.setColorRGBA_F(f5 * 0.9F, f6 * 0.9F, f7 * 0.9F, 0.8F); + if(i1 > -1) + { + tessellator.setNormal(-1F, 0.0F, 0.0F); + for(int k1 = 0; k1 < k; k1++) + { + tessellator.addVertexWithUV(f19 + (float)k1 + 0.0F, f4 + 0.0F, f20 + (float)k, (f17 + (float)k1 + 0.5F) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k1 + 0.0F, f4 + f3, f20 + (float)k, (f17 + (float)k1 + 0.5F) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k1 + 0.0F, f4 + f3, f20 + 0.0F, (f17 + (float)k1 + 0.5F) * f13 + f9, (f18 + 0.0F) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k1 + 0.0F, f4 + 0.0F, f20 + 0.0F, (f17 + (float)k1 + 0.5F) * f13 + f9, (f18 + 0.0F) * f13 + f11); + } + + } + if(i1 <= 1) + { + tessellator.setNormal(1.0F, 0.0F, 0.0F); + for(int l1 = 0; l1 < k; l1++) + { + tessellator.addVertexWithUV((f19 + (float)l1 + 1.0F) - f16, f4 + 0.0F, f20 + (float)k, (f17 + (float)l1 + 0.5F) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV((f19 + (float)l1 + 1.0F) - f16, f4 + f3, f20 + (float)k, (f17 + (float)l1 + 0.5F) * f13 + f9, (f18 + (float)k) * f13 + f11); + tessellator.addVertexWithUV((f19 + (float)l1 + 1.0F) - f16, f4 + f3, f20 + 0.0F, (f17 + (float)l1 + 0.5F) * f13 + f9, (f18 + 0.0F) * f13 + f11); + tessellator.addVertexWithUV((f19 + (float)l1 + 1.0F) - f16, f4 + 0.0F, f20 + 0.0F, (f17 + (float)l1 + 0.5F) * f13 + f9, (f18 + 0.0F) * f13 + f11); + } + + } + tessellator.setColorRGBA_F(f5 * 0.8F, f6 * 0.8F, f7 * 0.8F, 0.8F); + if(j1 > -1) + { + tessellator.setNormal(0.0F, 0.0F, -1F); + for(int i2 = 0; i2 < k; i2++) + { + tessellator.addVertexWithUV(f19 + 0.0F, f4 + f3, f20 + (float)i2 + 0.0F, (f17 + 0.0F) * f13 + f9, (f18 + (float)i2 + 0.5F) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, f4 + f3, f20 + (float)i2 + 0.0F, (f17 + (float)k) * f13 + f9, (f18 + (float)i2 + 0.5F) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, f4 + 0.0F, f20 + (float)i2 + 0.0F, (f17 + (float)k) * f13 + f9, (f18 + (float)i2 + 0.5F) * f13 + f11); + tessellator.addVertexWithUV(f19 + 0.0F, f4 + 0.0F, f20 + (float)i2 + 0.0F, (f17 + 0.0F) * f13 + f9, (f18 + (float)i2 + 0.5F) * f13 + f11); + } + + } + if(j1 <= 1) + { + tessellator.setNormal(0.0F, 0.0F, 1.0F); + for(int j2 = 0; j2 < k; j2++) + { + tessellator.addVertexWithUV(f19 + 0.0F, f4 + f3, (f20 + (float)j2 + 1.0F) - f16, (f17 + 0.0F) * f13 + f9, (f18 + (float)j2 + 0.5F) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, f4 + f3, (f20 + (float)j2 + 1.0F) - f16, (f17 + (float)k) * f13 + f9, (f18 + (float)j2 + 0.5F) * f13 + f11); + tessellator.addVertexWithUV(f19 + (float)k, f4 + 0.0F, (f20 + (float)j2 + 1.0F) - f16, (f17 + (float)k) * f13 + f9, (f18 + (float)j2 + 0.5F) * f13 + f11); + tessellator.addVertexWithUV(f19 + 0.0F, f4 + 0.0F, (f20 + (float)j2 + 1.0F) - f16, (f17 + 0.0F) * f13 + f9, (f18 + (float)j2 + 0.5F) * f13 + f11); + } + + } + tessellator.draw(); + } + + } + + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(2884 /*GL_CULL_FACE*/); + } + + public boolean updateRenderers(EntityLiving entityliving, boolean flag) + { + boolean flag1 = false; + if(flag1) + { + Collections.sort(worldRenderersToUpdate, new RenderSorter(entityliving)); + int i = worldRenderersToUpdate.size() - 1; + int j = worldRenderersToUpdate.size(); + for(int k = 0; k < j; k++) + { + WorldRenderer worldrenderer = (WorldRenderer)worldRenderersToUpdate.get(i - k); + if(!flag) + { + if(worldrenderer.distanceToEntity(entityliving) > 1024F) + { + if(worldrenderer.isInFrustum) + { + if(k >= 3) + { + return false; + } + } else + if(k >= 1) + { + return false; + } + } + } else + if(!worldrenderer.isInFrustum) + { + continue; + } + worldrenderer.updateRenderer(); + worldRenderersToUpdate.remove(worldrenderer); + worldrenderer.needsUpdate = false; + } + + return worldRenderersToUpdate.size() == 0; + } + RenderSorter rendersorter = new RenderSorter(entityliving); + WorldRenderer aworldrenderer[] = new WorldRenderer[3]; + ArrayList arraylist = null; + int l = worldRenderersToUpdate.size(); + int i1 = 0; + for(int j1 = 0; j1 < l; j1++) + { + WorldRenderer worldrenderer1 = (WorldRenderer)worldRenderersToUpdate.get(j1); + if(!flag) + { + if(worldrenderer1.distanceToEntity(entityliving) > 1024F) + { + int k2; + for(k2 = 0; k2 < 3 && (aworldrenderer[k2] == null || rendersorter.func_993_a(aworldrenderer[k2], worldrenderer1) <= 0); k2++) { } + if(--k2 <= 0) + { + continue; + } + for(int i3 = k2; --i3 != 0;) + { + aworldrenderer[i3 - 1] = aworldrenderer[i3]; + } + + aworldrenderer[k2] = worldrenderer1; + continue; + } + } else + if(!worldrenderer1.isInFrustum) + { + continue; + } + if(arraylist == null) + { + arraylist = new ArrayList(); + } + i1++; + arraylist.add(worldrenderer1); + worldRenderersToUpdate.set(j1, null); + } + + if(arraylist != null) + { + if(arraylist.size() > 1) + { + Collections.sort(arraylist, rendersorter); + } + for(int k1 = arraylist.size() - 1; k1 >= 0; k1--) + { + WorldRenderer worldrenderer2 = (WorldRenderer)arraylist.get(k1); + worldrenderer2.updateRenderer(); + worldrenderer2.needsUpdate = false; + } + + } + int l1 = 0; + for(int i2 = 2; i2 >= 0; i2--) + { + WorldRenderer worldrenderer3 = aworldrenderer[i2]; + if(worldrenderer3 == null) + { + continue; + } + if(!worldrenderer3.isInFrustum && i2 != 2) + { + aworldrenderer[i2] = null; + aworldrenderer[0] = null; + break; + } + aworldrenderer[i2].updateRenderer(); + aworldrenderer[i2].needsUpdate = false; + l1++; + } + + int j2 = 0; + int l2 = 0; + for(int j3 = worldRenderersToUpdate.size(); j2 != j3; j2++) + { + WorldRenderer worldrenderer4 = (WorldRenderer)worldRenderersToUpdate.get(j2); + if(worldrenderer4 == null || worldrenderer4 == aworldrenderer[0] || worldrenderer4 == aworldrenderer[1] || worldrenderer4 == aworldrenderer[2]) + { + continue; + } + if(l2 != j2) + { + worldRenderersToUpdate.set(l2, worldrenderer4); + } + l2++; + } + + while(--j2 >= l2) + { + worldRenderersToUpdate.remove(j2); + } + return l == i1 + l1; + } + + public void func_959_a(EntityPlayer entityplayer, MovingObjectPosition movingobjectposition, int i, ItemStack itemstack, float f) + { + Tessellator tessellator = Tessellator.instance; + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glBlendFunc(770, 1); + GL11.glColor4f(1.0F, 1.0F, 1.0F, (MathHelper.sin((float)System.currentTimeMillis() / 100F) * 0.2F + 0.4F) * 0.5F); + if(i == 0) + { + if(field_1450_i > 0.0F) + { + GL11.glBlendFunc(774, 768); + int j = renderEngine.getTexture("/terrain.png"); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, j); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F); + GL11.glPushMatrix(); + int k = worldObj.getBlockId(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); + Block block = k <= 0 ? null : Block.blocksList[k]; + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glPolygonOffset(-3F, -3F); + GL11.glEnable(32823 /*GL_POLYGON_OFFSET_FILL*/); + tessellator.startDrawingQuads(); + double d = entityplayer.lastTickPosX + (entityplayer.posX - entityplayer.lastTickPosX) * (double)f; + double d1 = entityplayer.lastTickPosY + (entityplayer.posY - entityplayer.lastTickPosY) * (double)f; + double d2 = entityplayer.lastTickPosZ + (entityplayer.posZ - entityplayer.lastTickPosZ) * (double)f; + tessellator.setTranslationD(-d, -d1, -d2); + tessellator.disableColor(); + if(block == null) + { + block = Block.stone; + } + field_1438_u.renderBlockUsingTexture(block, movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ, 240 + (int)(field_1450_i * 10F)); + tessellator.draw(); + tessellator.setTranslationD(0.0D, 0.0D, 0.0D); + GL11.glPolygonOffset(0.0F, 0.0F); + GL11.glDisable(32823 /*GL_POLYGON_OFFSET_FILL*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glDepthMask(true); + GL11.glPopMatrix(); + } + } else + if(itemstack != null) + { + GL11.glBlendFunc(770, 771); + float f1 = MathHelper.sin((float)System.currentTimeMillis() / 100F) * 0.2F + 0.8F; + GL11.glColor4f(f1, f1, f1, MathHelper.sin((float)System.currentTimeMillis() / 200F) * 0.2F + 0.5F); + int l = renderEngine.getTexture("/terrain.png"); + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, l); + int i1 = movingobjectposition.blockX; + int j1 = movingobjectposition.blockY; + int k1 = movingobjectposition.blockZ; + if(movingobjectposition.sideHit == 0) + { + j1--; + } + if(movingobjectposition.sideHit == 1) + { + j1++; + } + if(movingobjectposition.sideHit == 2) + { + k1--; + } + if(movingobjectposition.sideHit == 3) + { + k1++; + } + if(movingobjectposition.sideHit == 4) + { + i1--; + } + if(movingobjectposition.sideHit == 5) + { + i1++; + } + } + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + } + + public void drawSelectionBox(EntityPlayer entityplayer, MovingObjectPosition movingobjectposition, int i, ItemStack itemstack, float f) + { + if(i == 0 && movingobjectposition.typeOfHit == EnumMovingObjectType.TILE) + { + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(0.0F, 0.0F, 0.0F, 0.4F); + GL11.glLineWidth(2.0F); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glDepthMask(false); + float f1 = 0.002F; + int j = worldObj.getBlockId(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); + if(j > 0) + { + Block.blocksList[j].setBlockBoundsBasedOnState(worldObj, movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); + double d = entityplayer.lastTickPosX + (entityplayer.posX - entityplayer.lastTickPosX) * (double)f; + double d1 = entityplayer.lastTickPosY + (entityplayer.posY - entityplayer.lastTickPosY) * (double)f; + double d2 = entityplayer.lastTickPosZ + (entityplayer.posZ - entityplayer.lastTickPosZ) * (double)f; + drawOutlinedBoundingBox(Block.blocksList[j].getSelectedBoundingBoxFromPool(worldObj, movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ).expand(f1, f1, f1).getOffsetBoundingBox(-d, -d1, -d2)); + } + GL11.glDepthMask(true); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(3042 /*GL_BLEND*/); + } + } + + private void drawOutlinedBoundingBox(AxisAlignedBB axisalignedbb) + { + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawing(3); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.draw(); + tessellator.startDrawing(3); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.draw(); + tessellator.startDrawing(1); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.minZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.maxZ); + tessellator.addVertex(axisalignedbb.minX, axisalignedbb.maxY, axisalignedbb.maxZ); + tessellator.draw(); + } + + public void func_949_a(int i, int j, int k, int l, int i1, int j1) + { + int k1 = MathHelper.bucketInt(i, 16); + int l1 = MathHelper.bucketInt(j, 16); + int i2 = MathHelper.bucketInt(k, 16); + int j2 = MathHelper.bucketInt(l, 16); + int k2 = MathHelper.bucketInt(i1, 16); + int l2 = MathHelper.bucketInt(j1, 16); + for(int i3 = k1; i3 <= j2; i3++) + { + int j3 = i3 % renderChunksWide; + if(j3 < 0) + { + j3 += renderChunksWide; + } + for(int k3 = l1; k3 <= k2; k3++) + { + int l3 = k3 % renderChunksTall; + if(l3 < 0) + { + l3 += renderChunksTall; + } + for(int i4 = i2; i4 <= l2; i4++) + { + int j4 = i4 % renderChunksDeep; + if(j4 < 0) + { + j4 += renderChunksDeep; + } + int k4 = (j4 * renderChunksTall + l3) * renderChunksWide + j3; + WorldRenderer worldrenderer = worldRenderers[k4]; + if(!worldrenderer.needsUpdate) + { + worldRenderersToUpdate.add(worldrenderer); + worldrenderer.markDirty(); + } + } + + } + + } + + } + + public void func_934_a(int i, int j, int k) + { + func_949_a(i - 1, j - 1, k - 1, i + 1, j + 1, k + 1); + } + + public void markBlockRangeNeedsUpdate(int i, int j, int k, int l, int i1, int j1) + { + func_949_a(i - 1, j - 1, k - 1, l + 1, i1 + 1, j1 + 1); + } + + public void func_960_a(ICamera icamera, float f) + { + for(int i = 0; i < worldRenderers.length; i++) + { + if(!worldRenderers[i].canRender() && (!worldRenderers[i].isInFrustum || (i + field_1449_j & 0xf) == 0)) + { + worldRenderers[i].updateInFrustrum(icamera); + } + } + + field_1449_j++; + } + + public void playRecord(String s, int i, int j, int k) + { + if(s != null) + { + mc.ingameGUI.setRecordPlayingMessage((new StringBuilder()).append("C418 - ").append(s).toString()); + } + mc.sndManager.func_331_a(s, i, j, k, 1.0F, 1.0F); + } + + public void playSound(String s, double d, double d1, double d2, + float f, float f1) + { + float f2 = 16F; + if(f > 1.0F) + { + f2 *= f; + } + if(mc.field_22009_h.getDistanceSq(d, d1, d2) < (double)(f2 * f2)) + { + mc.sndManager.playSound(s, (float)d, (float)d1, (float)d2, f, f1); + } + } + + public void spawnParticle(String s, double d, double d1, double d2, + double d3, double d4, double d5) + { + double d6 = mc.field_22009_h.posX - d; + double d7 = mc.field_22009_h.posY - d1; + double d8 = mc.field_22009_h.posZ - d2; + double d9 = 16D; + if(d6 * d6 + d7 * d7 + d8 * d8 > d9 * d9) + { + return; + } + if(s == "bubble") + { + mc.effectRenderer.addEffect(new EntityBubbleFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "smoke") + { + mc.effectRenderer.addEffect(new EntitySmokeFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "note") + { + mc.effectRenderer.addEffect(new EntityNoteFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "portal") + { + mc.effectRenderer.addEffect(new EntityPortalFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "explode") + { + mc.effectRenderer.addEffect(new EntityExplodeFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "flame") + { + mc.effectRenderer.addEffect(new EntityFlameFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "lava") + { + mc.effectRenderer.addEffect(new EntityLavaFX(worldObj, d, d1, d2)); + } else + if(s == "splash") + { + mc.effectRenderer.addEffect(new EntitySplashFX(worldObj, d, d1, d2, d3, d4, d5)); + } else + if(s == "largesmoke") + { + mc.effectRenderer.addEffect(new EntitySmokeFX(worldObj, d, d1, d2, d3, d4, d5, 2.5F)); + } else + if(s == "reddust") + { + mc.effectRenderer.addEffect(new EntityReddustFX(worldObj, d, d1, d2, (float)d3, (float)d4, (float)d5)); + } else + if(s == "snowballpoof") + { + mc.effectRenderer.addEffect(new EntitySlimeFX(worldObj, d, d1, d2, Item.snowball)); + } else + if(s == "slime") + { + mc.effectRenderer.addEffect(new EntitySlimeFX(worldObj, d, d1, d2, Item.slimeBall)); + } + } + + public void obtainEntitySkin(Entity entity) + { + entity.updateCloak(); + if(entity.skinUrl != null) + { + renderEngine.obtainImageData(entity.skinUrl, new ImageBufferDownload()); + } + if(entity.cloakUrl != null) + { + renderEngine.obtainImageData(entity.cloakUrl, new ImageBufferDownload()); + } + } + + public void releaseEntitySkin(Entity entity) + { + if(entity.skinUrl != null) + { + renderEngine.releaseImageData(entity.skinUrl); + } + if(entity.cloakUrl != null) + { + renderEngine.releaseImageData(entity.cloakUrl); + } + } + + public void updateAllRenderers() + { + for(int i = 0; i < worldRenderers.length; i++) + { + if(worldRenderers[i].field_1747_A && !worldRenderers[i].needsUpdate) + { + worldRenderersToUpdate.add(worldRenderers[i]); + worldRenderers[i].markDirty(); + } + } + + } + + public void doNothingWithTileEntity(int i, int j, int k, TileEntity tileentity) + { + } + + public List tileEntities; + private World worldObj; + private RenderEngine renderEngine; + private List worldRenderersToUpdate; + private WorldRenderer sortedWorldRenderers[]; + private WorldRenderer worldRenderers[]; + private int renderChunksWide; + private int renderChunksTall; + private int renderChunksDeep; + private int field_1440_s; + private Minecraft mc; + private RenderBlocks field_1438_u; + private IntBuffer field_1437_v; + private boolean field_1436_w; + private int field_1435_x; + private int field_1434_y; + private int field_1433_z; + private int field_1432_A; + private int field_1431_B; + private int field_1430_C; + private int field_1429_D; + private int field_1428_E; + private int field_1427_F; + private int field_1426_G; + private int renderDistance; + private int field_1424_I; + private int field_1423_J; + private int field_1422_K; + private int field_1421_L; + int field_1457_b[]; + IntBuffer field_1456_c; + private int field_1420_M; + private int field_1419_N; + private int field_1418_O; + private int field_1417_P; + private int field_1416_Q; + private int field_21156_R; + private List field_1415_R; + private RenderList field_1414_S[] = { + new RenderList(), new RenderList(), new RenderList(), new RenderList() + }; + int field_1455_d; + int field_1454_e; + double field_1453_f; + double field_1452_g; + double field_1451_h; + public float field_1450_i; + int field_1449_j; +} diff --git a/src/main/java/net/minecraft/src/RenderHelper.java b/src/main/java/net/minecraft/src/RenderHelper.java new file mode 100644 index 0000000..c7ddb93 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderHelper.java @@ -0,0 +1,63 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.nio.FloatBuffer; +import org.lwjgl.opengl.GL11; + +public class RenderHelper +{ + + public RenderHelper() + { + } + + public static void disableStandardItemLighting() + { + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(16384 /*GL_LIGHT0*/); + GL11.glDisable(16385 /*GL_LIGHT1*/); + GL11.glDisable(2903 /*GL_COLOR_MATERIAL*/); + } + + public static void enableStandardItemLighting() + { + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(16384 /*GL_LIGHT0*/); + GL11.glEnable(16385 /*GL_LIGHT1*/); + GL11.glEnable(2903 /*GL_COLOR_MATERIAL*/); + GL11.glColorMaterial(1032 /*GL_FRONT_AND_BACK*/, 5634 /*GL_AMBIENT_AND_DIFFUSE*/); + float f = 0.4F; + float f1 = 0.6F; + float f2 = 0.0F; + Vec3D vec3d = Vec3D.createVector(0.20000000298023224D, 1.0D, -0.69999998807907104D).normalize(); + GL11.glLight(16384 /*GL_LIGHT0*/, 4611 /*GL_POSITION*/, func_1157_a(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord, 0.0D)); + GL11.glLight(16384 /*GL_LIGHT0*/, 4609 /*GL_DIFFUSE*/, func_1156_a(f1, f1, f1, 1.0F)); + GL11.glLight(16384 /*GL_LIGHT0*/, 4608 /*GL_AMBIENT*/, func_1156_a(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glLight(16384 /*GL_LIGHT0*/, 4610 /*GL_SPECULAR*/, func_1156_a(f2, f2, f2, 1.0F)); + vec3d = Vec3D.createVector(-0.20000000298023224D, 1.0D, 0.69999998807907104D).normalize(); + GL11.glLight(16385 /*GL_LIGHT1*/, 4611 /*GL_POSITION*/, func_1157_a(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord, 0.0D)); + GL11.glLight(16385 /*GL_LIGHT1*/, 4609 /*GL_DIFFUSE*/, func_1156_a(f1, f1, f1, 1.0F)); + GL11.glLight(16385 /*GL_LIGHT1*/, 4608 /*GL_AMBIENT*/, func_1156_a(0.0F, 0.0F, 0.0F, 1.0F)); + GL11.glLight(16385 /*GL_LIGHT1*/, 4610 /*GL_SPECULAR*/, func_1156_a(f2, f2, f2, 1.0F)); + GL11.glShadeModel(7424 /*GL_FLAT*/); + GL11.glLightModel(2899 /*GL_LIGHT_MODEL_AMBIENT*/, func_1156_a(f, f, f, 1.0F)); + } + + private static FloatBuffer func_1157_a(double d, double d1, double d2, double d3) + { + return func_1156_a((float)d, (float)d1, (float)d2, (float)d3); + } + + private static FloatBuffer func_1156_a(float f, float f1, float f2, float f3) + { + field_1695_a.clear(); + field_1695_a.put(f).put(f1).put(f2).put(f3); + field_1695_a.flip(); + return field_1695_a; + } + + private static FloatBuffer field_1695_a = GLAllocation.createDirectFloatBuffer(16); + +} diff --git a/src/main/java/net/minecraft/src/RenderItem.java b/src/main/java/net/minecraft/src/RenderItem.java new file mode 100644 index 0000000..41a98b2 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderItem.java @@ -0,0 +1,218 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; +import org.lwjgl.opengl.GL11; + +public class RenderItem extends Render +{ + + public RenderItem() + { + renderBlocks = new RenderBlocks(); + random = new Random(); + shadowSize = 0.15F; + field_194_c = 0.75F; + } + + public void func_165_a(EntityItem entityitem, double d, double d1, double d2, + float f, float f1) + { + random.setSeed(187L); + ItemStack itemstack = entityitem.item; + GL11.glPushMatrix(); + float f2 = MathHelper.sin(((float)entityitem.age + f1) / 10F + entityitem.field_804_d) * 0.1F + 0.1F; + float f3 = (((float)entityitem.age + f1) / 20F + entityitem.field_804_d) * 57.29578F; + byte byte0 = 1; + if(entityitem.item.stackSize > 1) + { + byte0 = 2; + } + if(entityitem.item.stackSize > 5) + { + byte0 = 3; + } + if(entityitem.item.stackSize > 20) + { + byte0 = 4; + } + GL11.glTranslatef((float)d, (float)d1 + f2, (float)d2); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + if(itemstack.itemID < 256 && RenderBlocks.func_1219_a(Block.blocksList[itemstack.itemID].getRenderType())) + { + GL11.glRotatef(f3, 0.0F, 1.0F, 0.0F); + loadTexture("/terrain.png"); + float f4 = 0.25F; + if(!Block.blocksList[itemstack.itemID].renderAsNormalBlock() && itemstack.itemID != Block.stairSingle.blockID) + { + f4 = 0.5F; + } + GL11.glScalef(f4, f4, f4); + for(int j = 0; j < byte0; j++) + { + GL11.glPushMatrix(); + if(j > 0) + { + float f5 = ((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / f4; + float f7 = ((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / f4; + float f9 = ((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / f4; + GL11.glTranslatef(f5, f7, f9); + } + renderBlocks.func_1227_a(Block.blocksList[itemstack.itemID], itemstack.getItemDamage()); + GL11.glPopMatrix(); + } + + } else + { + GL11.glScalef(0.5F, 0.5F, 0.5F); + int i = itemstack.getIconIndex(); + if(itemstack.itemID < 256) + { + loadTexture("/terrain.png"); + } else + { + loadTexture("/gui/items.png"); + } + Tessellator tessellator = Tessellator.instance; + float f6 = (float)((i % 16) * 16 + 0) / 256F; + float f8 = (float)((i % 16) * 16 + 16) / 256F; + float f10 = (float)((i / 16) * 16 + 0) / 256F; + float f11 = (float)((i / 16) * 16 + 16) / 256F; + float f12 = 1.0F; + float f13 = 0.5F; + float f14 = 0.25F; + for(int k = 0; k < byte0; k++) + { + GL11.glPushMatrix(); + if(k > 0) + { + float f15 = (random.nextFloat() * 2.0F - 1.0F) * 0.3F; + float f16 = (random.nextFloat() * 2.0F - 1.0F) * 0.3F; + float f17 = (random.nextFloat() * 2.0F - 1.0F) * 0.3F; + GL11.glTranslatef(f15, f16, f17); + } + GL11.glRotatef(180F - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV(0.0F - f13, 0.0F - f14, 0.0D, f6, f11); + tessellator.addVertexWithUV(f12 - f13, 0.0F - f14, 0.0D, f8, f11); + tessellator.addVertexWithUV(f12 - f13, 1.0F - f14, 0.0D, f8, f10); + tessellator.addVertexWithUV(0.0F - f13, 1.0F - f14, 0.0D, f6, f10); + tessellator.draw(); + GL11.glPopMatrix(); + } + + } + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPopMatrix(); + } + + public void renderItemIntoGUI(FontRenderer fontrenderer, RenderEngine renderengine, ItemStack itemstack, int i, int j) + { + if(itemstack == null) + { + return; + } + if(itemstack.itemID < 256 && RenderBlocks.func_1219_a(Block.blocksList[itemstack.itemID].getRenderType())) + { + int k = itemstack.itemID; + renderengine.bindTexture(renderengine.getTexture("/terrain.png")); + Block block = Block.blocksList[k]; + GL11.glPushMatrix(); + GL11.glTranslatef(i - 2, j + 3, 0.0F); + GL11.glScalef(10F, 10F, 10F); + GL11.glTranslatef(1.0F, 0.5F, 8F); + GL11.glRotatef(210F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glScalef(1.0F, 1.0F, 1.0F); + renderBlocks.func_1227_a(block, itemstack.getItemDamage()); + GL11.glPopMatrix(); + } else + if(itemstack.getIconIndex() >= 0) + { + GL11.glDisable(2896 /*GL_LIGHTING*/); + if(itemstack.itemID < 256) + { + renderengine.bindTexture(renderengine.getTexture("/terrain.png")); + } else + { + renderengine.bindTexture(renderengine.getTexture("/gui/items.png")); + } + renderTexturedQuad(i, j, (itemstack.getIconIndex() % 16) * 16, (itemstack.getIconIndex() / 16) * 16, 16, 16); + GL11.glEnable(2896 /*GL_LIGHTING*/); + } + GL11.glEnable(2884 /*GL_CULL_FACE*/); + } + + public void renderItemOverlayIntoGUI(FontRenderer fontrenderer, RenderEngine renderengine, ItemStack itemstack, int i, int j) + { + if(itemstack == null) + { + return; + } + if(itemstack.stackSize > 1) + { + String s = (new StringBuilder()).append("").append(itemstack.stackSize).toString(); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + fontrenderer.drawStringWithShadow(s, (i + 19) - 2 - fontrenderer.getStringWidth(s), j + 6 + 3, 0xffffff); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + } + if(itemstack.isItemDamaged()) + { + int k = (int)Math.round(13D - ((double)itemstack.getItemDamageForDisplay() * 13D) / (double)itemstack.getMaxDamage()); + int l = (int)Math.round(255D - ((double)itemstack.getItemDamageForDisplay() * 255D) / (double)itemstack.getMaxDamage()); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + Tessellator tessellator = Tessellator.instance; + int i1 = 255 - l << 16 | l << 8; + int j1 = (255 - l) / 4 << 16 | 0x3f00; + renderQuad(tessellator, i + 2, j + 13, 13, 2, 0); + renderQuad(tessellator, i + 2, j + 13, 12, 1, j1); + renderQuad(tessellator, i + 2, j + 13, k, 1, i1); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + } + + private void renderQuad(Tessellator tessellator, int i, int j, int k, int l, int i1) + { + tessellator.startDrawingQuads(); + tessellator.setColorOpaque_I(i1); + tessellator.addVertex(i + 0, j + 0, 0.0D); + tessellator.addVertex(i + 0, j + l, 0.0D); + tessellator.addVertex(i + k, j + l, 0.0D); + tessellator.addVertex(i + k, j + 0, 0.0D); + tessellator.draw(); + } + + public void renderTexturedQuad(int i, int j, int k, int l, int i1, int j1) + { + float f = 0.0F; + float f1 = 0.00390625F; + float f2 = 0.00390625F; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(i + 0, j + j1, f, (float)(k + 0) * f1, (float)(l + j1) * f2); + tessellator.addVertexWithUV(i + i1, j + j1, f, (float)(k + i1) * f1, (float)(l + j1) * f2); + tessellator.addVertexWithUV(i + i1, j + 0, f, (float)(k + i1) * f1, (float)(l + 0) * f2); + tessellator.addVertexWithUV(i + 0, j + 0, f, (float)(k + 0) * f1, (float)(l + 0) * f2); + tessellator.draw(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_165_a((EntityItem)entity, d, d1, d2, f, f1); + } + + private RenderBlocks renderBlocks; + private Random random; +} diff --git a/src/main/java/net/minecraft/src/RenderList.java b/src/main/java/net/minecraft/src/RenderList.java new file mode 100644 index 0000000..0190b33 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderList.java @@ -0,0 +1,87 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.nio.IntBuffer; +import org.lwjgl.opengl.GL11; + +public class RenderList +{ + + public RenderList() + { + field_1236_g = GLAllocation.createDirectIntBuffer(0x10000); + field_1235_h = false; + field_1234_i = false; + } + + public void func_861_a(int i, int j, int k, double d, double d1, + double d2) + { + field_1235_h = true; + field_1236_g.clear(); + field_1242_a = i; + field_1241_b = j; + field_1240_c = k; + field_1239_d = (float)d; + field_1238_e = (float)d1; + field_1237_f = (float)d2; + } + + public boolean func_862_a(int i, int j, int k) + { + if(!field_1235_h) + { + return false; + } else + { + return i == field_1242_a && j == field_1241_b && k == field_1240_c; + } + } + + public void func_858_a(int i) + { + field_1236_g.put(i); + if(field_1236_g.remaining() == 0) + { + func_860_a(); + } + } + + public void func_860_a() + { + if(!field_1235_h) + { + return; + } + if(!field_1234_i) + { + field_1236_g.flip(); + field_1234_i = true; + } + if(field_1236_g.remaining() > 0) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)field_1242_a - field_1239_d, (float)field_1241_b - field_1238_e, (float)field_1240_c - field_1237_f); + GL11.glCallLists(field_1236_g); + GL11.glPopMatrix(); + } + } + + public void func_859_b() + { + field_1235_h = false; + field_1234_i = false; + } + + private int field_1242_a; + private int field_1241_b; + private int field_1240_c; + private float field_1239_d; + private float field_1238_e; + private float field_1237_f; + private IntBuffer field_1236_g; + private boolean field_1235_h; + private boolean field_1234_i; +} diff --git a/src/main/java/net/minecraft/src/RenderLiving.java b/src/main/java/net/minecraft/src/RenderLiving.java new file mode 100644 index 0000000..f0c653b --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderLiving.java @@ -0,0 +1,240 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class RenderLiving extends Render +{ + + public RenderLiving(ModelBase modelbase, float f) + { + mainModel = modelbase; + shadowSize = f; + } + + public void setRenderPassModel(ModelBase modelbase) + { + renderPassModel = modelbase; + } + + public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glDisable(2884 /*GL_CULL_FACE*/); + mainModel.onGround = func_167_c(entityliving, f1); + mainModel.isRiding = entityliving.func_21063_V(); + if(renderPassModel != null) + { + renderPassModel.isRiding = mainModel.isRiding; + } + try + { + float f2 = entityliving.prevRenderYawOffset + (entityliving.renderYawOffset - entityliving.prevRenderYawOffset) * f1; + float f3 = entityliving.prevRotationYaw + (entityliving.rotationYaw - entityliving.prevRotationYaw) * f1; + float f4 = entityliving.prevRotationPitch + (entityliving.rotationPitch - entityliving.prevRotationPitch) * f1; + func_22012_b(entityliving, d, d1, d2); + float f5 = func_170_d(entityliving, f1); + func_21004_a(entityliving, f5, f2, f1); + float f6 = 0.0625F; + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glScalef(-1F, -1F, 1.0F); + preRenderCallback(entityliving, f1); + GL11.glTranslatef(0.0F, -24F * f6 - 0.0078125F, 0.0F); + float f7 = entityliving.field_705_Q + (entityliving.field_704_R - entityliving.field_705_Q) * f1; + float f8 = entityliving.field_703_S - entityliving.field_704_R * (1.0F - f1); + if(f7 > 1.0F) + { + f7 = 1.0F; + } + loadDownloadableImageTexture(entityliving.skinUrl, entityliving.getEntityTexture()); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + mainModel.render(f8, f7, f5, f3 - f2, f4, f6); + for(int i = 0; i < 4; i++) + { + if(shouldRenderPass(entityliving, i, f1)) + { + renderPassModel.render(f8, f7, f5, f3 - f2, f4, f6); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + } + } + + renderEquippedItems(entityliving, f1); + float f9 = entityliving.getEntityBrightness(f1); + int j = getColorMultiplier(entityliving, f9, f1); + if((j >> 24 & 0xff) > 0 || entityliving.hurtTime > 0 || entityliving.deathTime > 0) + { + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + GL11.glDepthFunc(514); + if(entityliving.hurtTime > 0 || entityliving.deathTime > 0) + { + GL11.glColor4f(f9, 0.0F, 0.0F, 0.4F); + mainModel.render(f8, f7, f5, f3 - f2, f4, f6); + for(int k = 0; k < 4; k++) + { + if(shouldRenderPass(entityliving, k, f1)) + { + GL11.glColor4f(f9, 0.0F, 0.0F, 0.4F); + renderPassModel.render(f8, f7, f5, f3 - f2, f4, f6); + } + } + + } + if((j >> 24 & 0xff) > 0) + { + float f10 = (float)(j >> 16 & 0xff) / 255F; + float f11 = (float)(j >> 8 & 0xff) / 255F; + float f12 = (float)(j & 0xff) / 255F; + float f13 = (float)(j >> 24 & 0xff) / 255F; + GL11.glColor4f(f10, f11, f12, f13); + mainModel.render(f8, f7, f5, f3 - f2, f4, f6); + for(int l = 0; l < 4; l++) + { + if(shouldRenderPass(entityliving, l, f1)) + { + GL11.glColor4f(f10, f11, f12, f13); + renderPassModel.render(f8, f7, f5, f3 - f2, f4, f6); + } + } + + } + GL11.glDepthFunc(515); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(3008 /*GL_ALPHA_TEST*/); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + GL11.glEnable(2884 /*GL_CULL_FACE*/); + GL11.glPopMatrix(); + func_22014_a(entityliving, d, d1, d2); + } + + protected void func_22012_b(EntityLiving entityliving, double d, double d1, double d2) + { + GL11.glTranslatef((float)d, (float)d1, (float)d2); + } + + protected void func_21004_a(EntityLiving entityliving, float f, float f1, float f2) + { + GL11.glRotatef(180F - f1, 0.0F, 1.0F, 0.0F); + if(entityliving.deathTime > 0) + { + float f3 = ((((float)entityliving.deathTime + f2) - 1.0F) / 20F) * 1.6F; + f3 = MathHelper.sqrt_float(f3); + if(f3 > 1.0F) + { + f3 = 1.0F; + } + GL11.glRotatef(f3 * func_172_a(entityliving), 0.0F, 0.0F, 1.0F); + } + } + + protected float func_167_c(EntityLiving entityliving, float f) + { + return entityliving.getSwingProgress(f); + } + + protected float func_170_d(EntityLiving entityliving, float f) + { + return (float)entityliving.ticksExisted + f; + } + + protected void renderEquippedItems(EntityLiving entityliving, float f) + { + } + + protected boolean shouldRenderPass(EntityLiving entityliving, int i, float f) + { + return false; + } + + protected float func_172_a(EntityLiving entityliving) + { + return 90F; + } + + protected int getColorMultiplier(EntityLiving entityliving, float f, float f1) + { + return 0; + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + } + + protected void func_22014_a(EntityLiving entityliving, double d, double d1, double d2) + { + if(Minecraft.func_22007_w()) + { + func_22013_a(entityliving, Integer.toString(entityliving.entityId), d, d1, d2, 64); + } + } + + protected void func_22013_a(EntityLiving entityliving, String s, double d, double d1, double d2, int i) + { + float f = entityliving.getDistanceToEntity(renderManager.field_22188_h); + if(f > (float)i) + { + return; + } + FontRenderer fontrenderer = getFontRendererFromRenderManager(); + float f1 = 1.6F; + float f2 = 0.01666667F * f1; + GL11.glPushMatrix(); + GL11.glTranslatef((float)d + 0.0F, (float)d1 + 2.3F, (float)d2); + GL11.glNormal3f(0.0F, 1.0F, 0.0F); + GL11.glRotatef(-renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(renderManager.playerViewX, 1.0F, 0.0F, 0.0F); + GL11.glScalef(-f2, -f2, f2); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glDepthMask(false); + GL11.glDisable(2929 /*GL_DEPTH_TEST*/); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + Tessellator tessellator = Tessellator.instance; + byte byte0 = 0; + if(s.equals("deadmau5")) + { + byte0 = -10; + } + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + tessellator.startDrawingQuads(); + int j = fontrenderer.getStringWidth(s) / 2; + tessellator.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F); + tessellator.addVertex(-j - 1, -1 + byte0, 0.0D); + tessellator.addVertex(-j - 1, 8 + byte0, 0.0D); + tessellator.addVertex(j + 1, 8 + byte0, 0.0D); + tessellator.addVertex(j + 1, -1 + byte0, 0.0D); + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, byte0, 0x20ffffff); + GL11.glEnable(2929 /*GL_DEPTH_TEST*/); + GL11.glDepthMask(true); + fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, byte0, -1); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + doRenderLiving((EntityLiving)entity, d, d1, d2, f, f1); + } + + protected ModelBase mainModel; + protected ModelBase renderPassModel; +} diff --git a/src/main/java/net/minecraft/src/RenderManager.java b/src/main/java/net/minecraft/src/RenderManager.java new file mode 100644 index 0000000..a4a6c28 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderManager.java @@ -0,0 +1,136 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; +import org.lwjgl.opengl.GL11; + +public class RenderManager +{ + + private RenderManager() + { + entityRenderMap = new HashMap(); + entityRenderMap.put(EntitySpider.class, new RenderSpider()); + entityRenderMap.put(EntityPig.class, new RenderPig(new ModelPig(), new ModelPig(0.5F), 0.7F)); + entityRenderMap.put(EntitySheep.class, new RenderSheep(new ModelSheep2(), new ModelSheep1(), 0.7F)); + entityRenderMap.put(EntityCow.class, new RenderCow(new ModelCow(), 0.7F)); + entityRenderMap.put(EntityChicken.class, new RenderChicken(new ModelChicken(), 0.3F)); + entityRenderMap.put(EntityCreeper.class, new RenderCreeper()); + entityRenderMap.put(EntitySkeleton.class, new RenderBiped(new ModelSkeleton(), 0.5F)); + entityRenderMap.put(EntityZombie.class, new RenderBiped(new ModelZombie(), 0.5F)); + entityRenderMap.put(EntitySlime.class, new RenderSlime(new ModelSlime(16), new ModelSlime(0), 0.25F)); + entityRenderMap.put(EntityPlayer.class, new RenderPlayer()); + entityRenderMap.put(EntityZombieSimple.class, new RenderZombieSimple(new ModelZombie(), 0.5F, 6F)); + entityRenderMap.put(EntityGhast.class, new RenderGhast()); + entityRenderMap.put(EntitySquid.class, new RenderSquid(new ModelSquid(), 0.7F)); + entityRenderMap.put(EntityLiving.class, new RenderLiving(new ModelBiped(), 0.5F)); + entityRenderMap.put(Entity.class, new RenderEntity()); + entityRenderMap.put(EntityPainting.class, new RenderPainting()); + entityRenderMap.put(EntityArrow.class, new RenderArrow()); + entityRenderMap.put(EntitySnowball.class, new RenderSnowball(Item.snowball.getIconIndex(null))); + entityRenderMap.put(EntityEgg.class, new RenderSnowball(Item.egg.getIconIndex(null))); + entityRenderMap.put(EntityFireball.class, new RenderFireball()); + entityRenderMap.put(EntityItem.class, new RenderItem()); + entityRenderMap.put(EntityTNTPrimed.class, new RenderTNTPrimed()); + entityRenderMap.put(EntityFallingSand.class, new RenderFallingSand()); + entityRenderMap.put(EntityMinecart.class, new RenderMinecart()); + entityRenderMap.put(EntityBoat.class, new RenderBoat()); + entityRenderMap.put(EntityFish.class, new RenderFish()); + Render render; + for(Iterator iterator = entityRenderMap.values().iterator(); iterator.hasNext(); render.setRenderManager(this)) + { + render = (Render)iterator.next(); + } + + } + + public Render getEntityClassRenderObject(Class class1) + { + Render render = (Render)entityRenderMap.get(class1); + if(render == null && class1 != (Entity.class)) + { + render = getEntityClassRenderObject(class1.getSuperclass()); + entityRenderMap.put(class1, render); + } + return render; + } + + public Render getEntityRenderObject(Entity entity) + { + return getEntityClassRenderObject(entity.getClass()); + } + + public void func_22187_a(World world, RenderEngine renderengine, FontRenderer fontrenderer, EntityLiving entityliving, GameSettings gamesettings, float f) + { + worldObj = world; + renderEngine = renderengine; + options = gamesettings; + field_22188_h = entityliving; + field_1218_p = fontrenderer; + playerViewY = entityliving.prevRotationYaw + (entityliving.rotationYaw - entityliving.prevRotationYaw) * f; + playerViewX = entityliving.prevRotationPitch + (entityliving.rotationPitch - entityliving.prevRotationPitch) * f; + field_1222_l = entityliving.lastTickPosX + (entityliving.posX - entityliving.lastTickPosX) * (double)f; + field_1221_m = entityliving.lastTickPosY + (entityliving.posY - entityliving.lastTickPosY) * (double)f; + field_1220_n = entityliving.lastTickPosZ + (entityliving.posZ - entityliving.lastTickPosZ) * (double)f; + } + + public void renderEntity(Entity entity, float f) + { + double d = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double)f; + double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double)f; + double d2 = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double)f; + float f1 = entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * f; + float f2 = entity.getEntityBrightness(f); + GL11.glColor3f(f2, f2, f2); + renderEntityWithPosYaw(entity, d - renderPosX, d1 - renderPosY, d2 - renderPosZ, f1, f); + } + + public void renderEntityWithPosYaw(Entity entity, double d, double d1, double d2, + float f, float f1) + { + Render render = getEntityRenderObject(entity); + if(render != null) + { + render.doRender(entity, d, d1, d2, f, f1); + render.doRenderShadowAndFire(entity, d, d1, d2, f, f1); + } + } + + public void func_852_a(World world) + { + worldObj = world; + } + + public double func_851_a(double d, double d1, double d2) + { + double d3 = d - field_1222_l; + double d4 = d1 - field_1221_m; + double d5 = d2 - field_1220_n; + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public FontRenderer getFontRenderer() + { + return field_1218_p; + } + + private Map entityRenderMap; + public static RenderManager instance = new RenderManager(); + private FontRenderer field_1218_p; + public static double renderPosX; + public static double renderPosY; + public static double renderPosZ; + public RenderEngine renderEngine; + public ItemRenderer itemRenderer; + public World worldObj; + public EntityLiving field_22188_h; + public float playerViewY; + public float playerViewX; + public GameSettings options; + public double field_1222_l; + public double field_1221_m; + public double field_1220_n; + +} diff --git a/src/main/java/net/minecraft/src/RenderMinecart.java b/src/main/java/net/minecraft/src/RenderMinecart.java new file mode 100644 index 0000000..e432ab5 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderMinecart.java @@ -0,0 +1,95 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderMinecart extends Render +{ + + public RenderMinecart() + { + shadowSize = 0.5F; + modelMinecart = new ModelMinecart(); + } + + public void func_152_a(EntityMinecart entityminecart, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + double d3 = entityminecart.lastTickPosX + (entityminecart.posX - entityminecart.lastTickPosX) * (double)f1; + double d4 = entityminecart.lastTickPosY + (entityminecart.posY - entityminecart.lastTickPosY) * (double)f1; + double d5 = entityminecart.lastTickPosZ + (entityminecart.posZ - entityminecart.lastTickPosZ) * (double)f1; + double d6 = 0.30000001192092896D; + Vec3D vec3d = entityminecart.func_514_g(d3, d4, d5); + float f2 = entityminecart.prevRotationPitch + (entityminecart.rotationPitch - entityminecart.prevRotationPitch) * f1; + if(vec3d != null) + { + Vec3D vec3d1 = entityminecart.func_515_a(d3, d4, d5, d6); + Vec3D vec3d2 = entityminecart.func_515_a(d3, d4, d5, -d6); + if(vec3d1 == null) + { + vec3d1 = vec3d; + } + if(vec3d2 == null) + { + vec3d2 = vec3d; + } + d += vec3d.xCoord - d3; + d1 += (vec3d1.yCoord + vec3d2.yCoord) / 2D - d4; + d2 += vec3d.zCoord - d5; + Vec3D vec3d3 = vec3d2.addVector(-vec3d1.xCoord, -vec3d1.yCoord, -vec3d1.zCoord); + if(vec3d3.lengthVector() != 0.0D) + { + vec3d3 = vec3d3.normalize(); + f = (float)((Math.atan2(vec3d3.zCoord, vec3d3.xCoord) * 180D) / 3.1415926535897931D); + f2 = (float)(Math.atan(vec3d3.yCoord) * 73D); + } + } + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glRotatef(180F - f, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-f2, 0.0F, 0.0F, 1.0F); + float f3 = (float)entityminecart.field_20911_b - f1; + float f4 = (float)entityminecart.field_20910_a - f1; + if(f4 < 0.0F) + { + f4 = 0.0F; + } + if(f3 > 0.0F) + { + GL11.glRotatef(((MathHelper.sin(f3) * f3 * f4) / 10F) * (float)entityminecart.field_20912_c, 1.0F, 0.0F, 0.0F); + } + if(entityminecart.minecartType != 0) + { + loadTexture("/terrain.png"); + float f5 = 0.75F; + GL11.glScalef(f5, f5, f5); + GL11.glTranslatef(0.0F, 0.3125F, 0.0F); + GL11.glRotatef(90F, 0.0F, 1.0F, 0.0F); + if(entityminecart.minecartType == 1) + { + (new RenderBlocks()).func_1227_a(Block.crate, 0); + } else + if(entityminecart.minecartType == 2) + { + (new RenderBlocks()).func_1227_a(Block.stoneOvenIdle, 0); + } + GL11.glRotatef(-90F, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(0.0F, -0.3125F, 0.0F); + GL11.glScalef(1.0F / f5, 1.0F / f5, 1.0F / f5); + } + loadTexture("/item/cart.png"); + GL11.glScalef(-1F, -1F, 1.0F); + modelMinecart.render(0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_152_a((EntityMinecart)entity, d, d1, d2, f, f1); + } + + protected ModelBase modelMinecart; +} diff --git a/src/main/java/net/minecraft/src/RenderPainting.java b/src/main/java/net/minecraft/src/RenderPainting.java new file mode 100644 index 0000000..0b75423 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderPainting.java @@ -0,0 +1,136 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; +import org.lwjgl.opengl.GL11; + +public class RenderPainting extends Render +{ + + public RenderPainting() + { + rand = new Random(); + } + + public void func_158_a(EntityPainting entitypainting, double d, double d1, double d2, + float f, float f1) + { + rand.setSeed(187L); + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glRotatef(f, 0.0F, 1.0F, 0.0F); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + loadTexture("/art/kz.png"); + EnumArt enumart = entitypainting.art; + float f2 = 0.0625F; + GL11.glScalef(f2, f2, f2); + func_159_a(entitypainting, enumart.sizeX, enumart.sizeY, enumart.offsetX, enumart.offsetY); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPopMatrix(); + } + + private void func_159_a(EntityPainting entitypainting, int i, int j, int k, int l) + { + float f = (float)(-i) / 2.0F; + float f1 = (float)(-j) / 2.0F; + float f2 = -0.5F; + float f3 = 0.5F; + for(int i1 = 0; i1 < i / 16; i1++) + { + for(int j1 = 0; j1 < j / 16; j1++) + { + float f4 = f + (float)((i1 + 1) * 16); + float f5 = f + (float)(i1 * 16); + float f6 = f1 + (float)((j1 + 1) * 16); + float f7 = f1 + (float)(j1 * 16); + func_160_a(entitypainting, (f4 + f5) / 2.0F, (f6 + f7) / 2.0F); + float f8 = (float)((k + i) - i1 * 16) / 256F; + float f9 = (float)((k + i) - (i1 + 1) * 16) / 256F; + float f10 = (float)((l + j) - j1 * 16) / 256F; + float f11 = (float)((l + j) - (j1 + 1) * 16) / 256F; + float f12 = 0.75F; + float f13 = 0.8125F; + float f14 = 0.0F; + float f15 = 0.0625F; + float f16 = 0.75F; + float f17 = 0.8125F; + float f18 = 0.001953125F; + float f19 = 0.001953125F; + float f20 = 0.7519531F; + float f21 = 0.7519531F; + float f22 = 0.0F; + float f23 = 0.0625F; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 0.0F, -1F); + tessellator.addVertexWithUV(f4, f7, f2, f9, f10); + tessellator.addVertexWithUV(f5, f7, f2, f8, f10); + tessellator.addVertexWithUV(f5, f6, f2, f8, f11); + tessellator.addVertexWithUV(f4, f6, f2, f9, f11); + tessellator.setNormal(0.0F, 0.0F, 1.0F); + tessellator.addVertexWithUV(f4, f6, f3, f12, f14); + tessellator.addVertexWithUV(f5, f6, f3, f13, f14); + tessellator.addVertexWithUV(f5, f7, f3, f13, f15); + tessellator.addVertexWithUV(f4, f7, f3, f12, f15); + tessellator.setNormal(0.0F, -1F, 0.0F); + tessellator.addVertexWithUV(f4, f6, f2, f16, f18); + tessellator.addVertexWithUV(f5, f6, f2, f17, f18); + tessellator.addVertexWithUV(f5, f6, f3, f17, f19); + tessellator.addVertexWithUV(f4, f6, f3, f16, f19); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV(f4, f7, f3, f16, f18); + tessellator.addVertexWithUV(f5, f7, f3, f17, f18); + tessellator.addVertexWithUV(f5, f7, f2, f17, f19); + tessellator.addVertexWithUV(f4, f7, f2, f16, f19); + tessellator.setNormal(-1F, 0.0F, 0.0F); + tessellator.addVertexWithUV(f4, f6, f3, f21, f22); + tessellator.addVertexWithUV(f4, f7, f3, f21, f23); + tessellator.addVertexWithUV(f4, f7, f2, f20, f23); + tessellator.addVertexWithUV(f4, f6, f2, f20, f22); + tessellator.setNormal(1.0F, 0.0F, 0.0F); + tessellator.addVertexWithUV(f5, f6, f2, f21, f22); + tessellator.addVertexWithUV(f5, f7, f2, f21, f23); + tessellator.addVertexWithUV(f5, f7, f3, f20, f23); + tessellator.addVertexWithUV(f5, f6, f3, f20, f22); + tessellator.draw(); + } + + } + + } + + private void func_160_a(EntityPainting entitypainting, float f, float f1) + { + int i = MathHelper.floor_double(entitypainting.posX); + int j = MathHelper.floor_double(entitypainting.posY + (double)(f1 / 16F)); + int k = MathHelper.floor_double(entitypainting.posZ); + if(entitypainting.direction == 0) + { + i = MathHelper.floor_double(entitypainting.posX + (double)(f / 16F)); + } + if(entitypainting.direction == 1) + { + k = MathHelper.floor_double(entitypainting.posZ - (double)(f / 16F)); + } + if(entitypainting.direction == 2) + { + i = MathHelper.floor_double(entitypainting.posX - (double)(f / 16F)); + } + if(entitypainting.direction == 3) + { + k = MathHelper.floor_double(entitypainting.posZ + (double)(f / 16F)); + } + float f2 = renderManager.worldObj.getLightBrightness(i, j, k); + GL11.glColor3f(f2, f2, f2); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_158_a((EntityPainting)entity, d, d1, d2, f, f1); + } + + private Random rand; +} diff --git a/src/main/java/net/minecraft/src/RenderPig.java b/src/main/java/net/minecraft/src/RenderPig.java new file mode 100644 index 0000000..e5b2541 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderPig.java @@ -0,0 +1,26 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class RenderPig extends RenderLiving +{ + + public RenderPig(ModelBase modelbase, ModelBase modelbase1, float f) + { + super(modelbase, f); + setRenderPassModel(modelbase1); + } + + protected boolean renderSaddledPig(EntityPig entitypig, int i, float f) + { + loadTexture("/mob/saddle.png"); + return i == 0 && entitypig.func_21068_q(); + } + + protected boolean shouldRenderPass(EntityLiving entityliving, int i, float f) + { + return renderSaddledPig((EntityPig)entityliving, i, f); + } +} diff --git a/src/main/java/net/minecraft/src/RenderPlayer.java b/src/main/java/net/minecraft/src/RenderPlayer.java new file mode 100644 index 0000000..b3cf523 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderPlayer.java @@ -0,0 +1,313 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class RenderPlayer extends RenderLiving +{ + + public RenderPlayer() + { + super(new ModelBiped(0.0F), 0.5F); + modelBipedMain = (ModelBiped)mainModel; + modelArmorChestplate = new ModelBiped(1.0F); + modelArmor = new ModelBiped(0.5F); + } + + protected boolean setArmorModel(EntityPlayer entityplayer, int i, float f) + { + ItemStack itemstack = entityplayer.inventory.armorItemInSlot(3 - i); + if(itemstack != null) + { + Item item = itemstack.getItem(); + if(item instanceof ItemArmor) + { + ItemArmor itemarmor = (ItemArmor)item; + loadTexture((new StringBuilder()).append("/armor/").append(armorFilenamePrefix[itemarmor.renderIndex]).append("_").append(i != 2 ? 1 : 2).append(".png").toString()); + ModelBiped modelbiped = i != 2 ? modelArmorChestplate : modelArmor; + modelbiped.bipedHead.showModel = i == 0; + modelbiped.bipedHeadwear.showModel = i == 0; + modelbiped.bipedBody.showModel = i == 1 || i == 2; + modelbiped.bipedRightArm.showModel = i == 1; + modelbiped.bipedLeftArm.showModel = i == 1; + modelbiped.bipedRightLeg.showModel = i == 2 || i == 3; + modelbiped.bipedLeftLeg.showModel = i == 2 || i == 3; + setRenderPassModel(modelbiped); + return true; + } + } + return false; + } + + public void func_188_a(EntityPlayer entityplayer, double d, double d1, double d2, + float f, float f1) + { + ItemStack itemstack = entityplayer.inventory.getCurrentItem(); + modelArmorChestplate.field_1278_i = modelArmor.field_1278_i = modelBipedMain.field_1278_i = itemstack != null; + modelArmorChestplate.isSneak = modelArmor.isSneak = modelBipedMain.isSneak = entityplayer.isSneaking(); + double d3 = d1 - (double)entityplayer.yOffset; + if(entityplayer.isSneaking()) + { + d3 -= 0.125D; + } + super.doRenderLiving(entityplayer, d, d3, d2, f, f1); + modelArmorChestplate.isSneak = modelArmor.isSneak = modelBipedMain.isSneak = false; + modelArmorChestplate.field_1278_i = modelArmor.field_1278_i = modelBipedMain.field_1278_i = false; + } + + protected void func_22015_a(EntityPlayer entityplayer, double d, double d1, double d2) + { + if(Minecraft.func_22006_t() && entityplayer != renderManager.field_22188_h) + { + float f = 1.6F; + float f1 = 0.01666667F * f; + float f2 = entityplayer.getDistanceToEntity(renderManager.field_22188_h); + float f3 = entityplayer.isSneaking() ? 32F : 64F; + if(f2 < f3) + { + String s = entityplayer.username; + if(!entityplayer.isSneaking()) + { + func_22013_a(entityplayer, s, d, d1, d2, 64); + } else + { + FontRenderer fontrenderer = getFontRendererFromRenderManager(); + GL11.glPushMatrix(); + GL11.glTranslatef((float)d + 0.0F, (float)d1 + 2.3F, (float)d2); + GL11.glNormal3f(0.0F, 1.0F, 0.0F); + GL11.glRotatef(-renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(renderManager.playerViewX, 1.0F, 0.0F, 0.0F); + GL11.glScalef(-f1, -f1, f1); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glTranslatef(0.0F, 0.25F / f1, 0.0F); + GL11.glDepthMask(false); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + Tessellator tessellator = Tessellator.instance; + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + tessellator.startDrawingQuads(); + int i = fontrenderer.getStringWidth(s) / 2; + tessellator.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F); + tessellator.addVertex(-i - 1, -1D, 0.0D); + tessellator.addVertex(-i - 1, 8D, 0.0D); + tessellator.addVertex(i + 1, 8D, 0.0D); + tessellator.addVertex(i + 1, -1D, 0.0D); + tessellator.draw(); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + GL11.glDepthMask(true); + fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, 0, 0x20ffffff); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + } + } + } + + protected void func_4015_a(EntityPlayer entityplayer, float f) + { + ItemStack itemstack = entityplayer.inventory.armorItemInSlot(3); + if(itemstack != null && itemstack.getItem().shiftedIndex < 256) + { + GL11.glPushMatrix(); + modelBipedMain.bipedHead.func_926_b(0.0625F); + if(RenderBlocks.func_1219_a(Block.blocksList[itemstack.itemID].getRenderType())) + { + float f1 = 0.625F; + GL11.glTranslatef(0.0F, -0.25F, 0.0F); + GL11.glRotatef(180F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f1, -f1, f1); + } + renderManager.itemRenderer.renderItem(itemstack); + GL11.glPopMatrix(); + } + if(entityplayer.username.equals("deadmau5") && loadDownloadableImageTexture(entityplayer.skinUrl, null)) + { + for(int i = 0; i < 2; i++) + { + float f2 = (entityplayer.prevRotationYaw + (entityplayer.rotationYaw - entityplayer.prevRotationYaw) * f) - (entityplayer.prevRenderYawOffset + (entityplayer.renderYawOffset - entityplayer.prevRenderYawOffset) * f); + float f6 = entityplayer.prevRotationPitch + (entityplayer.rotationPitch - entityplayer.prevRotationPitch) * f; + GL11.glPushMatrix(); + GL11.glRotatef(f2, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(f6, 1.0F, 0.0F, 0.0F); + GL11.glTranslatef(0.375F * (float)(i * 2 - 1), 0.0F, 0.0F); + GL11.glTranslatef(0.0F, -0.375F, 0.0F); + GL11.glRotatef(-f6, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(-f2, 0.0F, 1.0F, 0.0F); + float f7 = 1.333333F; + GL11.glScalef(f7, f7, f7); + modelBipedMain.renderEars(0.0625F); + GL11.glPopMatrix(); + } + + } + if(loadDownloadableImageTexture(entityplayer.field_20067_q, null)) + { + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, 0.0F, 0.125F); + double d = (entityplayer.field_20066_r + (entityplayer.field_20063_u - entityplayer.field_20066_r) * (double)f) - (entityplayer.prevPosX + (entityplayer.posX - entityplayer.prevPosX) * (double)f); + double d1 = (entityplayer.field_20065_s + (entityplayer.field_20062_v - entityplayer.field_20065_s) * (double)f) - (entityplayer.prevPosY + (entityplayer.posY - entityplayer.prevPosY) * (double)f); + double d2 = (entityplayer.field_20064_t + (entityplayer.field_20061_w - entityplayer.field_20064_t) * (double)f) - (entityplayer.prevPosZ + (entityplayer.posZ - entityplayer.prevPosZ) * (double)f); + float f8 = entityplayer.prevRenderYawOffset + (entityplayer.renderYawOffset - entityplayer.prevRenderYawOffset) * f; + double d3 = MathHelper.sin((f8 * 3.141593F) / 180F); + double d4 = -MathHelper.cos((f8 * 3.141593F) / 180F); + float f9 = (float)d1 * 10F; + if(f9 < -6F) + { + f9 = -6F; + } + if(f9 > 32F) + { + f9 = 32F; + } + float f10 = (float)(d * d3 + d2 * d4) * 100F; + float f11 = (float)(d * d4 - d2 * d3) * 100F; + if(f10 < 0.0F) + { + f10 = 0.0F; + } + float f12 = entityplayer.field_775_e + (entityplayer.field_774_f - entityplayer.field_775_e) * f; + f9 += MathHelper.sin((entityplayer.prevDistanceWalkedModified + (entityplayer.distanceWalkedModified - entityplayer.prevDistanceWalkedModified) * f) * 6F) * 32F * f12; + GL11.glRotatef(6F + f10 / 2.0F + f9, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(f11 / 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-f11 / 2.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(180F, 0.0F, 1.0F, 0.0F); + modelBipedMain.renderCloak(0.0625F); + GL11.glPopMatrix(); + } + ItemStack itemstack1 = entityplayer.inventory.getCurrentItem(); + if(itemstack1 != null) + { + GL11.glPushMatrix(); + modelBipedMain.bipedRightArm.func_926_b(0.0625F); + GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F); + if(entityplayer.fishEntity != null) + { + itemstack1 = new ItemStack(Item.stick); + } + if(itemstack1.itemID < 256 && RenderBlocks.func_1219_a(Block.blocksList[itemstack1.itemID].getRenderType())) + { + float f3 = 0.5F; + GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); + f3 *= 0.75F; + GL11.glRotatef(20F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f3, -f3, f3); + } else + if(Item.itemsList[itemstack1.itemID].isFull3D()) + { + float f4 = 0.625F; + if(Item.itemsList[itemstack1.itemID].shouldRotateAroundWhenRendering()) + { + GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0F, -0.125F, 0.0F); + } + GL11.glTranslatef(0.0F, 0.1875F, 0.0F); + GL11.glScalef(f4, -f4, f4); + GL11.glRotatef(-100F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F); + } else + { + float f5 = 0.375F; + GL11.glTranslatef(0.25F, 0.1875F, -0.1875F); + GL11.glScalef(f5, f5, f5); + GL11.glRotatef(60F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-90F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(20F, 0.0F, 0.0F, 1.0F); + } + renderManager.itemRenderer.renderItem(itemstack1); + GL11.glPopMatrix(); + } + } + + protected void func_186_b(EntityPlayer entityplayer, float f) + { + float f1 = 0.9375F; + GL11.glScalef(f1, f1, f1); + } + + public void drawFirstPersonHand() + { + modelBipedMain.onGround = 0.0F; + modelBipedMain.setRotationAngles(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F); + modelBipedMain.bipedRightArm.render(0.0625F); + } + + protected void func_22016_b(EntityPlayer entityplayer, double d, double d1, double d2) + { + if(entityplayer.isEntityAlive() && entityplayer.isPlayerSleeping()) + { + super.func_22012_b(entityplayer, d + (double)entityplayer.field_22063_x, d1 + (double)entityplayer.field_22062_y, d2 + (double)entityplayer.field_22061_z); + } else + { + super.func_22012_b(entityplayer, d, d1, d2); + } + } + + protected void func_22017_a(EntityPlayer entityplayer, float f, float f1, float f2) + { + if(entityplayer.isEntityAlive() && entityplayer.isPlayerSleeping()) + { + GL11.glRotatef(entityplayer.func_22059_J(), 0.0F, 1.0F, 0.0F); + GL11.glRotatef(func_172_a(entityplayer), 0.0F, 0.0F, 1.0F); + GL11.glRotatef(270F, 0.0F, 1.0F, 0.0F); + } else + { + super.func_21004_a(entityplayer, f, f1, f2); + } + } + + protected void func_22014_a(EntityLiving entityliving, double d, double d1, double d2) + { + func_22015_a((EntityPlayer)entityliving, d, d1, d2); + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + func_186_b((EntityPlayer)entityliving, f); + } + + protected boolean shouldRenderPass(EntityLiving entityliving, int i, float f) + { + return setArmorModel((EntityPlayer)entityliving, i, f); + } + + protected void renderEquippedItems(EntityLiving entityliving, float f) + { + func_4015_a((EntityPlayer)entityliving, f); + } + + protected void func_21004_a(EntityLiving entityliving, float f, float f1, float f2) + { + func_22017_a((EntityPlayer)entityliving, f, f1, f2); + } + + protected void func_22012_b(EntityLiving entityliving, double d, double d1, double d2) + { + func_22016_b((EntityPlayer)entityliving, d, d1, d2); + } + + public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, + float f, float f1) + { + func_188_a((EntityPlayer)entityliving, d, d1, d2, f, f1); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_188_a((EntityPlayer)entity, d, d1, d2, f, f1); + } + + private ModelBiped modelBipedMain; + private ModelBiped modelArmorChestplate; + private ModelBiped modelArmor; + private static final String armorFilenamePrefix[] = { + "cloth", "chain", "iron", "diamond", "gold" + }; + +} diff --git a/src/main/java/net/minecraft/src/RenderSheep.java b/src/main/java/net/minecraft/src/RenderSheep.java new file mode 100644 index 0000000..86a9eb2 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderSheep.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderSheep extends RenderLiving +{ + + public RenderSheep(ModelBase modelbase, ModelBase modelbase1, float f) + { + super(modelbase, f); + setRenderPassModel(modelbase1); + } + + protected boolean func_176_a(EntitySheep entitysheep, int i, float f) + { + if(i == 0 && !entitysheep.func_21072_p()) + { + loadTexture("/mob/sheep_fur.png"); + float f1 = entitysheep.getEntityBrightness(f); + int j = entitysheep.getFleeceColor(); + GL11.glColor3f(f1 * EntitySheep.field_21075_a[j][0], f1 * EntitySheep.field_21075_a[j][1], f1 * EntitySheep.field_21075_a[j][2]); + return true; + } else + { + return false; + } + } + + protected boolean shouldRenderPass(EntityLiving entityliving, int i, float f) + { + return func_176_a((EntitySheep)entityliving, i, f); + } +} diff --git a/src/main/java/net/minecraft/src/RenderSlime.java b/src/main/java/net/minecraft/src/RenderSlime.java new file mode 100644 index 0000000..fcebd28 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderSlime.java @@ -0,0 +1,54 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderSlime extends RenderLiving +{ + + public RenderSlime(ModelBase modelbase, ModelBase modelbase1, float f) + { + super(modelbase, f); + scaleAmount = modelbase1; + } + + protected boolean func_179_a(EntitySlime entityslime, int i, float f) + { + if(i == 0) + { + setRenderPassModel(scaleAmount); + GL11.glEnable(2977 /*GL_NORMALIZE*/); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 771); + return true; + } + if(i == 1) + { + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + return false; + } + + protected void func_178_a(EntitySlime entityslime, float f) + { + float f1 = (entityslime.field_767_b + (entityslime.field_768_a - entityslime.field_767_b) * f) / ((float)entityslime.slimeSize * 0.5F + 1.0F); + float f2 = 1.0F / (f1 + 1.0F); + float f3 = entityslime.slimeSize; + GL11.glScalef(f2 * f3, (1.0F / f2) * f3, f2 * f3); + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + func_178_a((EntitySlime)entityliving, f); + } + + protected boolean shouldRenderPass(EntityLiving entityliving, int i, float f) + { + return func_179_a((EntitySlime)entityliving, i, f); + } + + private ModelBase scaleAmount; +} diff --git a/src/main/java/net/minecraft/src/RenderSnowball.java b/src/main/java/net/minecraft/src/RenderSnowball.java new file mode 100644 index 0000000..f83740d --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderSnowball.java @@ -0,0 +1,46 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderSnowball extends Render +{ + + public RenderSnowball(int i) + { + field_20003_a = i; + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + GL11.glEnable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glScalef(0.5F, 0.5F, 0.5F); + loadTexture("/gui/items.png"); + Tessellator tessellator = Tessellator.instance; + float f2 = (float)((field_20003_a % 16) * 16 + 0) / 256F; + float f3 = (float)((field_20003_a % 16) * 16 + 16) / 256F; + float f4 = (float)((field_20003_a / 16) * 16 + 0) / 256F; + float f5 = (float)((field_20003_a / 16) * 16 + 16) / 256F; + float f6 = 1.0F; + float f7 = 0.5F; + float f8 = 0.25F; + GL11.glRotatef(180F - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-renderManager.playerViewX, 1.0F, 0.0F, 0.0F); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV(0.0F - f7, 0.0F - f8, 0.0D, f2, f5); + tessellator.addVertexWithUV(f6 - f7, 0.0F - f8, 0.0D, f3, f5); + tessellator.addVertexWithUV(f6 - f7, 1.0F - f8, 0.0D, f3, f4); + tessellator.addVertexWithUV(0.0F - f7, 1.0F - f8, 0.0D, f2, f4); + tessellator.draw(); + GL11.glDisable(32826 /*GL_RESCALE_NORMAL_EXT*/); + GL11.glPopMatrix(); + } + + private int field_20003_a; +} diff --git a/src/main/java/net/minecraft/src/RenderSorter.java b/src/main/java/net/minecraft/src/RenderSorter.java new file mode 100644 index 0000000..57b6960 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderSorter.java @@ -0,0 +1,50 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Comparator; + +public class RenderSorter + implements Comparator +{ + + public RenderSorter(EntityLiving entityliving) + { + field_4274_a = entityliving; + } + + public int func_993_a(WorldRenderer worldrenderer, WorldRenderer worldrenderer1) + { + boolean flag = worldrenderer.isInFrustum; + boolean flag1 = worldrenderer1.isInFrustum; + if(flag && !flag1) + { + return 1; + } + if(flag1 && !flag) + { + return -1; + } + double d = worldrenderer.distanceToEntity(field_4274_a); + double d1 = worldrenderer1.distanceToEntity(field_4274_a); + if(d < d1) + { + return 1; + } + if(d > d1) + { + return -1; + } else + { + return worldrenderer.field_1735_w >= worldrenderer1.field_1735_w ? -1 : 1; + } + } + + public int compare(Object obj, Object obj1) + { + return func_993_a((WorldRenderer)obj, (WorldRenderer)obj1); + } + + private EntityLiving field_4274_a; +} diff --git a/src/main/java/net/minecraft/src/RenderSpider.java b/src/main/java/net/minecraft/src/RenderSpider.java new file mode 100644 index 0000000..660a68a --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderSpider.java @@ -0,0 +1,52 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderSpider extends RenderLiving +{ + + public RenderSpider() + { + super(new ModelSpider(), 1.0F); + setRenderPassModel(new ModelSpider()); + } + + protected float func_191_a(EntitySpider entityspider) + { + return 180F; + } + + protected boolean func_190_a(EntitySpider entityspider, int i, float f) + { + if(i != 0) + { + return false; + } + if(i != 0) + { + return false; + } else + { + loadTexture("/mob/spider_eyes.png"); + float f1 = (1.0F - entityspider.getEntityBrightness(1.0F)) * 0.5F; + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glDisable(3008 /*GL_ALPHA_TEST*/); + GL11.glBlendFunc(770, 771); + GL11.glColor4f(1.0F, 1.0F, 1.0F, f1); + return true; + } + } + + protected float func_172_a(EntityLiving entityliving) + { + return func_191_a((EntitySpider)entityliving); + } + + protected boolean shouldRenderPass(EntityLiving entityliving, int i, float f) + { + return func_190_a((EntitySpider)entityliving, i, f); + } +} diff --git a/src/main/java/net/minecraft/src/RenderSquid.java b/src/main/java/net/minecraft/src/RenderSquid.java new file mode 100644 index 0000000..3885624 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderSquid.java @@ -0,0 +1,69 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderSquid extends RenderLiving +{ + + public RenderSquid(ModelBase modelbase, float f) + { + super(modelbase, f); + } + + public void func_21008_a(EntitySquid entitysquid, double d, double d1, double d2, + float f, float f1) + { + super.doRenderLiving(entitysquid, d, d1, d2, f, f1); + } + + protected void func_21007_a(EntitySquid entitysquid, float f, float f1, float f2) + { + float f3 = entitysquid.field_21088_b + (entitysquid.field_21089_a - entitysquid.field_21088_b) * f2; + float f4 = entitysquid.field_21086_f + (entitysquid.field_21087_c - entitysquid.field_21086_f) * f2; + GL11.glTranslatef(0.0F, 0.5F, 0.0F); + GL11.glRotatef(180F - f1, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(f3, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(f4, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(0.0F, -1.2F, 0.0F); + } + + protected void func_21005_a(EntitySquid entitysquid, float f) + { + } + + protected float func_21006_b(EntitySquid entitysquid, float f) + { + float f1 = entitysquid.field_21082_j + (entitysquid.field_21083_i - entitysquid.field_21082_j) * f; + return f1; + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + func_21005_a((EntitySquid)entityliving, f); + } + + protected float func_170_d(EntityLiving entityliving, float f) + { + return func_21006_b((EntitySquid)entityliving, f); + } + + protected void func_21004_a(EntityLiving entityliving, float f, float f1, float f2) + { + func_21007_a((EntitySquid)entityliving, f, f1, f2); + } + + public void doRenderLiving(EntityLiving entityliving, double d, double d1, double d2, + float f, float f1) + { + func_21008_a((EntitySquid)entityliving, d, d1, d2, f, f1); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_21008_a((EntitySquid)entity, d, d1, d2, f, f1); + } +} diff --git a/src/main/java/net/minecraft/src/RenderTNTPrimed.java b/src/main/java/net/minecraft/src/RenderTNTPrimed.java new file mode 100644 index 0000000..9706cfb --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderTNTPrimed.java @@ -0,0 +1,64 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderTNTPrimed extends Render +{ + + public RenderTNTPrimed() + { + field_196_d = new RenderBlocks(); + shadowSize = 0.5F; + } + + public void func_153_a(EntityTNTPrimed entitytntprimed, double d, double d1, double d2, + float f, float f1) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d, (float)d1, (float)d2); + if(((float)entitytntprimed.fuse - f1) + 1.0F < 10F) + { + float f2 = 1.0F - (((float)entitytntprimed.fuse - f1) + 1.0F) / 10F; + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f2 > 1.0F) + { + f2 = 1.0F; + } + f2 *= f2; + f2 *= f2; + float f4 = 1.0F + f2 * 0.3F; + GL11.glScalef(f4, f4, f4); + } + float f3 = (1.0F - (((float)entitytntprimed.fuse - f1) + 1.0F) / 100F) * 0.8F; + loadTexture("/terrain.png"); + field_196_d.func_1227_a(Block.tnt, 0); + if((entitytntprimed.fuse / 5) % 2 == 0) + { + GL11.glDisable(3553 /*GL_TEXTURE_2D*/); + GL11.glDisable(2896 /*GL_LIGHTING*/); + GL11.glEnable(3042 /*GL_BLEND*/); + GL11.glBlendFunc(770, 772); + GL11.glColor4f(1.0F, 1.0F, 1.0F, f3); + field_196_d.func_1227_a(Block.tnt, 0); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glEnable(2896 /*GL_LIGHTING*/); + GL11.glEnable(3553 /*GL_TEXTURE_2D*/); + } + GL11.glPopMatrix(); + } + + public void doRender(Entity entity, double d, double d1, double d2, + float f, float f1) + { + func_153_a((EntityTNTPrimed)entity, d, d1, d2, f, f1); + } + + private RenderBlocks field_196_d; +} diff --git a/src/main/java/net/minecraft/src/RenderZombieSimple.java b/src/main/java/net/minecraft/src/RenderZombieSimple.java new file mode 100644 index 0000000..93f4980 --- /dev/null +++ b/src/main/java/net/minecraft/src/RenderZombieSimple.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class RenderZombieSimple extends RenderLiving +{ + + public RenderZombieSimple(ModelBase modelbase, float f, float f1) + { + super(modelbase, f * f1); + scale = f1; + } + + protected void preRenderScale(EntityZombieSimple entityzombiesimple, float f) + { + GL11.glScalef(scale, scale, scale); + } + + protected void preRenderCallback(EntityLiving entityliving, float f) + { + preRenderScale((EntityZombieSimple)entityliving, f); + } + + private float scale; +} diff --git a/src/main/java/net/minecraft/src/SaveConverterMcRegion.java b/src/main/java/net/minecraft/src/SaveConverterMcRegion.java new file mode 100644 index 0000000..8cdd944 --- /dev/null +++ b/src/main/java/net/minecraft/src/SaveConverterMcRegion.java @@ -0,0 +1,184 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.*; +import java.util.zip.GZIPInputStream; + +public class SaveConverterMcRegion extends SaveFormatOld +{ + + public SaveConverterMcRegion(File file) + { + super(file); + } + + public String func_22178_a() + { + return "Scaevolus' McRegion"; + } + + public List func_22176_b() + { + ArrayList arraylist = new ArrayList(); + File afile[] = field_22180_a.listFiles(); + File afile1[] = afile; + int i = afile1.length; + for(int j = 0; j < i; j++) + { + File file = afile1[j]; + if(!file.isDirectory()) + { + continue; + } + String s = file.getName(); + WorldInfo worldinfo = func_22173_b(s); + if(worldinfo == null) + { + continue; + } + boolean flag = worldinfo.func_22296_k() != 19132; + String s1 = worldinfo.getWorldName(); + if(s1 == null || MathHelper.func_22282_a(s1)) + { + s1 = s; + } + arraylist.add(new SaveFormatComparator(s, s1, worldinfo.func_22301_l(), worldinfo.func_22306_g(), flag)); + } + + return arraylist; + } + + public void func_22177_c() + { + RegionFileCache.func_22192_a(); + } + + public ISaveHandler func_22174_a(String s, boolean flag) + { + return new SaveOldDir(field_22180_a, s, flag); + } + + public boolean func_22175_a(String s) + { + WorldInfo worldinfo = func_22173_b(s); + return worldinfo != null && worldinfo.func_22296_k() == 0; + } + + public boolean func_22171_a(String s, IProgressUpdate iprogressupdate) + { + iprogressupdate.setLoadingProgress(0); + ArrayList arraylist = new ArrayList(); + ArrayList arraylist1 = new ArrayList(); + ArrayList arraylist2 = new ArrayList(); + ArrayList arraylist3 = new ArrayList(); + File file = new File(field_22180_a, s); + File file1 = new File(file, "DIM-1"); + System.out.println("Scanning folders..."); + func_22183_a(file, arraylist, arraylist1); + if(file1.exists()) + { + func_22183_a(file1, arraylist2, arraylist3); + } + int i = arraylist.size() + arraylist2.size() + arraylist1.size() + arraylist3.size(); + System.out.println((new StringBuilder()).append("Total conversion count is ").append(i).toString()); + func_22181_a(file, arraylist, 0, i, iprogressupdate); + func_22181_a(file1, arraylist2, arraylist.size(), i, iprogressupdate); + WorldInfo worldinfo = func_22173_b(s); + worldinfo.func_22289_d(19132); + ISaveHandler isavehandler = func_22174_a(s, false); + isavehandler.func_22152_a(worldinfo); + func_22182_a(arraylist1, arraylist.size() + arraylist2.size(), i, iprogressupdate); + if(file1.exists()) + { + func_22182_a(arraylist3, arraylist.size() + arraylist2.size() + arraylist1.size(), i, iprogressupdate); + } + return true; + } + + private void func_22183_a(File file, ArrayList arraylist, ArrayList arraylist1) + { + ChunkFolderPattern chunkfolderpattern = new ChunkFolderPattern(null); + ChunkFilePattern chunkfilepattern = new ChunkFilePattern(null); + File afile[] = file.listFiles(chunkfolderpattern); + File afile1[] = afile; + int i = afile1.length; + for(int j = 0; j < i; j++) + { + File file1 = afile1[j]; + arraylist1.add(file1); + File afile2[] = file1.listFiles(chunkfolderpattern); + File afile3[] = afile2; + int k = afile3.length; + for(int l = 0; l < k; l++) + { + File file2 = afile3[l]; + File afile4[] = file2.listFiles(chunkfilepattern); + File afile5[] = afile4; + int i1 = afile5.length; + for(int j1 = 0; j1 < i1; j1++) + { + File file3 = afile5[j1]; + arraylist.add(new FileMatcher(file3)); + } + + } + + } + + } + + private void func_22181_a(File file, ArrayList arraylist, int i, int j, IProgressUpdate iprogressupdate) + { + Collections.sort(arraylist); + byte abyte0[] = new byte[4096]; + int i1; + for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); iprogressupdate.setLoadingProgress(i1)) + { + FileMatcher filematcher = (FileMatcher)iterator.next(); + int k = filematcher.func_22323_b(); + int l = filematcher.func_22321_c(); + RegionFile regionfile = RegionFileCache.func_22193_a(file, k, l); + if(!regionfile.func_22202_c(k & 0x1f, l & 0x1f)) + { + try + { + DataInputStream datainputstream = new DataInputStream(new GZIPInputStream(new FileInputStream(filematcher.func_22324_a()))); + DataOutputStream dataoutputstream = regionfile.func_22205_b(k & 0x1f, l & 0x1f); + for(int j1 = 0; (j1 = datainputstream.read(abyte0)) != -1;) + { + dataoutputstream.write(abyte0, 0, j1); + } + + dataoutputstream.close(); + datainputstream.close(); + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + i++; + i1 = (int)Math.round((100D * (double)i) / (double)j); + } + + RegionFileCache.func_22192_a(); + } + + private void func_22182_a(ArrayList arraylist, int i, int j, IProgressUpdate iprogressupdate) + { + int k; + for(Iterator iterator = arraylist.iterator(); iterator.hasNext(); iprogressupdate.setLoadingProgress(k)) + { + File file = (File)iterator.next(); + File afile[] = file.listFiles(); + func_22179_a(afile); + file.delete(); + i++; + k = (int)Math.round((100D * (double)i) / (double)j); + } + + } +} diff --git a/src/main/java/net/minecraft/src/SaveFormatComparator.java b/src/main/java/net/minecraft/src/SaveFormatComparator.java new file mode 100644 index 0000000..6186242 --- /dev/null +++ b/src/main/java/net/minecraft/src/SaveFormatComparator.java @@ -0,0 +1,70 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class SaveFormatComparator + implements Comparable +{ + + public SaveFormatComparator(String s, String s1, long l, long l1, boolean flag) + { + field_22166_a = s; + field_22165_b = s1; + field_22169_c = l; + field_22168_d = l1; + field_22167_e = flag; + } + + public String func_22164_a() + { + return field_22166_a; + } + + public String func_22162_b() + { + return field_22165_b; + } + + public long func_22159_c() + { + return field_22168_d; + } + + public boolean func_22161_d() + { + return field_22167_e; + } + + public long func_22163_e() + { + return field_22169_c; + } + + public int func_22160_a(SaveFormatComparator saveformatcomparator) + { + if(field_22169_c < saveformatcomparator.field_22169_c) + { + return 1; + } + if(field_22169_c > saveformatcomparator.field_22169_c) + { + return -1; + } else + { + return field_22166_a.compareTo(saveformatcomparator.field_22166_a); + } + } + + public int compareTo(Object obj) + { + return func_22160_a((SaveFormatComparator)obj); + } + + private final String field_22166_a; + private final String field_22165_b; + private final long field_22169_c; + private final long field_22168_d; + private final boolean field_22167_e; +} diff --git a/src/main/java/net/minecraft/src/SaveFormatOld.java b/src/main/java/net/minecraft/src/SaveFormatOld.java new file mode 100644 index 0000000..6568866 --- /dev/null +++ b/src/main/java/net/minecraft/src/SaveFormatOld.java @@ -0,0 +1,139 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class SaveFormatOld + implements ISaveFormat +{ + + public SaveFormatOld(File file) + { + if(!file.exists()) + { + file.mkdirs(); + } + field_22180_a = file; + } + + public String func_22178_a() + { + return "Old Format"; + } + + public List func_22176_b() + { + ArrayList arraylist = new ArrayList(); + for(int i = 0; i < 5; i++) + { + String s = (new StringBuilder()).append("World").append(i + 1).toString(); + WorldInfo worldinfo = func_22173_b(s); + if(worldinfo != null) + { + arraylist.add(new SaveFormatComparator(s, "", worldinfo.func_22301_l(), worldinfo.func_22306_g(), false)); + } + } + + return arraylist; + } + + public void func_22177_c() + { + } + + public WorldInfo func_22173_b(String s) + { + File file = new File(field_22180_a, s); + if(!file.exists()) + { + return null; + } + File file1 = new File(file, "level.dat"); + if(file1.exists()) + { + try + { + NBTTagCompound nbttagcompound = CompressedStreamTools.func_1138_a(new FileInputStream(file1)); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); + return new WorldInfo(nbttagcompound1); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + return null; + } + + public void func_22170_a(String s, String s1) + { + File file = new File(field_22180_a, s); + if(!file.exists()) + { + return; + } + File file1 = new File(file, "level.dat"); + if(file1.exists()) + { + try + { + NBTTagCompound nbttagcompound = CompressedStreamTools.func_1138_a(new FileInputStream(file1)); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); + nbttagcompound1.setString("LevelName", s1); + CompressedStreamTools.writeGzippedCompoundToOutputStream(nbttagcompound, new FileOutputStream(file1)); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + } + + public void func_22172_c(String s) + { + File file = new File(field_22180_a, s); + if(!file.exists()) + { + return; + } else + { + func_22179_a(file.listFiles()); + file.delete(); + return; + } + } + + protected static void func_22179_a(File afile[]) + { + for(int i = 0; i < afile.length; i++) + { + if(afile[i].isDirectory()) + { + func_22179_a(afile[i].listFiles()); + } + afile[i].delete(); + } + + } + + public ISaveHandler func_22174_a(String s, boolean flag) + { + return new SaveHandler(field_22180_a, s, flag); + } + + public boolean func_22175_a(String s) + { + return false; + } + + public boolean func_22171_a(String s, IProgressUpdate iprogressupdate) + { + return false; + } + + protected final File field_22180_a; +} diff --git a/src/main/java/net/minecraft/src/SaveHandler.java b/src/main/java/net/minecraft/src/SaveHandler.java new file mode 100644 index 0000000..dee74e5 --- /dev/null +++ b/src/main/java/net/minecraft/src/SaveHandler.java @@ -0,0 +1,178 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.*; +import java.util.List; +import java.util.logging.Logger; + +public class SaveHandler + implements ISaveHandler +{ + + public SaveHandler(File file, String s, boolean flag) + { + field_22155_b = new File(file, s); + field_22155_b.mkdirs(); + field_22158_c = new File(field_22155_b, "players"); + if(flag) + { + field_22158_c.mkdirs(); + } + func_22154_d(); + } + + private void func_22154_d() + { + try + { + File file = new File(field_22155_b, "session.lock"); + DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file)); + try + { + dataoutputstream.writeLong(field_22157_d); + } + finally + { + dataoutputstream.close(); + } + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + throw new RuntimeException("Failed to check session lock, aborting"); + } + } + + protected File func_22153_a() + { + return field_22155_b; + } + + public void func_22150_b() + { + try + { + File file = new File(field_22155_b, "session.lock"); + DataInputStream datainputstream = new DataInputStream(new FileInputStream(file)); + try + { + if(datainputstream.readLong() != field_22157_d) + { + throw new MinecraftException("The save is being accessed from another location, aborting"); + } + } + finally + { + datainputstream.close(); + } + } + catch(IOException ioexception) + { + throw new MinecraftException("Failed to check session lock, aborting"); + } + } + + public IChunkLoader func_22149_a(WorldProvider worldprovider) + { + if(worldprovider instanceof WorldProviderHell) + { + File file = new File(field_22155_b, "DIM-1"); + file.mkdirs(); + return new ChunkLoader(file, true); + } else + { + return new ChunkLoader(field_22155_b, true); + } + } + + public WorldInfo func_22151_c() + { + File file = new File(field_22155_b, "level.dat"); + if(file.exists()) + { + try + { + NBTTagCompound nbttagcompound = CompressedStreamTools.func_1138_a(new FileInputStream(file)); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); + return new WorldInfo(nbttagcompound1); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + return null; + } + + public void func_22148_a(WorldInfo worldinfo, List list) + { + NBTTagCompound nbttagcompound = worldinfo.func_22305_a(list); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setTag("Data", nbttagcompound); + try + { + File file = new File(field_22155_b, "level.dat_new"); + File file1 = new File(field_22155_b, "level.dat_old"); + File file2 = new File(field_22155_b, "level.dat"); + CompressedStreamTools.writeGzippedCompoundToOutputStream(nbttagcompound1, new FileOutputStream(file)); + if(file1.exists()) + { + file1.delete(); + } + file2.renameTo(file1); + if(file2.exists()) + { + file2.delete(); + } + file.renameTo(file2); + if(file.exists()) + { + file.delete(); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + public void func_22152_a(WorldInfo worldinfo) + { + NBTTagCompound nbttagcompound = worldinfo.func_22299_a(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setTag("Data", nbttagcompound); + try + { + File file = new File(field_22155_b, "level.dat_new"); + File file1 = new File(field_22155_b, "level.dat_old"); + File file2 = new File(field_22155_b, "level.dat"); + CompressedStreamTools.writeGzippedCompoundToOutputStream(nbttagcompound1, new FileOutputStream(file)); + if(file1.exists()) + { + file1.delete(); + } + file2.renameTo(file1); + if(file2.exists()) + { + file2.delete(); + } + file.renameTo(file2); + if(file.exists()) + { + file.delete(); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + private static final Logger field_22156_a = Logger.getLogger("Minecraft"); + private final File field_22155_b; + private final File field_22158_c; + private final long field_22157_d = System.currentTimeMillis(); + +} diff --git a/src/main/java/net/minecraft/src/SaveHandlerMP.java b/src/main/java/net/minecraft/src/SaveHandlerMP.java new file mode 100644 index 0000000..93e2c3f --- /dev/null +++ b/src/main/java/net/minecraft/src/SaveHandlerMP.java @@ -0,0 +1,37 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public class SaveHandlerMP + implements ISaveHandler +{ + + public SaveHandlerMP() + { + } + + public WorldInfo func_22151_c() + { + return null; + } + + public void func_22150_b() + { + } + + public IChunkLoader func_22149_a(WorldProvider worldprovider) + { + return null; + } + + public void func_22148_a(WorldInfo worldinfo, List list) + { + } + + public void func_22152_a(WorldInfo worldinfo) + { + } +} diff --git a/src/main/java/net/minecraft/src/SaveOldDir.java b/src/main/java/net/minecraft/src/SaveOldDir.java new file mode 100644 index 0000000..26782b8 --- /dev/null +++ b/src/main/java/net/minecraft/src/SaveOldDir.java @@ -0,0 +1,36 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.util.List; + +public class SaveOldDir extends SaveHandler +{ + + public SaveOldDir(File file, String s, boolean flag) + { + super(file, s, flag); + } + + public IChunkLoader func_22149_a(WorldProvider worldprovider) + { + File file = func_22153_a(); + if(worldprovider instanceof WorldProviderHell) + { + File file1 = new File(file, "DIM-1"); + file1.mkdirs(); + return new McRegionChunkLoader(file1); + } else + { + return new McRegionChunkLoader(file); + } + } + + public void func_22148_a(WorldInfo worldinfo, List list) + { + worldinfo.func_22289_d(19132); + super.func_22148_a(worldinfo, list); + } +} diff --git a/src/main/java/net/minecraft/src/ScaledResolution.java b/src/main/java/net/minecraft/src/ScaledResolution.java new file mode 100644 index 0000000..ab83f79 --- /dev/null +++ b/src/main/java/net/minecraft/src/ScaledResolution.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ScaledResolution +{ + + public ScaledResolution(int i, int j) + { + scaledWidth = i; + scaledHeight = j; + for(scaleFactor = 1; scaledWidth / (scaleFactor + 1) >= 320 && scaledHeight / (scaleFactor + 1) >= 240; scaleFactor++) { } + scaledWidth = scaledWidth / scaleFactor; + scaledHeight = scaledHeight / scaleFactor; + } + + public int getScaledWidth() + { + return scaledWidth; + } + + public int getScaledHeight() + { + return scaledHeight; + } + + private int scaledWidth; + private int scaledHeight; + public int scaleFactor; +} diff --git a/src/main/java/net/minecraft/src/ScreenShotHelper.java b/src/main/java/net/minecraft/src/ScreenShotHelper.java new file mode 100644 index 0000000..06b2beb --- /dev/null +++ b/src/main/java/net/minecraft/src/ScreenShotHelper.java @@ -0,0 +1,147 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.ByteBuffer; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import javax.imageio.ImageIO; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +public class ScreenShotHelper +{ + + public static String saveScreenshot(File file, int i, int j) + { + try + { + File file1 = new File(file, "screenshots"); + file1.mkdir(); + if(buffer == null || buffer.capacity() < i * j) + { + buffer = BufferUtils.createByteBuffer(i * j * 3); + } + if(imageData == null || imageData.length < i * j * 3) + { + pixelData = new byte[i * j * 3]; + imageData = new int[i * j]; + } + GL11.glPixelStorei(3333 /*GL_PACK_ALIGNMENT*/, 1); + GL11.glPixelStorei(3317 /*GL_UNPACK_ALIGNMENT*/, 1); + buffer.clear(); + GL11.glReadPixels(0, 0, i, j, 6407 /*GL_RGB*/, 5121 /*GL_UNSIGNED_BYTE*/, buffer); + buffer.clear(); + String s = (new StringBuilder()).append("").append(dateFormat.format(new Date())).toString(); + File file2; + for(int k = 1; (file2 = new File(file1, (new StringBuilder()).append(s).append(k != 1 ? (new StringBuilder()).append("_").append(k).toString() : "").append(".png").toString())).exists(); k++) { } + buffer.get(pixelData); + for(int l = 0; l < i; l++) + { + for(int i1 = 0; i1 < j; i1++) + { + int j1 = l + (j - i1 - 1) * i; + int k1 = pixelData[j1 * 3 + 0] & 0xff; + int l1 = pixelData[j1 * 3 + 1] & 0xff; + int i2 = pixelData[j1 * 3 + 2] & 0xff; + int j2 = 0xff000000 | k1 << 16 | l1 << 8 | i2; + imageData[l + i1 * i] = j2; + } + + } + + BufferedImage bufferedimage = new BufferedImage(i, j, 1); + bufferedimage.setRGB(0, 0, i, j, imageData, 0, i); + ImageIO.write(bufferedimage, "png", file2); + return (new StringBuilder()).append("Saved screenshot as ").append(file2.getName()).toString(); + } + catch(Exception exception) + { + exception.printStackTrace(); + return (new StringBuilder()).append("Failed to save: ").append(exception).toString(); + } + } + + public ScreenShotHelper(File file, int i, int j, int k) + { + field_21194_h = i; + field_21193_i = j; + field_21197_e = k; + File file1 = new File(file, "screenshots"); + file1.mkdir(); + String s = (new StringBuilder()).append("huge_").append(dateFormat.format(new Date())).toString(); + for(int l = 1; (field_21192_j = new File(file1, (new StringBuilder()).append(s).append(l != 1 ? (new StringBuilder()).append("_").append(l).toString() : "").append(".tga").toString())).exists(); l++) { } + byte abyte0[] = new byte[18]; + abyte0[2] = 2; + abyte0[12] = (byte)(i % 256); + abyte0[13] = (byte)(i / 256); + abyte0[14] = (byte)(j % 256); + abyte0[15] = (byte)(j / 256); + abyte0[16] = 24; + field_21195_g = new byte[i * k * 3]; + try { + field_21196_f = new DataOutputStream(new FileOutputStream(field_21192_j)); + field_21196_f.write(abyte0); + }catch(IOException e) { + e.printStackTrace(); + } + } + + public void func_21189_a(ByteBuffer bytebuffer, int i, int j, int k, int l) + { + int i1 = k; + int j1 = l; + if(i1 > field_21194_h - i) + { + i1 = field_21194_h - i; + } + if(j1 > field_21193_i - j) + { + j1 = field_21193_i - j; + } + field_21197_e = j1; + for(int k1 = 0; k1 < j1; k1++) + { + bytebuffer.position((l - j1) * k * 3 + k1 * k * 3); + int l1 = (i + k1 * field_21194_h) * 3; + bytebuffer.get(field_21195_g, l1, i1 * 3); + } + + } + + public void func_21191_a() + { + try { + field_21196_f.write(field_21195_g, 0, field_21194_h * 3 * field_21197_e); + }catch(IOException e) { + e.printStackTrace(); + } + } + + public String func_21190_b() + { + try { + field_21196_f.close(); + return (new StringBuilder()).append("Saved screenshot as ").append(field_21192_j.getName()).toString(); + }catch(IOException e) { + e.printStackTrace(); + return "Failed to save screenshot: " + e.toString(); + } + } + + private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss"); + private static ByteBuffer buffer; + private static byte pixelData[]; + private static int imageData[]; + private int field_21197_e; + private DataOutputStream field_21196_f; + private byte field_21195_g[]; + private int field_21194_h; + private int field_21193_i; + private File field_21192_j; + +} diff --git a/src/main/java/net/minecraft/src/Session.java b/src/main/java/net/minecraft/src/Session.java new file mode 100644 index 0000000..b58419a --- /dev/null +++ b/src/main/java/net/minecraft/src/Session.java @@ -0,0 +1,57 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +public class Session +{ + + public Session(String s, String s1) + { + username = s; + sessionId = s1; + } + + public static List registeredBlocksList; + public String username; + public String sessionId; + public String mpPassParameter; + + static + { + registeredBlocksList = new ArrayList(); + registeredBlocksList.add(Block.stone); + registeredBlocksList.add(Block.cobblestone); + registeredBlocksList.add(Block.brick); + registeredBlocksList.add(Block.dirt); + registeredBlocksList.add(Block.planks); + registeredBlocksList.add(Block.wood); + registeredBlocksList.add(Block.leaves); + registeredBlocksList.add(Block.torchWood); + registeredBlocksList.add(Block.stairSingle); + registeredBlocksList.add(Block.glass); + registeredBlocksList.add(Block.cobblestoneMossy); + registeredBlocksList.add(Block.sapling); + registeredBlocksList.add(Block.plantYellow); + registeredBlocksList.add(Block.plantRed); + registeredBlocksList.add(Block.mushroomBrown); + registeredBlocksList.add(Block.mushroomRed); + registeredBlocksList.add(Block.sand); + registeredBlocksList.add(Block.gravel); + registeredBlocksList.add(Block.sponge); + registeredBlocksList.add(Block.cloth); + registeredBlocksList.add(Block.oreCoal); + registeredBlocksList.add(Block.oreIron); + registeredBlocksList.add(Block.oreGold); + registeredBlocksList.add(Block.blockSteel); + registeredBlocksList.add(Block.blockGold); + registeredBlocksList.add(Block.bookShelf); + registeredBlocksList.add(Block.tnt); + registeredBlocksList.add(Block.obsidian); + System.out.println(registeredBlocksList.size()); + } +} diff --git a/src/main/java/net/minecraft/src/ShapedRecipes.java b/src/main/java/net/minecraft/src/ShapedRecipes.java new file mode 100644 index 0000000..a0a9920 --- /dev/null +++ b/src/main/java/net/minecraft/src/ShapedRecipes.java @@ -0,0 +1,99 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class ShapedRecipes + implements IRecipe +{ + + public ShapedRecipes(int i, int j, ItemStack aitemstack[], ItemStack itemstack) + { + field_21139_a = itemstack.itemID; + field_21138_b = i; + field_21142_c = j; + field_21141_d = aitemstack; + field_21140_e = itemstack; + } + + public boolean func_21135_a(InventoryCrafting inventorycrafting) + { + for(int i = 0; i <= 3 - field_21138_b; i++) + { + for(int j = 0; j <= 3 - field_21142_c; j++) + { + if(func_21137_a(inventorycrafting, i, j, true)) + { + return true; + } + if(func_21137_a(inventorycrafting, i, j, false)) + { + return true; + } + } + + } + + return false; + } + + private boolean func_21137_a(InventoryCrafting inventorycrafting, int i, int j, boolean flag) + { + for(int k = 0; k < 3; k++) + { + for(int l = 0; l < 3; l++) + { + int i1 = k - i; + int j1 = l - j; + ItemStack itemstack = null; + if(i1 >= 0 && j1 >= 0 && i1 < field_21138_b && j1 < field_21142_c) + { + if(flag) + { + itemstack = field_21141_d[(field_21138_b - i1 - 1) + j1 * field_21138_b]; + } else + { + itemstack = field_21141_d[i1 + j1 * field_21138_b]; + } + } + ItemStack itemstack1 = inventorycrafting.func_21103_b(k, l); + if(itemstack1 == null && itemstack == null) + { + continue; + } + if(itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null) + { + return false; + } + if(itemstack.itemID != itemstack1.itemID) + { + return false; + } + if(itemstack.getItemDamage() != -1 && itemstack.getItemDamage() != itemstack1.getItemDamage()) + { + return false; + } + } + + } + + return true; + } + + public ItemStack func_21136_b(InventoryCrafting inventorycrafting) + { + return new ItemStack(field_21140_e.itemID, field_21140_e.stackSize, field_21140_e.getItemDamage()); + } + + public int getRecipeSize() + { + return field_21138_b * field_21142_c; + } + + private int field_21138_b; + private int field_21142_c; + private ItemStack field_21141_d[]; + private ItemStack field_21140_e; + public final int field_21139_a; +} diff --git a/src/main/java/net/minecraft/src/ShapelessRecipes.java b/src/main/java/net/minecraft/src/ShapelessRecipes.java new file mode 100644 index 0000000..598c5f9 --- /dev/null +++ b/src/main/java/net/minecraft/src/ShapelessRecipes.java @@ -0,0 +1,75 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class ShapelessRecipes + implements IRecipe +{ + + public ShapelessRecipes(ItemStack itemstack, List list) + { + field_21144_a = itemstack; + field_21143_b = list; + } + + public boolean func_21135_a(InventoryCrafting inventorycrafting) + { + ArrayList arraylist = new ArrayList(field_21143_b); + int i = 0; + do + { + if(i >= 3) + { + break; + } + for(int j = 0; j < 3; j++) + { + ItemStack itemstack = inventorycrafting.func_21103_b(j, i); + if(itemstack == null) + { + continue; + } + boolean flag = false; + Iterator iterator = arraylist.iterator(); + do + { + if(!iterator.hasNext()) + { + break; + } + ItemStack itemstack1 = (ItemStack)iterator.next(); + if(itemstack.itemID != itemstack1.itemID || itemstack1.getItemDamage() != -1 && itemstack.getItemDamage() != itemstack1.getItemDamage()) + { + continue; + } + flag = true; + arraylist.remove(itemstack1); + break; + } while(true); + if(!flag) + { + return false; + } + } + + i++; + } while(true); + return arraylist.isEmpty(); + } + + public ItemStack func_21136_b(InventoryCrafting inventorycrafting) + { + return field_21144_a.copy(); + } + + public int getRecipeSize() + { + return field_21143_b.size(); + } + + private final ItemStack field_21144_a; + private final List field_21143_b; +} diff --git a/src/main/java/net/minecraft/src/SignModel.java b/src/main/java/net/minecraft/src/SignModel.java new file mode 100644 index 0000000..c007f4f --- /dev/null +++ b/src/main/java/net/minecraft/src/SignModel.java @@ -0,0 +1,26 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class SignModel +{ + + public SignModel() + { + field_1346_a = new ModelRenderer(0, 0); + field_1346_a.addBox(-12F, -14F, -1F, 24, 12, 2, 0.0F); + field_1345_b = new ModelRenderer(0, 14); + field_1345_b.addBox(-1F, -2F, -1F, 2, 14, 2, 0.0F); + } + + public void func_887_a() + { + field_1346_a.render(0.0625F); + field_1345_b.render(0.0625F); + } + + public ModelRenderer field_1346_a; + public ModelRenderer field_1345_b; +} diff --git a/src/main/java/net/minecraft/src/Slot.java b/src/main/java/net/minecraft/src/Slot.java new file mode 100644 index 0000000..99bdabd --- /dev/null +++ b/src/main/java/net/minecraft/src/Slot.java @@ -0,0 +1,69 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class Slot +{ + + public Slot(IInventory iinventory, int i, int j, int k) + { + inventory = iinventory; + slotIndex = i; + xDisplayPosition = j; + yDisplayPosition = k; + } + + public void onPickupFromSlot() + { + onSlotChanged(); + } + + public boolean isItemValid(ItemStack itemstack) + { + return true; + } + + public ItemStack getStack() + { + return inventory.getStackInSlot(slotIndex); + } + + public boolean func_20005_c() + { + return getStack() != null; + } + + public void putStack(ItemStack itemstack) + { + inventory.setInventorySlotContents(slotIndex, itemstack); + onSlotChanged(); + } + + public void onSlotChanged() + { + inventory.onInventoryChanged(); + } + + public int getSlotStackLimit() + { + return inventory.getInventoryStackLimit(); + } + + public int func_775_c() + { + return -1; + } + + public ItemStack decrStackSize(int i) + { + return inventory.decrStackSize(slotIndex, i); + } + + private final int slotIndex; + private final IInventory inventory; + public int field_20007_a; + public int xDisplayPosition; + public int yDisplayPosition; +} diff --git a/src/main/java/net/minecraft/src/SlotArmor.java b/src/main/java/net/minecraft/src/SlotArmor.java new file mode 100644 index 0000000..f9b4f8e --- /dev/null +++ b/src/main/java/net/minecraft/src/SlotArmor.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class SlotArmor extends Slot +{ + + SlotArmor(CraftingInventoryPlayerCB craftinginventoryplayercb, IInventory iinventory, int i, int j, int k, int l) + { + super(iinventory, i, j, k); + field_1123_d = craftinginventoryplayercb; + field_1124_c = l; + } + + public int getSlotStackLimit() + { + return 1; + } + + public boolean isItemValid(ItemStack itemstack) + { + if(itemstack.getItem() instanceof ItemArmor) + { + return ((ItemArmor)itemstack.getItem()).armorType == field_1124_c; + } + if(itemstack.getItem().shiftedIndex == Block.pumpkin.blockID) + { + return field_1124_c == 0; + } else + { + return false; + } + } + + final int field_1124_c; /* synthetic field */ + final CraftingInventoryPlayerCB field_1123_d; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/SlotCrafting.java b/src/main/java/net/minecraft/src/SlotCrafting.java new file mode 100644 index 0000000..595a052 --- /dev/null +++ b/src/main/java/net/minecraft/src/SlotCrafting.java @@ -0,0 +1,40 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class SlotCrafting extends Slot +{ + + public SlotCrafting(IInventory iinventory, IInventory iinventory1, int i, int j, int k) + { + super(iinventory1, i, j, k); + craftMatrix = iinventory; + } + + public boolean isItemValid(ItemStack itemstack) + { + return false; + } + + public void onPickupFromSlot() + { + for(int i = 0; i < craftMatrix.getSizeInventory(); i++) + { + ItemStack itemstack = craftMatrix.getStackInSlot(i); + if(itemstack == null) + { + continue; + } + craftMatrix.decrStackSize(i, 1); + if(itemstack.getItem().func_21014_i()) + { + craftMatrix.setInventorySlotContents(i, new ItemStack(itemstack.getItem().getContainerItem())); + } + } + + } + + private final IInventory craftMatrix; +} diff --git a/src/main/java/net/minecraft/src/SoundManager.java b/src/main/java/net/minecraft/src/SoundManager.java new file mode 100644 index 0000000..1d19464 --- /dev/null +++ b/src/main/java/net/minecraft/src/SoundManager.java @@ -0,0 +1,247 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.io.PrintStream; +import java.util.Random; +import paulscode.sound.SoundSystem; +import paulscode.sound.SoundSystemConfig; +import paulscode.sound.libraries.LibraryLWJGLOpenAL; + +public class SoundManager +{ + + public SoundManager() + { + soundPoolSounds = new SoundPool(); + soundPoolStreaming = new SoundPool(); + soundPoolMusic = new SoundPool(); + field_587_e = 0; + rand = new Random(); + ticksBeforeMusic = rand.nextInt(12000); + } + + public void loadSoundSettings(GameSettings gamesettings) + { + soundPoolStreaming.field_1657_b = false; + options = gamesettings; + if(!loaded && (gamesettings == null || gamesettings.soundVolume != 0.0F || gamesettings.musicVolume != 0.0F)) + { + tryToSetLibraryAndCodecs(); + } + } + + private void tryToSetLibraryAndCodecs() + { + /* + try + { + float f = options.soundVolume; + float f1 = options.musicVolume; + options.soundVolume = 0.0F; + options.musicVolume = 0.0F; + options.saveOptions(); + SoundSystemConfig.addLibrary(paulscode.sound.libraries.LibraryLWJGLOpenAL.class); + SoundSystemConfig.setCodec("ogg", paulscode.sound.codecs.CodecJOrbis.class); + SoundSystemConfig.setCodec("mus", CodecMus.class); + SoundSystemConfig.setCodec("wav", paulscode.sound.codecs.CodecWav.class); + sndSystem = new SoundSystem(); + options.soundVolume = f; + options.musicVolume = f1; + options.saveOptions(); + } + catch(Throwable throwable) + { + throwable.printStackTrace(); + System.err.println("error linking with the LibraryJavaSound plug-in"); + } + */ + loaded = false; + } + + public void onSoundOptionsChanged() + { + if(!loaded && (options.soundVolume != 0.0F || options.musicVolume != 0.0F)) + { + tryToSetLibraryAndCodecs(); + } + if(loaded) + { + if(options.musicVolume == 0.0F) + { + sndSystem.stop("BgMusic"); + } else + { + sndSystem.setVolume("BgMusic", options.musicVolume); + } + } + } + + public void closeMinecraft() + { + if(loaded) + { + sndSystem.cleanup(); + } + } + + public void addSound(String s, File file) + { + soundPoolSounds.addSound(s, file); + } + + public void addStreaming(String s, File file) + { + soundPoolStreaming.addSound(s, file); + } + + public void addMusic(String s, File file) + { + soundPoolMusic.addSound(s, file); + } + + public void playRandomMusicIfReady() + { + if(!loaded || options.musicVolume == 0.0F) + { + return; + } + if(!sndSystem.playing("BgMusic") && !sndSystem.playing("streaming")) + { + if(ticksBeforeMusic > 0) + { + ticksBeforeMusic--; + return; + } + SoundPoolEntry soundpoolentry = soundPoolMusic.getRandomSound(); + if(soundpoolentry != null) + { + ticksBeforeMusic = rand.nextInt(12000) + 12000; + sndSystem.backgroundMusic("BgMusic", soundpoolentry.soundUrl, soundpoolentry.soundName, false); + sndSystem.setVolume("BgMusic", options.musicVolume); + sndSystem.play("BgMusic"); + } + } + } + + public void func_338_a(EntityLiving entityliving, float f) + { + if(!loaded || options.soundVolume == 0.0F) + { + return; + } + if(entityliving == null) + { + return; + } else + { + float f1 = entityliving.prevRotationYaw + (entityliving.rotationYaw - entityliving.prevRotationYaw) * f; + double d = entityliving.prevPosX + (entityliving.posX - entityliving.prevPosX) * (double)f; + double d1 = entityliving.prevPosY + (entityliving.posY - entityliving.prevPosY) * (double)f; + double d2 = entityliving.prevPosZ + (entityliving.posZ - entityliving.prevPosZ) * (double)f; + float f2 = MathHelper.cos(-f1 * 0.01745329F - 3.141593F); + float f3 = MathHelper.sin(-f1 * 0.01745329F - 3.141593F); + float f4 = -f3; + float f5 = 0.0F; + float f6 = -f2; + float f7 = 0.0F; + float f8 = 1.0F; + float f9 = 0.0F; + sndSystem.setListenerPosition((float)d, (float)d1, (float)d2); + sndSystem.setListenerOrientation(f4, f5, f6, f7, f8, f9); + return; + } + } + + public void func_331_a(String s, float f, float f1, float f2, float f3, float f4) + { + if(!loaded || options.soundVolume == 0.0F) + { + return; + } + String s1 = "streaming"; + if(sndSystem.playing("streaming")) + { + sndSystem.stop("streaming"); + } + if(s == null) + { + return; + } + SoundPoolEntry soundpoolentry = soundPoolStreaming.getRandomSoundFromSoundPool(s); + if(soundpoolentry != null && f3 > 0.0F) + { + if(sndSystem.playing("BgMusic")) + { + sndSystem.stop("BgMusic"); + } + float f5 = 16F; + sndSystem.newStreamingSource(true, s1, soundpoolentry.soundUrl, soundpoolentry.soundName, false, f, f1, f2, 2, f5 * 4F); + sndSystem.setVolume(s1, 0.5F * options.soundVolume); + sndSystem.play(s1); + } + } + + public void playSound(String s, float f, float f1, float f2, float f3, float f4) + { + if(!loaded || options.soundVolume == 0.0F) + { + return; + } + SoundPoolEntry soundpoolentry = soundPoolSounds.getRandomSoundFromSoundPool(s); + if(soundpoolentry != null && f3 > 0.0F) + { + field_587_e = (field_587_e + 1) % 256; + String s1 = (new StringBuilder()).append("sound_").append(field_587_e).toString(); + float f5 = 16F; + if(f3 > 1.0F) + { + f5 *= f3; + } + sndSystem.newSource(f3 > 1.0F, s1, soundpoolentry.soundUrl, soundpoolentry.soundName, false, f, f1, f2, 2, f5); + sndSystem.setPitch(s1, f4); + if(f3 > 1.0F) + { + f3 = 1.0F; + } + sndSystem.setVolume(s1, f3 * options.soundVolume); + sndSystem.play(s1); + } + } + + public void func_337_a(String s, float f, float f1) + { + if(!loaded || options.soundVolume == 0.0F) + { + return; + } + SoundPoolEntry soundpoolentry = soundPoolSounds.getRandomSoundFromSoundPool(s); + if(soundpoolentry != null) + { + field_587_e = (field_587_e + 1) % 256; + String s1 = (new StringBuilder()).append("sound_").append(field_587_e).toString(); + sndSystem.newSource(false, s1, soundpoolentry.soundUrl, soundpoolentry.soundName, false, 0.0F, 0.0F, 0.0F, 0, 0.0F); + if(f > 1.0F) + { + f = 1.0F; + } + f *= 0.25F; + sndSystem.setPitch(s1, f1); + sndSystem.setVolume(s1, f * options.soundVolume); + sndSystem.play(s1); + } + } + + private static SoundSystem sndSystem; + private SoundPool soundPoolSounds; + private SoundPool soundPoolStreaming; + private SoundPool soundPoolMusic; + private int field_587_e; + private GameSettings options; + private static boolean loaded = false; + private Random rand; + private int ticksBeforeMusic; + +} diff --git a/src/main/java/net/minecraft/src/SoundPool.java b/src/main/java/net/minecraft/src/SoundPool.java new file mode 100644 index 0000000..ea5110f --- /dev/null +++ b/src/main/java/net/minecraft/src/SoundPool.java @@ -0,0 +1,79 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.*; + +public class SoundPool +{ + + public SoundPool() + { + rand = new Random(); + nameToSoundPoolEntriesMapping = new HashMap(); + allSoundPoolEntries = new ArrayList(); + numberOfSoundPoolEntries = 0; + field_1657_b = true; + } + + public SoundPoolEntry addSound(String s, File file) + { + try + { + String s1 = s; + s = s.substring(0, s.indexOf(".")); + if(field_1657_b) + { + for(; Character.isDigit(s.charAt(s.length() - 1)); s = s.substring(0, s.length() - 1)) { } + } + s = s.replaceAll("/", "."); + if(!nameToSoundPoolEntriesMapping.containsKey(s)) + { + nameToSoundPoolEntriesMapping.put(s, new ArrayList()); + } + SoundPoolEntry soundpoolentry = new SoundPoolEntry(s1, file.toURI().toURL()); + ((List)nameToSoundPoolEntriesMapping.get(s)).add(soundpoolentry); + allSoundPoolEntries.add(soundpoolentry); + numberOfSoundPoolEntries++; + return soundpoolentry; + } + catch(MalformedURLException malformedurlexception) + { + malformedurlexception.printStackTrace(); + throw new RuntimeException(malformedurlexception); + } + } + + public SoundPoolEntry getRandomSoundFromSoundPool(String s) + { + List list = (List)nameToSoundPoolEntriesMapping.get(s); + if(list == null) + { + return null; + } else + { + return (SoundPoolEntry)list.get(rand.nextInt(list.size())); + } + } + + public SoundPoolEntry getRandomSound() + { + if(allSoundPoolEntries.size() == 0) + { + return null; + } else + { + return (SoundPoolEntry)allSoundPoolEntries.get(rand.nextInt(allSoundPoolEntries.size())); + } + } + + private Random rand; + private Map nameToSoundPoolEntriesMapping; + private List allSoundPoolEntries; + public int numberOfSoundPoolEntries; + public boolean field_1657_b; +} diff --git a/src/main/java/net/minecraft/src/SoundPoolEntry.java b/src/main/java/net/minecraft/src/SoundPoolEntry.java new file mode 100644 index 0000000..f682495 --- /dev/null +++ b/src/main/java/net/minecraft/src/SoundPoolEntry.java @@ -0,0 +1,19 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.net.URL; + +public class SoundPoolEntry +{ + + public SoundPoolEntry(String s, URL url) + { + soundName = s; + soundUrl = url; + } + + public String soundName; + public URL soundUrl; +} diff --git a/src/main/java/net/minecraft/src/SpawnerAnimals.java b/src/main/java/net/minecraft/src/SpawnerAnimals.java new file mode 100644 index 0000000..73f75e5 --- /dev/null +++ b/src/main/java/net/minecraft/src/SpawnerAnimals.java @@ -0,0 +1,194 @@ +// Decompiled with: CFR 0.152 +// Class Version: 5 +package net.minecraft.src; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public final class SpawnerAnimals { + private static Set field_6544_a = new HashSet(); + protected static final Class[] field_22391_a = new Class[] { EntitySpider.class, EntityZombie.class, + EntitySkeleton.class }; + + protected static ChunkPosition func_4153_a(World world, int n, int n2) { + int n3 = n + world.rand.nextInt(16); + int n4 = world.rand.nextInt(128); + int n5 = n2 + world.rand.nextInt(16); + return new ChunkPosition(n3, n4, n5); + } + + public static final int performSpawning(World world, boolean bl, boolean bl2) { + Object object; + int n; + if (!bl && !bl2) { + return 0; + } + field_6544_a.clear(); + for (n = 0; n < world.playerEntities.size(); ++n) { + object = (EntityPlayer) world.playerEntities.get(n); + int n2 = MathHelper.floor_double(((EntityPlayer) object).posX / 16.0); + int n3 = MathHelper.floor_double(((EntityPlayer) object).posZ / 16.0); + int n4 = 8; + for (int i = -n4; i <= n4; ++i) { + for (int j = -n4; j <= n4; ++j) { + field_6544_a.add(new ChunkCoordIntPair(i + n2, j + n3)); + } + } + } + n = 0; + object = world.func_22137_s(); + for (EnumCreatureType enumCreatureType : EnumCreatureType.values()) { + if (enumCreatureType.func_21168_d() && !bl2 || !enumCreatureType.func_21168_d() && !bl + || world.countEntities(enumCreatureType.getCreatureClass()) > enumCreatureType.getMaxNumberOfCreature() + * field_6544_a.size() / 256) + continue; + block6: for (ChunkCoordIntPair chunkCoordIntPair : field_6544_a) { + MobSpawnerBase mobSpawnerBase = world.getWorldChunkManager().func_4074_a(chunkCoordIntPair); + Class[] classArray = mobSpawnerBase.getEntitiesForType(enumCreatureType); + if (classArray == null || classArray.length == 0) + continue; + int n5 = world.rand.nextInt(classArray.length); + ChunkPosition chunkPosition = SpawnerAnimals.func_4153_a(world, chunkCoordIntPair.chunkXPos * 16, + chunkCoordIntPair.chunkZPos * 16); + int n6 = chunkPosition.x; + int n7 = chunkPosition.y; + int n8 = chunkPosition.z; + if (world.isBlockOpaqueCube(n6, n7, n8) || world.getBlockMaterial(n6, n7, n8) != enumCreatureType.getCreatureMaterial()) + continue; + int n9 = 0; + for (int i = 0; i < 3; ++i) { + int n10 = n6; + int n11 = n7; + int n12 = n8; + int n13 = 6; + for (int j = 0; j < 4; ++j) { + EntityLiving entityLiving; + float f; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + if (!SpawnerAnimals.func_21203_a(enumCreatureType, world, + n10 += world.rand.nextInt(n13) - world.rand.nextInt(n13), + n11 += world.rand.nextInt(1) - world.rand.nextInt(1), + n12 += world.rand.nextInt(n13) - world.rand.nextInt(n13)) + || world.getClosestPlayer(f7 = (float) n10 + 0.5f, f6 = (float) n11, f5 = (float) n12 + 0.5f, + 24.0) != null + || (f4 = (f3 = f7 - (float) ((ChunkCoordinates) object).field_22395_a) * f3 + + (f2 = f6 - (float) ((ChunkCoordinates) object).field_22394_b) * f2 + + (f = f5 - (float) ((ChunkCoordinates) object).field_22396_c) * f) < 576.0f) + continue; + try { + entityLiving = (EntityLiving) classArray[n5].getConstructor(World.class).newInstance(world); + } catch (Exception exception) { + exception.printStackTrace(); + return n; + } + entityLiving.setLocationAndAngles(f7, f6, f5, world.rand.nextFloat() * 360.0f, 0.0f); + if (entityLiving.getCanSpawnHere()) { + world.entityJoinedWorld(entityLiving); + SpawnerAnimals.func_21204_a(entityLiving, world, f7, f6, f5); + if (++n9 >= entityLiving.getMaxSpawnedInChunk()) + continue block6; + } + n += n9; + } + } + } + } + return n; + } + + private static boolean func_21203_a(EnumCreatureType enumCreatureType, World world, int n, int n2, int n3) { + if (enumCreatureType.getCreatureMaterial() == Material.water) { + return world.getBlockMaterial(n, n2, n3).getIsLiquid() && !world.isBlockOpaqueCube(n, n2 + 1, n3); + } + return world.isBlockOpaqueCube(n, n2 - 1, n3) && !world.isBlockOpaqueCube(n, n2, n3) + && !world.getBlockMaterial(n, n2, n3).getIsLiquid() && !world.isBlockOpaqueCube(n, n2 + 1, n3); + } + + private static void func_21204_a(EntityLiving entityLiving, World world, float f, float f2, float f3) { + if (entityLiving instanceof EntitySpider && world.rand.nextInt(100) == 0) { + EntitySkeleton entitySkeleton = new EntitySkeleton(world); + entitySkeleton.setLocationAndAngles(f, f2, f3, entityLiving.rotationYaw, 0.0f); + world.entityJoinedWorld(entitySkeleton); + entitySkeleton.mountEntity(entityLiving); + } else if (entityLiving instanceof EntitySheep) { + ((EntitySheep) ((Object) entityLiving)).setFleeceColor(EntitySheep.func_21070_a(world.rand)); + } + } + + public static boolean func_22390_a(World world, List list) { + boolean bl = false; + Pathfinder pathfinder = new Pathfinder(world); + for (EntityPlayer entityPlayer : (List)list) { + Class[] classArray = field_22391_a; + if (classArray == null || classArray.length == 0) + continue; + boolean bl2 = false; + for (int i = 0; i < 20 && !bl2; ++i) { + PathEntity pathEntity; + EntityLiving entityLiving; + int n; + int n2 = MathHelper.floor_double(entityPlayer.posX) + world.rand.nextInt(32) + - world.rand.nextInt(32); + int n3 = MathHelper.floor_double(entityPlayer.posY) + world.rand.nextInt(32) + - world.rand.nextInt(32); + int n4 = MathHelper.floor_double(entityPlayer.posZ) + world.rand.nextInt(16) + - world.rand.nextInt(16); + if (n4 < 1) { + n4 = 1; + } else if (n4 > 128) { + n4 = 128; + } + int n5 = world.rand.nextInt(classArray.length); + for (n = n4; n > 2 && !world.isBlockOpaqueCube(n2, n - 1, n3); --n) { + } + while (!SpawnerAnimals.func_21203_a(EnumCreatureType.monster, world, n2, n, n3) && n < n4 + 16 + && n < 128) { + ++n; + } + if (n >= n4 + 16 || n >= 128) { + n = n4; + continue; + } + float f = (float) n2 + 0.5f; + float f2 = n; + float f3 = (float) n3 + 0.5f; + try { + entityLiving = (EntityLiving) classArray[n5].getConstructor(World.class).newInstance(world); + } catch (Exception exception) { + exception.printStackTrace(); + return bl; + } + entityLiving.setLocationAndAngles(f, f2, f3, world.rand.nextFloat() * 360.0f, 0.0f); + if (!entityLiving.getCanSpawnHere() + || (pathEntity = pathfinder.createEntityPathTo(entityLiving, entityPlayer, 32.0f)) == null + || pathEntity.pathLength <= 1) + continue; + PathPoint pathPoint = pathEntity.func_22328_c(); + if (!(Math.abs((double) pathPoint.xCoord - entityPlayer.posX) < 1.5) + || !(Math.abs((double) pathPoint.yCoord - entityPlayer.posY) < 1.5) + || !(Math.abs((double) pathPoint.zCoord - entityPlayer.posZ) < 1.5)) + continue; + ChunkCoordinates chunkCoordinates = BlockBed.func_22028_g(world, + MathHelper.floor_double(entityPlayer.posX), + MathHelper.floor_double(entityPlayer.posY), + MathHelper.floor_double(entityPlayer.posZ), 1); + entityLiving.setLocationAndAngles((float) chunkCoordinates.field_22395_a + 0.5f, chunkCoordinates.field_22394_b, + (float) chunkCoordinates.field_22396_c + 0.5f, 0.0f, 0.0f); + world.entityJoinedWorld(entityLiving); + SpawnerAnimals.func_21204_a(entityLiving, world, (float) chunkCoordinates.field_22395_a + 0.5f, + chunkCoordinates.field_22394_b, (float) chunkCoordinates.field_22396_c + 0.5f); + entityPlayer.func_22056_a(true, false); + entityLiving.func_22050_O(); + bl = true; + bl2 = true; + } + } + return bl; + } +} diff --git a/src/main/java/net/minecraft/src/StepSound.java b/src/main/java/net/minecraft/src/StepSound.java new file mode 100644 index 0000000..92a90b3 --- /dev/null +++ b/src/main/java/net/minecraft/src/StepSound.java @@ -0,0 +1,40 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class StepSound +{ + + public StepSound(String s, float f, float f1) + { + field_1678_a = s; + field_1677_b = f; + field_1679_c = f1; + } + + public float func_1147_b() + { + return field_1677_b; + } + + public float func_1144_c() + { + return field_1679_c; + } + + public String func_1146_a() + { + return (new StringBuilder()).append("step.").append(field_1678_a).toString(); + } + + public String func_1145_d() + { + return (new StringBuilder()).append("step.").append(field_1678_a).toString(); + } + + public final String field_1678_a; + public final float field_1677_b; + public final float field_1679_c; +} diff --git a/src/main/java/net/minecraft/src/StepSoundSand.java b/src/main/java/net/minecraft/src/StepSoundSand.java new file mode 100644 index 0000000..ad4bc4e --- /dev/null +++ b/src/main/java/net/minecraft/src/StepSoundSand.java @@ -0,0 +1,19 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +final class StepSoundSand extends StepSound +{ + + StepSoundSand(String s, float f, float f1) + { + super(s, f, f1); + } + + public String func_1146_a() + { + return "step.gravel"; + } +} diff --git a/src/main/java/net/minecraft/src/StepSoundStone.java b/src/main/java/net/minecraft/src/StepSoundStone.java new file mode 100644 index 0000000..ea9d753 --- /dev/null +++ b/src/main/java/net/minecraft/src/StepSoundStone.java @@ -0,0 +1,19 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +final class StepSoundStone extends StepSound +{ + + StepSoundStone(String s, float f, float f1) + { + super(s, f, f1); + } + + public String func_1146_a() + { + return "random.glass"; + } +} diff --git a/src/main/java/net/minecraft/src/StringTranslate.java b/src/main/java/net/minecraft/src/StringTranslate.java new file mode 100644 index 0000000..49e77fd --- /dev/null +++ b/src/main/java/net/minecraft/src/StringTranslate.java @@ -0,0 +1,49 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.IOException; +import java.util.Properties; + +public class StringTranslate +{ + + private StringTranslate() + { + translateTable = new Properties(); + try + { + translateTable.load((StringTranslate.class).getResourceAsStream("/lang/en_US.lang")); + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + public static StringTranslate getInstance() + { + return instance; + } + + public String translateKey(String s) + { + return translateTable.getProperty(s, s); + } + + public String translateKeyFormat(String s, Object aobj[]) + { + String s1 = translateTable.getProperty(s, s); + return String.format(s1, aobj); + } + + public String translateNamedKey(String s) + { + return translateTable.getProperty((new StringBuilder()).append(s).append(".name").toString(), ""); + } + + private static StringTranslate instance = new StringTranslate(); + private Properties translateTable; + +} diff --git a/src/main/java/net/minecraft/src/Teleporter.java b/src/main/java/net/minecraft/src/Teleporter.java new file mode 100644 index 0000000..92e3c7f --- /dev/null +++ b/src/main/java/net/minecraft/src/Teleporter.java @@ -0,0 +1,302 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.Random; + +public class Teleporter +{ + + public Teleporter() + { + field_4232_a = new Random(); + } + + public void func_4107_a(World world, Entity entity) + { + if(func_4106_b(world, entity)) + { + return; + } else + { + func_4108_c(world, entity); + func_4106_b(world, entity); + return; + } + } + + public boolean func_4106_b(World world, Entity entity) + { + char c = '\200'; + double d = -1D; + int i = 0; + int j = 0; + int k = 0; + int l = MathHelper.floor_double(entity.posX); + int i1 = MathHelper.floor_double(entity.posZ); + for(int j1 = l - c; j1 <= l + c; j1++) + { + double d1 = ((double)j1 + 0.5D) - entity.posX; + for(int j2 = i1 - c; j2 <= i1 + c; j2++) + { + double d3 = ((double)j2 + 0.5D) - entity.posZ; + for(int k2 = 127; k2 >= 0; k2--) + { + if(world.getBlockId(j1, k2, j2) != Block.portal.blockID) + { + continue; + } + for(; world.getBlockId(j1, k2 - 1, j2) == Block.portal.blockID; k2--) { } + double d5 = ((double)k2 + 0.5D) - entity.posY; + double d7 = d1 * d1 + d5 * d5 + d3 * d3; + if(d < 0.0D || d7 < d) + { + d = d7; + i = j1; + j = k2; + k = j2; + } + } + + } + + } + + if(d >= 0.0D) + { + int k1 = i; + int l1 = j; + int i2 = k; + double d2 = (double)k1 + 0.5D; + double d4 = (double)l1 + 0.5D; + double d6 = (double)i2 + 0.5D; + if(world.getBlockId(k1 - 1, l1, i2) == Block.portal.blockID) + { + d2 -= 0.5D; + } + if(world.getBlockId(k1 + 1, l1, i2) == Block.portal.blockID) + { + d2 += 0.5D; + } + if(world.getBlockId(k1, l1, i2 - 1) == Block.portal.blockID) + { + d6 -= 0.5D; + } + if(world.getBlockId(k1, l1, i2 + 1) == Block.portal.blockID) + { + d6 += 0.5D; + } + System.out.println((new StringBuilder()).append("Teleporting to ").append(d2).append(", ").append(d4).append(", ").append(d6).toString()); + entity.setLocationAndAngles(d2, d4, d6, entity.rotationYaw, 0.0F); + entity.motionX = entity.motionY = entity.motionZ = 0.0D; + return true; + } else + { + return false; + } + } + + public boolean func_4108_c(World world, Entity entity) + { + byte byte0 = 16; + double d = -1D; + int i = MathHelper.floor_double(entity.posX); + int j = MathHelper.floor_double(entity.posY); + int k = MathHelper.floor_double(entity.posZ); + int l = i; + int i1 = j; + int j1 = k; + int k1 = 0; + int l1 = field_4232_a.nextInt(4); + for(int i2 = i - byte0; i2 <= i + byte0; i2++) + { + double d1 = ((double)i2 + 0.5D) - entity.posX; + for(int j3 = k - byte0; j3 <= k + byte0; j3++) + { + double d3 = ((double)j3 + 0.5D) - entity.posZ; + for(int k4 = 127; k4 >= 0; k4--) + { + if(!world.isAirBlock(i2, k4, j3)) + { + continue; + } + for(; k4 > 0 && world.isAirBlock(i2, k4 - 1, j3); k4--) { } +label0: + for(int k5 = l1; k5 < l1 + 4; k5++) + { + int l6 = k5 % 2; + int i8 = 1 - l6; + if(k5 % 4 >= 2) + { + l6 = -l6; + i8 = -i8; + } + for(int j9 = 0; j9 < 3; j9++) + { + for(int k10 = 0; k10 < 4; k10++) + { + for(int l11 = -1; l11 < 4; l11++) + { + int j12 = i2 + (k10 - 1) * l6 + j9 * i8; + int l12 = k4 + l11; + int j13 = (j3 + (k10 - 1) * i8) - j9 * l6; + if(l11 < 0 && !world.getBlockMaterial(j12, l12, j13).isSolid() || l11 >= 0 && !world.isAirBlock(j12, l12, j13)) + { + break label0; + } + } + + } + + } + + double d5 = ((double)k4 + 0.5D) - entity.posY; + double d7 = d1 * d1 + d5 * d5 + d3 * d3; + if(d < 0.0D || d7 < d) + { + d = d7; + l = i2; + i1 = k4; + j1 = j3; + k1 = k5 % 4; + } + } + + } + + } + + } + + if(d < 0.0D) + { + for(int j2 = i - byte0; j2 <= i + byte0; j2++) + { + double d2 = ((double)j2 + 0.5D) - entity.posX; + for(int k3 = k - byte0; k3 <= k + byte0; k3++) + { + double d4 = ((double)k3 + 0.5D) - entity.posZ; + for(int l4 = 127; l4 >= 0; l4--) + { + if(!world.isAirBlock(j2, l4, k3)) + { + continue; + } + for(; world.isAirBlock(j2, l4 - 1, k3); l4--) { } +label1: + for(int l5 = l1; l5 < l1 + 2; l5++) + { + int i7 = l5 % 2; + int j8 = 1 - i7; + for(int k9 = 0; k9 < 4; k9++) + { + for(int l10 = -1; l10 < 4; l10++) + { + int i12 = j2 + (k9 - 1) * i7; + int k12 = l4 + l10; + int i13 = k3 + (k9 - 1) * j8; + if(l10 < 0 && !world.getBlockMaterial(i12, k12, i13).isSolid() || l10 >= 0 && !world.isAirBlock(i12, k12, i13)) + { + break label1; + } + } + + } + + double d6 = ((double)l4 + 0.5D) - entity.posY; + double d8 = d2 * d2 + d6 * d6 + d4 * d4; + if(d < 0.0D || d8 < d) + { + d = d8; + l = j2; + i1 = l4; + j1 = k3; + k1 = l5 % 2; + } + } + + } + + } + + } + + } + int k2 = k1; + int l2 = l; + int i3 = i1; + int l3 = j1; + int i4 = k2 % 2; + int j4 = 1 - i4; + if(k2 % 4 >= 2) + { + i4 = -i4; + j4 = -j4; + } + if(d < 0.0D) + { + if(i1 < 70) + { + i1 = 70; + } + if(i1 > 118) + { + i1 = 118; + } + i3 = i1; + for(int i5 = -1; i5 <= 1; i5++) + { + for(int i6 = 1; i6 < 3; i6++) + { + for(int j7 = -1; j7 < 3; j7++) + { + int k8 = l2 + (i6 - 1) * i4 + i5 * j4; + int l9 = i3 + j7; + int i11 = (l3 + (i6 - 1) * j4) - i5 * i4; + boolean flag = j7 < 0; + world.setBlockWithNotify(k8, l9, i11, flag ? Block.obsidian.blockID : 0); + } + + } + + } + + } + for(int j5 = 0; j5 < 4; j5++) + { + world.field_1043_h = true; + for(int j6 = 0; j6 < 4; j6++) + { + for(int k7 = -1; k7 < 4; k7++) + { + int l8 = l2 + (j6 - 1) * i4; + int i10 = i3 + k7; + int j11 = l3 + (j6 - 1) * j4; + boolean flag1 = j6 == 0 || j6 == 3 || k7 == -1 || k7 == 3; + world.setBlockWithNotify(l8, i10, j11, flag1 ? Block.obsidian.blockID : Block.portal.blockID); + } + + } + + world.field_1043_h = false; + for(int k6 = 0; k6 < 4; k6++) + { + for(int l7 = -1; l7 < 4; l7++) + { + int i9 = l2 + (k6 - 1) * i4; + int j10 = i3 + l7; + int k11 = l3 + (k6 - 1) * j4; + world.notifyBlocksOfNeighborChange(i9, j10, k11, world.getBlockId(i9, j10, k11)); + } + + } + + } + + return true; + } + + private Random field_4232_a; +} diff --git a/src/main/java/net/minecraft/src/TerrainTextureManager.java b/src/main/java/net/minecraft/src/TerrainTextureManager.java new file mode 100644 index 0000000..339e246 --- /dev/null +++ b/src/main/java/net/minecraft/src/TerrainTextureManager.java @@ -0,0 +1,268 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Arrays; +import javax.imageio.ImageIO; + +public class TerrainTextureManager +{ + + public TerrainTextureManager() + { + field_1181_a = new float[768]; + field_1180_b = new int[5120]; + field_1186_c = new int[5120]; + field_1185_d = new int[5120]; + field_1184_e = new int[5120]; + field_1183_f = new int[34]; + field_1182_g = new int[768]; + try + { + BufferedImage bufferedimage = ImageIO.read((TerrainTextureManager.class).getResource("/terrain.png")); + int ai[] = new int[0x10000]; + bufferedimage.getRGB(0, 0, 256, 256, ai, 0, 256); + for(int j = 0; j < 256; j++) + { + int k = 0; + int l = 0; + int i1 = 0; + int j1 = (j % 16) * 16; + int k1 = (j / 16) * 16; + int l1 = 0; + for(int i2 = 0; i2 < 16; i2++) + { + for(int j2 = 0; j2 < 16; j2++) + { + int k2 = ai[j2 + j1 + (i2 + k1) * 256]; + int l2 = k2 >> 24 & 0xff; + if(l2 > 128) + { + k += k2 >> 16 & 0xff; + l += k2 >> 8 & 0xff; + i1 += k2 & 0xff; + l1++; + } + } + + if(l1 == 0) + { + l1++; + } + field_1181_a[j * 3 + 0] = k / l1; + field_1181_a[j * 3 + 1] = l / l1; + field_1181_a[j * 3 + 2] = i1 / l1; + } + + } + + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + for(int i = 0; i < 256; i++) + { + if(Block.blocksList[i] != null) + { + field_1182_g[i * 3 + 0] = Block.blocksList[i].getBlockTextureFromSide(1); + field_1182_g[i * 3 + 1] = Block.blocksList[i].getBlockTextureFromSide(2); + field_1182_g[i * 3 + 2] = Block.blocksList[i].getBlockTextureFromSide(3); + } + } + + } + + public void func_799_a(IsoImageBuffer isoimagebuffer) + { + World world = isoimagebuffer.worldObj; + if(world == null) + { + isoimagebuffer.field_1351_f = true; + isoimagebuffer.field_1352_e = true; + return; + } + int i = isoimagebuffer.field_1354_c * 16; + int j = isoimagebuffer.field_1353_d * 16; + int k = i + 16; + int l = j + 16; + Chunk chunk = world.getChunkFromChunkCoords(isoimagebuffer.field_1354_c, isoimagebuffer.field_1353_d); + if(chunk.func_21167_h()) + { + isoimagebuffer.field_1351_f = true; + isoimagebuffer.field_1352_e = true; + return; + } + isoimagebuffer.field_1351_f = false; + Arrays.fill(field_1186_c, 0); + Arrays.fill(field_1185_d, 0); + Arrays.fill(field_1183_f, 160); + for(int i1 = l - 1; i1 >= j; i1--) + { + for(int j1 = k - 1; j1 >= i; j1--) + { + int k1 = j1 - i; + int l1 = i1 - j; + int i2 = k1 + l1; + boolean flag = true; + for(int j2 = 0; j2 < 128; j2++) + { + int k2 = ((l1 - k1 - j2) + 160) - 16; + if(k2 >= field_1183_f[i2] && k2 >= field_1183_f[i2 + 1]) + { + continue; + } + Block block = Block.blocksList[world.getBlockId(j1, j2, i1)]; + if(block == null) + { + flag = false; + continue; + } + if(block.blockMaterial == Material.water) + { + int l2 = world.getBlockId(j1, j2 + 1, i1); + if(l2 != 0 && Block.blocksList[l2].blockMaterial == Material.water) + { + continue; + } + float f1 = ((float)j2 / 127F) * 0.6F + 0.4F; + float f2 = world.getLightBrightness(j1, j2 + 1, i1) * f1; + if(k2 < 0 || k2 >= 160) + { + continue; + } + int i4 = i2 + k2 * 32; + if(i2 >= 0 && i2 <= 32 && field_1185_d[i4] <= j2) + { + field_1185_d[i4] = j2; + field_1184_e[i4] = (int)(f2 * 127F); + } + if(i2 >= -1 && i2 <= 31 && field_1185_d[i4 + 1] <= j2) + { + field_1185_d[i4 + 1] = j2; + field_1184_e[i4 + 1] = (int)(f2 * 127F); + } + flag = false; + continue; + } + if(flag) + { + if(k2 < field_1183_f[i2]) + { + field_1183_f[i2] = k2; + } + if(k2 < field_1183_f[i2 + 1]) + { + field_1183_f[i2 + 1] = k2; + } + } + float f = ((float)j2 / 127F) * 0.6F + 0.4F; + if(k2 >= 0 && k2 < 160) + { + int i3 = i2 + k2 * 32; + int k3 = field_1182_g[block.blockID * 3 + 0]; + float f3 = (world.getLightBrightness(j1, j2 + 1, i1) * 0.8F + 0.2F) * f; + int j4 = k3; + if(i2 >= 0) + { + float f5 = f3; + if(field_1186_c[i3] <= j2) + { + field_1186_c[i3] = j2; + field_1180_b[i3] = 0xff000000 | (int)(field_1181_a[j4 * 3 + 0] * f5) << 16 | (int)(field_1181_a[j4 * 3 + 1] * f5) << 8 | (int)(field_1181_a[j4 * 3 + 2] * f5); + } + } + if(i2 < 31) + { + float f6 = f3 * 0.9F; + if(field_1186_c[i3 + 1] <= j2) + { + field_1186_c[i3 + 1] = j2; + field_1180_b[i3 + 1] = 0xff000000 | (int)(field_1181_a[j4 * 3 + 0] * f6) << 16 | (int)(field_1181_a[j4 * 3 + 1] * f6) << 8 | (int)(field_1181_a[j4 * 3 + 2] * f6); + } + } + } + if(k2 < -1 || k2 >= 159) + { + continue; + } + int j3 = i2 + (k2 + 1) * 32; + int l3 = field_1182_g[block.blockID * 3 + 1]; + float f4 = world.getLightBrightness(j1 - 1, j2, i1) * 0.8F + 0.2F; + int k4 = field_1182_g[block.blockID * 3 + 2]; + float f7 = world.getLightBrightness(j1, j2, i1 + 1) * 0.8F + 0.2F; + if(i2 >= 0) + { + float f8 = f4 * f * 0.6F; + if(field_1186_c[j3] <= j2 - 1) + { + field_1186_c[j3] = j2 - 1; + field_1180_b[j3] = 0xff000000 | (int)(field_1181_a[l3 * 3 + 0] * f8) << 16 | (int)(field_1181_a[l3 * 3 + 1] * f8) << 8 | (int)(field_1181_a[l3 * 3 + 2] * f8); + } + } + if(i2 >= 31) + { + continue; + } + float f9 = f7 * 0.9F * f * 0.4F; + if(field_1186_c[j3 + 1] <= j2 - 1) + { + field_1186_c[j3 + 1] = j2 - 1; + field_1180_b[j3 + 1] = 0xff000000 | (int)(field_1181_a[k4 * 3 + 0] * f9) << 16 | (int)(field_1181_a[k4 * 3 + 1] * f9) << 8 | (int)(field_1181_a[k4 * 3 + 2] * f9); + } + } + + } + + } + + func_800_a(); + if(isoimagebuffer.field_1348_a == null) + { + isoimagebuffer.field_1348_a = new BufferedImage(32, 160, 2); + } + isoimagebuffer.field_1348_a.setRGB(0, 0, 32, 160, field_1180_b, 0, 32); + isoimagebuffer.field_1352_e = true; + } + + private void func_800_a() + { + for(int i = 0; i < 32; i++) + { + for(int j = 0; j < 160; j++) + { + int k = i + j * 32; + if(field_1186_c[k] == 0) + { + field_1180_b[k] = 0; + } + if(field_1185_d[k] <= field_1186_c[k]) + { + continue; + } + int l = field_1180_b[k] >> 24 & 0xff; + field_1180_b[k] = ((field_1180_b[k] & 0xfefefe) >> 1) + field_1184_e[k]; + if(l < 128) + { + field_1180_b[k] = 0x80000000 + field_1184_e[k] * 2; + } else + { + field_1180_b[k] |= 0xff000000; + } + } + + } + + } + + private float field_1181_a[]; + private int field_1180_b[]; + private int field_1186_c[]; + private int field_1185_d[]; + private int field_1184_e[]; + private int field_1183_f[]; + private int field_1182_g[]; +} diff --git a/src/main/java/net/minecraft/src/Tessellator.java b/src/main/java/net/minecraft/src/Tessellator.java new file mode 100644 index 0000000..069f5db --- /dev/null +++ b/src/main/java/net/minecraft/src/Tessellator.java @@ -0,0 +1,361 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.nio.*; +import org.lwjgl.opengl.*; + +public class Tessellator +{ + + private Tessellator(int i) + { + vertexCount = 0; + hasColor = false; + hasTexture = false; + hasNormals = false; + rawBufferIndex = 0; + addedVertices = 0; + isColorDisabled = false; + isDrawing = false; + useVBO = false; + vboIndex = 0; + vboCount = 10; + bufferSize = i; + byteBuffer = GLAllocation.createDirectByteBuffer(i * 4); + intBuffer = byteBuffer.asIntBuffer(); + floatBuffer = byteBuffer.asFloatBuffer(); + rawBuffer = new int[i]; + useVBO = tryVBO && GLContext.getCapabilities().GL_ARB_vertex_buffer_object; + if(useVBO) + { + vertexBuffers = GLAllocation.createDirectIntBuffer(vboCount); + ARBVertexBufferObject.glGenBuffersARB(vertexBuffers); + } + } + + public void draw() + { + if(!isDrawing) + { + throw new IllegalStateException("Not tesselating!"); + } + isDrawing = false; + if(vertexCount > 0) + { + intBuffer.clear(); + intBuffer.put(rawBuffer, 0, rawBufferIndex); + byteBuffer.position(0); + byteBuffer.limit(rawBufferIndex * 4); + if(useVBO) + { + vboIndex = (vboIndex + 1) % vboCount; + ARBVertexBufferObject.glBindBufferARB(34962 /*GL_ARRAY_BUFFER_ARB*/, vertexBuffers.get(vboIndex)); + ARBVertexBufferObject.glBufferDataARB(34962 /*GL_ARRAY_BUFFER_ARB*/, byteBuffer, 35040 /*GL_STREAM_DRAW_ARB*/); + } + if(hasTexture) + { + if(useVBO) + { + GL11.glTexCoordPointer(2, 5126 /*GL_FLOAT*/, 32, 12L); + } else + { + floatBuffer.position(3); + GL11.glTexCoordPointer(2, 32, floatBuffer); + } + GL11.glEnableClientState(32888 /*GL_TEXTURE_COORD_ARRAY_EXT*/); + } + if(hasColor) + { + if(useVBO) + { + GL11.glColorPointer(4, 5121 /*GL_UNSIGNED_BYTE*/, 32, 20L); + } else + { + byteBuffer.position(20); + GL11.glColorPointer(4, true, 32, byteBuffer); + } + GL11.glEnableClientState(32886 /*GL_COLOR_ARRAY_EXT*/); + } + if(hasNormals) + { + if(useVBO) + { + GL11.glNormalPointer(5120 /*GL_BYTE*/, 32, 24L); + } else + { + byteBuffer.position(24); + GL11.glNormalPointer(32, byteBuffer); + } + GL11.glEnableClientState(32885 /*GL_NORMAL_ARRAY_EXT*/); + } + if(useVBO) + { + GL11.glVertexPointer(3, 5126 /*GL_FLOAT*/, 32, 0L); + } else + { + floatBuffer.position(0); + GL11.glVertexPointer(3, 32, floatBuffer); + } + GL11.glEnableClientState(32884 /*GL_VERTEX_ARRAY_EXT*/); + if(drawMode == 7 && convertQuadsToTriangles) + { + GL11.glDrawArrays(4, 0, vertexCount); + } else + { + GL11.glDrawArrays(drawMode, 0, vertexCount); + } + GL11.glDisableClientState(32884 /*GL_VERTEX_ARRAY_EXT*/); + if(hasTexture) + { + GL11.glDisableClientState(32888 /*GL_TEXTURE_COORD_ARRAY_EXT*/); + } + if(hasColor) + { + GL11.glDisableClientState(32886 /*GL_COLOR_ARRAY_EXT*/); + } + if(hasNormals) + { + GL11.glDisableClientState(32885 /*GL_NORMAL_ARRAY_EXT*/); + } + } + reset(); + } + + private void reset() + { + vertexCount = 0; + byteBuffer.clear(); + rawBufferIndex = 0; + addedVertices = 0; + } + + public void startDrawingQuads() + { + startDrawing(7); + } + + public void startDrawing(int i) + { + if(isDrawing) + { + throw new IllegalStateException("Already tesselating!"); + } else + { + isDrawing = true; + reset(); + drawMode = i; + hasNormals = false; + hasColor = false; + hasTexture = false; + isColorDisabled = false; + return; + } + } + + public void setTextureUV(double d, double d1) + { + hasTexture = true; + textureU = d; + textureV = d1; + } + + public void setColorOpaque_F(float f, float f1, float f2) + { + setColorOpaque((int)(f * 255F), (int)(f1 * 255F), (int)(f2 * 255F)); + } + + public void setColorRGBA_F(float f, float f1, float f2, float f3) + { + setColorRGBA((int)(f * 255F), (int)(f1 * 255F), (int)(f2 * 255F), (int)(f3 * 255F)); + } + + public void setColorOpaque(int i, int j, int k) + { + setColorRGBA(i, j, k, 255); + } + + public void setColorRGBA(int i, int j, int k, int l) + { + if(isColorDisabled) + { + return; + } + if(i > 255) + { + i = 255; + } + if(j > 255) + { + j = 255; + } + if(k > 255) + { + k = 255; + } + if(l > 255) + { + l = 255; + } + if(i < 0) + { + i = 0; + } + if(j < 0) + { + j = 0; + } + if(k < 0) + { + k = 0; + } + if(l < 0) + { + l = 0; + } + hasColor = true; + if(ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) + { + color = l << 24 | k << 16 | j << 8 | i; + } else + { + color = i << 24 | j << 16 | k << 8 | l; + } + } + + public void addVertexWithUV(double d, double d1, double d2, double d3, double d4) + { + setTextureUV(d3, d4); + addVertex(d, d1, d2); + } + + public void addVertex(double d, double d1, double d2) + { + addedVertices++; + if(drawMode == 7 && convertQuadsToTriangles && addedVertices % 4 == 0) + { + for(int i = 0; i < 2; i++) + { + int j = 8 * (3 - i); + if(hasTexture) + { + rawBuffer[rawBufferIndex + 3] = rawBuffer[(rawBufferIndex - j) + 3]; + rawBuffer[rawBufferIndex + 4] = rawBuffer[(rawBufferIndex - j) + 4]; + } + if(hasColor) + { + rawBuffer[rawBufferIndex + 5] = rawBuffer[(rawBufferIndex - j) + 5]; + } + rawBuffer[rawBufferIndex + 0] = rawBuffer[(rawBufferIndex - j) + 0]; + rawBuffer[rawBufferIndex + 1] = rawBuffer[(rawBufferIndex - j) + 1]; + rawBuffer[rawBufferIndex + 2] = rawBuffer[(rawBufferIndex - j) + 2]; + vertexCount++; + rawBufferIndex += 8; + } + + } + if(hasTexture) + { + rawBuffer[rawBufferIndex + 3] = Float.floatToRawIntBits((float)textureU); + rawBuffer[rawBufferIndex + 4] = Float.floatToRawIntBits((float)textureV); + } + if(hasColor) + { + rawBuffer[rawBufferIndex + 5] = color; + } + if(hasNormals) + { + rawBuffer[rawBufferIndex + 6] = normal; + } + rawBuffer[rawBufferIndex + 0] = Float.floatToRawIntBits((float)(d + xOffset)); + rawBuffer[rawBufferIndex + 1] = Float.floatToRawIntBits((float)(d1 + yOffset)); + rawBuffer[rawBufferIndex + 2] = Float.floatToRawIntBits((float)(d2 + zOffset)); + rawBufferIndex += 8; + vertexCount++; + if(vertexCount % 4 == 0 && rawBufferIndex >= bufferSize - 32) + { + draw(); + isDrawing = true; + } + } + + public void setColorOpaque_I(int i) + { + int j = i >> 16 & 0xff; + int k = i >> 8 & 0xff; + int l = i & 0xff; + setColorOpaque(j, k, l); + } + + public void setColorRGBA_I(int i, int j) + { + int k = i >> 16 & 0xff; + int l = i >> 8 & 0xff; + int i1 = i & 0xff; + setColorRGBA(k, l, i1, j); + } + + public void disableColor() + { + isColorDisabled = true; + } + + public void setNormal(float f, float f1, float f2) + { + if(!isDrawing) + { + System.out.println("But.."); + } + hasNormals = true; + byte byte0 = (byte)(int)(f * 128F); + byte byte1 = (byte)(int)(f1 * 127F); + byte byte2 = (byte)(int)(f2 * 127F); + normal = byte0 | byte1 << 8 | byte2 << 16; + } + + public void setTranslationD(double d, double d1, double d2) + { + xOffset = d; + yOffset = d1; + zOffset = d2; + } + + public void setTranslationF(float f, float f1, float f2) + { + xOffset += f; + yOffset += f1; + zOffset += f2; + } + + private static boolean convertQuadsToTriangles = true; + private static boolean tryVBO = false; + private ByteBuffer byteBuffer; + private IntBuffer intBuffer; + private FloatBuffer floatBuffer; + private int rawBuffer[]; + private int vertexCount; + private double textureU; + private double textureV; + private int color; + private boolean hasColor; + private boolean hasTexture; + private boolean hasNormals; + private int rawBufferIndex; + private int addedVertices; + private boolean isColorDisabled; + private int drawMode; + private double xOffset; + private double yOffset; + private double zOffset; + private int normal; + public static final Tessellator instance = new Tessellator(0x200000); + private boolean isDrawing; + private boolean useVBO; + private IntBuffer vertexBuffers; + private int vboIndex; + private int vboCount; + private int bufferSize; + +} diff --git a/src/main/java/net/minecraft/src/TextureCompassFX.java b/src/main/java/net/minecraft/src/TextureCompassFX.java new file mode 100644 index 0000000..ee47693 --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureCompassFX.java @@ -0,0 +1,138 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import net.minecraft.client.Minecraft; + +public class TextureCompassFX extends TextureFX +{ + + public TextureCompassFX(Minecraft minecraft) + { + super(Item.compass.getIconIndex(null)); + field_4230_h = new int[256]; + mc = minecraft; + tileImage = 1; + try + { + BufferedImage bufferedimage = ImageIO.read((net.minecraft.client.Minecraft.class).getResource("/gui/items.png")); + int i = (iconIndex % 16) * 16; + int j = (iconIndex / 16) * 16; + bufferedimage.getRGB(i, j, 16, 16, field_4230_h, 0, 16); + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + public void onTick() + { + for(int i = 0; i < 256; i++) + { + int j = field_4230_h[i] >> 24 & 0xff; + int k = field_4230_h[i] >> 16 & 0xff; + int l = field_4230_h[i] >> 8 & 0xff; + int i1 = field_4230_h[i] >> 0 & 0xff; + if(anaglyphEnabled) + { + int j1 = (k * 30 + l * 59 + i1 * 11) / 100; + int k1 = (k * 30 + l * 70) / 100; + int l1 = (k * 30 + i1 * 70) / 100; + k = j1; + l = k1; + i1 = l1; + } + imageData[i * 4 + 0] = (byte)k; + imageData[i * 4 + 1] = (byte)l; + imageData[i * 4 + 2] = (byte)i1; + imageData[i * 4 + 3] = (byte)j; + } + + double d = 0.0D; + if(mc.theWorld != null && mc.thePlayer != null) + { + ChunkCoordinates chunkcoordinates = mc.theWorld.func_22137_s(); + double d2 = (double)chunkcoordinates.field_22395_a - mc.thePlayer.posX; + double d4 = (double)chunkcoordinates.field_22396_c - mc.thePlayer.posZ; + d = ((double)(mc.thePlayer.rotationYaw - 90F) * 3.1415926535897931D) / 180D - Math.atan2(d4, d2); + if(mc.theWorld.worldProvider.field_4220_c) + { + d = Math.random() * 3.1415927410125732D * 2D; + } + } + double d1; + for(d1 = d - field_4229_i; d1 < -3.1415926535897931D; d1 += 6.2831853071795862D) { } + for(; d1 >= 3.1415926535897931D; d1 -= 6.2831853071795862D) { } + if(d1 < -1D) + { + d1 = -1D; + } + if(d1 > 1.0D) + { + d1 = 1.0D; + } + field_4228_j += d1 * 0.10000000000000001D; + field_4228_j *= 0.80000000000000004D; + field_4229_i += field_4228_j; + double d3 = Math.sin(field_4229_i); + double d5 = Math.cos(field_4229_i); + for(int i2 = -4; i2 <= 4; i2++) + { + int k2 = (int)(8.5D + d5 * (double)i2 * 0.29999999999999999D); + int i3 = (int)(7.5D - d3 * (double)i2 * 0.29999999999999999D * 0.5D); + int k3 = i3 * 16 + k2; + int i4 = 100; + int k4 = 100; + int i5 = 100; + char c = '\377'; + if(anaglyphEnabled) + { + int k5 = (i4 * 30 + k4 * 59 + i5 * 11) / 100; + int i6 = (i4 * 30 + k4 * 70) / 100; + int k6 = (i4 * 30 + i5 * 70) / 100; + i4 = k5; + k4 = i6; + i5 = k6; + } + imageData[k3 * 4 + 0] = (byte)i4; + imageData[k3 * 4 + 1] = (byte)k4; + imageData[k3 * 4 + 2] = (byte)i5; + imageData[k3 * 4 + 3] = (byte)c; + } + + for(int j2 = -8; j2 <= 16; j2++) + { + int l2 = (int)(8.5D + d3 * (double)j2 * 0.29999999999999999D); + int j3 = (int)(7.5D + d5 * (double)j2 * 0.29999999999999999D * 0.5D); + int l3 = j3 * 16 + l2; + int j4 = j2 < 0 ? 100 : 255; + int l4 = j2 < 0 ? 100 : 20; + int j5 = j2 < 0 ? 100 : 20; + char c1 = '\377'; + if(anaglyphEnabled) + { + int l5 = (j4 * 30 + l4 * 59 + j5 * 11) / 100; + int j6 = (j4 * 30 + l4 * 70) / 100; + int l6 = (j4 * 30 + j5 * 70) / 100; + j4 = l5; + l4 = j6; + j5 = l6; + } + imageData[l3 * 4 + 0] = (byte)j4; + imageData[l3 * 4 + 1] = (byte)l4; + imageData[l3 * 4 + 2] = (byte)j5; + imageData[l3 * 4 + 3] = (byte)c1; + } + + } + + private Minecraft mc; + private int field_4230_h[]; + private double field_4229_i; + private double field_4228_j; +} diff --git a/src/main/java/net/minecraft/src/TextureFX.java b/src/main/java/net/minecraft/src/TextureFX.java new file mode 100644 index 0000000..d4f51f1 --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureFX.java @@ -0,0 +1,43 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class TextureFX +{ + + public TextureFX(int i) + { + imageData = new byte[1024 /*GL_FRONT_LEFT*/]; + anaglyphEnabled = false; + field_1130_d = 0; + tileSize = 1; + tileImage = 0; + iconIndex = i; + } + + public void onTick() + { + } + + public void bindImage(RenderEngine renderengine) + { + if(tileImage == 0) + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderengine.getTexture("/terrain.png")); + } else + if(tileImage == 1) + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderengine.getTexture("/gui/items.png")); + } + } + + public byte imageData[]; + public int iconIndex; + public boolean anaglyphEnabled; + public int field_1130_d; + public int tileSize; + public int tileImage; +} diff --git a/src/main/java/net/minecraft/src/TextureFlamesFX.java b/src/main/java/net/minecraft/src/TextureFlamesFX.java new file mode 100644 index 0000000..07fc4e4 --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureFlamesFX.java @@ -0,0 +1,92 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TextureFlamesFX extends TextureFX +{ + + public TextureFlamesFX(int i) + { + super(Block.fire.blockIndexInTexture + i * 16); + field_1133_g = new float[320]; + field_1132_h = new float[320]; + } + + public void onTick() + { + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 20; j++) + { + int l = 18; + float f1 = field_1133_g[i + ((j + 1) % 20) * 16] * (float)l; + for(int i1 = i - 1; i1 <= i + 1; i1++) + { + for(int k1 = j; k1 <= j + 1; k1++) + { + int i2 = i1; + int k2 = k1; + if(i2 >= 0 && k2 >= 0 && i2 < 16 && k2 < 20) + { + f1 += field_1133_g[i2 + k2 * 16]; + } + l++; + } + + } + + field_1132_h[i + j * 16] = f1 / ((float)l * 1.06F); + if(j >= 19) + { + field_1132_h[i + j * 16] = (float)(Math.random() * Math.random() * Math.random() * 4D + Math.random() * 0.10000000149011612D + 0.20000000298023224D); + } + } + + } + + float af[] = field_1132_h; + field_1132_h = field_1133_g; + field_1133_g = af; + for(int k = 0; k < 256; k++) + { + float f = field_1133_g[k] * 1.8F; + if(f > 1.0F) + { + f = 1.0F; + } + if(f < 0.0F) + { + f = 0.0F; + } + float f2 = f; + int j1 = (int)(f2 * 155F + 100F); + int l1 = (int)(f2 * f2 * 255F); + int j2 = (int)(f2 * f2 * f2 * f2 * f2 * f2 * f2 * f2 * f2 * f2 * 255F); + char c = '\377'; + if(f2 < 0.5F) + { + c = '\0'; + } + f2 = (f2 - 0.5F) * 2.0F; + if(anaglyphEnabled) + { + int l2 = (j1 * 30 + l1 * 59 + j2 * 11) / 100; + int i3 = (j1 * 30 + l1 * 70) / 100; + int j3 = (j1 * 30 + j2 * 70) / 100; + j1 = l2; + l1 = i3; + j2 = j3; + } + imageData[k * 4 + 0] = (byte)j1; + imageData[k * 4 + 1] = (byte)l1; + imageData[k * 4 + 2] = (byte)j2; + imageData[k * 4 + 3] = (byte)c; + } + + } + + protected float field_1133_g[]; + protected float field_1132_h[]; +} diff --git a/src/main/java/net/minecraft/src/TextureLavaFX.java b/src/main/java/net/minecraft/src/TextureLavaFX.java new file mode 100644 index 0000000..73d3cb4 --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureLavaFX.java @@ -0,0 +1,93 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TextureLavaFX extends TextureFX +{ + + public TextureLavaFX() + { + super(Block.lavaStill.blockIndexInTexture); + field_1147_g = new float[256]; + field_1146_h = new float[256]; + field_1145_i = new float[256]; + field_1144_j = new float[256]; + } + + public void onTick() + { + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 16; j++) + { + float f = 0.0F; + int l = (int)(MathHelper.sin(((float)j * 3.141593F * 2.0F) / 16F) * 1.2F); + int i1 = (int)(MathHelper.sin(((float)i * 3.141593F * 2.0F) / 16F) * 1.2F); + for(int k1 = i - 1; k1 <= i + 1; k1++) + { + for(int i2 = j - 1; i2 <= j + 1; i2++) + { + int k2 = k1 + l & 0xf; + int i3 = i2 + i1 & 0xf; + f += field_1147_g[k2 + i3 * 16]; + } + + } + + field_1146_h[i + j * 16] = f / 10F + ((field_1145_i[(i + 0 & 0xf) + (j + 0 & 0xf) * 16] + field_1145_i[(i + 1 & 0xf) + (j + 0 & 0xf) * 16] + field_1145_i[(i + 1 & 0xf) + (j + 1 & 0xf) * 16] + field_1145_i[(i + 0 & 0xf) + (j + 1 & 0xf) * 16]) / 4F) * 0.8F; + field_1145_i[i + j * 16] += field_1144_j[i + j * 16] * 0.01F; + if(field_1145_i[i + j * 16] < 0.0F) + { + field_1145_i[i + j * 16] = 0.0F; + } + field_1144_j[i + j * 16] -= 0.06F; + if(Math.random() < 0.0050000000000000001D) + { + field_1144_j[i + j * 16] = 1.5F; + } + } + + } + + float af[] = field_1146_h; + field_1146_h = field_1147_g; + field_1147_g = af; + for(int k = 0; k < 256; k++) + { + float f1 = field_1147_g[k] * 2.0F; + if(f1 > 1.0F) + { + f1 = 1.0F; + } + if(f1 < 0.0F) + { + f1 = 0.0F; + } + float f2 = f1; + int j1 = (int)(f2 * 100F + 155F); + int l1 = (int)(f2 * f2 * 255F); + int j2 = (int)(f2 * f2 * f2 * f2 * 128F); + if(anaglyphEnabled) + { + int l2 = (j1 * 30 + l1 * 59 + j2 * 11) / 100; + int j3 = (j1 * 30 + l1 * 70) / 100; + int k3 = (j1 * 30 + j2 * 70) / 100; + j1 = l2; + l1 = j3; + j2 = k3; + } + imageData[k * 4 + 0] = (byte)j1; + imageData[k * 4 + 1] = (byte)l1; + imageData[k * 4 + 2] = (byte)j2; + imageData[k * 4 + 3] = -1; + } + + } + + protected float field_1147_g[]; + protected float field_1146_h[]; + protected float field_1145_i[]; + protected float field_1144_j[]; +} diff --git a/src/main/java/net/minecraft/src/TextureLavaFlowFX.java b/src/main/java/net/minecraft/src/TextureLavaFlowFX.java new file mode 100644 index 0000000..2f43642 --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureLavaFlowFX.java @@ -0,0 +1,97 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TextureLavaFlowFX extends TextureFX +{ + + public TextureLavaFlowFX() + { + super(Block.lavaStill.blockIndexInTexture + 1); + field_1143_g = new float[256]; + field_1142_h = new float[256]; + field_1141_i = new float[256]; + field_1140_j = new float[256]; + field_1139_k = 0; + tileSize = 2; + } + + public void onTick() + { + field_1139_k++; + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 16; j++) + { + float f = 0.0F; + int l = (int)(MathHelper.sin(((float)j * 3.141593F * 2.0F) / 16F) * 1.2F); + int i1 = (int)(MathHelper.sin(((float)i * 3.141593F * 2.0F) / 16F) * 1.2F); + for(int k1 = i - 1; k1 <= i + 1; k1++) + { + for(int i2 = j - 1; i2 <= j + 1; i2++) + { + int k2 = k1 + l & 0xf; + int i3 = i2 + i1 & 0xf; + f += field_1143_g[k2 + i3 * 16]; + } + + } + + field_1142_h[i + j * 16] = f / 10F + ((field_1141_i[(i + 0 & 0xf) + (j + 0 & 0xf) * 16] + field_1141_i[(i + 1 & 0xf) + (j + 0 & 0xf) * 16] + field_1141_i[(i + 1 & 0xf) + (j + 1 & 0xf) * 16] + field_1141_i[(i + 0 & 0xf) + (j + 1 & 0xf) * 16]) / 4F) * 0.8F; + field_1141_i[i + j * 16] += field_1140_j[i + j * 16] * 0.01F; + if(field_1141_i[i + j * 16] < 0.0F) + { + field_1141_i[i + j * 16] = 0.0F; + } + field_1140_j[i + j * 16] -= 0.06F; + if(Math.random() < 0.0050000000000000001D) + { + field_1140_j[i + j * 16] = 1.5F; + } + } + + } + + float af[] = field_1142_h; + field_1142_h = field_1143_g; + field_1143_g = af; + for(int k = 0; k < 256; k++) + { + float f1 = field_1143_g[k - (field_1139_k / 3) * 16 & 0xff] * 2.0F; + if(f1 > 1.0F) + { + f1 = 1.0F; + } + if(f1 < 0.0F) + { + f1 = 0.0F; + } + float f2 = f1; + int j1 = (int)(f2 * 100F + 155F); + int l1 = (int)(f2 * f2 * 255F); + int j2 = (int)(f2 * f2 * f2 * f2 * 128F); + if(anaglyphEnabled) + { + int l2 = (j1 * 30 + l1 * 59 + j2 * 11) / 100; + int j3 = (j1 * 30 + l1 * 70) / 100; + int k3 = (j1 * 30 + j2 * 70) / 100; + j1 = l2; + l1 = j3; + j2 = k3; + } + imageData[k * 4 + 0] = (byte)j1; + imageData[k * 4 + 1] = (byte)l1; + imageData[k * 4 + 2] = (byte)j2; + imageData[k * 4 + 3] = -1; + } + + } + + protected float field_1143_g[]; + protected float field_1142_h[]; + protected float field_1141_i[]; + protected float field_1140_j[]; + int field_1139_k; +} diff --git a/src/main/java/net/minecraft/src/TexturePackBase.java b/src/main/java/net/minecraft/src/TexturePackBase.java new file mode 100644 index 0000000..ec2ba8f --- /dev/null +++ b/src/main/java/net/minecraft/src/TexturePackBase.java @@ -0,0 +1,45 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.InputStream; +import net.minecraft.client.Minecraft; + +public abstract class TexturePackBase +{ + + public TexturePackBase() + { + } + + public void func_6482_a() + { + } + + public void closeTexturePackFile() + { + } + + public void func_6485_a(Minecraft minecraft) + { + } + + public void func_6484_b(Minecraft minecraft) + { + } + + public void func_6483_c(Minecraft minecraft) + { + } + + public InputStream func_6481_a(String s) + { + return (TexturePackBase.class).getResourceAsStream(s); + } + + public String texturePackFileName; + public String firstDescriptionLine; + public String secondDescriptionLine; + public String field_6488_d; +} diff --git a/src/main/java/net/minecraft/src/TexturePackCustom.java b/src/main/java/net/minecraft/src/TexturePackCustom.java new file mode 100644 index 0000000..821d45e --- /dev/null +++ b/src/main/java/net/minecraft/src/TexturePackCustom.java @@ -0,0 +1,138 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.zip.ZipFile; +import javax.imageio.ImageIO; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class TexturePackCustom extends TexturePackBase +{ + + public TexturePackCustom(File file) + { + texturePackName = -1; + texturePackFileName = file.getName(); + texturePackFile = file; + } + + private String truncateString(String s) + { + if(s != null && s.length() > 34) + { + s = s.substring(0, 34); + } + return s; + } + + public void func_6485_a(Minecraft minecraft) + { + ZipFile zipfile = null; + InputStream inputstream = null; + try + { + zipfile = new ZipFile(texturePackFile); + try + { + inputstream = zipfile.getInputStream(zipfile.getEntry("pack.txt")); + BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(inputstream)); + firstDescriptionLine = truncateString(bufferedreader.readLine()); + secondDescriptionLine = truncateString(bufferedreader.readLine()); + bufferedreader.close(); + inputstream.close(); + } + catch(Exception exception) { } + try + { + inputstream = zipfile.getInputStream(zipfile.getEntry("pack.png")); + texturePackThumbnail = ImageIO.read(inputstream); + inputstream.close(); + } + catch(Exception exception1) { } + zipfile.close(); + } + catch(Exception exception2) + { + exception2.printStackTrace(); + } + finally + { + try + { + inputstream.close(); + } + catch(Exception exception4) { } + try + { + zipfile.close(); + } + catch(Exception exception5) { } + } + } + + public void func_6484_b(Minecraft minecraft) + { + if(texturePackThumbnail != null) + { + minecraft.renderEngine.deleteTexture(texturePackName); + } + closeTexturePackFile(); + } + + public void func_6483_c(Minecraft minecraft) + { + if(texturePackThumbnail != null && texturePackName < 0) + { + texturePackName = minecraft.renderEngine.allocateAndSetupTexture(texturePackThumbnail); + } + if(texturePackThumbnail != null) + { + minecraft.renderEngine.bindTexture(texturePackName); + } else + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, minecraft.renderEngine.getTexture("/gui/unknown_pack.png")); + } + } + + public void func_6482_a() + { + try + { + texturePackZipFile = new ZipFile(texturePackFile); + } + catch(Exception exception) { } + } + + public void closeTexturePackFile() + { + try + { + texturePackZipFile.close(); + } + catch(Exception exception) { } + texturePackZipFile = null; + } + + public InputStream func_6481_a(String s) + { + try + { + java.util.zip.ZipEntry zipentry = texturePackZipFile.getEntry(s.substring(1)); + if(zipentry != null) + { + return texturePackZipFile.getInputStream(zipentry); + } + } + catch(Exception exception) { } + return (TexturePackBase.class).getResourceAsStream(s); + } + + private ZipFile texturePackZipFile; + private int texturePackName; + private BufferedImage texturePackThumbnail; + private File texturePackFile; +} diff --git a/src/main/java/net/minecraft/src/TexturePackDefault.java b/src/main/java/net/minecraft/src/TexturePackDefault.java new file mode 100644 index 0000000..a849974 --- /dev/null +++ b/src/main/java/net/minecraft/src/TexturePackDefault.java @@ -0,0 +1,55 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL11; + +public class TexturePackDefault extends TexturePackBase +{ + + public TexturePackDefault() + { + texturePackName = -1; + texturePackFileName = "Default"; + firstDescriptionLine = "The default look of Minecraft"; + try + { + texturePackThumbnail = ImageIO.read((TexturePackDefault.class).getResource("/pack.png")); + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + public void func_6484_b(Minecraft minecraft) + { + if(texturePackThumbnail != null) + { + minecraft.renderEngine.deleteTexture(texturePackName); + } + } + + public void func_6483_c(Minecraft minecraft) + { + if(texturePackThumbnail != null && texturePackName < 0) + { + texturePackName = minecraft.renderEngine.allocateAndSetupTexture(texturePackThumbnail); + } + if(texturePackThumbnail != null) + { + minecraft.renderEngine.bindTexture(texturePackName); + } else + { + GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, minecraft.renderEngine.getTexture("/gui/unknown_pack.png")); + } + } + + private int texturePackName; + private BufferedImage texturePackThumbnail; +} diff --git a/src/main/java/net/minecraft/src/TexturePackList.java b/src/main/java/net/minecraft/src/TexturePackList.java new file mode 100644 index 0000000..660d0e8 --- /dev/null +++ b/src/main/java/net/minecraft/src/TexturePackList.java @@ -0,0 +1,108 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.File; +import java.io.IOException; +import java.util.*; +import net.minecraft.client.Minecraft; + +public class TexturePackList +{ + + public TexturePackList(Minecraft minecraft, File file) + { + availableTexturePacks = new ArrayList(); + defaultTexturePack = new TexturePackDefault(); + field_6538_d = new HashMap(); + mc = minecraft; + texturePackDir = new File(file, "texturepacks"); + if(!texturePackDir.exists()) + { + texturePackDir.mkdirs(); + } + currentTexturePack = minecraft.gameSettings.skin; + func_6532_a(); + selectedTexturePack.func_6482_a(); + } + + public boolean setTexturePack(TexturePackBase texturepackbase) + { + if(texturepackbase == selectedTexturePack) + { + return false; + } else + { + selectedTexturePack.closeTexturePackFile(); + currentTexturePack = texturepackbase.texturePackFileName; + selectedTexturePack = texturepackbase; + mc.gameSettings.skin = currentTexturePack; + mc.gameSettings.saveOptions(); + selectedTexturePack.func_6482_a(); + return true; + } + } + + public void func_6532_a() + { + ArrayList arraylist = new ArrayList(); + selectedTexturePack = null; + arraylist.add(defaultTexturePack); + if(texturePackDir.exists() && texturePackDir.isDirectory()) + { + File afile[] = texturePackDir.listFiles(); + File afile1[] = afile; + int i = afile1.length; + for(int j = 0; j < i; j++) + { + File file = afile1[j]; + if(!file.isFile() || !file.getName().toLowerCase().endsWith(".zip")) + { + continue; + } + String s = (new StringBuilder()).append(file.getName()).append(":").append(file.length()).append(":").append(file.lastModified()).toString(); + if(!field_6538_d.containsKey(s)) + { + TexturePackCustom texturepackcustom = new TexturePackCustom(file); + texturepackcustom.field_6488_d = s; + field_6538_d.put(s, texturepackcustom); + texturepackcustom.func_6485_a(mc); + } + TexturePackBase texturepackbase1 = (TexturePackBase)field_6538_d.get(s); + if(texturepackbase1.texturePackFileName.equals(currentTexturePack)) + { + selectedTexturePack = texturepackbase1; + } + arraylist.add(texturepackbase1); + } + + } + if(selectedTexturePack == null) + { + selectedTexturePack = defaultTexturePack; + } + availableTexturePacks.removeAll(arraylist); + TexturePackBase texturepackbase; + for(Iterator iterator = availableTexturePacks.iterator(); iterator.hasNext(); field_6538_d.remove(texturepackbase.field_6488_d)) + { + texturepackbase = (TexturePackBase)iterator.next(); + texturepackbase.func_6484_b(mc); + } + + availableTexturePacks = arraylist; + } + + public List availableTexturePacks() + { + return new ArrayList(availableTexturePacks); + } + + private List availableTexturePacks; + private TexturePackBase defaultTexturePack; + public TexturePackBase selectedTexturePack; + private Map field_6538_d; + private Minecraft mc; + private File texturePackDir; + private String currentTexturePack; +} diff --git a/src/main/java/net/minecraft/src/TexturePortalFX.java b/src/main/java/net/minecraft/src/TexturePortalFX.java new file mode 100644 index 0000000..f602f1f --- /dev/null +++ b/src/main/java/net/minecraft/src/TexturePortalFX.java @@ -0,0 +1,100 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class TexturePortalFX extends TextureFX +{ + + public TexturePortalFX() + { + super(Block.portal.blockIndexInTexture); + field_4227_g = 0; + field_4226_h = new byte[32][1024]; + Random random = new Random(100L); + for(int i = 0; i < 32; i++) + { + for(int j = 0; j < 16; j++) + { + for(int k = 0; k < 16; k++) + { + float f = 0.0F; + for(int l = 0; l < 2; l++) + { + float f1 = l * 8; + float f2 = l * 8; + float f3 = (((float)j - f1) / 16F) * 2.0F; + float f4 = (((float)k - f2) / 16F) * 2.0F; + if(f3 < -1F) + { + f3 += 2.0F; + } + if(f3 >= 1.0F) + { + f3 -= 2.0F; + } + if(f4 < -1F) + { + f4 += 2.0F; + } + if(f4 >= 1.0F) + { + f4 -= 2.0F; + } + float f5 = f3 * f3 + f4 * f4; + float f6 = (float)Math.atan2(f4, f3) + ((((float)i / 32F) * 3.141593F * 2.0F - f5 * 10F) + (float)(l * 2)) * (float)(l * 2 - 1); + f6 = (MathHelper.sin(f6) + 1.0F) / 2.0F; + f6 /= f5 + 1.0F; + f += f6 * 0.5F; + } + + f += random.nextFloat() * 0.1F; + int i1 = (int)(f * 100F + 155F); + int j1 = (int)(f * f * 200F + 55F); + int k1 = (int)(f * f * f * f * 255F); + int l1 = (int)(f * 100F + 155F); + int i2 = k * 16 + j; + field_4226_h[i][i2 * 4 + 0] = (byte)j1; + field_4226_h[i][i2 * 4 + 1] = (byte)k1; + field_4226_h[i][i2 * 4 + 2] = (byte)i1; + field_4226_h[i][i2 * 4 + 3] = (byte)l1; + } + + } + + } + + } + + public void onTick() + { + field_4227_g++; + byte abyte0[] = field_4226_h[field_4227_g & 0x1f]; + for(int i = 0; i < 256; i++) + { + int j = abyte0[i * 4 + 0] & 0xff; + int k = abyte0[i * 4 + 1] & 0xff; + int l = abyte0[i * 4 + 2] & 0xff; + int i1 = abyte0[i * 4 + 3] & 0xff; + if(anaglyphEnabled) + { + int j1 = (j * 30 + k * 59 + l * 11) / 100; + int k1 = (j * 30 + k * 70) / 100; + int l1 = (j * 30 + l * 70) / 100; + j = j1; + k = k1; + l = l1; + } + imageData[i * 4 + 0] = (byte)j; + imageData[i * 4 + 1] = (byte)k; + imageData[i * 4 + 2] = (byte)l; + imageData[i * 4 + 3] = (byte)i1; + } + + } + + private int field_4227_g; + private byte field_4226_h[][]; +} diff --git a/src/main/java/net/minecraft/src/TextureWatchFX.java b/src/main/java/net/minecraft/src/TextureWatchFX.java new file mode 100644 index 0000000..27b69ff --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureWatchFX.java @@ -0,0 +1,105 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.imageio.ImageIO; +import net.minecraft.client.Minecraft; + +public class TextureWatchFX extends TextureFX +{ + + public TextureWatchFX(Minecraft minecraft) + { + super(Item.pocketSundial.getIconIndex(null)); + field_4224_h = new int[256]; + field_4223_i = new int[256]; + field_4225_g = minecraft; + tileImage = 1; + try + { + BufferedImage bufferedimage = ImageIO.read((net.minecraft.client.Minecraft.class).getResource("/gui/items.png")); + int i = (iconIndex % 16) * 16; + int j = (iconIndex / 16) * 16; + bufferedimage.getRGB(i, j, 16, 16, field_4224_h, 0, 16); + bufferedimage = ImageIO.read((net.minecraft.client.Minecraft.class).getResource("/misc/dial.png")); + bufferedimage.getRGB(0, 0, 16, 16, field_4223_i, 0, 16); + } + catch(IOException ioexception) + { + ioexception.printStackTrace(); + } + } + + public void onTick() + { + double d = 0.0D; + if(field_4225_g.theWorld != null && field_4225_g.thePlayer != null) + { + float f = field_4225_g.theWorld.getCelestialAngle(1.0F); + d = -f * 3.141593F * 2.0F; + if(field_4225_g.theWorld.worldProvider.field_4220_c) + { + d = Math.random() * 3.1415927410125732D * 2D; + } + } + double d1; + for(d1 = d - field_4222_j; d1 < -3.1415926535897931D; d1 += 6.2831853071795862D) { } + for(; d1 >= 3.1415926535897931D; d1 -= 6.2831853071795862D) { } + if(d1 < -1D) + { + d1 = -1D; + } + if(d1 > 1.0D) + { + d1 = 1.0D; + } + field_4221_k += d1 * 0.10000000000000001D; + field_4221_k *= 0.80000000000000004D; + field_4222_j += field_4221_k; + double d2 = Math.sin(field_4222_j); + double d3 = Math.cos(field_4222_j); + for(int i = 0; i < 256; i++) + { + int j = field_4224_h[i] >> 24 & 0xff; + int k = field_4224_h[i] >> 16 & 0xff; + int l = field_4224_h[i] >> 8 & 0xff; + int i1 = field_4224_h[i] >> 0 & 0xff; + if(k == i1 && l == 0 && i1 > 0) + { + double d4 = -((double)(i % 16) / 15D - 0.5D); + double d5 = (double)(i / 16) / 15D - 0.5D; + int i2 = k; + int j2 = (int)((d4 * d3 + d5 * d2 + 0.5D) * 16D); + int k2 = (int)(((d5 * d3 - d4 * d2) + 0.5D) * 16D); + int l2 = (j2 & 0xf) + (k2 & 0xf) * 16; + j = field_4223_i[l2] >> 24 & 0xff; + k = ((field_4223_i[l2] >> 16 & 0xff) * i2) / 255; + l = ((field_4223_i[l2] >> 8 & 0xff) * i2) / 255; + i1 = ((field_4223_i[l2] >> 0 & 0xff) * i2) / 255; + } + if(anaglyphEnabled) + { + int j1 = (k * 30 + l * 59 + i1 * 11) / 100; + int k1 = (k * 30 + l * 70) / 100; + int l1 = (k * 30 + i1 * 70) / 100; + k = j1; + l = k1; + i1 = l1; + } + imageData[i * 4 + 0] = (byte)k; + imageData[i * 4 + 1] = (byte)l; + imageData[i * 4 + 2] = (byte)i1; + imageData[i * 4 + 3] = (byte)j; + } + + } + + private Minecraft field_4225_g; + private int field_4224_h[]; + private int field_4223_i[]; + private double field_4222_j; + private double field_4221_k; +} diff --git a/src/main/java/net/minecraft/src/TextureWaterFX.java b/src/main/java/net/minecraft/src/TextureWaterFX.java new file mode 100644 index 0000000..e6ca3ec --- /dev/null +++ b/src/main/java/net/minecraft/src/TextureWaterFX.java @@ -0,0 +1,99 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TextureWaterFX extends TextureFX +{ + + public TextureWaterFX() + { + super(Block.waterStill.blockIndexInTexture); + field_1158_g = new float[256]; + field_1157_h = new float[256]; + field_1156_i = new float[256]; + field_1155_j = new float[256]; + tickCounter = 0; + } + + public void onTick() + { + tickCounter++; + for(int i = 0; i < 16; i++) + { + for(int k = 0; k < 16; k++) + { + float f = 0.0F; + for(int j1 = i - 1; j1 <= i + 1; j1++) + { + int k1 = j1 & 0xf; + int i2 = k & 0xf; + f += field_1158_g[k1 + i2 * 16]; + } + + field_1157_h[i + k * 16] = f / 3.3F + field_1156_i[i + k * 16] * 0.8F; + } + + } + + for(int j = 0; j < 16; j++) + { + for(int l = 0; l < 16; l++) + { + field_1156_i[j + l * 16] += field_1155_j[j + l * 16] * 0.05F; + if(field_1156_i[j + l * 16] < 0.0F) + { + field_1156_i[j + l * 16] = 0.0F; + } + field_1155_j[j + l * 16] -= 0.1F; + if(Math.random() < 0.050000000000000003D) + { + field_1155_j[j + l * 16] = 0.5F; + } + } + + } + + float af[] = field_1157_h; + field_1157_h = field_1158_g; + field_1158_g = af; + for(int i1 = 0; i1 < 256; i1++) + { + float f1 = field_1158_g[i1]; + if(f1 > 1.0F) + { + f1 = 1.0F; + } + if(f1 < 0.0F) + { + f1 = 0.0F; + } + float f2 = f1 * f1; + int l1 = (int)(32F + f2 * 32F); + int j2 = (int)(50F + f2 * 64F); + int k2 = 255; + int l2 = (int)(146F + f2 * 50F); + if(anaglyphEnabled) + { + int i3 = (l1 * 30 + j2 * 59 + k2 * 11) / 100; + int j3 = (l1 * 30 + j2 * 70) / 100; + int k3 = (l1 * 30 + k2 * 70) / 100; + l1 = i3; + j2 = j3; + k2 = k3; + } + imageData[i1 * 4 + 0] = (byte)l1; + imageData[i1 * 4 + 1] = (byte)j2; + imageData[i1 * 4 + 2] = (byte)k2; + imageData[i1 * 4 + 3] = (byte)l2; + } + + } + + protected float field_1158_g[]; + protected float field_1157_h[]; + protected float field_1156_i[]; + protected float field_1155_j[]; + private int tickCounter; +} diff --git a/src/main/java/net/minecraft/src/TexturedQuad.java b/src/main/java/net/minecraft/src/TexturedQuad.java new file mode 100644 index 0000000..37a9e1d --- /dev/null +++ b/src/main/java/net/minecraft/src/TexturedQuad.java @@ -0,0 +1,65 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TexturedQuad +{ + + public TexturedQuad(PositionTexureVertex apositiontexurevertex[]) + { + nVertices = 0; + invertNormal = false; + vertexPositions = apositiontexurevertex; + nVertices = apositiontexurevertex.length; + } + + public TexturedQuad(PositionTexureVertex apositiontexurevertex[], int i, int j, int k, int l) + { + this(apositiontexurevertex); + float f = 0.0015625F; + float f1 = 0.003125F; + apositiontexurevertex[0] = apositiontexurevertex[0].setTexturePosition((float)k / 64F - f, (float)j / 32F + f1); + apositiontexurevertex[1] = apositiontexurevertex[1].setTexturePosition((float)i / 64F + f, (float)j / 32F + f1); + apositiontexurevertex[2] = apositiontexurevertex[2].setTexturePosition((float)i / 64F + f, (float)l / 32F - f1); + apositiontexurevertex[3] = apositiontexurevertex[3].setTexturePosition((float)k / 64F - f, (float)l / 32F - f1); + } + + public void flipFace() + { + PositionTexureVertex apositiontexurevertex[] = new PositionTexureVertex[vertexPositions.length]; + for(int i = 0; i < vertexPositions.length; i++) + { + apositiontexurevertex[i] = vertexPositions[vertexPositions.length - i - 1]; + } + + vertexPositions = apositiontexurevertex; + } + + public void draw(Tessellator tessellator, float f) + { + Vec3D vec3d = vertexPositions[1].vector3D.subtract(vertexPositions[0].vector3D); + Vec3D vec3d1 = vertexPositions[1].vector3D.subtract(vertexPositions[2].vector3D); + Vec3D vec3d2 = vec3d1.crossProduct(vec3d).normalize(); + tessellator.startDrawingQuads(); + if(invertNormal) + { + tessellator.setNormal(-(float)vec3d2.xCoord, -(float)vec3d2.yCoord, -(float)vec3d2.zCoord); + } else + { + tessellator.setNormal((float)vec3d2.xCoord, (float)vec3d2.yCoord, (float)vec3d2.zCoord); + } + for(int i = 0; i < 4; i++) + { + PositionTexureVertex positiontexurevertex = vertexPositions[i]; + tessellator.addVertexWithUV((float)positiontexurevertex.vector3D.xCoord * f, (float)positiontexurevertex.vector3D.yCoord * f, (float)positiontexurevertex.vector3D.zCoord * f, positiontexurevertex.texturePositionX, positiontexurevertex.texturePositionY); + } + + tessellator.draw(); + } + + public PositionTexureVertex vertexPositions[]; + public int nVertices; + private boolean invertNormal; +} diff --git a/src/main/java/net/minecraft/src/TexureWaterFlowFX.java b/src/main/java/net/minecraft/src/TexureWaterFlowFX.java new file mode 100644 index 0000000..a4a50fc --- /dev/null +++ b/src/main/java/net/minecraft/src/TexureWaterFlowFX.java @@ -0,0 +1,100 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TexureWaterFlowFX extends TextureFX +{ + + public TexureWaterFlowFX() + { + super(Block.waterStill.blockIndexInTexture + 1); + field_1138_g = new float[256]; + field_1137_h = new float[256]; + field_1136_i = new float[256]; + field_1135_j = new float[256]; + field_1134_k = 0; + tileSize = 2; + } + + public void onTick() + { + field_1134_k++; + for(int i = 0; i < 16; i++) + { + for(int k = 0; k < 16; k++) + { + float f = 0.0F; + for(int j1 = k - 2; j1 <= k; j1++) + { + int k1 = i & 0xf; + int i2 = j1 & 0xf; + f += field_1138_g[k1 + i2 * 16]; + } + + field_1137_h[i + k * 16] = f / 3.2F + field_1136_i[i + k * 16] * 0.8F; + } + + } + + for(int j = 0; j < 16; j++) + { + for(int l = 0; l < 16; l++) + { + field_1136_i[j + l * 16] += field_1135_j[j + l * 16] * 0.05F; + if(field_1136_i[j + l * 16] < 0.0F) + { + field_1136_i[j + l * 16] = 0.0F; + } + field_1135_j[j + l * 16] -= 0.3F; + if(Math.random() < 0.20000000000000001D) + { + field_1135_j[j + l * 16] = 0.5F; + } + } + + } + + float af[] = field_1137_h; + field_1137_h = field_1138_g; + field_1138_g = af; + for(int i1 = 0; i1 < 256; i1++) + { + float f1 = field_1138_g[i1 - field_1134_k * 16 & 0xff]; + if(f1 > 1.0F) + { + f1 = 1.0F; + } + if(f1 < 0.0F) + { + f1 = 0.0F; + } + float f2 = f1 * f1; + int l1 = (int)(32F + f2 * 32F); + int j2 = (int)(50F + f2 * 64F); + int k2 = 255; + int l2 = (int)(146F + f2 * 50F); + if(anaglyphEnabled) + { + int i3 = (l1 * 30 + j2 * 59 + k2 * 11) / 100; + int j3 = (l1 * 30 + j2 * 70) / 100; + int k3 = (l1 * 30 + k2 * 70) / 100; + l1 = i3; + j2 = j3; + k2 = k3; + } + imageData[i1 * 4 + 0] = (byte)l1; + imageData[i1 * 4 + 1] = (byte)j2; + imageData[i1 * 4 + 2] = (byte)k2; + imageData[i1 * 4 + 3] = (byte)l2; + } + + } + + protected float field_1138_g[]; + protected float field_1137_h[]; + protected float field_1136_i[]; + protected float field_1135_j[]; + private int field_1134_k; +} diff --git a/src/main/java/net/minecraft/src/ThreadConnectToServer.java b/src/main/java/net/minecraft/src/ThreadConnectToServer.java new file mode 100644 index 0000000..9743d7a --- /dev/null +++ b/src/main/java/net/minecraft/src/ThreadConnectToServer.java @@ -0,0 +1,68 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +class ThreadConnectToServer extends Thread +{ + + ThreadConnectToServer(GuiConnecting guiconnecting, Minecraft minecraft, String s, int i) + { + connectingGui = guiconnecting; + mc = minecraft; + hostName = s; + port = i; + } + + public void run() + { + //try + //{ + GuiConnecting.setNetClientHandler(connectingGui, new NetClientHandler(mc, hostName, port)); + if(GuiConnecting.isCancelled(connectingGui)) + { + return; + } + GuiConnecting.getNetClientHandler(connectingGui).addToSendQueue(new Packet2Handshake(mc.session.username)); + //} + /* + catch(UnknownHostException unknownhostexception) + { + if(GuiConnecting.isCancelled(connectingGui)) + { + return; + } + mc.displayGuiScreen(new GuiConnectFailed("connect.failed", "disconnect.genericReason", new Object[] { + (new StringBuilder()).append("Unknown host '").append(hostName).append("'").toString() + })); + } + catch(ConnectException connectexception) + { + if(GuiConnecting.isCancelled(connectingGui)) + { + return; + } + mc.displayGuiScreen(new GuiConnectFailed("connect.failed", "disconnect.genericReason", new Object[] { + connectexception.getMessage() + })); + } + catch(Exception exception) + { + if(GuiConnecting.isCancelled(connectingGui)) + { + return; + } + exception.printStackTrace(); + mc.displayGuiScreen(new GuiConnectFailed("connect.failed", "disconnect.genericReason", new Object[] { + exception.toString() + })); + } + */ + } + final Minecraft mc; /* synthetic field */ + final String hostName; /* synthetic field */ + final int port; /* synthetic field */ + final GuiConnecting connectingGui; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/ThreadDownloadImage.java b/src/main/java/net/minecraft/src/ThreadDownloadImage.java new file mode 100644 index 0000000..a47e1dd --- /dev/null +++ b/src/main/java/net/minecraft/src/ThreadDownloadImage.java @@ -0,0 +1,55 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.net.HttpURLConnection; +import java.net.URL; +import javax.imageio.ImageIO; + +class ThreadDownloadImage extends Thread +{ + + ThreadDownloadImage(ThreadDownloadImageData threaddownloadimagedata, String s, ImageBuffer imagebuffer) + { + imageData = threaddownloadimagedata; + location = s; + buffer = imagebuffer; + } + + public void run() + { + HttpURLConnection httpurlconnection = null; + try + { + URL url = new URL(location); + httpurlconnection = (HttpURLConnection)url.openConnection(); + httpurlconnection.setDoInput(true); + httpurlconnection.setDoOutput(false); + httpurlconnection.connect(); + if(httpurlconnection.getResponseCode() / 100 == 4) + { + return; + } + if(buffer == null) + { + imageData.image = ImageIO.read(httpurlconnection.getInputStream()); + } else + { + imageData.image = buffer.parseUserSkin(ImageIO.read(httpurlconnection.getInputStream())); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + finally + { + httpurlconnection.disconnect(); + } + } + + final String location; /* synthetic field */ + final ImageBuffer buffer; /* synthetic field */ + final ThreadDownloadImageData imageData; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/ThreadDownloadImageData.java b/src/main/java/net/minecraft/src/ThreadDownloadImageData.java new file mode 100644 index 0000000..af2e1c2 --- /dev/null +++ b/src/main/java/net/minecraft/src/ThreadDownloadImageData.java @@ -0,0 +1,23 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.awt.image.BufferedImage; + +public class ThreadDownloadImageData +{ + + public ThreadDownloadImageData(String s, ImageBuffer imagebuffer) + { + referenceCount = 1; + textureName = -1; + textureSetupComplete = false; + (new ThreadDownloadImage(this, s, imagebuffer)).start(); + } + + public BufferedImage image; + public int referenceCount; + public int textureName; + public boolean textureSetupComplete; +} diff --git a/src/main/java/net/minecraft/src/ThreadSleepForever.java b/src/main/java/net/minecraft/src/ThreadSleepForever.java new file mode 100644 index 0000000..de3a776 --- /dev/null +++ b/src/main/java/net/minecraft/src/ThreadSleepForever.java @@ -0,0 +1,32 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import net.minecraft.client.Minecraft; + +public class ThreadSleepForever extends Thread +{ + + public ThreadSleepForever(Minecraft minecraft, String s) + { + super(s); + mc = minecraft; + setDaemon(true); + start(); + } + + public void run() + { + while(mc.running) + { + try + { + Thread.sleep(0x7fffffffL); + } + catch(InterruptedException interruptedexception) { } + } + } + + final Minecraft mc; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/TileEntity.java b/src/main/java/net/minecraft/src/TileEntity.java new file mode 100644 index 0000000..2fed025 --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntity.java @@ -0,0 +1,136 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; + +public class TileEntity +{ + + public TileEntity() + { + } + + private static void addMapping(Class class1, String s) + { + if(classToNameMap.containsKey(s)) + { + throw new IllegalArgumentException((new StringBuilder()).append("Duplicate id: ").append(s).toString()); + } else + { + nameToClassMap.put(s, class1); + classToNameMap.put(class1, s); + return; + } + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + xCoord = nbttagcompound.getInteger("x"); + yCoord = nbttagcompound.getInteger("y"); + zCoord = nbttagcompound.getInteger("z"); + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + String s = (String)classToNameMap.get(getClass()); + if(s == null) + { + throw new RuntimeException((new StringBuilder()).append(getClass()).append(" is missing a mapping! This is a bug!").toString()); + } else + { + nbttagcompound.setString("id", s); + nbttagcompound.setInteger("x", xCoord); + nbttagcompound.setInteger("y", yCoord); + nbttagcompound.setInteger("z", zCoord); + return; + } + } + + public void updateEntity() + { + } + + public static TileEntity createAndLoadEntity(NBTTagCompound nbttagcompound) + { + TileEntity tileentity = null; + try + { + Class class1 = (Class)nameToClassMap.get(nbttagcompound.getString("id")); + if(class1 != null) + { + tileentity = (TileEntity)class1.newInstance(); + } + } + catch(Exception exception) + { + exception.printStackTrace(); + } + if(tileentity != null) + { + tileentity.readFromNBT(nbttagcompound); + } else + { + System.out.println((new StringBuilder()).append("Skipping TileEntity with id ").append(nbttagcompound.getString("id")).toString()); + } + return tileentity; + } + + public int getBlockMetadata() + { + return worldObj.getBlockMetadata(xCoord, yCoord, zCoord); + } + + public void onInventoryChanged() + { + if(worldObj != null) + { + worldObj.func_698_b(xCoord, yCoord, zCoord, this); + } + } + + public double getDistanceFrom(double d, double d1, double d2) + { + double d3 = ((double)xCoord + 0.5D) - d; + double d4 = ((double)yCoord + 0.5D) - d1; + double d5 = ((double)zCoord + 0.5D) - d2; + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public Block getBlockType() + { + return Block.blocksList[worldObj.getBlockId(xCoord, yCoord, zCoord)]; + } + + static Class _mthclass$(String s) + { + try + { + return Class.forName(s); + } + catch(ClassNotFoundException classnotfoundexception) + { + throw new NoClassDefFoundError(classnotfoundexception.getMessage()); + } + } + + private static Map nameToClassMap = new HashMap(); + private static Map classToNameMap = new HashMap(); + public World worldObj; + public int xCoord; + public int yCoord; + public int zCoord; + + static + { + addMapping(TileEntityFurnace.class, "Furnace"); + addMapping(TileEntityChest.class, "Chest"); + addMapping(TileEntityDispenser.class, "Trap"); + addMapping(TileEntitySign.class, "Sign"); + addMapping(TileEntityMobSpawner.class, "MobSpawner"); + addMapping(TileEntityNote.class, "Music"); + } +} diff --git a/src/main/java/net/minecraft/src/TileEntityChest.java b/src/main/java/net/minecraft/src/TileEntityChest.java new file mode 100644 index 0000000..726439e --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityChest.java @@ -0,0 +1,115 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TileEntityChest extends TileEntity + implements IInventory +{ + + public TileEntityChest() + { + chestContents = new ItemStack[36]; + } + + public int getSizeInventory() + { + return 27; + } + + public ItemStack getStackInSlot(int i) + { + return chestContents[i]; + } + + public ItemStack decrStackSize(int i, int j) + { + if(chestContents[i] != null) + { + if(chestContents[i].stackSize <= j) + { + ItemStack itemstack = chestContents[i]; + chestContents[i] = null; + onInventoryChanged(); + return itemstack; + } + ItemStack itemstack1 = chestContents[i].splitStack(j); + if(chestContents[i].stackSize == 0) + { + chestContents[i] = null; + } + onInventoryChanged(); + return itemstack1; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + chestContents[i] = itemstack; + if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + { + itemstack.stackSize = getInventoryStackLimit(); + } + onInventoryChanged(); + } + + public String getInvName() + { + return "Chest"; + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + super.readFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Items"); + chestContents = new ItemStack[getSizeInventory()]; + for(int i = 0; i < nbttaglist.tagCount(); i++) + { + NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); + int j = nbttagcompound1.getByte("Slot") & 0xff; + if(j >= 0 && j < chestContents.length) + { + chestContents[j] = new ItemStack(nbttagcompound1); + } + } + + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + super.writeToNBT(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + for(int i = 0; i < chestContents.length; i++) + { + if(chestContents[i] != null) + { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte)i); + chestContents[i].writeToNBT(nbttagcompound1); + nbttaglist.setTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + + public int getInventoryStackLimit() + { + return 64; + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + if(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this) + { + return false; + } + return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D; + } + + private ItemStack chestContents[]; +} diff --git a/src/main/java/net/minecraft/src/TileEntityDispenser.java b/src/main/java/net/minecraft/src/TileEntityDispenser.java new file mode 100644 index 0000000..847775d --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityDispenser.java @@ -0,0 +1,140 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class TileEntityDispenser extends TileEntity + implements IInventory +{ + + public TileEntityDispenser() + { + dispenserContents = new ItemStack[9]; + dispenserRandom = new Random(); + } + + public int getSizeInventory() + { + return 9; + } + + public ItemStack getStackInSlot(int i) + { + return dispenserContents[i]; + } + + public ItemStack decrStackSize(int i, int j) + { + if(dispenserContents[i] != null) + { + if(dispenserContents[i].stackSize <= j) + { + ItemStack itemstack = dispenserContents[i]; + dispenserContents[i] = null; + onInventoryChanged(); + return itemstack; + } + ItemStack itemstack1 = dispenserContents[i].splitStack(j); + if(dispenserContents[i].stackSize == 0) + { + dispenserContents[i] = null; + } + onInventoryChanged(); + return itemstack1; + } else + { + return null; + } + } + + public ItemStack getRandomStackFromInventory() + { + int i = -1; + int j = 1; + for(int k = 0; k < dispenserContents.length; k++) + { + if(dispenserContents[k] != null && dispenserRandom.nextInt(j) == 0) + { + i = k; + j++; + } + } + + if(i >= 0) + { + return decrStackSize(i, 1); + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + dispenserContents[i] = itemstack; + if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + { + itemstack.stackSize = getInventoryStackLimit(); + } + onInventoryChanged(); + } + + public String getInvName() + { + return "Trap"; + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + super.readFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Items"); + dispenserContents = new ItemStack[getSizeInventory()]; + for(int i = 0; i < nbttaglist.tagCount(); i++) + { + NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); + int j = nbttagcompound1.getByte("Slot") & 0xff; + if(j >= 0 && j < dispenserContents.length) + { + dispenserContents[j] = new ItemStack(nbttagcompound1); + } + } + + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + super.writeToNBT(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + for(int i = 0; i < dispenserContents.length; i++) + { + if(dispenserContents[i] != null) + { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte)i); + dispenserContents[i].writeToNBT(nbttagcompound1); + nbttaglist.setTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + + public int getInventoryStackLimit() + { + return 64; + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + if(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this) + { + return false; + } + return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D; + } + + private ItemStack dispenserContents[]; + private Random dispenserRandom; +} diff --git a/src/main/java/net/minecraft/src/TileEntityFurnace.java b/src/main/java/net/minecraft/src/TileEntityFurnace.java new file mode 100644 index 0000000..327bde0 --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityFurnace.java @@ -0,0 +1,263 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TileEntityFurnace extends TileEntity + implements IInventory +{ + + public TileEntityFurnace() + { + furnaceItemStacks = new ItemStack[3]; + furnaceBurnTime = 0; + currentItemBurnTime = 0; + furnaceCookTime = 0; + } + + public int getSizeInventory() + { + return furnaceItemStacks.length; + } + + public ItemStack getStackInSlot(int i) + { + return furnaceItemStacks[i]; + } + + public ItemStack decrStackSize(int i, int j) + { + if(furnaceItemStacks[i] != null) + { + if(furnaceItemStacks[i].stackSize <= j) + { + ItemStack itemstack = furnaceItemStacks[i]; + furnaceItemStacks[i] = null; + return itemstack; + } + ItemStack itemstack1 = furnaceItemStacks[i].splitStack(j); + if(furnaceItemStacks[i].stackSize == 0) + { + furnaceItemStacks[i] = null; + } + return itemstack1; + } else + { + return null; + } + } + + public void setInventorySlotContents(int i, ItemStack itemstack) + { + furnaceItemStacks[i] = itemstack; + if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + { + itemstack.stackSize = getInventoryStackLimit(); + } + } + + public String getInvName() + { + return "Furnace"; + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + super.readFromNBT(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getTagList("Items"); + furnaceItemStacks = new ItemStack[getSizeInventory()]; + for(int i = 0; i < nbttaglist.tagCount(); i++) + { + NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); + byte byte0 = nbttagcompound1.getByte("Slot"); + if(byte0 >= 0 && byte0 < furnaceItemStacks.length) + { + furnaceItemStacks[byte0] = new ItemStack(nbttagcompound1); + } + } + + furnaceBurnTime = nbttagcompound.getShort("BurnTime"); + furnaceCookTime = nbttagcompound.getShort("CookTime"); + currentItemBurnTime = getItemBurnTime(furnaceItemStacks[1]); + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + super.writeToNBT(nbttagcompound); + nbttagcompound.setShort("BurnTime", (short)furnaceBurnTime); + nbttagcompound.setShort("CookTime", (short)furnaceCookTime); + NBTTagList nbttaglist = new NBTTagList(); + for(int i = 0; i < furnaceItemStacks.length; i++) + { + if(furnaceItemStacks[i] != null) + { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Slot", (byte)i); + furnaceItemStacks[i].writeToNBT(nbttagcompound1); + nbttaglist.setTag(nbttagcompound1); + } + } + + nbttagcompound.setTag("Items", nbttaglist); + } + + public int getInventoryStackLimit() + { + return 64; + } + + public int getCookProgressScaled(int i) + { + return (furnaceCookTime * i) / 200; + } + + public int getBurnTimeRemainingScaled(int i) + { + if(currentItemBurnTime == 0) + { + currentItemBurnTime = 200; + } + return (furnaceBurnTime * i) / currentItemBurnTime; + } + + public boolean isBurning() + { + return furnaceBurnTime > 0; + } + + public void updateEntity() + { + boolean flag = furnaceBurnTime > 0; + boolean flag1 = false; + if(furnaceBurnTime > 0) + { + furnaceBurnTime--; + } + if(!worldObj.multiplayerWorld) + { + if(furnaceBurnTime == 0 && canSmelt()) + { + currentItemBurnTime = furnaceBurnTime = getItemBurnTime(furnaceItemStacks[1]); + if(furnaceBurnTime > 0) + { + flag1 = true; + if(furnaceItemStacks[1] != null) + { + furnaceItemStacks[1].stackSize--; + if(furnaceItemStacks[1].stackSize == 0) + { + furnaceItemStacks[1] = null; + } + } + } + } + if(isBurning() && canSmelt()) + { + furnaceCookTime++; + if(furnaceCookTime == 200) + { + furnaceCookTime = 0; + smeltItem(); + flag1 = true; + } + } else + { + furnaceCookTime = 0; + } + if(flag != (furnaceBurnTime > 0)) + { + flag1 = true; + BlockFurnace.updateFurnaceBlockState(furnaceBurnTime > 0, worldObj, xCoord, yCoord, zCoord); + } + } + if(flag1) + { + onInventoryChanged(); + } + } + + private boolean canSmelt() + { + if(furnaceItemStacks[0] == null) + { + return false; + } + ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(furnaceItemStacks[0].getItem().shiftedIndex); + if(itemstack == null) + { + return false; + } + if(furnaceItemStacks[2] == null) + { + return true; + } + if(!furnaceItemStacks[2].isItemEqual(itemstack)) + { + return false; + } + if(furnaceItemStacks[2].stackSize < getInventoryStackLimit() && furnaceItemStacks[2].stackSize < furnaceItemStacks[2].getMaxStackSize()) + { + return true; + } + return furnaceItemStacks[2].stackSize < itemstack.getMaxStackSize(); + } + + public void smeltItem() + { + if(!canSmelt()) + { + return; + } + ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(furnaceItemStacks[0].getItem().shiftedIndex); + if(furnaceItemStacks[2] == null) + { + furnaceItemStacks[2] = itemstack.copy(); + } else + if(furnaceItemStacks[2].itemID == itemstack.itemID) + { + furnaceItemStacks[2].stackSize++; + } + furnaceItemStacks[0].stackSize--; + if(furnaceItemStacks[0].stackSize <= 0) + { + furnaceItemStacks[0] = null; + } + } + + private int getItemBurnTime(ItemStack itemstack) + { + if(itemstack == null) + { + return 0; + } + int i = itemstack.getItem().shiftedIndex; + if(i < 256 && Block.blocksList[i].blockMaterial == Material.wood) + { + return 300; + } + if(i == Item.stick.shiftedIndex) + { + return 100; + } + if(i == Item.coal.shiftedIndex) + { + return 1600; + } + return i != Item.bucketLava.shiftedIndex ? 0 : 20000; + } + + public boolean canInteractWith(EntityPlayer entityplayer) + { + if(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this) + { + return false; + } + return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D; + } + + private ItemStack furnaceItemStacks[]; + public int furnaceBurnTime; + public int currentItemBurnTime; + public int furnaceCookTime; +} diff --git a/src/main/java/net/minecraft/src/TileEntityMobSpawner.java b/src/main/java/net/minecraft/src/TileEntityMobSpawner.java new file mode 100644 index 0000000..634dc5e --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityMobSpawner.java @@ -0,0 +1,128 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; +import java.util.Random; + +public class TileEntityMobSpawner extends TileEntity +{ + + public TileEntityMobSpawner() + { + delay = -1; + yaw2 = 0.0D; + mobID = "Pig"; + delay = 20; + } + + public String getMobID() + { + return mobID; + } + + public void setMobID(String s) + { + mobID = s; + } + + public boolean anyPlayerInRange() + { + return worldObj.getClosestPlayer((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D, 16D) != null; + } + + public void updateEntity() + { + yaw2 = yaw; + if(!anyPlayerInRange()) + { + return; + } + double d = (float)xCoord + worldObj.rand.nextFloat(); + double d2 = (float)yCoord + worldObj.rand.nextFloat(); + double d4 = (float)zCoord + worldObj.rand.nextFloat(); + worldObj.spawnParticle("smoke", d, d2, d4, 0.0D, 0.0D, 0.0D); + worldObj.spawnParticle("flame", d, d2, d4, 0.0D, 0.0D, 0.0D); + for(yaw += 1000F / ((float)delay + 200F); yaw > 360D;) + { + yaw -= 360D; + yaw2 -= 360D; + } + + if(delay == -1) + { + updateDelay(); + } + if(delay > 0) + { + delay--; + return; + } + byte byte0 = 4; + for(int i = 0; i < byte0; i++) + { + EntityLiving entityliving = (EntityLiving)EntityList.createEntityInWorld(mobID, worldObj); + if(entityliving == null) + { + return; + } + int j = worldObj.getEntitiesWithinAABB(entityliving.getClass(), AxisAlignedBB.getBoundingBoxFromPool(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 1, zCoord + 1).expand(8D, 4D, 8D)).size(); + if(j >= 6) + { + updateDelay(); + return; + } + if(entityliving == null) + { + continue; + } + double d6 = (double)xCoord + (worldObj.rand.nextDouble() - worldObj.rand.nextDouble()) * 4D; + double d7 = (yCoord + worldObj.rand.nextInt(3)) - 1; + double d8 = (double)zCoord + (worldObj.rand.nextDouble() - worldObj.rand.nextDouble()) * 4D; + entityliving.setLocationAndAngles(d6, d7, d8, worldObj.rand.nextFloat() * 360F, 0.0F); + if(!entityliving.getCanSpawnHere()) + { + continue; + } + worldObj.entityJoinedWorld(entityliving); + for(int k = 0; k < 20; k++) + { + double d1 = (double)xCoord + 0.5D + ((double)worldObj.rand.nextFloat() - 0.5D) * 2D; + double d3 = (double)yCoord + 0.5D + ((double)worldObj.rand.nextFloat() - 0.5D) * 2D; + double d5 = (double)zCoord + 0.5D + ((double)worldObj.rand.nextFloat() - 0.5D) * 2D; + worldObj.spawnParticle("smoke", d1, d3, d5, 0.0D, 0.0D, 0.0D); + worldObj.spawnParticle("flame", d1, d3, d5, 0.0D, 0.0D, 0.0D); + } + + entityliving.spawnExplosionParticle(); + updateDelay(); + } + + super.updateEntity(); + } + + private void updateDelay() + { + delay = 200 + worldObj.rand.nextInt(600); + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + super.readFromNBT(nbttagcompound); + mobID = nbttagcompound.getString("EntityId"); + delay = nbttagcompound.getShort("Delay"); + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + super.writeToNBT(nbttagcompound); + nbttagcompound.setString("EntityId", mobID); + nbttagcompound.setShort("Delay", (short)delay); + } + + public int delay; + private String mobID; + public double yaw; + public double yaw2; +} diff --git a/src/main/java/net/minecraft/src/TileEntityMobSpawnerRenderer.java b/src/main/java/net/minecraft/src/TileEntityMobSpawnerRenderer.java new file mode 100644 index 0000000..93e272c --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityMobSpawnerRenderer.java @@ -0,0 +1,51 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.HashMap; +import java.util.Map; +import org.lwjgl.opengl.GL11; + +public class TileEntityMobSpawnerRenderer extends TileEntitySpecialRenderer +{ + + public TileEntityMobSpawnerRenderer() + { + entityHashMap = new HashMap(); + } + + public void renderTileEntityMobSpawner(TileEntityMobSpawner tileentitymobspawner, double d, double d1, double d2, + float f) + { + GL11.glPushMatrix(); + GL11.glTranslatef((float)d + 0.5F, (float)d1, (float)d2 + 0.5F); + Entity entity = (Entity)entityHashMap.get(tileentitymobspawner.getMobID()); + if(entity == null) + { + entity = EntityList.createEntityInWorld(tileentitymobspawner.getMobID(), null); + entityHashMap.put(tileentitymobspawner.getMobID(), entity); + } + if(entity != null) + { + entity.setWorld(tileentitymobspawner.worldObj); + float f1 = 0.4375F; + GL11.glTranslatef(0.0F, 0.4F, 0.0F); + GL11.glRotatef((float)(tileentitymobspawner.yaw2 + (tileentitymobspawner.yaw - tileentitymobspawner.yaw2) * (double)f) * 10F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-30F, 1.0F, 0.0F, 0.0F); + GL11.glTranslatef(0.0F, -0.4F, 0.0F); + GL11.glScalef(f1, f1, f1); + entity.setLocationAndAngles(d, d1, d2, 0.0F, 0.0F); + RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, f); + } + GL11.glPopMatrix(); + } + + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, + float f) + { + renderTileEntityMobSpawner((TileEntityMobSpawner)tileentity, d, d1, d2, f); + } + + private Map entityHashMap; +} diff --git a/src/main/java/net/minecraft/src/TileEntityNote.java b/src/main/java/net/minecraft/src/TileEntityNote.java new file mode 100644 index 0000000..6b9481f --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityNote.java @@ -0,0 +1,71 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TileEntityNote extends TileEntity +{ + + public TileEntityNote() + { + note = 0; + previousRedstoneState = false; + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + super.writeToNBT(nbttagcompound); + nbttagcompound.setByte("note", note); + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + super.readFromNBT(nbttagcompound); + note = nbttagcompound.getByte("note"); + if(note < 0) + { + note = 0; + } + if(note > 24) + { + note = 24; + } + } + + public void changePitch() + { + note = (byte)((note + 1) % 25); + onInventoryChanged(); + } + + public void triggerNote(World world, int i, int j, int k) + { + if(world.getBlockMaterial(i, j + 1, k) != Material.air) + { + return; + } + Material material = world.getBlockMaterial(i, j - 1, k); + byte byte0 = 0; + if(material == Material.rock) + { + byte0 = 1; + } + if(material == Material.sand) + { + byte0 = 2; + } + if(material == Material.glass) + { + byte0 = 3; + } + if(material == Material.wood) + { + byte0 = 4; + } + world.playNoteAt(i, j, k, byte0, note); + } + + public byte note; + public boolean previousRedstoneState; +} diff --git a/src/main/java/net/minecraft/src/TileEntityRenderer.java b/src/main/java/net/minecraft/src/TileEntityRenderer.java new file mode 100644 index 0000000..e320414 --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntityRenderer.java @@ -0,0 +1,105 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; +import org.lwjgl.opengl.GL11; + +public class TileEntityRenderer +{ + + private TileEntityRenderer() + { + specialRendererMap = new HashMap(); + specialRendererMap.put(TileEntitySign.class, new TileEntitySignRenderer()); + specialRendererMap.put(TileEntityMobSpawner.class, new TileEntityMobSpawnerRenderer()); + TileEntitySpecialRenderer tileentityspecialrenderer; + for(Iterator iterator = specialRendererMap.values().iterator(); iterator.hasNext(); tileentityspecialrenderer.setTileEntityRenderer(this)) + { + tileentityspecialrenderer = (TileEntitySpecialRenderer)iterator.next(); + } + + } + + public TileEntitySpecialRenderer getSpecialRendererForClass(Class class1) + { + TileEntitySpecialRenderer tileentityspecialrenderer = (TileEntitySpecialRenderer)specialRendererMap.get(class1); + if(tileentityspecialrenderer == null && class1 != (TileEntity.class)) + { + tileentityspecialrenderer = getSpecialRendererForClass(class1.getSuperclass()); + specialRendererMap.put(class1, tileentityspecialrenderer); + } + return tileentityspecialrenderer; + } + + public boolean hasSpecialRenderer(TileEntity tileentity) + { + return getSpecialRendererForEntity(tileentity) != null; + } + + public TileEntitySpecialRenderer getSpecialRendererForEntity(TileEntity tileentity) + { + if(tileentity == null) + { + return null; + } else + { + return getSpecialRendererForClass(tileentity.getClass()); + } + } + + public void func_22267_a(World world, RenderEngine renderengine, FontRenderer fontrenderer, EntityLiving entityliving, float f) + { + worldObj = world; + renderEngine = renderengine; + field_22270_g = entityliving; + fontRenderer = fontrenderer; + field_22269_h = entityliving.prevRotationYaw + (entityliving.rotationYaw - entityliving.prevRotationYaw) * f; + field_22268_i = entityliving.prevRotationPitch + (entityliving.rotationPitch - entityliving.prevRotationPitch) * f; + playerX = entityliving.lastTickPosX + (entityliving.posX - entityliving.lastTickPosX) * (double)f; + playerY = entityliving.lastTickPosY + (entityliving.posY - entityliving.lastTickPosY) * (double)f; + playerZ = entityliving.lastTickPosZ + (entityliving.posZ - entityliving.lastTickPosZ) * (double)f; + } + + public void renderTileEntity(TileEntity tileentity, float f) + { + if(tileentity.getDistanceFrom(playerX, playerY, playerZ) < 4096D) + { + float f1 = worldObj.getLightBrightness(tileentity.xCoord, tileentity.yCoord, tileentity.zCoord); + GL11.glColor3f(f1, f1, f1); + renderTileEntityAt(tileentity, (double)tileentity.xCoord - staticPlayerX, (double)tileentity.yCoord - staticPlayerY, (double)tileentity.zCoord - staticPlayerZ, f); + } + } + + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, + float f) + { + TileEntitySpecialRenderer tileentityspecialrenderer = getSpecialRendererForEntity(tileentity); + if(tileentityspecialrenderer != null) + { + tileentityspecialrenderer.renderTileEntityAt(tileentity, d, d1, d2, f); + } + } + + public FontRenderer getFontRenderer() + { + return fontRenderer; + } + + private Map specialRendererMap; + public static TileEntityRenderer instance = new TileEntityRenderer(); + private FontRenderer fontRenderer; + public static double staticPlayerX; + public static double staticPlayerY; + public static double staticPlayerZ; + public RenderEngine renderEngine; + public World worldObj; + public EntityLiving field_22270_g; + public float field_22269_h; + public float field_22268_i; + public double playerX; + public double playerY; + public double playerZ; + +} diff --git a/src/main/java/net/minecraft/src/TileEntitySign.java b/src/main/java/net/minecraft/src/TileEntitySign.java new file mode 100644 index 0000000..08eff14 --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntitySign.java @@ -0,0 +1,42 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class TileEntitySign extends TileEntity +{ + + public TileEntitySign() + { + lineBeingEdited = -1; + } + + public void writeToNBT(NBTTagCompound nbttagcompound) + { + super.writeToNBT(nbttagcompound); + nbttagcompound.setString("Text1", signText[0]); + nbttagcompound.setString("Text2", signText[1]); + nbttagcompound.setString("Text3", signText[2]); + nbttagcompound.setString("Text4", signText[3]); + } + + public void readFromNBT(NBTTagCompound nbttagcompound) + { + super.readFromNBT(nbttagcompound); + for(int i = 0; i < 4; i++) + { + signText[i] = nbttagcompound.getString((new StringBuilder()).append("Text").append(i + 1).toString()); + if(signText[i].length() > 15) + { + signText[i] = signText[i].substring(0, 15); + } + } + + } + + public String signText[] = { + "", "", "", "" + }; + public int lineBeingEdited; +} diff --git a/src/main/java/net/minecraft/src/TileEntitySignRenderer.java b/src/main/java/net/minecraft/src/TileEntitySignRenderer.java new file mode 100644 index 0000000..938f887 --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntitySignRenderer.java @@ -0,0 +1,86 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import org.lwjgl.opengl.GL11; + +public class TileEntitySignRenderer extends TileEntitySpecialRenderer +{ + + public TileEntitySignRenderer() + { + signModel = new SignModel(); + } + + public void renderTileEntitySignAt(TileEntitySign tileentitysign, double d, double d1, double d2, + float f) + { + Block block = tileentitysign.getBlockType(); + GL11.glPushMatrix(); + float f1 = 0.6666667F; + if(block == Block.signPost) + { + GL11.glTranslatef((float)d + 0.5F, (float)d1 + 0.75F * f1, (float)d2 + 0.5F); + float f2 = (float)(tileentitysign.getBlockMetadata() * 360) / 16F; + GL11.glRotatef(-f2, 0.0F, 1.0F, 0.0F); + signModel.field_1345_b.showModel = true; + } else + { + int i = tileentitysign.getBlockMetadata(); + float f3 = 0.0F; + if(i == 2) + { + f3 = 180F; + } + if(i == 4) + { + f3 = 90F; + } + if(i == 5) + { + f3 = -90F; + } + GL11.glTranslatef((float)d + 0.5F, (float)d1 + 0.75F * f1, (float)d2 + 0.5F); + GL11.glRotatef(-f3, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(0.0F, -0.3125F, -0.4375F); + signModel.field_1345_b.showModel = false; + } + bindTextureByName("/item/sign.png"); + GL11.glPushMatrix(); + GL11.glScalef(f1, -f1, -f1); + signModel.func_887_a(); + GL11.glPopMatrix(); + FontRenderer fontrenderer = getFontRenderer(); + float f4 = 0.01666667F * f1; + GL11.glTranslatef(0.0F, 0.5F * f1, 0.07F * f1); + GL11.glScalef(f4, -f4, f4); + GL11.glNormal3f(0.0F, 0.0F, -1F * f4); + GL11.glDepthMask(false); + int j = 0; + for(int k = 0; k < tileentitysign.signText.length; k++) + { + String s = tileentitysign.signText[k]; + if(k == tileentitysign.lineBeingEdited) + { + s = (new StringBuilder()).append("> ").append(s).append(" <").toString(); + fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, k * 10 - tileentitysign.signText.length * 5, j); + } else + { + fontrenderer.drawString(s, -fontrenderer.getStringWidth(s) / 2, k * 10 - tileentitysign.signText.length * 5, j); + } + } + + GL11.glDepthMask(true); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glPopMatrix(); + } + + public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, + float f) + { + renderTileEntitySignAt((TileEntitySign)tileentity, d, d1, d2, f); + } + + private SignModel signModel; +} diff --git a/src/main/java/net/minecraft/src/TileEntitySpecialRenderer.java b/src/main/java/net/minecraft/src/TileEntitySpecialRenderer.java new file mode 100644 index 0000000..e3d236f --- /dev/null +++ b/src/main/java/net/minecraft/src/TileEntitySpecialRenderer.java @@ -0,0 +1,34 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public abstract class TileEntitySpecialRenderer +{ + + public TileEntitySpecialRenderer() + { + } + + public abstract void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, + float f); + + protected void bindTextureByName(String s) + { + RenderEngine renderengine = tileEntityRenderer.renderEngine; + renderengine.bindTexture(renderengine.getTexture(s)); + } + + public void setTileEntityRenderer(TileEntityRenderer tileentityrenderer) + { + tileEntityRenderer = tileentityrenderer; + } + + public FontRenderer getFontRenderer() + { + return tileEntityRenderer.getFontRenderer(); + } + + protected TileEntityRenderer tileEntityRenderer; +} diff --git a/src/main/java/net/minecraft/src/Timer.java b/src/main/java/net/minecraft/src/Timer.java new file mode 100644 index 0000000..97bb230 --- /dev/null +++ b/src/main/java/net/minecraft/src/Timer.java @@ -0,0 +1,68 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class Timer +{ + + public Timer(float f) + { + timerSpeed = 1.0F; + elapsedPartialTicks = 0.0F; + timeSyncAdjustment = 1.0D; + ticksPerSecond = f; + lastSyncSysClock = System.currentTimeMillis(); + lastSyncHRClock = System.nanoTime() / 0xf4240L; + } + + public void updateTimer() + { + long l = System.currentTimeMillis(); + long l1 = l - lastSyncSysClock; + long l2 = System.nanoTime() / 0xf4240L; + if(l1 > 1000L) + { + long l3 = l2 - lastSyncHRClock; + double d1 = (double)l1 / (double)l3; + timeSyncAdjustment += (d1 - timeSyncAdjustment) * 0.20000000298023224D; + lastSyncSysClock = l; + lastSyncHRClock = l2; + } + if(l1 < 0L) + { + lastSyncSysClock = l; + lastSyncHRClock = l2; + } + double d = (double)l2 / 1000D; + double d2 = (d - lastHRTime) * timeSyncAdjustment; + lastHRTime = d; + if(d2 < 0.0D) + { + d2 = 0.0D; + } + if(d2 > 1.0D) + { + d2 = 1.0D; + } + elapsedPartialTicks += d2 * (double)timerSpeed * (double)ticksPerSecond; + elapsedTicks = (int)elapsedPartialTicks; + elapsedPartialTicks -= elapsedTicks; + if(elapsedTicks > 10) + { + elapsedTicks = 10; + } + renderPartialTicks = elapsedPartialTicks; + } + + public float ticksPerSecond; + private double lastHRTime; + public int elapsedTicks; + public float renderPartialTicks; + public float timerSpeed; + public float elapsedPartialTicks; + private long lastSyncSysClock; + private long lastSyncHRClock; + private double timeSyncAdjustment; +} diff --git a/src/main/java/net/minecraft/src/UnexpectedThrowable.java b/src/main/java/net/minecraft/src/UnexpectedThrowable.java new file mode 100644 index 0000000..a86fb3d --- /dev/null +++ b/src/main/java/net/minecraft/src/UnexpectedThrowable.java @@ -0,0 +1,18 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class UnexpectedThrowable +{ + + public UnexpectedThrowable(String s, Throwable throwable) + { + description = s; + exception = throwable; + } + + public final String description; + public final Throwable exception; +} diff --git a/src/main/java/net/minecraft/src/Vec3D.java b/src/main/java/net/minecraft/src/Vec3D.java new file mode 100644 index 0000000..dc9371f --- /dev/null +++ b/src/main/java/net/minecraft/src/Vec3D.java @@ -0,0 +1,206 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.ArrayList; +import java.util.List; + +public class Vec3D +{ + + public static Vec3D createVectorHelper(double d, double d1, double d2) + { + return new Vec3D(d, d1, d2); + } + + public static void initialize() + { + nextVector = 0; + } + + public static Vec3D createVector(double d, double d1, double d2) + { + if(nextVector >= vectorList.size()) + { + vectorList.add(createVectorHelper(0.0D, 0.0D, 0.0D)); + } + return ((Vec3D)vectorList.get(nextVector++)).setComponents(d, d1, d2); + } + + private Vec3D(double d, double d1, double d2) + { + if(d == -0D) + { + d = 0.0D; + } + if(d1 == -0D) + { + d1 = 0.0D; + } + if(d2 == -0D) + { + d2 = 0.0D; + } + xCoord = d; + yCoord = d1; + zCoord = d2; + } + + private Vec3D setComponents(double d, double d1, double d2) + { + xCoord = d; + yCoord = d1; + zCoord = d2; + return this; + } + + public Vec3D subtract(Vec3D vec3d) + { + return createVector(vec3d.xCoord - xCoord, vec3d.yCoord - yCoord, vec3d.zCoord - zCoord); + } + + public Vec3D normalize() + { + double d = MathHelper.sqrt_double(xCoord * xCoord + yCoord * yCoord + zCoord * zCoord); + if(d < 0.0001D) + { + return createVector(0.0D, 0.0D, 0.0D); + } else + { + return createVector(xCoord / d, yCoord / d, zCoord / d); + } + } + + public Vec3D crossProduct(Vec3D vec3d) + { + return createVector(yCoord * vec3d.zCoord - zCoord * vec3d.yCoord, zCoord * vec3d.xCoord - xCoord * vec3d.zCoord, xCoord * vec3d.yCoord - yCoord * vec3d.xCoord); + } + + public Vec3D addVector(double d, double d1, double d2) + { + return createVector(xCoord + d, yCoord + d1, zCoord + d2); + } + + public double distanceTo(Vec3D vec3d) + { + double d = vec3d.xCoord - xCoord; + double d1 = vec3d.yCoord - yCoord; + double d2 = vec3d.zCoord - zCoord; + return (double)MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); + } + + public double squareDistanceTo(Vec3D vec3d) + { + double d = vec3d.xCoord - xCoord; + double d1 = vec3d.yCoord - yCoord; + double d2 = vec3d.zCoord - zCoord; + return d * d + d1 * d1 + d2 * d2; + } + + public double squareDistanceTo(double d, double d1, double d2) + { + double d3 = d - xCoord; + double d4 = d1 - yCoord; + double d5 = d2 - zCoord; + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public double lengthVector() + { + return (double)MathHelper.sqrt_double(xCoord * xCoord + yCoord * yCoord + zCoord * zCoord); + } + + public Vec3D getIntermediateWithXValue(Vec3D vec3d, double d) + { + double d1 = vec3d.xCoord - xCoord; + double d2 = vec3d.yCoord - yCoord; + double d3 = vec3d.zCoord - zCoord; + if(d1 * d1 < 1.0000000116860974E-007D) + { + return null; + } + double d4 = (d - xCoord) / d1; + if(d4 < 0.0D || d4 > 1.0D) + { + return null; + } else + { + return createVector(xCoord + d1 * d4, yCoord + d2 * d4, zCoord + d3 * d4); + } + } + + public Vec3D getIntermediateWithYValue(Vec3D vec3d, double d) + { + double d1 = vec3d.xCoord - xCoord; + double d2 = vec3d.yCoord - yCoord; + double d3 = vec3d.zCoord - zCoord; + if(d2 * d2 < 1.0000000116860974E-007D) + { + return null; + } + double d4 = (d - yCoord) / d2; + if(d4 < 0.0D || d4 > 1.0D) + { + return null; + } else + { + return createVector(xCoord + d1 * d4, yCoord + d2 * d4, zCoord + d3 * d4); + } + } + + public Vec3D getIntermediateWithZValue(Vec3D vec3d, double d) + { + double d1 = vec3d.xCoord - xCoord; + double d2 = vec3d.yCoord - yCoord; + double d3 = vec3d.zCoord - zCoord; + if(d3 * d3 < 1.0000000116860974E-007D) + { + return null; + } + double d4 = (d - zCoord) / d3; + if(d4 < 0.0D || d4 > 1.0D) + { + return null; + } else + { + return createVector(xCoord + d1 * d4, yCoord + d2 * d4, zCoord + d3 * d4); + } + } + + public String toString() + { + return (new StringBuilder()).append("(").append(xCoord).append(", ").append(yCoord).append(", ").append(zCoord).append(")").toString(); + } + + public void rotateAroundX(float f) + { + float f1 = MathHelper.cos(f); + float f2 = MathHelper.sin(f); + double d = xCoord; + double d1 = yCoord * (double)f1 + zCoord * (double)f2; + double d2 = zCoord * (double)f1 - yCoord * (double)f2; + xCoord = d; + yCoord = d1; + zCoord = d2; + } + + public void rotateAroundY(float f) + { + float f1 = MathHelper.cos(f); + float f2 = MathHelper.sin(f); + double d = xCoord * (double)f1 + zCoord * (double)f2; + double d1 = yCoord; + double d2 = zCoord * (double)f1 - xCoord * (double)f2; + xCoord = d; + yCoord = d1; + zCoord = d2; + } + + private static List vectorList = new ArrayList(); + private static int nextVector = 0; + public double xCoord; + public double yCoord; + public double zCoord; + +} diff --git a/src/main/java/net/minecraft/src/WatchableObject.java b/src/main/java/net/minecraft/src/WatchableObject.java new file mode 100644 index 0000000..becd905 --- /dev/null +++ b/src/main/java/net/minecraft/src/WatchableObject.java @@ -0,0 +1,47 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class WatchableObject +{ + + public WatchableObject(int i, int j, Object obj) + { + dataValueId = j; + watchedObject = obj; + objectType = i; + isWatching = true; + } + + public int getDataValueId() + { + return dataValueId; + } + + public void setObject(Object obj) + { + watchedObject = obj; + } + + public Object getObject() + { + return watchedObject; + } + + public int getObjectType() + { + return objectType; + } + + public void setWatching(boolean flag) + { + isWatching = flag; + } + + private final int objectType; + private final int dataValueId; + private Object watchedObject; + private boolean isWatching; +} diff --git a/src/main/java/net/minecraft/src/World.java b/src/main/java/net/minecraft/src/World.java new file mode 100644 index 0000000..1de75a9 --- /dev/null +++ b/src/main/java/net/minecraft/src/World.java @@ -0,0 +1,2450 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.io.PrintStream; +import java.util.*; + +public class World + implements IBlockAccess +{ + + public WorldChunkManager getWorldChunkManager() + { + return worldProvider.worldChunkMgr; + } + + public World(ISaveHandler isavehandler, String s, WorldProvider worldprovider, long l) + { + scheduledUpdatesAreImmediate = false; + field_1051_z = new ArrayList(); + loadedEntityList = new ArrayList(); + unloadedEntityList = new ArrayList(); + scheduledTickTreeSet = new TreeSet(); + scheduledTickSet = new HashSet(); + loadedTileEntityList = new ArrayList(); + playerEntities = new ArrayList(); + field_1019_F = 0xffffffL; + skylightSubtracted = 0; + field_9437_g = (new Random()).nextInt(); + field_9436_h = 0x3c6ef35f; + field_1043_h = false; + lockTimestamp = System.currentTimeMillis(); + autosavePeriod = 40; + rand = new Random(); + isNewWorld = false; + worldAccesses = new ArrayList(); + field_9428_I = new ArrayList(); + field_4204_J = 0; + spawnHostileMobs = true; + field_21120_L = true; + field_9427_K = new HashSet(); + field_9426_L = rand.nextInt(12000); + field_1012_M = new ArrayList(); + multiplayerWorld = false; + field_22147_p = isavehandler; + worldinfo = new WorldInfo(l, s); + worldProvider = worldprovider; + worldprovider.registerWorld(this); + chunkProvider = getChunkProvider(); + calculateInitialSkylight(); + } + + public World(World world, WorldProvider worldprovider) + { + scheduledUpdatesAreImmediate = false; + field_1051_z = new ArrayList(); + loadedEntityList = new ArrayList(); + unloadedEntityList = new ArrayList(); + scheduledTickTreeSet = new TreeSet(); + scheduledTickSet = new HashSet(); + loadedTileEntityList = new ArrayList(); + playerEntities = new ArrayList(); + field_1019_F = 0xffffffL; + skylightSubtracted = 0; + field_9437_g = (new Random()).nextInt(); + field_9436_h = 0x3c6ef35f; + field_1043_h = false; + lockTimestamp = System.currentTimeMillis(); + autosavePeriod = 40; + rand = new Random(); + isNewWorld = false; + worldAccesses = new ArrayList(); + field_9428_I = new ArrayList(); + field_4204_J = 0; + spawnHostileMobs = true; + field_21120_L = true; + field_9427_K = new HashSet(); + field_9426_L = rand.nextInt(12000); + field_1012_M = new ArrayList(); + multiplayerWorld = false; + lockTimestamp = world.lockTimestamp; + field_22147_p = world.field_22147_p; + worldinfo = new WorldInfo(world.worldinfo); + worldProvider = worldprovider; + worldprovider.registerWorld(this); + chunkProvider = getChunkProvider(); + calculateInitialSkylight(); + } + + public World(ISaveHandler isavehandler, String s, long l) + { + this(isavehandler, s, l, ((WorldProvider) (null))); + } + + public World(ISaveHandler isavehandler, String s, long l, WorldProvider worldprovider) + { + scheduledUpdatesAreImmediate = false; + field_1051_z = new ArrayList(); + loadedEntityList = new ArrayList(); + unloadedEntityList = new ArrayList(); + scheduledTickTreeSet = new TreeSet(); + scheduledTickSet = new HashSet(); + loadedTileEntityList = new ArrayList(); + playerEntities = new ArrayList(); + field_1019_F = 0xffffffL; + skylightSubtracted = 0; + field_9437_g = (new Random()).nextInt(); + field_9436_h = 0x3c6ef35f; + field_1043_h = false; + lockTimestamp = System.currentTimeMillis(); + autosavePeriod = 40; + rand = new Random(); + isNewWorld = false; + worldAccesses = new ArrayList(); + field_9428_I = new ArrayList(); + field_4204_J = 0; + spawnHostileMobs = true; + field_21120_L = true; + field_9427_K = new HashSet(); + field_9426_L = rand.nextInt(12000); + field_1012_M = new ArrayList(); + multiplayerWorld = false; + field_22147_p = isavehandler; + worldinfo = isavehandler.func_22151_c(); + isNewWorld = worldinfo == null; + if(worldprovider != null) + { + worldProvider = worldprovider; + } else + if(worldinfo != null && worldinfo.func_22290_i() == -1) + { + worldProvider = new WorldProviderHell(); + } else + { + worldProvider = new WorldProvider(); + } + boolean flag = false; + if(worldinfo == null) + { + worldinfo = new WorldInfo(l, s); + flag = true; + } else + { + worldinfo.func_22287_a(s); + } + worldProvider.registerWorld(this); + chunkProvider = getChunkProvider(); + if(flag) + { + field_9430_x = true; + int i = 0; + byte byte0 = 64; + int j; + for(j = 0; !worldProvider.canCoordinateBeSpawn(i, j); j += rand.nextInt(64) - rand.nextInt(64)) + { + i += rand.nextInt(64) - rand.nextInt(64); + } + + worldinfo.func_22292_a(i, byte0, j); + field_9430_x = false; + } + calculateInitialSkylight(); + } + + protected IChunkProvider getChunkProvider() + { + IChunkLoader ichunkloader = field_22147_p.func_22149_a(worldProvider); + return new ChunkProviderLoadOrGenerate(this, ichunkloader, worldProvider.getChunkProvider()); + } + + public void setSpawnLocation() + { + if(worldinfo.func_22295_d() <= 0) + { + worldinfo.func_22308_b(64); + } + int i = worldinfo.func_22293_c(); + int j; + for(j = worldinfo.func_22300_e(); getFirstUncoveredBlock(i, j) == 0; j += rand.nextInt(8) - rand.nextInt(8)) + { + i += rand.nextInt(8) - rand.nextInt(8); + } + + worldinfo.func_22294_a(i); + worldinfo.func_22298_c(j); + } + + public int getFirstUncoveredBlock(int i, int j) + { + int k; + for(k = 63; !isAirBlock(i, k + 1, j); k++) { } + return getBlockId(i, k, j); + } + + public void func_6464_c() + { + } + + public void spawnPlayerWithLoadedChunks(EntityPlayer entityplayer) + { + try + { + NBTTagCompound nbttagcompound = worldinfo.func_22303_h(); + if(nbttagcompound != null) + { + entityplayer.readFromNBT(nbttagcompound); + worldinfo.func_22309_a(null); + } + if(chunkProvider instanceof ChunkProviderLoadOrGenerate) + { + ChunkProviderLoadOrGenerate chunkproviderloadorgenerate = (ChunkProviderLoadOrGenerate)chunkProvider; + int i = MathHelper.floor_float((int)entityplayer.posX) >> 4; + int j = MathHelper.floor_float((int)entityplayer.posZ) >> 4; + chunkproviderloadorgenerate.func_21110_c(i, j); + } + entityJoinedWorld(entityplayer); + } + catch(Exception exception) + { + exception.printStackTrace(); + } + } + + public void saveWorld(boolean flag, IProgressUpdate iprogressupdate) + { + if(!chunkProvider.func_536_b()) + { + return; + } + if(iprogressupdate != null) + { + iprogressupdate.func_594_b("Saving level"); + } + saveLevel(); + if(iprogressupdate != null) + { + iprogressupdate.displayLoadingString("Saving chunks"); + } + chunkProvider.saveChunks(flag, iprogressupdate); + } + + private void saveLevel() + { + checkSessionLock(); + field_22147_p.func_22148_a(worldinfo, playerEntities); + } + + public boolean func_650_a(int i) + { + if(!chunkProvider.func_536_b()) + { + return true; + } + if(i == 0) + { + saveLevel(); + } + return chunkProvider.saveChunks(false, null); + } + + public int getBlockId(int i, int j, int k) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return 0; + } + if(j < 0) + { + return 0; + } + if(j >= 128) + { + return 0; + } else + { + return getChunkFromChunkCoords(i >> 4, k >> 4).getBlockID(i & 0xf, j, k & 0xf); + } + } + + public boolean isAirBlock(int i, int j, int k) + { + return getBlockId(i, j, k) == 0; + } + + public boolean blockExists(int i, int j, int k) + { + if(j < 0 || j >= 128) + { + return false; + } else + { + return chunkExists(i >> 4, k >> 4); + } + } + + public boolean doChunksNearChunkExist(int i, int j, int k, int l) + { + return checkChunksExist(i - l, j - l, k - l, i + l, j + l, k + l); + } + + public boolean checkChunksExist(int i, int j, int k, int l, int i1, int j1) + { + if(i1 < 0 || j >= 128) + { + return false; + } + i >>= 4; + j >>= 4; + k >>= 4; + l >>= 4; + i1 >>= 4; + j1 >>= 4; + for(int k1 = i; k1 <= l; k1++) + { + for(int l1 = k; l1 <= j1; l1++) + { + if(!chunkExists(k1, l1)) + { + return false; + } + } + + } + + return true; + } + + private boolean chunkExists(int i, int j) + { + return chunkProvider.chunkExists(i, j); + } + + public Chunk getChunkFromBlockCoords(int i, int j) + { + return getChunkFromChunkCoords(i >> 4, j >> 4); + } + + public Chunk getChunkFromChunkCoords(int i, int j) + { + return chunkProvider.provideChunk(i, j); + } + + public boolean setBlockAndMetadata(int i, int j, int k, int l, int i1) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return false; + } + if(j < 0) + { + return false; + } + if(j >= 128) + { + return false; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + return chunk.setBlockIDWithMetadata(i & 0xf, j, k & 0xf, l, i1); + } + } + + public boolean setBlock(int i, int j, int k, int l) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return false; + } + if(j < 0) + { + return false; + } + if(j >= 128) + { + return false; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + return chunk.setBlockID(i & 0xf, j, k & 0xf, l); + } + } + + public Material getBlockMaterial(int i, int j, int k) + { + int l = getBlockId(i, j, k); + if(l == 0) + { + return Material.air; + } else + { + return Block.blocksList[l].blockMaterial; + } + } + + public int getBlockMetadata(int i, int j, int k) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return 0; + } + if(j < 0) + { + return 0; + } + if(j >= 128) + { + return 0; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + i &= 0xf; + k &= 0xf; + return chunk.getBlockMetadata(i, j, k); + } + } + + public void setBlockMetadataWithNotify(int i, int j, int k, int l) + { + if(setBlockMetadata(i, j, k, l)) + { + notifyBlockChange(i, j, k, getBlockId(i, j, k)); + } + } + + public boolean setBlockMetadata(int i, int j, int k, int l) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return false; + } + if(j < 0) + { + return false; + } + if(j >= 128) + { + return false; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + i &= 0xf; + k &= 0xf; + chunk.setBlockMetadata(i, j, k, l); + return true; + } + } + + public boolean setBlockWithNotify(int i, int j, int k, int l) + { + if(setBlock(i, j, k, l)) + { + notifyBlockChange(i, j, k, l); + return true; + } else + { + return false; + } + } + + public boolean setBlockAndMetadataWithNotify(int i, int j, int k, int l, int i1) + { + if(setBlockAndMetadata(i, j, k, l, i1)) + { + notifyBlockChange(i, j, k, l); + return true; + } else + { + return false; + } + } + + public void markBlockNeedsUpdate(int i, int j, int k) + { + for(int l = 0; l < worldAccesses.size(); l++) + { + ((IWorldAccess)worldAccesses.get(l)).func_934_a(i, j, k); + } + + } + + protected void notifyBlockChange(int i, int j, int k, int l) + { + markBlockNeedsUpdate(i, j, k); + notifyBlocksOfNeighborChange(i, j, k, l); + } + + public void markBlocksDirtyVertical(int i, int j, int k, int l) + { + if(k > l) + { + int i1 = l; + l = k; + k = i1; + } + markBlocksDirty(i, k, j, i, l, j); + } + + public void markBlockAsNeedsUpdate(int i, int j, int k) + { + for(int l = 0; l < worldAccesses.size(); l++) + { + ((IWorldAccess)worldAccesses.get(l)).markBlockRangeNeedsUpdate(i, j, k, i, j, k); + } + + } + + public void markBlocksDirty(int i, int j, int k, int l, int i1, int j1) + { + for(int k1 = 0; k1 < worldAccesses.size(); k1++) + { + ((IWorldAccess)worldAccesses.get(k1)).markBlockRangeNeedsUpdate(i, j, k, l, i1, j1); + } + + } + + public void notifyBlocksOfNeighborChange(int i, int j, int k, int l) + { + notifyBlockOfNeighborChange(i - 1, j, k, l); + notifyBlockOfNeighborChange(i + 1, j, k, l); + notifyBlockOfNeighborChange(i, j - 1, k, l); + notifyBlockOfNeighborChange(i, j + 1, k, l); + notifyBlockOfNeighborChange(i, j, k - 1, l); + notifyBlockOfNeighborChange(i, j, k + 1, l); + } + + private void notifyBlockOfNeighborChange(int i, int j, int k, int l) + { + if(field_1043_h || multiplayerWorld) + { + return; + } + Block block = Block.blocksList[getBlockId(i, j, k)]; + if(block != null) + { + block.onNeighborBlockChange(this, i, j, k, l); + } + } + + public boolean canBlockSeeTheSky(int i, int j, int k) + { + return getChunkFromChunkCoords(i >> 4, k >> 4).canBlockSeeTheSky(i & 0xf, j, k & 0xf); + } + + public int getBlockLightValue(int i, int j, int k) + { + return getBlockLightValue_do(i, j, k, true); + } + + public int getBlockLightValue_do(int i, int j, int k, boolean flag) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return 15; + } + if(flag) + { + int l = getBlockId(i, j, k); + if(l == Block.stairSingle.blockID || l == Block.tilledField.blockID) + { + int j1 = getBlockLightValue_do(i, j + 1, k, false); + int k1 = getBlockLightValue_do(i + 1, j, k, false); + int l1 = getBlockLightValue_do(i - 1, j, k, false); + int i2 = getBlockLightValue_do(i, j, k + 1, false); + int j2 = getBlockLightValue_do(i, j, k - 1, false); + if(k1 > j1) + { + j1 = k1; + } + if(l1 > j1) + { + j1 = l1; + } + if(i2 > j1) + { + j1 = i2; + } + if(j2 > j1) + { + j1 = j2; + } + return j1; + } + } + if(j < 0) + { + return 0; + } + if(j >= 128) + { + int i1 = 15 - skylightSubtracted; + if(i1 < 0) + { + i1 = 0; + } + return i1; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + i &= 0xf; + k &= 0xf; + return chunk.getBlockLightValue(i, j, k, skylightSubtracted); + } + } + + public boolean canExistingBlockSeeTheSky(int i, int j, int k) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return false; + } + if(j < 0) + { + return false; + } + if(j >= 128) + { + return true; + } + if(!chunkExists(i >> 4, k >> 4)) + { + return false; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + i &= 0xf; + k &= 0xf; + return chunk.canBlockSeeTheSky(i, j, k); + } + } + + public int getHeightValue(int i, int j) + { + if(i < 0xfe17b800 || j < 0xfe17b800 || i >= 0x1e84800 || j > 0x1e84800) + { + return 0; + } + if(!chunkExists(i >> 4, j >> 4)) + { + return 0; + } else + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, j >> 4); + return chunk.getHeightValue(i & 0xf, j & 0xf); + } + } + + public void neighborLightPropagationChanged(EnumSkyBlock enumskyblock, int i, int j, int k, int l) + { + if(worldProvider.field_6478_e && enumskyblock == EnumSkyBlock.Sky) + { + return; + } + if(!blockExists(i, j, k)) + { + return; + } + if(enumskyblock == EnumSkyBlock.Sky) + { + if(canExistingBlockSeeTheSky(i, j, k)) + { + l = 15; + } + } else + if(enumskyblock == EnumSkyBlock.Block) + { + int i1 = getBlockId(i, j, k); + if(Block.lightValue[i1] > l) + { + l = Block.lightValue[i1]; + } + } + if(getSavedLightValue(enumskyblock, i, j, k) != l) + { + func_616_a(enumskyblock, i, j, k, i, j, k); + } + } + + public int getSavedLightValue(EnumSkyBlock enumskyblock, int i, int j, int k) + { + if(j < 0 || j >= 128 || i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return enumskyblock.field_1722_c; + } + int l = i >> 4; + int i1 = k >> 4; + if(!chunkExists(l, i1)) + { + return 0; + } else + { + Chunk chunk = getChunkFromChunkCoords(l, i1); + return chunk.getSavedLightValue(enumskyblock, i & 0xf, j, k & 0xf); + } + } + + public void setLightValue(EnumSkyBlock enumskyblock, int i, int j, int k, int l) + { + if(i < 0xfe17b800 || k < 0xfe17b800 || i >= 0x1e84800 || k > 0x1e84800) + { + return; + } + if(j < 0) + { + return; + } + if(j >= 128) + { + return; + } + if(!chunkExists(i >> 4, k >> 4)) + { + return; + } + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + chunk.setLightValue(enumskyblock, i & 0xf, j, k & 0xf, l); + for(int i1 = 0; i1 < worldAccesses.size(); i1++) + { + ((IWorldAccess)worldAccesses.get(i1)).func_934_a(i, j, k); + } + + } + + public float getLightBrightness(int i, int j, int k) + { + return worldProvider.lightBrightnessTable[getBlockLightValue(i, j, k)]; + } + + public boolean isDaytime() + { + return skylightSubtracted < 4; + } + + public MovingObjectPosition rayTraceBlocks(Vec3D vec3d, Vec3D vec3d1) + { + return rayTraceBlocks_do(vec3d, vec3d1, false); + } + + public MovingObjectPosition rayTraceBlocks_do(Vec3D vec3d, Vec3D vec3d1, boolean flag) + { + if(Double.isNaN(vec3d.xCoord) || Double.isNaN(vec3d.yCoord) || Double.isNaN(vec3d.zCoord)) + { + return null; + } + if(Double.isNaN(vec3d1.xCoord) || Double.isNaN(vec3d1.yCoord) || Double.isNaN(vec3d1.zCoord)) + { + return null; + } + int i = MathHelper.floor_double(vec3d1.xCoord); + int j = MathHelper.floor_double(vec3d1.yCoord); + int k = MathHelper.floor_double(vec3d1.zCoord); + int l = MathHelper.floor_double(vec3d.xCoord); + int i1 = MathHelper.floor_double(vec3d.yCoord); + int j1 = MathHelper.floor_double(vec3d.zCoord); + for(int k1 = 200; k1-- >= 0;) + { + if(Double.isNaN(vec3d.xCoord) || Double.isNaN(vec3d.yCoord) || Double.isNaN(vec3d.zCoord)) + { + return null; + } + if(l == i && i1 == j && j1 == k) + { + return null; + } + double d = 999D; + double d1 = 999D; + double d2 = 999D; + if(i > l) + { + d = (double)l + 1.0D; + } + if(i < l) + { + d = (double)l + 0.0D; + } + if(j > i1) + { + d1 = (double)i1 + 1.0D; + } + if(j < i1) + { + d1 = (double)i1 + 0.0D; + } + if(k > j1) + { + d2 = (double)j1 + 1.0D; + } + if(k < j1) + { + d2 = (double)j1 + 0.0D; + } + double d3 = 999D; + double d4 = 999D; + double d5 = 999D; + double d6 = vec3d1.xCoord - vec3d.xCoord; + double d7 = vec3d1.yCoord - vec3d.yCoord; + double d8 = vec3d1.zCoord - vec3d.zCoord; + if(d != 999D) + { + d3 = (d - vec3d.xCoord) / d6; + } + if(d1 != 999D) + { + d4 = (d1 - vec3d.yCoord) / d7; + } + if(d2 != 999D) + { + d5 = (d2 - vec3d.zCoord) / d8; + } + byte byte0 = 0; + if(d3 < d4 && d3 < d5) + { + if(i > l) + { + byte0 = 4; + } else + { + byte0 = 5; + } + vec3d.xCoord = d; + vec3d.yCoord += d7 * d3; + vec3d.zCoord += d8 * d3; + } else + if(d4 < d5) + { + if(j > i1) + { + byte0 = 0; + } else + { + byte0 = 1; + } + vec3d.xCoord += d6 * d4; + vec3d.yCoord = d1; + vec3d.zCoord += d8 * d4; + } else + { + if(k > j1) + { + byte0 = 2; + } else + { + byte0 = 3; + } + vec3d.xCoord += d6 * d5; + vec3d.yCoord += d7 * d5; + vec3d.zCoord = d2; + } + Vec3D vec3d2 = Vec3D.createVector(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord); + l = (int)(vec3d2.xCoord = MathHelper.floor_double(vec3d.xCoord)); + if(byte0 == 5) + { + l--; + vec3d2.xCoord++; + } + i1 = (int)(vec3d2.yCoord = MathHelper.floor_double(vec3d.yCoord)); + if(byte0 == 1) + { + i1--; + vec3d2.yCoord++; + } + j1 = (int)(vec3d2.zCoord = MathHelper.floor_double(vec3d.zCoord)); + if(byte0 == 3) + { + j1--; + vec3d2.zCoord++; + } + int l1 = getBlockId(l, i1, j1); + int i2 = getBlockMetadata(l, i1, j1); + Block block = Block.blocksList[l1]; + if(l1 > 0 && block.canCollideCheck(i2, flag)) + { + MovingObjectPosition movingobjectposition = block.collisionRayTrace(this, l, i1, j1, vec3d, vec3d1); + if(movingobjectposition != null) + { + return movingobjectposition; + } + } + } + + return null; + } + + public void playSoundAtEntity(Entity entity, String s, float f, float f1) + { + for(int i = 0; i < worldAccesses.size(); i++) + { + ((IWorldAccess)worldAccesses.get(i)).playSound(s, entity.posX, entity.posY - (double)entity.yOffset, entity.posZ, f, f1); + } + + } + + public void playSoundEffect(double d, double d1, double d2, String s, + float f, float f1) + { + for(int i = 0; i < worldAccesses.size(); i++) + { + ((IWorldAccess)worldAccesses.get(i)).playSound(s, d, d1, d2, f, f1); + } + + } + + public void playRecord(String s, int i, int j, int k) + { + for(int l = 0; l < worldAccesses.size(); l++) + { + ((IWorldAccess)worldAccesses.get(l)).playRecord(s, i, j, k); + } + + } + + public void spawnParticle(String s, double d, double d1, double d2, + double d3, double d4, double d5) + { + for(int i = 0; i < worldAccesses.size(); i++) + { + ((IWorldAccess)worldAccesses.get(i)).spawnParticle(s, d, d1, d2, d3, d4, d5); + } + + } + + public boolean entityJoinedWorld(Entity entity) + { + int i = MathHelper.floor_double(entity.posX / 16D); + int j = MathHelper.floor_double(entity.posZ / 16D); + boolean flag = false; + if(entity instanceof EntityPlayer) + { + flag = true; + } + if(flag || chunkExists(i, j)) + { + if(entity instanceof EntityPlayer) + { + EntityPlayer entityplayer = (EntityPlayer)entity; + playerEntities.add(entityplayer); + func_22140_w(); + } + getChunkFromChunkCoords(i, j).addEntity(entity); + loadedEntityList.add(entity); + obtainEntitySkin(entity); + return true; + } else + { + return false; + } + } + + protected void obtainEntitySkin(Entity entity) + { + for(int i = 0; i < worldAccesses.size(); i++) + { + ((IWorldAccess)worldAccesses.get(i)).obtainEntitySkin(entity); + } + + } + + protected void releaseEntitySkin(Entity entity) + { + for(int i = 0; i < worldAccesses.size(); i++) + { + ((IWorldAccess)worldAccesses.get(i)).releaseEntitySkin(entity); + } + + } + + public void setEntityDead(Entity entity) + { + if(entity.riddenByEntity != null) + { + entity.riddenByEntity.mountEntity(null); + } + if(entity.ridingEntity != null) + { + entity.mountEntity(null); + } + entity.setEntityDead(); + if(entity instanceof EntityPlayer) + { + playerEntities.remove((EntityPlayer)entity); + func_22140_w(); + } + } + + public void addWorldAccess(IWorldAccess iworldaccess) + { + worldAccesses.add(iworldaccess); + } + + public void removeWorldAccess(IWorldAccess iworldaccess) + { + worldAccesses.remove(iworldaccess); + } + + public List getCollidingBoundingBoxes(Entity entity, AxisAlignedBB axisalignedbb) + { + field_9428_I.clear(); + int i = MathHelper.floor_double(axisalignedbb.minX); + int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); + int k = MathHelper.floor_double(axisalignedbb.minY); + int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); + int i1 = MathHelper.floor_double(axisalignedbb.minZ); + int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); + for(int k1 = i; k1 < j; k1++) + { + for(int l1 = i1; l1 < j1; l1++) + { + if(!blockExists(k1, 64, l1)) + { + continue; + } + for(int i2 = k - 1; i2 < l; i2++) + { + Block block = Block.blocksList[getBlockId(k1, i2, l1)]; + if(block != null) + { + block.getCollidingBoundingBoxes(this, k1, i2, l1, axisalignedbb, field_9428_I); + } + } + + } + + } + + double d = 0.25D; + List list = getEntitiesWithinAABBExcludingEntity(entity, axisalignedbb.expand(d, d, d)); + for(int j2 = 0; j2 < list.size(); j2++) + { + AxisAlignedBB axisalignedbb1 = ((Entity)list.get(j2)).getBoundingBox(); + if(axisalignedbb1 != null && axisalignedbb1.intersectsWith(axisalignedbb)) + { + field_9428_I.add(axisalignedbb1); + } + axisalignedbb1 = entity.func_383_b_((Entity)list.get(j2)); + if(axisalignedbb1 != null && axisalignedbb1.intersectsWith(axisalignedbb)) + { + field_9428_I.add(axisalignedbb1); + } + } + + return field_9428_I; + } + + public int calculateSkylightSubtracted(float f) + { + float f1 = getCelestialAngle(f); + float f2 = 1.0F - (MathHelper.cos(f1 * 3.141593F * 2.0F) * 2.0F + 0.5F); + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f2 > 1.0F) + { + f2 = 1.0F; + } + return (int)(f2 * 11F); + } + + public Vec3D func_4079_a(Entity entity, float f) + { + float f1 = getCelestialAngle(f); + float f2 = MathHelper.cos(f1 * 3.141593F * 2.0F) * 2.0F + 0.5F; + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f2 > 1.0F) + { + f2 = 1.0F; + } + int i = MathHelper.floor_double(entity.posX); + int j = MathHelper.floor_double(entity.posZ); + float f3 = (float)getWorldChunkManager().func_4072_b(i, j); + int k = getWorldChunkManager().func_4073_a(i, j).getSkyColorByTemp(f3); + float f4 = (float)(k >> 16 & 0xff) / 255F; + float f5 = (float)(k >> 8 & 0xff) / 255F; + float f6 = (float)(k & 0xff) / 255F; + f4 *= f2; + f5 *= f2; + f6 *= f2; + return Vec3D.createVector(f4, f5, f6); + } + + public float getCelestialAngle(float f) + { + return worldProvider.calculateCelestialAngle(worldinfo.getWorldTime(), f); + } + + public Vec3D func_628_d(float f) + { + float f1 = getCelestialAngle(f); + float f2 = MathHelper.cos(f1 * 3.141593F * 2.0F) * 2.0F + 0.5F; + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f2 > 1.0F) + { + f2 = 1.0F; + } + float f3 = (float)(field_1019_F >> 16 & 255L) / 255F; + float f4 = (float)(field_1019_F >> 8 & 255L) / 255F; + float f5 = (float)(field_1019_F & 255L) / 255F; + f3 *= f2 * 0.9F + 0.1F; + f4 *= f2 * 0.9F + 0.1F; + f5 *= f2 * 0.85F + 0.15F; + return Vec3D.createVector(f3, f4, f5); + } + + public Vec3D func_4082_d(float f) + { + float f1 = getCelestialAngle(f); + return worldProvider.func_4096_a(f1, f); + } + + public int findTopSolidBlock(int i, int j) + { + Chunk chunk = getChunkFromBlockCoords(i, j); + int k; + for(k = 127; getBlockMaterial(i, k, j).getIsSolid() && k > 0; k--) { } + i &= 0xf; + j &= 0xf; + while(k > 0) + { + int l = chunk.getBlockID(i, k, j); + if(l == 0 || !Block.blocksList[l].blockMaterial.getIsSolid() && !Block.blocksList[l].blockMaterial.getIsLiquid()) + { + k--; + } else + { + return k + 1; + } + } + return -1; + } + + public int func_696_e(int i, int j) + { + return getChunkFromBlockCoords(i, j).getHeightValue(i & 0xf, j & 0xf); + } + + public float func_679_f(float f) + { + float f1 = getCelestialAngle(f); + float f2 = 1.0F - (MathHelper.cos(f1 * 3.141593F * 2.0F) * 2.0F + 0.75F); + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f2 > 1.0F) + { + f2 = 1.0F; + } + return f2 * f2 * 0.5F; + } + + public void scheduleBlockUpdate(int i, int j, int k, int l, int i1) + { + NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, l); + byte byte0 = 8; + if(scheduledUpdatesAreImmediate) + { + if(checkChunksExist(nextticklistentry.xCoord - byte0, nextticklistentry.yCoord - byte0, nextticklistentry.zCoord - byte0, nextticklistentry.xCoord + byte0, nextticklistentry.yCoord + byte0, nextticklistentry.zCoord + byte0)) + { + int j1 = getBlockId(nextticklistentry.xCoord, nextticklistentry.yCoord, nextticklistentry.zCoord); + if(j1 == nextticklistentry.blockID && j1 > 0) + { + Block.blocksList[j1].updateTick(this, nextticklistentry.xCoord, nextticklistentry.yCoord, nextticklistentry.zCoord, rand); + } + } + return; + } + if(checkChunksExist(i - byte0, j - byte0, k - byte0, i + byte0, j + byte0, k + byte0)) + { + if(l > 0) + { + nextticklistentry.setScheduledTime((long)i1 + worldinfo.getWorldTime()); + } + if(!scheduledTickSet.contains(nextticklistentry)) + { + scheduledTickSet.add(nextticklistentry); + scheduledTickTreeSet.add(nextticklistentry); + } + } + } + + public void func_633_c() + { + loadedEntityList.removeAll(unloadedEntityList); + for(int i = 0; i < unloadedEntityList.size(); i++) + { + Entity entity = (Entity)unloadedEntityList.get(i); + int i1 = entity.chunkCoordX; + int k1 = entity.chunkCoordZ; + if(entity.addedToChunk && chunkExists(i1, k1)) + { + getChunkFromChunkCoords(i1, k1).func_1015_b(entity); + } + } + + for(int j = 0; j < unloadedEntityList.size(); j++) + { + releaseEntitySkin((Entity)unloadedEntityList.get(j)); + } + + unloadedEntityList.clear(); + for(int k = 0; k < loadedEntityList.size(); k++) + { + Entity entity1 = (Entity)loadedEntityList.get(k); + if(entity1.ridingEntity != null) + { + if(!entity1.ridingEntity.isDead && entity1.ridingEntity.riddenByEntity == entity1) + { + continue; + } + entity1.ridingEntity.riddenByEntity = null; + entity1.ridingEntity = null; + } + if(!entity1.isDead) + { + updateEntity(entity1); + } + if(!entity1.isDead) + { + continue; + } + int j1 = entity1.chunkCoordX; + int l1 = entity1.chunkCoordZ; + if(entity1.addedToChunk && chunkExists(j1, l1)) + { + getChunkFromChunkCoords(j1, l1).func_1015_b(entity1); + } + loadedEntityList.remove(k--); + releaseEntitySkin(entity1); + } + + for(int l = 0; l < loadedTileEntityList.size(); l++) + { + TileEntity tileentity = (TileEntity)loadedTileEntityList.get(l); + tileentity.updateEntity(); + } + + } + + public void updateEntity(Entity entity) + { + updateEntityWithOptionalForce(entity, true); + } + + public void updateEntityWithOptionalForce(Entity entity, boolean flag) + { + int i = MathHelper.floor_double(entity.posX); + int j = MathHelper.floor_double(entity.posZ); + byte byte0 = 32; + if(flag && !checkChunksExist(i - byte0, 0, j - byte0, i + byte0, 128, j + byte0)) + { + return; + } + entity.lastTickPosX = entity.posX; + entity.lastTickPosY = entity.posY; + entity.lastTickPosZ = entity.posZ; + entity.prevRotationYaw = entity.rotationYaw; + entity.prevRotationPitch = entity.rotationPitch; + if(flag && entity.addedToChunk) + { + if(entity.ridingEntity != null) + { + entity.updateRidden(); + } else + { + entity.onUpdate(); + } + } + if(Double.isNaN(entity.posX) || Double.isInfinite(entity.posX)) + { + entity.posX = entity.lastTickPosX; + } + if(Double.isNaN(entity.posY) || Double.isInfinite(entity.posY)) + { + entity.posY = entity.lastTickPosY; + } + if(Double.isNaN(entity.posZ) || Double.isInfinite(entity.posZ)) + { + entity.posZ = entity.lastTickPosZ; + } + if(Double.isNaN(entity.rotationPitch) || Double.isInfinite(entity.rotationPitch)) + { + entity.rotationPitch = entity.prevRotationPitch; + } + if(Double.isNaN(entity.rotationYaw) || Double.isInfinite(entity.rotationYaw)) + { + entity.rotationYaw = entity.prevRotationYaw; + } + int k = MathHelper.floor_double(entity.posX / 16D); + int l = MathHelper.floor_double(entity.posY / 16D); + int i1 = MathHelper.floor_double(entity.posZ / 16D); + if(!entity.addedToChunk || entity.chunkCoordX != k || entity.chunkCoordY != l || entity.chunkCoordZ != i1) + { + if(entity.addedToChunk && chunkExists(entity.chunkCoordX, entity.chunkCoordZ)) + { + getChunkFromChunkCoords(entity.chunkCoordX, entity.chunkCoordZ).func_1016_a(entity, entity.chunkCoordY); + } + if(chunkExists(k, i1)) + { + entity.addedToChunk = true; + getChunkFromChunkCoords(k, i1).addEntity(entity); + } else + { + entity.addedToChunk = false; + } + } + if(flag && entity.addedToChunk && entity.riddenByEntity != null) + { + if(entity.riddenByEntity.isDead || entity.riddenByEntity.ridingEntity != entity) + { + entity.riddenByEntity.ridingEntity = null; + entity.riddenByEntity = null; + } else + { + updateEntity(entity.riddenByEntity); + } + } + } + + public boolean checkIfAABBIsClear(AxisAlignedBB axisalignedbb) + { + List list = getEntitiesWithinAABBExcludingEntity(null, axisalignedbb); + for(int i = 0; i < list.size(); i++) + { + Entity entity = (Entity)list.get(i); + if(!entity.isDead && entity.preventEntitySpawning) + { + return false; + } + } + + return true; + } + + public boolean getIsAnyLiquid(AxisAlignedBB axisalignedbb) + { + int i = MathHelper.floor_double(axisalignedbb.minX); + int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); + int k = MathHelper.floor_double(axisalignedbb.minY); + int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); + int i1 = MathHelper.floor_double(axisalignedbb.minZ); + int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); + if(axisalignedbb.minX < 0.0D) + { + i--; + } + if(axisalignedbb.minY < 0.0D) + { + k--; + } + if(axisalignedbb.minZ < 0.0D) + { + i1--; + } + for(int k1 = i; k1 < j; k1++) + { + for(int l1 = k; l1 < l; l1++) + { + for(int i2 = i1; i2 < j1; i2++) + { + Block block = Block.blocksList[getBlockId(k1, l1, i2)]; + if(block != null && block.blockMaterial.getIsLiquid()) + { + return true; + } + } + + } + + } + + return false; + } + + public boolean isBoundingBoxBurning(AxisAlignedBB axisalignedbb) + { + int i = MathHelper.floor_double(axisalignedbb.minX); + int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); + int k = MathHelper.floor_double(axisalignedbb.minY); + int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); + int i1 = MathHelper.floor_double(axisalignedbb.minZ); + int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); + if(checkChunksExist(i, k, i1, j, l, j1)) + { + for(int k1 = i; k1 < j; k1++) + { + for(int l1 = k; l1 < l; l1++) + { + for(int i2 = i1; i2 < j1; i2++) + { + int j2 = getBlockId(k1, l1, i2); + if(j2 == Block.fire.blockID || j2 == Block.lavaStill.blockID || j2 == Block.lavaMoving.blockID) + { + return true; + } + } + + } + + } + + } + return false; + } + + public boolean handleMaterialAcceleration(AxisAlignedBB axisalignedbb, Material material, Entity entity) + { + int i = MathHelper.floor_double(axisalignedbb.minX); + int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); + int k = MathHelper.floor_double(axisalignedbb.minY); + int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); + int i1 = MathHelper.floor_double(axisalignedbb.minZ); + int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); + if(!checkChunksExist(i, k, i1, j, l, j1)) + { + return false; + } + boolean flag = false; + Vec3D vec3d = Vec3D.createVector(0.0D, 0.0D, 0.0D); + for(int k1 = i; k1 < j; k1++) + { + for(int l1 = k; l1 < l; l1++) + { + for(int i2 = i1; i2 < j1; i2++) + { + Block block = Block.blocksList[getBlockId(k1, l1, i2)]; + if(block == null || block.blockMaterial != material) + { + continue; + } + double d1 = (float)(l1 + 1) - BlockFluids.setFluidHeight(getBlockMetadata(k1, l1, i2)); + if((double)l >= d1) + { + flag = true; + block.velocityToAddToEntity(this, k1, l1, i2, entity, vec3d); + } + } + + } + + } + + if(vec3d.lengthVector() > 0.0D) + { + vec3d = vec3d.normalize(); + double d = 0.0040000000000000001D; + entity.motionX += vec3d.xCoord * d; + entity.motionY += vec3d.yCoord * d; + entity.motionZ += vec3d.zCoord * d; + } + return flag; + } + + public boolean isMaterialInBB(AxisAlignedBB axisalignedbb, Material material) + { + int i = MathHelper.floor_double(axisalignedbb.minX); + int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); + int k = MathHelper.floor_double(axisalignedbb.minY); + int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); + int i1 = MathHelper.floor_double(axisalignedbb.minZ); + int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); + for(int k1 = i; k1 < j; k1++) + { + for(int l1 = k; l1 < l; l1++) + { + for(int i2 = i1; i2 < j1; i2++) + { + Block block = Block.blocksList[getBlockId(k1, l1, i2)]; + if(block != null && block.blockMaterial == material) + { + return true; + } + } + + } + + } + + return false; + } + + public boolean isAABBInMaterial(AxisAlignedBB axisalignedbb, Material material) + { + int i = MathHelper.floor_double(axisalignedbb.minX); + int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); + int k = MathHelper.floor_double(axisalignedbb.minY); + int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); + int i1 = MathHelper.floor_double(axisalignedbb.minZ); + int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); + for(int k1 = i; k1 < j; k1++) + { + for(int l1 = k; l1 < l; l1++) + { + for(int i2 = i1; i2 < j1; i2++) + { + Block block = Block.blocksList[getBlockId(k1, l1, i2)]; + if(block == null || block.blockMaterial != material) + { + continue; + } + int j2 = getBlockMetadata(k1, l1, i2); + double d = l1 + 1; + if(j2 < 8) + { + d = (double)(l1 + 1) - (double)j2 / 8D; + } + if(d >= axisalignedbb.minY) + { + return true; + } + } + + } + + } + + return false; + } + + public Explosion createExplosion(Entity entity, double d, double d1, double d2, + float f) + { + return newExplosion(entity, d, d1, d2, f, false); + } + + public Explosion newExplosion(Entity entity, double d, double d1, double d2, + float f, boolean flag) + { + Explosion explosion = new Explosion(this, entity, d, d1, d2, f); + explosion.field_12257_a = flag; + explosion.func_12248_a(); + explosion.func_12247_b(); + return explosion; + } + + public float func_675_a(Vec3D vec3d, AxisAlignedBB axisalignedbb) + { + double d = 1.0D / ((axisalignedbb.maxX - axisalignedbb.minX) * 2D + 1.0D); + double d1 = 1.0D / ((axisalignedbb.maxY - axisalignedbb.minY) * 2D + 1.0D); + double d2 = 1.0D / ((axisalignedbb.maxZ - axisalignedbb.minZ) * 2D + 1.0D); + int i = 0; + int j = 0; + for(float f = 0.0F; f <= 1.0F; f = (float)((double)f + d)) + { + for(float f1 = 0.0F; f1 <= 1.0F; f1 = (float)((double)f1 + d1)) + { + for(float f2 = 0.0F; f2 <= 1.0F; f2 = (float)((double)f2 + d2)) + { + double d3 = axisalignedbb.minX + (axisalignedbb.maxX - axisalignedbb.minX) * (double)f; + double d4 = axisalignedbb.minY + (axisalignedbb.maxY - axisalignedbb.minY) * (double)f1; + double d5 = axisalignedbb.minZ + (axisalignedbb.maxZ - axisalignedbb.minZ) * (double)f2; + if(rayTraceBlocks(Vec3D.createVector(d3, d4, d5), vec3d) == null) + { + i++; + } + j++; + } + + } + + } + + return (float)i / (float)j; + } + + public void onBlockHit(int i, int j, int k, int l) + { + if(l == 0) + { + j--; + } + if(l == 1) + { + j++; + } + if(l == 2) + { + k--; + } + if(l == 3) + { + k++; + } + if(l == 4) + { + i--; + } + if(l == 5) + { + i++; + } + if(getBlockId(i, j, k) == Block.fire.blockID) + { + playSoundEffect((float)i + 0.5F, (float)j + 0.5F, (float)k + 0.5F, "random.fizz", 0.5F, 2.6F + (rand.nextFloat() - rand.nextFloat()) * 0.8F); + setBlockWithNotify(i, j, k, 0); + } + } + + public Entity func_4085_a(Class class1) + { + return null; + } + + public String func_687_d() + { + return (new StringBuilder()).append("All: ").append(loadedEntityList.size()).toString(); + } + + public String func_21119_g() + { + return chunkProvider.toString(); + } + + public TileEntity getBlockTileEntity(int i, int j, int k) + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + if(chunk != null) + { + return chunk.getChunkBlockTileEntity(i & 0xf, j, k & 0xf); + } else + { + return null; + } + } + + public void setBlockTileEntity(int i, int j, int k, TileEntity tileentity) + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + if(chunk != null) + { + chunk.setChunkBlockTileEntity(i & 0xf, j, k & 0xf, tileentity); + } + } + + public void removeBlockTileEntity(int i, int j, int k) + { + Chunk chunk = getChunkFromChunkCoords(i >> 4, k >> 4); + if(chunk != null) + { + chunk.removeChunkBlockTileEntity(i & 0xf, j, k & 0xf); + } + } + + public boolean isBlockOpaqueCube(int i, int j, int k) + { + Block block = Block.blocksList[getBlockId(i, j, k)]; + if(block == null) + { + return false; + } else + { + return block.isOpaqueCube(); + } + } + + public void func_651_a(IProgressUpdate iprogressupdate) + { + saveWorld(true, iprogressupdate); + } + + public boolean func_6465_g() + { + if(field_4204_J >= 50) + { + return false; + } + field_4204_J++; + try + { + int i = 500; + for(; field_1051_z.size() > 0; ((MetadataChunkBlock)field_1051_z.remove(field_1051_z.size() - 1)).func_4127_a(this)) + { + if(--i <= 0) + { + boolean flag = true; + return flag; + } + } + + boolean flag1 = false; + return flag1; + } + finally + { + field_4204_J--; + } + } + + public void func_616_a(EnumSkyBlock enumskyblock, int i, int j, int k, int l, int i1, int j1) + { + func_627_a(enumskyblock, i, j, k, l, i1, j1, true); + } + + public void func_627_a(EnumSkyBlock enumskyblock, int i, int j, int k, int l, int i1, int j1, + boolean flag) + { + if(worldProvider.field_6478_e && enumskyblock == EnumSkyBlock.Sky) + { + return; + } + field_9429_y++; + if(field_9429_y == 50) + { + field_9429_y--; + return; + } + int k1 = (l + i) / 2; + int l1 = (j1 + k) / 2; + if(!blockExists(k1, 64, l1)) + { + field_9429_y--; + return; + } + if(getChunkFromBlockCoords(k1, l1).func_21167_h()) + { + return; + } + int i2 = field_1051_z.size(); + if(flag) + { + int j2 = 5; + if(j2 > i2) + { + j2 = i2; + } + for(int l2 = 0; l2 < j2; l2++) + { + MetadataChunkBlock metadatachunkblock = (MetadataChunkBlock)field_1051_z.get(field_1051_z.size() - l2 - 1); + if(metadatachunkblock.field_1299_a == enumskyblock && metadatachunkblock.func_866_a(i, j, k, l, i1, j1)) + { + field_9429_y--; + return; + } + } + + } + field_1051_z.add(new MetadataChunkBlock(enumskyblock, i, j, k, l, i1, j1)); + int k2 = 0xf4240; + if(field_1051_z.size() > 0xf4240) + { + System.out.println((new StringBuilder()).append("More than ").append(k2).append(" updates, aborting lighting updates").toString()); + field_1051_z.clear(); + } + field_9429_y--; + } + + public void calculateInitialSkylight() + { + int i = calculateSkylightSubtracted(1.0F); + if(i != skylightSubtracted) + { + skylightSubtracted = i; + } + } + + public void func_21114_a(boolean flag, boolean flag1) + { + spawnHostileMobs = flag; + field_21120_L = flag1; + } + + public void tick() + { + if(func_22142_y()) + { + boolean flag = false; + if(spawnHostileMobs && difficultySetting >= 1) + { + flag = SpawnerAnimals.func_22390_a(this, playerEntities); + } + if(!flag) + { + long l = worldinfo.getWorldTime() + 24000L; + worldinfo.setWorldTime(l - l % 24000L); + func_22141_x(); + } + } + SpawnerAnimals.performSpawning(this, spawnHostileMobs, field_21120_L); + chunkProvider.func_532_a(); + int i = calculateSkylightSubtracted(1.0F); + if(i != skylightSubtracted) + { + skylightSubtracted = i; + for(int j = 0; j < worldAccesses.size(); j++) + { + ((IWorldAccess)worldAccesses.get(j)).updateAllRenderers(); + } + + } + long l1 = worldinfo.getWorldTime() + 1L; + if(l1 % (long)autosavePeriod == 0L) + { + saveWorld(false, null); + } + worldinfo.setWorldTime(l1); + TickUpdates(false); + func_4080_j(); + } + + protected void func_4080_j() + { + field_9427_K.clear(); + for(int i = 0; i < playerEntities.size(); i++) + { + EntityPlayer entityplayer = (EntityPlayer)playerEntities.get(i); + int j = MathHelper.floor_double(entityplayer.posX / 16D); + int l = MathHelper.floor_double(entityplayer.posZ / 16D); + byte byte0 = 9; + for(int j1 = -byte0; j1 <= byte0; j1++) + { + for(int i2 = -byte0; i2 <= byte0; i2++) + { + field_9427_K.add(new ChunkCoordIntPair(j1 + j, i2 + l)); + } + + } + + } + + if(field_9426_L > 0) + { + field_9426_L--; + } + for(Iterator iterator = field_9427_K.iterator(); iterator.hasNext();) + { + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair)iterator.next(); + int k = chunkcoordintpair.chunkXPos * 16; + int i1 = chunkcoordintpair.chunkZPos * 16; + Chunk chunk = getChunkFromChunkCoords(chunkcoordintpair.chunkXPos, chunkcoordintpair.chunkZPos); + if(field_9426_L == 0) + { + field_9437_g = field_9437_g * 3 + field_9436_h; + int k1 = field_9437_g >> 2; + int j2 = k1 & 0xf; + int l2 = k1 >> 8 & 0xf; + int j3 = k1 >> 16 & 0x7f; + int l3 = chunk.getBlockID(j2, j3, l2); + j2 += k; + l2 += i1; + if(l3 == 0 && getBlockLightValue(j2, j3, l2) <= rand.nextInt(8) && getSavedLightValue(EnumSkyBlock.Sky, j2, j3, l2) <= 0) + { + EntityPlayer entityplayer1 = getClosestPlayer((double)j2 + 0.5D, (double)j3 + 0.5D, (double)l2 + 0.5D, 8D); + if(entityplayer1 != null && entityplayer1.getDistanceSq((double)j2 + 0.5D, (double)j3 + 0.5D, (double)l2 + 0.5D) > 4D) + { + playSoundEffect((double)j2 + 0.5D, (double)j3 + 0.5D, (double)l2 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + rand.nextFloat() * 0.2F); + field_9426_L = rand.nextInt(12000) + 6000; + } + } + } + int l1 = 0; + while(l1 < 80) + { + field_9437_g = field_9437_g * 3 + field_9436_h; + int k2 = field_9437_g >> 2; + int i3 = k2 & 0xf; + int k3 = k2 >> 8 & 0xf; + int i4 = k2 >> 16 & 0x7f; + byte byte1 = chunk.blocks[i3 << 11 | k3 << 7 | i4]; + if(Block.tickOnLoad[byte1]) + { + Block.blocksList[byte1].updateTick(this, i3 + k, i4, k3 + i1, rand); + } + l1++; + } + } + + } + + public boolean TickUpdates(boolean flag) + { + int i = scheduledTickTreeSet.size(); + if(i != scheduledTickSet.size()) + { + throw new IllegalStateException("TickNextTick list out of synch"); + } + if(i > 1000) + { + i = 1000; + } + for(int j = 0; j < i; j++) + { + NextTickListEntry nextticklistentry = (NextTickListEntry)scheduledTickTreeSet.first(); + if(!flag && nextticklistentry.scheduledTime > worldinfo.getWorldTime()) + { + break; + } + scheduledTickTreeSet.remove(nextticklistentry); + scheduledTickSet.remove(nextticklistentry); + byte byte0 = 8; + if(!checkChunksExist(nextticklistentry.xCoord - byte0, nextticklistentry.yCoord - byte0, nextticklistentry.zCoord - byte0, nextticklistentry.xCoord + byte0, nextticklistentry.yCoord + byte0, nextticklistentry.zCoord + byte0)) + { + continue; + } + int k = getBlockId(nextticklistentry.xCoord, nextticklistentry.yCoord, nextticklistentry.zCoord); + if(k == nextticklistentry.blockID && k > 0) + { + Block.blocksList[k].updateTick(this, nextticklistentry.xCoord, nextticklistentry.yCoord, nextticklistentry.zCoord, rand); + } + } + + return scheduledTickTreeSet.size() != 0; + } + + public void randomDisplayUpdates(int i, int j, int k) + { + byte byte0 = 16; + Random random = new Random(); + for(int l = 0; l < 1000; l++) + { + int i1 = (i + rand.nextInt(byte0)) - rand.nextInt(byte0); + int j1 = (j + rand.nextInt(byte0)) - rand.nextInt(byte0); + int k1 = (k + rand.nextInt(byte0)) - rand.nextInt(byte0); + int l1 = getBlockId(i1, j1, k1); + if(l1 > 0) + { + Block.blocksList[l1].randomDisplayTick(this, i1, j1, k1, random); + } + } + + } + + public List getEntitiesWithinAABBExcludingEntity(Entity entity, AxisAlignedBB axisalignedbb) + { + field_1012_M.clear(); + int i = MathHelper.floor_double((axisalignedbb.minX - 2D) / 16D); + int j = MathHelper.floor_double((axisalignedbb.maxX + 2D) / 16D); + int k = MathHelper.floor_double((axisalignedbb.minZ - 2D) / 16D); + int l = MathHelper.floor_double((axisalignedbb.maxZ + 2D) / 16D); + for(int i1 = i; i1 <= j; i1++) + { + for(int j1 = k; j1 <= l; j1++) + { + if(chunkExists(i1, j1)) + { + getChunkFromChunkCoords(i1, j1).getEntitiesWithinAABBForEntity(entity, axisalignedbb, field_1012_M); + } + } + + } + + return field_1012_M; + } + + public List getEntitiesWithinAABB(Class class1, AxisAlignedBB axisalignedbb) + { + int i = MathHelper.floor_double((axisalignedbb.minX - 2D) / 16D); + int j = MathHelper.floor_double((axisalignedbb.maxX + 2D) / 16D); + int k = MathHelper.floor_double((axisalignedbb.minZ - 2D) / 16D); + int l = MathHelper.floor_double((axisalignedbb.maxZ + 2D) / 16D); + ArrayList arraylist = new ArrayList(); + for(int i1 = i; i1 <= j; i1++) + { + for(int j1 = k; j1 <= l; j1++) + { + if(chunkExists(i1, j1)) + { + getChunkFromChunkCoords(i1, j1).getEntitiesOfTypeWithinAAAB(class1, axisalignedbb, arraylist); + } + } + + } + + return arraylist; + } + + public List getLoadedEntityList() + { + return loadedEntityList; + } + + public void func_698_b(int i, int j, int k, TileEntity tileentity) + { + if(blockExists(i, j, k)) + { + getChunkFromBlockCoords(i, k).setChunkModified(); + } + for(int l = 0; l < worldAccesses.size(); l++) + { + ((IWorldAccess)worldAccesses.get(l)).doNothingWithTileEntity(i, j, k, tileentity); + } + + } + + public int countEntities(Class class1) + { + int i = 0; + for(int j = 0; j < loadedEntityList.size(); j++) + { + Entity entity = (Entity)loadedEntityList.get(j); + if(class1.isAssignableFrom(entity.getClass())) + { + i++; + } + } + + return i; + } + + public void func_636_a(List list) + { + loadedEntityList.addAll(list); + for(int i = 0; i < list.size(); i++) + { + obtainEntitySkin((Entity)list.get(i)); + } + + } + + public void func_632_b(List list) + { + unloadedEntityList.addAll(list); + } + + public void func_656_j() + { + while(chunkProvider.func_532_a()) ; + } + + public boolean canBlockBePlacedAt(int i, int j, int k, int l, boolean flag) + { + int i1 = getBlockId(j, k, l); + Block block = Block.blocksList[i1]; + Block block1 = Block.blocksList[i]; + AxisAlignedBB axisalignedbb = block1.getCollisionBoundingBoxFromPool(this, j, k, l); + if(flag) + { + axisalignedbb = null; + } + if(axisalignedbb != null && !checkIfAABBIsClear(axisalignedbb)) + { + return false; + } + if(block == Block.waterStill || block == Block.waterMoving || block == Block.lavaStill || block == Block.lavaMoving || block == Block.fire || block == Block.snow) + { + return true; + } + return i > 0 && block == null && block1.canPlaceBlockAt(this, j, k, l); + } + + public PathEntity getPathToEntity(Entity entity, Entity entity1, float f) + { + int i = MathHelper.floor_double(entity.posX); + int j = MathHelper.floor_double(entity.posY); + int k = MathHelper.floor_double(entity.posZ); + int l = (int)(f + 16F); + int i1 = i - l; + int j1 = j - l; + int k1 = k - l; + int l1 = i + l; + int i2 = j + l; + int j2 = k + l; + ChunkCache chunkcache = new ChunkCache(this, i1, j1, k1, l1, i2, j2); + return (new Pathfinder(chunkcache)).createEntityPathTo(entity, entity1, f); + } + + public PathEntity getEntityPathToXYZ(Entity entity, int i, int j, int k, float f) + { + int l = MathHelper.floor_double(entity.posX); + int i1 = MathHelper.floor_double(entity.posY); + int j1 = MathHelper.floor_double(entity.posZ); + int k1 = (int)(f + 8F); + int l1 = l - k1; + int i2 = i1 - k1; + int j2 = j1 - k1; + int k2 = l + k1; + int l2 = i1 + k1; + int i3 = j1 + k1; + ChunkCache chunkcache = new ChunkCache(this, l1, i2, j2, k2, l2, i3); + return (new Pathfinder(chunkcache)).createEntityPathTo(entity, i, j, k, f); + } + + public boolean isBlockProvidingPowerTo(int i, int j, int k, int l) + { + int i1 = getBlockId(i, j, k); + if(i1 == 0) + { + return false; + } else + { + return Block.blocksList[i1].isIndirectlyPoweringTo(this, i, j, k, l); + } + } + + public boolean isBlockGettingPowered(int i, int j, int k) + { + if(isBlockProvidingPowerTo(i, j - 1, k, 0)) + { + return true; + } + if(isBlockProvidingPowerTo(i, j + 1, k, 1)) + { + return true; + } + if(isBlockProvidingPowerTo(i, j, k - 1, 2)) + { + return true; + } + if(isBlockProvidingPowerTo(i, j, k + 1, 3)) + { + return true; + } + if(isBlockProvidingPowerTo(i - 1, j, k, 4)) + { + return true; + } + return isBlockProvidingPowerTo(i + 1, j, k, 5); + } + + public boolean isBlockIndirectlyProvidingPowerTo(int i, int j, int k, int l) + { + if(isBlockOpaqueCube(i, j, k)) + { + return isBlockGettingPowered(i, j, k); + } + int i1 = getBlockId(i, j, k); + if(i1 == 0) + { + return false; + } else + { + return Block.blocksList[i1].isPoweringTo(this, i, j, k, l); + } + } + + public boolean isBlockIndirectlyGettingPowered(int i, int j, int k) + { + if(isBlockIndirectlyProvidingPowerTo(i, j - 1, k, 0)) + { + return true; + } + if(isBlockIndirectlyProvidingPowerTo(i, j + 1, k, 1)) + { + return true; + } + if(isBlockIndirectlyProvidingPowerTo(i, j, k - 1, 2)) + { + return true; + } + if(isBlockIndirectlyProvidingPowerTo(i, j, k + 1, 3)) + { + return true; + } + if(isBlockIndirectlyProvidingPowerTo(i - 1, j, k, 4)) + { + return true; + } + return isBlockIndirectlyProvidingPowerTo(i + 1, j, k, 5); + } + + public EntityPlayer getClosestPlayerToEntity(Entity entity, double d) + { + return getClosestPlayer(entity.posX, entity.posY, entity.posZ, d); + } + + public EntityPlayer getClosestPlayer(double d, double d1, double d2, double d3) + { + double d4 = -1D; + EntityPlayer entityplayer = null; + for(int i = 0; i < playerEntities.size(); i++) + { + EntityPlayer entityplayer1 = (EntityPlayer)playerEntities.get(i); + double d5 = entityplayer1.getDistanceSq(d, d1, d2); + if((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1D || d5 < d4)) + { + d4 = d5; + entityplayer = entityplayer1; + } + } + + return entityplayer; + } + + public void setChunkData(int i, int j, int k, int l, int i1, int j1, byte abyte0[]) + { + int k1 = i >> 4; + int l1 = k >> 4; + int i2 = (i + l) - 1 >> 4; + int j2 = (k + j1) - 1 >> 4; + int k2 = 0; + int l2 = j; + int i3 = j + i1; + if(l2 < 0) + { + l2 = 0; + } + if(i3 > 128) + { + i3 = 128; + } + for(int j3 = k1; j3 <= i2; j3++) + { + int k3 = i - j3 * 16; + int l3 = (i + l) - j3 * 16; + if(k3 < 0) + { + k3 = 0; + } + if(l3 > 16) + { + l3 = 16; + } + for(int i4 = l1; i4 <= j2; i4++) + { + int j4 = k - i4 * 16; + int k4 = (k + j1) - i4 * 16; + if(j4 < 0) + { + j4 = 0; + } + if(k4 > 16) + { + k4 = 16; + } + k2 = getChunkFromChunkCoords(j3, i4).setChunkData(abyte0, k3, l2, j4, l3, i3, k4, k2); + markBlocksDirty(j3 * 16 + k3, l2, i4 * 16 + j4, j3 * 16 + l3, i3, i4 * 16 + k4); + } + + } + + } + + public void sendQuittingDisconnectingPacket() + { + } + + public void checkSessionLock() + { + field_22147_p.func_22150_b(); + } + + public void setWorldTime(long l) + { + worldinfo.setWorldTime(l); + } + + public long func_22138_q() + { + return worldinfo.getRandomSeed(); + } + + public long func_22139_r() + { + return worldinfo.getWorldTime(); + } + + public ChunkCoordinates func_22137_s() + { + return new ChunkCoordinates(worldinfo.func_22293_c(), worldinfo.func_22295_d(), worldinfo.func_22300_e()); + } + + public void func_22143_a(ChunkCoordinates chunkcoordinates) + { + worldinfo.func_22292_a(chunkcoordinates.field_22395_a, chunkcoordinates.field_22394_b, chunkcoordinates.field_22396_c); + } + + public void joinEntityInSurroundings(Entity entity) + { + int i = MathHelper.floor_double(entity.posX / 16D); + int j = MathHelper.floor_double(entity.posZ / 16D); + byte byte0 = 2; + for(int k = i - byte0; k <= i + byte0; k++) + { + for(int l = j - byte0; l <= j + byte0; l++) + { + getChunkFromChunkCoords(k, l); + } + + } + + if(!loadedEntityList.contains(entity)) + { + loadedEntityList.add(entity); + } + } + + public boolean func_6466_a(EntityPlayer entityplayer, int i, int j, int k) + { + return true; + } + + public void func_9425_a(Entity entity, byte byte0) + { + } + + public void updateEntityList() + { + loadedEntityList.removeAll(unloadedEntityList); + for(int i = 0; i < unloadedEntityList.size(); i++) + { + Entity entity = (Entity)unloadedEntityList.get(i); + int l = entity.chunkCoordX; + int j1 = entity.chunkCoordZ; + if(entity.addedToChunk && chunkExists(l, j1)) + { + getChunkFromChunkCoords(l, j1).func_1015_b(entity); + } + } + + for(int j = 0; j < unloadedEntityList.size(); j++) + { + releaseEntitySkin((Entity)unloadedEntityList.get(j)); + } + + unloadedEntityList.clear(); + for(int k = 0; k < loadedEntityList.size(); k++) + { + Entity entity1 = (Entity)loadedEntityList.get(k); + if(entity1.ridingEntity != null) + { + if(!entity1.ridingEntity.isDead && entity1.ridingEntity.riddenByEntity == entity1) + { + continue; + } + entity1.ridingEntity.riddenByEntity = null; + entity1.ridingEntity = null; + } + if(!entity1.isDead) + { + continue; + } + int i1 = entity1.chunkCoordX; + int k1 = entity1.chunkCoordZ; + if(entity1.addedToChunk && chunkExists(i1, k1)) + { + getChunkFromChunkCoords(i1, k1).func_1015_b(entity1); + } + loadedEntityList.remove(k--); + releaseEntitySkin(entity1); + } + + } + + public IChunkProvider func_21118_q() + { + return chunkProvider; + } + + public void playNoteAt(int i, int j, int k, int l, int i1) + { + int j1 = getBlockId(i, j, k); + if(j1 > 0) + { + Block.blocksList[j1].playBlock(this, i, j, k, l, i1); + } + } + + public WorldInfo func_22144_v() + { + return worldinfo; + } + + public void func_22140_w() + { + field_22146_A = !playerEntities.isEmpty(); + Iterator iterator = playerEntities.iterator(); + do + { + if(!iterator.hasNext()) + { + break; + } + EntityPlayer entityplayer = (EntityPlayer)iterator.next(); + if(entityplayer.isPlayerSleeping()) + { + continue; + } + field_22146_A = false; + break; + } while(true); + } + + protected void func_22141_x() + { + field_22146_A = false; + Iterator iterator = playerEntities.iterator(); + do + { + if(!iterator.hasNext()) + { + break; + } + EntityPlayer entityplayer = (EntityPlayer)iterator.next(); + if(entityplayer.isPlayerSleeping()) + { + entityplayer.func_22056_a(false, false); + } + } while(true); + } + + public boolean func_22142_y() + { + if(field_22146_A && !multiplayerWorld) + { + for(Iterator iterator = playerEntities.iterator(); iterator.hasNext();) + { + EntityPlayer entityplayer = (EntityPlayer)iterator.next(); + if(!entityplayer.func_22054_L()) + { + return false; + } + } + + return true; + } else + { + return false; + } + } + + public boolean scheduledUpdatesAreImmediate; + private List field_1051_z; + public List loadedEntityList; + private List unloadedEntityList; + private TreeSet scheduledTickTreeSet; + private Set scheduledTickSet; + public List loadedTileEntityList; + public List playerEntities; + private long field_1019_F; + public int skylightSubtracted; + protected int field_9437_g; + protected int field_9436_h; + public boolean field_1043_h; + private long lockTimestamp; + protected int autosavePeriod; + public int difficultySetting; + public Random rand; + public boolean isNewWorld; + public final WorldProvider worldProvider; + protected List worldAccesses; + protected IChunkProvider chunkProvider; + protected final ISaveHandler field_22147_p; + protected WorldInfo worldinfo; + public boolean field_9430_x; + private boolean field_22146_A; + private ArrayList field_9428_I; + private int field_4204_J; + private boolean spawnHostileMobs; + private boolean field_21120_L; + static int field_9429_y = 0; + private Set field_9427_K; + private int field_9426_L; + private List field_1012_M; + public boolean multiplayerWorld; + +} diff --git a/src/main/java/net/minecraft/src/WorldBlockPositionType.java b/src/main/java/net/minecraft/src/WorldBlockPositionType.java new file mode 100644 index 0000000..fe90962 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldBlockPositionType.java @@ -0,0 +1,28 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +class WorldBlockPositionType +{ + + public WorldBlockPositionType(WorldClient worldclient, int i, int j, int k, int l, int i1) + { + field_1203_g = worldclient; + field_1202_a = i; + field_1201_b = j; + field_1207_c = k; + field_1206_d = 80; + field_1205_e = l; + field_1204_f = i1; + } + + int field_1202_a; + int field_1201_b; + int field_1207_c; + int field_1206_d; + int field_1205_e; + int field_1204_f; + final WorldClient field_1203_g; /* synthetic field */ +} diff --git a/src/main/java/net/minecraft/src/WorldChunkManager.java b/src/main/java/net/minecraft/src/WorldChunkManager.java new file mode 100644 index 0000000..1527af2 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldChunkManager.java @@ -0,0 +1,134 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldChunkManager +{ + + protected WorldChunkManager() + { + } + + public WorldChunkManager(World world) + { + field_4194_e = new NoiseGeneratorOctaves2(new Random(world.func_22138_q() * 9871L), 4); + field_4193_f = new NoiseGeneratorOctaves2(new Random(world.func_22138_q() * 39811L), 4); + field_4192_g = new NoiseGeneratorOctaves2(new Random(world.func_22138_q() * 0x84a59L), 2); + } + + public MobSpawnerBase func_4074_a(ChunkCoordIntPair chunkcoordintpair) + { + return func_4073_a(chunkcoordintpair.chunkXPos >> 4, chunkcoordintpair.chunkZPos >> 4); + } + + public MobSpawnerBase func_4073_a(int i, int j) + { + return func_4069_a(i, j, 1, 1)[0]; + } + + public double func_4072_b(int i, int j) + { + temperature = field_4194_e.func_4112_a(temperature, i, j, 1, 1, 0.02500000037252903D, 0.02500000037252903D, 0.5D); + return temperature[0]; + } + + public MobSpawnerBase[] func_4069_a(int i, int j, int k, int l) + { + field_4195_d = loadBlockGeneratorData(field_4195_d, i, j, k, l); + return field_4195_d; + } + + public double[] getTemperatures(double ad[], int i, int j, int k, int l) + { + if(ad == null || ad.length < k * l) + { + ad = new double[k * l]; + } + ad = field_4194_e.func_4112_a(ad, i, j, k, l, 0.02500000037252903D, 0.02500000037252903D, 0.25D); + field_4196_c = field_4192_g.func_4112_a(field_4196_c, i, j, k, l, 0.25D, 0.25D, 0.58823529411764708D); + int i1 = 0; + for(int j1 = 0; j1 < k; j1++) + { + for(int k1 = 0; k1 < l; k1++) + { + double d = field_4196_c[i1] * 1.1000000000000001D + 0.5D; + double d1 = 0.01D; + double d2 = 1.0D - d1; + double d3 = (ad[i1] * 0.14999999999999999D + 0.69999999999999996D) * d2 + d * d1; + d3 = 1.0D - (1.0D - d3) * (1.0D - d3); + if(d3 < 0.0D) + { + d3 = 0.0D; + } + if(d3 > 1.0D) + { + d3 = 1.0D; + } + ad[i1] = d3; + i1++; + } + + } + + return ad; + } + + public MobSpawnerBase[] loadBlockGeneratorData(MobSpawnerBase amobspawnerbase[], int i, int j, int k, int l) + { + if(amobspawnerbase == null || amobspawnerbase.length < k * l) + { + amobspawnerbase = new MobSpawnerBase[k * l]; + } + temperature = field_4194_e.func_4112_a(temperature, i, j, k, k, 0.02500000037252903D, 0.02500000037252903D, 0.25D); + humidity = field_4193_f.func_4112_a(humidity, i, j, k, k, 0.05000000074505806D, 0.05000000074505806D, 0.33333333333333331D); + field_4196_c = field_4192_g.func_4112_a(field_4196_c, i, j, k, k, 0.25D, 0.25D, 0.58823529411764708D); + int i1 = 0; + for(int j1 = 0; j1 < k; j1++) + { + for(int k1 = 0; k1 < l; k1++) + { + double d = field_4196_c[i1] * 1.1000000000000001D + 0.5D; + double d1 = 0.01D; + double d2 = 1.0D - d1; + double d3 = (temperature[i1] * 0.14999999999999999D + 0.69999999999999996D) * d2 + d * d1; + d1 = 0.002D; + d2 = 1.0D - d1; + double d4 = (humidity[i1] * 0.14999999999999999D + 0.5D) * d2 + d * d1; + d3 = 1.0D - (1.0D - d3) * (1.0D - d3); + if(d3 < 0.0D) + { + d3 = 0.0D; + } + if(d4 < 0.0D) + { + d4 = 0.0D; + } + if(d3 > 1.0D) + { + d3 = 1.0D; + } + if(d4 > 1.0D) + { + d4 = 1.0D; + } + temperature[i1] = d3; + humidity[i1] = d4; + amobspawnerbase[i1++] = MobSpawnerBase.getBiomeFromLookup(d3, d4); + } + + } + + return amobspawnerbase; + } + + private NoiseGeneratorOctaves2 field_4194_e; + private NoiseGeneratorOctaves2 field_4193_f; + private NoiseGeneratorOctaves2 field_4192_g; + public double temperature[]; + public double humidity[]; + public double field_4196_c[]; + public MobSpawnerBase field_4195_d[]; +} diff --git a/src/main/java/net/minecraft/src/WorldChunkManagerHell.java b/src/main/java/net/minecraft/src/WorldChunkManagerHell.java new file mode 100644 index 0000000..f09100e --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldChunkManagerHell.java @@ -0,0 +1,66 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Arrays; + +public class WorldChunkManagerHell extends WorldChunkManager +{ + + public WorldChunkManagerHell(MobSpawnerBase mobspawnerbase, double d, double d1) + { + field_4201_e = mobspawnerbase; + field_4200_f = d; + field_4199_g = d1; + } + + public MobSpawnerBase func_4074_a(ChunkCoordIntPair chunkcoordintpair) + { + return field_4201_e; + } + + public MobSpawnerBase func_4073_a(int i, int j) + { + return field_4201_e; + } + + public double func_4072_b(int i, int j) + { + return field_4200_f; + } + + public MobSpawnerBase[] func_4069_a(int i, int j, int k, int l) + { + field_4195_d = loadBlockGeneratorData(field_4195_d, i, j, k, l); + return field_4195_d; + } + + public double[] getTemperatures(double ad[], int i, int j, int k, int l) + { + if(ad == null || ad.length < k * l) + { + ad = new double[k * l]; + } + Arrays.fill(ad, 0, k * l, field_4200_f); + return ad; + } + + public MobSpawnerBase[] loadBlockGeneratorData(MobSpawnerBase amobspawnerbase[], int i, int j, int k, int l) + { + if(amobspawnerbase == null || amobspawnerbase.length < k * l) + { + amobspawnerbase = new MobSpawnerBase[k * l]; + temperature = new double[k * l]; + humidity = new double[k * l]; + } + Arrays.fill(amobspawnerbase, 0, k * l, field_4201_e); + Arrays.fill(humidity, 0, k * l, field_4199_g); + Arrays.fill(temperature, 0, k * l, field_4200_f); + return amobspawnerbase; + } + + private MobSpawnerBase field_4201_e; + private double field_4200_f; + private double field_4199_g; +} diff --git a/src/main/java/net/minecraft/src/WorldClient.java b/src/main/java/net/minecraft/src/WorldClient.java new file mode 100644 index 0000000..f383b86 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldClient.java @@ -0,0 +1,243 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; + +public class WorldClient extends World +{ + + public WorldClient(NetClientHandler netclienthandler, long l, int i) + { + super(new SaveHandlerMP(), "MpServer", WorldProvider.func_4101_a(i), l); + field_1057_z = new LinkedList(); + field_1055_D = new MCHashTable(); + field_20914_E = new HashSet(); + field_1053_F = new HashSet(); + sendQueue = netclienthandler; + func_22143_a(new ChunkCoordinates(8, 64, 8)); + } + + public void tick() + { + setWorldTime(func_22139_r() + 1L); + int i = calculateSkylightSubtracted(1.0F); + if(i != skylightSubtracted) + { + skylightSubtracted = i; + for(int j = 0; j < worldAccesses.size(); j++) + { + ((IWorldAccess)worldAccesses.get(j)).updateAllRenderers(); + } + + } + for(int k = 0; k < 10 && !field_1053_F.isEmpty(); k++) + { + Entity entity = (Entity)field_1053_F.iterator().next(); + if(!loadedEntityList.contains(entity)) + { + entityJoinedWorld(entity); + } + } + + sendQueue.processReadPackets(); + for(int l = 0; l < field_1057_z.size(); l++) + { + WorldBlockPositionType worldblockpositiontype = (WorldBlockPositionType)field_1057_z.get(l); + if(--worldblockpositiontype.field_1206_d == 0) + { + super.setBlockAndMetadata(worldblockpositiontype.field_1202_a, worldblockpositiontype.field_1201_b, worldblockpositiontype.field_1207_c, worldblockpositiontype.field_1205_e, worldblockpositiontype.field_1204_f); + super.markBlockNeedsUpdate(worldblockpositiontype.field_1202_a, worldblockpositiontype.field_1201_b, worldblockpositiontype.field_1207_c); + field_1057_z.remove(l--); + } + } + + } + + public void func_711_c(int i, int j, int k, int l, int i1, int j1) + { + for(int k1 = 0; k1 < field_1057_z.size(); k1++) + { + WorldBlockPositionType worldblockpositiontype = (WorldBlockPositionType)field_1057_z.get(k1); + if(worldblockpositiontype.field_1202_a >= i && worldblockpositiontype.field_1201_b >= j && worldblockpositiontype.field_1207_c >= k && worldblockpositiontype.field_1202_a <= l && worldblockpositiontype.field_1201_b <= i1 && worldblockpositiontype.field_1207_c <= j1) + { + field_1057_z.remove(k1--); + } + } + + } + + protected IChunkProvider getChunkProvider() + { + field_20915_C = new ChunkProviderClient(this); + return field_20915_C; + } + + public void setSpawnLocation() + { + func_22143_a(new ChunkCoordinates(8, 64, 8)); + } + + protected void func_4080_j() + { + } + + public void scheduleBlockUpdate(int i, int j, int k, int l, int i1) + { + } + + public boolean TickUpdates(boolean flag) + { + return false; + } + + public void func_713_a(int i, int j, boolean flag) + { + if(flag) + { + field_20915_C.func_538_d(i, j); + } else + { + field_20915_C.func_539_c(i, j); + } + if(!flag) + { + markBlocksDirty(i * 16, 0, j * 16, i * 16 + 15, 128, j * 16 + 15); + } + } + + public boolean entityJoinedWorld(Entity entity) + { + boolean flag = super.entityJoinedWorld(entity); + field_20914_E.add(entity); + if(!flag) + { + field_1053_F.add(entity); + } + return flag; + } + + public void setEntityDead(Entity entity) + { + super.setEntityDead(entity); + field_20914_E.remove(entity); + } + + protected void obtainEntitySkin(Entity entity) + { + super.obtainEntitySkin(entity); + if(field_1053_F.contains(entity)) + { + field_1053_F.remove(entity); + } + } + + protected void releaseEntitySkin(Entity entity) + { + super.releaseEntitySkin(entity); + if(field_20914_E.contains(entity)) + { + field_1053_F.add(entity); + } + } + + public void func_712_a(int i, Entity entity) + { + Entity entity1 = func_709_b(i); + if(entity1 != null) + { + setEntityDead(entity1); + } + field_20914_E.add(entity); + entity.entityId = i; + if(!entityJoinedWorld(entity)) + { + field_1053_F.add(entity); + } + field_1055_D.addKey(i, entity); + } + + public Entity func_709_b(int i) + { + return (Entity)field_1055_D.lookup(i); + } + + public Entity removeEntityFromWorld(int i) + { + Entity entity = (Entity)field_1055_D.removeObject(i); + if(entity != null) + { + field_20914_E.remove(entity); + setEntityDead(entity); + } + return entity; + } + + public boolean setBlockMetadata(int i, int j, int k, int l) + { + int i1 = getBlockId(i, j, k); + int j1 = getBlockMetadata(i, j, k); + if(super.setBlockMetadata(i, j, k, l)) + { + field_1057_z.add(new WorldBlockPositionType(this, i, j, k, i1, j1)); + return true; + } else + { + return false; + } + } + + public boolean setBlockAndMetadata(int i, int j, int k, int l, int i1) + { + int j1 = getBlockId(i, j, k); + int k1 = getBlockMetadata(i, j, k); + if(super.setBlockAndMetadata(i, j, k, l, i1)) + { + field_1057_z.add(new WorldBlockPositionType(this, i, j, k, j1, k1)); + return true; + } else + { + return false; + } + } + + public boolean setBlock(int i, int j, int k, int l) + { + int i1 = getBlockId(i, j, k); + int j1 = getBlockMetadata(i, j, k); + if(super.setBlock(i, j, k, l)) + { + field_1057_z.add(new WorldBlockPositionType(this, i, j, k, i1, j1)); + return true; + } else + { + return false; + } + } + + public boolean func_714_c(int i, int j, int k, int l, int i1) + { + func_711_c(i, j, k, i, j, k); + if(super.setBlockAndMetadata(i, j, k, l, i1)) + { + notifyBlockChange(i, j, k, l); + return true; + } else + { + return false; + } + } + + public void sendQuittingDisconnectingPacket() + { + sendQueue.addToSendQueue(new Packet255KickDisconnect("Quitting")); + } + + private LinkedList field_1057_z; + private NetClientHandler sendQueue; + private ChunkProviderClient field_20915_C; + private MCHashTable field_1055_D; + private Set field_20914_E; + private Set field_1053_F; +} diff --git a/src/main/java/net/minecraft/src/WorldGenBigTree.java b/src/main/java/net/minecraft/src/WorldGenBigTree.java new file mode 100644 index 0000000..33f18d1 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenBigTree.java @@ -0,0 +1,450 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenBigTree extends WorldGenerator +{ + + public WorldGenBigTree() + { + field_881_b = new Random(); + field_878_e = 0; + field_876_g = 0.61799999999999999D; + field_875_h = 1.0D; + field_874_i = 0.38100000000000001D; + field_873_j = 1.0D; + field_872_k = 1.0D; + field_871_l = 1; + field_870_m = 12; + field_869_n = 4; + } + + void func_521_a() + { + height = (int)((double)field_878_e * field_876_g); + if(height >= field_878_e) + { + height = field_878_e - 1; + } + int i = (int)(1.3819999999999999D + Math.pow((field_872_k * (double)field_878_e) / 13D, 2D)); + if(i < 1) + { + i = 1; + } + int ai[][] = new int[i * field_878_e][4]; + int j = (basePos[1] + field_878_e) - field_869_n; + int k = 1; + int l = basePos[1] + height; + int i1 = j - basePos[1]; + ai[0][0] = basePos[0]; + ai[0][1] = j; + ai[0][2] = basePos[2]; + ai[0][3] = l; + j--; + while(i1 >= 0) + { + int j1 = 0; + float f = func_528_a(i1); + if(f < 0.0F) + { + j--; + i1--; + } else + { + double d = 0.5D; + for(; j1 < i; j1++) + { + double d1 = field_873_j * ((double)f * ((double)field_881_b.nextFloat() + 0.32800000000000001D)); + double d2 = (double)field_881_b.nextFloat() * 2D * 3.1415899999999999D; + int k1 = (int)(d1 * Math.sin(d2) + (double)basePos[0] + d); + int l1 = (int)(d1 * Math.cos(d2) + (double)basePos[2] + d); + int ai1[] = { + k1, j, l1 + }; + int ai2[] = { + k1, j + field_869_n, l1 + }; + if(func_524_a(ai1, ai2) != -1) + { + continue; + } + int ai3[] = { + basePos[0], basePos[1], basePos[2] + }; + double d3 = Math.sqrt(Math.pow(Math.abs(basePos[0] - ai1[0]), 2D) + Math.pow(Math.abs(basePos[2] - ai1[2]), 2D)); + double d4 = d3 * field_874_i; + if((double)ai1[1] - d4 > (double)l) + { + ai3[1] = l; + } else + { + ai3[1] = (int)((double)ai1[1] - d4); + } + if(func_524_a(ai3, ai1) == -1) + { + ai[k][0] = k1; + ai[k][1] = j; + ai[k][2] = l1; + ai[k][3] = ai3[1]; + k++; + } + } + + j--; + i1--; + } + } + field_868_o = new int[k][4]; + System.arraycopy(ai, 0, field_868_o, 0, k); + } + + void func_523_a(int i, int j, int k, float f, byte byte0, int l) + { + int i1 = (int)((double)f + 0.61799999999999999D); + byte byte1 = field_882_a[byte0]; + byte byte2 = field_882_a[byte0 + 3]; + int ai[] = { + i, j, k + }; + int ai1[] = { + 0, 0, 0 + }; + int j1 = -i1; + int k1 = -i1; + ai1[byte0] = ai[byte0]; + for(; j1 <= i1; j1++) + { + ai1[byte1] = ai[byte1] + j1; + for(int l1 = -i1; l1 <= i1;) + { + double d = Math.sqrt(Math.pow((double)Math.abs(j1) + 0.5D, 2D) + Math.pow((double)Math.abs(l1) + 0.5D, 2D)); + if(d > (double)f) + { + l1++; + } else + { + ai1[byte2] = ai[byte2] + l1; + int i2 = worldObj.getBlockId(ai1[0], ai1[1], ai1[2]); + if(i2 != 0 && i2 != 18) + { + l1++; + } else + { + worldObj.setBlock(ai1[0], ai1[1], ai1[2], l); + l1++; + } + } + } + + } + + } + + float func_528_a(int i) + { + if((double)i < (double)(float)field_878_e * 0.29999999999999999D) + { + return -1.618F; + } + float f = (float)field_878_e / 2.0F; + float f1 = (float)field_878_e / 2.0F - (float)i; + float f2; + if(f1 == 0.0F) + { + f2 = f; + } else + if(Math.abs(f1) >= f) + { + f2 = 0.0F; + } else + { + f2 = (float)Math.sqrt(Math.pow(Math.abs(f), 2D) - Math.pow(Math.abs(f1), 2D)); + } + f2 *= 0.5F; + return f2; + } + + float func_526_b(int i) + { + if(i < 0 || i >= field_869_n) + { + return -1F; + } + return i != 0 && i != field_869_n - 1 ? 3F : 2.0F; + } + + void func_520_a(int i, int j, int k) + { + int l = j; + for(int i1 = j + field_869_n; l < i1; l++) + { + float f = func_526_b(l - j); + func_523_a(i, l, k, f, (byte)1, 18); + } + + } + + void func_522_a(int ai[], int ai1[], int i) + { + int ai2[] = { + 0, 0, 0 + }; + byte byte0 = 0; + int j = 0; + for(; byte0 < 3; byte0++) + { + ai2[byte0] = ai1[byte0] - ai[byte0]; + if(Math.abs(ai2[byte0]) > Math.abs(ai2[j])) + { + j = byte0; + } + } + + if(ai2[j] == 0) + { + return; + } + byte byte1 = field_882_a[j]; + byte byte2 = field_882_a[j + 3]; + byte byte3; + if(ai2[j] > 0) + { + byte3 = 1; + } else + { + byte3 = -1; + } + double d = (double)ai2[byte1] / (double)ai2[j]; + double d1 = (double)ai2[byte2] / (double)ai2[j]; + int ai3[] = { + 0, 0, 0 + }; + int k = 0; + for(int l = ai2[j] + byte3; k != l; k += byte3) + { + ai3[j] = MathHelper.floor_double((double)(ai[j] + k) + 0.5D); + ai3[byte1] = MathHelper.floor_double((double)ai[byte1] + (double)k * d + 0.5D); + ai3[byte2] = MathHelper.floor_double((double)ai[byte2] + (double)k * d1 + 0.5D); + worldObj.setBlock(ai3[0], ai3[1], ai3[2], i); + } + + } + + void func_518_b() + { + int i = 0; + for(int j = field_868_o.length; i < j; i++) + { + int k = field_868_o[i][0]; + int l = field_868_o[i][1]; + int i1 = field_868_o[i][2]; + func_520_a(k, l, i1); + } + + } + + boolean func_527_c(int i) + { + return (double)i >= (double)field_878_e * 0.20000000000000001D; + } + + void func_529_c() + { + int i = basePos[0]; + int j = basePos[1]; + int k = basePos[1] + height; + int l = basePos[2]; + int ai[] = { + i, j, l + }; + int ai1[] = { + i, k, l + }; + func_522_a(ai, ai1, 17); + if(field_871_l == 2) + { + ai[0]++; + ai1[0]++; + func_522_a(ai, ai1, 17); + ai[2]++; + ai1[2]++; + func_522_a(ai, ai1, 17); + ai[0]--; + ai1[0]--; + func_522_a(ai, ai1, 17); + } + } + + void func_525_d() + { + int i = 0; + int j = field_868_o.length; + int ai[] = { + basePos[0], basePos[1], basePos[2] + }; + for(; i < j; i++) + { + int ai1[] = field_868_o[i]; + int ai2[] = { + ai1[0], ai1[1], ai1[2] + }; + ai[1] = ai1[3]; + int k = ai[1] - basePos[1]; + if(func_527_c(k)) + { + func_522_a(ai, ai2, 17); + } + } + + } + + int func_524_a(int ai[], int ai1[]) + { + int ai2[] = { + 0, 0, 0 + }; + byte byte0 = 0; + int i = 0; + for(; byte0 < 3; byte0++) + { + ai2[byte0] = ai1[byte0] - ai[byte0]; + if(Math.abs(ai2[byte0]) > Math.abs(ai2[i])) + { + i = byte0; + } + } + + if(ai2[i] == 0) + { + return -1; + } + byte byte1 = field_882_a[i]; + byte byte2 = field_882_a[i + 3]; + byte byte3; + if(ai2[i] > 0) + { + byte3 = 1; + } else + { + byte3 = -1; + } + double d = (double)ai2[byte1] / (double)ai2[i]; + double d1 = (double)ai2[byte2] / (double)ai2[i]; + int ai3[] = { + 0, 0, 0 + }; + int j = 0; + int k = ai2[i] + byte3; + do + { + if(j == k) + { + break; + } + ai3[i] = ai[i] + j; + ai3[byte1] = (int)((double)ai[byte1] + (double)j * d); + ai3[byte2] = (int)((double)ai[byte2] + (double)j * d1); + int l = worldObj.getBlockId(ai3[0], ai3[1], ai3[2]); + if(l != 0 && l != 18) + { + break; + } + j += byte3; + } while(true); + if(j == k) + { + return -1; + } else + { + return Math.abs(j); + } + } + + boolean func_519_e() + { + int ai[] = { + basePos[0], basePos[1], basePos[2] + }; + int ai1[] = { + basePos[0], (basePos[1] + field_878_e) - 1, basePos[2] + }; + int i = worldObj.getBlockId(basePos[0], basePos[1] - 1, basePos[2]); + if(i != 2 && i != 3) + { + return false; + } + int j = func_524_a(ai, ai1); + if(j == -1) + { + return true; + } + if(j < 6) + { + return false; + } else + { + field_878_e = j; + return true; + } + } + + public void func_517_a(double d, double d1, double d2) + { + field_870_m = (int)(d * 12D); + if(d > 0.5D) + { + field_869_n = 5; + } + field_873_j = d1; + field_872_k = d2; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + worldObj = world; + long l = random.nextLong(); + field_881_b.setSeed(l); + basePos[0] = i; + basePos[1] = j; + basePos[2] = k; + if(field_878_e == 0) + { + field_878_e = 5 + field_881_b.nextInt(field_870_m); + } + if(!func_519_e()) + { + return false; + } else + { + func_521_a(); + func_518_b(); + func_529_c(); + func_525_d(); + return true; + } + } + + static final byte field_882_a[] = { + 2, 0, 0, 1, 2, 1 + }; + Random field_881_b; + World worldObj; + int basePos[] = { + 0, 0, 0 + }; + int field_878_e; + int height; + double field_876_g; + double field_875_h; + double field_874_i; + double field_873_j; + double field_872_k; + int field_871_l; + int field_870_m; + int field_869_n; + int field_868_o[][]; + +} diff --git a/src/main/java/net/minecraft/src/WorldGenCactus.java b/src/main/java/net/minecraft/src/WorldGenCactus.java new file mode 100644 index 0000000..6adbe98 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenCactus.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenCactus extends WorldGenerator +{ + + public WorldGenCactus() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + for(int l = 0; l < 10; l++) + { + int i1 = (i + random.nextInt(8)) - random.nextInt(8); + int j1 = (j + random.nextInt(4)) - random.nextInt(4); + int k1 = (k + random.nextInt(8)) - random.nextInt(8); + if(!world.isAirBlock(i1, j1, k1)) + { + continue; + } + int l1 = 1 + random.nextInt(random.nextInt(3) + 1); + for(int i2 = 0; i2 < l1; i2++) + { + if(Block.cactus.canBlockStay(world, i1, j1 + i2, k1)) + { + world.setBlock(i1, j1 + i2, k1, Block.cactus.blockID); + } + } + + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenClay.java b/src/main/java/net/minecraft/src/WorldGenClay.java new file mode 100644 index 0000000..2dcdbb8 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenClay.java @@ -0,0 +1,69 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenClay extends WorldGenerator +{ + + public WorldGenClay(int i) + { + clayBlockId = Block.blockClay.blockID; + numberOfBlocks = i; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + if(world.getBlockMaterial(i, j, k) != Material.water) + { + return false; + } + float f = random.nextFloat() * 3.141593F; + double d = (float)(i + 8) + (MathHelper.sin(f) * (float)numberOfBlocks) / 8F; + double d1 = (float)(i + 8) - (MathHelper.sin(f) * (float)numberOfBlocks) / 8F; + double d2 = (float)(k + 8) + (MathHelper.cos(f) * (float)numberOfBlocks) / 8F; + double d3 = (float)(k + 8) - (MathHelper.cos(f) * (float)numberOfBlocks) / 8F; + double d4 = j + random.nextInt(3) + 2; + double d5 = j + random.nextInt(3) + 2; + for(int l = 0; l <= numberOfBlocks; l++) + { + double d6 = d + ((d1 - d) * (double)l) / (double)numberOfBlocks; + double d7 = d4 + ((d5 - d4) * (double)l) / (double)numberOfBlocks; + double d8 = d2 + ((d3 - d2) * (double)l) / (double)numberOfBlocks; + double d9 = (random.nextDouble() * (double)numberOfBlocks) / 16D; + double d10 = (double)(MathHelper.sin(((float)l * 3.141593F) / (float)numberOfBlocks) + 1.0F) * d9 + 1.0D; + double d11 = (double)(MathHelper.sin(((float)l * 3.141593F) / (float)numberOfBlocks) + 1.0F) * d9 + 1.0D; + for(int i1 = (int)(d6 - d10 / 2D); i1 <= (int)(d6 + d10 / 2D); i1++) + { + for(int j1 = (int)(d7 - d11 / 2D); j1 <= (int)(d7 + d11 / 2D); j1++) + { + for(int k1 = (int)(d8 - d10 / 2D); k1 <= (int)(d8 + d10 / 2D); k1++) + { + double d12 = (((double)i1 + 0.5D) - d6) / (d10 / 2D); + double d13 = (((double)j1 + 0.5D) - d7) / (d11 / 2D); + double d14 = (((double)k1 + 0.5D) - d8) / (d10 / 2D); + if(d12 * d12 + d13 * d13 + d14 * d14 >= 1.0D) + { + continue; + } + int l1 = world.getBlockId(i1, j1, k1); + if(l1 == Block.sand.blockID) + { + world.setBlock(i1, j1, k1, clayBlockId); + } + } + + } + + } + + } + + return true; + } + + private int clayBlockId; + private int numberOfBlocks; +} diff --git a/src/main/java/net/minecraft/src/WorldGenDungeons.java b/src/main/java/net/minecraft/src/WorldGenDungeons.java new file mode 100644 index 0000000..8944f3d --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenDungeons.java @@ -0,0 +1,214 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenDungeons extends WorldGenerator +{ + + public WorldGenDungeons() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + byte byte0 = 3; + int l = random.nextInt(2) + 2; + int i1 = random.nextInt(2) + 2; + int j1 = 0; + for(int k1 = i - l - 1; k1 <= i + l + 1; k1++) + { + for(int j2 = j - 1; j2 <= j + byte0 + 1; j2++) + { + for(int i3 = k - i1 - 1; i3 <= k + i1 + 1; i3++) + { + Material material = world.getBlockMaterial(k1, j2, i3); + if(j2 == j - 1 && !material.isSolid()) + { + return false; + } + if(j2 == j + byte0 + 1 && !material.isSolid()) + { + return false; + } + if((k1 == i - l - 1 || k1 == i + l + 1 || i3 == k - i1 - 1 || i3 == k + i1 + 1) && j2 == j && world.isAirBlock(k1, j2, i3) && world.isAirBlock(k1, j2 + 1, i3)) + { + j1++; + } + } + + } + + } + + if(j1 < 1 || j1 > 5) + { + return false; + } + for(int l1 = i - l - 1; l1 <= i + l + 1; l1++) + { + for(int k2 = j + byte0; k2 >= j - 1; k2--) + { + for(int j3 = k - i1 - 1; j3 <= k + i1 + 1; j3++) + { + if(l1 == i - l - 1 || k2 == j - 1 || j3 == k - i1 - 1 || l1 == i + l + 1 || k2 == j + byte0 + 1 || j3 == k + i1 + 1) + { + if(k2 >= 0 && !world.getBlockMaterial(l1, k2 - 1, j3).isSolid()) + { + world.setBlockWithNotify(l1, k2, j3, 0); + continue; + } + if(!world.getBlockMaterial(l1, k2, j3).isSolid()) + { + continue; + } + if(k2 == j - 1 && random.nextInt(4) != 0) + { + world.setBlockWithNotify(l1, k2, j3, Block.cobblestoneMossy.blockID); + } else + { + world.setBlockWithNotify(l1, k2, j3, Block.cobblestone.blockID); + } + } else + { + world.setBlockWithNotify(l1, k2, j3, 0); + } + } + + } + + } + + for(int i2 = 0; i2 < 2; i2++) + { +label0: + for(int l2 = 0; l2 < 3; l2++) + { + int k3 = (i + random.nextInt(l * 2 + 1)) - l; + int l3 = j; + int i4 = (k + random.nextInt(i1 * 2 + 1)) - i1; + if(!world.isAirBlock(k3, l3, i4)) + { + continue; + } + int j4 = 0; + if(world.getBlockMaterial(k3 - 1, l3, i4).isSolid()) + { + j4++; + } + if(world.getBlockMaterial(k3 + 1, l3, i4).isSolid()) + { + j4++; + } + if(world.getBlockMaterial(k3, l3, i4 - 1).isSolid()) + { + j4++; + } + if(world.getBlockMaterial(k3, l3, i4 + 1).isSolid()) + { + j4++; + } + if(j4 != 1) + { + continue; + } + world.setBlockWithNotify(k3, l3, i4, Block.crate.blockID); + TileEntityChest tileentitychest = (TileEntityChest)world.getBlockTileEntity(k3, l3, i4); + int k4 = 0; + do + { + if(k4 >= 8) + { + break label0; + } + ItemStack itemstack = pickCheckLootItem(random); + if(itemstack != null) + { + tileentitychest.setInventorySlotContents(random.nextInt(tileentitychest.getSizeInventory()), itemstack); + } + k4++; + } while(true); + } + + } + + world.setBlockWithNotify(i, j, k, Block.mobSpawner.blockID); + TileEntityMobSpawner tileentitymobspawner = (TileEntityMobSpawner)world.getBlockTileEntity(i, j, k); + tileentitymobspawner.setMobID(pickMobSpawner(random)); + return true; + } + + private ItemStack pickCheckLootItem(Random random) + { + int i = random.nextInt(11); + if(i == 0) + { + return new ItemStack(Item.saddle); + } + if(i == 1) + { + return new ItemStack(Item.ingotIron, random.nextInt(4) + 1); + } + if(i == 2) + { + return new ItemStack(Item.bread); + } + if(i == 3) + { + return new ItemStack(Item.wheat, random.nextInt(4) + 1); + } + if(i == 4) + { + return new ItemStack(Item.gunpowder, random.nextInt(4) + 1); + } + if(i == 5) + { + return new ItemStack(Item.silk, random.nextInt(4) + 1); + } + if(i == 6) + { + return new ItemStack(Item.bucketEmpty); + } + if(i == 7 && random.nextInt(100) == 0) + { + return new ItemStack(Item.appleGold); + } + if(i == 8 && random.nextInt(2) == 0) + { + return new ItemStack(Item.redstone, random.nextInt(4) + 1); + } + if(i == 9 && random.nextInt(10) == 0) + { + return new ItemStack(Item.itemsList[Item.record13.shiftedIndex + random.nextInt(2)]); + } else + { + return null; + } + } + + private String pickMobSpawner(Random random) + { + int i = random.nextInt(4); + if(i == 0) + { + return "Skeleton"; + } + if(i == 1) + { + return "Zombie"; + } + if(i == 2) + { + return "Zombie"; + } + if(i == 3) + { + return "Spider"; + } else + { + return ""; + } + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenFire.java b/src/main/java/net/minecraft/src/WorldGenFire.java new file mode 100644 index 0000000..a194d6b --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenFire.java @@ -0,0 +1,30 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenFire extends WorldGenerator +{ + + public WorldGenFire() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + for(int l = 0; l < 64; l++) + { + int i1 = (i + random.nextInt(8)) - random.nextInt(8); + int j1 = (j + random.nextInt(4)) - random.nextInt(4); + int k1 = (k + random.nextInt(8)) - random.nextInt(8); + if(world.isAirBlock(i1, j1, k1) && world.getBlockId(i1, j1 - 1, k1) == Block.bloodStone.blockID) + { + world.setBlockWithNotify(i1, j1, k1, Block.fire.blockID); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenFlowers.java b/src/main/java/net/minecraft/src/WorldGenFlowers.java new file mode 100644 index 0000000..2362ca8 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenFlowers.java @@ -0,0 +1,33 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenFlowers extends WorldGenerator +{ + + public WorldGenFlowers(int i) + { + plantBlockId = i; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + for(int l = 0; l < 64; l++) + { + int i1 = (i + random.nextInt(8)) - random.nextInt(8); + int j1 = (j + random.nextInt(4)) - random.nextInt(4); + int k1 = (k + random.nextInt(8)) - random.nextInt(8); + if(world.isAirBlock(i1, j1, k1) && ((BlockFlower)Block.blocksList[plantBlockId]).canBlockStay(world, i1, j1, k1)) + { + world.setBlock(i1, j1, k1, plantBlockId); + } + } + + return true; + } + + private int plantBlockId; +} diff --git a/src/main/java/net/minecraft/src/WorldGenForest.java b/src/main/java/net/minecraft/src/WorldGenForest.java new file mode 100644 index 0000000..e32f2ea --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenForest.java @@ -0,0 +1,96 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenForest extends WorldGenerator +{ + + public WorldGenForest() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + int l = random.nextInt(3) + 5; + boolean flag = true; + if(j < 1 || j + l + 1 > 128) + { + return false; + } + for(int i1 = j; i1 <= j + 1 + l; i1++) + { + byte byte0 = 1; + if(i1 == j) + { + byte0 = 0; + } + if(i1 >= (j + 1 + l) - 2) + { + byte0 = 2; + } + for(int i2 = i - byte0; i2 <= i + byte0 && flag; i2++) + { + for(int l2 = k - byte0; l2 <= k + byte0 && flag; l2++) + { + if(i1 >= 0 && i1 < 128) + { + int j3 = world.getBlockId(i2, i1, l2); + if(j3 != 0 && j3 != Block.leaves.blockID) + { + flag = false; + } + } else + { + flag = false; + } + } + + } + + } + + if(!flag) + { + return false; + } + int j1 = world.getBlockId(i, j - 1, k); + if(j1 != Block.grass.blockID && j1 != Block.dirt.blockID || j >= 128 - l - 1) + { + return false; + } + world.setBlock(i, j - 1, k, Block.dirt.blockID); + for(int k1 = (j - 3) + l; k1 <= j + l; k1++) + { + int j2 = k1 - (j + l); + int i3 = 1 - j2 / 2; + for(int k3 = i - i3; k3 <= i + i3; k3++) + { + int l3 = k3 - i; + for(int i4 = k - i3; i4 <= k + i3; i4++) + { + int j4 = i4 - k; + if((Math.abs(l3) != i3 || Math.abs(j4) != i3 || random.nextInt(2) != 0 && j2 != 0) && !Block.opaqueCubeLookup[world.getBlockId(k3, k1, i4)]) + { + world.setBlockAndMetadata(k3, k1, i4, Block.leaves.blockID, 2); + } + } + + } + + } + + for(int l1 = 0; l1 < l; l1++) + { + int k2 = world.getBlockId(i, j + l1, k); + if(k2 == 0 || k2 == Block.leaves.blockID) + { + world.setBlockAndMetadata(i, j + l1, k, Block.wood.blockID, 2); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenHellLava.java b/src/main/java/net/minecraft/src/WorldGenHellLava.java new file mode 100644 index 0000000..878b88c --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenHellLava.java @@ -0,0 +1,79 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenHellLava extends WorldGenerator +{ + + public WorldGenHellLava(int i) + { + field_4158_a = i; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + if(world.getBlockId(i, j + 1, k) != Block.bloodStone.blockID) + { + return false; + } + if(world.getBlockId(i, j, k) != 0 && world.getBlockId(i, j, k) != Block.bloodStone.blockID) + { + return false; + } + int l = 0; + if(world.getBlockId(i - 1, j, k) == Block.bloodStone.blockID) + { + l++; + } + if(world.getBlockId(i + 1, j, k) == Block.bloodStone.blockID) + { + l++; + } + if(world.getBlockId(i, j, k - 1) == Block.bloodStone.blockID) + { + l++; + } + if(world.getBlockId(i, j, k + 1) == Block.bloodStone.blockID) + { + l++; + } + if(world.getBlockId(i, j - 1, k) == Block.bloodStone.blockID) + { + l++; + } + int i1 = 0; + if(world.isAirBlock(i - 1, j, k)) + { + i1++; + } + if(world.isAirBlock(i + 1, j, k)) + { + i1++; + } + if(world.isAirBlock(i, j, k - 1)) + { + i1++; + } + if(world.isAirBlock(i, j, k + 1)) + { + i1++; + } + if(world.isAirBlock(i, j - 1, k)) + { + i1++; + } + if(l == 4 && i1 == 1) + { + world.setBlockWithNotify(i, j, k, field_4158_a); + world.scheduledUpdatesAreImmediate = true; + Block.blocksList[field_4158_a].updateTick(world, i, j, k, random); + world.scheduledUpdatesAreImmediate = false; + } + return true; + } + + private int field_4158_a; +} diff --git a/src/main/java/net/minecraft/src/WorldGenLakes.java b/src/main/java/net/minecraft/src/WorldGenLakes.java new file mode 100644 index 0000000..8b76465 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenLakes.java @@ -0,0 +1,135 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenLakes extends WorldGenerator +{ + + public WorldGenLakes(int i) + { + field_15235_a = i; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + i -= 8; + for(k -= 8; j > 0 && world.isAirBlock(i, j, k); j--) { } + j -= 4; + boolean aflag[] = new boolean[2048]; + int l = random.nextInt(4) + 4; + for(int i1 = 0; i1 < l; i1++) + { + double d = random.nextDouble() * 6D + 3D; + double d1 = random.nextDouble() * 4D + 2D; + double d2 = random.nextDouble() * 6D + 3D; + double d3 = random.nextDouble() * (16D - d - 2D) + 1.0D + d / 2D; + double d4 = random.nextDouble() * (8D - d1 - 4D) + 2D + d1 / 2D; + double d5 = random.nextDouble() * (16D - d2 - 2D) + 1.0D + d2 / 2D; + for(int j4 = 1; j4 < 15; j4++) + { + for(int k4 = 1; k4 < 15; k4++) + { + for(int l4 = 1; l4 < 7; l4++) + { + double d6 = ((double)j4 - d3) / (d / 2D); + double d7 = ((double)l4 - d4) / (d1 / 2D); + double d8 = ((double)k4 - d5) / (d2 / 2D); + double d9 = d6 * d6 + d7 * d7 + d8 * d8; + if(d9 < 1.0D) + { + aflag[(j4 * 16 + k4) * 8 + l4] = true; + } + } + + } + + } + + } + + for(int j1 = 0; j1 < 16; j1++) + { + for(int j2 = 0; j2 < 16; j2++) + { + for(int j3 = 0; j3 < 8; j3++) + { + boolean flag = !aflag[(j1 * 16 + j2) * 8 + j3] && (j1 < 15 && aflag[((j1 + 1) * 16 + j2) * 8 + j3] || j1 > 0 && aflag[((j1 - 1) * 16 + j2) * 8 + j3] || j2 < 15 && aflag[(j1 * 16 + (j2 + 1)) * 8 + j3] || j2 > 0 && aflag[(j1 * 16 + (j2 - 1)) * 8 + j3] || j3 < 7 && aflag[(j1 * 16 + j2) * 8 + (j3 + 1)] || j3 > 0 && aflag[(j1 * 16 + j2) * 8 + (j3 - 1)]); + if(!flag) + { + continue; + } + Material material = world.getBlockMaterial(i + j1, j + j3, k + j2); + if(j3 >= 4 && material.getIsLiquid()) + { + return false; + } + if(j3 < 4 && !material.isSolid() && world.getBlockId(i + j1, j + j3, k + j2) != field_15235_a) + { + return false; + } + } + + } + + } + + for(int k1 = 0; k1 < 16; k1++) + { + for(int k2 = 0; k2 < 16; k2++) + { + for(int k3 = 0; k3 < 8; k3++) + { + if(aflag[(k1 * 16 + k2) * 8 + k3]) + { + world.setBlock(i + k1, j + k3, k + k2, k3 < 4 ? field_15235_a : 0); + } + } + + } + + } + + for(int l1 = 0; l1 < 16; l1++) + { + for(int l2 = 0; l2 < 16; l2++) + { + for(int l3 = 4; l3 < 8; l3++) + { + if(aflag[(l1 * 16 + l2) * 8 + l3] && world.getBlockId(i + l1, (j + l3) - 1, k + l2) == Block.dirt.blockID && world.getSavedLightValue(EnumSkyBlock.Sky, i + l1, j + l3, k + l2) > 0) + { + world.setBlock(i + l1, (j + l3) - 1, k + l2, Block.grass.blockID); + } + } + + } + + } + + if(Block.blocksList[field_15235_a].blockMaterial == Material.lava) + { + for(int i2 = 0; i2 < 16; i2++) + { + for(int i3 = 0; i3 < 16; i3++) + { + for(int i4 = 0; i4 < 8; i4++) + { + boolean flag1 = !aflag[(i2 * 16 + i3) * 8 + i4] && (i2 < 15 && aflag[((i2 + 1) * 16 + i3) * 8 + i4] || i2 > 0 && aflag[((i2 - 1) * 16 + i3) * 8 + i4] || i3 < 15 && aflag[(i2 * 16 + (i3 + 1)) * 8 + i4] || i3 > 0 && aflag[(i2 * 16 + (i3 - 1)) * 8 + i4] || i4 < 7 && aflag[(i2 * 16 + i3) * 8 + (i4 + 1)] || i4 > 0 && aflag[(i2 * 16 + i3) * 8 + (i4 - 1)]); + if(flag1 && (i4 < 4 || random.nextInt(2) != 0) && world.getBlockMaterial(i + i2, j + i4, k + i3).isSolid()) + { + world.setBlock(i + i2, j + i4, k + i3, Block.stone.blockID); + } + } + + } + + } + + } + return true; + } + + private int field_15235_a; +} diff --git a/src/main/java/net/minecraft/src/WorldGenLightStone1.java b/src/main/java/net/minecraft/src/WorldGenLightStone1.java new file mode 100644 index 0000000..53ce7f8 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenLightStone1.java @@ -0,0 +1,77 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenLightStone1 extends WorldGenerator +{ + + public WorldGenLightStone1() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + if(!world.isAirBlock(i, j, k)) + { + return false; + } + if(world.getBlockId(i, j + 1, k) != Block.bloodStone.blockID) + { + return false; + } + world.setBlockWithNotify(i, j, k, Block.lightStone.blockID); + for(int l = 0; l < 1500; l++) + { + int i1 = (i + random.nextInt(8)) - random.nextInt(8); + int j1 = j - random.nextInt(12); + int k1 = (k + random.nextInt(8)) - random.nextInt(8); + if(world.getBlockId(i1, j1, k1) != 0) + { + continue; + } + int l1 = 0; + for(int i2 = 0; i2 < 6; i2++) + { + int j2 = 0; + if(i2 == 0) + { + j2 = world.getBlockId(i1 - 1, j1, k1); + } + if(i2 == 1) + { + j2 = world.getBlockId(i1 + 1, j1, k1); + } + if(i2 == 2) + { + j2 = world.getBlockId(i1, j1 - 1, k1); + } + if(i2 == 3) + { + j2 = world.getBlockId(i1, j1 + 1, k1); + } + if(i2 == 4) + { + j2 = world.getBlockId(i1, j1, k1 - 1); + } + if(i2 == 5) + { + j2 = world.getBlockId(i1, j1, k1 + 1); + } + if(j2 == Block.lightStone.blockID) + { + l1++; + } + } + + if(l1 == 1) + { + world.setBlockWithNotify(i1, j1, k1, Block.lightStone.blockID); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenLightStone2.java b/src/main/java/net/minecraft/src/WorldGenLightStone2.java new file mode 100644 index 0000000..69d4211 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenLightStone2.java @@ -0,0 +1,77 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenLightStone2 extends WorldGenerator +{ + + public WorldGenLightStone2() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + if(!world.isAirBlock(i, j, k)) + { + return false; + } + if(world.getBlockId(i, j + 1, k) != Block.bloodStone.blockID) + { + return false; + } + world.setBlockWithNotify(i, j, k, Block.lightStone.blockID); + for(int l = 0; l < 1500; l++) + { + int i1 = (i + random.nextInt(8)) - random.nextInt(8); + int j1 = j - random.nextInt(12); + int k1 = (k + random.nextInt(8)) - random.nextInt(8); + if(world.getBlockId(i1, j1, k1) != 0) + { + continue; + } + int l1 = 0; + for(int i2 = 0; i2 < 6; i2++) + { + int j2 = 0; + if(i2 == 0) + { + j2 = world.getBlockId(i1 - 1, j1, k1); + } + if(i2 == 1) + { + j2 = world.getBlockId(i1 + 1, j1, k1); + } + if(i2 == 2) + { + j2 = world.getBlockId(i1, j1 - 1, k1); + } + if(i2 == 3) + { + j2 = world.getBlockId(i1, j1 + 1, k1); + } + if(i2 == 4) + { + j2 = world.getBlockId(i1, j1, k1 - 1); + } + if(i2 == 5) + { + j2 = world.getBlockId(i1, j1, k1 + 1); + } + if(j2 == Block.lightStone.blockID) + { + l1++; + } + } + + if(l1 == 1) + { + world.setBlockWithNotify(i1, j1, k1, Block.lightStone.blockID); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenLiquids.java b/src/main/java/net/minecraft/src/WorldGenLiquids.java new file mode 100644 index 0000000..e1d610a --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenLiquids.java @@ -0,0 +1,75 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenLiquids extends WorldGenerator +{ + + public WorldGenLiquids(int i) + { + liquidBlockId = i; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + if(world.getBlockId(i, j + 1, k) != Block.stone.blockID) + { + return false; + } + if(world.getBlockId(i, j - 1, k) != Block.stone.blockID) + { + return false; + } + if(world.getBlockId(i, j, k) != 0 && world.getBlockId(i, j, k) != Block.stone.blockID) + { + return false; + } + int l = 0; + if(world.getBlockId(i - 1, j, k) == Block.stone.blockID) + { + l++; + } + if(world.getBlockId(i + 1, j, k) == Block.stone.blockID) + { + l++; + } + if(world.getBlockId(i, j, k - 1) == Block.stone.blockID) + { + l++; + } + if(world.getBlockId(i, j, k + 1) == Block.stone.blockID) + { + l++; + } + int i1 = 0; + if(world.isAirBlock(i - 1, j, k)) + { + i1++; + } + if(world.isAirBlock(i + 1, j, k)) + { + i1++; + } + if(world.isAirBlock(i, j, k - 1)) + { + i1++; + } + if(world.isAirBlock(i, j, k + 1)) + { + i1++; + } + if(l == 3 && i1 == 1) + { + world.setBlockWithNotify(i, j, k, liquidBlockId); + world.scheduledUpdatesAreImmediate = true; + Block.blocksList[liquidBlockId].updateTick(world, i, j, k, random); + world.scheduledUpdatesAreImmediate = false; + } + return true; + } + + private int liquidBlockId; +} diff --git a/src/main/java/net/minecraft/src/WorldGenMinable.java b/src/main/java/net/minecraft/src/WorldGenMinable.java new file mode 100644 index 0000000..f64e374 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenMinable.java @@ -0,0 +1,74 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenMinable extends WorldGenerator +{ + + public WorldGenMinable(int i, int j) + { + minableBlockId = i; + numberOfBlocks = j; + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + float f = random.nextFloat() * 3.141593F; + double d = (float)(i + 8) + (MathHelper.sin(f) * (float)numberOfBlocks) / 8F; + double d1 = (float)(i + 8) - (MathHelper.sin(f) * (float)numberOfBlocks) / 8F; + double d2 = (float)(k + 8) + (MathHelper.cos(f) * (float)numberOfBlocks) / 8F; + double d3 = (float)(k + 8) - (MathHelper.cos(f) * (float)numberOfBlocks) / 8F; + double d4 = j + random.nextInt(3) + 2; + double d5 = j + random.nextInt(3) + 2; + for(int l = 0; l <= numberOfBlocks; l++) + { + double d6 = d + ((d1 - d) * (double)l) / (double)numberOfBlocks; + double d7 = d4 + ((d5 - d4) * (double)l) / (double)numberOfBlocks; + double d8 = d2 + ((d3 - d2) * (double)l) / (double)numberOfBlocks; + double d9 = (random.nextDouble() * (double)numberOfBlocks) / 16D; + double d10 = (double)(MathHelper.sin(((float)l * 3.141593F) / (float)numberOfBlocks) + 1.0F) * d9 + 1.0D; + double d11 = (double)(MathHelper.sin(((float)l * 3.141593F) / (float)numberOfBlocks) + 1.0F) * d9 + 1.0D; + int i1 = (int)(d6 - d10 / 2D); + int j1 = (int)(d7 - d11 / 2D); + int k1 = (int)(d8 - d10 / 2D); + int l1 = (int)(d6 + d10 / 2D); + int i2 = (int)(d7 + d11 / 2D); + int j2 = (int)(d8 + d10 / 2D); + for(int k2 = i1; k2 <= l1; k2++) + { + double d12 = (((double)k2 + 0.5D) - d6) / (d10 / 2D); + if(d12 * d12 >= 1.0D) + { + continue; + } + for(int l2 = j1; l2 <= i2; l2++) + { + double d13 = (((double)l2 + 0.5D) - d7) / (d11 / 2D); + if(d12 * d12 + d13 * d13 >= 1.0D) + { + continue; + } + for(int i3 = k1; i3 <= j2; i3++) + { + double d14 = (((double)i3 + 0.5D) - d8) / (d10 / 2D); + if(d12 * d12 + d13 * d13 + d14 * d14 < 1.0D && world.getBlockId(k2, l2, i3) == Block.stone.blockID) + { + world.setBlock(k2, l2, i3, minableBlockId); + } + } + + } + + } + + } + + return true; + } + + private int minableBlockId; + private int numberOfBlocks; +} diff --git a/src/main/java/net/minecraft/src/WorldGenPumpkin.java b/src/main/java/net/minecraft/src/WorldGenPumpkin.java new file mode 100644 index 0000000..3ec75c8 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenPumpkin.java @@ -0,0 +1,30 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenPumpkin extends WorldGenerator +{ + + public WorldGenPumpkin() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + for(int l = 0; l < 64; l++) + { + int i1 = (i + random.nextInt(8)) - random.nextInt(8); + int j1 = (j + random.nextInt(4)) - random.nextInt(4); + int k1 = (k + random.nextInt(8)) - random.nextInt(8); + if(world.isAirBlock(i1, j1, k1) && world.getBlockId(i1, j1 - 1, k1) == Block.grass.blockID && Block.pumpkin.canPlaceBlockAt(world, i1, j1, k1)) + { + world.setBlockAndMetadata(i1, j1, k1, Block.pumpkin.blockID, random.nextInt(4)); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenReed.java b/src/main/java/net/minecraft/src/WorldGenReed.java new file mode 100644 index 0000000..2225e79 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenReed.java @@ -0,0 +1,39 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenReed extends WorldGenerator +{ + + public WorldGenReed() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + for(int l = 0; l < 20; l++) + { + int i1 = (i + random.nextInt(4)) - random.nextInt(4); + int j1 = j; + int k1 = (k + random.nextInt(4)) - random.nextInt(4); + if(!world.isAirBlock(i1, j1, k1) || world.getBlockMaterial(i1 - 1, j1 - 1, k1) != Material.water && world.getBlockMaterial(i1 + 1, j1 - 1, k1) != Material.water && world.getBlockMaterial(i1, j1 - 1, k1 - 1) != Material.water && world.getBlockMaterial(i1, j1 - 1, k1 + 1) != Material.water) + { + continue; + } + int l1 = 2 + random.nextInt(random.nextInt(3) + 1); + for(int i2 = 0; i2 < l1; i2++) + { + if(Block.reed.canBlockStay(world, i1, j1 + i2, k1)) + { + world.setBlock(i1, j1 + i2, k1, Block.reed.blockID); + } + } + + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenTaiga1.java b/src/main/java/net/minecraft/src/WorldGenTaiga1.java new file mode 100644 index 0000000..e12f63f --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenTaiga1.java @@ -0,0 +1,106 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenTaiga1 extends WorldGenerator +{ + + public WorldGenTaiga1() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + int l = random.nextInt(5) + 7; + int i1 = l - random.nextInt(2) - 3; + int j1 = l - i1; + int k1 = 1 + random.nextInt(j1 + 1); + boolean flag = true; + if(j < 1 || j + l + 1 > 128) + { + return false; + } + for(int l1 = j; l1 <= j + 1 + l && flag; l1++) + { + int j2 = 1; + if(l1 - j < i1) + { + j2 = 0; + } else + { + j2 = k1; + } + for(int l2 = i - j2; l2 <= i + j2 && flag; l2++) + { + for(int k3 = k - j2; k3 <= k + j2 && flag; k3++) + { + if(l1 >= 0 && l1 < 128) + { + int j4 = world.getBlockId(l2, l1, k3); + if(j4 != 0 && j4 != Block.leaves.blockID) + { + flag = false; + } + } else + { + flag = false; + } + } + + } + + } + + if(!flag) + { + return false; + } + int i2 = world.getBlockId(i, j - 1, k); + if(i2 != Block.grass.blockID && i2 != Block.dirt.blockID || j >= 128 - l - 1) + { + return false; + } + world.setBlock(i, j - 1, k, Block.dirt.blockID); + int k2 = 0; + for(int i3 = j + l; i3 >= j + i1; i3--) + { + for(int l3 = i - k2; l3 <= i + k2; l3++) + { + int k4 = l3 - i; + for(int l4 = k - k2; l4 <= k + k2; l4++) + { + int i5 = l4 - k; + if((Math.abs(k4) != k2 || Math.abs(i5) != k2 || k2 <= 0) && !Block.opaqueCubeLookup[world.getBlockId(l3, i3, l4)]) + { + world.setBlockAndMetadata(l3, i3, l4, Block.leaves.blockID, 1); + } + } + + } + + if(k2 >= 1 && i3 == j + i1 + 1) + { + k2--; + continue; + } + if(k2 < k1) + { + k2++; + } + } + + for(int j3 = 0; j3 < l - 1; j3++) + { + int i4 = world.getBlockId(i, j + j3, k); + if(i4 == 0 || i4 == Block.leaves.blockID) + { + world.setBlockAndMetadata(i, j + j3, k, Block.wood.blockID, 1); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenTaiga2.java b/src/main/java/net/minecraft/src/WorldGenTaiga2.java new file mode 100644 index 0000000..862e3c3 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenTaiga2.java @@ -0,0 +1,113 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenTaiga2 extends WorldGenerator +{ + + public WorldGenTaiga2() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + int l = random.nextInt(4) + 6; + int i1 = 1 + random.nextInt(2); + int j1 = l - i1; + int k1 = 2 + random.nextInt(2); + boolean flag = true; + if(j < 1 || j + l + 1 > 128) + { + return false; + } + for(int l1 = j; l1 <= j + 1 + l && flag; l1++) + { + int j2 = 1; + if(l1 - j < i1) + { + j2 = 0; + } else + { + j2 = k1; + } + for(int l2 = i - j2; l2 <= i + j2 && flag; l2++) + { + for(int j3 = k - j2; j3 <= k + j2 && flag; j3++) + { + if(l1 >= 0 && l1 < 128) + { + int k3 = world.getBlockId(l2, l1, j3); + if(k3 != 0 && k3 != Block.leaves.blockID) + { + flag = false; + } + } else + { + flag = false; + } + } + + } + + } + + if(!flag) + { + return false; + } + int i2 = world.getBlockId(i, j - 1, k); + if(i2 != Block.grass.blockID && i2 != Block.dirt.blockID || j >= 128 - l - 1) + { + return false; + } + world.setBlock(i, j - 1, k, Block.dirt.blockID); + int k2 = random.nextInt(2); + int i3 = 1; + boolean flag1 = false; + for(int l3 = 0; l3 <= j1; l3++) + { + int j4 = (j + l) - l3; + for(int l4 = i - k2; l4 <= i + k2; l4++) + { + int j5 = l4 - i; + for(int k5 = k - k2; k5 <= k + k2; k5++) + { + int l5 = k5 - k; + if((Math.abs(j5) != k2 || Math.abs(l5) != k2 || k2 <= 0) && !Block.opaqueCubeLookup[world.getBlockId(l4, j4, k5)]) + { + world.setBlockAndMetadata(l4, j4, k5, Block.leaves.blockID, 1); + } + } + + } + + if(k2 >= i3) + { + k2 = ((flag1) ? 1 : 0); + flag1 = true; + if(++i3 > k1) + { + i3 = k1; + } + } else + { + k2++; + } + } + + int i4 = random.nextInt(3); + for(int k4 = 0; k4 < l - i4; k4++) + { + int i5 = world.getBlockId(i, j + k4, k); + if(i5 == 0 || i5 == Block.leaves.blockID) + { + world.setBlockAndMetadata(i, j + k4, k, Block.wood.blockID, 1); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenTrees.java b/src/main/java/net/minecraft/src/WorldGenTrees.java new file mode 100644 index 0000000..4253f98 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenTrees.java @@ -0,0 +1,96 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public class WorldGenTrees extends WorldGenerator +{ + + public WorldGenTrees() + { + } + + public boolean generate(World world, Random random, int i, int j, int k) + { + int l = random.nextInt(3) + 4; + boolean flag = true; + if(j < 1 || j + l + 1 > 128) + { + return false; + } + for(int i1 = j; i1 <= j + 1 + l; i1++) + { + byte byte0 = 1; + if(i1 == j) + { + byte0 = 0; + } + if(i1 >= (j + 1 + l) - 2) + { + byte0 = 2; + } + for(int i2 = i - byte0; i2 <= i + byte0 && flag; i2++) + { + for(int l2 = k - byte0; l2 <= k + byte0 && flag; l2++) + { + if(i1 >= 0 && i1 < 128) + { + int j3 = world.getBlockId(i2, i1, l2); + if(j3 != 0 && j3 != Block.leaves.blockID) + { + flag = false; + } + } else + { + flag = false; + } + } + + } + + } + + if(!flag) + { + return false; + } + int j1 = world.getBlockId(i, j - 1, k); + if(j1 != Block.grass.blockID && j1 != Block.dirt.blockID || j >= 128 - l - 1) + { + return false; + } + world.setBlock(i, j - 1, k, Block.dirt.blockID); + for(int k1 = (j - 3) + l; k1 <= j + l; k1++) + { + int j2 = k1 - (j + l); + int i3 = 1 - j2 / 2; + for(int k3 = i - i3; k3 <= i + i3; k3++) + { + int l3 = k3 - i; + for(int i4 = k - i3; i4 <= k + i3; i4++) + { + int j4 = i4 - k; + if((Math.abs(l3) != i3 || Math.abs(j4) != i3 || random.nextInt(2) != 0 && j2 != 0) && !Block.opaqueCubeLookup[world.getBlockId(k3, k1, i4)]) + { + world.setBlock(k3, k1, i4, Block.leaves.blockID); + } + } + + } + + } + + for(int l1 = 0; l1 < l; l1++) + { + int k2 = world.getBlockId(i, j + l1, k); + if(k2 == 0 || k2 == Block.leaves.blockID) + { + world.setBlock(i, j + l1, k, Block.wood.blockID); + } + } + + return true; + } +} diff --git a/src/main/java/net/minecraft/src/WorldGenerator.java b/src/main/java/net/minecraft/src/WorldGenerator.java new file mode 100644 index 0000000..d596d82 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldGenerator.java @@ -0,0 +1,20 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.Random; + +public abstract class WorldGenerator +{ + + public WorldGenerator() + { + } + + public abstract boolean generate(World world, Random random, int i, int j, int k); + + public void func_517_a(double d, double d1, double d2) + { + } +} diff --git a/src/main/java/net/minecraft/src/WorldInfo.java b/src/main/java/net/minecraft/src/WorldInfo.java new file mode 100644 index 0000000..613a099 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldInfo.java @@ -0,0 +1,205 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.List; + +public class WorldInfo +{ + + public WorldInfo(NBTTagCompound nbttagcompound) + { + randomSeed = nbttagcompound.getLong("RandomSeed"); + spawnX = nbttagcompound.getInteger("SpawnX"); + spawnY = nbttagcompound.getInteger("SpawnY"); + spawnZ = nbttagcompound.getInteger("SpawnZ"); + worldTime = nbttagcompound.getLong("Time"); + field_22315_f = nbttagcompound.getLong("LastPlayed"); + sizeOnDisk = nbttagcompound.getLong("SizeOnDisk"); + levelName = nbttagcompound.getString("LevelName"); + saveVersion = nbttagcompound.getInteger("version"); + if(nbttagcompound.hasKey("Player")) + { + field_22313_h = nbttagcompound.getCompoundTag("Player"); + field_22312_i = field_22313_h.getInteger("Dimension"); + } + } + + public WorldInfo(long l, String s) + { + randomSeed = l; + levelName = s; + } + + public WorldInfo(WorldInfo worldinfo) + { + randomSeed = worldinfo.randomSeed; + spawnX = worldinfo.spawnX; + spawnY = worldinfo.spawnY; + spawnZ = worldinfo.spawnZ; + worldTime = worldinfo.worldTime; + field_22315_f = worldinfo.field_22315_f; + sizeOnDisk = worldinfo.sizeOnDisk; + field_22313_h = worldinfo.field_22313_h; + field_22312_i = worldinfo.field_22312_i; + levelName = worldinfo.levelName; + saveVersion = worldinfo.saveVersion; + } + + public NBTTagCompound func_22299_a() + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + func_22291_a(nbttagcompound, field_22313_h); + return nbttagcompound; + } + + public NBTTagCompound func_22305_a(List list) + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + EntityPlayer entityplayer = null; + NBTTagCompound nbttagcompound1 = null; + if(list.size() > 0) + { + entityplayer = (EntityPlayer)list.get(0); + } + if(entityplayer != null) + { + nbttagcompound1 = new NBTTagCompound(); + entityplayer.writeToNBT(nbttagcompound1); + } + func_22291_a(nbttagcompound, nbttagcompound1); + return nbttagcompound; + } + + private void func_22291_a(NBTTagCompound nbttagcompound, NBTTagCompound nbttagcompound1) + { + nbttagcompound.setLong("RandomSeed", randomSeed); + nbttagcompound.setInteger("SpawnX", spawnX); + nbttagcompound.setInteger("SpawnY", spawnY); + nbttagcompound.setInteger("SpawnZ", spawnZ); + nbttagcompound.setLong("Time", worldTime); + nbttagcompound.setLong("SizeOnDisk", sizeOnDisk); + nbttagcompound.setLong("LastPlayed", System.currentTimeMillis()); + nbttagcompound.setString("LevelName", levelName); + nbttagcompound.setInteger("version", saveVersion); + if(nbttagcompound1 != null) + { + nbttagcompound.setCompoundTag("Player", nbttagcompound1); + } + } + + public long getRandomSeed() + { + return randomSeed; + } + + public int func_22293_c() + { + return spawnX; + } + + public int func_22295_d() + { + return spawnY; + } + + public int func_22300_e() + { + return spawnZ; + } + + public long getWorldTime() + { + return worldTime; + } + + public long func_22306_g() + { + return sizeOnDisk; + } + + public NBTTagCompound func_22303_h() + { + return field_22313_h; + } + + public int func_22290_i() + { + return field_22312_i; + } + + public void func_22294_a(int i) + { + spawnX = i; + } + + public void func_22308_b(int i) + { + spawnY = i; + } + + public void func_22298_c(int i) + { + spawnZ = i; + } + + public void setWorldTime(long l) + { + worldTime = l; + } + + public void func_22297_b(long l) + { + sizeOnDisk = l; + } + + public void func_22309_a(NBTTagCompound nbttagcompound) + { + field_22313_h = nbttagcompound; + } + + public void func_22292_a(int i, int j, int k) + { + spawnX = i; + spawnY = j; + spawnZ = k; + } + + public String getWorldName() + { + return levelName; + } + + public void func_22287_a(String s) + { + levelName = s; + } + + public int func_22296_k() + { + return saveVersion; + } + + public void func_22289_d(int i) + { + saveVersion = i; + } + + public long func_22301_l() + { + return field_22315_f; + } + + private long randomSeed; + private int spawnX; + private int spawnY; + private int spawnZ; + private long worldTime; + private long field_22315_f; + private long sizeOnDisk; + private NBTTagCompound field_22313_h; + private int field_22312_i; + private String levelName; + private int saveVersion; +} diff --git a/src/main/java/net/minecraft/src/WorldProvider.java b/src/main/java/net/minecraft/src/WorldProvider.java new file mode 100644 index 0000000..8b5ff8b --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldProvider.java @@ -0,0 +1,141 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class WorldProvider +{ + + public WorldProvider() + { + field_4220_c = false; + isHellWorld = false; + field_6478_e = false; + lightBrightnessTable = new float[16]; + worldType = 0; + field_4217_f = new float[4]; + } + + public final void registerWorld(World world) + { + worldObj = world; + registerWorldChunkManager(); + generateLightBrightnessTable(); + } + + protected void generateLightBrightnessTable() + { + float f = 0.05F; + for(int i = 0; i <= 15; i++) + { + float f1 = 1.0F - (float)i / 15F; + lightBrightnessTable[i] = ((1.0F - f1) / (f1 * 3F + 1.0F)) * (1.0F - f) + f; + } + + } + + protected void registerWorldChunkManager() + { + worldChunkMgr = new WorldChunkManager(worldObj); + } + + public IChunkProvider getChunkProvider() + { + return new ChunkProviderGenerate(worldObj, worldObj.func_22138_q()); + } + + public boolean canCoordinateBeSpawn(int i, int j) + { + int k = worldObj.getFirstUncoveredBlock(i, j); + return k == Block.sand.blockID; + } + + public float calculateCelestialAngle(long l, float f) + { + int i = (int)(l % 24000L); + float f1 = ((float)i + f) / 24000F - 0.25F; + if(f1 < 0.0F) + { + f1++; + } + if(f1 > 1.0F) + { + f1--; + } + float f2 = f1; + f1 = 1.0F - (float)((Math.cos((double)f1 * 3.1415926535897931D) + 1.0D) / 2D); + f1 = f2 + (f1 - f2) / 3F; + return f1; + } + + public float[] func_4097_b(float f, float f1) + { + float f2 = 0.4F; + float f3 = MathHelper.cos(f * 3.141593F * 2.0F) - 0.0F; + float f4 = -0F; + if(f3 >= f4 - f2 && f3 <= f4 + f2) + { + float f5 = ((f3 - f4) / f2) * 0.5F + 0.5F; + float f6 = 1.0F - (1.0F - MathHelper.sin(f5 * 3.141593F)) * 0.99F; + f6 *= f6; + field_4217_f[0] = f5 * 0.3F + 0.7F; + field_4217_f[1] = f5 * f5 * 0.7F + 0.2F; + field_4217_f[2] = f5 * f5 * 0.0F + 0.2F; + field_4217_f[3] = f6; + return field_4217_f; + } else + { + return null; + } + } + + public Vec3D func_4096_a(float f, float f1) + { + float f2 = MathHelper.cos(f * 3.141593F * 2.0F) * 2.0F + 0.5F; + if(f2 < 0.0F) + { + f2 = 0.0F; + } + if(f2 > 1.0F) + { + f2 = 1.0F; + } + float f3 = 0.7529412F; + float f4 = 0.8470588F; + float f5 = 1.0F; + f3 *= f2 * 0.94F + 0.06F; + f4 *= f2 * 0.94F + 0.06F; + f5 *= f2 * 0.91F + 0.09F; + return Vec3D.createVector(f3, f4, f5); + } + + public boolean canRespawnHere() + { + return true; + } + + public static WorldProvider func_4101_a(int i) + { + if(i == 0) + { + return new WorldProvider(); + } + if(i == -1) + { + return new WorldProviderHell(); + } else + { + return null; + } + } + + public World worldObj; + public WorldChunkManager worldChunkMgr; + public boolean field_4220_c; + public boolean isHellWorld; + public boolean field_6478_e; + public float lightBrightnessTable[]; + public int worldType; + private float field_4217_f[]; +} diff --git a/src/main/java/net/minecraft/src/WorldProviderHell.java b/src/main/java/net/minecraft/src/WorldProviderHell.java new file mode 100644 index 0000000..df83161 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldProviderHell.java @@ -0,0 +1,67 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + + +public class WorldProviderHell extends WorldProvider +{ + + public WorldProviderHell() + { + } + + public void registerWorldChunkManager() + { + worldChunkMgr = new WorldChunkManagerHell(MobSpawnerBase.hell, 1.0D, 0.0D); + field_4220_c = true; + isHellWorld = true; + field_6478_e = true; + worldType = -1; + } + + public Vec3D func_4096_a(float f, float f1) + { + return Vec3D.createVector(0.20000000298023224D, 0.029999999329447746D, 0.029999999329447746D); + } + + protected void generateLightBrightnessTable() + { + float f = 0.1F; + for(int i = 0; i <= 15; i++) + { + float f1 = 1.0F - (float)i / 15F; + lightBrightnessTable[i] = ((1.0F - f1) / (f1 * 3F + 1.0F)) * (1.0F - f) + f; + } + + } + + public IChunkProvider getChunkProvider() + { + return new ChunkProviderHell(worldObj, worldObj.func_22138_q()); + } + + public boolean canCoordinateBeSpawn(int i, int j) + { + int k = worldObj.getFirstUncoveredBlock(i, j); + if(k == Block.bedrock.blockID) + { + return false; + } + if(k == 0) + { + return false; + } + return Block.opaqueCubeLookup[k]; + } + + public float calculateCelestialAngle(long l, float f) + { + return 0.5F; + } + + public boolean canRespawnHere() + { + return false; + } +} diff --git a/src/main/java/net/minecraft/src/WorldRenderer.java b/src/main/java/net/minecraft/src/WorldRenderer.java new file mode 100644 index 0000000..7f9ac58 --- /dev/null +++ b/src/main/java/net/minecraft/src/WorldRenderer.java @@ -0,0 +1,282 @@ +package net.minecraft.src; +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) braces deadcode + +import java.util.*; +import org.lwjgl.opengl.GL11; + +public class WorldRenderer +{ + + public WorldRenderer(World world, List list, int i, int j, int k, int l, int i1) + { + glRenderList = -1; + isInFrustum = false; + skipRenderPass = new boolean[2]; + isVisible = true; + isInitialized = false; + tileEntityRenderers = new ArrayList(); + worldObj = world; + tileEntities = list; + sizeWidth = sizeHeight = sizeDepth = l; + field_1740_t = MathHelper.sqrt_float(sizeWidth * sizeWidth + sizeHeight * sizeHeight + sizeDepth * sizeDepth) / 2.0F; + glRenderList = i1; + posX = -999; + func_1197_a(i, j, k); + needsUpdate = false; + } + + public void func_1197_a(int i, int j, int k) + { + if(i == posX && j == posY && k == posZ) + { + return; + } else + { + setDontDraw(); + posX = i; + posY = j; + posZ = k; + field_1746_q = i + sizeWidth / 2; + field_1743_r = j + sizeHeight / 2; + field_1741_s = k + sizeDepth / 2; + field_1752_l = i & 0x3ff; + field_1751_m = j; + field_1750_n = k & 0x3ff; + field_1755_i = i - field_1752_l; + field_1754_j = j - field_1751_m; + field_1753_k = k - field_1750_n; + float f = 6F; + field_1736_v = AxisAlignedBB.getBoundingBox((float)i - f, (float)j - f, (float)k - f, (float)(i + sizeWidth) + f, (float)(j + sizeHeight) + f, (float)(k + sizeDepth) + f); + GL11.glNewList(glRenderList + 2, 4864 /*GL_COMPILE*/); + RenderItem.renderAABB(AxisAlignedBB.getBoundingBoxFromPool((float)field_1752_l - f, (float)field_1751_m - f, (float)field_1750_n - f, (float)(field_1752_l + sizeWidth) + f, (float)(field_1751_m + sizeHeight) + f, (float)(field_1750_n + sizeDepth) + f)); + GL11.glEndList(); + markDirty(); + return; + } + } + + private void setupGLTranslation() + { + GL11.glTranslatef(field_1752_l, field_1751_m, field_1750_n); + } + + public void updateRenderer() + { + if(!needsUpdate) + { + return; + } + chunksUpdated++; + int i = posX; + int j = posY; + int k = posZ; + int l = posX + sizeWidth; + int i1 = posY + sizeHeight; + int j1 = posZ + sizeDepth; + for(int k1 = 0; k1 < 2; k1++) + { + skipRenderPass[k1] = true; + } + + Chunk.isLit = false; + HashSet hashset = new HashSet(); + hashset.addAll(tileEntityRenderers); + tileEntityRenderers.clear(); + int l1 = 1; + ChunkCache chunkcache = new ChunkCache(worldObj, i - l1, j - l1, k - l1, l + l1, i1 + l1, j1 + l1); + RenderBlocks renderblocks = new RenderBlocks(chunkcache); + int i2 = 0; + do + { + if(i2 >= 2) + { + break; + } + boolean flag = false; + boolean flag1 = false; + boolean flag2 = false; + for(int j2 = j; j2 < i1; j2++) + { + for(int k2 = k; k2 < j1; k2++) + { + for(int l2 = i; l2 < l; l2++) + { + int i3 = chunkcache.getBlockId(l2, j2, k2); + if(i3 <= 0) + { + continue; + } + if(!flag2) + { + flag2 = true; + GL11.glNewList(glRenderList + i2, 4864 /*GL_COMPILE*/); + GL11.glPushMatrix(); + setupGLTranslation(); + float f = 1.000001F; + GL11.glTranslatef((float)(-sizeDepth) / 2.0F, (float)(-sizeHeight) / 2.0F, (float)(-sizeDepth) / 2.0F); + GL11.glScalef(f, f, f); + GL11.glTranslatef((float)sizeDepth / 2.0F, (float)sizeHeight / 2.0F, (float)sizeDepth / 2.0F); + tessellator.startDrawingQuads(); + tessellator.setTranslationD(-posX, -posY, -posZ); + } + if(i2 == 0 && Block.isBlockContainer[i3]) + { + TileEntity tileentity = chunkcache.getBlockTileEntity(l2, j2, k2); + if(TileEntityRenderer.instance.hasSpecialRenderer(tileentity)) + { + tileEntityRenderers.add(tileentity); + } + } + Block block = Block.blocksList[i3]; + int j3 = block.getRenderBlockPass(); + if(j3 != i2) + { + flag = true; + continue; + } + if(j3 == i2) + { + flag1 |= renderblocks.renderBlockByRenderType(block, l2, j2, k2); + } + } + + } + + } + + if(flag2) + { + tessellator.draw(); + GL11.glPopMatrix(); + GL11.glEndList(); + tessellator.setTranslationD(0.0D, 0.0D, 0.0D); + } else + { + flag1 = false; + } + if(flag1) + { + skipRenderPass[i2] = false; + } + if(!flag) + { + break; + } + i2++; + } while(true); + HashSet hashset1 = new HashSet(); + hashset1.addAll(tileEntityRenderers); + hashset1.removeAll(hashset); + tileEntities.addAll(hashset1); + hashset.removeAll(tileEntityRenderers); + tileEntities.removeAll(hashset); + field_1747_A = Chunk.isLit; + isInitialized = true; + } + + public float distanceToEntity(Entity entity) + { + float f = (float)(entity.posX - (double)field_1746_q); + float f1 = (float)(entity.posY - (double)field_1743_r); + float f2 = (float)(entity.posZ - (double)field_1741_s); + return f * f + f1 * f1 + f2 * f2; + } + + public void setDontDraw() + { + for(int i = 0; i < 2; i++) + { + skipRenderPass[i] = true; + } + + isInFrustum = false; + isInitialized = false; + } + + public void func_1204_c() + { + setDontDraw(); + worldObj = null; + } + + public int getGLCallListForPass(int i) + { + if(!isInFrustum) + { + return -1; + } + if(!skipRenderPass[i]) + { + return glRenderList + i; + } else + { + return -1; + } + } + + public void updateInFrustrum(ICamera icamera) + { + isInFrustum = icamera.isBoundingBoxInFrustum(field_1736_v); + } + + public void callOcclusionQueryList() + { + GL11.glCallList(glRenderList + 2); + } + + public boolean canRender() + { + if(!isInitialized) + { + return false; + } else + { + return skipRenderPass[0] && skipRenderPass[1]; + } + } + + public void markDirty() + { + needsUpdate = true; + } + + public World worldObj; + private int glRenderList; + private static Tessellator tessellator; + public static int chunksUpdated = 0; + public int posX; + public int posY; + public int posZ; + public int sizeWidth; + public int sizeHeight; + public int sizeDepth; + public int field_1755_i; + public int field_1754_j; + public int field_1753_k; + public int field_1752_l; + public int field_1751_m; + public int field_1750_n; + public boolean isInFrustum; + public boolean skipRenderPass[]; + public int field_1746_q; + public int field_1743_r; + public int field_1741_s; + public float field_1740_t; + public boolean needsUpdate; + public AxisAlignedBB field_1736_v; + public int field_1735_w; + public boolean isVisible; + public boolean isWaitingOnOcclusionQuery; + public int field_1732_z; + public boolean field_1747_A; + private boolean isInitialized; + public List tileEntityRenderers; + private List tileEntities; + + static + { + tessellator = Tessellator.instance; + } +} diff --git a/src/main/java/org/json/CDL.java b/src/main/java/org/json/CDL.java new file mode 100644 index 0000000..f12cfc0 --- /dev/null +++ b/src/main/java/org/json/CDL.java @@ -0,0 +1,287 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +/** + * This provides static methods to convert comma delimited text into a + * JSONArray, and to convert a JSONArray into comma delimited text. Comma + * delimited text is a very popular format for data interchange. It is + * understood by most database, spreadsheet, and organizer programs. + *

+ * Each row of text represents a row in a table or a data record. Each row + * ends with a NEWLINE character. Each row contains one or more values. + * Values are separated by commas. A value can contain any character except + * for comma, unless is is wrapped in single quotes or double quotes. + *

+ * The first row usually contains the names of the columns. + *

+ * A comma delimited list can be converted into a JSONArray of JSONObjects. + * The names for the elements in the JSONObjects can be taken from the names + * in the first row. + * @author JSON.org + * @version 2016-05-01 + */ +public class CDL { + + /** + * Get the next value. The value can be wrapped in quotes. The value can + * be empty. + * @param x A JSONTokener of the source text. + * @return The value string, or null if empty. + * @throws JSONException if the quoted string is badly formed. + */ + private static String getValue(JSONTokener x) throws JSONException { + char c; + char q; + StringBuilder sb; + do { + c = x.next(); + } while (c == ' ' || c == '\t'); + switch (c) { + case 0: + return null; + case '"': + case '\'': + q = c; + sb = new StringBuilder(); + for (;;) { + c = x.next(); + if (c == q) { + //Handle escaped double-quote + char nextC = x.next(); + if(nextC != '\"') { + // if our quote was the end of the file, don't step + if(nextC > 0) { + x.back(); + } + break; + } + } + if (c == 0 || c == '\n' || c == '\r') { + throw x.syntaxError("Missing close quote '" + q + "'."); + } + sb.append(c); + } + return sb.toString(); + case ',': + x.back(); + return ""; + default: + x.back(); + return x.nextTo(','); + } + } + + /** + * Produce a JSONArray of strings from a row of comma delimited values. + * @param x A JSONTokener of the source text. + * @return A JSONArray of strings. + * @throws JSONException if a called function fails + */ + public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { + JSONArray ja = new JSONArray(); + for (;;) { + String value = getValue(x); + char c = x.next(); + if (value == null || + (ja.length() == 0 && value.length() == 0 && c != ',')) { + return null; + } + ja.put(value); + for (;;) { + if (c == ',') { + break; + } + if (c != ' ') { + if (c == '\n' || c == '\r' || c == 0) { + return ja; + } + throw x.syntaxError("Bad character '" + c + "' (" + + (int)c + ")."); + } + c = x.next(); + } + } + } + + /** + * Produce a JSONObject from a row of comma delimited text, using a + * parallel JSONArray of strings to provides the names of the elements. + * @param names A JSONArray of names. This is commonly obtained from the + * first row of a comma delimited text file using the rowToJSONArray + * method. + * @param x A JSONTokener of the source text. + * @return A JSONObject combining the names and values. + * @throws JSONException if a called function fails + */ + public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) + throws JSONException { + JSONArray ja = rowToJSONArray(x); + return ja != null ? ja.toJSONObject(names) : null; + } + + /** + * Produce a comma delimited text row from a JSONArray. Values containing + * the comma character will be quoted. Troublesome characters may be + * removed. + * @param ja A JSONArray of strings. + * @return A string ending in NEWLINE. + */ + public static String rowToString(JSONArray ja) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ja.length(); i += 1) { + if (i > 0) { + sb.append(','); + } + Object object = ja.opt(i); + if (object != null) { + String string = object.toString(); + if (string.length() > 0 && (string.indexOf(',') >= 0 || + string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 || + string.indexOf(0) >= 0 || string.charAt(0) == '"')) { + sb.append('"'); + int length = string.length(); + for (int j = 0; j < length; j += 1) { + char c = string.charAt(j); + if (c >= ' ' && c != '"') { + sb.append(c); + } + } + sb.append('"'); + } else { + sb.append(string); + } + } + } + sb.append('\n'); + return sb.toString(); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string, + * using the first row as a source of names. + * @param string The comma delimited text. + * @return A JSONArray of JSONObjects. + * @throws JSONException if a called function fails + */ + public static JSONArray toJSONArray(String string) throws JSONException { + return toJSONArray(new JSONTokener(string)); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string, + * using the first row as a source of names. + * @param x The JSONTokener containing the comma delimited text. + * @return A JSONArray of JSONObjects. + * @throws JSONException if a called function fails + */ + public static JSONArray toJSONArray(JSONTokener x) throws JSONException { + return toJSONArray(rowToJSONArray(x), x); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string + * using a supplied JSONArray as the source of element names. + * @param names A JSONArray of strings. + * @param string The comma delimited text. + * @return A JSONArray of JSONObjects. + * @throws JSONException if a called function fails + */ + public static JSONArray toJSONArray(JSONArray names, String string) + throws JSONException { + return toJSONArray(names, new JSONTokener(string)); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string + * using a supplied JSONArray as the source of element names. + * @param names A JSONArray of strings. + * @param x A JSONTokener of the source text. + * @return A JSONArray of JSONObjects. + * @throws JSONException if a called function fails + */ + public static JSONArray toJSONArray(JSONArray names, JSONTokener x) + throws JSONException { + if (names == null || names.length() == 0) { + return null; + } + JSONArray ja = new JSONArray(); + for (;;) { + JSONObject jo = rowToJSONObject(names, x); + if (jo == null) { + break; + } + ja.put(jo); + } + if (ja.length() == 0) { + return null; + } + return ja; + } + + + /** + * Produce a comma delimited text from a JSONArray of JSONObjects. The + * first row will be a list of names obtained by inspecting the first + * JSONObject. + * @param ja A JSONArray of JSONObjects. + * @return A comma delimited text. + * @throws JSONException if a called function fails + */ + public static String toString(JSONArray ja) throws JSONException { + JSONObject jo = ja.optJSONObject(0); + if (jo != null) { + JSONArray names = jo.names(); + if (names != null) { + return rowToString(names) + toString(names, ja); + } + } + return null; + } + + /** + * Produce a comma delimited text from a JSONArray of JSONObjects using + * a provided list of names. The list of names is not included in the + * output. + * @param names A JSONArray of strings. + * @param ja A JSONArray of JSONObjects. + * @return A comma delimited text. + * @throws JSONException if a called function fails + */ + public static String toString(JSONArray names, JSONArray ja) + throws JSONException { + if (names == null || names.length() == 0) { + return null; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ja.length(); i += 1) { + JSONObject jo = ja.optJSONObject(i); + if (jo != null) { + sb.append(rowToString(jo.toJSONArray(names))); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/org/json/Cookie.java b/src/main/java/org/json/Cookie.java new file mode 100644 index 0000000..1c5fb78 --- /dev/null +++ b/src/main/java/org/json/Cookie.java @@ -0,0 +1,224 @@ +package org.json; + +import java.util.Locale; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * Convert a web browser cookie specification to a JSONObject and back. + * JSON and Cookies are both notations for name/value pairs. + * See also: https://tools.ietf.org/html/rfc6265 + * @author JSON.org + * @version 2015-12-09 + */ +public class Cookie { + + /** + * Produce a copy of a string in which the characters '+', '%', '=', ';' + * and control characters are replaced with "%hh". This is a gentle form + * of URL encoding, attempting to cause as little distortion to the + * string as possible. The characters '=' and ';' are meta characters in + * cookies. By convention, they are escaped using the URL-encoding. This is + * only a convention, not a standard. Often, cookies are expected to have + * encoded values. We encode '=' and ';' because we must. We encode '%' and + * '+' because they are meta characters in URL encoding. + * @param string The source string. + * @return The escaped result. + */ + public static String escape(String string) { + char c; + String s = string.trim(); + int length = s.length(); + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i += 1) { + c = s.charAt(i); + if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') { + sb.append('%'); + sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16)); + sb.append(Character.forDigit((char)(c & 0x0f), 16)); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + + /** + * Convert a cookie specification string into a JSONObject. The string + * must contain a name value pair separated by '='. The name and the value + * will be unescaped, possibly converting '+' and '%' sequences. The + * cookie properties may follow, separated by ';', also represented as + * name=value (except the Attribute properties like "Secure" or "HttpOnly", + * which do not have a value. The value {@link Boolean#TRUE} will be used for these). + * The name will be stored under the key "name", and the value will be + * stored under the key "value". This method does not do checking or + * validation of the parameters. It only converts the cookie string into + * a JSONObject. All attribute names are converted to lower case keys in the + * JSONObject (HttpOnly => httponly). If an attribute is specified more than + * once, only the value found closer to the end of the cookie-string is kept. + * @param string The cookie specification string. + * @return A JSONObject containing "name", "value", and possibly other + * members. + * @throws JSONException If there is an error parsing the Cookie String. + * Cookie strings must have at least one '=' character and the 'name' + * portion of the cookie must not be blank. + */ + public static JSONObject toJSONObject(String string) { + final JSONObject jo = new JSONObject(); + String name; + Object value; + + + JSONTokener x = new JSONTokener(string); + + name = unescape(x.nextTo('=').trim()); + //per RFC6265, if the name is blank, the cookie should be ignored. + if("".equals(name)) { + throw new JSONException("Cookies must have a 'name'"); + } + jo.put("name", name); + // per RFC6265, if there is no '=', the cookie should be ignored. + // the 'next' call here throws an exception if the '=' is not found. + x.next('='); + jo.put("value", unescape(x.nextTo(';')).trim()); + // discard the ';' + x.next(); + // parse the remaining cookie attributes + while (x.more()) { + name = unescape(x.nextTo("=;")).trim().toLowerCase(Locale.ROOT); + // don't allow a cookies attributes to overwrite its name or value. + if("name".equalsIgnoreCase(name)) { + throw new JSONException("Illegal attribute name: 'name'"); + } + if("value".equalsIgnoreCase(name)) { + throw new JSONException("Illegal attribute name: 'value'"); + } + // check to see if it's a flag property + if (x.next() != '=') { + value = Boolean.TRUE; + } else { + value = unescape(x.nextTo(';')).trim(); + x.next(); + } + // only store non-blank attributes + if(!"".equals(name) && !"".equals(value)) { + jo.put(name, value); + } + } + return jo; + } + + + /** + * Convert a JSONObject into a cookie specification string. The JSONObject + * must contain "name" and "value" members (case insensitive). + * If the JSONObject contains other members, they will be appended to the cookie + * specification string. User-Agents are instructed to ignore unknown attributes, + * so ensure your JSONObject is using only known attributes. + * See also: https://tools.ietf.org/html/rfc6265 + * @param jo A JSONObject + * @return A cookie specification string + * @throws JSONException thrown if the cookie has no name. + */ + public static String toString(JSONObject jo) throws JSONException { + StringBuilder sb = new StringBuilder(); + + String name = null; + Object value = null; + for(String key : jo.keySet()){ + if("name".equalsIgnoreCase(key)) { + name = jo.getString(key).trim(); + } + if("value".equalsIgnoreCase(key)) { + value=jo.getString(key).trim(); + } + if(name != null && value != null) { + break; + } + } + + if(name == null || "".equals(name.trim())) { + throw new JSONException("Cookie does not have a name"); + } + if(value == null) { + value = ""; + } + + sb.append(escape(name)); + sb.append("="); + sb.append(escape((String)value)); + + for(String key : jo.keySet()){ + if("name".equalsIgnoreCase(key) + || "value".equalsIgnoreCase(key)) { + // already processed above + continue; + } + value = jo.opt(key); + if(value instanceof Boolean) { + if(Boolean.TRUE.equals(value)) { + sb.append(';').append(escape(key)); + } + // don't emit false values + } else { + sb.append(';') + .append(escape(key)) + .append('=') + .append(escape(value.toString())); + } + } + + return sb.toString(); + } + + /** + * Convert %hh sequences to single characters, and + * convert plus to space. + * @param string A string that may contain + * + (plus) and + * %hh sequences. + * @return The unescaped string. + */ + public static String unescape(String string) { + int length = string.length(); + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; ++i) { + char c = string.charAt(i); + if (c == '+') { + c = ' '; + } else if (c == '%' && i + 2 < length) { + int d = JSONTokener.dehexchar(string.charAt(i + 1)); + int e = JSONTokener.dehexchar(string.charAt(i + 2)); + if (d >= 0 && e >= 0) { + c = (char)(d * 16 + e); + i += 2; + } + } + sb.append(c); + } + return sb.toString(); + } +} diff --git a/src/main/java/org/json/CookieList.java b/src/main/java/org/json/CookieList.java new file mode 100644 index 0000000..83b2630 --- /dev/null +++ b/src/main/java/org/json/CookieList.java @@ -0,0 +1,86 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +/** + * Convert a web browser cookie list string to a JSONObject and back. + * @author JSON.org + * @version 2015-12-09 + */ +public class CookieList { + + /** + * Convert a cookie list into a JSONObject. A cookie list is a sequence + * of name/value pairs. The names are separated from the values by '='. + * The pairs are separated by ';'. The names and the values + * will be unescaped, possibly converting '+' and '%' sequences. + * + * To add a cookie to a cookie list, + * cookielistJSONObject.put(cookieJSONObject.getString("name"), + * cookieJSONObject.getString("value")); + * @param string A cookie list string + * @return A JSONObject + * @throws JSONException if a called function fails + */ + public static JSONObject toJSONObject(String string) throws JSONException { + JSONObject jo = new JSONObject(); + JSONTokener x = new JSONTokener(string); + while (x.more()) { + String name = Cookie.unescape(x.nextTo('=')); + x.next('='); + jo.put(name, Cookie.unescape(x.nextTo(';'))); + x.next(); + } + return jo; + } + + /** + * Convert a JSONObject into a cookie list. A cookie list is a sequence + * of name/value pairs. The names are separated from the values by '='. + * The pairs are separated by ';'. The characters '%', '+', '=', and ';' + * in the names and values are replaced by "%hh". + * @param jo A JSONObject + * @return A cookie list string + * @throws JSONException if a called function fails + */ + public static String toString(JSONObject jo) throws JSONException { + boolean b = false; + final StringBuilder sb = new StringBuilder(); + // Don't use the new entrySet API to maintain Android support + for (final String key : jo.keySet()) { + final Object value = jo.opt(key); + if (!JSONObject.NULL.equals(value)) { + if (b) { + sb.append(';'); + } + sb.append(Cookie.escape(key)); + sb.append("="); + sb.append(Cookie.escape(value.toString())); + b = true; + } + } + return sb.toString(); + } +} diff --git a/src/main/java/org/json/HTTP.java b/src/main/java/org/json/HTTP.java new file mode 100644 index 0000000..cc01167 --- /dev/null +++ b/src/main/java/org/json/HTTP.java @@ -0,0 +1,162 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Locale; + +/** + * Convert an HTTP header to a JSONObject and back. + * @author JSON.org + * @version 2015-12-09 + */ +public class HTTP { + + /** Carriage return/line feed. */ + public static final String CRLF = "\r\n"; + + /** + * Convert an HTTP header string into a JSONObject. It can be a request + * header or a response header. A request header will contain + *

{
+     *    Method: "POST" (for example),
+     *    "Request-URI": "/" (for example),
+     *    "HTTP-Version": "HTTP/1.1" (for example)
+     * }
+ * A response header will contain + *
{
+     *    "HTTP-Version": "HTTP/1.1" (for example),
+     *    "Status-Code": "200" (for example),
+     *    "Reason-Phrase": "OK" (for example)
+     * }
+ * In addition, the other parameters in the header will be captured, using + * the HTTP field names as JSON names, so that
{@code
+     *    Date: Sun, 26 May 2002 18:06:04 GMT
+     *    Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
+     *    Cache-Control: no-cache}
+ * become + *
{@code
+     *    Date: "Sun, 26 May 2002 18:06:04 GMT",
+     *    Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
+     *    "Cache-Control": "no-cache",
+     * ...}
+ * It does no further checking or conversion. It does not parse dates. + * It does not do '%' transforms on URLs. + * @param string An HTTP header string. + * @return A JSONObject containing the elements and attributes + * of the XML string. + * @throws JSONException if a called function fails + */ + public static JSONObject toJSONObject(String string) throws JSONException { + JSONObject jo = new JSONObject(); + HTTPTokener x = new HTTPTokener(string); + String token; + + token = x.nextToken(); + if (token.toUpperCase(Locale.ROOT).startsWith("HTTP")) { + +// Response + + jo.put("HTTP-Version", token); + jo.put("Status-Code", x.nextToken()); + jo.put("Reason-Phrase", x.nextTo('\0')); + x.next(); + + } else { + +// Request + + jo.put("Method", token); + jo.put("Request-URI", x.nextToken()); + jo.put("HTTP-Version", x.nextToken()); + } + +// Fields + + while (x.more()) { + String name = x.nextTo(':'); + x.next(':'); + jo.put(name, x.nextTo('\0')); + x.next(); + } + return jo; + } + + + /** + * Convert a JSONObject into an HTTP header. A request header must contain + *
{
+     *    Method: "POST" (for example),
+     *    "Request-URI": "/" (for example),
+     *    "HTTP-Version": "HTTP/1.1" (for example)
+     * }
+ * A response header must contain + *
{
+     *    "HTTP-Version": "HTTP/1.1" (for example),
+     *    "Status-Code": "200" (for example),
+     *    "Reason-Phrase": "OK" (for example)
+     * }
+ * Any other members of the JSONObject will be output as HTTP fields. + * The result will end with two CRLF pairs. + * @param jo A JSONObject + * @return An HTTP header string. + * @throws JSONException if the object does not contain enough + * information. + */ + public static String toString(JSONObject jo) throws JSONException { + StringBuilder sb = new StringBuilder(); + if (jo.has("Status-Code") && jo.has("Reason-Phrase")) { + sb.append(jo.getString("HTTP-Version")); + sb.append(' '); + sb.append(jo.getString("Status-Code")); + sb.append(' '); + sb.append(jo.getString("Reason-Phrase")); + } else if (jo.has("Method") && jo.has("Request-URI")) { + sb.append(jo.getString("Method")); + sb.append(' '); + sb.append('"'); + sb.append(jo.getString("Request-URI")); + sb.append('"'); + sb.append(' '); + sb.append(jo.getString("HTTP-Version")); + } else { + throw new JSONException("Not enough material for an HTTP header."); + } + sb.append(CRLF); + // Don't use the new entrySet API to maintain Android support + for (final String key : jo.keySet()) { + String value = jo.optString(key); + if (!"HTTP-Version".equals(key) && !"Status-Code".equals(key) && + !"Reason-Phrase".equals(key) && !"Method".equals(key) && + !"Request-URI".equals(key) && !JSONObject.NULL.equals(value)) { + sb.append(key); + sb.append(": "); + sb.append(jo.optString(key)); + sb.append(CRLF); + } + } + sb.append(CRLF); + return sb.toString(); + } +} diff --git a/src/main/java/org/json/HTTPTokener.java b/src/main/java/org/json/HTTPTokener.java new file mode 100644 index 0000000..16c7081 --- /dev/null +++ b/src/main/java/org/json/HTTPTokener.java @@ -0,0 +1,77 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * The HTTPTokener extends the JSONTokener to provide additional methods + * for the parsing of HTTP headers. + * @author JSON.org + * @version 2015-12-09 + */ +public class HTTPTokener extends JSONTokener { + + /** + * Construct an HTTPTokener from a string. + * @param string A source string. + */ + public HTTPTokener(String string) { + super(string); + } + + + /** + * Get the next token or string. This is used in parsing HTTP headers. + * @return A String. + * @throws JSONException if a syntax error occurs + */ + public String nextToken() throws JSONException { + char c; + char q; + StringBuilder sb = new StringBuilder(); + do { + c = next(); + } while (Character.isWhitespace(c)); + if (c == '"' || c == '\'') { + q = c; + for (;;) { + c = next(); + if (c < ' ') { + throw syntaxError("Unterminated string."); + } + if (c == q) { + return sb.toString(); + } + sb.append(c); + } + } + for (;;) { + if (c == 0 || Character.isWhitespace(c)) { + return sb.toString(); + } + sb.append(c); + c = next(); + } + } +} diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java new file mode 100644 index 0000000..7e95a96 --- /dev/null +++ b/src/main/java/org/json/JSONArray.java @@ -0,0 +1,1716 @@ +package org.json; + +/* + Copyright (c) 2002 JSON.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + The Software shall be used for Good, not Evil. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Array; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * A JSONArray is an ordered sequence of values. Its external text form is a + * string wrapped in square brackets with commas separating the values. The + * internal form is an object having get and opt + * methods for accessing the values by index, and put methods for + * adding or replacing values. The values can be any of these types: + * Boolean, JSONArray, JSONObject, + * Number, String, or the + * JSONObject.NULL object. + *

+ * The constructor can convert a JSON text into a Java object. The + * toString method converts to JSON text. + *

+ * A get method returns a value if one can be found, and throws an + * exception if one cannot be found. An opt method returns a + * default value instead of throwing an exception, and so is useful for + * obtaining optional values. + *

+ * The generic get() and opt() methods return an + * object which you can cast or query for type. There are also typed + * get and opt methods that do type checking and type + * coercion for you. + *

+ * The texts produced by the toString methods strictly conform to + * JSON syntax rules. The constructors are more forgiving in the texts they will + * accept: + *

    + *
  • An extra , (comma) may appear just + * before the closing bracket.
  • + *
  • The null value will be inserted when there is , + *  (comma) elision.
  • + *
  • Strings may be quoted with ' (single + * quote).
  • + *
  • Strings do not need to be quoted at all if they do not begin with a quote + * or single quote, and if they do not contain leading or trailing spaces, and + * if they do not contain any of these characters: + * { } [ ] / \ : , # and if they do not look like numbers and + * if they are not the reserved words true, false, or + * null.
  • + *
+ * + * @author JSON.org + * @version 2016-08/15 + */ +public class JSONArray implements Iterable { + + /** + * The arrayList where the JSONArray's properties are kept. + */ + private final ArrayList myArrayList; + + /** + * Construct an empty JSONArray. + */ + public JSONArray() { + this.myArrayList = new ArrayList(); + } + + /** + * Construct a JSONArray from a JSONTokener. + * + * @param x + * A JSONTokener + * @throws JSONException + * If there is a syntax error. + */ + public JSONArray(JSONTokener x) throws JSONException { + this(); + if (x.nextClean() != '[') { + throw x.syntaxError("A JSONArray text must start with '['"); + } + + char nextChar = x.nextClean(); + if (nextChar == 0) { + // array is unclosed. No ']' found, instead EOF + throw x.syntaxError("Expected a ',' or ']'"); + } + if (nextChar != ']') { + x.back(); + for (;;) { + if (x.nextClean() == ',') { + x.back(); + this.myArrayList.add(JSONObject.NULL); + } else { + x.back(); + this.myArrayList.add(x.nextValue()); + } + switch (x.nextClean()) { + case 0: + // array is unclosed. No ']' found, instead EOF + throw x.syntaxError("Expected a ',' or ']'"); + case ',': + nextChar = x.nextClean(); + if (nextChar == 0) { + // array is unclosed. No ']' found, instead EOF + throw x.syntaxError("Expected a ',' or ']'"); + } + if (nextChar == ']') { + return; + } + x.back(); + break; + case ']': + return; + default: + throw x.syntaxError("Expected a ',' or ']'"); + } + } + } + } + + /** + * Construct a JSONArray from a source JSON text. + * + * @param source + * A string that begins with [ (left + * bracket) and ends with ] + *  (right bracket). + * @throws JSONException + * If there is a syntax error. + */ + public JSONArray(String source) throws JSONException { + this(new JSONTokener(source)); + } + + /** + * Construct a JSONArray from a Collection. + * + * @param collection + * A Collection. + */ + public JSONArray(Collection collection) { + if (collection == null) { + this.myArrayList = new ArrayList(); + } else { + this.myArrayList = new ArrayList(collection.size()); + this.addAll(collection, true); + } + } + + /** + * Construct a JSONArray from an Iterable. This is a shallow copy. + * + * @param iter + * A Iterable collection. + */ + public JSONArray(Iterable iter) { + this(); + if (iter == null) { + return; + } + this.addAll(iter, true); + } + + /** + * Construct a JSONArray from another JSONArray. This is a shallow copy. + * + * @param array + * A array. + */ + public JSONArray(JSONArray array) { + if (array == null) { + this.myArrayList = new ArrayList(); + } else { + // shallow copy directly the internal array lists as any wrapping + // should have been done already in the original JSONArray + this.myArrayList = new ArrayList(array.myArrayList); + } + } + + /** + * Construct a JSONArray from an array. + * + * @param array + * Array. If the parameter passed is null, or not an array, an + * exception will be thrown. + * + * @throws JSONException + * If not an array or if an array value is non-finite number. + * @throws NullPointerException + * Thrown if the array parameter is null. + */ + public JSONArray(Object array) throws JSONException { + this(); + if (!array.getClass().isArray()) { + throw new JSONException( + "JSONArray initial value should be a string or collection or array."); + } + this.addAll(array, true); + } + + /** + * Construct a JSONArray with the specified initial capacity. + * + * @param initialCapacity + * the initial capacity of the JSONArray. + * @throws JSONException + * If the initial capacity is negative. + */ + public JSONArray(int initialCapacity) throws JSONException { + if (initialCapacity < 0) { + throw new JSONException( + "JSONArray initial capacity cannot be negative."); + } + this.myArrayList = new ArrayList(initialCapacity); + } + + @Override + public Iterator iterator() { + return this.myArrayList.iterator(); + } + + /** + * Get the object value associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return An object value. + * @throws JSONException + * If there is no value for the index. + */ + public Object get(int index) throws JSONException { + Object object = this.opt(index); + if (object == null) { + throw new JSONException("JSONArray[" + index + "] not found."); + } + return object; + } + + /** + * Get the boolean value associated with an index. The string values "true" + * and "false" are converted to boolean. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The truth. + * @throws JSONException + * If there is no value for the index or if the value is not + * convertible to boolean. + */ + public boolean getBoolean(int index) throws JSONException { + Object object = this.get(index); + if (object.equals(Boolean.FALSE) + || (object instanceof String && ((String) object) + .equalsIgnoreCase("false"))) { + return false; + } else if (object.equals(Boolean.TRUE) + || (object instanceof String && ((String) object) + .equalsIgnoreCase("true"))) { + return true; + } + throw wrongValueFormatException(index, "boolean", null); + } + + /** + * Get the double value associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException + * If the key is not found or if the value cannot be converted + * to a number. + */ + public double getDouble(int index) throws JSONException { + final Object object = this.get(index); + if(object instanceof Number) { + return ((Number)object).doubleValue(); + } + try { + return Double.parseDouble(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(index, "double", e); + } + } + + /** + * Get the float value associated with a key. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value is not a Number + * object and cannot be converted to a number. + */ + public float getFloat(int index) throws JSONException { + final Object object = this.get(index); + if(object instanceof Number) { + return ((Number)object).floatValue(); + } + try { + return Float.parseFloat(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(index, "float", e); + } + } + + /** + * Get the Number value associated with a key. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value is not a Number + * object and cannot be converted to a number. + */ + public Number getNumber(int index) throws JSONException { + Object object = this.get(index); + try { + if (object instanceof Number) { + return (Number)object; + } + return JSONObject.stringToNumber(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(index, "number", e); + } + } + + /** + * Get the enum value associated with an index. + * + * @param + * Enum Type + * @param clazz + * The type of enum to retrieve. + * @param index + * The index must be between 0 and length() - 1. + * @return The enum value at the index location + * @throws JSONException + * if the key is not found or if the value cannot be converted + * to an enum. + */ + public > E getEnum(Class clazz, int index) throws JSONException { + E val = optEnum(clazz, index); + if(val==null) { + // JSONException should really take a throwable argument. + // If it did, I would re-implement this with the Enum.valueOf + // method and place any thrown exception in the JSONException + throw wrongValueFormatException(index, "enum of type " + + JSONObject.quote(clazz.getSimpleName()), null); + } + return val; + } + + /** + * Get the BigDecimal value associated with an index. If the value is float + * or double, the {@link BigDecimal#BigDecimal(double)} constructor + * will be used. See notes on the constructor for conversion issues that + * may arise. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException + * If the key is not found or if the value cannot be converted + * to a BigDecimal. + */ + public BigDecimal getBigDecimal (int index) throws JSONException { + Object object = this.get(index); + BigDecimal val = JSONObject.objectToBigDecimal(object, null); + if(val == null) { + throw wrongValueFormatException(index, "BigDecimal", object, null); + } + return val; + } + + /** + * Get the BigInteger value associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException + * If the key is not found or if the value cannot be converted + * to a BigInteger. + */ + public BigInteger getBigInteger (int index) throws JSONException { + Object object = this.get(index); + BigInteger val = JSONObject.objectToBigInteger(object, null); + if(val == null) { + throw wrongValueFormatException(index, "BigInteger", object, null); + } + return val; + } + + /** + * Get the int value associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException + * If the key is not found or if the value is not a number. + */ + public int getInt(int index) throws JSONException { + final Object object = this.get(index); + if(object instanceof Number) { + return ((Number)object).intValue(); + } + try { + return Integer.parseInt(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(index, "int", e); + } + } + + /** + * Get the JSONArray associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return A JSONArray value. + * @throws JSONException + * If there is no value for the index. or if the value is not a + * JSONArray + */ + public JSONArray getJSONArray(int index) throws JSONException { + Object object = this.get(index); + if (object instanceof JSONArray) { + return (JSONArray) object; + } + throw wrongValueFormatException(index, "JSONArray", null); + } + + /** + * Get the JSONObject associated with an index. + * + * @param index + * subscript + * @return A JSONObject value. + * @throws JSONException + * If there is no value for the index or if the value is not a + * JSONObject + */ + public JSONObject getJSONObject(int index) throws JSONException { + Object object = this.get(index); + if (object instanceof JSONObject) { + return (JSONObject) object; + } + throw wrongValueFormatException(index, "JSONObject", null); + } + + /** + * Get the long value associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException + * If the key is not found or if the value cannot be converted + * to a number. + */ + public long getLong(int index) throws JSONException { + final Object object = this.get(index); + if(object instanceof Number) { + return ((Number)object).longValue(); + } + try { + return Long.parseLong(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(index, "long", e); + } + } + + /** + * Get the string associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. + * @return A string value. + * @throws JSONException + * If there is no string value for the index. + */ + public String getString(int index) throws JSONException { + Object object = this.get(index); + if (object instanceof String) { + return (String) object; + } + throw wrongValueFormatException(index, "String", null); + } + + /** + * Determine if the value is null. + * + * @param index + * The index must be between 0 and length() - 1. + * @return true if the value at the index is null, or if there is no value. + */ + public boolean isNull(int index) { + return JSONObject.NULL.equals(this.opt(index)); + } + + /** + * Make a string from the contents of this JSONArray. The + * separator string is inserted between each element. Warning: + * This method assumes that the data structure is acyclical. + * + * @param separator + * A string that will be inserted between the elements. + * @return a string. + * @throws JSONException + * If the array contains an invalid number. + */ + public String join(String separator) throws JSONException { + int len = this.length(); + if (len == 0) { + return ""; + } + + StringBuilder sb = new StringBuilder( + JSONObject.valueToString(this.myArrayList.get(0))); + + for (int i = 1; i < len; i++) { + sb.append(separator) + .append(JSONObject.valueToString(this.myArrayList.get(i))); + } + return sb.toString(); + } + + /** + * Get the number of elements in the JSONArray, included nulls. + * + * @return The length (or size). + */ + public int length() { + return this.myArrayList.size(); + } + + /** + * Removes all of the elements from this JSONArray. + * The JSONArray will be empty after this call returns. + */ + public void clear() { + this.myArrayList.clear(); + } + + /** + * Get the optional object value associated with an index. + * + * @param index + * The index must be between 0 and length() - 1. If not, null is returned. + * @return An object value, or null if there is no object at that index. + */ + public Object opt(int index) { + return (index < 0 || index >= this.length()) ? null : this.myArrayList + .get(index); + } + + /** + * Get the optional boolean value associated with an index. It returns false + * if there is no value at that index, or if the value is not Boolean.TRUE + * or the String "true". + * + * @param index + * The index must be between 0 and length() - 1. + * @return The truth. + */ + public boolean optBoolean(int index) { + return this.optBoolean(index, false); + } + + /** + * Get the optional boolean value associated with an index. It returns the + * defaultValue if there is no value at that index or if it is not a Boolean + * or the String "true" or "false" (case insensitive). + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * A boolean default. + * @return The truth. + */ + public boolean optBoolean(int index, boolean defaultValue) { + try { + return this.getBoolean(index); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * Get the optional double value associated with an index. NaN is returned + * if there is no value for the index, or if the value is not a number and + * cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + */ + public double optDouble(int index) { + return this.optDouble(index, Double.NaN); + } + + /** + * Get the optional double value associated with an index. The defaultValue + * is returned if there is no value for the index, or if the value is not a + * number and cannot be converted to a number. + * + * @param index + * subscript + * @param defaultValue + * The default value. + * @return The value. + */ + public double optDouble(int index, double defaultValue) { + final Number val = this.optNumber(index, null); + if (val == null) { + return defaultValue; + } + final double doubleValue = val.doubleValue(); + // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) { + // return defaultValue; + // } + return doubleValue; + } + + /** + * Get the optional float value associated with an index. NaN is returned + * if there is no value for the index, or if the value is not a number and + * cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + */ + public float optFloat(int index) { + return this.optFloat(index, Float.NaN); + } + + /** + * Get the optional float value associated with an index. The defaultValue + * is returned if there is no value for the index, or if the value is not a + * number and cannot be converted to a number. + * + * @param index + * subscript + * @param defaultValue + * The default value. + * @return The value. + */ + public float optFloat(int index, float defaultValue) { + final Number val = this.optNumber(index, null); + if (val == null) { + return defaultValue; + } + final float floatValue = val.floatValue(); + // if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) { + // return floatValue; + // } + return floatValue; + } + + /** + * Get the optional int value associated with an index. Zero is returned if + * there is no value for the index, or if the value is not a number and + * cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + */ + public int optInt(int index) { + return this.optInt(index, 0); + } + + /** + * Get the optional int value associated with an index. The defaultValue is + * returned if there is no value for the index, or if the value is not a + * number and cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default value. + * @return The value. + */ + public int optInt(int index, int defaultValue) { + final Number val = this.optNumber(index, null); + if (val == null) { + return defaultValue; + } + return val.intValue(); + } + + /** + * Get the enum value associated with a key. + * + * @param + * Enum Type + * @param clazz + * The type of enum to retrieve. + * @param index + * The index must be between 0 and length() - 1. + * @return The enum value at the index location or null if not found + */ + public > E optEnum(Class clazz, int index) { + return this.optEnum(clazz, index, null); + } + + /** + * Get the enum value associated with a key. + * + * @param + * Enum Type + * @param clazz + * The type of enum to retrieve. + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default in case the value is not found + * @return The enum value at the index location or defaultValue if + * the value is not found or cannot be assigned to clazz + */ + public > E optEnum(Class clazz, int index, E defaultValue) { + try { + Object val = this.opt(index); + if (JSONObject.NULL.equals(val)) { + return defaultValue; + } + if (clazz.isAssignableFrom(val.getClass())) { + // we just checked it! + @SuppressWarnings("unchecked") + E myE = (E) val; + return myE; + } + return Enum.valueOf(clazz, val.toString()); + } catch (IllegalArgumentException e) { + return defaultValue; + } catch (NullPointerException e) { + return defaultValue; + } + } + + /** + * Get the optional BigInteger value associated with an index. The + * defaultValue is returned if there is no value for the index, or if the + * value is not a number and cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default value. + * @return The value. + */ + public BigInteger optBigInteger(int index, BigInteger defaultValue) { + Object val = this.opt(index); + return JSONObject.objectToBigInteger(val, defaultValue); + } + + /** + * Get the optional BigDecimal value associated with an index. The + * defaultValue is returned if there is no value for the index, or if the + * value is not a number and cannot be converted to a number. If the value + * is float or double, the {@link BigDecimal#BigDecimal(double)} + * constructor will be used. See notes on the constructor for conversion + * issues that may arise. + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default value. + * @return The value. + */ + public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) { + Object val = this.opt(index); + return JSONObject.objectToBigDecimal(val, defaultValue); + } + + /** + * Get the optional JSONArray associated with an index. + * + * @param index + * subscript + * @return A JSONArray value, or null if the index has no value, or if the + * value is not a JSONArray. + */ + public JSONArray optJSONArray(int index) { + Object o = this.opt(index); + return o instanceof JSONArray ? (JSONArray) o : null; + } + + /** + * Get the optional JSONObject associated with an index. Null is returned if + * the key is not found, or null if the index has no value, or if the value + * is not a JSONObject. + * + * @param index + * The index must be between 0 and length() - 1. + * @return A JSONObject value. + */ + public JSONObject optJSONObject(int index) { + Object o = this.opt(index); + return o instanceof JSONObject ? (JSONObject) o : null; + } + + /** + * Get the optional long value associated with an index. Zero is returned if + * there is no value for the index, or if the value is not a number and + * cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @return The value. + */ + public long optLong(int index) { + return this.optLong(index, 0); + } + + /** + * Get the optional long value associated with an index. The defaultValue is + * returned if there is no value for the index, or if the value is not a + * number and cannot be converted to a number. + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default value. + * @return The value. + */ + public long optLong(int index, long defaultValue) { + final Number val = this.optNumber(index, null); + if (val == null) { + return defaultValue; + } + return val.longValue(); + } + + /** + * Get an optional {@link Number} value associated with a key, or null + * if there is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method + * would be used in cases where type coercion of the number value is unwanted. + * + * @param index + * The index must be between 0 and length() - 1. + * @return An object which is the value. + */ + public Number optNumber(int index) { + return this.optNumber(index, null); + } + + /** + * Get an optional {@link Number} value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method + * would be used in cases where type coercion of the number value is unwanted. + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public Number optNumber(int index, Number defaultValue) { + Object val = this.opt(index); + if (JSONObject.NULL.equals(val)) { + return defaultValue; + } + if (val instanceof Number){ + return (Number) val; + } + + if (val instanceof String) { + try { + return JSONObject.stringToNumber((String) val); + } catch (Exception e) { + return defaultValue; + } + } + return defaultValue; + } + + /** + * Get the optional string value associated with an index. It returns an + * empty string if there is no value at that index. If the value is not a + * string and is not null, then it is converted to a string. + * + * @param index + * The index must be between 0 and length() - 1. + * @return A String value. + */ + public String optString(int index) { + return this.optString(index, ""); + } + + /** + * Get the optional string associated with an index. The defaultValue is + * returned if the key is not found. + * + * @param index + * The index must be between 0 and length() - 1. + * @param defaultValue + * The default value. + * @return A String value. + */ + public String optString(int index, String defaultValue) { + Object object = this.opt(index); + return JSONObject.NULL.equals(object) ? defaultValue : object + .toString(); + } + + /** + * Append a boolean value. This increases the array's length by one. + * + * @param value + * A boolean value. + * @return this. + */ + public JSONArray put(boolean value) { + return this.put(value ? Boolean.TRUE : Boolean.FALSE); + } + + /** + * Put a value in the JSONArray, where the value will be a JSONArray which + * is produced from a Collection. + * + * @param value + * A Collection value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + */ + public JSONArray put(Collection value) { + return this.put(new JSONArray(value)); + } + + /** + * Append a double value. This increases the array's length by one. + * + * @param value + * A double value. + * @return this. + * @throws JSONException + * if the value is not finite. + */ + public JSONArray put(double value) throws JSONException { + return this.put(Double.valueOf(value)); + } + + /** + * Append a float value. This increases the array's length by one. + * + * @param value + * A float value. + * @return this. + * @throws JSONException + * if the value is not finite. + */ + public JSONArray put(float value) throws JSONException { + return this.put(Float.valueOf(value)); + } + + /** + * Append an int value. This increases the array's length by one. + * + * @param value + * An int value. + * @return this. + */ + public JSONArray put(int value) { + return this.put(Integer.valueOf(value)); + } + + /** + * Append an long value. This increases the array's length by one. + * + * @param value + * A long value. + * @return this. + */ + public JSONArray put(long value) { + return this.put(Long.valueOf(value)); + } + + /** + * Put a value in the JSONArray, where the value will be a JSONObject which + * is produced from a Map. + * + * @param value + * A Map value. + * @return this. + * @throws JSONException + * If a value in the map is non-finite number. + * @throws NullPointerException + * If a key in the map is null + */ + public JSONArray put(Map value) { + return this.put(new JSONObject(value)); + } + + /** + * Append an object value. This increases the array's length by one. + * + * @param value + * An object value. The value should be a Boolean, Double, + * Integer, JSONArray, JSONObject, Long, or String, or the + * JSONObject.NULL object. + * @return this. + * @throws JSONException + * If the value is non-finite number. + */ + public JSONArray put(Object value) { + JSONObject.testValidity(value); + this.myArrayList.add(value); + return this; + } + + /** + * Put or replace a boolean value in the JSONArray. If the index is greater + * than the length of the JSONArray, then null elements will be added as + * necessary to pad it out. + * + * @param index + * The subscript. + * @param value + * A boolean value. + * @return this. + * @throws JSONException + * If the index is negative. + */ + public JSONArray put(int index, boolean value) throws JSONException { + return this.put(index, value ? Boolean.TRUE : Boolean.FALSE); + } + + /** + * Put a value in the JSONArray, where the value will be a JSONArray which + * is produced from a Collection. + * + * @param index + * The subscript. + * @param value + * A Collection value. + * @return this. + * @throws JSONException + * If the index is negative or if the value is non-finite. + */ + public JSONArray put(int index, Collection value) throws JSONException { + return this.put(index, new JSONArray(value)); + } + + /** + * Put or replace a double value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad it + * out. + * + * @param index + * The subscript. + * @param value + * A double value. + * @return this. + * @throws JSONException + * If the index is negative or if the value is non-finite. + */ + public JSONArray put(int index, double value) throws JSONException { + return this.put(index, Double.valueOf(value)); + } + + /** + * Put or replace a float value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad it + * out. + * + * @param index + * The subscript. + * @param value + * A float value. + * @return this. + * @throws JSONException + * If the index is negative or if the value is non-finite. + */ + public JSONArray put(int index, float value) throws JSONException { + return this.put(index, Float.valueOf(value)); + } + + /** + * Put or replace an int value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad it + * out. + * + * @param index + * The subscript. + * @param value + * An int value. + * @return this. + * @throws JSONException + * If the index is negative. + */ + public JSONArray put(int index, int value) throws JSONException { + return this.put(index, Integer.valueOf(value)); + } + + /** + * Put or replace a long value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad it + * out. + * + * @param index + * The subscript. + * @param value + * A long value. + * @return this. + * @throws JSONException + * If the index is negative. + */ + public JSONArray put(int index, long value) throws JSONException { + return this.put(index, Long.valueOf(value)); + } + + /** + * Put a value in the JSONArray, where the value will be a JSONObject that + * is produced from a Map. + * + * @param index + * The subscript. + * @param value + * The Map value. + * @return this. + * @throws JSONException + * If the index is negative or if the value is an invalid + * number. + * @throws NullPointerException + * If a key in the map is null + */ + public JSONArray put(int index, Map value) throws JSONException { + this.put(index, new JSONObject(value)); + return this; + } + + /** + * Put or replace an object value in the JSONArray. If the index is greater + * than the length of the JSONArray, then null elements will be added as + * necessary to pad it out. + * + * @param index + * The subscript. + * @param value + * The value to put into the array. The value should be a + * Boolean, Double, Integer, JSONArray, JSONObject, Long, or + * String, or the JSONObject.NULL object. + * @return this. + * @throws JSONException + * If the index is negative or if the value is an invalid + * number. + */ + public JSONArray put(int index, Object value) throws JSONException { + if (index < 0) { + throw new JSONException("JSONArray[" + index + "] not found."); + } + if (index < this.length()) { + JSONObject.testValidity(value); + this.myArrayList.set(index, value); + return this; + } + if(index == this.length()){ + // simple append + return this.put(value); + } + // if we are inserting past the length, we want to grow the array all at once + // instead of incrementally. + this.myArrayList.ensureCapacity(index + 1); + while (index != this.length()) { + // we don't need to test validity of NULL objects + this.myArrayList.add(JSONObject.NULL); + } + return this.put(value); + } + + /** + * Put a collection's elements in to the JSONArray. + * + * @param collection + * A Collection. + * @return this. + */ + public JSONArray putAll(Collection collection) { + this.addAll(collection, false); + return this; + } + + /** + * Put an Iterable's elements in to the JSONArray. + * + * @param iter + * An Iterable. + * @return this. + */ + public JSONArray putAll(Iterable iter) { + this.addAll(iter, false); + return this; + } + + /** + * Put a JSONArray's elements in to the JSONArray. + * + * @param array + * A JSONArray. + * @return this. + */ + public JSONArray putAll(JSONArray array) { + // directly copy the elements from the source array to this one + // as all wrapping should have been done already in the source. + this.myArrayList.addAll(array.myArrayList); + return this; + } + + /** + * Put an array's elements in to the JSONArray. + * + * @param array + * Array. If the parameter passed is null, or not an array or Iterable, an + * exception will be thrown. + * @return this. + * + * @throws JSONException + * If not an array, JSONArray, Iterable or if an value is non-finite number. + * @throws NullPointerException + * Thrown if the array parameter is null. + */ + public JSONArray putAll(Object array) throws JSONException { + this.addAll(array, false); + return this; + } + + /** + * Creates a JSONPointer using an initialization string and tries to + * match it to an item within this JSONArray. For example, given a + * JSONArray initialized with this document: + *
+     * [
+     *     {"b":"c"}
+     * ]
+     * 
+ * and this JSONPointer string: + *
+     * "/0/b"
+     * 
+ * Then this method will return the String "c" + * A JSONPointerException may be thrown from code called by this method. + * + * @param jsonPointer string that can be used to create a JSONPointer + * @return the item matched by the JSONPointer, otherwise null + */ + public Object query(String jsonPointer) { + return query(new JSONPointer(jsonPointer)); + } + + /** + * Uses a user initialized JSONPointer and tries to + * match it to an item within this JSONArray. For example, given a + * JSONArray initialized with this document: + *
+     * [
+     *     {"b":"c"}
+     * ]
+     * 
+ * and this JSONPointer: + *
+     * "/0/b"
+     * 
+ * Then this method will return the String "c" + * A JSONPointerException may be thrown from code called by this method. + * + * @param jsonPointer string that can be used to create a JSONPointer + * @return the item matched by the JSONPointer, otherwise null + */ + public Object query(JSONPointer jsonPointer) { + return jsonPointer.queryFrom(this); + } + + /** + * Queries and returns a value from this object using {@code jsonPointer}, or + * returns null if the query fails due to a missing key. + * + * @param jsonPointer the string representation of the JSON pointer + * @return the queried value or {@code null} + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax + */ + public Object optQuery(String jsonPointer) { + return optQuery(new JSONPointer(jsonPointer)); + } + + /** + * Queries and returns a value from this object using {@code jsonPointer}, or + * returns null if the query fails due to a missing key. + * + * @param jsonPointer The JSON pointer + * @return the queried value or {@code null} + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax + */ + public Object optQuery(JSONPointer jsonPointer) { + try { + return jsonPointer.queryFrom(this); + } catch (JSONPointerException e) { + return null; + } + } + + /** + * Remove an index and close the hole. + * + * @param index + * The index of the element to be removed. + * @return The value that was associated with the index, or null if there + * was no value. + */ + public Object remove(int index) { + return index >= 0 && index < this.length() + ? this.myArrayList.remove(index) + : null; + } + + /** + * Determine if two JSONArrays are similar. + * They must contain similar sequences. + * + * @param other The other JSONArray + * @return true if they are equal + */ + public boolean similar(Object other) { + if (!(other instanceof JSONArray)) { + return false; + } + int len = this.length(); + if (len != ((JSONArray)other).length()) { + return false; + } + for (int i = 0; i < len; i += 1) { + Object valueThis = this.myArrayList.get(i); + Object valueOther = ((JSONArray)other).myArrayList.get(i); + if(valueThis == valueOther) { + continue; + } + if(valueThis == null) { + return false; + } + if (valueThis instanceof JSONObject) { + if (!((JSONObject)valueThis).similar(valueOther)) { + return false; + } + } else if (valueThis instanceof JSONArray) { + if (!((JSONArray)valueThis).similar(valueOther)) { + return false; + } + } else if (valueThis instanceof Number && valueOther instanceof Number) { + if (!JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther)) { + return false; + } + } else if (!valueThis.equals(valueOther)) { + return false; + } + } + return true; + } + + /** + * Produce a JSONObject by combining a JSONArray of names with the values of + * this JSONArray. + * + * @param names + * A JSONArray containing a list of key strings. These will be + * paired with the values. + * @return A JSONObject, or null if there are no names or if this JSONArray + * has no values. + * @throws JSONException + * If any of the names are null. + */ + public JSONObject toJSONObject(JSONArray names) throws JSONException { + if (names == null || names.isEmpty() || this.isEmpty()) { + return null; + } + JSONObject jo = new JSONObject(names.length()); + for (int i = 0; i < names.length(); i += 1) { + jo.put(names.getString(i), this.opt(i)); + } + return jo; + } + + /** + * Make a JSON text of this JSONArray. For compactness, no unnecessary + * whitespace is added. If it is not possible to produce a syntactically + * correct JSON text then null will be returned instead. This could occur if + * the array contains an invalid number. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * + * @return a printable, displayable, transmittable representation of the + * array. + */ + @Override + public String toString() { + try { + return this.toString(0); + } catch (Exception e) { + return null; + } + } + + /** + * Make a pretty-printed JSON text of this JSONArray. + * + *

If

 {@code indentFactor > 0}
and the {@link JSONArray} has only + * one element, then the array will be output on a single line: + *
{@code [1]}
+ * + *

If an array has 2 or more elements, then it will be output across + * multiple lines:

{@code
+     * [
+     * 1,
+     * "value 2",
+     * 3
+     * ]
+     * }
+ *

+ * Warning: This method assumes that the data structure is acyclical. + * + * + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @return a printable, displayable, transmittable representation of the + * object, beginning with [ (left + * bracket) and ending with ] + *  (right bracket). + * @throws JSONException if a called function fails + */ + public String toString(int indentFactor) throws JSONException { + StringWriter sw = new StringWriter(); + synchronized (sw.getBuffer()) { + return this.write(sw, indentFactor, 0).toString(); + } + } + + /** + * Write the contents of the JSONArray as JSON text to a writer. For + * compactness, no whitespace is added. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @param writer the writer object + * @return The writer. + * @throws JSONException if a called function fails + */ + public Writer write(Writer writer) throws JSONException { + return this.write(writer, 0, 0); + } + + /** + * Write the contents of the JSONArray as JSON text to a writer. + * + *

If

{@code indentFactor > 0}
and the {@link JSONArray} has only + * one element, then the array will be output on a single line: + *
{@code [1]}
+ * + *

If an array has 2 or more elements, then it will be output across + * multiple lines:

{@code
+     * [
+     * 1,
+     * "value 2",
+     * 3
+     * ]
+     * }
+ *

+ * Warning: This method assumes that the data structure is acyclical. + * + * + * @param writer + * Writes the serialized JSON + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @param indent + * The indentation of the top level. + * @return The writer. + * @throws JSONException if a called function fails or unable to write + */ + public Writer write(Writer writer, int indentFactor, int indent) + throws JSONException { + try { + boolean needsComma = false; + int length = this.length(); + writer.write('['); + + if (length == 1) { + try { + JSONObject.writeValue(writer, this.myArrayList.get(0), + indentFactor, indent); + } catch (Exception e) { + throw new JSONException("Unable to write JSONArray value at index: 0", e); + } + } else if (length != 0) { + final int newIndent = indent + indentFactor; + + for (int i = 0; i < length; i += 1) { + if (needsComma) { + writer.write(','); + } + if (indentFactor > 0) { + writer.write('\n'); + } + JSONObject.indent(writer, newIndent); + try { + JSONObject.writeValue(writer, this.myArrayList.get(i), + indentFactor, newIndent); + } catch (Exception e) { + throw new JSONException("Unable to write JSONArray value at index: " + i, e); + } + needsComma = true; + } + if (indentFactor > 0) { + writer.write('\n'); + } + JSONObject.indent(writer, indent); + } + writer.write(']'); + return writer; + } catch (IOException e) { + throw new JSONException(e); + } + } + + /** + * Returns a java.util.List containing all of the elements in this array. + * If an element in the array is a JSONArray or JSONObject it will also + * be converted to a List and a Map respectively. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return a java.util.List containing the elements of this array + */ + public List toList() { + List results = new ArrayList(this.myArrayList.size()); + for (Object element : this.myArrayList) { + if (element == null || JSONObject.NULL.equals(element)) { + results.add(null); + } else if (element instanceof JSONArray) { + results.add(((JSONArray) element).toList()); + } else if (element instanceof JSONObject) { + results.add(((JSONObject) element).toMap()); + } else { + results.add(element); + } + } + return results; + } + + /** + * Check if JSONArray is empty. + * + * @return true if JSONArray is empty, otherwise false. + */ + public boolean isEmpty() { + return this.myArrayList.isEmpty(); + } + + /** + * Add a collection's elements to the JSONArray. + * + * @param collection + * A Collection. + * @param wrap + * {@code true} to call {@link JSONObject#wrap(Object)} for each item, + * {@code false} to add the items directly + * + */ + private void addAll(Collection collection, boolean wrap) { + this.myArrayList.ensureCapacity(this.myArrayList.size() + collection.size()); + if (wrap) { + for (Object o: collection){ + this.put(JSONObject.wrap(o)); + } + } else { + for (Object o: collection){ + this.put(o); + } + } + } + + /** + * Add an Iterable's elements to the JSONArray. + * + * @param iter + * An Iterable. + * @param wrap + * {@code true} to call {@link JSONObject#wrap(Object)} for each item, + * {@code false} to add the items directly + */ + private void addAll(Iterable iter, boolean wrap) { + if (wrap) { + for (Object o: iter){ + this.put(JSONObject.wrap(o)); + } + } else { + for (Object o: iter){ + this.put(o); + } + } + } + + /** + * Add an array's elements to the JSONArray. + * + * @param array + * Array. If the parameter passed is null, or not an array, + * JSONArray, Collection, or Iterable, an exception will be + * thrown. + * @param wrap + * {@code true} to call {@link JSONObject#wrap(Object)} for each item, + * {@code false} to add the items directly + * + * @throws JSONException + * If not an array or if an array value is non-finite number. + * @throws NullPointerException + * Thrown if the array parameter is null. + */ + private void addAll(Object array, boolean wrap) throws JSONException { + if (array.getClass().isArray()) { + int length = Array.getLength(array); + this.myArrayList.ensureCapacity(this.myArrayList.size() + length); + if (wrap) { + for (int i = 0; i < length; i += 1) { + this.put(JSONObject.wrap(Array.get(array, i))); + } + } else { + for (int i = 0; i < length; i += 1) { + this.put(Array.get(array, i)); + } + } + } else if (array instanceof JSONArray) { + // use the built in array list `addAll` as all object + // wrapping should have been completed in the original + // JSONArray + this.myArrayList.addAll(((JSONArray)array).myArrayList); + } else if (array instanceof Collection) { + this.addAll((Collection)array, wrap); + } else if (array instanceof Iterable) { + this.addAll((Iterable)array, wrap); + } else { + throw new JSONException( + "JSONArray initial value should be a string or collection or array."); + } + } + + /** + * Create a new JSONException in a common format for incorrect conversions. + * @param idx index of the item + * @param valueType the type of value being coerced to + * @param cause optional cause of the coercion failure + * @return JSONException that can be thrown. + */ + private static JSONException wrongValueFormatException( + int idx, + String valueType, + Throwable cause) { + return new JSONException( + "JSONArray[" + idx + "] is not a " + valueType + "." + , cause); + } + + /** + * Create a new JSONException in a common format for incorrect conversions. + * @param idx index of the item + * @param valueType the type of value being coerced to + * @param cause optional cause of the coercion failure + * @return JSONException that can be thrown. + */ + private static JSONException wrongValueFormatException( + int idx, + String valueType, + Object value, + Throwable cause) { + return new JSONException( + "JSONArray[" + idx + "] is not a " + valueType + " (" + value + ")." + , cause); + } + +} diff --git a/src/main/java/org/json/JSONException.java b/src/main/java/org/json/JSONException.java new file mode 100644 index 0000000..ab7ff77 --- /dev/null +++ b/src/main/java/org/json/JSONException.java @@ -0,0 +1,69 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +/** + * The JSONException is thrown by the JSON.org classes when things are amiss. + * + * @author JSON.org + * @version 2015-12-09 + */ +public class JSONException extends RuntimeException { + /** Serialization ID */ + private static final long serialVersionUID = 0; + + /** + * Constructs a JSONException with an explanatory message. + * + * @param message + * Detail about the reason for the exception. + */ + public JSONException(final String message) { + super(message); + } + + /** + * Constructs a JSONException with an explanatory message and cause. + * + * @param message + * Detail about the reason for the exception. + * @param cause + * The cause. + */ + public JSONException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new JSONException with the specified cause. + * + * @param cause + * The cause. + */ + public JSONException(final Throwable cause) { + super(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/org/json/JSONML.java b/src/main/java/org/json/JSONML.java new file mode 100644 index 0000000..aafdf72 --- /dev/null +++ b/src/main/java/org/json/JSONML.java @@ -0,0 +1,542 @@ +package org.json; + +/* +Copyright (c) 2008 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * This provides static methods to convert an XML text into a JSONArray or + * JSONObject, and to covert a JSONArray or JSONObject into an XML text using + * the JsonML transform. + * + * @author JSON.org + * @version 2016-01-30 + */ +public class JSONML { + /** + * Parse XML values and store them in a JSONArray. + * @param x The XMLTokener containing the source string. + * @param arrayForm true if array form, false if object form. + * @param ja The JSONArray that is containing the current tag or null + * if we are at the outermost level. + * @param keepStrings Don't type-convert text nodes and attribute values + * @return A JSONArray if the value is the outermost tag, otherwise null. + * @throws JSONException if a parsing error occurs + */ + private static Object parse( + XMLTokener x, + boolean arrayForm, + JSONArray ja, + boolean keepStrings + ) throws JSONException { + String attribute; + char c; + String closeTag = null; + int i; + JSONArray newja = null; + JSONObject newjo = null; + Object token; + String tagName = null; + +// Test for and skip past these forms: +// +// +// +// + + while (true) { + if (!x.more()) { + throw x.syntaxError("Bad XML"); + } + token = x.nextContent(); + if (token == XML.LT) { + token = x.nextToken(); + if (token instanceof Character) { + if (token == XML.SLASH) { + +// Close tag "); + } else { + x.back(); + } + } else if (c == '[') { + token = x.nextToken(); + if (token.equals("CDATA") && x.next() == '[') { + if (ja != null) { + ja.put(x.nextCDATA()); + } + } else { + throw x.syntaxError("Expected 'CDATA['"); + } + } else { + i = 1; + do { + token = x.nextMeta(); + if (token == null) { + throw x.syntaxError("Missing '>' after ' 0); + } + } else if (token == XML.QUEST) { + +// "); + } else { + throw x.syntaxError("Misshaped tag"); + } + +// Open tag < + + } else { + if (!(token instanceof String)) { + throw x.syntaxError("Bad tagName '" + token + "'."); + } + tagName = (String)token; + newja = new JSONArray(); + newjo = new JSONObject(); + if (arrayForm) { + newja.put(tagName); + if (ja != null) { + ja.put(newja); + } + } else { + newjo.put("tagName", tagName); + if (ja != null) { + ja.put(newjo); + } + } + token = null; + for (;;) { + if (token == null) { + token = x.nextToken(); + } + if (token == null) { + throw x.syntaxError("Misshaped tag"); + } + if (!(token instanceof String)) { + break; + } + +// attribute = value + + attribute = (String)token; + if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) { + throw x.syntaxError("Reserved attribute."); + } + token = x.nextToken(); + if (token == XML.EQ) { + token = x.nextToken(); + if (!(token instanceof String)) { + throw x.syntaxError("Missing value"); + } + newjo.accumulate(attribute, keepStrings ? ((String)token) :XML.stringToValue((String)token)); + token = null; + } else { + newjo.accumulate(attribute, ""); + } + } + if (arrayForm && newjo.length() > 0) { + newja.put(newjo); + } + +// Empty tag <.../> + + if (token == XML.SLASH) { + if (x.nextToken() != XML.GT) { + throw x.syntaxError("Misshaped tag"); + } + if (ja == null) { + if (arrayForm) { + return newja; + } + return newjo; + } + +// Content, between <...> and + + } else { + if (token != XML.GT) { + throw x.syntaxError("Misshaped tag"); + } + closeTag = (String)parse(x, arrayForm, newja, keepStrings); + if (closeTag != null) { + if (!closeTag.equals(tagName)) { + throw x.syntaxError("Mismatched '" + tagName + + "' and '" + closeTag + "'"); + } + tagName = null; + if (!arrayForm && newja.length() > 0) { + newjo.put("childNodes", newja); + } + if (ja == null) { + if (arrayForm) { + return newja; + } + return newjo; + } + } + } + } + } else { + if (ja != null) { + ja.put(token instanceof String + ? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token) + : token); + } + } + } + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child tags. + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param string The source string. + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONArray + */ + public static JSONArray toJSONArray(String string) throws JSONException { + return (JSONArray)parse(new XMLTokener(string), true, null, false); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child tags. + * As opposed to toJSONArray this method does not attempt to convert + * any text node or attribute value to any type + * but just leaves it as a string. + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param string The source string. + * @param keepStrings If true, then values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONArray + */ + public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException { + return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child content and tags. + * As opposed to toJSONArray this method does not attempt to convert + * any text node or attribute value to any type + * but just leaves it as a string. + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param x An XMLTokener. + * @param keepStrings If true, then values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONArray + */ + public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException { + return (JSONArray)parse(x, true, null, keepStrings); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child content and tags. + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param x An XMLTokener. + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONArray + */ + public static JSONArray toJSONArray(XMLTokener x) throws JSONException { + return (JSONArray)parse(x, true, null, false); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param string The XML source text. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONObject + */ + public static JSONObject toJSONObject(String string) throws JSONException { + return (JSONObject)parse(new XMLTokener(string), false, null, false); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param string The XML source text. + * @param keepStrings If true, then values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONObject + */ + public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException { + return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param x An XMLTokener of the XML source text. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONObject + */ + public static JSONObject toJSONObject(XMLTokener x) throws JSONException { + return (JSONObject)parse(x, false, null, false); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param x An XMLTokener of the XML source text. + * @param keepStrings If true, then values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONObject + */ + public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException { + return (JSONObject)parse(x, false, null, keepStrings); + } + + + /** + * Reverse the JSONML transformation, making an XML text from a JSONArray. + * @param ja A JSONArray. + * @return An XML string. + * @throws JSONException Thrown on error converting to a string + */ + public static String toString(JSONArray ja) throws JSONException { + int i; + JSONObject jo; + int length; + Object object; + StringBuilder sb = new StringBuilder(); + String tagName; + +// Emit = length) { + sb.append('/'); + sb.append('>'); + } else { + sb.append('>'); + do { + object = ja.get(i); + i += 1; + if (object != null) { + if (object instanceof String) { + sb.append(XML.escape(object.toString())); + } else if (object instanceof JSONObject) { + sb.append(toString((JSONObject)object)); + } else if (object instanceof JSONArray) { + sb.append(toString((JSONArray)object)); + } else { + sb.append(object.toString()); + } + } + } while (i < length); + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + } + return sb.toString(); + } + + /** + * Reverse the JSONML transformation, making an XML text from a JSONObject. + * The JSONObject must contain a "tagName" property. If it has children, + * then it must have a "childNodes" property containing an array of objects. + * The other properties are attributes with string values. + * @param jo A JSONObject. + * @return An XML string. + * @throws JSONException Thrown on error converting to a string + */ + public static String toString(JSONObject jo) throws JSONException { + StringBuilder sb = new StringBuilder(); + int i; + JSONArray ja; + int length; + Object object; + String tagName; + Object value; + +//Emit '); + } else { + sb.append('>'); + length = ja.length(); + for (i = 0; i < length; i += 1) { + object = ja.get(i); + if (object != null) { + if (object instanceof String) { + sb.append(XML.escape(object.toString())); + } else if (object instanceof JSONObject) { + sb.append(toString((JSONObject)object)); + } else if (object instanceof JSONArray) { + sb.append(toString((JSONArray)object)); + } else { + sb.append(object.toString()); + } + } + } + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + } + return sb.toString(); + } +} diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java new file mode 100644 index 0000000..5c37249 --- /dev/null +++ b/src/main/java/org/json/JSONObject.java @@ -0,0 +1,2732 @@ +package org.json; + +import java.io.Closeable; + +/* + Copyright (c) 2002 JSON.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + The Software shall be used for Good, not Evil. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * A JSONObject is an unordered collection of name/value pairs. Its external + * form is a string wrapped in curly braces with colons between the names and + * values, and commas between the values and names. The internal form is an + * object having get and opt methods for accessing + * the values by name, and put methods for adding or replacing + * values by name. The values can be any of these types: Boolean, + * JSONArray, JSONObject, Number, + * String, or the JSONObject.NULL object. A + * JSONObject constructor can be used to convert an external form JSON text + * into an internal form whose values can be retrieved with the + * get and opt methods, or to convert values into a + * JSON text using the put and toString methods. A + * get method returns a value if one can be found, and throws an + * exception if one cannot be found. An opt method returns a + * default value instead of throwing an exception, and so is useful for + * obtaining optional values. + *

+ * The generic get() and opt() methods return an + * object, which you can cast or query for type. There are also typed + * get and opt methods that do type checking and type + * coercion for you. The opt methods differ from the get methods in that they + * do not throw. Instead, they return a specified value, such as null. + *

+ * The put methods add or replace values in an object. For + * example, + * + *

+ * myString = new JSONObject()
+ *         .put("JSON", "Hello, World!").toString();
+ * 
+ * + * produces the string {"JSON": "Hello, World"}. + *

+ * The texts produced by the toString methods strictly conform to + * the JSON syntax rules. The constructors are more forgiving in the texts they + * will accept: + *

    + *
  • An extra , (comma) may appear just + * before the closing brace.
  • + *
  • Strings may be quoted with ' (single + * quote).
  • + *
  • Strings do not need to be quoted at all if they do not begin with a + * quote or single quote, and if they do not contain leading or trailing + * spaces, and if they do not contain any of these characters: + * { } [ ] / \ : , # and if they do not look like numbers and + * if they are not the reserved words true, false, + * or null.
  • + *
+ * + * @author JSON.org + * @version 2016-08-15 + */ +public class JSONObject { + /** + * JSONObject.NULL is equivalent to the value that JavaScript calls null, + * whilst Java's null is equivalent to the value that JavaScript calls + * undefined. + */ + private static final class Null { + + /** + * There is only intended to be a single instance of the NULL object, + * so the clone method returns itself. + * + * @return NULL. + */ + @Override + protected final Object clone() { + return this; + } + + /** + * A Null object is equal to the null value and to itself. + * + * @param object + * An object to test for nullness. + * @return true if the object parameter is the JSONObject.NULL object or + * null. + */ + @Override + @SuppressWarnings("lgtm[java/unchecked-cast-in-equals]") + public boolean equals(Object object) { + return object == null || object == this; + } + /** + * A Null object is equal to the null value and to itself. + * + * @return always returns 0. + */ + @Override + public int hashCode() { + return 0; + } + + /** + * Get the "null" string value. + * + * @return The string "null". + */ + @Override + public String toString() { + return "null"; + } + } + + /** + * Regular Expression Pattern that matches JSON Numbers. This is primarily used for + * output to guarantee that we are always writing valid JSON. + */ + static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?"); + + /** + * The map where the JSONObject's properties are kept. + */ + private final Map map; + + /** + * It is sometimes more convenient and less ambiguous to have a + * NULL object than to use Java's null value. + * JSONObject.NULL.equals(null) returns true. + * JSONObject.NULL.toString() returns "null". + */ + public static final Object NULL = new Null(); + + /** + * Construct an empty JSONObject. + */ + public JSONObject() { + // HashMap is used on purpose to ensure that elements are unordered by + // the specification. + // JSON tends to be a portable transfer format to allows the container + // implementations to rearrange their items for a faster element + // retrieval based on associative access. + // Therefore, an implementation mustn't rely on the order of the item. + this.map = new HashMap(); + } + + /** + * Construct a JSONObject from a subset of another JSONObject. An array of + * strings is used to identify the keys that should be copied. Missing keys + * are ignored. + * + * @param jo + * A JSONObject. + * @param names + * An array of strings. + */ + public JSONObject(JSONObject jo, String ... names) { + this(names.length); + for (int i = 0; i < names.length; i += 1) { + try { + this.putOnce(names[i], jo.opt(names[i])); + } catch (Exception ignore) { + } + } + } + + /** + * Construct a JSONObject from a JSONTokener. + * + * @param x + * A JSONTokener object containing the source string. + * @throws JSONException + * If there is a syntax error in the source string or a + * duplicated key. + */ + public JSONObject(JSONTokener x) throws JSONException { + this(); + char c; + String key; + + if (x.nextClean() != '{') { + throw x.syntaxError("A JSONObject text must begin with '{'"); + } + for (;;) { + char prev = x.getPrevious(); + c = x.nextClean(); + switch (c) { + case 0: + throw x.syntaxError("A JSONObject text must end with '}'"); + case '}': + return; + case '{': + case '[': + if(prev=='{') { + throw x.syntaxError("A JSON Object can not directly nest another JSON Object or JSON Array."); + } + // fall through + default: + x.back(); + key = x.nextValue().toString(); + } + + // The key is followed by ':'. + + c = x.nextClean(); + if (c != ':') { + throw x.syntaxError("Expected a ':' after a key"); + } + + // Use syntaxError(..) to include error location + + if (key != null) { + // Check if key exists + if (this.opt(key) != null) { + // key already exists + throw x.syntaxError("Duplicate key \"" + key + "\""); + } + // Only add value if non-null + Object value = x.nextValue(); + if (value!=null) { + this.put(key, value); + } + } + + // Pairs are separated by ','. + + switch (x.nextClean()) { + case ';': + case ',': + if (x.nextClean() == '}') { + return; + } + x.back(); + break; + case '}': + return; + default: + throw x.syntaxError("Expected a ',' or '}'"); + } + } + } + + /** + * Construct a JSONObject from a Map. + * + * @param m + * A map object that can be used to initialize the contents of + * the JSONObject. + * @throws JSONException + * If a value in the map is non-finite number. + * @throws NullPointerException + * If a key in the map is null + */ + public JSONObject(Map m) { + if (m == null) { + this.map = new HashMap(); + } else { + this.map = new HashMap(m.size()); + for (final Entry e : m.entrySet()) { + if(e.getKey() == null) { + throw new NullPointerException("Null key."); + } + final Object value = e.getValue(); + if (value != null) { + this.map.put(String.valueOf(e.getKey()), wrap(value)); + } + } + } + } + + /** + * Construct a JSONObject from an Object using bean getters. It reflects on + * all of the public methods of the object. For each of the methods with no + * parameters and a name starting with "get" or + * "is" followed by an uppercase letter, the method is invoked, + * and a key and the value returned from the getter method are put into the + * new JSONObject. + *

+ * The key is formed by removing the "get" or "is" + * prefix. If the second remaining character is not upper case, then the + * first character is converted to lower case. + *

+ * Methods that are static, return void, + * have parameters, or are "bridge" methods, are ignored. + *

+ * For example, if an object has a method named "getName", and + * if the result of calling object.getName() is + * "Larry Fine", then the JSONObject will contain + * "name": "Larry Fine". + *

+ * The {@link JSONPropertyName} annotation can be used on a bean getter to + * override key name used in the JSONObject. For example, using the object + * above with the getName method, if we annotated it with: + *

+     * @JSONPropertyName("FullName")
+     * public String getName() { return this.name; }
+     * 
+ * The resulting JSON object would contain "FullName": "Larry Fine" + *

+ * Similarly, the {@link JSONPropertyName} annotation can be used on non- + * get and is methods. We can also override key + * name used in the JSONObject as seen below even though the field would normally + * be ignored: + *

+     * @JSONPropertyName("FullName")
+     * public String fullName() { return this.name; }
+     * 
+ * The resulting JSON object would contain "FullName": "Larry Fine" + *

+ * The {@link JSONPropertyIgnore} annotation can be used to force the bean property + * to not be serialized into JSON. If both {@link JSONPropertyIgnore} and + * {@link JSONPropertyName} are defined on the same method, a depth comparison is + * performed and the one closest to the concrete class being serialized is used. + * If both annotations are at the same level, then the {@link JSONPropertyIgnore} + * annotation takes precedent and the field is not serialized. + * For example, the following declaration would prevent the getName + * method from being serialized: + *

+     * @JSONPropertyName("FullName")
+     * @JSONPropertyIgnore
+     * public String getName() { return this.name; }
+     * 
+ *

+ * + * @param bean + * An object that has getter methods that should be used to make + * a JSONObject. + */ + public JSONObject(Object bean) { + this(); + this.populateMap(bean); + } + + private JSONObject(Object bean, Set objectsRecord) { + this(); + this.populateMap(bean, objectsRecord); + } + + /** + * Construct a JSONObject from an Object, using reflection to find the + * public members. The resulting JSONObject's keys will be the strings from + * the names array, and the values will be the field values associated with + * those keys in the object. If a key is not found or not visible, then it + * will not be copied into the new JSONObject. + * + * @param object + * An object that has fields that should be used to make a + * JSONObject. + * @param names + * An array of strings, the names of the fields to be obtained + * from the object. + */ + public JSONObject(Object object, String ... names) { + this(names.length); + Class c = object.getClass(); + for (int i = 0; i < names.length; i += 1) { + String name = names[i]; + try { + this.putOpt(name, c.getField(name).get(object)); + } catch (Exception ignore) { + } + } + } + + /** + * Construct a JSONObject from a source JSON text string. This is the most + * commonly used JSONObject constructor. + * + * @param source + * A string beginning with { (left + * brace) and ending with } + *  (right brace). + * @exception JSONException + * If there is a syntax error in the source string or a + * duplicated key. + */ + public JSONObject(String source) throws JSONException { + this(new JSONTokener(source)); + } + + /** + * Construct a JSONObject from a ResourceBundle. + * + * @param baseName + * The ResourceBundle base name. + * @param locale + * The Locale to load the ResourceBundle for. + * @throws JSONException + * If any JSONExceptions are detected. + */ + public JSONObject(String baseName, Locale locale) throws JSONException { + this(); + ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, + Thread.currentThread().getContextClassLoader()); + +// Iterate through the keys in the bundle. + + Enumeration keys = bundle.getKeys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + if (key != null) { + +// Go through the path, ensuring that there is a nested JSONObject for each +// segment except the last. Add the value using the last segment's name into +// the deepest nested JSONObject. + + String[] path = ((String) key).split("\\."); + int last = path.length - 1; + JSONObject target = this; + for (int i = 0; i < last; i += 1) { + String segment = path[i]; + JSONObject nextTarget = target.optJSONObject(segment); + if (nextTarget == null) { + nextTarget = new JSONObject(); + target.put(segment, nextTarget); + } + target = nextTarget; + } + target.put(path[last], bundle.getString((String) key)); + } + } + } + + /** + * Constructor to specify an initial capacity of the internal map. Useful for library + * internal calls where we know, or at least can best guess, how big this JSONObject + * will be. + * + * @param initialCapacity initial capacity of the internal map. + */ + protected JSONObject(int initialCapacity){ + this.map = new HashMap(initialCapacity); + } + + /** + * Accumulate values under a key. It is similar to the put method except + * that if there is already an object stored under the key then a JSONArray + * is stored under the key to hold all of the accumulated values. If there + * is already a JSONArray, then the new value is appended to it. In + * contrast, the put method replaces the previous value. + * + * If only one value is accumulated that is not a JSONArray, then the result + * will be the same as using put. But if multiple values are accumulated, + * then the result will be like append. + * + * @param key + * A key string. + * @param value + * An object to be accumulated under the key. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject accumulate(String key, Object value) throws JSONException { + testValidity(value); + Object object = this.opt(key); + if (object == null) { + this.put(key, + value instanceof JSONArray ? new JSONArray().put(value) + : value); + } else if (object instanceof JSONArray) { + ((JSONArray) object).put(value); + } else { + this.put(key, new JSONArray().put(object).put(value)); + } + return this; + } + + /** + * Append values to the array under a key. If the key does not exist in the + * JSONObject, then the key is put in the JSONObject with its value being a + * JSONArray containing the value parameter. If the key was already + * associated with a JSONArray, then the value parameter is appended to it. + * + * @param key + * A key string. + * @param value + * An object to be accumulated under the key. + * @return this. + * @throws JSONException + * If the value is non-finite number or if the current value associated with + * the key is not a JSONArray. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject append(String key, Object value) throws JSONException { + testValidity(value); + Object object = this.opt(key); + if (object == null) { + this.put(key, new JSONArray().put(value)); + } else if (object instanceof JSONArray) { + this.put(key, ((JSONArray) object).put(value)); + } else { + throw wrongValueFormatException(key, "JSONArray", null, null); + } + return this; + } + + /** + * Produce a string from a double. The string "null" will be returned if the + * number is not finite. + * + * @param d + * A double. + * @return A String. + */ + public static String doubleToString(double d) { + if (Double.isInfinite(d) || Double.isNaN(d)) { + return "null"; + } + +// Shave off trailing zeros and decimal point, if possible. + + String string = Double.toString(d); + if (string.indexOf('.') > 0 && string.indexOf('e') < 0 + && string.indexOf('E') < 0) { + while (string.endsWith("0")) { + string = string.substring(0, string.length() - 1); + } + if (string.endsWith(".")) { + string = string.substring(0, string.length() - 1); + } + } + return string; + } + + /** + * Get the value object associated with a key. + * + * @param key + * A key string. + * @return The object associated with the key. + * @throws JSONException + * if the key is not found. + */ + public Object get(String key) throws JSONException { + if (key == null) { + throw new JSONException("Null key."); + } + Object object = this.opt(key); + if (object == null) { + throw new JSONException("JSONObject[" + quote(key) + "] not found."); + } + return object; + } + + /** + * Get the enum value associated with a key. + * + * @param + * Enum Type + * @param clazz + * The type of enum to retrieve. + * @param key + * A key string. + * @return The enum value associated with the key + * @throws JSONException + * if the key is not found or if the value cannot be converted + * to an enum. + */ + public > E getEnum(Class clazz, String key) throws JSONException { + E val = optEnum(clazz, key); + if(val==null) { + // JSONException should really take a throwable argument. + // If it did, I would re-implement this with the Enum.valueOf + // method and place any thrown exception in the JSONException + throw wrongValueFormatException(key, "enum of type " + quote(clazz.getSimpleName()), null); + } + return val; + } + + /** + * Get the boolean value associated with a key. + * + * @param key + * A key string. + * @return The truth. + * @throws JSONException + * if the value is not a Boolean or the String "true" or + * "false". + */ + public boolean getBoolean(String key) throws JSONException { + Object object = this.get(key); + if (object.equals(Boolean.FALSE) + || (object instanceof String && ((String) object) + .equalsIgnoreCase("false"))) { + return false; + } else if (object.equals(Boolean.TRUE) + || (object instanceof String && ((String) object) + .equalsIgnoreCase("true"))) { + return true; + } + throw wrongValueFormatException(key, "Boolean", null); + } + + /** + * Get the BigInteger value associated with a key. + * + * @param key + * A key string. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value cannot + * be converted to BigInteger. + */ + public BigInteger getBigInteger(String key) throws JSONException { + Object object = this.get(key); + BigInteger ret = objectToBigInteger(object, null); + if (ret != null) { + return ret; + } + throw wrongValueFormatException(key, "BigInteger", object, null); + } + + /** + * Get the BigDecimal value associated with a key. If the value is float or + * double, the {@link BigDecimal#BigDecimal(double)} constructor will + * be used. See notes on the constructor for conversion issues that may + * arise. + * + * @param key + * A key string. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value + * cannot be converted to BigDecimal. + */ + public BigDecimal getBigDecimal(String key) throws JSONException { + Object object = this.get(key); + BigDecimal ret = objectToBigDecimal(object, null); + if (ret != null) { + return ret; + } + throw wrongValueFormatException(key, "BigDecimal", object, null); + } + + /** + * Get the double value associated with a key. + * + * @param key + * A key string. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value is not a Number + * object and cannot be converted to a number. + */ + public double getDouble(String key) throws JSONException { + final Object object = this.get(key); + if(object instanceof Number) { + return ((Number)object).doubleValue(); + } + try { + return Double.parseDouble(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(key, "double", e); + } + } + + /** + * Get the float value associated with a key. + * + * @param key + * A key string. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value is not a Number + * object and cannot be converted to a number. + */ + public float getFloat(String key) throws JSONException { + final Object object = this.get(key); + if(object instanceof Number) { + return ((Number)object).floatValue(); + } + try { + return Float.parseFloat(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(key, "float", e); + } + } + + /** + * Get the Number value associated with a key. + * + * @param key + * A key string. + * @return The numeric value. + * @throws JSONException + * if the key is not found or if the value is not a Number + * object and cannot be converted to a number. + */ + public Number getNumber(String key) throws JSONException { + Object object = this.get(key); + try { + if (object instanceof Number) { + return (Number)object; + } + return stringToNumber(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(key, "number", e); + } + } + + /** + * Get the int value associated with a key. + * + * @param key + * A key string. + * @return The integer value. + * @throws JSONException + * if the key is not found or if the value cannot be converted + * to an integer. + */ + public int getInt(String key) throws JSONException { + final Object object = this.get(key); + if(object instanceof Number) { + return ((Number)object).intValue(); + } + try { + return Integer.parseInt(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(key, "int", e); + } + } + + /** + * Get the JSONArray value associated with a key. + * + * @param key + * A key string. + * @return A JSONArray which is the value. + * @throws JSONException + * if the key is not found or if the value is not a JSONArray. + */ + public JSONArray getJSONArray(String key) throws JSONException { + Object object = this.get(key); + if (object instanceof JSONArray) { + return (JSONArray) object; + } + throw wrongValueFormatException(key, "JSONArray", null); + } + + /** + * Get the JSONObject value associated with a key. + * + * @param key + * A key string. + * @return A JSONObject which is the value. + * @throws JSONException + * if the key is not found or if the value is not a JSONObject. + */ + public JSONObject getJSONObject(String key) throws JSONException { + Object object = this.get(key); + if (object instanceof JSONObject) { + return (JSONObject) object; + } + throw wrongValueFormatException(key, "JSONObject", null); + } + + /** + * Get the long value associated with a key. + * + * @param key + * A key string. + * @return The long value. + * @throws JSONException + * if the key is not found or if the value cannot be converted + * to a long. + */ + public long getLong(String key) throws JSONException { + final Object object = this.get(key); + if(object instanceof Number) { + return ((Number)object).longValue(); + } + try { + return Long.parseLong(object.toString()); + } catch (Exception e) { + throw wrongValueFormatException(key, "long", e); + } + } + + /** + * Get an array of field names from a JSONObject. + * + * @param jo + * JSON object + * @return An array of field names, or null if there are no names. + */ + public static String[] getNames(JSONObject jo) { + if (jo.isEmpty()) { + return null; + } + return jo.keySet().toArray(new String[jo.length()]); + } + + /** + * Get an array of public field names from an Object. + * + * @param object + * object to read + * @return An array of field names, or null if there are no names. + */ + public static String[] getNames(Object object) { + if (object == null) { + return null; + } + Class klass = object.getClass(); + Field[] fields = klass.getFields(); + int length = fields.length; + if (length == 0) { + return null; + } + String[] names = new String[length]; + for (int i = 0; i < length; i += 1) { + names[i] = fields[i].getName(); + } + return names; + } + + /** + * Get the string associated with a key. + * + * @param key + * A key string. + * @return A string which is the value. + * @throws JSONException + * if there is no string value for the key. + */ + public String getString(String key) throws JSONException { + Object object = this.get(key); + if (object instanceof String) { + return (String) object; + } + throw wrongValueFormatException(key, "string", null); + } + + /** + * Determine if the JSONObject contains a specific key. + * + * @param key + * A key string. + * @return true if the key exists in the JSONObject. + */ + public boolean has(String key) { + return this.map.containsKey(key); + } + + /** + * Increment a property of a JSONObject. If there is no such property, + * create one with a value of 1 (Integer). If there is such a property, and if it is + * an Integer, Long, Double, Float, BigInteger, or BigDecimal then add one to it. + * No overflow bounds checking is performed, so callers should initialize the key + * prior to this call with an appropriate type that can handle the maximum expected + * value. + * + * @param key + * A key string. + * @return this. + * @throws JSONException + * If there is already a property with this name that is not an + * Integer, Long, Double, or Float. + */ + public JSONObject increment(String key) throws JSONException { + Object value = this.opt(key); + if (value == null) { + this.put(key, 1); + } else if (value instanceof Integer) { + this.put(key, ((Integer) value).intValue() + 1); + } else if (value instanceof Long) { + this.put(key, ((Long) value).longValue() + 1L); + } else if (value instanceof BigInteger) { + this.put(key, ((BigInteger)value).add(BigInteger.ONE)); + } else if (value instanceof Float) { + this.put(key, ((Float) value).floatValue() + 1.0f); + } else if (value instanceof Double) { + this.put(key, ((Double) value).doubleValue() + 1.0d); + } else if (value instanceof BigDecimal) { + this.put(key, ((BigDecimal)value).add(BigDecimal.ONE)); + } else { + throw new JSONException("Unable to increment [" + quote(key) + "]."); + } + return this; + } + + /** + * Determine if the value associated with the key is null or if there is no + * value. + * + * @param key + * A key string. + * @return true if there is no value associated with the key or if the value + * is the JSONObject.NULL object. + */ + public boolean isNull(String key) { + return JSONObject.NULL.equals(this.opt(key)); + } + + /** + * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also + * modify the JSONObject. Use with caution. + * + * @see Set#iterator() + * + * @return An iterator of the keys. + */ + public Iterator keys() { + return this.keySet().iterator(); + } + + /** + * Get a set of keys of the JSONObject. Modifying this key Set will also modify the + * JSONObject. Use with caution. + * + * @see Map#keySet() + * + * @return A keySet. + */ + public Set keySet() { + return this.map.keySet(); + } + + /** + * Get a set of entries of the JSONObject. These are raw values and may not + * match what is returned by the JSONObject get* and opt* functions. Modifying + * the returned EntrySet or the Entry objects contained therein will modify the + * backing JSONObject. This does not return a clone or a read-only view. + * + * Use with caution. + * + * @see Map#entrySet() + * + * @return An Entry Set + */ + protected Set> entrySet() { + return this.map.entrySet(); + } + + /** + * Get the number of keys stored in the JSONObject. + * + * @return The number of keys in the JSONObject. + */ + public int length() { + return this.map.size(); + } + + /** + * Removes all of the elements from this JSONObject. + * The JSONObject will be empty after this call returns. + */ + public void clear() { + this.map.clear(); + } + + /** + * Check if JSONObject is empty. + * + * @return true if JSONObject is empty, otherwise false. + */ + public boolean isEmpty() { + return this.map.isEmpty(); + } + + /** + * Produce a JSONArray containing the names of the elements of this + * JSONObject. + * + * @return A JSONArray containing the key strings, or null if the JSONObject + * is empty. + */ + public JSONArray names() { + if(this.map.isEmpty()) { + return null; + } + return new JSONArray(this.map.keySet()); + } + + /** + * Produce a string from a Number. + * + * @param number + * A Number + * @return A String. + * @throws JSONException + * If n is a non-finite number. + */ + public static String numberToString(Number number) throws JSONException { + if (number == null) { + throw new JSONException("Null pointer"); + } + testValidity(number); + + // Shave off trailing zeros and decimal point, if possible. + + String string = number.toString(); + if (string.indexOf('.') > 0 && string.indexOf('e') < 0 + && string.indexOf('E') < 0) { + while (string.endsWith("0")) { + string = string.substring(0, string.length() - 1); + } + if (string.endsWith(".")) { + string = string.substring(0, string.length() - 1); + } + } + return string; + } + + /** + * Get an optional value associated with a key. + * + * @param key + * A key string. + * @return An object which is the value, or null if there is no value. + */ + public Object opt(String key) { + return key == null ? null : this.map.get(key); + } + + /** + * Get the enum value associated with a key. + * + * @param + * Enum Type + * @param clazz + * The type of enum to retrieve. + * @param key + * A key string. + * @return The enum value associated with the key or null if not found + */ + public > E optEnum(Class clazz, String key) { + return this.optEnum(clazz, key, null); + } + + /** + * Get the enum value associated with a key. + * + * @param + * Enum Type + * @param clazz + * The type of enum to retrieve. + * @param key + * A key string. + * @param defaultValue + * The default in case the value is not found + * @return The enum value associated with the key or defaultValue + * if the value is not found or cannot be assigned to clazz + */ + public > E optEnum(Class clazz, String key, E defaultValue) { + try { + Object val = this.opt(key); + if (NULL.equals(val)) { + return defaultValue; + } + if (clazz.isAssignableFrom(val.getClass())) { + // we just checked it! + @SuppressWarnings("unchecked") + E myE = (E) val; + return myE; + } + return Enum.valueOf(clazz, val.toString()); + } catch (IllegalArgumentException e) { + return defaultValue; + } catch (NullPointerException e) { + return defaultValue; + } + } + + /** + * Get an optional boolean associated with a key. It returns false if there + * is no such key, or if the value is not Boolean.TRUE or the String "true". + * + * @param key + * A key string. + * @return The truth. + */ + public boolean optBoolean(String key) { + return this.optBoolean(key, false); + } + + /** + * Get an optional boolean associated with a key. It returns the + * defaultValue if there is no such key, or if it is not a Boolean or the + * String "true" or "false" (case insensitive). + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return The truth. + */ + public boolean optBoolean(String key, boolean defaultValue) { + Object val = this.opt(key); + if (NULL.equals(val)) { + return defaultValue; + } + if (val instanceof Boolean){ + return ((Boolean) val).booleanValue(); + } + try { + // we'll use the get anyway because it does string conversion. + return this.getBoolean(key); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * Get an optional BigDecimal associated with a key, or the defaultValue if + * there is no such key or if its value is not a number. If the value is a + * string, an attempt will be made to evaluate it as a number. If the value + * is float or double, then the {@link BigDecimal#BigDecimal(double)} + * constructor will be used. See notes on the constructor for conversion + * issues that may arise. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) { + Object val = this.opt(key); + return objectToBigDecimal(val, defaultValue); + } + + /** + * @param val value to convert + * @param defaultValue default value to return is the conversion doesn't work or is null. + * @return BigDecimal conversion of the original value, or the defaultValue if unable + * to convert. + */ + static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) { + return objectToBigDecimal(val, defaultValue, true); + } + + /** + * @param val value to convert + * @param defaultValue default value to return is the conversion doesn't work or is null. + * @param exact When true, then {@link Double} and {@link Float} values will be converted exactly. + * When false, they will be converted to {@link String} values before converting to {@link BigDecimal}. + * @return BigDecimal conversion of the original value, or the defaultValue if unable + * to convert. + */ + static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue, boolean exact) { + if (NULL.equals(val)) { + return defaultValue; + } + if (val instanceof BigDecimal){ + return (BigDecimal) val; + } + if (val instanceof BigInteger){ + return new BigDecimal((BigInteger) val); + } + if (val instanceof Double || val instanceof Float){ + if (!numberIsFinite((Number)val)) { + return defaultValue; + } + if (exact) { + return new BigDecimal(((Number)val).doubleValue()); + }else { + // use the string constructor so that we maintain "nice" values for doubles and floats + // the double constructor will translate doubles to "exact" values instead of the likely + // intended representation + return new BigDecimal(val.toString()); + } + } + if (val instanceof Long || val instanceof Integer + || val instanceof Short || val instanceof Byte){ + return new BigDecimal(((Number) val).longValue()); + } + // don't check if it's a string in case of unchecked Number subclasses + try { + return new BigDecimal(val.toString()); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * Get an optional BigInteger associated with a key, or the defaultValue if + * there is no such key or if its value is not a number. If the value is a + * string, an attempt will be made to evaluate it as a number. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public BigInteger optBigInteger(String key, BigInteger defaultValue) { + Object val = this.opt(key); + return objectToBigInteger(val, defaultValue); + } + + /** + * @param val value to convert + * @param defaultValue default value to return is the conversion doesn't work or is null. + * @return BigInteger conversion of the original value, or the defaultValue if unable + * to convert. + */ + static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) { + if (NULL.equals(val)) { + return defaultValue; + } + if (val instanceof BigInteger){ + return (BigInteger) val; + } + if (val instanceof BigDecimal){ + return ((BigDecimal) val).toBigInteger(); + } + if (val instanceof Double || val instanceof Float){ + if (!numberIsFinite((Number)val)) { + return defaultValue; + } + return new BigDecimal(((Number) val).doubleValue()).toBigInteger(); + } + if (val instanceof Long || val instanceof Integer + || val instanceof Short || val instanceof Byte){ + return BigInteger.valueOf(((Number) val).longValue()); + } + // don't check if it's a string in case of unchecked Number subclasses + try { + // the other opt functions handle implicit conversions, i.e. + // jo.put("double",1.1d); + // jo.optInt("double"); -- will return 1, not an error + // this conversion to BigDecimal then to BigInteger is to maintain + // that type cast support that may truncate the decimal. + final String valStr = val.toString(); + if(isDecimalNotation(valStr)) { + return new BigDecimal(valStr).toBigInteger(); + } + return new BigInteger(valStr); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * Get an optional double associated with a key, or NaN if there is no such + * key or if its value is not a number. If the value is a string, an attempt + * will be made to evaluate it as a number. + * + * @param key + * A string which is the key. + * @return An object which is the value. + */ + public double optDouble(String key) { + return this.optDouble(key, Double.NaN); + } + + /** + * Get an optional double associated with a key, or the defaultValue if + * there is no such key or if its value is not a number. If the value is a + * string, an attempt will be made to evaluate it as a number. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public double optDouble(String key, double defaultValue) { + Number val = this.optNumber(key); + if (val == null) { + return defaultValue; + } + final double doubleValue = val.doubleValue(); + // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) { + // return defaultValue; + // } + return doubleValue; + } + + /** + * Get the optional double value associated with an index. NaN is returned + * if there is no value for the index, or if the value is not a number and + * cannot be converted to a number. + * + * @param key + * A key string. + * @return The value. + */ + public float optFloat(String key) { + return this.optFloat(key, Float.NaN); + } + + /** + * Get the optional double value associated with an index. The defaultValue + * is returned if there is no value for the index, or if the value is not a + * number and cannot be converted to a number. + * + * @param key + * A key string. + * @param defaultValue + * The default value. + * @return The value. + */ + public float optFloat(String key, float defaultValue) { + Number val = this.optNumber(key); + if (val == null) { + return defaultValue; + } + final float floatValue = val.floatValue(); + // if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) { + // return defaultValue; + // } + return floatValue; + } + + /** + * Get an optional int value associated with a key, or zero if there is no + * such key or if the value is not a number. If the value is a string, an + * attempt will be made to evaluate it as a number. + * + * @param key + * A key string. + * @return An object which is the value. + */ + public int optInt(String key) { + return this.optInt(key, 0); + } + + /** + * Get an optional int value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public int optInt(String key, int defaultValue) { + final Number val = this.optNumber(key, null); + if (val == null) { + return defaultValue; + } + return val.intValue(); + } + + /** + * Get an optional JSONArray associated with a key. It returns null if there + * is no such key, or if its value is not a JSONArray. + * + * @param key + * A key string. + * @return A JSONArray which is the value. + */ + public JSONArray optJSONArray(String key) { + Object o = this.opt(key); + return o instanceof JSONArray ? (JSONArray) o : null; + } + + /** + * Get an optional JSONObject associated with a key. It returns null if + * there is no such key, or if its value is not a JSONObject. + * + * @param key + * A key string. + * @return A JSONObject which is the value. + */ + public JSONObject optJSONObject(String key) { return this.optJSONObject(key, null); } + + /** + * Get an optional JSONObject associated with a key, or the default if there + * is no such key or if the value is not a JSONObject. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An JSONObject which is the value. + */ + public JSONObject optJSONObject(String key, JSONObject defaultValue) { + Object object = this.opt(key); + return object instanceof JSONObject ? (JSONObject) object : defaultValue; + } + + /** + * Get an optional long value associated with a key, or zero if there is no + * such key or if the value is not a number. If the value is a string, an + * attempt will be made to evaluate it as a number. + * + * @param key + * A key string. + * @return An object which is the value. + */ + public long optLong(String key) { + return this.optLong(key, 0); + } + + /** + * Get an optional long value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public long optLong(String key, long defaultValue) { + final Number val = this.optNumber(key, null); + if (val == null) { + return defaultValue; + } + + return val.longValue(); + } + + /** + * Get an optional {@link Number} value associated with a key, or null + * if there is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method + * would be used in cases where type coercion of the number value is unwanted. + * + * @param key + * A key string. + * @return An object which is the value. + */ + public Number optNumber(String key) { + return this.optNumber(key, null); + } + + /** + * Get an optional {@link Number} value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number. This method + * would be used in cases where type coercion of the number value is unwanted. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return An object which is the value. + */ + public Number optNumber(String key, Number defaultValue) { + Object val = this.opt(key); + if (NULL.equals(val)) { + return defaultValue; + } + if (val instanceof Number){ + return (Number) val; + } + + try { + return stringToNumber(val.toString()); + } catch (Exception e) { + return defaultValue; + } + } + + /** + * Get an optional string associated with a key. It returns an empty string + * if there is no such key. If the value is not a string and is not null, + * then it is converted to a string. + * + * @param key + * A key string. + * @return A string which is the value. + */ + public String optString(String key) { + return this.optString(key, ""); + } + + /** + * Get an optional string associated with a key. It returns the defaultValue + * if there is no such key. + * + * @param key + * A key string. + * @param defaultValue + * The default. + * @return A string which is the value. + */ + public String optString(String key, String defaultValue) { + Object object = this.opt(key); + return NULL.equals(object) ? defaultValue : object.toString(); + } + + /** + * Populates the internal map of the JSONObject with the bean properties. The + * bean can not be recursive. + * + * @see JSONObject#JSONObject(Object) + * + * @param bean + * the bean + */ + private void populateMap(Object bean) { + populateMap(bean, Collections.newSetFromMap(new IdentityHashMap())); + } + + private void populateMap(Object bean, Set objectsRecord) { + Class klass = bean.getClass(); + + // If klass is a System class then set includeSuperClass to false. + + boolean includeSuperClass = klass.getClassLoader() != null; + + Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); + for (final Method method : methods) { + final int modifiers = method.getModifiers(); + if (Modifier.isPublic(modifiers) + && !Modifier.isStatic(modifiers) + && method.getParameterTypes().length == 0 + && !method.isBridge() + && method.getReturnType() != Void.TYPE + && isValidMethodName(method.getName())) { + final String key = getKeyNameFromMethod(method); + if (key != null && !key.isEmpty()) { + try { + final Object result = method.invoke(bean); + if (result != null) { + // check cyclic dependency and throw error if needed + // the wrap and populateMap combination method is + // itself DFS recursive + if (objectsRecord.contains(result)) { + throw recursivelyDefinedObjectException(key); + } + + objectsRecord.add(result); + + this.map.put(key, wrap(result, objectsRecord)); + + objectsRecord.remove(result); + + // we don't use the result anywhere outside of wrap + // if it's a resource we should be sure to close it + // after calling toString + if (result instanceof Closeable) { + try { + ((Closeable) result).close(); + } catch (IOException ignore) { + } + } + } + } catch (IllegalAccessException ignore) { + } catch (IllegalArgumentException ignore) { + } catch (InvocationTargetException ignore) { + } + } + } + } + } + + private static boolean isValidMethodName(String name) { + return !"getClass".equals(name) && !"getDeclaringClass".equals(name); + } + + private static String getKeyNameFromMethod(Method method) { + final int ignoreDepth = getAnnotationDepth(method, JSONPropertyIgnore.class); + if (ignoreDepth > 0) { + final int forcedNameDepth = getAnnotationDepth(method, JSONPropertyName.class); + if (forcedNameDepth < 0 || ignoreDepth <= forcedNameDepth) { + // the hierarchy asked to ignore, and the nearest name override + // was higher or non-existent + return null; + } + } + JSONPropertyName annotation = getAnnotation(method, JSONPropertyName.class); + if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) { + return annotation.value(); + } + String key; + final String name = method.getName(); + if (name.startsWith("get") && name.length() > 3) { + key = name.substring(3); + } else if (name.startsWith("is") && name.length() > 2) { + key = name.substring(2); + } else { + return null; + } + // if the first letter in the key is not uppercase, then skip. + // This is to maintain backwards compatibility before PR406 + // (https://github.com/stleary/JSON-java/pull/406/) + if (key.length() == 0 || Character.isLowerCase(key.charAt(0))) { + return null; + } + if (key.length() == 1) { + key = key.toLowerCase(Locale.ROOT); + } else if (!Character.isUpperCase(key.charAt(1))) { + key = key.substring(0, 1).toLowerCase(Locale.ROOT) + key.substring(1); + } + return key; + } + + /** + * Searches the class hierarchy to see if the method or it's super + * implementations and interfaces has the annotation. + * + * @param + * type of the annotation + * + * @param m + * method to check + * @param annotationClass + * annotation to look for + * @return the {@link Annotation} if the annotation exists on the current method + * or one of its super class definitions + */ + private static A getAnnotation(final Method m, final Class annotationClass) { + // if we have invalid data the result is null + if (m == null || annotationClass == null) { + return null; + } + + if (m.isAnnotationPresent(annotationClass)) { + return m.getAnnotation(annotationClass); + } + + // if we've already reached the Object class, return null; + Class c = m.getDeclaringClass(); + if (c.getSuperclass() == null) { + return null; + } + + // check directly implemented interfaces for the method being checked + for (Class i : c.getInterfaces()) { + try { + Method im = i.getMethod(m.getName(), m.getParameterTypes()); + return getAnnotation(im, annotationClass); + } catch (final SecurityException ex) { + continue; + } catch (final NoSuchMethodException ex) { + continue; + } + } + + try { + return getAnnotation( + c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()), + annotationClass); + } catch (final SecurityException ex) { + return null; + } catch (final NoSuchMethodException ex) { + return null; + } + } + + /** + * Searches the class hierarchy to see if the method or it's super + * implementations and interfaces has the annotation. Returns the depth of the + * annotation in the hierarchy. + * + * @param m + * method to check + * @param annotationClass + * annotation to look for + * @return Depth of the annotation or -1 if the annotation is not on the method. + */ + private static int getAnnotationDepth(final Method m, final Class annotationClass) { + // if we have invalid data the result is -1 + if (m == null || annotationClass == null) { + return -1; + } + + if (m.isAnnotationPresent(annotationClass)) { + return 1; + } + + // if we've already reached the Object class, return -1; + Class c = m.getDeclaringClass(); + if (c.getSuperclass() == null) { + return -1; + } + + // check directly implemented interfaces for the method being checked + for (Class i : c.getInterfaces()) { + try { + Method im = i.getMethod(m.getName(), m.getParameterTypes()); + int d = getAnnotationDepth(im, annotationClass); + if (d > 0) { + // since the annotation was on the interface, add 1 + return d + 1; + } + } catch (final SecurityException ex) { + continue; + } catch (final NoSuchMethodException ex) { + continue; + } + } + + try { + int d = getAnnotationDepth( + c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()), + annotationClass); + if (d > 0) { + // since the annotation was on the superclass, add 1 + return d + 1; + } + return -1; + } catch (final SecurityException ex) { + return -1; + } catch (final NoSuchMethodException ex) { + return -1; + } + } + + /** + * Put a key/boolean pair in the JSONObject. + * + * @param key + * A key string. + * @param value + * A boolean which is the value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, boolean value) throws JSONException { + return this.put(key, value ? Boolean.TRUE : Boolean.FALSE); + } + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONArray which is produced from a Collection. + * + * @param key + * A key string. + * @param value + * A Collection value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, Collection value) throws JSONException { + return this.put(key, new JSONArray(value)); + } + + /** + * Put a key/double pair in the JSONObject. + * + * @param key + * A key string. + * @param value + * A double which is the value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, double value) throws JSONException { + return this.put(key, Double.valueOf(value)); + } + + /** + * Put a key/float pair in the JSONObject. + * + * @param key + * A key string. + * @param value + * A float which is the value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, float value) throws JSONException { + return this.put(key, Float.valueOf(value)); + } + + /** + * Put a key/int pair in the JSONObject. + * + * @param key + * A key string. + * @param value + * An int which is the value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, int value) throws JSONException { + return this.put(key, Integer.valueOf(value)); + } + + /** + * Put a key/long pair in the JSONObject. + * + * @param key + * A key string. + * @param value + * A long which is the value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, long value) throws JSONException { + return this.put(key, Long.valueOf(value)); + } + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONObject which is produced from a Map. + * + * @param key + * A key string. + * @param value + * A Map value. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, Map value) throws JSONException { + return this.put(key, new JSONObject(value)); + } + + /** + * Put a key/value pair in the JSONObject. If the value is null, then the + * key will be removed from the JSONObject if it is present. + * + * @param key + * A key string. + * @param value + * An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, + * String, or the JSONObject.NULL object. + * @return this. + * @throws JSONException + * If the value is non-finite number. + * @throws NullPointerException + * If the key is null. + */ + public JSONObject put(String key, Object value) throws JSONException { + if (key == null) { + throw new NullPointerException("Null key."); + } + if (value != null) { + testValidity(value); + this.map.put(key, value); + } else { + this.remove(key); + } + return this; + } + + /** + * Put a key/value pair in the JSONObject, but only if the key and the value + * are both non-null, and only if there is not already a member with that + * name. + * + * @param key + * key to insert into + * @param value + * value to insert + * @return this. + * @throws JSONException + * if the key is a duplicate + */ + public JSONObject putOnce(String key, Object value) throws JSONException { + if (key != null && value != null) { + if (this.opt(key) != null) { + throw new JSONException("Duplicate key \"" + key + "\""); + } + return this.put(key, value); + } + return this; + } + + /** + * Put a key/value pair in the JSONObject, but only if the key and the value + * are both non-null. + * + * @param key + * A key string. + * @param value + * An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, + * String, or the JSONObject.NULL object. + * @return this. + * @throws JSONException + * If the value is a non-finite number. + */ + public JSONObject putOpt(String key, Object value) throws JSONException { + if (key != null && value != null) { + return this.put(key, value); + } + return this; + } + + /** + * Creates a JSONPointer using an initialization string and tries to + * match it to an item within this JSONObject. For example, given a + * JSONObject initialized with this document: + *
+     * {
+     *     "a":{"b":"c"}
+     * }
+     * 
+ * and this JSONPointer string: + *
+     * "/a/b"
+     * 
+ * Then this method will return the String "c". + * A JSONPointerException may be thrown from code called by this method. + * + * @param jsonPointer string that can be used to create a JSONPointer + * @return the item matched by the JSONPointer, otherwise null + */ + public Object query(String jsonPointer) { + return query(new JSONPointer(jsonPointer)); + } + /** + * Uses a user initialized JSONPointer and tries to + * match it to an item within this JSONObject. For example, given a + * JSONObject initialized with this document: + *
+     * {
+     *     "a":{"b":"c"}
+     * }
+     * 
+ * and this JSONPointer: + *
+     * "/a/b"
+     * 
+ * Then this method will return the String "c". + * A JSONPointerException may be thrown from code called by this method. + * + * @param jsonPointer string that can be used to create a JSONPointer + * @return the item matched by the JSONPointer, otherwise null + */ + public Object query(JSONPointer jsonPointer) { + return jsonPointer.queryFrom(this); + } + + /** + * Queries and returns a value from this object using {@code jsonPointer}, or + * returns null if the query fails due to a missing key. + * + * @param jsonPointer the string representation of the JSON pointer + * @return the queried value or {@code null} + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax + */ + public Object optQuery(String jsonPointer) { + return optQuery(new JSONPointer(jsonPointer)); + } + + /** + * Queries and returns a value from this object using {@code jsonPointer}, or + * returns null if the query fails due to a missing key. + * + * @param jsonPointer The JSON pointer + * @return the queried value or {@code null} + * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax + */ + public Object optQuery(JSONPointer jsonPointer) { + try { + return jsonPointer.queryFrom(this); + } catch (JSONPointerException e) { + return null; + } + } + + /** + * Produce a string in double quotes with backslash sequences in all the + * right places. A backslash will be inserted within </, producing + * <\/, allowing JSON text to be delivered in HTML. In JSON text, a + * string cannot contain a control character or an unescaped quote or + * backslash. + * + * @param string + * A String + * @return A String correctly formatted for insertion in a JSON text. + */ + public static String quote(String string) { + StringWriter sw = new StringWriter(); + synchronized (sw.getBuffer()) { + try { + return quote(string, sw).toString(); + } catch (IOException ignored) { + // will never happen - we are writing to a string writer + return ""; + } + } + } + + public static Writer quote(String string, Writer w) throws IOException { + if (string == null || string.isEmpty()) { + w.write("\"\""); + return w; + } + + char b; + char c = 0; + String hhhh; + int i; + int len = string.length(); + + w.write('"'); + for (i = 0; i < len; i += 1) { + b = c; + c = string.charAt(i); + switch (c) { + case '\\': + case '"': + w.write('\\'); + w.write(c); + break; + case '/': + if (b == '<') { + w.write('\\'); + } + w.write(c); + break; + case '\b': + w.write("\\b"); + break; + case '\t': + w.write("\\t"); + break; + case '\n': + w.write("\\n"); + break; + case '\f': + w.write("\\f"); + break; + case '\r': + w.write("\\r"); + break; + default: + if (c < ' ' || (c >= '\u0080' && c < '\u00a0') + || (c >= '\u2000' && c < '\u2100')) { + w.write("\\u"); + hhhh = Integer.toHexString(c); + w.write("0000", 0, 4 - hhhh.length()); + w.write(hhhh); + } else { + w.write(c); + } + } + } + w.write('"'); + return w; + } + + /** + * Remove a name and its value, if present. + * + * @param key + * The name to be removed. + * @return The value that was associated with the name, or null if there was + * no value. + */ + public Object remove(String key) { + return this.map.remove(key); + } + + /** + * Determine if two JSONObjects are similar. + * They must contain the same set of names which must be associated with + * similar values. + * + * @param other The other JSONObject + * @return true if they are equal + */ + public boolean similar(Object other) { + try { + if (!(other instanceof JSONObject)) { + return false; + } + if (!this.keySet().equals(((JSONObject)other).keySet())) { + return false; + } + for (final Entry entry : this.entrySet()) { + String name = entry.getKey(); + Object valueThis = entry.getValue(); + Object valueOther = ((JSONObject)other).get(name); + if(valueThis == valueOther) { + continue; + } + if(valueThis == null) { + return false; + } + if (valueThis instanceof JSONObject) { + if (!((JSONObject)valueThis).similar(valueOther)) { + return false; + } + } else if (valueThis instanceof JSONArray) { + if (!((JSONArray)valueThis).similar(valueOther)) { + return false; + } + } else if (valueThis instanceof Number && valueOther instanceof Number) { + if (!isNumberSimilar((Number)valueThis, (Number)valueOther)) { + return false; + }; + } else if (!valueThis.equals(valueOther)) { + return false; + } + } + return true; + } catch (Throwable exception) { + return false; + } + } + + /** + * Compares two numbers to see if they are similar. + * + * If either of the numbers are Double or Float instances, then they are checked to have + * a finite value. If either value is not finite (NaN or ±infinity), then this + * function will always return false. If both numbers are finite, they are first checked + * to be the same type and implement {@link Comparable}. If they do, then the actual + * {@link Comparable#compareTo(Object)} is called. If they are not the same type, or don't + * implement Comparable, then they are converted to {@link BigDecimal}s. Finally the + * BigDecimal values are compared using {@link BigDecimal#compareTo(BigDecimal)}. + * + * @param l the Left value to compare. Can not be null. + * @param r the right value to compare. Can not be null. + * @return true if the numbers are similar, false otherwise. + */ + static boolean isNumberSimilar(Number l, Number r) { + if (!numberIsFinite(l) || !numberIsFinite(r)) { + // non-finite numbers are never similar + return false; + } + + // if the classes are the same and implement Comparable + // then use the built in compare first. + if(l.getClass().equals(r.getClass()) && l instanceof Comparable) { + @SuppressWarnings({ "rawtypes", "unchecked" }) + int compareTo = ((Comparable)l).compareTo(r); + return compareTo==0; + } + + // BigDecimal should be able to handle all of our number types that we support through + // documentation. Convert to BigDecimal first, then use the Compare method to + // decide equality. + final BigDecimal lBigDecimal = objectToBigDecimal(l, null, false); + final BigDecimal rBigDecimal = objectToBigDecimal(r, null, false); + if (lBigDecimal == null || rBigDecimal == null) { + return false; + } + return lBigDecimal.compareTo(rBigDecimal) == 0; + } + + private static boolean numberIsFinite(Number n) { + if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) { + return false; + } else if (n instanceof Float && (((Float) n).isInfinite() || ((Float) n).isNaN())) { + return false; + } + return true; + } + + /** + * Tests if the value should be tried as a decimal. It makes no test if there are actual digits. + * + * @param val value to test + * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise. + */ + protected static boolean isDecimalNotation(final String val) { + return val.indexOf('.') > -1 || val.indexOf('e') > -1 + || val.indexOf('E') > -1 || "-0".equals(val); + } + + /** + * Converts a string to a number using the narrowest possible type. Possible + * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer. + * When a Double is returned, it should always be a valid Double and not NaN or +-infinity. + * + * @param val value to convert + * @return Number representation of the value. + * @throws NumberFormatException thrown if the value is not a valid number. A public + * caller should catch this and wrap it in a {@link JSONException} if applicable. + */ + protected static Number stringToNumber(final String val) throws NumberFormatException { + char initial = val.charAt(0); + if ((initial >= '0' && initial <= '9') || initial == '-') { + // decimal representation + if (isDecimalNotation(val)) { + // Use a BigDecimal all the time so we keep the original + // representation. BigDecimal doesn't support -0.0, ensure we + // keep that by forcing a decimal. + try { + BigDecimal bd = new BigDecimal(val); + if(initial == '-' && BigDecimal.ZERO.compareTo(bd)==0) { + return Double.valueOf(-0.0); + } + return bd; + } catch (NumberFormatException retryAsDouble) { + // this is to support "Hex Floats" like this: 0x1.0P-1074 + try { + Double d = Double.valueOf(val); + if(d.isNaN() || d.isInfinite()) { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + return d; + } catch (NumberFormatException ignore) { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + } + } + // block items like 00 01 etc. Java number parsers treat these as Octal. + if(initial == '0' && val.length() > 1) { + char at1 = val.charAt(1); + if(at1 >= '0' && at1 <= '9') { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + } else if (initial == '-' && val.length() > 2) { + char at1 = val.charAt(1); + char at2 = val.charAt(2); + if(at1 == '0' && at2 >= '0' && at2 <= '9') { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + } + // integer representation. + // This will narrow any values to the smallest reasonable Object representation + // (Integer, Long, or BigInteger) + + // BigInteger down conversion: We use a similar bitLength compare as + // BigInteger#intValueExact uses. Increases GC, but objects hold + // only what they need. i.e. Less runtime overhead if the value is + // long lived. + BigInteger bi = new BigInteger(val); + if(bi.bitLength() <= 31){ + return Integer.valueOf(bi.intValue()); + } + if(bi.bitLength() <= 63){ + return Long.valueOf(bi.longValue()); + } + return bi; + } + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + + /** + * Try to convert a string into a number, boolean, or null. If the string + * can't be converted, return the string. + * + * @param string + * A String. can not be null. + * @return A simple JSON value. + * @throws NullPointerException + * Thrown if the string is null. + */ + // Changes to this method must be copied to the corresponding method in + // the XML class to keep full support for Android + public static Object stringToValue(String string) { + if ("".equals(string)) { + return string; + } + + // check JSON key words true/false/null + if ("true".equalsIgnoreCase(string)) { + return Boolean.TRUE; + } + if ("false".equalsIgnoreCase(string)) { + return Boolean.FALSE; + } + if ("null".equalsIgnoreCase(string)) { + return JSONObject.NULL; + } + + /* + * If it might be a number, try converting it. If a number cannot be + * produced, then the value will just be a string. + */ + + char initial = string.charAt(0); + if ((initial >= '0' && initial <= '9') || initial == '-') { + try { + return stringToNumber(string); + } catch (Exception ignore) { + } + } + return string; + } + + /** + * Throw an exception if the object is a NaN or infinite number. + * + * @param o + * The object to test. + * @throws JSONException + * If o is a non-finite number. + */ + public static void testValidity(Object o) throws JSONException { + if (o instanceof Number && !numberIsFinite((Number) o)) { + throw new JSONException("JSON does not allow non-finite numbers."); + } + } + + /** + * Produce a JSONArray containing the values of the members of this + * JSONObject. + * + * @param names + * A JSONArray containing a list of key strings. This determines + * the sequence of the values in the result. + * @return A JSONArray of values. + * @throws JSONException + * If any of the values are non-finite numbers. + */ + public JSONArray toJSONArray(JSONArray names) throws JSONException { + if (names == null || names.isEmpty()) { + return null; + } + JSONArray ja = new JSONArray(); + for (int i = 0; i < names.length(); i += 1) { + ja.put(this.opt(names.getString(i))); + } + return ja; + } + + /** + * Make a JSON text of this JSONObject. For compactness, no whitespace is + * added. If this would not result in a syntactically correct JSON text, + * then null will be returned instead. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * + * @return a printable, displayable, portable, transmittable representation + * of the object, beginning with { (left + * brace) and ending with } (right + * brace). + */ + @Override + public String toString() { + try { + return this.toString(0); + } catch (Exception e) { + return null; + } + } + + /** + * Make a pretty-printed JSON text of this JSONObject. + * + *

If

{@code indentFactor > 0}
and the {@link JSONObject} + * has only one key, then the object will be output on a single line: + *
{@code {"key": 1}}
+ * + *

If an object has 2 or more keys, then it will be output across + * multiple lines:

{@code {
+     *  "key1": 1,
+     *  "key2": "value 2",
+     *  "key3": 3
+     * }}
+ *

+ * Warning: This method assumes that the data structure is acyclical. + * + * + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @return a printable, displayable, portable, transmittable representation + * of the object, beginning with { (left + * brace) and ending with } (right + * brace). + * @throws JSONException + * If the object contains an invalid number. + */ + public String toString(int indentFactor) throws JSONException { + StringWriter w = new StringWriter(); + synchronized (w.getBuffer()) { + return this.write(w, indentFactor, 0).toString(); + } + } + + /** + * Make a JSON text of an Object value. If the object has an + * value.toJSONString() method, then that method will be used to produce the + * JSON text. The method is required to produce a strictly conforming text. + * If the object does not contain a toJSONString method (which is the most + * common case), then a text will be produced by other means. If the value + * is an array or Collection, then a JSONArray will be made from it and its + * toJSONString method will be called. If the value is a MAP, then a + * JSONObject will be made from it and its toJSONString method will be + * called. Otherwise, the value's toString method will be called, and the + * result will be quoted. + * + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @param value + * The value to be serialized. + * @return a printable, displayable, transmittable representation of the + * object, beginning with { (left + * brace) and ending with } (right + * brace). + * @throws JSONException + * If the value is or contains an invalid number. + */ + public static String valueToString(Object value) throws JSONException { + // moves the implementation to JSONWriter as: + // 1. It makes more sense to be part of the writer class + // 2. For Android support this method is not available. By implementing it in the Writer + // Android users can use the writer with the built in Android JSONObject implementation. + return JSONWriter.valueToString(value); + } + + /** + * Wrap an object, if necessary. If the object is null, return the NULL + * object. If it is an array or collection, wrap it in a JSONArray. If it is + * a map, wrap it in a JSONObject. If it is a standard property (Double, + * String, et al) then it is already wrapped. Otherwise, if it comes from + * one of the java packages, turn it into a string. And if it doesn't, try + * to wrap it in a JSONObject. If the wrapping fails, then null is returned. + * + * @param object + * The object to wrap + * @return The wrapped value + */ + public static Object wrap(Object object) { + return wrap(object, null); + } + + private static Object wrap(Object object, Set objectsRecord) { + try { + if (NULL.equals(object)) { + return NULL; + } + if (object instanceof JSONObject || object instanceof JSONArray + || NULL.equals(object) || object instanceof JSONString + || object instanceof Byte || object instanceof Character + || object instanceof Short || object instanceof Integer + || object instanceof Long || object instanceof Boolean + || object instanceof Float || object instanceof Double + || object instanceof String || object instanceof BigInteger + || object instanceof BigDecimal || object instanceof Enum) { + return object; + } + + if (object instanceof Collection) { + Collection coll = (Collection) object; + return new JSONArray(coll); + } + if (object.getClass().isArray()) { + return new JSONArray(object); + } + if (object instanceof Map) { + Map map = (Map) object; + return new JSONObject(map); + } + Package objectPackage = object.getClass().getPackage(); + String objectPackageName = objectPackage != null ? objectPackage + .getName() : ""; + if (objectPackageName.startsWith("java.") + || objectPackageName.startsWith("javax.") + || object.getClass().getClassLoader() == null) { + return object.toString(); + } + if (objectsRecord != null) { + return new JSONObject(object, objectsRecord); + } + else { + return new JSONObject(object); + } + } + catch (JSONException exception) { + throw exception; + } catch (Exception exception) { + return null; + } + } + + /** + * Write the contents of the JSONObject as JSON text to a writer. For + * compactness, no whitespace is added. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @param writer the writer object + * @return The writer. + * @throws JSONException if a called function has an error + */ + public Writer write(Writer writer) throws JSONException { + return this.write(writer, 0, 0); + } + + static final Writer writeValue(Writer writer, Object value, + int indentFactor, int indent) throws JSONException, IOException { + if (value == null || value.equals(null)) { + writer.write("null"); + } else if (value instanceof JSONString) { + Object o; + try { + o = ((JSONString) value).toJSONString(); + } catch (Exception e) { + throw new JSONException(e); + } + writer.write(o != null ? o.toString() : quote(value.toString())); + } else if (value instanceof Number) { + // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary + final String numberAsString = numberToString((Number) value); + if(NUMBER_PATTERN.matcher(numberAsString).matches()) { + writer.write(numberAsString); + } else { + // The Number value is not a valid JSON number. + // Instead we will quote it as a string + quote(numberAsString, writer); + } + } else if (value instanceof Boolean) { + writer.write(value.toString()); + } else if (value instanceof Enum) { + writer.write(quote(((Enum)value).name())); + } else if (value instanceof JSONObject) { + ((JSONObject) value).write(writer, indentFactor, indent); + } else if (value instanceof JSONArray) { + ((JSONArray) value).write(writer, indentFactor, indent); + } else if (value instanceof Map) { + Map map = (Map) value; + new JSONObject(map).write(writer, indentFactor, indent); + } else if (value instanceof Collection) { + Collection coll = (Collection) value; + new JSONArray(coll).write(writer, indentFactor, indent); + } else if (value.getClass().isArray()) { + new JSONArray(value).write(writer, indentFactor, indent); + } else { + quote(value.toString(), writer); + } + return writer; + } + + static final void indent(Writer writer, int indent) throws IOException { + for (int i = 0; i < indent; i += 1) { + writer.write(' '); + } + } + + /** + * Write the contents of the JSONObject as JSON text to a writer. + * + *

If

{@code indentFactor > 0}
and the {@link JSONObject} + * has only one key, then the object will be output on a single line: + *
{@code {"key": 1}}
+ * + *

If an object has 2 or more keys, then it will be output across + * multiple lines:

{@code {
+     *  "key1": 1,
+     *  "key2": "value 2",
+     *  "key3": 3
+     * }}
+ *

+ * Warning: This method assumes that the data structure is acyclical. + * + * + * @param writer + * Writes the serialized JSON + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @param indent + * The indentation of the top level. + * @return The writer. + * @throws JSONException if a called function has an error or a write error + * occurs + */ + public Writer write(Writer writer, int indentFactor, int indent) + throws JSONException { + try { + boolean needsComma = false; + final int length = this.length(); + writer.write('{'); + + if (length == 1) { + final Entry entry = this.entrySet().iterator().next(); + final String key = entry.getKey(); + writer.write(quote(key)); + writer.write(':'); + if (indentFactor > 0) { + writer.write(' '); + } + try{ + writeValue(writer, entry.getValue(), indentFactor, indent); + } catch (Exception e) { + throw new JSONException("Unable to write JSONObject value for key: " + key, e); + } + } else if (length != 0) { + final int newIndent = indent + indentFactor; + for (final Entry entry : this.entrySet()) { + if (needsComma) { + writer.write(','); + } + if (indentFactor > 0) { + writer.write('\n'); + } + indent(writer, newIndent); + final String key = entry.getKey(); + writer.write(quote(key)); + writer.write(':'); + if (indentFactor > 0) { + writer.write(' '); + } + try { + writeValue(writer, entry.getValue(), indentFactor, newIndent); + } catch (Exception e) { + throw new JSONException("Unable to write JSONObject value for key: " + key, e); + } + needsComma = true; + } + if (indentFactor > 0) { + writer.write('\n'); + } + indent(writer, indent); + } + writer.write('}'); + return writer; + } catch (IOException exception) { + throw new JSONException(exception); + } + } + + /** + * Returns a java.util.Map containing all of the entries in this object. + * If an entry in the object is a JSONArray or JSONObject it will also + * be converted. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return a java.util.Map containing the entries of this object + */ + public Map toMap() { + Map results = new HashMap(); + for (Entry entry : this.entrySet()) { + Object value; + if (entry.getValue() == null || NULL.equals(entry.getValue())) { + value = null; + } else if (entry.getValue() instanceof JSONObject) { + value = ((JSONObject) entry.getValue()).toMap(); + } else if (entry.getValue() instanceof JSONArray) { + value = ((JSONArray) entry.getValue()).toList(); + } else { + value = entry.getValue(); + } + results.put(entry.getKey(), value); + } + return results; + } + + /** + * Create a new JSONException in a common format for incorrect conversions. + * @param key name of the key + * @param valueType the type of value being coerced to + * @param cause optional cause of the coercion failure + * @return JSONException that can be thrown. + */ + private static JSONException wrongValueFormatException( + String key, + String valueType, + Throwable cause) { + return new JSONException( + "JSONObject[" + quote(key) + "] is not a " + valueType + "." + , cause); + } + + /** + * Create a new JSONException in a common format for incorrect conversions. + * @param key name of the key + * @param valueType the type of value being coerced to + * @param cause optional cause of the coercion failure + * @return JSONException that can be thrown. + */ + private static JSONException wrongValueFormatException( + String key, + String valueType, + Object value, + Throwable cause) { + return new JSONException( + "JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")." + , cause); + } + + /** + * Create a new JSONException in a common format for recursive object definition. + * @param key name of the key + * @return JSONException that can be thrown. + */ + private static JSONException recursivelyDefinedObjectException(String key) { + return new JSONException( + "JavaBean object contains recursively defined member variable of key " + quote(key) + ); + } +} diff --git a/src/main/java/org/json/JSONPointer.java b/src/main/java/org/json/JSONPointer.java new file mode 100644 index 0000000..f1f7f33 --- /dev/null +++ b/src/main/java/org/json/JSONPointer.java @@ -0,0 +1,295 @@ +package org.json; + +import static java.lang.String.format; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * A JSON Pointer is a simple query language defined for JSON documents by + * RFC 6901. + * + * In a nutshell, JSONPointer allows the user to navigate into a JSON document + * using strings, and retrieve targeted objects, like a simple form of XPATH. + * Path segments are separated by the '/' char, which signifies the root of + * the document when it appears as the first char of the string. Array + * elements are navigated using ordinals, counting from 0. JSONPointer strings + * may be extended to any arbitrary number of segments. If the navigation + * is successful, the matched item is returned. A matched item may be a + * JSONObject, a JSONArray, or a JSON value. If the JSONPointer string building + * fails, an appropriate exception is thrown. If the navigation fails to find + * a match, a JSONPointerException is thrown. + * + * @author JSON.org + * @version 2016-05-14 + */ +public class JSONPointer { + + // used for URL encoding and decoding + private static final String ENCODING = "utf-8"; + + /** + * This class allows the user to build a JSONPointer in steps, using + * exactly one segment in each step. + */ + public static class Builder { + + // Segments for the eventual JSONPointer string + private final List refTokens = new ArrayList(); + + /** + * Creates a {@code JSONPointer} instance using the tokens previously set using the + * {@link #append(String)} method calls. + * @return a JSONPointer object + */ + public JSONPointer build() { + return new JSONPointer(this.refTokens); + } + + /** + * Adds an arbitrary token to the list of reference tokens. It can be any non-null value. + * + * Unlike in the case of JSON string or URI fragment representation of JSON pointers, the + * argument of this method MUST NOT be escaped. If you want to query the property called + * {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no + * need to escape it as {@code "a~0b"}. + * + * @param token the new token to be appended to the list + * @return {@code this} + * @throws NullPointerException if {@code token} is null + */ + public Builder append(String token) { + if (token == null) { + throw new NullPointerException("token cannot be null"); + } + this.refTokens.add(token); + return this; + } + + /** + * Adds an integer to the reference token list. Although not necessarily, mostly this token will + * denote an array index. + * + * @param arrayIndex the array index to be added to the token list + * @return {@code this} + */ + public Builder append(int arrayIndex) { + this.refTokens.add(String.valueOf(arrayIndex)); + return this; + } + } + + /** + * Static factory method for {@link Builder}. Example usage: + * + *


+     * JSONPointer pointer = JSONPointer.builder()
+     *       .append("obj")
+     *       .append("other~key").append("another/key")
+     *       .append("\"")
+     *       .append(0)
+     *       .build();
+     * 
+ * + * @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained + * {@link Builder#append(String)} calls. + */ + public static Builder builder() { + return new Builder(); + } + + // Segments for the JSONPointer string + private final List refTokens; + + /** + * Pre-parses and initializes a new {@code JSONPointer} instance. If you want to + * evaluate the same JSON Pointer on different JSON documents then it is recommended + * to keep the {@code JSONPointer} instances due to performance considerations. + * + * @param pointer the JSON String or URI Fragment representation of the JSON pointer. + * @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer + */ + public JSONPointer(final String pointer) { + if (pointer == null) { + throw new NullPointerException("pointer cannot be null"); + } + if (pointer.isEmpty() || pointer.equals("#")) { + this.refTokens = Collections.emptyList(); + return; + } + String refs; + if (pointer.startsWith("#/")) { + refs = pointer.substring(2); + try { + refs = URLDecoder.decode(refs, ENCODING); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } else if (pointer.startsWith("/")) { + refs = pointer.substring(1); + } else { + throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'"); + } + this.refTokens = new ArrayList(); + int slashIdx = -1; + int prevSlashIdx = 0; + do { + prevSlashIdx = slashIdx + 1; + slashIdx = refs.indexOf('/', prevSlashIdx); + if(prevSlashIdx == slashIdx || prevSlashIdx == refs.length()) { + // found 2 slashes in a row ( obj//next ) + // or single slash at the end of a string ( obj/test/ ) + this.refTokens.add(""); + } else if (slashIdx >= 0) { + final String token = refs.substring(prevSlashIdx, slashIdx); + this.refTokens.add(unescape(token)); + } else { + // last item after separator, or no separator at all. + final String token = refs.substring(prevSlashIdx); + this.refTokens.add(unescape(token)); + } + } while (slashIdx >= 0); + // using split does not take into account consecutive separators or "ending nulls" + //for (String token : refs.split("/")) { + // this.refTokens.add(unescape(token)); + //} + } + + public JSONPointer(List refTokens) { + this.refTokens = new ArrayList(refTokens); + } + + /** + * @see rfc6901 section 3 + */ + private static String unescape(String token) { + return token.replace("~1", "/").replace("~0", "~"); + } + + /** + * Evaluates this JSON Pointer on the given {@code document}. The {@code document} + * is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty + * JSON Pointer ({@code ""}) can be evaluated on any JSON values and in such case the + * returned value will be {@code document} itself. + * + * @param document the JSON document which should be the subject of querying. + * @return the result of the evaluation + * @throws JSONPointerException if an error occurs during evaluation + */ + public Object queryFrom(Object document) throws JSONPointerException { + if (this.refTokens.isEmpty()) { + return document; + } + Object current = document; + for (String token : this.refTokens) { + if (current instanceof JSONObject) { + current = ((JSONObject) current).opt(unescape(token)); + } else if (current instanceof JSONArray) { + current = readByIndexToken(current, token); + } else { + throw new JSONPointerException(format( + "value [%s] is not an array or object therefore its key %s cannot be resolved", current, + token)); + } + } + return current; + } + + /** + * Matches a JSONArray element by ordinal position + * @param current the JSONArray to be evaluated + * @param indexToken the array index in string form + * @return the matched object. If no matching item is found a + * @throws JSONPointerException is thrown if the index is out of bounds + */ + private static Object readByIndexToken(Object current, String indexToken) throws JSONPointerException { + try { + int index = Integer.parseInt(indexToken); + JSONArray currentArr = (JSONArray) current; + if (index >= currentArr.length()) { + throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken, + Integer.valueOf(currentArr.length()))); + } + try { + return currentArr.get(index); + } catch (JSONException e) { + throw new JSONPointerException("Error reading value at index position " + index, e); + } + } catch (NumberFormatException e) { + throw new JSONPointerException(format("%s is not an array index", indexToken), e); + } + } + + /** + * Returns a string representing the JSONPointer path value using string + * representation + */ + @Override + public String toString() { + StringBuilder rval = new StringBuilder(""); + for (String token: this.refTokens) { + rval.append('/').append(escape(token)); + } + return rval.toString(); + } + + /** + * Escapes path segment values to an unambiguous form. + * The escape char to be inserted is '~'. The chars to be escaped + * are ~, which maps to ~0, and /, which maps to ~1. + * @param token the JSONPointer segment value to be escaped + * @return the escaped value for the token + * + * @see rfc6901 section 3 + */ + private static String escape(String token) { + return token.replace("~", "~0") + .replace("/", "~1"); + } + + /** + * Returns a string representing the JSONPointer path value using URI + * fragment identifier representation + * @return a uri fragment string + */ + public String toURIFragment() { + try { + StringBuilder rval = new StringBuilder("#"); + for (String token : this.refTokens) { + rval.append('/').append(URLEncoder.encode(token, ENCODING)); + } + return rval.toString(); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/org/json/JSONPointerException.java b/src/main/java/org/json/JSONPointerException.java new file mode 100644 index 0000000..0ce1aeb --- /dev/null +++ b/src/main/java/org/json/JSONPointerException.java @@ -0,0 +1,45 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * The JSONPointerException is thrown by {@link JSONPointer} if an error occurs + * during evaluating a pointer. + * + * @author JSON.org + * @version 2016-05-13 + */ +public class JSONPointerException extends JSONException { + private static final long serialVersionUID = 8872944667561856751L; + + public JSONPointerException(String message) { + super(message); + } + + public JSONPointerException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/org/json/JSONPropertyIgnore.java b/src/main/java/org/json/JSONPropertyIgnore.java new file mode 100644 index 0000000..682de74 --- /dev/null +++ b/src/main/java/org/json/JSONPropertyIgnore.java @@ -0,0 +1,43 @@ +package org.json; + +/* +Copyright (c) 2018 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Documented +@Retention(RUNTIME) +@Target({METHOD}) +/** + * Use this annotation on a getter method to override the Bean name + * parser for Bean -> JSONObject mapping. If this annotation is + * present at any level in the class hierarchy, then the method will + * not be serialized from the bean into the JSONObject. + */ +public @interface JSONPropertyIgnore { } diff --git a/src/main/java/org/json/JSONPropertyName.java b/src/main/java/org/json/JSONPropertyName.java new file mode 100644 index 0000000..a1bcd58 --- /dev/null +++ b/src/main/java/org/json/JSONPropertyName.java @@ -0,0 +1,47 @@ +package org.json; + +/* +Copyright (c) 2018 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Documented +@Retention(RUNTIME) +@Target({METHOD}) +/** + * Use this annotation on a getter method to override the Bean name + * parser for Bean -> JSONObject mapping. A value set to empty string "" + * will have the Bean parser fall back to the default field name processing. + */ +public @interface JSONPropertyName { + /** + * @return The name of the property as to be used in the JSON Object. + */ + String value(); +} diff --git a/src/main/java/org/json/JSONString.java b/src/main/java/org/json/JSONString.java new file mode 100644 index 0000000..bcd9a81 --- /dev/null +++ b/src/main/java/org/json/JSONString.java @@ -0,0 +1,43 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +/** + * The JSONString interface allows a toJSONString() + * method so that a class can change the behavior of + * JSONObject.toString(), JSONArray.toString(), + * and JSONWriter.value(Object). The + * toJSONString method will be used instead of the default behavior + * of using the Object's toString() method and quoting the result. + */ +public interface JSONString { + /** + * The toJSONString method allows a class to produce its own JSON + * serialization. + * + * @return A strictly syntactically correct JSON text. + */ + public String toJSONString(); +} diff --git a/src/main/java/org/json/JSONStringer.java b/src/main/java/org/json/JSONStringer.java new file mode 100644 index 0000000..d2a4dfb --- /dev/null +++ b/src/main/java/org/json/JSONStringer.java @@ -0,0 +1,79 @@ +package org.json; + +/* +Copyright (c) 2006 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.io.StringWriter; + +/** + * JSONStringer provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONStringer can produce one JSON text. + *

+ * A JSONStringer instance provides a value method for appending + * values to the + * text, and a key + * method for adding keys before values in objects. There are array + * and endArray methods that make and bound array values, and + * object and endObject methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting cascade style. For example,

+ * myString = new JSONStringer()
+ *     .object()
+ *         .key("JSON")
+ *         .value("Hello, World!")
+ *     .endObject()
+ *     .toString();
which produces the string
+ * {"JSON":"Hello, World!"}
+ *

+ * The first method called must be array or object. + * There are no methods for adding commas or colons. JSONStringer adds them for + * you. Objects and arrays can be nested up to 200 levels deep. + *

+ * This can sometimes be easier than using a JSONObject to build a string. + * @author JSON.org + * @version 2015-12-09 + */ +public class JSONStringer extends JSONWriter { + /** + * Make a fresh JSONStringer. It can be used to build one JSON text. + */ + public JSONStringer() { + super(new StringWriter()); + } + + /** + * Return the JSON text. This method is used to obtain the product of the + * JSONStringer instance. It will return null if there was a + * problem in the construction of the JSON text (such as the calls to + * array were not properly balanced with calls to + * endArray). + * @return The JSON text. + */ + @Override + public String toString() { + return this.mode == 'd' ? this.writer.toString() : null; + } +} diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java new file mode 100644 index 0000000..7f0c86a --- /dev/null +++ b/src/main/java/org/json/JSONTokener.java @@ -0,0 +1,545 @@ +package org.json; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +/** + * A JSONTokener takes a source string and extracts characters and tokens from + * it. It is used by the JSONObject and JSONArray constructors to parse + * JSON source strings. + * @author JSON.org + * @version 2014-05-03 + */ +public class JSONTokener { + /** current read character position on the current line. */ + private long character; + /** flag to indicate if the end of the input has been found. */ + private boolean eof; + /** current read index of the input. */ + private long index; + /** current line of the input. */ + private long line; + /** previous character read from the input. */ + private char previous; + /** Reader for the input. */ + private final Reader reader; + /** flag to indicate that a previous character was requested. */ + private boolean usePrevious; + /** the number of characters read in the previous line. */ + private long characterPreviousLine; + + + /** + * Construct a JSONTokener from a Reader. The caller must close the Reader. + * + * @param reader A reader. + */ + public JSONTokener(Reader reader) { + this.reader = reader.markSupported() + ? reader + : new BufferedReader(reader); + this.eof = false; + this.usePrevious = false; + this.previous = 0; + this.index = 0; + this.character = 1; + this.characterPreviousLine = 0; + this.line = 1; + } + + + /** + * Construct a JSONTokener from an InputStream. The caller must close the input stream. + * @param inputStream The source. + */ + public JSONTokener(InputStream inputStream) { + this(new InputStreamReader(inputStream)); + } + + + /** + * Construct a JSONTokener from a string. + * + * @param s A source string. + */ + public JSONTokener(String s) { + this(new StringReader(s)); + } + + + /** + * Back up one character. This provides a sort of lookahead capability, + * so that you can test for a digit or letter before attempting to parse + * the next number or identifier. + * @throws JSONException Thrown if trying to step back more than 1 step + * or if already at the start of the string + */ + public void back() throws JSONException { + if (this.usePrevious || this.index <= 0) { + throw new JSONException("Stepping back two steps is not supported"); + } + this.decrementIndexes(); + this.usePrevious = true; + this.eof = false; + } + + /** + * Decrements the indexes for the {@link #back()} method based on the previous character read. + */ + private void decrementIndexes() { + this.index--; + if(this.previous=='\r' || this.previous == '\n') { + this.line--; + this.character=this.characterPreviousLine ; + } else if(this.character > 0){ + this.character--; + } + } + + /** + * Get the hex value of a character (base16). + * @param c A character between '0' and '9' or between 'A' and 'F' or + * between 'a' and 'f'. + * @return An int between 0 and 15, or -1 if c was not a hex digit. + */ + public static int dehexchar(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'A' && c <= 'F') { + return c - ('A' - 10); + } + if (c >= 'a' && c <= 'f') { + return c - ('a' - 10); + } + return -1; + } + + /** + * Checks if the end of the input has been reached. + * + * @return true if at the end of the file and we didn't step back + */ + public boolean end() { + return this.eof && !this.usePrevious; + } + + + /** + * Determine if the source string still contains characters that next() + * can consume. + * @return true if not yet at the end of the source. + * @throws JSONException thrown if there is an error stepping forward + * or backward while checking for more data. + */ + public boolean more() throws JSONException { + if(this.usePrevious) { + return true; + } + try { + this.reader.mark(1); + } catch (IOException e) { + throw new JSONException("Unable to preserve stream position", e); + } + try { + // -1 is EOF, but next() can not consume the null character '\0' + if(this.reader.read() <= 0) { + this.eof = true; + return false; + } + this.reader.reset(); + } catch (IOException e) { + throw new JSONException("Unable to read the next character from the stream", e); + } + return true; + } + + + /** + * Get the next character in the source string. + * + * @return The next character, or 0 if past the end of the source string. + * @throws JSONException Thrown if there is an error reading the source string. + */ + public char next() throws JSONException { + int c; + if (this.usePrevious) { + this.usePrevious = false; + c = this.previous; + } else { + try { + c = this.reader.read(); + } catch (IOException exception) { + throw new JSONException(exception); + } + } + if (c <= 0) { // End of stream + this.eof = true; + return 0; + } + this.incrementIndexes(c); + this.previous = (char) c; + return this.previous; + } + + /** + * Get the last character read from the input or '\0' if nothing has been read yet. + * @return the last character read from the input. + */ + protected char getPrevious() { return this.previous;} + + /** + * Increments the internal indexes according to the previous character + * read and the character passed as the current character. + * @param c the current character read. + */ + private void incrementIndexes(int c) { + if(c > 0) { + this.index++; + if(c=='\r') { + this.line++; + this.characterPreviousLine = this.character; + this.character=0; + }else if (c=='\n') { + if(this.previous != '\r') { + this.line++; + this.characterPreviousLine = this.character; + } + this.character=0; + } else { + this.character++; + } + } + } + + /** + * Consume the next character, and check that it matches a specified + * character. + * @param c The character to match. + * @return The character. + * @throws JSONException if the character does not match. + */ + public char next(char c) throws JSONException { + char n = this.next(); + if (n != c) { + if(n > 0) { + throw this.syntaxError("Expected '" + c + "' and instead saw '" + + n + "'"); + } + throw this.syntaxError("Expected '" + c + "' and instead saw ''"); + } + return n; + } + + + /** + * Get the next n characters. + * + * @param n The number of characters to take. + * @return A string of n characters. + * @throws JSONException + * Substring bounds error if there are not + * n characters remaining in the source string. + */ + public String next(int n) throws JSONException { + if (n == 0) { + return ""; + } + + char[] chars = new char[n]; + int pos = 0; + + while (pos < n) { + chars[pos] = this.next(); + if (this.end()) { + throw this.syntaxError("Substring bounds error"); + } + pos += 1; + } + return new String(chars); + } + + + /** + * Get the next char in the string, skipping whitespace. + * @throws JSONException Thrown if there is an error reading the source string. + * @return A character, or 0 if there are no more characters. + */ + public char nextClean() throws JSONException { + for (;;) { + char c = this.next(); + if (c == 0 || c > ' ') { + return c; + } + } + } + + + /** + * Return the characters up to the next close quote character. + * Backslash processing is done. The formal JSON format does not + * allow strings in single quotes, but an implementation is allowed to + * accept them. + * @param quote The quoting character, either + * " (double quote) or + * ' (single quote). + * @return A String. + * @throws JSONException Unterminated string. + */ + public String nextString(char quote) throws JSONException { + char c; + StringBuilder sb = new StringBuilder(); + for (;;) { + c = this.next(); + switch (c) { + case 0: + case '\n': + case '\r': + throw this.syntaxError("Unterminated string"); + case '\\': + c = this.next(); + switch (c) { + case 'b': + sb.append('\b'); + break; + case 't': + sb.append('\t'); + break; + case 'n': + sb.append('\n'); + break; + case 'f': + sb.append('\f'); + break; + case 'r': + sb.append('\r'); + break; + case 'u': + try { + sb.append((char)Integer.parseInt(this.next(4), 16)); + } catch (NumberFormatException e) { + throw this.syntaxError("Illegal escape.", e); + } + break; + case '"': + case '\'': + case '\\': + case '/': + sb.append(c); + break; + default: + throw this.syntaxError("Illegal escape."); + } + break; + default: + if (c == quote) { + return sb.toString(); + } + sb.append(c); + } + } + } + + + /** + * Get the text up but not including the specified character or the + * end of line, whichever comes first. + * @param delimiter A delimiter character. + * @return A string. + * @throws JSONException Thrown if there is an error while searching + * for the delimiter + */ + public String nextTo(char delimiter) throws JSONException { + StringBuilder sb = new StringBuilder(); + for (;;) { + char c = this.next(); + if (c == delimiter || c == 0 || c == '\n' || c == '\r') { + if (c != 0) { + this.back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + + /** + * Get the text up but not including one of the specified delimiter + * characters or the end of line, whichever comes first. + * @param delimiters A set of delimiter characters. + * @return A string, trimmed. + * @throws JSONException Thrown if there is an error while searching + * for the delimiter + */ + public String nextTo(String delimiters) throws JSONException { + char c; + StringBuilder sb = new StringBuilder(); + for (;;) { + c = this.next(); + if (delimiters.indexOf(c) >= 0 || c == 0 || + c == '\n' || c == '\r') { + if (c != 0) { + this.back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + + /** + * Get the next value. The value can be a Boolean, Double, Integer, + * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. + * @throws JSONException If syntax error. + * + * @return An object. + */ + public Object nextValue() throws JSONException { + char c = this.nextClean(); + String string; + + switch (c) { + case '"': + case '\'': + return this.nextString(c); + case '{': + this.back(); + try { + return new JSONObject(this); + } catch (StackOverflowError e) { + throw new JSONException("JSON Array or Object depth too large to process.", e); + } + case '[': + this.back(); + try { + return new JSONArray(this); + } catch (StackOverflowError e) { + throw new JSONException("JSON Array or Object depth too large to process.", e); + } + } + + /* + * Handle unquoted text. This could be the values true, false, or + * null, or it can be a number. An implementation (such as this one) + * is allowed to also accept non-standard forms. + * + * Accumulate characters until we reach the end of the text or a + * formatting character. + */ + + StringBuilder sb = new StringBuilder(); + while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { + sb.append(c); + c = this.next(); + } + if (!this.eof) { + this.back(); + } + + string = sb.toString().trim(); + if ("".equals(string)) { + throw this.syntaxError("Missing value"); + } + return JSONObject.stringToValue(string); + } + + + /** + * Skip characters until the next character is the requested character. + * If the requested character is not found, no characters are skipped. + * @param to A character to skip to. + * @return The requested character, or zero if the requested character + * is not found. + * @throws JSONException Thrown if there is an error while searching + * for the to character + */ + public char skipTo(char to) throws JSONException { + char c; + try { + long startIndex = this.index; + long startCharacter = this.character; + long startLine = this.line; + this.reader.mark(1000000); + do { + c = this.next(); + if (c == 0) { + // in some readers, reset() may throw an exception if + // the remaining portion of the input is greater than + // the mark size (1,000,000 above). + this.reader.reset(); + this.index = startIndex; + this.character = startCharacter; + this.line = startLine; + return 0; + } + } while (c != to); + this.reader.mark(1); + } catch (IOException exception) { + throw new JSONException(exception); + } + this.back(); + return c; + } + + /** + * Make a JSONException to signal a syntax error. + * + * @param message The error message. + * @return A JSONException object, suitable for throwing + */ + public JSONException syntaxError(String message) { + return new JSONException(message + this.toString()); + } + + /** + * Make a JSONException to signal a syntax error. + * + * @param message The error message. + * @param causedBy The throwable that caused the error. + * @return A JSONException object, suitable for throwing + */ + public JSONException syntaxError(String message, Throwable causedBy) { + return new JSONException(message + this.toString(), causedBy); + } + + /** + * Make a printable string of this JSONTokener. + * + * @return " at {index} [character {character} line {line}]" + */ + @Override + public String toString() { + return " at " + this.index + " [character " + this.character + " line " + + this.line + "]"; + } +} diff --git a/src/main/java/org/json/JSONWriter.java b/src/main/java/org/json/JSONWriter.java new file mode 100644 index 0000000..dafb1b2 --- /dev/null +++ b/src/main/java/org/json/JSONWriter.java @@ -0,0 +1,414 @@ +package org.json; + +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +/* +Copyright (c) 2006 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * JSONWriter provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONWriter can produce one JSON text. + *

+ * A JSONWriter instance provides a value method for appending + * values to the + * text, and a key + * method for adding keys before values in objects. There are array + * and endArray methods that make and bound array values, and + * object and endObject methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting a cascade style. For example,

+ * new JSONWriter(myWriter)
+ *     .object()
+ *         .key("JSON")
+ *         .value("Hello, World!")
+ *     .endObject();
which writes
+ * {"JSON":"Hello, World!"}
+ *

+ * The first method called must be array or object. + * There are no methods for adding commas or colons. JSONWriter adds them for + * you. Objects and arrays can be nested up to 200 levels deep. + *

+ * This can sometimes be easier than using a JSONObject to build a string. + * @author JSON.org + * @version 2016-08-08 + */ +public class JSONWriter { + private static final int maxdepth = 200; + + /** + * The comma flag determines if a comma should be output before the next + * value. + */ + private boolean comma; + + /** + * The current mode. Values: + * 'a' (array), + * 'd' (done), + * 'i' (initial), + * 'k' (key), + * 'o' (object). + */ + protected char mode; + + /** + * The object/array stack. + */ + private final JSONObject stack[]; + + /** + * The stack top index. A value of 0 indicates that the stack is empty. + */ + private int top; + + /** + * The writer that will receive the output. + */ + protected Appendable writer; + + /** + * Make a fresh JSONWriter. It can be used to build one JSON text. + * @param w an appendable object + */ + public JSONWriter(Appendable w) { + this.comma = false; + this.mode = 'i'; + this.stack = new JSONObject[maxdepth]; + this.top = 0; + this.writer = w; + } + + /** + * Append a value. + * @param string A string value. + * @return this + * @throws JSONException If the value is out of sequence. + */ + private JSONWriter append(String string) throws JSONException { + if (string == null) { + throw new JSONException("Null pointer"); + } + if (this.mode == 'o' || this.mode == 'a') { + try { + if (this.comma && this.mode == 'a') { + this.writer.append(','); + } + this.writer.append(string); + } catch (IOException e) { + // Android as of API 25 does not support this exception constructor + // however we won't worry about it. If an exception is happening here + // it will just throw a "Method not found" exception instead. + throw new JSONException(e); + } + if (this.mode == 'o') { + this.mode = 'k'; + } + this.comma = true; + return this; + } + throw new JSONException("Value out of sequence."); + } + + /** + * Begin appending a new array. All values until the balancing + * endArray will be appended to this array. The + * endArray method must be called to mark the array's end. + * @return this + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter array() throws JSONException { + if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { + this.push(null); + this.append("["); + this.comma = false; + return this; + } + throw new JSONException("Misplaced array."); + } + + /** + * End something. + * @param m Mode + * @param c Closing character + * @return this + * @throws JSONException If unbalanced. + */ + private JSONWriter end(char m, char c) throws JSONException { + if (this.mode != m) { + throw new JSONException(m == 'a' + ? "Misplaced endArray." + : "Misplaced endObject."); + } + this.pop(m); + try { + this.writer.append(c); + } catch (IOException e) { + // Android as of API 25 does not support this exception constructor + // however we won't worry about it. If an exception is happening here + // it will just throw a "Method not found" exception instead. + throw new JSONException(e); + } + this.comma = true; + return this; + } + + /** + * End an array. This method most be called to balance calls to + * array. + * @return this + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endArray() throws JSONException { + return this.end('a', ']'); + } + + /** + * End an object. This method most be called to balance calls to + * object. + * @return this + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endObject() throws JSONException { + return this.end('k', '}'); + } + + /** + * Append a key. The key will be associated with the next value. In an + * object, every value must be preceded by a key. + * @param string A key string. + * @return this + * @throws JSONException If the key is out of place. For example, keys + * do not belong in arrays or if the key is null. + */ + public JSONWriter key(String string) throws JSONException { + if (string == null) { + throw new JSONException("Null key."); + } + if (this.mode == 'k') { + try { + JSONObject topObject = this.stack[this.top - 1]; + // don't use the built in putOnce method to maintain Android support + if(topObject.has(string)) { + throw new JSONException("Duplicate key \"" + string + "\""); + } + topObject.put(string, true); + if (this.comma) { + this.writer.append(','); + } + this.writer.append(JSONObject.quote(string)); + this.writer.append(':'); + this.comma = false; + this.mode = 'o'; + return this; + } catch (IOException e) { + // Android as of API 25 does not support this exception constructor + // however we won't worry about it. If an exception is happening here + // it will just throw a "Method not found" exception instead. + throw new JSONException(e); + } + } + throw new JSONException("Misplaced key."); + } + + + /** + * Begin appending a new object. All keys and values until the balancing + * endObject will be appended to this object. The + * endObject method must be called to mark the object's end. + * @return this + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter object() throws JSONException { + if (this.mode == 'i') { + this.mode = 'o'; + } + if (this.mode == 'o' || this.mode == 'a') { + this.append("{"); + this.push(new JSONObject()); + this.comma = false; + return this; + } + throw new JSONException("Misplaced object."); + + } + + + /** + * Pop an array or object scope. + * @param c The scope to close. + * @throws JSONException If nesting is wrong. + */ + private void pop(char c) throws JSONException { + if (this.top <= 0) { + throw new JSONException("Nesting error."); + } + char m = this.stack[this.top - 1] == null ? 'a' : 'k'; + if (m != c) { + throw new JSONException("Nesting error."); + } + this.top -= 1; + this.mode = this.top == 0 + ? 'd' + : this.stack[this.top - 1] == null + ? 'a' + : 'k'; + } + + /** + * Push an array or object scope. + * @param jo The scope to open. + * @throws JSONException If nesting is too deep. + */ + private void push(JSONObject jo) throws JSONException { + if (this.top >= maxdepth) { + throw new JSONException("Nesting too deep."); + } + this.stack[this.top] = jo; + this.mode = jo == null ? 'a' : 'k'; + this.top += 1; + } + + /** + * Make a JSON text of an Object value. If the object has an + * value.toJSONString() method, then that method will be used to produce the + * JSON text. The method is required to produce a strictly conforming text. + * If the object does not contain a toJSONString method (which is the most + * common case), then a text will be produced by other means. If the value + * is an array or Collection, then a JSONArray will be made from it and its + * toJSONString method will be called. If the value is a MAP, then a + * JSONObject will be made from it and its toJSONString method will be + * called. Otherwise, the value's toString method will be called, and the + * result will be quoted. + * + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @param value + * The value to be serialized. + * @return a printable, displayable, transmittable representation of the + * object, beginning with { (left + * brace) and ending with } (right + * brace). + * @throws JSONException + * If the value is or contains an invalid number. + */ + public static String valueToString(Object value) throws JSONException { + if (value == null || value.equals(null)) { + return "null"; + } + if (value instanceof JSONString) { + String object; + try { + object = ((JSONString) value).toJSONString(); + } catch (Exception e) { + throw new JSONException(e); + } + if (object != null) { + return object; + } + throw new JSONException("Bad value from toJSONString: " + object); + } + if (value instanceof Number) { + // not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex + final String numberAsString = JSONObject.numberToString((Number) value); + if(JSONObject.NUMBER_PATTERN.matcher(numberAsString).matches()) { + // Close enough to a JSON number that we will return it unquoted + return numberAsString; + } + // The Number value is not a valid JSON number. + // Instead we will quote it as a string + return JSONObject.quote(numberAsString); + } + if (value instanceof Boolean || value instanceof JSONObject + || value instanceof JSONArray) { + return value.toString(); + } + if (value instanceof Map) { + Map map = (Map) value; + return new JSONObject(map).toString(); + } + if (value instanceof Collection) { + Collection coll = (Collection) value; + return new JSONArray(coll).toString(); + } + if (value.getClass().isArray()) { + return new JSONArray(value).toString(); + } + if(value instanceof Enum){ + return JSONObject.quote(((Enum)value).name()); + } + return JSONObject.quote(value.toString()); + } + + /** + * Append either the value true or the value + * false. + * @param b A boolean. + * @return this + * @throws JSONException if a called function has an error + */ + public JSONWriter value(boolean b) throws JSONException { + return this.append(b ? "true" : "false"); + } + + /** + * Append a double value. + * @param d A double. + * @return this + * @throws JSONException If the number is not finite. + */ + public JSONWriter value(double d) throws JSONException { + return this.value(Double.valueOf(d)); + } + + /** + * Append a long value. + * @param l A long. + * @return this + * @throws JSONException if a called function has an error + */ + public JSONWriter value(long l) throws JSONException { + return this.append(Long.toString(l)); + } + + + /** + * Append an object value. + * @param object The object to append. It can be null, or a Boolean, Number, + * String, JSONObject, or JSONArray, or an object that implements JSONString. + * @return this + * @throws JSONException If the value is out of sequence. + */ + public JSONWriter value(Object object) throws JSONException { + return this.append(valueToString(object)); + } +} diff --git a/src/main/java/org/json/Property.java b/src/main/java/org/json/Property.java new file mode 100644 index 0000000..7caeebb --- /dev/null +++ b/src/main/java/org/json/Property.java @@ -0,0 +1,75 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Enumeration; +import java.util.Properties; + +/** + * Converts a Property file data into JSONObject and back. + * @author JSON.org + * @version 2015-05-05 + */ +public class Property { + /** + * Converts a property file object into a JSONObject. The property file object is a table of name value pairs. + * @param properties java.util.Properties + * @return JSONObject + * @throws JSONException if a called function has an error + */ + public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException { + // can't use the new constructor for Android support + // JSONObject jo = new JSONObject(properties == null ? 0 : properties.size()); + JSONObject jo = new JSONObject(); + if (properties != null && !properties.isEmpty()) { + Enumeration enumProperties = properties.propertyNames(); + while(enumProperties.hasMoreElements()) { + String name = (String)enumProperties.nextElement(); + jo.put(name, properties.getProperty(name)); + } + } + return jo; + } + + /** + * Converts the JSONObject into a property file object. + * @param jo JSONObject + * @return java.util.Properties + * @throws JSONException if a called function has an error + */ + public static Properties toProperties(JSONObject jo) throws JSONException { + Properties properties = new Properties(); + if (jo != null) { + // Don't use the new entrySet API to maintain Android support + for (final String key : jo.keySet()) { + Object value = jo.opt(key); + if (!JSONObject.NULL.equals(value)) { + properties.put(key, value.toString()); + } + } + } + return properties; + } +} diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java new file mode 100644 index 0000000..9b2ba89 --- /dev/null +++ b/src/main/java/org/json/XML.java @@ -0,0 +1,884 @@ +package org.json; + +/* +Copyright (c) 2015 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.io.Reader; +import java.io.StringReader; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Iterator; + + +/** + * This provides static methods to convert an XML text into a JSONObject, and to + * covert a JSONObject into an XML text. + * + * @author JSON.org + * @version 2016-08-10 + */ +@SuppressWarnings("boxing") +public class XML { + + /** The Character '&'. */ + public static final Character AMP = '&'; + + /** The Character '''. */ + public static final Character APOS = '\''; + + /** The Character '!'. */ + public static final Character BANG = '!'; + + /** The Character '='. */ + public static final Character EQ = '='; + + /** The Character

{@code '>'. }
*/ + public static final Character GT = '>'; + + /** The Character '<'. */ + public static final Character LT = '<'; + + /** The Character '?'. */ + public static final Character QUEST = '?'; + + /** The Character '"'. */ + public static final Character QUOT = '"'; + + /** The Character '/'. */ + public static final Character SLASH = '/'; + + /** + * Null attribute name + */ + public static final String NULL_ATTR = "xsi:nil"; + + public static final String TYPE_ATTR = "xsi:type"; + + /** + * Creates an iterator for navigating Code Points in a string instead of + * characters. Once Java7 support is dropped, this can be replaced with + * + * string.codePoints() + * + * which is available in Java8 and above. + * + * @see http://stackoverflow.com/a/21791059/6030888 + */ + private static Iterable codePointIterator(final String string) { + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + private int nextIndex = 0; + private int length = string.length(); + + @Override + public boolean hasNext() { + return this.nextIndex < this.length; + } + + @Override + public Integer next() { + int result = string.codePointAt(this.nextIndex); + this.nextIndex += Character.charCount(result); + return result; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + + /** + * Replace special characters with XML escapes: + * + *
{@code 
+     * & (ampersand) is replaced by &amp;
+     * < (less than) is replaced by &lt;
+     * > (greater than) is replaced by &gt;
+     * " (double quote) is replaced by &quot;
+     * ' (single quote / apostrophe) is replaced by &apos;
+     * }
+ * + * @param string + * The string to be escaped. + * @return The escaped string. + */ + public static String escape(String string) { + StringBuilder sb = new StringBuilder(string.length()); + for (final int cp : codePointIterator(string)) { + switch (cp) { + case '&': + sb.append("&"); + break; + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '"': + sb.append("""); + break; + case '\'': + sb.append("'"); + break; + default: + if (mustEscape(cp)) { + sb.append("&#x"); + sb.append(Integer.toHexString(cp)); + sb.append(';'); + } else { + sb.appendCodePoint(cp); + } + } + } + return sb.toString(); + } + + /** + * @param cp code point to test + * @return true if the code point is not valid for an XML + */ + private static boolean mustEscape(int cp) { + /* Valid range from https://www.w3.org/TR/REC-xml/#charsets + * + * #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + * + * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. + */ + // isISOControl is true when (cp >= 0 && cp <= 0x1F) || (cp >= 0x7F && cp <= 0x9F) + // all ISO control characters are out of range except tabs and new lines + return (Character.isISOControl(cp) + && cp != 0x9 + && cp != 0xA + && cp != 0xD + ) || !( + // valid the range of acceptable characters that aren't control + (cp >= 0x20 && cp <= 0xD7FF) + || (cp >= 0xE000 && cp <= 0xFFFD) + || (cp >= 0x10000 && cp <= 0x10FFFF) + ) + ; + } + + /** + * Removes XML escapes from the string. + * + * @param string + * string to remove escapes from + * @return string with converted entities + */ + public static String unescape(String string) { + StringBuilder sb = new StringBuilder(string.length()); + for (int i = 0, length = string.length(); i < length; i++) { + char c = string.charAt(i); + if (c == '&') { + final int semic = string.indexOf(';', i); + if (semic > i) { + final String entity = string.substring(i + 1, semic); + sb.append(XMLTokener.unescapeEntity(entity)); + // skip past the entity we just parsed. + i += entity.length() + 1; + } else { + // this shouldn't happen in most cases since the parser + // errors on unclosed entries. + sb.append(c); + } + } else { + // not part of an entity + sb.append(c); + } + } + return sb.toString(); + } + + /** + * Throw an exception if the string contains whitespace. Whitespace is not + * allowed in tagNames and attributes. + * + * @param string + * A string. + * @throws JSONException Thrown if the string contains whitespace or is empty. + */ + public static void noSpace(String string) throws JSONException { + int i, length = string.length(); + if (length == 0) { + throw new JSONException("Empty string."); + } + for (i = 0; i < length; i += 1) { + if (Character.isWhitespace(string.charAt(i))) { + throw new JSONException("'" + string + + "' contains a space character."); + } + } + } + + /** + * Scan the content following the named tag, attaching it to the context. + * + * @param x + * The XMLTokener containing the source string. + * @param context + * The JSONObject that will include the new material. + * @param name + * The tag name. + * @return true if the close tag is processed. + * @throws JSONException + */ + private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config) + throws JSONException { + char c; + int i; + JSONObject jsonObject = null; + String string; + String tagName; + Object token; + XMLXsiTypeConverter xmlXsiTypeConverter; + + // Test for and skip past these forms: + // + // + // + // + // Report errors for these forms: + // <> + // <= + // << + + token = x.nextToken(); + + // "); + return false; + } + x.back(); + } else if (c == '[') { + token = x.nextToken(); + if ("CDATA".equals(token)) { + if (x.next() == '[') { + string = x.nextCDATA(); + if (string.length() > 0) { + context.accumulate(config.getcDataTagName(), string); + } + return false; + } + } + throw x.syntaxError("Expected 'CDATA['"); + } + i = 1; + do { + token = x.nextMeta(); + if (token == null) { + throw x.syntaxError("Missing '>' after ' 0); + return false; + } else if (token == QUEST) { + + // "); + return false; + } else if (token == SLASH) { + + // Close tag + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped tag"); + } + if (config.getForceList().contains(tagName)) { + // Force the value to be an array + if (nilAttributeFound) { + context.append(tagName, JSONObject.NULL); + } else if (jsonObject.length() > 0) { + context.append(tagName, jsonObject); + } else { + context.put(tagName, new JSONArray()); + } + } else { + if (nilAttributeFound) { + context.accumulate(tagName, JSONObject.NULL); + } else if (jsonObject.length() > 0) { + context.accumulate(tagName, jsonObject); + } else { + context.accumulate(tagName, ""); + } + } + return false; + + } else if (token == GT) { + // Content, between <...> and + for (;;) { + token = x.nextContent(); + if (token == null) { + if (tagName != null) { + throw x.syntaxError("Unclosed tag " + tagName); + } + return false; + } else if (token instanceof String) { + string = (String) token; + if (string.length() > 0) { + if(xmlXsiTypeConverter != null) { + jsonObject.accumulate(config.getcDataTagName(), + stringToValue(string, xmlXsiTypeConverter)); + } else { + jsonObject.accumulate(config.getcDataTagName(), + config.isKeepStrings() ? string : stringToValue(string)); + } + } + + } else if (token == LT) { + // Nested element + if (parse(x, jsonObject, tagName, config)) { + if (config.getForceList().contains(tagName)) { + // Force the value to be an array + if (jsonObject.length() == 0) { + context.put(tagName, new JSONArray()); + } else if (jsonObject.length() == 1 + && jsonObject.opt(config.getcDataTagName()) != null) { + context.append(tagName, jsonObject.opt(config.getcDataTagName())); + } else { + context.append(tagName, jsonObject); + } + } else { + if (jsonObject.length() == 0) { + context.accumulate(tagName, ""); + } else if (jsonObject.length() == 1 + && jsonObject.opt(config.getcDataTagName()) != null) { + context.accumulate(tagName, jsonObject.opt(config.getcDataTagName())); + } else { + context.accumulate(tagName, jsonObject); + } + } + + return false; + } + } + } + } else { + throw x.syntaxError("Misshaped tag"); + } + } + } + } + + /** + * This method tries to convert the given string value to the target object + * @param string String to convert + * @param typeConverter value converter to convert string to integer, boolean e.t.c + * @return JSON value of this string or the string + */ + public static Object stringToValue(String string, XMLXsiTypeConverter typeConverter) { + if(typeConverter != null) { + return typeConverter.convert(string); + } + return stringToValue(string); + } + + /** + * This method is the same as {@link JSONObject#stringToValue(String)}. + * + * @param string String to convert + * @return JSON value of this string or the string + */ + // To maintain compatibility with the Android API, this method is a direct copy of + // the one in JSONObject. Changes made here should be reflected there. + // This method should not make calls out of the XML object. + public static Object stringToValue(String string) { + if ("".equals(string)) { + return string; + } + + // check JSON key words true/false/null + if ("true".equalsIgnoreCase(string)) { + return Boolean.TRUE; + } + if ("false".equalsIgnoreCase(string)) { + return Boolean.FALSE; + } + if ("null".equalsIgnoreCase(string)) { + return JSONObject.NULL; + } + + /* + * If it might be a number, try converting it. If a number cannot be + * produced, then the value will just be a string. + */ + + char initial = string.charAt(0); + if ((initial >= '0' && initial <= '9') || initial == '-') { + try { + return stringToNumber(string); + } catch (Exception ignore) { + } + } + return string; + } + + /** + * direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support. + */ + private static Number stringToNumber(final String val) throws NumberFormatException { + char initial = val.charAt(0); + if ((initial >= '0' && initial <= '9') || initial == '-') { + // decimal representation + if (isDecimalNotation(val)) { + // Use a BigDecimal all the time so we keep the original + // representation. BigDecimal doesn't support -0.0, ensure we + // keep that by forcing a decimal. + try { + BigDecimal bd = new BigDecimal(val); + if(initial == '-' && BigDecimal.ZERO.compareTo(bd)==0) { + return Double.valueOf(-0.0); + } + return bd; + } catch (NumberFormatException retryAsDouble) { + // this is to support "Hex Floats" like this: 0x1.0P-1074 + try { + Double d = Double.valueOf(val); + if(d.isNaN() || d.isInfinite()) { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + return d; + } catch (NumberFormatException ignore) { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + } + } + // block items like 00 01 etc. Java number parsers treat these as Octal. + if(initial == '0' && val.length() > 1) { + char at1 = val.charAt(1); + if(at1 >= '0' && at1 <= '9') { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + } else if (initial == '-' && val.length() > 2) { + char at1 = val.charAt(1); + char at2 = val.charAt(2); + if(at1 == '0' && at2 >= '0' && at2 <= '9') { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + } + // integer representation. + // This will narrow any values to the smallest reasonable Object representation + // (Integer, Long, or BigInteger) + + // BigInteger down conversion: We use a similar bitLength compare as + // BigInteger#intValueExact uses. Increases GC, but objects hold + // only what they need. i.e. Less runtime overhead if the value is + // long lived. + BigInteger bi = new BigInteger(val); + if(bi.bitLength() <= 31){ + return Integer.valueOf(bi.intValue()); + } + if(bi.bitLength() <= 63){ + return Long.valueOf(bi.longValue()); + } + return bi; + } + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + + /** + * direct copy of {@link JSONObject#isDecimalNotation(String)} to maintain Android support. + */ + private static boolean isDecimalNotation(final String val) { + return val.indexOf('.') > -1 || val.indexOf('e') > -1 + || val.indexOf('E') > -1 || "-0".equals(val); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * name/value pairs and arrays of values. JSON does not does not like to + * distinguish between elements and attributes. Sequences of similar + * elements are represented as JSONArrays. Content text may be placed in a + * "content" member. Comments, prologs, DTDs, and
{@code 
+     * <[ [ ]]>}
+ * are ignored. + * + * @param string + * The source string. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(String string) throws JSONException { + return toJSONObject(string, XMLParserConfiguration.ORIGINAL); + } + + /** + * Convert a well-formed (but not necessarily valid) XML into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * name/value pairs and arrays of values. JSON does not does not like to + * distinguish between elements and attributes. Sequences of similar + * elements are represented as JSONArrays. Content text may be placed in a + * "content" member. Comments, prologs, DTDs, and
{@code 
+     * <[ [ ]]>}
+ * are ignored. + * + * @param reader The XML source reader. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(Reader reader) throws JSONException { + return toJSONObject(reader, XMLParserConfiguration.ORIGINAL); + } + + /** + * Convert a well-formed (but not necessarily valid) XML into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * name/value pairs and arrays of values. JSON does not does not like to + * distinguish between elements and attributes. Sequences of similar + * elements are represented as JSONArrays. Content text may be placed in a + * "content" member. Comments, prologs, DTDs, and
{@code
+     * <[ [ ]]>}
+ * are ignored. + * + * All values are converted as strings, for 1, 01, 29.0 will not be coerced to + * numbers but will instead be the exact value as seen in the XML document. + * + * @param reader The XML source reader. + * @param keepStrings If true, then values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(Reader reader, boolean keepStrings) throws JSONException { + if(keepStrings) { + return toJSONObject(reader, XMLParserConfiguration.KEEP_STRINGS); + } + return toJSONObject(reader, XMLParserConfiguration.ORIGINAL); + } + + /** + * Convert a well-formed (but not necessarily valid) XML into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * name/value pairs and arrays of values. JSON does not does not like to + * distinguish between elements and attributes. Sequences of similar + * elements are represented as JSONArrays. Content text may be placed in a + * "content" member. Comments, prologs, DTDs, and
{@code
+     * <[ [ ]]>}
+ * are ignored. + * + * All values are converted as strings, for 1, 01, 29.0 will not be coerced to + * numbers but will instead be the exact value as seen in the XML document. + * + * @param reader The XML source reader. + * @param config Configuration options for the parser + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(Reader reader, XMLParserConfiguration config) throws JSONException { + JSONObject jo = new JSONObject(); + XMLTokener x = new XMLTokener(reader); + while (x.more()) { + x.skipPast("<"); + if(x.more()) { + parse(x, jo, null, config); + } + } + return jo; + } + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * name/value pairs and arrays of values. JSON does not does not like to + * distinguish between elements and attributes. Sequences of similar + * elements are represented as JSONArrays. Content text may be placed in a + * "content" member. Comments, prologs, DTDs, and
{@code 
+     * <[ [ ]]>}
+ * are ignored. + * + * All values are converted as strings, for 1, 01, 29.0 will not be coerced to + * numbers but will instead be the exact value as seen in the XML document. + * + * @param string + * The source string. + * @param keepStrings If true, then values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException { + return toJSONObject(new StringReader(string), keepStrings); + } + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * name/value pairs and arrays of values. JSON does not does not like to + * distinguish between elements and attributes. Sequences of similar + * elements are represented as JSONArrays. Content text may be placed in a + * "content" member. Comments, prologs, DTDs, and
{@code 
+     * <[ [ ]]>}
+ * are ignored. + * + * All values are converted as strings, for 1, 01, 29.0 will not be coerced to + * numbers but will instead be the exact value as seen in the XML document. + * + * @param string + * The source string. + * @param config Configuration options for the parser. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(String string, XMLParserConfiguration config) throws JSONException { + return toJSONObject(new StringReader(string), config); + } + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * + * @param object + * A JSONObject. + * @return A string. + * @throws JSONException Thrown if there is an error parsing the string + */ + public static String toString(Object object) throws JSONException { + return toString(object, null, XMLParserConfiguration.ORIGINAL); + } + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * + * @param object + * A JSONObject. + * @param tagName + * The optional name of the enclosing tag. + * @return A string. + * @throws JSONException Thrown if there is an error parsing the string + */ + public static String toString(final Object object, final String tagName) { + return toString(object, tagName, XMLParserConfiguration.ORIGINAL); + } + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * + * @param object + * A JSONObject. + * @param tagName + * The optional name of the enclosing tag. + * @param config + * Configuration that can control output to XML. + * @return A string. + * @throws JSONException Thrown if there is an error parsing the string + */ + public static String toString(final Object object, final String tagName, final XMLParserConfiguration config) + throws JSONException { + StringBuilder sb = new StringBuilder(); + JSONArray ja; + JSONObject jo; + String string; + + if (object instanceof JSONObject) { + + // Emit + if (tagName != null) { + sb.append('<'); + sb.append(tagName); + sb.append('>'); + } + + // Loop thru the keys. + // don't use the new entrySet accessor to maintain Android Support + jo = (JSONObject) object; + for (final String key : jo.keySet()) { + Object value = jo.opt(key); + if (value == null) { + value = ""; + } else if (value.getClass().isArray()) { + value = new JSONArray(value); + } + + // Emit content in body + if (key.equals(config.getcDataTagName())) { + if (value instanceof JSONArray) { + ja = (JSONArray) value; + int jaLength = ja.length(); + // don't use the new iterator API to maintain support for Android + for (int i = 0; i < jaLength; i++) { + if (i > 0) { + sb.append('\n'); + } + Object val = ja.opt(i); + sb.append(escape(val.toString())); + } + } else { + sb.append(escape(value.toString())); + } + + // Emit an array of similar keys + + } else if (value instanceof JSONArray) { + ja = (JSONArray) value; + int jaLength = ja.length(); + // don't use the new iterator API to maintain support for Android + for (int i = 0; i < jaLength; i++) { + Object val = ja.opt(i); + if (val instanceof JSONArray) { + sb.append('<'); + sb.append(key); + sb.append('>'); + sb.append(toString(val, null, config)); + sb.append("'); + } else { + sb.append(toString(val, key, config)); + } + } + } else if ("".equals(value)) { + sb.append('<'); + sb.append(key); + sb.append("/>"); + + // Emit a new tag + + } else { + sb.append(toString(value, key, config)); + } + } + if (tagName != null) { + + // Emit the close tag + sb.append("'); + } + return sb.toString(); + + } + + if (object != null && (object instanceof JSONArray || object.getClass().isArray())) { + if(object.getClass().isArray()) { + ja = new JSONArray(object); + } else { + ja = (JSONArray) object; + } + int jaLength = ja.length(); + // don't use the new iterator API to maintain support for Android + for (int i = 0; i < jaLength; i++) { + Object val = ja.opt(i); + // XML does not have good support for arrays. If an array + // appears in a place where XML is lacking, synthesize an + // element. + sb.append(toString(val, tagName == null ? "array" : tagName, config)); + } + return sb.toString(); + } + + string = (object == null) ? "null" : escape(object.toString()); + return (tagName == null) ? "\"" + string + "\"" + : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName + + ">" + string + ""; + + } +} diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java new file mode 100644 index 0000000..a1fd63e --- /dev/null +++ b/src/main/java/org/json/XMLParserConfiguration.java @@ -0,0 +1,320 @@ +package org.json; +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + + +/** + * Configuration object for the XML parser. The configuration is immutable. + * @author AylwardJ + */ +@SuppressWarnings({""}) +public class XMLParserConfiguration { + /** Original Configuration of the XML Parser. */ + public static final XMLParserConfiguration ORIGINAL + = new XMLParserConfiguration(); + /** Original configuration of the XML Parser except that values are kept as strings. */ + public static final XMLParserConfiguration KEEP_STRINGS + = new XMLParserConfiguration().withKeepStrings(true); + + /** + * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + */ + private boolean keepStrings; + + /** + * The name of the key in a JSON Object that indicates a CDATA section. Historically this has + * been the value "content" but can be changed. Use null to indicate no CDATA + * processing. + */ + private String cDataTagName; + + /** + * When parsing the XML into JSON, specifies if values with attribute xsi:nil="true" + * should be kept as attribute(false), or they should be converted to + * null(true) + */ + private boolean convertNilAttributeToNull; + + /** + * This will allow type conversion for values in XML if xsi:type attribute is defined + */ + private Map> xsiTypeMap; + + /** + * When parsing the XML into JSON, specifies the tags whose values should be converted + * to arrays + */ + private Set forceList; + + /** + * Default parser configuration. Does not keep strings (tries to implicitly convert + * values), and the CDATA Tag Name is "content". + */ + public XMLParserConfiguration () { + this.keepStrings = false; + this.cDataTagName = "content"; + this.convertNilAttributeToNull = false; + this.xsiTypeMap = Collections.emptyMap(); + this.forceList = Collections.emptySet(); + } + + /** + * Configure the parser string processing and use the default CDATA Tag Name as "content". + * @param keepStrings true to parse all values as string. + * false to try and convert XML string values into a JSON value. + * @deprecated This constructor has been deprecated in favor of using the new builder + * pattern for the configuration. + * This constructor may be removed in a future release. + */ + @Deprecated + public XMLParserConfiguration (final boolean keepStrings) { + this(keepStrings, "content", false); + } + + /** + * Configure the parser string processing to try and convert XML values to JSON values and + * use the passed CDATA Tag Name the processing value. Pass null to + * disable CDATA processing + * @param cDataTagName null to disable CDATA processing. Any other value + * to use that value as the JSONObject key name to process as CDATA. + * @deprecated This constructor has been deprecated in favor of using the new builder + * pattern for the configuration. + * This constructor may be removed in a future release. + */ + @Deprecated + public XMLParserConfiguration (final String cDataTagName) { + this(false, cDataTagName, false); + } + + /** + * Configure the parser to use custom settings. + * @param keepStrings true to parse all values as string. + * false to try and convert XML string values into a JSON value. + * @param cDataTagName null to disable CDATA processing. Any other value + * to use that value as the JSONObject key name to process as CDATA. + * @deprecated This constructor has been deprecated in favor of using the new builder + * pattern for the configuration. + * This constructor may be removed in a future release. + */ + @Deprecated + public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) { + this.keepStrings = keepStrings; + this.cDataTagName = cDataTagName; + this.convertNilAttributeToNull = false; + } + + /** + * Configure the parser to use custom settings. + * @param keepStrings true to parse all values as string. + * false to try and convert XML string values into a JSON value. + * @param cDataTagName null to disable CDATA processing. Any other value + * to use that value as the JSONObject key name to process as CDATA. + * @param convertNilAttributeToNull true to parse values with attribute xsi:nil="true" as null. + * false to parse values with attribute xsi:nil="true" as {"xsi:nil":true}. + * @deprecated This constructor has been deprecated in favor of using the new builder + * pattern for the configuration. + * This constructor may be removed or marked private in a future release. + */ + @Deprecated + public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) { + this.keepStrings = keepStrings; + this.cDataTagName = cDataTagName; + this.convertNilAttributeToNull = convertNilAttributeToNull; + } + + /** + * Configure the parser to use custom settings. + * @param keepStrings true to parse all values as string. + * false to try and convert XML string values into a JSON value. + * @param cDataTagName null to disable CDATA processing. Any other value + * to use that value as the JSONObject key name to process as CDATA. + * @param convertNilAttributeToNull true to parse values with attribute xsi:nil="true" as null. + * false to parse values with attribute xsi:nil="true" as {"xsi:nil":true}. + * @param xsiTypeMap new HashMap>() to parse values with attribute + * xsi:type="integer" as integer, xsi:type="string" as string + * @param forceList new HashSet() to parse the provided tags' values as arrays + */ + private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, + final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList ) { + this.keepStrings = keepStrings; + this.cDataTagName = cDataTagName; + this.convertNilAttributeToNull = convertNilAttributeToNull; + this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap); + this.forceList = Collections.unmodifiableSet(forceList); + } + + /** + * Provides a new instance of the same configuration. + */ + @Override + protected XMLParserConfiguration clone() { + // future modifications to this method should always ensure a "deep" + // clone in the case of collections. i.e. if a Map is added as a configuration + // item, a new map instance should be created and if possible each value in the + // map should be cloned as well. If the values of the map are known to also + // be immutable, then a shallow clone of the map is acceptable. + return new XMLParserConfiguration( + this.keepStrings, + this.cDataTagName, + this.convertNilAttributeToNull, + this.xsiTypeMap, + this.forceList + ); + } + + /** + * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + * + * @return The keepStrings configuration value. + */ + public boolean isKeepStrings() { + return this.keepStrings; + } + + /** + * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + * + * @param newVal + * new value to use for the keepStrings configuration option. + * + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLParserConfiguration withKeepStrings(final boolean newVal) { + XMLParserConfiguration newConfig = this.clone(); + newConfig.keepStrings = newVal; + return newConfig; + } + + /** + * The name of the key in a JSON Object that indicates a CDATA section. Historically this has + * been the value "content" but can be changed. Use null to indicate no CDATA + * processing. + * + * @return The cDataTagName configuration value. + */ + public String getcDataTagName() { + return this.cDataTagName; + } + + /** + * The name of the key in a JSON Object that indicates a CDATA section. Historically this has + * been the value "content" but can be changed. Use null to indicate no CDATA + * processing. + * + * @param newVal + * new value to use for the cDataTagName configuration option. + * + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLParserConfiguration withcDataTagName(final String newVal) { + XMLParserConfiguration newConfig = this.clone(); + newConfig.cDataTagName = newVal; + return newConfig; + } + + /** + * When parsing the XML into JSON, specifies if values with attribute xsi:nil="true" + * should be kept as attribute(false), or they should be converted to + * null(true) + * + * @return The convertNilAttributeToNull configuration value. + */ + public boolean isConvertNilAttributeToNull() { + return this.convertNilAttributeToNull; + } + + /** + * When parsing the XML into JSON, specifies if values with attribute xsi:nil="true" + * should be kept as attribute(false), or they should be converted to + * null(true) + * + * @param newVal + * new value to use for the convertNilAttributeToNull configuration option. + * + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLParserConfiguration withConvertNilAttributeToNull(final boolean newVal) { + XMLParserConfiguration newConfig = this.clone(); + newConfig.convertNilAttributeToNull = newVal; + return newConfig; + } + + /** + * When parsing the XML into JSON, specifies that the values with attribute xsi:type + * will be converted to target type defined to client in this configuration + * {@code Map>} to parse values with attribute + * xsi:type="integer" as integer, xsi:type="string" as string + * @return xsiTypeMap unmodifiable configuration map. + */ + public Map> getXsiTypeMap() { + return this.xsiTypeMap; + } + + /** + * When parsing the XML into JSON, specifies that the values with attribute xsi:type + * will be converted to target type defined to client in this configuration + * {@code Map>} to parse values with attribute + * xsi:type="integer" as integer, xsi:type="string" as string + * @param xsiTypeMap {@code new HashMap>()} to parse values with attribute + * xsi:type="integer" as integer, xsi:type="string" as string + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLParserConfiguration withXsiTypeMap(final Map> xsiTypeMap) { + XMLParserConfiguration newConfig = this.clone(); + Map> cloneXsiTypeMap = new HashMap>(xsiTypeMap); + newConfig.xsiTypeMap = Collections.unmodifiableMap(cloneXsiTypeMap); + return newConfig; + } + + /** + * When parsing the XML into JSON, specifies that tags that will be converted to arrays + * in this configuration {@code Set} to parse the provided tags' values as arrays + * @return forceList unmodifiable configuration set. + */ + public Set getForceList() { + return this.forceList; + } + + /** + * When parsing the XML into JSON, specifies that tags that will be converted to arrays + * in this configuration {@code Set} to parse the provided tags' values as arrays + * @param forceList {@code new HashSet()} to parse the provided tags' values as arrays + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLParserConfiguration withForceList(final Set forceList) { + XMLParserConfiguration newConfig = this.clone(); + Set cloneForceList = new HashSet(forceList); + newConfig.forceList = Collections.unmodifiableSet(cloneForceList); + return newConfig; + } +} diff --git a/src/main/java/org/json/XMLTokener.java b/src/main/java/org/json/XMLTokener.java new file mode 100644 index 0000000..3bbd382 --- /dev/null +++ b/src/main/java/org/json/XMLTokener.java @@ -0,0 +1,416 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.io.Reader; + +/** + * The XMLTokener extends the JSONTokener to provide additional methods + * for the parsing of XML texts. + * @author JSON.org + * @version 2015-12-09 + */ +public class XMLTokener extends JSONTokener { + + + /** The table of entity values. It initially contains Character values for + * amp, apos, gt, lt, quot. + */ + public static final java.util.HashMap entity; + + static { + entity = new java.util.HashMap(8); + entity.put("amp", XML.AMP); + entity.put("apos", XML.APOS); + entity.put("gt", XML.GT); + entity.put("lt", XML.LT); + entity.put("quot", XML.QUOT); + } + + /** + * Construct an XMLTokener from a Reader. + * @param r A source reader. + */ + public XMLTokener(Reader r) { + super(r); + } + + /** + * Construct an XMLTokener from a string. + * @param s A source string. + */ + public XMLTokener(String s) { + super(s); + } + + /** + * Get the text in the CDATA block. + * @return The string up to the ]]>. + * @throws JSONException If the ]]> is not found. + */ + public String nextCDATA() throws JSONException { + char c; + int i; + StringBuilder sb = new StringBuilder(); + while (more()) { + c = next(); + sb.append(c); + i = sb.length() - 3; + if (i >= 0 && sb.charAt(i) == ']' && + sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') { + sb.setLength(i); + return sb.toString(); + } + } + throw syntaxError("Unclosed CDATA"); + } + + + /** + * Get the next XML outer token, trimming whitespace. There are two kinds + * of tokens: the
{@code '<' }
character which begins a markup + * tag, and the content + * text between markup tags. + * + * @return A string, or a
{@code '<' }
Character, or null if + * there is no more source text. + * @throws JSONException if a called function has an error + */ + public Object nextContent() throws JSONException { + char c; + StringBuilder sb; + do { + c = next(); + } while (Character.isWhitespace(c)); + if (c == 0) { + return null; + } + if (c == '<') { + return XML.LT; + } + sb = new StringBuilder(); + for (;;) { + if (c == 0) { + return sb.toString().trim(); + } + if (c == '<') { + back(); + return sb.toString().trim(); + } + if (c == '&') { + sb.append(nextEntity(c)); + } else { + sb.append(c); + } + c = next(); + } + } + + + /** + *
{@code
+     * Return the next entity. These entities are translated to Characters:
+     *     &  '  >  <  ".
+     * }
+ * @param ampersand An ampersand character. + * @return A Character or an entity String if the entity is not recognized. + * @throws JSONException If missing ';' in XML entity. + */ + public Object nextEntity(@SuppressWarnings("unused") char ampersand) throws JSONException { + StringBuilder sb = new StringBuilder(); + for (;;) { + char c = next(); + if (Character.isLetterOrDigit(c) || c == '#') { + sb.append(Character.toLowerCase(c)); + } else if (c == ';') { + break; + } else { + throw syntaxError("Missing ';' in XML entity: &" + sb); + } + } + String string = sb.toString(); + return unescapeEntity(string); + } + + /** + * Unescape an XML entity encoding; + * @param e entity (only the actual entity value, not the preceding & or ending ; + * @return + */ + static String unescapeEntity(String e) { + // validate + if (e == null || e.isEmpty()) { + return ""; + } + // if our entity is an encoded unicode point, parse it. + if (e.charAt(0) == '#') { + int cp; + if (e.charAt(1) == 'x' || e.charAt(1) == 'X') { + // hex encoded unicode + cp = Integer.parseInt(e.substring(2), 16); + } else { + // decimal encoded unicode + cp = Integer.parseInt(e.substring(1)); + } + return new String(new int[] {cp},0,1); + } + Character knownEntity = entity.get(e); + if(knownEntity==null) { + // we don't know the entity so keep it encoded + return '&' + e + ';'; + } + return knownEntity.toString(); + } + + + /** + *
{@code 
+     * Returns the next XML meta token. This is used for skipping over 
+     * and  structures.
+     *  }
+ * @return
{@code Syntax characters (< > / = ! ?) are returned as
+     *  Character, and strings and names are returned as Boolean. We don't care
+     *  what the values actually are.
+     *  }
+ * @throws JSONException If a string is not properly closed or if the XML + * is badly structured. + */ + public Object nextMeta() throws JSONException { + char c; + char q; + do { + c = next(); + } while (Character.isWhitespace(c)); + switch (c) { + case 0: + throw syntaxError("Misshaped meta tag"); + case '<': + return XML.LT; + case '>': + return XML.GT; + case '/': + return XML.SLASH; + case '=': + return XML.EQ; + case '!': + return XML.BANG; + case '?': + return XML.QUEST; + case '"': + case '\'': + q = c; + for (;;) { + c = next(); + if (c == 0) { + throw syntaxError("Unterminated string"); + } + if (c == q) { + return Boolean.TRUE; + } + } + default: + for (;;) { + c = next(); + if (Character.isWhitespace(c)) { + return Boolean.TRUE; + } + switch (c) { + case 0: + throw syntaxError("Unterminated string"); + case '<': + case '>': + case '/': + case '=': + case '!': + case '?': + case '"': + case '\'': + back(); + return Boolean.TRUE; + } + } + } + } + + + /** + *
{@code
+     * Get the next XML Token. These tokens are found inside of angle
+     * brackets. It may be one of these characters: / > = ! ? or it
+     * may be a string wrapped in single quotes or double quotes, or it may be a
+     * name.
+     * }
+ * @return a String or a Character. + * @throws JSONException If the XML is not well formed. + */ + public Object nextToken() throws JSONException { + char c; + char q; + StringBuilder sb; + do { + c = next(); + } while (Character.isWhitespace(c)); + switch (c) { + case 0: + throw syntaxError("Misshaped element"); + case '<': + throw syntaxError("Misplaced '<'"); + case '>': + return XML.GT; + case '/': + return XML.SLASH; + case '=': + return XML.EQ; + case '!': + return XML.BANG; + case '?': + return XML.QUEST; + +// Quoted string + + case '"': + case '\'': + q = c; + sb = new StringBuilder(); + for (;;) { + c = next(); + if (c == 0) { + throw syntaxError("Unterminated string"); + } + if (c == q) { + return sb.toString(); + } + if (c == '&') { + sb.append(nextEntity(c)); + } else { + sb.append(c); + } + } + default: + +// Name + + sb = new StringBuilder(); + for (;;) { + sb.append(c); + c = next(); + if (Character.isWhitespace(c)) { + return sb.toString(); + } + switch (c) { + case 0: + return sb.toString(); + case '>': + case '/': + case '=': + case '!': + case '?': + case '[': + case ']': + back(); + return sb.toString(); + case '<': + case '"': + case '\'': + throw syntaxError("Bad character in a name"); + } + } + } + } + + + /** + * Skip characters until past the requested string. + * If it is not found, we are left at the end of the source with a result of false. + * @param to A string to skip past. + */ + // The Android implementation of JSONTokener has a public method of public void skipPast(String to) + // even though ours does not have that method, to have API compatibility, our method in the subclass + // should match. + public void skipPast(String to) { + boolean b; + char c; + int i; + int j; + int offset = 0; + int length = to.length(); + char[] circle = new char[length]; + + /* + * First fill the circle buffer with as many characters as are in the + * to string. If we reach an early end, bail. + */ + + for (i = 0; i < length; i += 1) { + c = next(); + if (c == 0) { + return; + } + circle[i] = c; + } + + /* We will loop, possibly for all of the remaining characters. */ + + for (;;) { + j = offset; + b = true; + + /* Compare the circle buffer with the to string. */ + + for (i = 0; i < length; i += 1) { + if (circle[j] != to.charAt(i)) { + b = false; + break; + } + j += 1; + if (j >= length) { + j -= length; + } + } + + /* If we exit the loop with b intact, then victory is ours. */ + + if (b) { + return; + } + + /* Get the next character. If there isn't one, then defeat is ours. */ + + c = next(); + if (c == 0) { + return; + } + /* + * Shove the character in the circle buffer and advance the + * circle offset. The offset is mod n. + */ + circle[offset] = c; + offset += 1; + if (offset >= length) { + offset -= length; + } + } + } +} diff --git a/src/main/java/org/json/XMLXsiTypeConverter.java b/src/main/java/org/json/XMLXsiTypeConverter.java new file mode 100644 index 0000000..0f8a8c3 --- /dev/null +++ b/src/main/java/org/json/XMLXsiTypeConverter.java @@ -0,0 +1,66 @@ +package org.json; +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * Type conversion configuration interface to be used with xsi:type attributes. + *
+ * XML Sample
+ * {@code
+ *      
+ *          12345
+ *          54321
+ *      
+ * }
+ * JSON Output
+ * {@code
+ *     {
+ *         "root" : {
+ *             "asString" : "12345",
+ *             "asInt": 54321
+ *         }
+ *     }
+ * }
+ *
+ * Usage
+ * {@code
+ *      Map> xsiTypeMap = new HashMap>();
+ *      xsiTypeMap.put("string", new XMLXsiTypeConverter() {
+ *          @Override public String convert(final String value) {
+ *              return value;
+ *          }
+ *      });
+ *      xsiTypeMap.put("integer", new XMLXsiTypeConverter() {
+ *          @Override public Integer convert(final String value) {
+ *              return Integer.valueOf(value);
+ *          }
+ *      });
+ * }
+ * 
+ * @author kumar529 + * @param return type of convert method + */ +public interface XMLXsiTypeConverter { + T convert(String value); +}