├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build.gradle ├── build.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mcp ├── fields.csv ├── joined.srg ├── methods.csv └── params.csv └── src ├── main ├── java │ └── alexiil │ │ └── mc │ │ └── mod │ │ └── load │ │ ├── CLSLog.java │ │ ├── ClsManager.java │ │ ├── ClsRandom.java │ │ ├── Config.java │ │ ├── ConfigGuiFactory.java │ │ ├── CustomLoadingScreen.java │ │ ├── Lib.java │ │ ├── ModLoadingListener.java │ │ ├── ProgressDisplayer.java │ │ ├── Tips.java │ │ ├── Translation.java │ │ ├── baked │ │ ├── BakedAction.java │ │ ├── BakedConfig.java │ │ ├── BakedConfigurable.java │ │ ├── BakedFactory.java │ │ ├── BakedRender.java │ │ ├── BakedRenderingPart.java │ │ ├── BakedTickable.java │ │ ├── BakedVariable.java │ │ ├── action │ │ │ └── ActionSound.java │ │ ├── factory │ │ │ └── BakedFactoryVariableChange.java │ │ ├── insn │ │ │ ├── BakedColourFunctional.java │ │ │ ├── BakedColourFunctionalTogether.java │ │ │ ├── BakedColourSimple.java │ │ │ ├── BakedInsn.java │ │ │ ├── BakedRotationFunctional.java │ │ │ ├── BakedRotationSimple.java │ │ │ ├── BakedScaleFunctional.java │ │ │ ├── BakedScaleSimple.java │ │ │ ├── BakedTranslateFunctional.java │ │ │ └── BakedTranslateSimple.java │ │ └── render │ │ │ ├── BakedAnimatedRender.java │ │ │ ├── BakedArea.java │ │ │ ├── BakedImageRender.java │ │ │ ├── BakedPanoramaRender.java │ │ │ ├── BakedRenderPositioned.java │ │ │ ├── BakedSlideshowRender.java │ │ │ ├── BakedTextRender.java │ │ │ ├── BakedTextRenderStatic.java │ │ │ └── BakedVideoRender.java │ │ ├── coremod │ │ ├── ClsPlugin.java │ │ └── ClsTransformer.java │ │ ├── frame │ │ ├── FrameDisplayer.java │ │ └── LoadingFrame.java │ │ ├── json │ │ ├── Area.java │ │ ├── ConfigManager.java │ │ ├── EPosition.java │ │ ├── InvalidSourceException.java │ │ ├── JsonAction.java │ │ ├── JsonConfig.java │ │ ├── JsonConfigLoader.java │ │ ├── JsonConfigurable.java │ │ ├── JsonFactory.java │ │ ├── JsonInsn.java │ │ ├── JsonRender.java │ │ ├── JsonRenderingPart.java │ │ ├── JsonVariable.java │ │ ├── ResourceWrappingInputStream.java │ │ ├── serial │ │ │ ├── ConfigDeserialiser.java │ │ │ ├── FactoryDeserialiser.java │ │ │ ├── IThrowingDeserialiser.java │ │ │ ├── ImageDeserialiser.java │ │ │ ├── InstructionDeserialiser.java │ │ │ ├── RenderingPartDeserialiser.java │ │ │ └── VariableArrayDeserialiser.java │ │ └── subtypes │ │ │ ├── JsonActionSound.java │ │ │ ├── JsonFactoryVariableChange.java │ │ │ ├── JsonRenderImage.java │ │ │ ├── JsonRenderPanorama.java │ │ │ ├── JsonRenderPositioned.java │ │ │ ├── JsonRenderSlideshow.java │ │ │ └── JsonRenderText.java │ │ ├── progress │ │ ├── LongTermProgressTracker.java │ │ ├── ProgressSectionInfo.java │ │ └── SingleProgressBarTracker.java │ │ └── render │ │ ├── ClsTexture.java │ │ ├── FontRendererSeparate.java │ │ ├── MainSplashRenderer.java │ │ ├── MinecraftDisplayer.java │ │ ├── MinecraftDisplayerRenderer.java │ │ ├── MinecraftDisplayerWrapper.java │ │ ├── OpenGlErrorUtil.java │ │ ├── RenderingStatus.java │ │ ├── TextureAnimator.java │ │ ├── TextureLoader.java │ │ └── TextureManagerCLS.java └── resources │ ├── assets │ └── customloadingscreen │ │ ├── lang │ │ ├── en_us.lang │ │ └── ru_ru.lang │ │ ├── sample │ │ ├── action │ │ │ └── sound_at_end.json │ │ ├── config │ │ │ ├── dark.json │ │ │ ├── default.json │ │ │ ├── forge_duplicate.json │ │ │ ├── generic_error.json │ │ │ ├── panorama_lower.json │ │ │ ├── rotating_cakes.json │ │ │ ├── scrolling.json │ │ │ ├── scrolling_detailed.json │ │ │ ├── slideshow.json │ │ │ ├── white.json │ │ │ └── worldload.json │ │ ├── function │ │ │ ├── interpolate.json │ │ │ └── item_rotation.json │ │ ├── image │ │ │ ├── block_4_wide.json │ │ │ ├── block_4_wide_percentage.json │ │ │ ├── block_cake_inner_4_wide.json │ │ │ ├── block_cake_side_4_wide.json │ │ │ ├── bottom_bar.json │ │ │ ├── cake.json │ │ │ ├── cake_bottom_left.json │ │ │ ├── cake_bottom_right.json │ │ │ ├── cake_top_left.json │ │ │ ├── cake_top_right.json │ │ │ ├── dirt_background.json │ │ │ ├── flat_background.json │ │ │ ├── horizontal_stripe.json │ │ │ ├── item.json │ │ │ ├── loading_bar_bevel.json │ │ │ ├── loading_bar_bevel_percentage.json │ │ │ ├── loading_bar_boss.json │ │ │ ├── loading_bar_boss_percentage.json │ │ │ ├── loading_bar_standard.json │ │ │ ├── loading_bar_standard_percentage.json │ │ │ ├── mojang_splash.json │ │ │ ├── mojang_splash_dark.json │ │ │ ├── panorama.json │ │ │ ├── text_generic_error.json │ │ │ ├── text_percentage.json │ │ │ ├── text_percentage_scrolling.json │ │ │ ├── text_percentage_white.json │ │ │ ├── text_status.json │ │ │ ├── text_status_white.json │ │ │ ├── text_sub_status.json │ │ │ └── text_sub_status_white.json │ │ ├── imagemeta │ │ │ ├── rotating_cake_bottom_left.json │ │ │ ├── rotating_cake_bottom_right.json │ │ │ ├── rotating_cake_top_left.json │ │ │ └── rotating_cake_top_right.json │ │ └── instruction │ │ │ ├── item_rotate_anti_clockwise.json │ │ │ └── item_rotate_clockwise.json │ │ └── textures │ │ ├── generic │ │ ├── darkened_blur.png │ │ ├── darkened_blur_horizontal_strip.png │ │ ├── darkened_blur_vertical_strip.png │ │ └── white.png │ │ ├── logo.png │ │ └── progress_bars.png │ ├── changelog │ ├── 1.4.0.txt │ ├── 1.4.1.txt │ ├── 1.5.1.txt │ ├── 1.5.3.txt │ ├── 1.5.4.txt │ ├── 1.5.5.txt │ ├── 1.5.6.txt │ └── 1.5.9.txt │ └── mcmod.info └── test └── java └── alexiil └── mods └── load └── test ├── BasicTestMod.java ├── TestModExporter.java ├── TestModHelper.java └── TestModVars.java /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | testing/ 3 | run/ 4 | .gradle/ 5 | .project 6 | .classpath 7 | .settings/ 8 | eclipse/ 9 | serverTest/ 10 | 11 | *.iml 12 | *.ipr 13 | *.iws 14 | out/ 15 | build/ 16 | VersionInfo/ 17 | custom/ 18 | 19 | *.launch 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | 5 | sudo: false 6 | addons: 7 | apt: 8 | packages: 9 | - oracle-java8-installer 10 | 11 | install: /bin/true 12 | script: ./setupWorkspace build 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CustomLoadingScreen 2 | 3 | ## Building from scratch 4 | Clone this repository into an empty folder 5 | 6 | git clone https://github.com/AlexIIL/CustomLoadingScreen.git 7 | cd CustomLoadingScreen 8 | 9 | If you are on linux, run: 10 | 11 | ./setupWorkspace build 12 | 13 | Otherwise you need to run: 14 | 15 | ./gradlew setupCIWorkspace 16 | ./gradlew build 17 | 18 | The build jar files will be in /build/libs. 19 | 20 | ## Contributing 21 | Fork this repository 22 | 23 | Clone the forked repository into an empty folder 24 | 25 | If you are on linux run 26 | 27 | ./setupWorkspace 28 | 29 | Otherwise you need to run 30 | 31 | ./gradlew setupDecompWorkspace 32 | 33 | If you use eclipse... 34 | 35 | ./gradlew eclipse 36 | 37 | If you use Idea... 38 | 39 | ./gradlew idea 40 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // DON'T TOUCH THE BUILDSCRIPT[] BLOCK 2 | // its special, and it is only there to make ForgeGradle work correctly. 3 | 4 | buildscript { 5 | repositories { 6 | mavenCentral() 7 | maven { 8 | name = "forge" 9 | url = "https://files.minecraftforge.net/maven" 10 | } 11 | maven { 12 | name = "sonatype" 13 | url = "https://oss.sonatype.org/content/repositories/snapshots/" 14 | } 15 | maven { 16 | url "https://plugins.gradle.org/m2/" 17 | } 18 | } 19 | dependencies { 20 | classpath "com.anatawa12.forge:ForgeGradle:2.3-1.0.+" 21 | } 22 | } 23 | 24 | apply plugin: "net.minecraftforge.gradle.forge" // adds the forge dependency 25 | apply plugin: 'maven' // for uploading to a maven repo 26 | 27 | // Feel free to rename this at some point 28 | group= "alexiil.mc.mod.load" 29 | archivesBaseName = "CustomLoadingScreen" 30 | 31 | sourceCompatibility = JavaVersion.VERSION_1_8 32 | targetCompatibility = JavaVersion.VERSION_1_8 33 | 34 | repositories { 35 | mavenLocal() 36 | maven { 37 | name = "BuildCraft" 38 | url = "https://mod-buildcraft.com/maven" 39 | } 40 | } 41 | 42 | configurations { 43 | shade 44 | compile.extendsFrom shade 45 | } 46 | 47 | dependencies { 48 | testCompile "junit:junit:4.12" 49 | shade "com.mod-buildcraft:buildcraft-libexpression:0.9.3-pre.4" 50 | } 51 | 52 | reobfJar { 53 | addExtraSrgLine("PK: buildcraft/lib/expression alexiil/mc/mod/load/repackage/buildcraft/lib/expression") 54 | } 55 | 56 | ext.configFile = file "build.properties" 57 | configFile.withReader { 58 | // Load config. It shall from now be referenced as simply config or project.config 59 | def prop = new Properties() 60 | prop.load(it) 61 | project.ext.config = new ConfigSlurper().parse prop 62 | } 63 | 64 | version = "${project.config.mc_version}-${project.config.mod_version}" 65 | 66 | minecraft { 67 | version = config.mc_version + "-" + config.forge_version 68 | runDir = "run" 69 | 70 | // the mappings can be changed at any time, and must be in the following format. 71 | // snapshot_YYYYMMDD snapshot are built nightly. 72 | // stable_# stables are built at the discretion of the MCP team. 73 | // Use non-default mappings at your own risk. they may not allways work. 74 | // simply re-run your setup task after changing the mappings to update your workspace. 75 | mappings = config.mcp_mappings 76 | 77 | replaceIn "alexiil/mods/load/Lib.java" 78 | replace "@VERSION@", "${project.config.mod_version}" 79 | replace "@COMMIT_HASH@", System.getenv("DRONE_COMMIT")?: "manual build" 80 | } 81 | 82 | processResources 83 | { 84 | // this will ensure that this task is redone when the versions change. 85 | inputs.property "version", project.version 86 | inputs.property "mcversion", project.minecraft.version 87 | 88 | // replace stuff in mcmod.info, nothing else 89 | from(sourceSets.main.resources.srcDirs) { 90 | include 'mcmod.info' 91 | 92 | // replace version and mcversion 93 | expand 'version':project.version, 'mcversion':project.minecraft.version 94 | } 95 | 96 | // copy everything else, thats not the mcmod.info 97 | from(sourceSets.main.resources.srcDirs) { 98 | exclude 'mcmod.info' 99 | } 100 | } 101 | 102 | sourceSets { 103 | main { 104 | java { 105 | srcDir "src/main/java" 106 | } 107 | resources { 108 | srcDir "src/main/resources" 109 | } 110 | } 111 | test { 112 | java { 113 | srcDir "src/test/java" 114 | } 115 | } 116 | } 117 | 118 | jar { 119 | configurations.shade.forEach { dep -> 120 | from(project.zipTree(dep)) { 121 | exclude "META-INF", "META-INF/**" 122 | } 123 | } 124 | manifest { 125 | attributes 'FMLCorePluginContainsFMLMod': 'true' 126 | attributes 'FMLCorePlugin': 'alexiil.mc.mod.load.coremod.ClsPlugin' 127 | } 128 | } 129 | 130 | /* 131 | String getSys(String env, String prop) { 132 | String p = System.getProperty(prop); 133 | if (p != null) { 134 | return p; 135 | } 136 | return System.getenv(env); 137 | } 138 | 139 | var comp = getSys("JAVA_COMPILER", "java_compiler"); 140 | 141 | if (comp != null) { 142 | compileJava.options.fork = true 143 | compileJava.options.forkOptions.executable = "$JAVA_COMPILER" 144 | } 145 | */ -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | mc_version=1.12.2 2 | forge_version=14.23.0.2544 3 | mcp_mappings=snapshot_20171120 4 | 5 | mod_version=1.5.10-qfix84.1 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Jul 02 15:54:47 CDT 2014 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/ClsRandom.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load; 2 | 3 | import java.security.SecureRandom; 4 | import java.util.Random; 5 | 6 | import buildcraft.lib.expression.FunctionContext; 7 | 8 | public final class ClsRandom { 9 | 10 | public static final FunctionContext CTX_RANDOM = new FunctionContext("Random numbers"); 11 | 12 | private static final Random RAND = new Random(); 13 | 14 | static { 15 | FunctionContext c = CTX_RANDOM; 16 | SecureRandom srand = new SecureRandom(); 17 | 18 | c.put_l("generate_seed", () -> { 19 | synchronized (srand) { 20 | return srand.nextLong(); 21 | } 22 | }); 23 | 24 | c.put_l_d("random", (seed) -> random(seed, 0)); 25 | c.put_ll_d("random", (seed, index) -> random(seed, index)); 26 | c.put_ll_l("random_int", (seed, max) -> randomInt(seed, 0, max)); 27 | c.put_lll_l("random_int", (seed, index, max) -> randomInt(seed, index, max)); 28 | } 29 | 30 | private static double random(long seed, long index) { 31 | // No reason not to sync as setSeed is synchronized 32 | synchronized (RAND) { 33 | RAND.setSeed(seed ^ ((index & 0xFF_FF_FF_FF) << 16)); 34 | return RAND.nextDouble(); 35 | } 36 | } 37 | 38 | private static long randomInt(long seed, long index, long max) { 39 | if (max <= 1) { 40 | return 0; 41 | } 42 | return Math.min(max - 1, (int) (random(seed, index) * max)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/Config.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import net.minecraft.client.gui.GuiScreen; 7 | 8 | import net.minecraftforge.common.config.ConfigCategory; 9 | import net.minecraftforge.common.config.ConfigElement; 10 | import net.minecraftforge.common.config.Configuration; 11 | import net.minecraftforge.fml.client.config.GuiConfig; 12 | import net.minecraftforge.fml.client.config.IConfigElement; 13 | 14 | public class Config extends GuiConfig { 15 | public Config(GuiScreen screen) { 16 | super(screen, getConfigElements(), Lib.Mod.ID, false, false, "CustomLoadingScreen"); 17 | } 18 | 19 | private static List getConfigElements() { 20 | List elements = new ArrayList<>(); 21 | Configuration cfg = CustomLoadingScreen.CONFIG; 22 | for (String name : cfg.getCategoryNames()) { 23 | ConfigCategory cat = cfg.getCategory(name); 24 | if (!cat.isChild()) elements.add(new ConfigElement(cfg.getCategory(name))); 25 | } 26 | return elements; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/ConfigGuiFactory.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load; 2 | 3 | import java.util.Set; 4 | 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiScreen; 7 | 8 | import net.minecraftforge.fml.client.IModGuiFactory; 9 | 10 | public class ConfigGuiFactory implements IModGuiFactory { 11 | @Override 12 | public void initialize(Minecraft minecraftInstance) {} 13 | 14 | @Override 15 | public Set runtimeGuiCategories() { 16 | return null; 17 | } 18 | 19 | @Override 20 | public boolean hasConfigGui() { 21 | return true; 22 | } 23 | 24 | @Override 25 | public GuiScreen createConfigGui(GuiScreen parentScreen) { 26 | return new Config(parentScreen); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/Lib.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load; 2 | 3 | public class Lib { 4 | public static class Mod { 5 | public static final String ID = "customloadingscreen"; 6 | public static final String NAME = "Custom Loading Screen"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedAction.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 6 | 7 | public abstract class BakedAction extends BakedTickable { 8 | protected final INodeBoolean conditionStart, conditionEnd; 9 | private boolean started = false; 10 | 11 | public BakedAction(INodeBoolean conditionStart, INodeBoolean conditionEnd) { 12 | this.conditionStart = conditionStart; 13 | this.conditionEnd = conditionEnd; 14 | } 15 | 16 | @Override 17 | public void tick(MinecraftDisplayerRenderer renderer) { 18 | if (!started && conditionStart.evaluate()) { 19 | started = true; 20 | start(); 21 | } else if (started) { 22 | tick(); 23 | } 24 | if (started && conditionEnd.evaluate()) { 25 | started = false; 26 | end(); 27 | } 28 | } 29 | 30 | /** Called the first time conditionStart resolves to true */ 31 | protected abstract void start(); 32 | 33 | /** Called once per tick after start() has been called, and before stop() has been called */ 34 | protected abstract void tick(); 35 | 36 | /** Called whenever conditionEnd resolves to true, provided that start() has already been called */ 37 | protected abstract void end(); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedConfig.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | public class BakedConfig extends BakedTickable { 6 | public final BakedVariable[] variables; 7 | public final BakedRenderingPart[] renderingParts; 8 | public final BakedAction[] actions; 9 | public final BakedFactory[] factories; 10 | 11 | public BakedConfig(BakedVariable[] vars, BakedRenderingPart[] renderingParts, BakedAction[] actions, BakedFactory[] factories) { 12 | this.variables = vars; 13 | this.renderingParts = renderingParts; 14 | this.actions = actions; 15 | this.factories = factories; 16 | } 17 | 18 | @Override 19 | public void tick(MinecraftDisplayerRenderer renderer) { 20 | // NO-OP 21 | // This is handled specially by MinecraftDisplayerRenderer 22 | } 23 | 24 | @Override 25 | public void preLoad(MinecraftDisplayerRenderer renderer) { 26 | super.preLoad(renderer); 27 | 28 | for (BakedRenderingPart part : renderingParts) { 29 | part.preLoad(renderer); 30 | } 31 | 32 | for (BakedFactory factory : factories) { 33 | factory.preLoad(renderer); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedConfigurable.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | 5 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 6 | 7 | public abstract class BakedConfigurable { 8 | private ResourceLocation origin = null; 9 | private String rawText; 10 | 11 | public ResourceLocation getOrigin() { 12 | return origin; 13 | } 14 | 15 | public String getRawText() { 16 | return rawText; 17 | } 18 | 19 | public final void setOrigin(ResourceLocation location, String src) { 20 | if (location != null) origin = location; 21 | if (src != null) rawText = src; 22 | } 23 | 24 | protected void throwError(Throwable cause) throws Error { 25 | throw reportError(cause); 26 | } 27 | 28 | protected Error reportError(Throwable cause) { 29 | if (cause == null) { 30 | throw new Error(origin + " failed, but did not provide a cause!\n" + rawText); 31 | } 32 | return new Error(origin + " failed!\n" + rawText, cause); 33 | } 34 | 35 | public void preLoad(MinecraftDisplayerRenderer renderer) { 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedFactory.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import java.util.Iterator; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 8 | 9 | import buildcraft.lib.expression.node.value.NodeVariableLong; 10 | 11 | public abstract class BakedFactory extends BakedTickable { 12 | public final NodeVariableLong factoryIndex, factoryCount; 13 | public final BakedRenderingPart[] component; 14 | 15 | public final List elements = new LinkedList<>(); 16 | protected int createdCount = 0; 17 | 18 | public BakedFactory(NodeVariableLong factoryIndex, NodeVariableLong factoryCount, BakedRenderingPart[] component) { 19 | this.factoryIndex = factoryIndex; 20 | this.factoryCount = factoryCount; 21 | this.component = component; 22 | } 23 | 24 | @Override 25 | public void tick(MinecraftDisplayerRenderer renderer) { 26 | Iterator iter = elements.iterator(); 27 | while (iter.hasNext()) { 28 | FactoryElement elem = iter.next(); 29 | if (!elem.tick(renderer)) { 30 | iter.remove(); 31 | } 32 | } 33 | } 34 | 35 | public class FactoryElement { 36 | public final int elementIndex = createdCount++; 37 | 38 | protected void setVariables(MinecraftDisplayerRenderer renderer) { 39 | factoryIndex.value = elementIndex; 40 | factoryCount.value = createdCount; 41 | } 42 | 43 | public boolean tick(MinecraftDisplayerRenderer renderer) { 44 | setVariables(renderer); 45 | for (BakedRenderingPart part : component) { 46 | part.tick(renderer); 47 | } 48 | return true; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | public abstract class BakedRender extends BakedTickable { 6 | public abstract void evaluateVariables(MinecraftDisplayerRenderer renderer); 7 | 8 | public abstract void render(MinecraftDisplayerRenderer renderer); 9 | 10 | @Override 11 | public void tick(MinecraftDisplayerRenderer renderer) { 12 | render(renderer); 13 | } 14 | 15 | public abstract String getLocation(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedRenderingPart.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import alexiil.mc.mod.load.baked.insn.BakedInsn; 6 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 7 | 8 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 9 | 10 | public class BakedRenderingPart extends BakedTickable { 11 | public final BakedInsn[] instructions; 12 | public final BakedRender render; 13 | public final INodeBoolean shouldRender; 14 | 15 | public BakedRenderingPart(BakedInsn[] instructions, BakedRender render, INodeBoolean shouldRender) { 16 | this.instructions = instructions; 17 | this.render = render; 18 | if (render == null) throw new NullPointerException("render"); 19 | this.shouldRender = shouldRender; 20 | } 21 | 22 | public void render(MinecraftDisplayerRenderer renderer) { 23 | GL11.glPushMatrix(); 24 | GL11.glMatrixMode(GL11.GL_PROJECTION); 25 | GL11.glPushMatrix(); 26 | GL11.glMatrixMode(GL11.GL_MODELVIEW); 27 | render.evaluateVariables(renderer); 28 | for (BakedInsn insn : instructions) { 29 | insn.render(); 30 | } 31 | render.render(renderer); 32 | GL11.glPopMatrix(); 33 | GL11.glMatrixMode(GL11.GL_PROJECTION); 34 | GL11.glPopMatrix(); 35 | GL11.glMatrixMode(GL11.GL_MODELVIEW); 36 | } 37 | 38 | @Override 39 | public void tick(MinecraftDisplayerRenderer renderer) { 40 | if (shouldRender.evaluate()) { 41 | render(renderer); 42 | } 43 | } 44 | 45 | @Override 46 | public void preLoad(MinecraftDisplayerRenderer renderer) { 47 | super.preLoad(renderer); 48 | 49 | for (BakedInsn insn : instructions) { 50 | insn.preLoad(renderer); 51 | } 52 | 53 | render.preLoad(renderer); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedTickable.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | public abstract class BakedTickable extends BakedConfigurable { 6 | public abstract void tick(MinecraftDisplayerRenderer renderer); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/BakedVariable.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode; 6 | import buildcraft.lib.expression.api.IVariableNode; 7 | import buildcraft.lib.expression.api.NodeTypes; 8 | 9 | public class BakedVariable extends BakedTickable { 10 | private final boolean constant; 11 | private final IVariableNode varNode; 12 | private final IExpressionNode expNode; 13 | 14 | public BakedVariable(boolean constant, IVariableNode varNode, IExpressionNode expNode) { 15 | this.constant = constant; 16 | this.varNode = varNode; 17 | this.expNode = expNode; 18 | } 19 | 20 | @Override 21 | public void tick(MinecraftDisplayerRenderer renderer) { 22 | if (!constant) { 23 | varNode.set(expNode); 24 | } 25 | } 26 | 27 | public BakedVariable copyAsConstant() { 28 | return new BakedVariable(false, varNode, NodeTypes.createConstantNode(expNode)); 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return "" + expNode; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/action/ActionSound.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.action; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.audio.ISound; 5 | import net.minecraft.client.audio.SoundHandler; 6 | import net.minecraft.util.ResourceLocation; 7 | 8 | import alexiil.mc.mod.load.baked.BakedAction; 9 | 10 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 11 | import buildcraft.lib.expression.api.IExpressionNode.INodeObject; 12 | 13 | public class ActionSound extends BakedAction { 14 | public static final SoundHandler sndHandler = Minecraft.getMinecraft().getSoundHandler(); 15 | public final INodeObject sound; 16 | public final INodeBoolean repeat; 17 | private ISound currentSound = null; 18 | 19 | public ActionSound(INodeBoolean conditionStart, INodeBoolean conditionEnd, INodeObject sound, INodeBoolean repeat) { 20 | super(conditionStart, conditionEnd); 21 | this.sound = sound; 22 | this.repeat = repeat; 23 | } 24 | 25 | @Override 26 | protected void start() { 27 | ResourceLocation soundLocation = new ResourceLocation(sound.evaluate()); 28 | // currentSound = PositionedSoundRecord.create(soundLocation); 29 | // sndHandler.playSound(currentSound); 30 | // TODO finish action sound! 31 | } 32 | 33 | @Override 34 | protected void tick() { 35 | if ((!sndHandler.isSoundPlaying(currentSound)) && repeat.evaluate() && !conditionEnd.evaluate()) { 36 | sndHandler.playSound(currentSound); 37 | } 38 | } 39 | 40 | @Override 41 | protected void end() {} 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/factory/BakedFactoryVariableChange.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.factory; 2 | 3 | import alexiil.mc.mod.load.baked.BakedFactory; 4 | import alexiil.mc.mod.load.baked.BakedRenderingPart; 5 | import alexiil.mc.mod.load.baked.BakedVariable; 6 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 7 | 8 | import buildcraft.lib.expression.FunctionContext; 9 | import buildcraft.lib.expression.GenericExpressionCompiler; 10 | import buildcraft.lib.expression.api.IExpressionNode; 11 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 12 | import buildcraft.lib.expression.api.IVariableNode; 13 | import buildcraft.lib.expression.api.InvalidExpressionException; 14 | import buildcraft.lib.expression.api.NodeTypes; 15 | import buildcraft.lib.expression.node.value.NodeVariableLong; 16 | 17 | public class BakedFactoryVariableChange extends BakedFactory { 18 | private final INodeBoolean shouldDestroy; 19 | private final IExpressionNode node; 20 | private final IVariableNode checkNode; 21 | private final BakedVariable[] variables, keptVariables; 22 | private final INodeBoolean hasChanged; 23 | private boolean hasAddedFirst; 24 | 25 | public BakedFactoryVariableChange(NodeVariableLong factoryIndex, NodeVariableLong factoryCount, 26 | BakedRenderingPart[] component, BakedVariable[] variables, BakedVariable[] keptVariables, 27 | INodeBoolean shouldDestroy, IExpressionNode node, boolean shouldSpawnFirst) throws InvalidExpressionException { 28 | 29 | super(factoryIndex, factoryCount, component); 30 | this.hasAddedFirst = !shouldSpawnFirst; 31 | this.variables = variables; 32 | this.keptVariables = keptVariables; 33 | this.shouldDestroy = shouldDestroy; 34 | this.node = node; 35 | this.checkNode = NodeTypes.makeVariableNode(NodeTypes.getType(node), "check"); 36 | FunctionContext ctx = new FunctionContext("not_equal"); 37 | ctx.putVariable("a", node); 38 | ctx.putVariable("b", checkNode); 39 | hasChanged = GenericExpressionCompiler.compileExpressionBoolean("a != b", ctx); 40 | } 41 | 42 | @Override 43 | public void tick(MinecraftDisplayerRenderer renderer) { 44 | if (!hasAddedFirst || hasChanged.evaluate()) { 45 | hasAddedFirst = true; 46 | checkNode.set(node); 47 | elements.add(new ElementVarChange(keptVariables)); 48 | } 49 | super.tick(renderer); 50 | } 51 | 52 | public class ElementVarChange extends FactoryElement { 53 | private final BakedVariable[] _keptVariables; 54 | 55 | public ElementVarChange(BakedVariable[] keptVariables) { 56 | _keptVariables = new BakedVariable[keptVariables.length]; 57 | for (int i = 0; i < keptVariables.length; i++) { 58 | BakedVariable v = keptVariables[i]; 59 | _keptVariables[i] = v.copyAsConstant(); 60 | } 61 | } 62 | 63 | @Override 64 | protected void setVariables(MinecraftDisplayerRenderer renderer) { 65 | super.setVariables(renderer); 66 | for (BakedVariable v : _keptVariables) { 67 | v.tick(renderer); 68 | } 69 | for (BakedVariable v : variables) { 70 | v.tick(renderer); 71 | } 72 | } 73 | 74 | @Override 75 | public boolean tick(MinecraftDisplayerRenderer renderer) { 76 | super.tick(renderer); 77 | return !shouldDestroy.evaluate(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedColourFunctional.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 6 | 7 | public class BakedColourFunctional extends BakedInsn { 8 | private final INodeDouble a, r, g, b; 9 | 10 | public BakedColourFunctional(INodeDouble a, INodeDouble r, INodeDouble g, INodeDouble b) { 11 | this.a = a; 12 | this.r = r; 13 | this.g = g; 14 | this.b = b; 15 | } 16 | 17 | @Override 18 | public void render() { 19 | GL11.glColor4d(r.evaluate(), g.evaluate(), b.evaluate(), a.evaluate()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedColourFunctionalTogether.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 6 | 7 | public class BakedColourFunctionalTogether extends BakedInsn { 8 | private final INodeLong argb; 9 | 10 | public BakedColourFunctionalTogether(INodeLong argb) { 11 | this.argb = argb; 12 | } 13 | 14 | @Override 15 | public void render() { 16 | long value = argb.evaluate(); 17 | float a = ((value >> 24) & 0xFF) / 255f; 18 | float r = ((value >> 16) & 0xFF) / 255f; 19 | float g = ((value >> 8) & 0xFF) / 255f; 20 | float b = (value & 0xFF) / 255f; 21 | GL11.glColor4f(r, g, b, a); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedColourSimple.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | public class BakedColourSimple extends BakedInsn { 6 | private final float a, r, g, b; 7 | 8 | public BakedColourSimple(float a, float r, float g, float b) { 9 | this.a = a; 10 | this.r = r; 11 | this.g = g; 12 | this.b = b; 13 | } 14 | 15 | @Override 16 | public void render() { 17 | GL11.glColor4f(r, g, b, a); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedInsn.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import alexiil.mc.mod.load.baked.BakedTickable; 4 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 5 | 6 | public abstract class BakedInsn extends BakedTickable { 7 | public abstract void render(); 8 | 9 | @Override 10 | public void tick(MinecraftDisplayerRenderer renderer) { 11 | render(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedRotationFunctional.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 6 | 7 | public class BakedRotationFunctional extends BakedInsn { 8 | private final INodeDouble angle, x, y, z; 9 | 10 | public BakedRotationFunctional(INodeDouble angle, INodeDouble x, INodeDouble y, INodeDouble z) { 11 | this.angle = angle; 12 | this.x = x; 13 | this.y = y; 14 | this.z = z; 15 | } 16 | 17 | @Override 18 | public void render() { 19 | double angle = this.angle.evaluate(); 20 | double x = this.x.evaluate(); 21 | double y = this.y.evaluate(); 22 | double z = this.z.evaluate(); 23 | GL11.glRotated(angle, x, y, z); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedRotationSimple.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | public class BakedRotationSimple extends BakedInsn { 6 | private final double angle, x, y, z; 7 | 8 | public BakedRotationSimple(double angle, double x, double y, double z) { 9 | this.angle = angle; 10 | this.x = x; 11 | this.y = y; 12 | this.z = z; 13 | } 14 | 15 | @Override 16 | public void render() { 17 | GL11.glRotated(angle, x, y, z); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedScaleFunctional.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 6 | 7 | public class BakedScaleFunctional extends BakedInsn { 8 | private final INodeDouble x, y, z; 9 | 10 | public BakedScaleFunctional(INodeDouble x, INodeDouble y, INodeDouble z) { 11 | this.x = x; 12 | this.y = y; 13 | this.z = z; 14 | } 15 | 16 | @Override 17 | public void render() { 18 | GL11.glScaled(x.evaluate(), y.evaluate(), z.evaluate()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedScaleSimple.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | public class BakedScaleSimple extends BakedInsn { 6 | private final double x, y, z; 7 | 8 | public BakedScaleSimple(double x, double y, double z) { 9 | this.x = x; 10 | this.y = y; 11 | this.z = z; 12 | } 13 | 14 | @Override 15 | public void render() { 16 | GL11.glScaled(x, y, z); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedTranslateFunctional.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import buildcraft.lib.expression.FunctionContext; 6 | import buildcraft.lib.expression.GenericExpressionCompiler; 7 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 8 | import buildcraft.lib.expression.api.InvalidExpressionException; 9 | import buildcraft.lib.expression.node.value.NodeConstantDouble; 10 | 11 | public class BakedTranslateFunctional extends BakedInsn { 12 | private final INodeDouble x, y, z; 13 | 14 | public static BakedTranslateFunctional bake(String x, String y, FunctionContext functions) throws InvalidExpressionException { 15 | INodeDouble expX = GenericExpressionCompiler.compileExpressionDouble(x, functions); 16 | INodeDouble expY = GenericExpressionCompiler.compileExpressionDouble(y, functions); 17 | return new BakedTranslateFunctional(expX, expY, NodeConstantDouble.ZERO); 18 | } 19 | 20 | public BakedTranslateFunctional(INodeDouble x, INodeDouble y, INodeDouble z) { 21 | this.x = x; 22 | this.y = y; 23 | this.z = z; 24 | } 25 | 26 | @Override 27 | public void render() { 28 | GL11.glTranslated(x.evaluate(), y.evaluate(), z.evaluate()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/insn/BakedTranslateSimple.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.insn; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | public class BakedTranslateSimple extends BakedInsn { 6 | private final double x, y, z; 7 | 8 | public BakedTranslateSimple(double x, double y, double z) { 9 | this.x = x; 10 | this.y = y; 11 | this.z = z; 12 | } 13 | 14 | @Override 15 | public void render() { 16 | GL11.glTranslated(x, y, z); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedAnimatedRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 6 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 7 | 8 | public class BakedAnimatedRender extends BakedImageRender { 9 | private final INodeDouble frame; 10 | private final boolean loop; 11 | 12 | public BakedAnimatedRender( 13 | NodeVariableDouble varWidth, NodeVariableDouble varHeight, String res, BakedArea pos, BakedArea tex, 14 | INodeDouble frame, boolean loop 15 | ) { 16 | super(varWidth, varHeight, res, pos, tex); 17 | this.frame = frame; 18 | this.loop = loop; 19 | } 20 | 21 | @Override 22 | public void bindTexture(MinecraftDisplayerRenderer renderer) { 23 | renderer.animator.bindTexture(res.toString(), (int) frame.evaluate(), loop); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedArea.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import buildcraft.lib.expression.FunctionContext; 4 | import buildcraft.lib.expression.GenericExpressionCompiler; 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 6 | import buildcraft.lib.expression.api.InvalidExpressionException; 7 | 8 | public class BakedArea { 9 | public final INodeDouble x, y, width, height; 10 | public double _x, _y, _w, _h; 11 | 12 | public BakedArea(String x, String y, String width, String height, FunctionContext context) throws InvalidExpressionException { 13 | this.x = GenericExpressionCompiler.compileExpressionDouble(x, context); 14 | this.y = GenericExpressionCompiler.compileExpressionDouble(y, context); 15 | this.width = GenericExpressionCompiler.compileExpressionDouble(width, context); 16 | this.height = GenericExpressionCompiler.compileExpressionDouble(height, context); 17 | } 18 | 19 | public BakedArea(INodeDouble x, INodeDouble y, INodeDouble width, INodeDouble height) { 20 | this.x = x; 21 | this.y = y; 22 | this.width = width; 23 | this.height = height; 24 | } 25 | 26 | public void evaluate() { 27 | _x = x.evaluate(); 28 | _y = y.evaluate(); 29 | _w = width.evaluate(); 30 | _h = height.evaluate(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedImageRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import net.minecraft.client.renderer.BufferBuilder; 6 | import net.minecraft.client.renderer.Tessellator; 7 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 8 | import net.minecraft.util.ResourceLocation; 9 | 10 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 11 | import alexiil.mc.mod.load.render.TextureLoader; 12 | import alexiil.mc.mod.load.render.TextureLoader.PreScannedImageData; 13 | 14 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 15 | 16 | public class BakedImageRender extends BakedRenderPositioned { 17 | 18 | /** We only ever render 4 x (3 pos, 2 uv) ints each time then reset for the next face. 19 | *

20 | * So this 64 is overkill. */ 21 | private static final int TESS_INT_COUNT = 64; 22 | 23 | private final Tessellator tess = new Tessellator(TESS_INT_COUNT); 24 | 25 | protected final ResourceLocation res; 26 | private final BakedArea pos, tex; 27 | 28 | PreScannedImageData preScanned = null; 29 | 30 | public BakedImageRender( 31 | NodeVariableDouble varWidth, NodeVariableDouble varHeight, String res, BakedArea pos, BakedArea tex 32 | ) { 33 | super(varWidth, varHeight); 34 | this.res = new ResourceLocation(res); 35 | this.pos = pos; 36 | this.tex = tex; 37 | } 38 | 39 | @Override 40 | public void preLoad(MinecraftDisplayerRenderer renderer) { 41 | super.preLoad(renderer); 42 | 43 | preScanned = TextureLoader.preScan(res); 44 | } 45 | 46 | @Override 47 | public void evaluateVariables(MinecraftDisplayerRenderer renderer) { 48 | pos.evaluate(); 49 | tex.evaluate(); 50 | varWidth.value = pos._w; 51 | varHeight.value = pos._h; 52 | } 53 | 54 | @Override 55 | public void render(MinecraftDisplayerRenderer renderer) { 56 | bindTexture(renderer); 57 | BufferBuilder vb = tess.getBuffer(); 58 | vb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); 59 | vb.pos(pos._x, pos._y + pos._h, 0).tex(tex._x, tex._y + tex._h).endVertex(); 60 | vb.pos(pos._x + pos._w, pos._y + pos._h, 0).tex(tex._x + tex._w, tex._y + tex._h).endVertex(); 61 | vb.pos(pos._x + pos._w, pos._y, 0).tex(tex._x + tex._w, tex._y).endVertex(); 62 | vb.pos(pos._x, pos._y, 0).tex(tex._x, tex._y).endVertex(); 63 | tess.draw(); 64 | } 65 | 66 | public void bindTexture(MinecraftDisplayerRenderer renderer) { 67 | if (preScanned != null) { 68 | preScanned.bind(renderer.textureManager); 69 | } else { 70 | TextureLoader.bindTexture(renderer.textureManager, res); 71 | } 72 | } 73 | 74 | @Override 75 | public String getLocation() { 76 | return res.toString(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedPanoramaRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | import org.lwjgl.util.glu.Project; 5 | 6 | import net.minecraft.client.renderer.BufferBuilder; 7 | import net.minecraft.client.renderer.Tessellator; 8 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 9 | import net.minecraft.util.ResourceLocation; 10 | import net.minecraft.util.math.MathHelper; 11 | 12 | import alexiil.mc.mod.load.baked.BakedRender; 13 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 14 | 15 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 16 | 17 | public class BakedPanoramaRender extends BakedRender { 18 | 19 | /** We only ever render 4 x (3 pos, 2 uv, 1 colour) ints each time then reset for the next face. 20 | *

21 | * So this 64 is overkill. */ 22 | private static final int TESS_INT_COUNT = 0x40; 23 | 24 | private final Tessellator tess = new Tessellator(TESS_INT_COUNT); 25 | 26 | /** Timer used to rotate the panorama, increases every minecraft tick. (20tps) */ 27 | private double actualAngle; 28 | private final INodeDouble angleFunc; 29 | private final ResourceLocation[] cubeSides; 30 | 31 | public BakedPanoramaRender(INodeDouble angle, String resourceLocation) { 32 | String[] strings = new String[6]; 33 | for (int i = 0; i < 6; i++) { 34 | strings[i] = resourceLocation.replace("_x", "_" + i); 35 | } 36 | cubeSides = new ResourceLocation[6]; 37 | for (int i = 0; i < 6; i++) { 38 | cubeSides[i] = new ResourceLocation(strings[i]); 39 | } 40 | angleFunc = angle; 41 | } 42 | 43 | @Override 44 | public void preLoad(MinecraftDisplayerRenderer renderer) { 45 | super.preLoad(renderer); 46 | 47 | for (ResourceLocation loc : cubeSides) { 48 | // TODO: Replace this with loading the texture data to bind on the correct thread. 49 | // TextureLoader.bindTexture(renderer.textureManager, loc); 50 | } 51 | } 52 | 53 | @Override 54 | public void evaluateVariables(MinecraftDisplayerRenderer renderer) {} 55 | 56 | /* This is mostly the same as GuiMainMenu.renderSkyBox() method, with a few things removed, and a bit of 57 | * customizability added. TODO: Add customizability */ 58 | @Override 59 | public void render(MinecraftDisplayerRenderer renderer) { 60 | actualAngle = angleFunc.evaluate(); 61 | drawPanorama(renderer); 62 | } 63 | 64 | private void drawPanorama(MinecraftDisplayerRenderer renderer) { 65 | BufferBuilder vb = tess.getBuffer(); 66 | 67 | GL11.glMatrixMode(GL11.GL_PROJECTION); 68 | GL11.glPushMatrix(); 69 | GL11.glLoadIdentity(); 70 | Project.gluPerspective(120.0F, 1.0F, 0.05F, 10.0F); 71 | GL11.glMatrixMode(GL11.GL_MODELVIEW); 72 | GL11.glPushMatrix(); 73 | GL11.glLoadIdentity(); 74 | GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 75 | GL11.glRotatef(180.0F, 1.0F, 0.0F, 0.0F); 76 | GL11.glDisable(GL11.GL_ALPHA); 77 | byte b0 = 8; 78 | 79 | for (int k = 0; k < b0 * b0; ++k) { 80 | GL11.glPushMatrix(); 81 | float f1 = ((float) (k % b0) / (float) b0 - 0.5F) / 64.0F; 82 | float f2 = ((float) (k / b0) / (float) b0 - 0.5F) / 64.0F; 83 | float f3 = 0.0F; 84 | GL11.glTranslatef(f1, f2, f3); 85 | GL11.glRotatef(MathHelper.sin(((float) this.actualAngle) / 400.0F) * 25.0F + 20.0F, 1.0F, 0.0F, 0.0F); 86 | GL11.glRotatef(-((float) this.actualAngle) * 0.1F, 0.0F, 1.0F, 0.0F); 87 | 88 | for (int l = 0; l < 6; ++l) { 89 | GL11.glPushMatrix(); 90 | 91 | if (l == 1) { 92 | GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); 93 | } 94 | 95 | if (l == 2) { 96 | GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); 97 | } 98 | 99 | if (l == 3) { 100 | GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); 101 | } 102 | 103 | if (l == 4) { 104 | GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); 105 | } 106 | 107 | if (l == 5) { 108 | GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); 109 | } 110 | 111 | renderer.textureManager.bindTexture(cubeSides[l]); 112 | vb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); 113 | int rgb = 0xFF; 114 | int alpha = 255 / (k + 1); 115 | float f4 = 0.0F; 116 | vb.pos(-1.0D, -1.0D, 1.0D).tex(0.0F + f4, 0.0F + f4).color(rgb, rgb, rgb, alpha).endVertex(); 117 | vb.pos(1.0D, -1.0D, 1.0D).tex(1.0F - f4, 0.0F + f4).color(rgb, rgb, rgb, alpha).endVertex(); 118 | vb.pos(1.0D, 1.0D, 1.0D).tex(1.0F - f4, 1.0F - f4).color(rgb, rgb, rgb, alpha).endVertex(); 119 | vb.pos(-1.0D, 1.0D, 1.0D).tex(0.0F + f4, 1.0F - f4).color(rgb, rgb, rgb, alpha).endVertex(); 120 | tess.draw(); 121 | GL11.glPopMatrix(); 122 | } 123 | 124 | GL11.glPopMatrix(); 125 | GL11.glColorMask(true, true, true, false); 126 | } 127 | 128 | vb.setTranslation(0.0D, 0.0D, 0.0D); 129 | GL11.glColorMask(true, true, true, true); 130 | GL11.glRotatef(-180.0F, 1.0F, 0.0F, 0.0F); 131 | GL11.glMatrixMode(GL11.GL_PROJECTION); 132 | GL11.glPopMatrix(); 133 | GL11.glMatrixMode(GL11.GL_MODELVIEW); 134 | GL11.glPopMatrix(); 135 | GL11.glEnable(GL11.GL_ALPHA_TEST); 136 | } 137 | 138 | @Override 139 | public String getLocation() { 140 | return null; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedRenderPositioned.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import alexiil.mc.mod.load.baked.BakedRender; 4 | 5 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 6 | 7 | public abstract class BakedRenderPositioned extends BakedRender { 8 | protected final NodeVariableDouble varWidth, varHeight; 9 | 10 | public BakedRenderPositioned(NodeVariableDouble varWidth, NodeVariableDouble varHeight) { 11 | this.varWidth = varWidth; 12 | this.varHeight = varHeight; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedSlideshowRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import net.minecraft.client.renderer.BufferBuilder; 6 | import net.minecraft.client.renderer.Tessellator; 7 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 8 | import net.minecraft.util.ResourceLocation; 9 | 10 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 11 | import alexiil.mc.mod.load.render.TextureLoader; 12 | 13 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 14 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 15 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 16 | 17 | public class BakedSlideshowRender extends BakedRenderPositioned { 18 | 19 | /** We only ever render 4 x (3 pos, 2 uv) ints each time then reset for the next face. 20 | *

21 | * So this 64 is overkill. */ 22 | private static final int TESS_INT_COUNT = 0x40; 23 | 24 | private final Tessellator tess = new Tessellator(TESS_INT_COUNT); 25 | 26 | private final INodeLong colour; 27 | private final INodeDouble frame; 28 | protected final ResourceLocation[] res; 29 | private final BakedArea pos, tex; 30 | 31 | public BakedSlideshowRender( 32 | NodeVariableDouble varWidth, NodeVariableDouble varHeight, INodeLong colour, INodeDouble frame, 33 | ResourceLocation[] res, BakedArea pos, BakedArea tex 34 | ) { 35 | super(varWidth, varHeight); 36 | this.colour = colour; 37 | this.frame = frame; 38 | this.res = res; 39 | this.pos = pos; 40 | this.tex = tex; 41 | } 42 | 43 | @Override 44 | public void evaluateVariables(MinecraftDisplayerRenderer renderer) { 45 | pos.evaluate(); 46 | tex.evaluate(); 47 | varWidth.value = pos._w; 48 | varHeight.value = pos._h; 49 | } 50 | 51 | @Override 52 | public void render(MinecraftDisplayerRenderer renderer) { 53 | bindTexture(renderer); 54 | 55 | int c = (int) colour.evaluate(); 56 | if ((c & 0xFF_00_00_00) == 0) { 57 | c |= 0xFF_00_00_00; 58 | } else if ((c & 0xFF_00_00_00) == 0x01_00_00_00) { 59 | c &= 0xFF_FF_FF; 60 | } 61 | 62 | if (c != -1) { 63 | GL11.glColor4f( 64 | ((c >>> 16) & 0xFF) / 255f, 65 | ((c >>> 8) & 0xFF) / 255f, 66 | ((c >>> 0) & 0xFF) / 255f, 67 | ((c >>> 24) & 0xFF) / 255f 68 | ); 69 | } 70 | 71 | BufferBuilder vb = tess.getBuffer(); 72 | vb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); 73 | vb.pos(pos._x, pos._y + pos._h, 0).tex(tex._x, tex._y + tex._h).endVertex(); 74 | vb.pos(pos._x + pos._w, pos._y + pos._h, 0).tex(tex._x + tex._w, tex._y + tex._h).endVertex(); 75 | vb.pos(pos._x + pos._w, pos._y, 0).tex(tex._x + tex._w, tex._y).endVertex(); 76 | vb.pos(pos._x, pos._y, 0).tex(tex._x, tex._y).endVertex(); 77 | tess.draw(); 78 | 79 | if (c != -1) { 80 | GL11.glColor4f(1, 1, 1, 1); 81 | } 82 | } 83 | 84 | public void bindTexture(MinecraftDisplayerRenderer renderer) { 85 | int index = (int) frame.evaluate(); 86 | if (index < 0) { 87 | index = 0; 88 | } else { 89 | index %= res.length; 90 | } 91 | TextureLoader.bindTexture(renderer.textureManager, res[index]); 92 | } 93 | 94 | @Override 95 | public String getLocation() { 96 | return res.toString(); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedTextRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import net.minecraft.client.gui.FontRenderer; 6 | 7 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 8 | 9 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 10 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 11 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 12 | import buildcraft.lib.expression.node.value.NodeVariableObject; 13 | 14 | public abstract class BakedTextRender extends BakedRenderPositioned { 15 | protected final NodeVariableObject varText; 16 | protected final INodeDouble scale; 17 | protected final INodeDouble x; 18 | protected final INodeDouble y; 19 | protected final INodeLong colour; 20 | protected final String fontTexture; 21 | private String _text; 22 | private double _scale; 23 | private double _width; 24 | private long _colour; 25 | private double _x, _y; 26 | 27 | public BakedTextRender( 28 | NodeVariableObject varText, NodeVariableDouble varWidth, NodeVariableDouble varHeight, 29 | INodeDouble scale, INodeDouble x, INodeDouble y, INodeLong colour, String fontTexture 30 | ) { 31 | super(varWidth, varHeight); 32 | this.varText = varText; 33 | this.scale = scale; 34 | this.x = x; 35 | this.y = y; 36 | this.colour = colour; 37 | this.fontTexture = fontTexture; 38 | } 39 | 40 | @Override 41 | public void evaluateVariables(MinecraftDisplayerRenderer renderer) { 42 | _text = getText(); 43 | _scale = scale.evaluate(); 44 | FontRenderer font = renderer.fontRenderer(fontTexture); 45 | _width = (int) (font.getStringWidth(_text) * _scale); 46 | varWidth.value = _width; 47 | varHeight.value = font.FONT_HEIGHT * _scale; 48 | _x = x.evaluate(); 49 | _y = y.evaluate(); 50 | _colour = colour.evaluate(); 51 | if ((_colour & 0xFF_00_00_00) == 0) { 52 | _colour |= 0xFF_00_00_00; 53 | } else if ((_colour & 0xFF_00_00_00) == 0x01_00_00_00) { 54 | _colour &= 0xFF_FF_FF; 55 | } 56 | } 57 | 58 | @Override 59 | public void render(MinecraftDisplayerRenderer renderer) { 60 | FontRenderer font = renderer.fontRenderer(fontTexture); 61 | GL11.glPushMatrix(); 62 | GL11.glTranslated(_x, _y, 0); 63 | GL11.glScaled(_scale, _scale, _scale); 64 | font.drawString(_text, 0, 0, (int) _colour, false); 65 | GL11.glPopMatrix(); 66 | GL11.glColor4f(1, 1, 1, 1); 67 | } 68 | 69 | public abstract String getText(); 70 | 71 | @Override 72 | public String getLocation() { 73 | return fontTexture; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedTextRenderStatic.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 4 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 5 | import buildcraft.lib.expression.api.IExpressionNode.INodeObject; 6 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 7 | import buildcraft.lib.expression.node.value.NodeVariableObject; 8 | 9 | public class BakedTextRenderStatic extends BakedTextRender { 10 | private final INodeObject text; 11 | 12 | public BakedTextRenderStatic( 13 | NodeVariableObject varText, 14 | NodeVariableDouble varWidth, 15 | NodeVariableDouble varHeight, 16 | INodeDouble scale, 17 | INodeDouble x, 18 | INodeDouble y, 19 | INodeLong colour, 20 | String fontTexture, 21 | INodeObject text) { 22 | super(varText, varWidth, varHeight, scale, x, y, colour, fontTexture); 23 | this.text = text; 24 | } 25 | 26 | @Override 27 | public String getText() { 28 | return text.evaluate(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/baked/render/BakedVideoRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.baked.render; 2 | 3 | import alexiil.mc.mod.load.render.MinecraftDisplayerRenderer; 4 | 5 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 6 | 7 | public class BakedVideoRender extends BakedRenderPositioned { 8 | // TODO: Implement this! 9 | // Essentially as an alternative to using BakedAnimatedRender 10 | // (also so we don't have to make the frame-rate be passed in as a function) 11 | // I suppose we need to support that anyway though? 12 | 13 | public BakedVideoRender(NodeVariableDouble varWidth, NodeVariableDouble varHeight) { 14 | super(varWidth, varHeight); 15 | } 16 | 17 | @Override 18 | public void evaluateVariables(MinecraftDisplayerRenderer renderer) { 19 | // TODO Auto-generated method stub 20 | throw new AbstractMethodError("// TODO: Implement this!"); 21 | } 22 | 23 | @Override 24 | public void render(MinecraftDisplayerRenderer renderer) { 25 | // TODO Auto-generated method stub 26 | throw new AbstractMethodError("// TODO: Implement this!"); 27 | } 28 | 29 | @Override 30 | public String getLocation() { 31 | // TODO Auto-generated method stub 32 | throw new AbstractMethodError("// TODO: Implement this!"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/coremod/ClsPlugin.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.coremod; 2 | 3 | import java.io.File; 4 | import java.util.Map; 5 | 6 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; 7 | 8 | import alexiil.mc.mod.load.Translation; 9 | 10 | @IFMLLoadingPlugin.MCVersion("1.12.2") 11 | @IFMLLoadingPlugin.TransformerExclusions({ "alexiil.mc.mod.load.coremod" }) 12 | @IFMLLoadingPlugin.SortingIndex(Integer.MAX_VALUE - 80) 13 | public class ClsPlugin implements IFMLLoadingPlugin { 14 | @Override 15 | public String[] getASMTransformerClass() { 16 | return new String[] { ClsTransformer.class.getName() }; 17 | } 18 | 19 | @Override 20 | public String getModContainerClass() { 21 | return null; 22 | } 23 | 24 | @Override 25 | public String getSetupClass() { 26 | return null; 27 | } 28 | 29 | @Override 30 | public void injectData(Map data) { 31 | if (!Translation.scanUrlsForTranslations()) { 32 | File coremodLocation = (File) data.get("coremodLocation"); 33 | if (coremodLocation == null) { 34 | coremodLocation = new File("./../bin/"); 35 | } 36 | // Assume this is a dev environment, and that the build dir is in bin, and the test dir has the same parent 37 | // as 38 | // the bin dir... 39 | Translation.scanFileForTranslations(coremodLocation); 40 | } 41 | Translation.setTranslator(); 42 | } 43 | 44 | @Override 45 | public String getAccessTransformerClass() { 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/frame/FrameDisplayer.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.frame; 2 | 3 | import java.util.Timer; 4 | import java.util.TimerTask; 5 | 6 | public class FrameDisplayer { 7 | public final LoadingFrame frame; 8 | private Timer timer; 9 | 10 | public FrameDisplayer() { 11 | frame = LoadingFrame.openWindow(); 12 | } 13 | 14 | public void start() { 15 | if (frame == null) { 16 | return; 17 | } 18 | Timer t = new Timer("CLS-frame-updater"); 19 | TimerTask task = new TimerTask() { 20 | @Override 21 | public void run() { 22 | frame.setProgress(); 23 | } 24 | }; 25 | t.schedule(task, 0, 10); 26 | } 27 | 28 | public void finish() { 29 | if (timer != null) { 30 | timer.cancel(); 31 | } 32 | if (frame != null) { 33 | frame.dispose(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/frame/LoadingFrame.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.frame; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Dimension; 5 | import java.awt.Rectangle; 6 | import java.awt.Toolkit; 7 | 8 | import javax.swing.JFrame; 9 | import javax.swing.JPanel; 10 | import javax.swing.JProgressBar; 11 | import javax.swing.UIManager; 12 | import javax.swing.border.EmptyBorder; 13 | 14 | import alexiil.mc.mod.load.progress.SingleProgressBarTracker; 15 | import alexiil.mc.mod.load.progress.SingleProgressBarTracker.LockUnlocker; 16 | 17 | @SuppressWarnings("serial") 18 | public class LoadingFrame extends JFrame { 19 | public static LoadingFrame openWindow() { 20 | String clsName = UIManager.getSystemLookAndFeelClassName(); 21 | try { 22 | UIManager.setLookAndFeel(clsName); 23 | } catch (Throwable t) { 24 | t.printStackTrace(); 25 | } 26 | try { 27 | LoadingFrame frame = new LoadingFrame(); 28 | frame.setBounds(getWindowBounds(frame)); 29 | frame.setAlwaysOnTop(true); 30 | frame.setVisible(true); 31 | return frame; 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } 35 | return null; 36 | } 37 | 38 | public static Rectangle getWindowBounds(LoadingFrame frame) { 39 | Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); 40 | Rectangle bounds = frame.getBounds(); 41 | return new Rectangle((size.width - bounds.width) / 2, (size.height - bounds.height) / 2, bounds.width, bounds.height); 42 | } 43 | 44 | private final JProgressBar jprogress; 45 | 46 | /** Create the frame. */ 47 | public LoadingFrame() { 48 | setTitle("Minecraft Loading"); 49 | // setBounds(0, 0, 300, 100); 50 | setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 51 | 52 | JPanel contentPane = new JPanel(); 53 | contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 54 | contentPane.setLayout(new BorderLayout(0, 0)); 55 | setContentPane(contentPane); 56 | 57 | jprogress = new JProgressBar(0, 100); 58 | contentPane.add(jprogress, BorderLayout.CENTER); 59 | 60 | pack(); 61 | setSize(400, getHeight()); 62 | } 63 | 64 | public void setProgress() { 65 | String status; 66 | String subStatus; 67 | int progress; 68 | boolean isInReload; 69 | try (LockUnlocker u = SingleProgressBarTracker.lockUpdate()) { 70 | status = SingleProgressBarTracker.getStatusText(); 71 | subStatus = SingleProgressBarTracker.getSubStatus(); 72 | progress = SingleProgressBarTracker.getProgress(); 73 | isInReload = SingleProgressBarTracker.isInReload(); 74 | } 75 | 76 | setTitle(isInReload ? status : (status + " - " + subStatus)); 77 | double p = progress / SingleProgressBarTracker.MAX_PROGRESS_D; 78 | jprogress.setValue((int) (p * 100)); 79 | jprogress.repaint(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/Area.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonDeserializer; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonObject; 9 | import com.google.gson.JsonParseException; 10 | 11 | import net.minecraft.util.JsonUtils; 12 | 13 | import alexiil.mc.mod.load.baked.render.BakedArea; 14 | 15 | import buildcraft.lib.expression.FunctionContext; 16 | import buildcraft.lib.expression.api.InvalidExpressionException; 17 | 18 | public class Area { 19 | public static final JsonDeserializer DESERIALISER = Area::deserialise; 20 | 21 | public final String x, y, width, height; 22 | 23 | public Area(double x, double y, double width, double height) { 24 | this.x = Double.toString(x); 25 | this.y = Double.toString(y); 26 | this.width = Double.toString(width); 27 | this.height = Double.toString(height); 28 | } 29 | 30 | public Area(String x, String y, String width, String height) { 31 | this.x = x; 32 | this.y = y; 33 | this.width = width; 34 | this.height = height; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "Area [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + "]"; 40 | } 41 | 42 | public BakedArea bake(FunctionContext context) throws InvalidExpressionException { 43 | if (width == null) { 44 | throw new InvalidExpressionException("Missing 'width'!"); 45 | } 46 | if (height == null) { 47 | throw new InvalidExpressionException("Missing 'height'!"); 48 | } 49 | return new BakedArea(x == null ? "0" : x, y == null ? "0" : y, width, height, context); 50 | } 51 | 52 | private static Area deserialise(JsonElement json, Type typeOfT, JsonDeserializationContext context) 53 | throws JsonParseException { 54 | 55 | if (!json.isJsonObject()) { 56 | throw new JsonParseException("Expected an object, but got " + json); 57 | } 58 | 59 | JsonObject obj = json.getAsJsonObject(); 60 | 61 | String x = JsonUtils.getString(obj, "x", null); 62 | String y = JsonUtils.getString(obj, "y", null); 63 | String width = JsonUtils.getString(obj, "width", null); 64 | String height = JsonUtils.getString(obj, "height", null); 65 | 66 | return new Area(x, y, width, height); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/EPosition.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | public enum EPosition { 4 | TOP_LEFT(-1, -1), 5 | TOP_CENTER(0, -1), 6 | TOP_RIGHT(1, -1), 7 | CENTER_LEFT(-1, 0), 8 | CENTER(0, 0), 9 | CENTER_RIGHT(1, 0), 10 | BOTTOM_LEFT(-1, 1), 11 | BOTTOM_CENTER(0, 1), 12 | BOTTOM_RIGHT(1, 1); 13 | 14 | private final int x; 15 | private final int y; 16 | 17 | EPosition(int x, int y) { 18 | this.x = x; 19 | this.y = y; 20 | } 21 | 22 | public String getPositionFunctionX(String width, String argument) { 23 | if (x == -1) return argument; 24 | else if (x == 0) return "(" + width + ") / 2 + (" + argument + ")"; 25 | else return "(" + width + ") + (" + argument + ")"; 26 | } 27 | 28 | public String getPositionFunctionY(String height, String argument) { 29 | if (y == -1) return argument; 30 | else if (y == 0) return "(" + height + ") / 2 + (" + argument + ")"; 31 | else return "(" + height + ") + (" + argument + ")"; 32 | } 33 | 34 | public String getOffsetFunctionX(String width) { 35 | if (x == -1) return "0"; 36 | if (x == 0) return "-(" + width + ")/2"; 37 | return "-(" + width + ")"; 38 | } 39 | 40 | public String getOffsetFunctionY(String height) { 41 | if (y == -1) return "0"; 42 | if (y == 0) return "-(" + height + ")/2"; 43 | return "-(" + height + ")"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/InvalidSourceException.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | 5 | import buildcraft.lib.expression.api.InvalidExpressionException; 6 | 7 | public class InvalidSourceException extends InvalidExpressionException { 8 | public InvalidSourceException(String message) { 9 | super(message); 10 | } 11 | 12 | public InvalidSourceException(String message, Throwable cause) { 13 | super(message); 14 | initCause(cause); 15 | } 16 | 17 | public InvalidSourceException(ResourceLocation loc, String src, Throwable cause) { 18 | this(loc + ":\n" + src, cause); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonAction.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import alexiil.mc.mod.load.baked.BakedAction; 4 | 5 | public abstract class JsonAction extends JsonConfigurable { 6 | public final String conditionStart; 7 | public final String conditionEnd; 8 | 9 | public JsonAction(String conditionStart, String conditionEnd) { 10 | this.conditionStart = conditionStart; 11 | this.conditionEnd = conditionEnd; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonConfig.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | 5 | import alexiil.mc.mod.load.baked.BakedAction; 6 | import alexiil.mc.mod.load.baked.BakedConfig; 7 | import alexiil.mc.mod.load.baked.BakedFactory; 8 | import alexiil.mc.mod.load.baked.BakedRenderingPart; 9 | import alexiil.mc.mod.load.baked.BakedVariable; 10 | 11 | import buildcraft.lib.expression.FunctionContext; 12 | import buildcraft.lib.expression.FunctionSignature; 13 | import buildcraft.lib.expression.InternalCompiler; 14 | import buildcraft.lib.expression.api.InvalidExpressionException; 15 | 16 | public class JsonConfig extends JsonConfigurable { 17 | public final JsonRenderingPart[] renders; 18 | public final String[][] functions; 19 | public final JsonFactory[] factories; 20 | public final JsonAction[] actions; 21 | public final JsonVariable[] constants; 22 | public final JsonVariable[] variables; 23 | 24 | public JsonConfig( 25 | JsonRenderingPart[] renders, String[][] functions, JsonFactory[] factories, JsonAction[] actions, 26 | JsonVariable[] constants, JsonVariable[] variables 27 | ) { 28 | this.renders = renders; 29 | this.functions = functions; 30 | this.factories = factories; 31 | this.actions = actions; 32 | this.constants = constants; 33 | this.variables = variables; 34 | } 35 | 36 | public JsonConfig( 37 | JsonConfig parent, JsonRenderingPart[] renders, String[][] functions, JsonFactory[] factories, 38 | JsonAction[] actions, JsonVariable[] constants, JsonVariable[] variables 39 | ) { 40 | this.renders = consolidateArray(parent == null ? null : parent.renders, renders); 41 | this.functions = consolidateArray(parent == null ? null : parent.functions, functions); 42 | this.factories = consolidateArray(parent == null ? null : parent.factories, factories); 43 | this.actions = consolidateArray(parent == null ? null : parent.actions, actions); 44 | this.constants = consolidateArray(parent == null ? null : parent.constants, constants); 45 | this.variables = consolidateArray(parent == null ? null : parent.variables, variables); 46 | } 47 | 48 | @Override 49 | public void setLocation(ResourceLocation location) { 50 | super.setLocation(location); 51 | location = this.resourceLocation; 52 | for (JsonVariable c : constants) 53 | c.setLocation(location); 54 | for (JsonVariable v : variables) 55 | v.setLocation(location); 56 | for (JsonRenderingPart p : renders) 57 | p.setLocation(location); 58 | for (JsonFactory f : factories) 59 | f.setLocation(location); 60 | for (JsonAction a : actions) 61 | a.setLocation(location); 62 | } 63 | 64 | @Override 65 | protected BakedConfig actuallyBake(FunctionContext context) throws InvalidExpressionException { 66 | for (JsonVariable c : constants) { 67 | c.bake(context); 68 | } 69 | 70 | context = new FunctionContext("User Functions", context); 71 | 72 | for (String[] fn : this.functions) { 73 | 74 | FunctionSignature signature = FunctionSignature.parse(fn[0]); 75 | 76 | String function = null; 77 | 78 | if (signature.func != null) { 79 | if (fn.length == 2) { 80 | throw new InvalidExpressionException("Cannot provide two function implementations!"); 81 | } 82 | function = signature.func; 83 | } else { 84 | function = fn[1]; 85 | } 86 | 87 | String name = signature.name; 88 | context.putFunction(name, InternalCompiler.compileFunction(function, context, signature.args)); 89 | } 90 | 91 | BakedVariable[] vars = new BakedVariable[variables.length]; 92 | for (int i = 0; i < variables.length; i++) { 93 | vars[i] = variables[i].bake(context); 94 | } 95 | 96 | BakedRenderingPart[] array = new BakedRenderingPart[this.renders.length]; 97 | for (int i = 0; i < this.renders.length; i++) { 98 | JsonRenderingPart jrp = this.renders[i]; 99 | array[i] = jrp.bake(context); 100 | } 101 | 102 | BakedAction[] actions; 103 | if (this.actions == null || this.actions.length == 0) { 104 | actions = new BakedAction[0]; 105 | } else { 106 | actions = new BakedAction[this.actions.length]; 107 | for (int i = 0; i < this.actions.length; i++) { 108 | JsonAction ja = this.actions[i]; 109 | actions[i] = ja.bake(context); 110 | } 111 | } 112 | 113 | BakedFactory[] factories; 114 | if (this.factories == null || this.factories.length == 0) { 115 | factories = new BakedFactory[0]; 116 | } else { 117 | factories = new BakedFactory[this.factories.length]; 118 | for (int i = 0; i < this.factories.length; i++) { 119 | JsonFactory jf = this.factories[i]; 120 | factories[i] = jf.bake(context); 121 | } 122 | } 123 | return new BakedConfig(vars, array, actions, factories); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonConfigLoader.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.BufferedWriter; 5 | import java.io.File; 6 | import java.io.FileNotFoundException; 7 | import java.io.FileReader; 8 | import java.io.FileWriter; 9 | import java.io.IOException; 10 | 11 | import com.google.gson.Gson; 12 | import com.google.gson.GsonBuilder; 13 | 14 | public class JsonConfigLoader { 15 | private final Class clazz; 16 | private final File file; 17 | private final T defaultConfig; 18 | 19 | public JsonConfigLoader(File file, Class clazz, T defaultConfig) { 20 | this.file = file; 21 | this.clazz = clazz; 22 | this.defaultConfig = defaultConfig; 23 | } 24 | 25 | /** Overwrite any existing config: Treat it as a default config */ 26 | public void createNew() { 27 | BufferedWriter writer = null; 28 | try { 29 | writer = new BufferedWriter(new FileWriter(file)); 30 | writer.write(new GsonBuilder().setPrettyPrinting().create().toJson(defaultConfig)); 31 | writer.close(); 32 | } catch (IOException e1) { 33 | e1.printStackTrace(); 34 | } finally { 35 | if (writer != null) try { 36 | writer.close(); 37 | } catch (IOException e1) { 38 | e1.printStackTrace(); 39 | } 40 | } 41 | } 42 | 43 | public T load() { 44 | BufferedReader reader = null; 45 | try { 46 | reader = new BufferedReader(new FileReader(file)); 47 | return new Gson().fromJson(reader, clazz); 48 | } catch (FileNotFoundException e) { 49 | createNew(); 50 | } finally { 51 | if (reader != null) try { 52 | reader.close(); 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | return defaultConfig; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonFactory.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonDeserializationContext; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.google.gson.JsonSyntaxException; 8 | 9 | import net.minecraft.util.ResourceLocation; 10 | 11 | import alexiil.mc.mod.load.baked.BakedFactory; 12 | 13 | public abstract class JsonFactory extends JsonConfigurable { 14 | public final JsonRenderingPart[] toCreate; 15 | 16 | public JsonFactory(JsonRenderingPart[] toCreate) { 17 | this.toCreate = toCreate; 18 | } 19 | 20 | public JsonFactory(JsonFactory parent, JsonObject obj, JsonDeserializationContext context) { 21 | JsonElement elem = obj.get("to_create"); 22 | JsonRenderingPart[] arr; 23 | if (elem instanceof JsonObject) { 24 | arr = new JsonRenderingPart[] { context.deserialize(elem, JsonRenderingPart.class) }; 25 | } else if (elem instanceof JsonArray) { 26 | JsonArray jArray = (JsonArray) elem; 27 | arr = new JsonRenderingPart[jArray.size()]; 28 | for (int i = 0; i < arr.length; i++) { 29 | arr[i] = context.deserialize(jArray.get(i), JsonRenderingPart.class); 30 | } 31 | } else { 32 | throw new JsonSyntaxException("Expected to_create as an object or an array, got " + elem + "!"); 33 | } 34 | toCreate = consolidateArray(parent == null ? null : parent.toCreate, arr); 35 | } 36 | 37 | @Override 38 | public void setLocation(ResourceLocation location) { 39 | super.setLocation(location); 40 | location = this.resourceLocation; 41 | for (JsonRenderingPart part : toCreate) { 42 | part.setLocation(location); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonRender.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.google.gson.JsonDeserializationContext; 7 | import com.google.gson.JsonObject; 8 | 9 | import alexiil.mc.mod.load.baked.BakedRender; 10 | import alexiil.mc.mod.load.baked.insn.BakedInsn; 11 | import alexiil.mc.mod.load.json.JsonInsn.JsonInsnColourTogether; 12 | 13 | import buildcraft.lib.expression.FunctionContext; 14 | import buildcraft.lib.expression.api.InvalidExpressionException; 15 | 16 | public abstract class JsonRender extends JsonConfigurable { 17 | public final String image; 18 | public final String colour; 19 | 20 | public JsonRender(String image, String colour) { 21 | this.image = image; 22 | this.colour = colour; 23 | } 24 | 25 | public JsonRender(JsonRender parent, JsonObject json, JsonDeserializationContext context) { 26 | this.image 27 | = overrideObject(json, "image", context, String.class, parent == null ? null : parent.image, "missingno"); 28 | 29 | this.colour = overrideObject( 30 | json, "colour", context, String.class, parent == null ? null : parent.colour, "0xFFFFFFFF" 31 | ); 32 | } 33 | 34 | public List bakeInstructions(FunctionContext context) throws InvalidExpressionException { 35 | List list = new ArrayList<>(); 36 | JsonInsnColourTogether insn = new JsonInsnColourTogether(colour); 37 | insn.setLocation(resourceLocation); 38 | list.add(insn.bake(context)); 39 | return list; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonRenderingPart.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.google.gson.JsonDeserializationContext; 7 | import com.google.gson.JsonObject; 8 | 9 | import net.minecraft.util.ResourceLocation; 10 | 11 | import alexiil.mc.mod.load.baked.BakedRender; 12 | import alexiil.mc.mod.load.baked.BakedRenderingPart; 13 | import alexiil.mc.mod.load.baked.insn.BakedInsn; 14 | 15 | import buildcraft.lib.expression.FunctionContext; 16 | import buildcraft.lib.expression.GenericExpressionCompiler; 17 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 18 | import buildcraft.lib.expression.api.InvalidExpressionException; 19 | import buildcraft.lib.expression.node.value.NodeConstantBoolean; 20 | 21 | /** A rendering part is something that defines the meta about a particular ImageRender: so, OpenGL commands and whether 22 | * or not it should render at this time */ 23 | public class JsonRenderingPart extends JsonConfigurable { 24 | public final JsonRender image; 25 | public final JsonInsn[] instructions; 26 | public final String shouldRender; 27 | 28 | public JsonRenderingPart(JsonRender image, JsonInsn[] instructions, String shouldRender) { 29 | this.image = image; 30 | this.instructions = instructions; 31 | this.shouldRender = shouldRender; 32 | } 33 | 34 | public JsonRenderingPart(JsonRenderingPart parent, JsonObject json, JsonDeserializationContext context) { 35 | if (json.has("image")) { 36 | image = context.deserialize(json.get("image"), JsonRender.class); 37 | } else { 38 | image = parent == null ? null : parent.image; 39 | } 40 | JsonInsn[] insns; 41 | if (json.has("instructions")) { 42 | insns = context.deserialize(json.get("instructions"), JsonInsn[].class); 43 | } else { 44 | insns = new JsonInsn[0]; 45 | } 46 | this.instructions = consolidateArray(parent == null ? null : parent.instructions, insns); 47 | this.shouldRender = consolidateFunction(json, "should_render", context, parent == null ? null : parent.shouldRender, "true"); 48 | } 49 | 50 | @Override 51 | public void setLocation(ResourceLocation location) { 52 | super.setLocation(location); 53 | location = this.resourceLocation; 54 | image.setLocation(location); 55 | for (JsonInsn insn : instructions) { 56 | insn.setLocation(location); 57 | } 58 | } 59 | 60 | @Override 61 | protected BakedRenderingPart actuallyBake(FunctionContext context) throws InvalidExpressionException { 62 | List args = new ArrayList<>(); 63 | 64 | JsonRender element = image; 65 | 66 | context = new FunctionContext(context); 67 | 68 | BakedRender actualRender = element.bake(context); 69 | args.addAll(element.bakeInstructions(context)); 70 | 71 | if (instructions != null) { 72 | for (JsonInsn insn : instructions) { 73 | args.add(insn.bake(context)); 74 | } 75 | } 76 | 77 | BakedInsn[] instructions = args.toArray(new BakedInsn[args.size()]); 78 | 79 | INodeBoolean shouldRenderFunc; 80 | // = FunctionBaker.bakeFunctionBoolean(shouldRender == null ? "true" : shouldRender, functions); 81 | if (shouldRender == null) { 82 | shouldRenderFunc = NodeConstantBoolean.TRUE; 83 | } else { 84 | shouldRenderFunc = GenericExpressionCompiler.compileExpressionBoolean(shouldRender, context); 85 | } 86 | 87 | return new BakedRenderingPart(instructions, actualRender, shouldRenderFunc); 88 | } 89 | 90 | public JsonRender getImageRender() { 91 | return image; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/JsonVariable.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import alexiil.mc.mod.load.baked.BakedVariable; 4 | 5 | import buildcraft.lib.expression.FunctionContext; 6 | import buildcraft.lib.expression.InternalCompiler; 7 | import buildcraft.lib.expression.api.IExpressionNode; 8 | import buildcraft.lib.expression.api.IVariableNode; 9 | import buildcraft.lib.expression.api.InvalidExpressionException; 10 | import buildcraft.lib.expression.api.NodeTypes; 11 | 12 | public class JsonVariable extends JsonConfigurable { 13 | public final String name, value; 14 | public final boolean constant; 15 | 16 | public JsonVariable(boolean constant, String name, String value) { 17 | 18 | boolean specified = false; 19 | boolean specifiedAsConstant = false; 20 | 21 | if (name.startsWith("variable ")) { 22 | specified = true; 23 | specifiedAsConstant = false; 24 | } else if (name.startsWith("constant ") || name.startsWith("const ")) { 25 | specified = true; 26 | specifiedAsConstant = true; 27 | } 28 | 29 | if (specified) { 30 | this.constant = specifiedAsConstant; 31 | this.name = name.substring(name.indexOf(" ") + 1); 32 | } else { 33 | this.constant = constant; 34 | this.name = name; 35 | } 36 | 37 | this.value = value; 38 | } 39 | 40 | @Override 41 | protected BakedVariable actuallyBake(FunctionContext context) throws InvalidExpressionException { 42 | IExpressionNode node = InternalCompiler.compileExpression(value, context); 43 | 44 | IVariableNode variable = NodeTypes.makeVariableNode(NodeTypes.getType(node), name); 45 | 46 | if (constant) { 47 | node = NodeTypes.createConstantNode(node); 48 | } 49 | 50 | BakedVariable bv = new BakedVariable(constant, variable, node); 51 | if (constant) { 52 | context.putVariable(name, node); 53 | return bv; 54 | } else { 55 | context.putVariable(name, variable); 56 | return bv; 57 | } 58 | } 59 | 60 | /** Just for json processing. */ 61 | public static final class JsonConstant extends JsonVariable { 62 | public JsonConstant(boolean constant, String name, String value) { 63 | super(constant, name, value); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/ResourceWrappingInputStream.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import net.minecraft.client.resources.IResource; 7 | 8 | public final class ResourceWrappingInputStream extends InputStream { 9 | private final IResource res; 10 | final InputStream from; 11 | 12 | public ResourceWrappingInputStream(IResource res) { 13 | this.res = res; 14 | from = res.getInputStream(); 15 | } 16 | 17 | @Override 18 | public int read() throws IOException { 19 | return from.read(); 20 | } 21 | 22 | @Override 23 | public int read(byte[] b, int off, int len) throws IOException { 24 | return from.read(b, off, len); 25 | } 26 | 27 | @Override 28 | public int available() throws IOException { 29 | return from.available(); 30 | } 31 | 32 | @Override 33 | public synchronized void mark(int readlimit) { 34 | from.mark(readlimit); 35 | } 36 | 37 | @Override 38 | public boolean markSupported() { 39 | return from.markSupported(); 40 | } 41 | 42 | @Override 43 | public synchronized void reset() throws IOException { 44 | from.reset(); 45 | } 46 | 47 | @Override 48 | public long skip(long n) throws IOException { 49 | return from.skip(n); 50 | } 51 | 52 | @Override 53 | public void close() throws IOException { 54 | // All so that we can close the resource rather than 55 | // just the stream 56 | res.close(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/ConfigDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Map.Entry; 7 | import java.util.Set; 8 | 9 | import com.google.gson.JsonDeserializationContext; 10 | import com.google.gson.JsonElement; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonPrimitive; 13 | import com.google.gson.JsonSyntaxException; 14 | 15 | import net.minecraft.util.JsonUtils; 16 | 17 | import alexiil.mc.mod.load.json.ConfigManager; 18 | import alexiil.mc.mod.load.json.JsonAction; 19 | import alexiil.mc.mod.load.json.JsonConfig; 20 | import alexiil.mc.mod.load.json.JsonFactory; 21 | import alexiil.mc.mod.load.json.JsonRenderingPart; 22 | import alexiil.mc.mod.load.json.JsonVariable; 23 | import alexiil.mc.mod.load.json.JsonVariable.JsonConstant; 24 | 25 | import buildcraft.lib.expression.api.InvalidExpressionException; 26 | 27 | public enum ConfigDeserialiser implements IThrowingDeserialiser { 28 | INSTANCE; 29 | 30 | @Override 31 | public JsonConfig deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException { 32 | if (json.isJsonObject()) { 33 | JsonObject obj = json.getAsJsonObject(); 34 | JsonConfig parent = obj.has("parent") ? JsonUtils.deserializeClass(obj, "parent", context, JsonConfig.class) : null; 35 | JsonRenderingPart[] renders = JsonUtils.deserializeClass(obj, "renders", context, JsonRenderingPart[].class); 36 | JsonFactory[] factories = JsonUtils.deserializeClass(obj, "factories", context, JsonFactory[].class); 37 | JsonAction[] actions = JsonUtils.deserializeClass(obj, "actions", context, JsonAction[].class); 38 | JsonConstant[] constants = obj.has("constants") ? JsonUtils.deserializeClass(obj, "constants", context, JsonConstant[].class) : new JsonConstant[0]; 39 | JsonVariable[] variables = obj.has("variables") ? JsonUtils.deserializeClass(obj, "variables", context, JsonVariable[].class) : new JsonVariable[0]; 40 | 41 | List functions = new ArrayList<>(); 42 | if (obj.has("functions")) { 43 | deserializeFunctions(obj.get("functions"), functions); 44 | } 45 | 46 | JsonConfig cfg = new JsonConfig(parent, renders, functions.toArray(new String[0][]), factories, actions, constants, variables); 47 | cfg.setSource(obj); 48 | return cfg; 49 | } else if (json.isJsonPrimitive()) { 50 | JsonPrimitive prim = json.getAsJsonPrimitive(); 51 | if (prim.isString()) { 52 | return ConfigManager.getAsConfig(prim.getAsString()); 53 | } else { 54 | throw new JsonSyntaxException("Expected an object or a string, found " + prim); 55 | } 56 | } else { 57 | throw new JsonSyntaxException("Expected an object or a string, found " + json); 58 | } 59 | } 60 | 61 | private static void deserializeFunctions(JsonElement json, List functions) { 62 | if (!json.isJsonObject()) { 63 | // A lot of older configs had an array. 64 | return; 65 | } 66 | JsonObject obj = json.getAsJsonObject(); 67 | Set> entrySet = obj.entrySet(); 68 | for (Entry entry : entrySet) { 69 | String name = entry.getKey(); 70 | JsonElement jvalue = entry.getValue(); 71 | String value = jvalue.getAsString(); 72 | functions.add(new String[] { name, value }); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/FactoryDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonPrimitive; 9 | import com.google.gson.JsonSyntaxException; 10 | 11 | import alexiil.mc.mod.load.json.ConfigManager; 12 | import alexiil.mc.mod.load.json.JsonFactory; 13 | import alexiil.mc.mod.load.json.subtypes.JsonFactoryVariableChange; 14 | 15 | import buildcraft.lib.expression.api.InvalidExpressionException; 16 | 17 | public enum FactoryDeserialiser implements IThrowingDeserialiser { 18 | INSTANCE; 19 | 20 | private static final JsonPrimitive BUILTIN_CHANGE = new JsonPrimitive("builtin/change"); 21 | 22 | @Override 23 | public JsonFactory deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException { 24 | if (json.isJsonObject()) { 25 | JsonObject obj = json.getAsJsonObject(); 26 | if (obj.has("parent")) { 27 | JsonFactory factory = deserialise0(context, obj); 28 | factory.setSource(obj); 29 | return factory; 30 | } else { 31 | throw new JsonSyntaxException("Expected either a builtin parent, or a known existing parent!"); 32 | } 33 | } else if (json.isJsonPrimitive()) { 34 | JsonPrimitive prim = json.getAsJsonPrimitive(); 35 | if (prim.isString()) { 36 | return ConfigManager.getAsFactory(prim.getAsString()); 37 | } else { 38 | throw new JsonSyntaxException("Expected an object or a string, found " + prim); 39 | } 40 | } else { 41 | throw new JsonSyntaxException("Expected an object or a string, found " + json); 42 | } 43 | } 44 | 45 | private static JsonFactory deserialise0(JsonDeserializationContext context, JsonObject obj) { 46 | JsonElement pe = obj.get("parent"); 47 | if (BUILTIN_CHANGE.equals(pe)) { 48 | return new JsonFactoryVariableChange(null, obj, context); 49 | } else { 50 | JsonFactory parent = context.deserialize(pe, JsonFactory.class); 51 | if (parent instanceof JsonFactoryVariableChange) { 52 | return new JsonFactoryVariableChange((JsonFactoryVariableChange) parent, obj, context); 53 | } else { 54 | throw new IllegalStateException("Unknown JsonFactory " + parent.getClass()); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/IThrowingDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonDeserializer; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonParseException; 9 | import com.google.gson.JsonSyntaxException; 10 | 11 | import buildcraft.lib.expression.api.InvalidExpressionException; 12 | 13 | public interface IThrowingDeserialiser extends JsonDeserializer { 14 | @Override 15 | default T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 16 | try { 17 | return deserialize0(json, typeOfT, context); 18 | } catch (InvalidExpressionException iee) { 19 | throw new JsonSyntaxException(iee); 20 | } 21 | } 22 | 23 | T deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/ImageDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonPrimitive; 9 | import com.google.gson.JsonSyntaxException; 10 | 11 | import alexiil.mc.mod.load.json.ConfigManager; 12 | import alexiil.mc.mod.load.json.JsonRender; 13 | import alexiil.mc.mod.load.json.subtypes.JsonRenderImage; 14 | import alexiil.mc.mod.load.json.subtypes.JsonRenderPanorama; 15 | import alexiil.mc.mod.load.json.subtypes.JsonRenderSlideshow; 16 | import alexiil.mc.mod.load.json.subtypes.JsonRenderText; 17 | 18 | import buildcraft.lib.expression.api.InvalidExpressionException; 19 | 20 | public enum ImageDeserialiser implements IThrowingDeserialiser { 21 | INSTANCE; 22 | 23 | private static final JsonPrimitive BUILTIN_TEXT = new JsonPrimitive("builtin/text"); 24 | private static final JsonPrimitive BUILTIN_IMAGE = new JsonPrimitive("builtin/image"); 25 | private static final JsonPrimitive BUILTIN_SLIDESHOW = new JsonPrimitive("builtin/slideshow"); 26 | private static final JsonPrimitive BUILTIN_PANORAMA = new JsonPrimitive("builtin/panorama"); 27 | 28 | @Override 29 | public JsonRender deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException { 30 | if (json.isJsonObject()) { 31 | JsonObject obj = json.getAsJsonObject(); 32 | if (obj.has("parent")) { 33 | JsonRender render = deserialise0(context, obj); 34 | render.setSource(obj); 35 | return render; 36 | } else { 37 | throw new JsonSyntaxException("Expected either a builtin parent, or a known existing parent!"); 38 | } 39 | } else if (json.isJsonPrimitive()) { 40 | JsonPrimitive prim = json.getAsJsonPrimitive(); 41 | if (prim.isString()) { 42 | return ConfigManager.getAsImage(prim.getAsString()); 43 | } else { 44 | throw new JsonSyntaxException("Expected an object or a string, found " + prim); 45 | } 46 | } else { 47 | throw new JsonSyntaxException("Expected an object or a string, found " + json); 48 | } 49 | } 50 | 51 | private static JsonRender deserialise0(JsonDeserializationContext context, JsonObject obj) { 52 | JsonElement pe = obj.get("parent"); 53 | if (BUILTIN_TEXT.equals(pe)) { 54 | return new JsonRenderText(null, obj, context); 55 | } else if (BUILTIN_IMAGE.equals(pe)) { 56 | return new JsonRenderImage(null, obj, context); 57 | } else if (BUILTIN_SLIDESHOW.equals(pe)) { 58 | return new JsonRenderSlideshow(null, obj, context); 59 | } else if (BUILTIN_PANORAMA.equals(pe)) { 60 | return new JsonRenderPanorama(null, obj, context); 61 | } else { 62 | JsonRender parent = context.deserialize(pe, JsonRender.class); 63 | if (parent instanceof JsonRenderText) { 64 | return new JsonRenderText((JsonRenderText) parent, obj, context); 65 | } else if (parent instanceof JsonRenderSlideshow) { 66 | return new JsonRenderSlideshow((JsonRenderSlideshow) parent, obj, context); 67 | } else if (parent instanceof JsonRenderImage) { 68 | return new JsonRenderImage((JsonRenderImage) parent, obj, context); 69 | } else if (parent instanceof JsonRenderPanorama) { 70 | return new JsonRenderPanorama((JsonRenderPanorama) parent, obj, context); 71 | } else { 72 | throw new IllegalStateException("Unknown JsonRender " + parent.getClass()); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/InstructionDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Arrays; 5 | import java.util.LinkedHashMap; 6 | import java.util.Map; 7 | 8 | import com.google.gson.JsonDeserializationContext; 9 | import com.google.gson.JsonElement; 10 | import com.google.gson.JsonObject; 11 | import com.google.gson.JsonParseException; 12 | import com.google.gson.JsonPrimitive; 13 | import com.google.gson.JsonSyntaxException; 14 | 15 | import net.minecraft.util.JsonUtils; 16 | 17 | import alexiil.mc.mod.load.json.ConfigManager; 18 | import alexiil.mc.mod.load.json.JsonInsn; 19 | import alexiil.mc.mod.load.json.JsonInsn.JsonInsnColourSplit; 20 | import alexiil.mc.mod.load.json.JsonInsn.JsonInsnColourTogether; 21 | import alexiil.mc.mod.load.json.JsonInsn.JsonInsnRotate; 22 | import alexiil.mc.mod.load.json.JsonInsn.JsonInsnScale; 23 | import alexiil.mc.mod.load.json.JsonInsn.JsonInsnTranslate; 24 | 25 | import buildcraft.lib.expression.api.InvalidExpressionException; 26 | 27 | public enum InstructionDeserialiser implements IThrowingDeserialiser { 28 | INSTANCE; 29 | 30 | private static final Map types = new LinkedHashMap<>(); 31 | private static String validTypes = "[]"; 32 | 33 | private static void putType(String type, TypeDeserialiser des) { 34 | types.put(type, des); 35 | validTypes = Arrays.toString(types.keySet().toArray()); 36 | } 37 | 38 | static { 39 | putType("builtin/translate", InstructionDeserialiser::deserialiseTranslation); 40 | putType("builtin/scale", InstructionDeserialiser::deserialiseScale); 41 | putType("builtin/rotate", InstructionDeserialiser::deserialiseRotation); 42 | putType("builtin/colour", InstructionDeserialiser::deserialiseColour0); 43 | } 44 | 45 | @Override 46 | public JsonInsn deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException { 47 | if (json.isJsonObject()) { 48 | JsonObject obj = json.getAsJsonObject(); 49 | String type = JsonUtils.getString(obj, "parent"); 50 | TypeDeserialiser des = types.get(type); 51 | if (des != null) { 52 | JsonInsn insn = des.deserialize(obj); 53 | insn.setSource(obj); 54 | return insn; 55 | } else { 56 | throw new JsonSyntaxException("Unknown instruction type" + type + ", should be one of " + validTypes); 57 | } 58 | } else if (json.isJsonPrimitive()) { 59 | JsonPrimitive prim = json.getAsJsonPrimitive(); 60 | if (prim.isString()) { 61 | return ConfigManager.getAsInsn(prim.getAsString()); 62 | } else { 63 | throw new JsonSyntaxException("Expected an object or a string, found " + prim); 64 | } 65 | } else { 66 | throw new JsonSyntaxException("Expected an object or a string, found " + json); 67 | } 68 | } 69 | 70 | @FunctionalInterface 71 | private interface TypeDeserialiser { 72 | JsonInsn deserialize(JsonObject obj) throws JsonParseException; 73 | } 74 | 75 | private static String getOptionalString(JsonObject obj, String member, String fallback) { 76 | if (obj.has(member)) { 77 | return JsonUtils.getString(obj, member); 78 | } else { 79 | return fallback; 80 | } 81 | } 82 | 83 | private static JsonInsnTranslate deserialiseTranslation(JsonObject obj) { 84 | String x = JsonUtils.getString(obj, "x"); 85 | String y = JsonUtils.getString(obj, "y"); 86 | String z = getOptionalString(obj, "z", "0"); 87 | return new JsonInsnTranslate(x, y, z); 88 | } 89 | 90 | private static JsonInsnScale deserialiseScale(JsonObject obj) { 91 | String x = JsonUtils.getString(obj, "x"); 92 | String y = JsonUtils.getString(obj, "y"); 93 | String z = getOptionalString(obj, "z", "0"); 94 | return new JsonInsnScale(x, y, z); 95 | } 96 | 97 | private static JsonInsnRotate deserialiseRotation(JsonObject obj) { 98 | String a = JsonUtils.getString(obj, "angle"); 99 | String x = getOptionalString(obj, "x", "0"); 100 | String y = getOptionalString(obj, "y", "0"); 101 | String z = getOptionalString(obj, "z", "0"); 102 | return new JsonInsnRotate(a, x, y, z); 103 | } 104 | 105 | private static JsonInsn deserialiseColour0(JsonObject obj) { 106 | if (obj.has("rgb")) { 107 | String rgb = JsonUtils.getString(obj, "argb"); 108 | return createFromRgb(rgb); 109 | } else if (obj.has("argb")) { 110 | String argb = JsonUtils.getString(obj, "argb"); 111 | return new JsonInsnColourTogether(argb); 112 | } else { 113 | String a = obj.has("a") ? JsonUtils.getString(obj, "a") : "0xFF"; 114 | String r = JsonUtils.getString(obj, "r"); 115 | String g = JsonUtils.getString(obj, "g"); 116 | String b = JsonUtils.getString(obj, "b"); 117 | return new JsonInsnColourSplit(a, r, g, b); 118 | } 119 | } 120 | 121 | private static JsonInsnColourTogether createFromRgb(String rgb) { 122 | return new JsonInsnColourTogether("0xFF_00_00_00 | (" + rgb + ")"); 123 | } 124 | 125 | public static JsonInsn deserialiseColour(JsonElement elem) { 126 | if (elem.isJsonPrimitive() && ((JsonPrimitive) elem).isString()) { 127 | String argb = elem.getAsString(); 128 | JsonInsnColourTogether insn = createFromRgb(argb); 129 | insn.setSource(elem); 130 | return insn; 131 | } else if (elem.isJsonObject()) { 132 | JsonInsn insn = deserialiseColour0(elem.getAsJsonObject()); 133 | insn.setSource(elem); 134 | return insn; 135 | } else { 136 | throw new JsonSyntaxException("Expected an object or a string, got " + elem); 137 | } 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/RenderingPartDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonObject; 8 | import com.google.gson.JsonPrimitive; 9 | import com.google.gson.JsonSyntaxException; 10 | 11 | import alexiil.mc.mod.load.json.ConfigManager; 12 | import alexiil.mc.mod.load.json.JsonRenderingPart; 13 | 14 | import buildcraft.lib.expression.api.InvalidExpressionException; 15 | 16 | public enum RenderingPartDeserialiser implements IThrowingDeserialiser { 17 | INSTANCE; 18 | 19 | @Override 20 | public JsonRenderingPart deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException { 21 | if (json.isJsonObject()) { 22 | JsonObject obj = json.getAsJsonObject(); 23 | JsonRenderingPart parent = null; 24 | if (obj.has("parent")) { 25 | parent = context.deserialize(obj.get("parent"), JsonRenderingPart.class); 26 | } 27 | JsonRenderingPart jrp = new JsonRenderingPart(parent, obj, context); 28 | jrp.setSource(obj); 29 | return jrp; 30 | } else if (json.isJsonPrimitive()) { 31 | JsonPrimitive prim = json.getAsJsonPrimitive(); 32 | if (prim.isString()) { 33 | return ConfigManager.getAsRenderingPart(prim.getAsString()); 34 | } else { 35 | throw new JsonSyntaxException("Expected an object or a string, found " + prim); 36 | } 37 | } else { 38 | throw new JsonSyntaxException("Expected an object or a string, found " + json); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/serial/VariableArrayDeserialiser.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.serial; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.Map.Entry; 5 | import java.util.Set; 6 | 7 | import com.google.gson.JsonDeserializationContext; 8 | import com.google.gson.JsonElement; 9 | import com.google.gson.JsonObject; 10 | 11 | import alexiil.mc.mod.load.json.JsonVariable; 12 | import alexiil.mc.mod.load.json.JsonVariable.JsonConstant; 13 | 14 | import buildcraft.lib.expression.api.InvalidExpressionException; 15 | 16 | public enum VariableArrayDeserialiser implements IThrowingDeserialiser { 17 | CONSTANTS(true), 18 | VARIABLES(false); 19 | 20 | final boolean constant; 21 | 22 | VariableArrayDeserialiser(boolean constant) { 23 | this.constant = constant; 24 | } 25 | 26 | @Override 27 | public JsonVariable[] deserialize0(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws InvalidExpressionException { 28 | JsonObject obj = json.getAsJsonObject(); 29 | Set> entrySet = obj.entrySet(); 30 | JsonVariable[] vars = constant ? new JsonConstant[entrySet.size()] : new JsonVariable[entrySet.size()]; 31 | int i = 0; 32 | for (Entry entry : entrySet) { 33 | String name = entry.getKey(); 34 | JsonElement jvalue = entry.getValue(); 35 | String value = jvalue.getAsString(); 36 | JsonVariable var = constant ? new JsonConstant(constant, name, value) : new JsonVariable(constant, name, value); 37 | var.setSource(jvalue); 38 | vars[i++] = var; 39 | } 40 | return vars; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonActionSound.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import alexiil.mc.mod.load.baked.BakedAction; 4 | import alexiil.mc.mod.load.baked.action.ActionSound; 5 | import alexiil.mc.mod.load.json.JsonAction; 6 | 7 | import buildcraft.lib.expression.FunctionContext; 8 | import buildcraft.lib.expression.GenericExpressionCompiler; 9 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 10 | import buildcraft.lib.expression.api.IExpressionNode.INodeObject; 11 | import buildcraft.lib.expression.api.InvalidExpressionException; 12 | 13 | public class JsonActionSound extends JsonAction { 14 | public final String sound; 15 | public final String repeat; 16 | 17 | public JsonActionSound(String conditionStart, String conditionEnd, String sound, String repeat) { 18 | super(conditionStart, conditionEnd); 19 | this.sound = sound; 20 | this.repeat = repeat; 21 | } 22 | 23 | @Override 24 | protected BakedAction actuallyBake(FunctionContext functions) throws InvalidExpressionException { 25 | INodeBoolean start = GenericExpressionCompiler.compileExpressionBoolean(conditionStart, functions); 26 | INodeBoolean end = GenericExpressionCompiler.compileExpressionBoolean(conditionStart, functions); 27 | INodeObject _sound = GenericExpressionCompiler.compileExpressionString(sound, functions); 28 | INodeBoolean _repeat = GenericExpressionCompiler.compileExpressionBoolean(repeat, functions); 29 | return new ActionSound(start, end, _sound, _repeat); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonFactoryVariableChange.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonObject; 5 | 6 | import net.minecraft.util.ResourceLocation; 7 | 8 | import alexiil.mc.mod.load.baked.BakedFactory; 9 | import alexiil.mc.mod.load.baked.BakedRenderingPart; 10 | import alexiil.mc.mod.load.baked.BakedVariable; 11 | import alexiil.mc.mod.load.baked.factory.BakedFactoryVariableChange; 12 | import alexiil.mc.mod.load.json.JsonFactory; 13 | import alexiil.mc.mod.load.json.JsonRenderingPart; 14 | import alexiil.mc.mod.load.json.JsonVariable; 15 | 16 | import buildcraft.lib.expression.FunctionContext; 17 | import buildcraft.lib.expression.GenericExpressionCompiler; 18 | import buildcraft.lib.expression.InternalCompiler; 19 | import buildcraft.lib.expression.api.IExpressionNode; 20 | import buildcraft.lib.expression.api.IExpressionNode.INodeBoolean; 21 | import buildcraft.lib.expression.api.InvalidExpressionException; 22 | import buildcraft.lib.expression.node.value.NodeVariableLong; 23 | 24 | public class JsonFactoryVariableChange extends JsonFactory { 25 | public final String changeExpression, shouldDestroy; 26 | public final JsonVariable[] variables, keptVariables; 27 | 28 | public JsonFactoryVariableChange(JsonRenderingPart[] toCreate, String changeExpression, String shouldDestroy, JsonVariable[] variables, JsonVariable[] keptVariables) { 29 | super(toCreate); 30 | this.changeExpression = changeExpression; 31 | this.shouldDestroy = shouldDestroy; 32 | this.variables = variables; 33 | this.keptVariables = keptVariables; 34 | } 35 | 36 | public JsonFactoryVariableChange(JsonFactoryVariableChange parent, JsonObject obj, JsonDeserializationContext context) { 37 | super(parent, obj, context); 38 | this.changeExpression = overrideObject(obj, "change", context, String.class, parent == null ? null : parent.changeExpression, "false"); 39 | this.shouldDestroy = overrideObject(obj, "should_destroy", context, String.class, parent == null ? null : parent.shouldDestroy, "false"); 40 | this.keptVariables = overrideVariables(obj, "kept_variables", context, parent == null ? null : parent.keptVariables); 41 | this.variables = overrideVariables(obj, "variables", context, parent == null ? null : parent.variables); 42 | } 43 | 44 | @Override 45 | public void setLocation(ResourceLocation location) { 46 | super.setLocation(location); 47 | location = this.resourceLocation; 48 | for (JsonVariable v : keptVariables) { 49 | v.setLocation(location); 50 | } 51 | for (JsonVariable v : variables) { 52 | v.setLocation(location); 53 | } 54 | } 55 | 56 | @Override 57 | protected BakedFactory actuallyBake(FunctionContext context) throws InvalidExpressionException { 58 | NodeVariableLong varFactoryCount = context.putVariableLong("factory_count"); 59 | IExpressionNode exp = InternalCompiler.compileExpression(changeExpression, context); 60 | NodeVariableLong varFactoryIndex = context.putVariableLong("factory_index"); 61 | BakedVariable[] _keptVariables = bakeVariables(keptVariables, context); 62 | BakedVariable[] _variables = bakeVariables(variables, context); 63 | 64 | INodeBoolean _shouldDestroy = GenericExpressionCompiler.compileExpressionBoolean(shouldDestroy, context); 65 | BakedRenderingPart[] baked = new BakedRenderingPart[toCreate.length]; 66 | for (int i = 0; i < baked.length; i++) { 67 | baked[i] = toCreate[i].bake(context); 68 | } 69 | return new BakedFactoryVariableChange(varFactoryIndex, varFactoryCount, baked, _variables, _keptVariables, _shouldDestroy, exp, true); 70 | } 71 | 72 | private static BakedVariable[] bakeVariables(JsonVariable[] vars, FunctionContext context) throws InvalidExpressionException { 73 | BakedVariable[] baked = new BakedVariable[vars.length]; 74 | for (int i = 0; i < vars.length; i++) { 75 | baked[i] = vars[i].bake(context); 76 | } 77 | return baked; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonRenderImage.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonObject; 5 | 6 | import alexiil.mc.mod.load.baked.BakedRender; 7 | import alexiil.mc.mod.load.baked.render.BakedAnimatedRender; 8 | import alexiil.mc.mod.load.baked.render.BakedArea; 9 | import alexiil.mc.mod.load.baked.render.BakedImageRender; 10 | import alexiil.mc.mod.load.json.Area; 11 | import alexiil.mc.mod.load.render.TextureAnimator; 12 | 13 | import buildcraft.lib.expression.FunctionContext; 14 | import buildcraft.lib.expression.GenericExpressionCompiler; 15 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 16 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 17 | import buildcraft.lib.expression.api.InvalidExpressionException; 18 | import buildcraft.lib.expression.node.value.NodeConstantDouble; 19 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 20 | 21 | public class JsonRenderImage extends JsonRenderPositioned { 22 | public final Area texture; 23 | public final String frame; 24 | public final boolean loop; 25 | 26 | public JsonRenderImage(JsonRenderImage parent, JsonObject json, JsonDeserializationContext context) { 27 | super(parent, json, context); 28 | texture = consolidateArea(json, "texture", context, parent == null ? null : parent.texture); 29 | frame = overrideObject(json, "frame", context, String.class, parent == null ? null : parent.frame, "time"); 30 | loop = overrideObject(json, "loop", context, Boolean.class, parent == null ? null : parent.loop, true); 31 | } 32 | 33 | @Override 34 | protected BakedRender actuallyBake(FunctionContext context) throws InvalidExpressionException { 35 | NodeVariableDouble varWidth = context.putVariableDouble("elem_width"); 36 | NodeVariableDouble varHeight = context.putVariableDouble("elem_height"); 37 | INodeLong _colour = GenericExpressionCompiler.compileExpressionLong(colour, context); 38 | BakedArea pos = (position == null ? new Area("0", "0", "screen_width", "screen_height") : position).bake(context); 39 | BakedArea tex; 40 | if (texture == null) { 41 | NodeConstantDouble zero = NodeConstantDouble.ZERO; 42 | NodeConstantDouble one = NodeConstantDouble.ONE; 43 | tex = new BakedArea(zero, zero, one, one); 44 | } else { 45 | tex = texture.bake(context); 46 | } 47 | 48 | if (TextureAnimator.isAnimated(image)) { 49 | INodeDouble _frame = GenericExpressionCompiler.compileExpressionDouble(frame, context); 50 | return new BakedAnimatedRender(varWidth, varHeight, image, pos, tex, _frame, loop); 51 | } else { 52 | return new BakedImageRender(varWidth, varHeight, image, pos, tex); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonRenderPanorama.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import com.google.gson.JsonDeserializationContext; 7 | import com.google.gson.JsonObject; 8 | 9 | import alexiil.mc.mod.load.baked.insn.BakedInsn; 10 | import alexiil.mc.mod.load.baked.render.BakedPanoramaRender; 11 | import alexiil.mc.mod.load.json.JsonRender; 12 | 13 | import buildcraft.lib.expression.FunctionContext; 14 | import buildcraft.lib.expression.GenericExpressionCompiler; 15 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 16 | import buildcraft.lib.expression.api.InvalidExpressionException; 17 | 18 | public class JsonRenderPanorama extends JsonRender { 19 | public final String angle; 20 | 21 | public JsonRenderPanorama(JsonRenderPanorama parent, JsonObject json, JsonDeserializationContext context) { 22 | super(parent, json, context); 23 | angle = overrideObject(json, "angle", context, String.class, parent == null ? null : parent.angle, "time * 40"); 24 | } 25 | 26 | @Override 27 | protected BakedPanoramaRender actuallyBake(FunctionContext functions) throws InvalidExpressionException { 28 | INodeDouble _angle = GenericExpressionCompiler.compileExpressionDouble(angle, functions); 29 | return new BakedPanoramaRender(_angle, image); 30 | } 31 | 32 | @Override 33 | public List bakeInstructions(FunctionContext functions) { 34 | return Collections.emptyList(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonRenderPositioned.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import java.util.List; 4 | 5 | import com.google.gson.JsonDeserializationContext; 6 | import com.google.gson.JsonObject; 7 | 8 | import alexiil.mc.mod.load.baked.insn.BakedInsn; 9 | import alexiil.mc.mod.load.baked.insn.BakedTranslateFunctional; 10 | import alexiil.mc.mod.load.json.Area; 11 | import alexiil.mc.mod.load.json.EPosition; 12 | import alexiil.mc.mod.load.json.JsonRender; 13 | 14 | import buildcraft.lib.expression.FunctionContext; 15 | import buildcraft.lib.expression.GenericExpressionCompiler; 16 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 17 | import buildcraft.lib.expression.api.InvalidExpressionException; 18 | import buildcraft.lib.expression.node.value.NodeConstantDouble; 19 | 20 | public abstract class JsonRenderPositioned extends JsonRender { 21 | public final EPosition positionType; 22 | public final EPosition offsetPos; 23 | public final Area position; 24 | 25 | public JsonRenderPositioned(JsonRenderPositioned parent, JsonObject json, JsonDeserializationContext context) { 26 | super(parent, json, context); 27 | positionType = overrideObject( 28 | json, "position_type", context, EPosition.class, parent == null ? null : parent.positionType, 29 | EPosition.CENTER 30 | ); 31 | offsetPos = overrideObject( 32 | json, "offset_pos", context, EPosition.class, parent == null ? null : parent.offsetPos, EPosition.CENTER 33 | ); 34 | position = consolidateArea(json, "position", context, parent == null ? null : parent.position); 35 | } 36 | 37 | @Override 38 | public List bakeInstructions(FunctionContext context) throws InvalidExpressionException { 39 | List list = super.bakeInstructions(context); 40 | String x = positionType.getPositionFunctionX("screen_width", offsetPos.getOffsetFunctionX("elem_width")); 41 | String y = positionType.getPositionFunctionY("screen_height", offsetPos.getOffsetFunctionY("elem_height")); 42 | 43 | INodeDouble expX = GenericExpressionCompiler.compileExpressionDouble(x, context); 44 | INodeDouble expY = GenericExpressionCompiler.compileExpressionDouble(y, context); 45 | INodeDouble expZ = NodeConstantDouble.ZERO; 46 | list.add(new BakedTranslateFunctional(expX, expY, expZ)); 47 | return list; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonRenderSlideshow.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import com.google.gson.JsonDeserializationContext; 10 | import com.google.gson.JsonObject; 11 | 12 | import net.minecraft.util.ResourceLocation; 13 | 14 | import alexiil.mc.mod.load.baked.BakedRender; 15 | import alexiil.mc.mod.load.baked.render.BakedArea; 16 | import alexiil.mc.mod.load.baked.render.BakedSlideshowRender; 17 | import alexiil.mc.mod.load.render.TextureLoader; 18 | 19 | import buildcraft.lib.expression.FunctionContext; 20 | import buildcraft.lib.expression.GenericExpressionCompiler; 21 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 22 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 23 | import buildcraft.lib.expression.api.InvalidExpressionException; 24 | import buildcraft.lib.expression.node.value.NodeConstantDouble; 25 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 26 | 27 | public class JsonRenderSlideshow extends JsonRenderImage { 28 | 29 | public JsonRenderSlideshow(JsonRenderSlideshow parent, JsonObject json, JsonDeserializationContext context) { 30 | super(parent, json, context); 31 | } 32 | 33 | @Override 34 | protected BakedRender actuallyBake(FunctionContext context) throws InvalidExpressionException { 35 | NodeVariableDouble varWidth = context.putVariableDouble("elem_width"); 36 | NodeVariableDouble varHeight = context.putVariableDouble("elem_height"); 37 | INodeLong _colour = GenericExpressionCompiler.compileExpressionLong(colour, context); 38 | BakedArea pos = position.bake(context); 39 | BakedArea tex; 40 | if (texture == null) { 41 | NodeConstantDouble zero = NodeConstantDouble.ZERO; 42 | NodeConstantDouble one = NodeConstantDouble.ONE; 43 | tex = new BakedArea(zero, zero, one, one); 44 | } else { 45 | tex = texture.bake(context); 46 | } 47 | 48 | // Find available textures 49 | List images = new ArrayList<>(); 50 | 51 | for (int i = 0; i < 10000; i++) { 52 | String l = image.replace("#", Integer.toString(i)); 53 | 54 | ResourceLocation r = new ResourceLocation(l); 55 | try (InputStream stream = TextureLoader.openResourceStream(r)) { 56 | if (stream == null) { 57 | if (i == 0) { 58 | continue; 59 | } else { 60 | break; 61 | } 62 | } 63 | } catch (FileNotFoundException fnfe) { 64 | if (i == 0) { 65 | continue; 66 | } else { 67 | break; 68 | } 69 | } catch (IOException e) { 70 | e.printStackTrace(); 71 | break; 72 | } 73 | images.add(r); 74 | } 75 | 76 | if (images.isEmpty()) { 77 | images.add(new ResourceLocation("missingno")); 78 | } 79 | 80 | FunctionContext ctx2 = new FunctionContext("frame", context); 81 | ctx2.putConstantLong("frame_count", images.size()); 82 | INodeDouble frameNode = GenericExpressionCompiler.compileExpressionDouble(frame, ctx2); 83 | 84 | return new BakedSlideshowRender( 85 | varWidth, varHeight, _colour, frameNode, images.toArray(new ResourceLocation[0]), pos, tex 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/json/subtypes/JsonRenderText.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.json.subtypes; 2 | 3 | import com.google.gson.JsonDeserializationContext; 4 | import com.google.gson.JsonObject; 5 | 6 | import alexiil.mc.mod.load.baked.render.BakedTextRenderStatic; 7 | 8 | import buildcraft.lib.expression.FunctionContext; 9 | import buildcraft.lib.expression.GenericExpressionCompiler; 10 | import buildcraft.lib.expression.api.IExpressionNode.INodeDouble; 11 | import buildcraft.lib.expression.api.IExpressionNode.INodeLong; 12 | import buildcraft.lib.expression.api.IExpressionNode.INodeObject; 13 | import buildcraft.lib.expression.api.InvalidExpressionException; 14 | import buildcraft.lib.expression.node.value.NodeConstantDouble; 15 | import buildcraft.lib.expression.node.value.NodeVariableDouble; 16 | import buildcraft.lib.expression.node.value.NodeVariableObject; 17 | 18 | public class JsonRenderText extends JsonRenderPositioned { 19 | public final String text; 20 | public final String scale; 21 | 22 | public JsonRenderText(JsonRenderText parent, JsonObject json, JsonDeserializationContext context) { 23 | super(parent, json, context); 24 | text = overrideObject(json, "text", context, String.class, parent == null ? null : parent.text, null); 25 | scale = overrideObject(json, "scale", context, String.class, parent == null ? null : parent.scale, null); 26 | } 27 | 28 | @Override 29 | protected BakedTextRenderStatic actuallyBake(FunctionContext context) throws InvalidExpressionException { 30 | NodeVariableObject varText = context.putVariableString("text"); 31 | NodeVariableDouble varWidth = context.putVariableDouble("elem_width"); 32 | NodeVariableDouble varHeight = context.putVariableDouble("elem_height"); 33 | 34 | ensureExists(text, "text"); 35 | ensureExists(position, "position"); 36 | ensureExists(position.x, "position.x"); 37 | ensureExists(position.y, "position.y"); 38 | ensureExists(colour, "colour"); 39 | 40 | INodeObject textFunc = GenericExpressionCompiler.compileExpressionObject(String.class, text, context); 41 | INodeDouble scaleFunc = scale == null ? NodeConstantDouble.ONE : GenericExpressionCompiler.compileExpressionDouble(scale, context); 42 | INodeDouble xFunc = GenericExpressionCompiler.compileExpressionDouble(position.x, context); 43 | INodeDouble yFunc = GenericExpressionCompiler.compileExpressionDouble(position.y, context); 44 | INodeLong colourFunc = GenericExpressionCompiler.compileExpressionLong(colour, context); 45 | return new BakedTextRenderStatic(varText, varWidth, varHeight, scaleFunc, xFunc, yFunc, colourFunc, image, textFunc); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/progress/LongTermProgressTracker.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.progress; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | import javax.annotation.Nullable; 10 | 11 | import net.minecraft.nbt.CompressedStreamTools; 12 | import net.minecraft.nbt.NBTTagCompound; 13 | import net.minecraft.nbt.NBTTagList; 14 | import net.minecraft.nbt.NBTTagString; 15 | 16 | import net.minecraftforge.common.util.Constants; 17 | import net.minecraftforge.fml.common.Loader; 18 | 19 | import alexiil.mc.mod.load.ModLoadingListener; 20 | import alexiil.mc.mod.load.ModLoadingListener.LoaderStage; 21 | import alexiil.mc.mod.load.progress.SingleProgressBarTracker.ReloadPart; 22 | 23 | public class LongTermProgressTracker { 24 | 25 | public final String[] modIds; 26 | public final ProgressSectionInfo[] infos; 27 | 28 | @Nullable 29 | public static LongTermProgressTracker load() { 30 | File file = Loader.instance().getConfigDir(); 31 | file = new File(file, "customloadingscreen_timings.nbt"); 32 | if (file.isFile()) { 33 | try (FileInputStream fis = new FileInputStream(file)) { 34 | NBTTagCompound nbt = CompressedStreamTools.readCompressed(fis); 35 | return new LongTermProgressTracker(nbt); 36 | } catch (IOException io) { 37 | io.printStackTrace(); 38 | return null; 39 | } 40 | } else { 41 | return null; 42 | } 43 | } 44 | 45 | public static void save(List infos) { 46 | NBTTagCompound nbt = new NBTTagCompound(); 47 | NBTTagList modList = new NBTTagList(); 48 | for (String modId : ModLoadingListener.modIds) { 49 | modList.appendTag(new NBTTagString(modId)); 50 | } 51 | nbt.setTag("mods", modList); 52 | int[] ids = new int[infos.size()]; 53 | int[] timings = new int[ids.length]; 54 | for (int i = 0; i < ids.length; i++) { 55 | ProgressSectionInfo info = infos.get(i); 56 | int id = 0; 57 | if (info.modState != null) { 58 | id |= 1; 59 | id |= info.modState.ordinal() << 1; 60 | id |= ModLoadingListener.modIds.indexOf(info.modId) << 5; 61 | } else { 62 | id |= info.reloadPart.ordinal() << 1; 63 | } 64 | ids[i] = id; 65 | timings[i] = (int) info.time; 66 | } 67 | nbt.setIntArray("ids", ids); 68 | nbt.setIntArray("timings", timings); 69 | 70 | File file = Loader.instance().getConfigDir(); 71 | file = new File(file, "customloadingscreen_timings.nbt"); 72 | try (FileOutputStream fos = new FileOutputStream(file)) { 73 | CompressedStreamTools.writeCompressed(nbt, fos); 74 | } catch (IOException io) { 75 | io.printStackTrace(); 76 | } 77 | } 78 | 79 | private LongTermProgressTracker(NBTTagCompound nbt) throws IOException { 80 | NBTTagList list = nbt.getTagList("mods", Constants.NBT.TAG_STRING); 81 | modIds = new String[list.tagCount()]; 82 | 83 | if (modIds.length == 0) { 84 | throw new IOException("0 mods isn't right!"); 85 | } 86 | 87 | for (int i = 0; i < modIds.length; i++) { 88 | modIds[i] = list.getStringTagAt(i); 89 | } 90 | 91 | int[] ids = nbt.getIntArray("ids"); 92 | int[] timings = nbt.getIntArray("timings"); 93 | 94 | if (ids.length != timings.length || ids.length == 0) { 95 | throw new IOException("wrong lengths!"); 96 | } 97 | 98 | infos = new ProgressSectionInfo[ids.length]; 99 | 100 | for (int i = 0; i < ids.length; i++) { 101 | int id = ids[i]; 102 | int time = timings[i]; 103 | if ((id & 1) == 1) { 104 | // mod 105 | int stage = (id >> 1) & 0xF; 106 | if (stage >= LoaderStage.values().length) { 107 | throw new IOException("Index out of bounds"); 108 | } 109 | LoaderStage loaderStage = LoaderStage.values()[stage]; 110 | int modIndex = id >>> 5; 111 | if (modIndex < 0 || modIndex >= modIds.length) { 112 | throw new IOException("Index out of bounds"); 113 | } 114 | String modId = modIds[modIndex]; 115 | infos[i] = new ProgressSectionInfo(loaderStage, modId, time); 116 | } else { 117 | // reload section 118 | int stage = id >>> 1; 119 | if (stage >= ReloadPart.values().length) { 120 | throw new IOException("Index out of bounds"); 121 | } 122 | ReloadPart reloadPart = ReloadPart.values()[stage]; 123 | infos[i] = new ProgressSectionInfo(reloadPart, time); 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/progress/ProgressSectionInfo.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.progress; 2 | 3 | import alexiil.mc.mod.load.ModLoadingListener; 4 | import alexiil.mc.mod.load.progress.SingleProgressBarTracker.ReloadPart; 5 | 6 | public class ProgressSectionInfo { 7 | public final ReloadPart reloadPart; 8 | public final ModLoadingListener.LoaderStage modState; 9 | public final String modId; 10 | 11 | public long time; 12 | 13 | public ProgressSectionInfo(ReloadPart reloadPart, long time) { 14 | this.reloadPart = reloadPart; 15 | this.modState = null; 16 | this.modId = null; 17 | this.time = time; 18 | } 19 | 20 | public ProgressSectionInfo(ModLoadingListener.LoaderStage modState, String modId, long time) { 21 | this.reloadPart = null; 22 | this.modState = modState; 23 | this.modId = modId; 24 | this.time = time; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | String pre; 30 | if (reloadPart != null) { 31 | pre = reloadPart.toString(); 32 | } else { 33 | pre = modState + ": " + modId; 34 | } 35 | return pre + " took " + time + "ms"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/render/ClsTexture.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.render; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.nio.IntBuffer; 8 | 9 | import org.lwjgl.BufferUtils; 10 | import org.lwjgl.opengl.GL11; 11 | import org.lwjgl.opengl.GL12; 12 | import org.lwjgl.opengl.GL14; 13 | import org.lwjgl.opengl.GLContext; 14 | import org.lwjgl.opengl.KHRDebug; 15 | 16 | import net.minecraft.client.renderer.texture.SimpleTexture; 17 | import net.minecraft.client.renderer.texture.TextureUtil; 18 | import net.minecraft.client.resources.IResourceManager; 19 | import net.minecraft.util.ResourceLocation; 20 | 21 | public class ClsTexture extends SimpleTexture { 22 | 23 | private BufferedImage image; 24 | private boolean blur; 25 | private boolean clamp; 26 | 27 | public ClsTexture(ResourceLocation location) { 28 | super(location); 29 | } 30 | 31 | public ResourceLocation location() { 32 | return textureLocation; 33 | } 34 | 35 | @Override 36 | public int getGlTextureId() { 37 | if (glTextureId == -1) { 38 | glTextureId = GL11.glGenTextures(); 39 | } 40 | return glTextureId; 41 | } 42 | 43 | @Override 44 | public void deleteGlTexture() { 45 | if (glTextureId != -1) { 46 | GL11.glDeleteTextures(glTextureId); 47 | glTextureId = -1; 48 | } 49 | } 50 | 51 | public void loadImage(IResourceManager resourceManager) throws IOException { 52 | 53 | try (InputStream is = TextureLoader.openResourceStream(location())) { 54 | 55 | if (is == null) { 56 | throw new FileNotFoundException(location().toString()); 57 | } 58 | 59 | image = TextureUtil.readBufferedImage(is); 60 | blur = false; 61 | clamp = false; 62 | 63 | // if (m.exists()) { 64 | // try { 65 | // TextureMetadataSection meta = (TextureMetadataSection) iresource.getMetadata("texture"); 66 | // 67 | // if (meta != null) { 68 | // blur = meta.getTextureBlur(); 69 | // clamp = meta.getTextureClamp(); 70 | // } 71 | // } catch (RuntimeException runtimeexception) { 72 | // LOGGER.warn("Failed reading metadata of: {}", this.textureLocation, runtimeexception); 73 | // } 74 | // } 75 | } 76 | } 77 | 78 | @Override 79 | public void loadTexture(IResourceManager resourceManager) throws IOException { 80 | deleteGlTexture(); 81 | 82 | if (image == null) { 83 | loadImage(resourceManager); 84 | } 85 | 86 | int id = getGlTextureId(); 87 | GL11.glBindTexture(GL11.GL_TEXTURE_2D, id); 88 | 89 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0); 90 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MIN_LOD, 0); 91 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LOD, 0); 92 | GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0.0F); 93 | 94 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, blur ? GL11.GL_LINEAR : GL11.GL_NEAREST); 95 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, blur ? GL11.GL_LINEAR : GL11.GL_NEAREST); 96 | 97 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, clamp ? GL11.GL_CLAMP : GL11.GL_REPEAT); 98 | GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, clamp ? GL11.GL_CLAMP : GL11.GL_REPEAT); 99 | 100 | int width = image.getWidth(); 101 | int height = image.getHeight(); 102 | IntBuffer buffer = BufferUtils.createIntBuffer(width * height); 103 | 104 | for (int y = 0; y < height; y++) { 105 | for (int x = 0; x < width; x++) { 106 | buffer.put(image.getRGB(x, y)); 107 | } 108 | } 109 | 110 | buffer.flip(); 111 | 112 | GL11.glTexImage2D( 113 | GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, 114 | buffer 115 | ); 116 | 117 | if (GLContext.getCapabilities().GL_KHR_debug) { 118 | KHRDebug.glObjectLabel(GL11.GL_TEXTURE, id, "CLS_custom_tex_'" + location() + "'"); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/render/FontRendererSeparate.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.render; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import org.lwjgl.opengl.GL11; 11 | 12 | import net.minecraft.client.Minecraft; 13 | import net.minecraft.client.gui.FontRenderer; 14 | import net.minecraft.client.renderer.BufferBuilder; 15 | import net.minecraft.client.renderer.Tessellator; 16 | import net.minecraft.client.renderer.texture.TextureManager; 17 | import net.minecraft.client.renderer.texture.TextureUtil; 18 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 19 | import net.minecraft.client.resources.IResource; 20 | import net.minecraft.client.resources.SimpleResource; 21 | import net.minecraft.client.settings.GameSettings; 22 | import net.minecraft.util.ResourceLocation; 23 | 24 | import alexiil.mc.mod.load.CLSLog; 25 | import alexiil.mc.mod.load.json.ConfigManager; 26 | 27 | public class FontRendererSeparate extends FontRenderer { 28 | 29 | private static final BufferedImage EMPTY_IMAGE = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR); 30 | 31 | private final Map textureData = new HashMap<>(); 32 | private final Map textureLocations = new HashMap<>(); 33 | 34 | private boolean __cls__replaced__underline; 35 | private boolean __cls__replaced__strikethrough; 36 | 37 | public FontRendererSeparate( 38 | GameSettings settings, ResourceLocation location, TextureManager textureManagerIn, boolean unicode 39 | ) { 40 | super(settings, location, textureManagerIn, unicode); 41 | 42 | loadTex(location); 43 | for (int i = 0; i < 256; i++) { 44 | if (i == 8) continue; 45 | if (0xd8 <= i && i <= 0xf8) continue; 46 | loadTex(new ResourceLocation(String.format("textures/font/unicode_page_%02x.png", i))); 47 | } 48 | } 49 | 50 | private BufferedImage loadTex(ResourceLocation location) { 51 | try (InputStream stream = ConfigManager.getInputStream(location)) { 52 | BufferedImage img = TextureUtil.readBufferedImage(stream); 53 | if (img == null) { 54 | CLSLog.warn("Failed to read a texture from " + location + " - " + stream); 55 | return EMPTY_IMAGE; 56 | } 57 | textureData.put(location, img); 58 | return img; 59 | } catch (FileNotFoundException e) { 60 | CLSLog.warn("loadTex(" + location + ") : " + e); 61 | return EMPTY_IMAGE; 62 | } catch (IOException e) { 63 | CLSLog.warn("loadTex(" + location + ") : " + e); 64 | return EMPTY_IMAGE; 65 | } 66 | } 67 | 68 | @Override 69 | protected void bindTexture(ResourceLocation location) { 70 | if (textureLocations == null) { 71 | // During init, so we don't care 72 | return; 73 | } 74 | Integer value = textureLocations.get(location); 75 | if (value == null) { 76 | BufferedImage img = textureData.computeIfAbsent(location, this::loadTex); 77 | if (img == null || img == EMPTY_IMAGE) { 78 | CLSLog.warn("Non-cached texture: '" + location + "'"); 79 | return; 80 | } 81 | int next = GL11.glGenTextures(); 82 | TextureUtil.uploadTextureImage(next, img); 83 | textureLocations.put(location, next); 84 | value = next; 85 | } 86 | GL11.glBindTexture(GL11.GL_TEXTURE_2D, value.intValue()); 87 | } 88 | 89 | @Override 90 | protected IResource getResource(ResourceLocation location) throws IOException { 91 | if ("config".equals(location.getResourceDomain())) { 92 | InputStream stream = ConfigManager.getInputStream(location); 93 | InputStream metaStream = null; 94 | try { 95 | metaStream = ConfigManager.getInputStream( 96 | new ResourceLocation(location.getResourceDomain(), location.getResourcePath() + ".mcmeta") 97 | ); 98 | } catch (IOException e) { 99 | // Ignored 100 | } 101 | return new SimpleResource( 102 | "cls config", location, stream, metaStream, 103 | Minecraft.getMinecraft().getResourcePackRepository().rprMetadataSerializer 104 | ); 105 | } 106 | return super.getResource(location); 107 | } 108 | 109 | public void destroy() { 110 | for (Integer value : textureLocations.values()) { 111 | GL11.glDeleteTextures(value.intValue()); 112 | } 113 | textureLocations.clear(); 114 | } 115 | 116 | @Override 117 | protected void setColor(float r, float g, float b, float a) { 118 | GL11.glColor4f(r, g, b, a); 119 | } 120 | 121 | @Override 122 | protected void enableAlpha() { 123 | GL11.glEnable(GL11.GL_ALPHA_TEST); 124 | } 125 | 126 | @Override 127 | protected void doDraw(float width) { 128 | 129 | if (__cls__replaced__strikethrough || __cls__replaced__underline) { 130 | Tessellator tess = Tessellator.getInstance(); 131 | BufferBuilder bb = tess.getBuffer(); 132 | GL11.glDisable(GL11.GL_TEXTURE_2D); 133 | bb.begin(7, DefaultVertexFormats.POSITION); 134 | if (__cls__replaced__strikethrough) { 135 | int halfHeight = FONT_HEIGHT / 2; 136 | bb.pos(posX, posY + halfHeight, 0).endVertex(); 137 | bb.pos(posX + width, posY + halfHeight, 0).endVertex(); 138 | bb.pos(posX + width, posY + halfHeight - 1, 0).endVertex(); 139 | bb.pos(posX, posY + halfHeight - 1, 0).endVertex(); 140 | } 141 | if (__cls__replaced__underline) { 142 | bb.pos(posX - 1, posY + FONT_HEIGHT, 0).endVertex(); 143 | bb.pos(posX + width, posY + FONT_HEIGHT, 0).endVertex(); 144 | bb.pos(posX + width, posY + FONT_HEIGHT - 1, 0).endVertex(); 145 | bb.pos(posX - 1, posY + FONT_HEIGHT - 1, 0).endVertex(); 146 | } 147 | tess.draw(); 148 | GL11.glEnable(GL11.GL_TEXTURE_2D); 149 | } 150 | 151 | posX += width; 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/render/MinecraftDisplayerRenderer.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.render; 2 | 3 | import java.util.Map; 4 | 5 | import com.google.common.collect.Maps; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | import org.lwjgl.opengl.GL14; 9 | import org.lwjgl.opengl.GLContext; 10 | import org.lwjgl.opengl.KHRDebug; 11 | import org.lwjgl.opengl.SharedDrawable; 12 | 13 | import net.minecraft.client.Minecraft; 14 | import net.minecraft.client.gui.FontRenderer; 15 | import net.minecraft.util.ResourceLocation; 16 | 17 | import alexiil.mc.mod.load.ClsManager; 18 | import alexiil.mc.mod.load.ClsManager.Resolution; 19 | import alexiil.mc.mod.load.baked.BakedAction; 20 | import alexiil.mc.mod.load.baked.BakedConfig; 21 | import alexiil.mc.mod.load.baked.BakedFactory; 22 | import alexiil.mc.mod.load.baked.BakedRenderingPart; 23 | import alexiil.mc.mod.load.baked.BakedVariable; 24 | 25 | public class MinecraftDisplayerRenderer { 26 | private static final ResourceLocation FONT_LOCATION = new ResourceLocation("textures/font/ascii.png"); 27 | 28 | public final TextureAnimator animator; 29 | private final BakedVariable[] variables; 30 | private final BakedRenderingPart[] renderingParts; 31 | private final BakedAction[] actions; 32 | private final BakedFactory[] factories; 33 | private long lastTime; 34 | private Minecraft mc; 35 | private final Map fontRenderers = Maps.newHashMap(); 36 | private final FontRendererSeparate _font_render_instance; 37 | public TextureManagerCLS textureManager; 38 | private boolean first = true; 39 | private SharedDrawable drawable; 40 | 41 | public MinecraftDisplayerRenderer(BakedConfig config) { 42 | this.animator = new TextureAnimator(config); 43 | mc = Minecraft.getMinecraft(); 44 | 45 | textureManager = new TextureManagerCLS(mc.getResourceManager()); 46 | _font_render_instance = new FontRendererSeparate(mc.gameSettings, FONT_LOCATION, textureManager, false); 47 | mc.refreshResources(); 48 | textureManager.onResourceManagerReload(mc.getResourceManager()); 49 | _font_render_instance.onResourceManagerReload(mc.getResourceManager()); 50 | 51 | variables = config.variables; 52 | renderingParts = config.renderingParts; 53 | actions = config.actions; 54 | factories = config.factories; 55 | 56 | lastTime = System.currentTimeMillis(); 57 | 58 | config.preLoad(this); 59 | } 60 | 61 | public void render() { 62 | if (GLContext.getCapabilities().GL_KHR_debug) { 63 | KHRDebug.glPushDebugGroup(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, 10, "CLS_Render"); 64 | } 65 | 66 | Resolution resolution = ClsManager.RESOLUTION; 67 | 68 | // Pre render stuffs 69 | GL11.glMatrixMode(GL11.GL_PROJECTION); 70 | GL11.glLoadIdentity(); 71 | GL11.glOrtho(0.0D, resolution.getWidth(), resolution.getHeight(), 0.0D, -1, 1); 72 | GL11.glMatrixMode(GL11.GL_MODELVIEW); 73 | GL11.glLoadIdentity(); 74 | GL11.glDisable(GL11.GL_LIGHTING); 75 | GL11.glDisable(GL11.GL_FOG); 76 | GL11.glDisable(GL11.GL_DEPTH_TEST); 77 | GL11.glEnable(GL11.GL_TEXTURE_2D); 78 | 79 | GL11.glClearColor(1, 1, 1, 1); 80 | GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); 81 | 82 | GL11.glEnable(GL11.GL_ALPHA_TEST); 83 | GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); 84 | 85 | GL11.glEnable(GL11.GL_BLEND); 86 | GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); 87 | 88 | GL11.glColor4f(1, 1, 1, 1); 89 | 90 | animator.tick(); 91 | 92 | for (BakedVariable variable : variables) { 93 | variable.tick(this); 94 | } 95 | 96 | for (BakedRenderingPart brp : renderingParts) { 97 | if (brp != null) { 98 | 99 | if (GLContext.getCapabilities().GL_KHR_debug) { 100 | KHRDebug.glPushDebugGroup(KHRDebug.GL_DEBUG_SOURCE_APPLICATION, 10, "" + brp.getOrigin()); 101 | } 102 | 103 | brp.tick(this); 104 | 105 | if (GLContext.getCapabilities().GL_KHR_debug) { 106 | KHRDebug.glPopDebugGroup(); 107 | } 108 | } 109 | } 110 | 111 | for (BakedFactory bf : factories) { 112 | bf.tick(this); 113 | } 114 | 115 | for (BakedAction ba : actions) { 116 | ba.tick(this); 117 | } 118 | 119 | // Post render stuffs 120 | GL11.glEnable(GL11.GL_BLEND); 121 | GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 0, 0); 122 | 123 | GL11.glEnable(GL11.GL_ALPHA_TEST); 124 | GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); 125 | GL11.glColor4f(1, 1, 1, 1); 126 | 127 | textureManager.onFrame(); 128 | 129 | if (GLContext.getCapabilities().GL_KHR_debug) { 130 | KHRDebug.glPopDebugGroup(); 131 | } 132 | } 133 | 134 | public FontRenderer fontRenderer(String fontTexture) { 135 | if ("missingno".equals(fontTexture)) { 136 | return _font_render_instance; 137 | } 138 | if (fontRenderers.containsKey(fontTexture)) { 139 | return fontRenderers.get(fontTexture); 140 | } 141 | FontRenderer font 142 | = new FontRendererSeparate(mc.gameSettings, new ResourceLocation(fontTexture), textureManager, false); 143 | // font.onResourceManagerReload(mc.getResourceManager()); 144 | // mc.refreshResources(); 145 | font.onResourceManagerReload(mc.getResourceManager()); 146 | fontRenderers.put(fontTexture, font); 147 | return font; 148 | } 149 | 150 | public void close() { 151 | // GL11.glEnable(GL11.GL_BLEND); 152 | // GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 0, 1); 153 | // GL11.glEnable(GL11.GL_ALPHA_TEST); 154 | // GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); 155 | // GL11.glClearColor(1, 1, 1, 1); 156 | // GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); 157 | _font_render_instance.destroy(); 158 | animator.close(); 159 | textureManager.deleteAll(); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/render/MinecraftDisplayerWrapper.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.render; 2 | 3 | import net.minecraftforge.common.config.Configuration; 4 | 5 | import alexiil.mc.mod.load.ProgressDisplayer.IDisplayer; 6 | 7 | public class MinecraftDisplayerWrapper implements IDisplayer { 8 | private MinecraftDisplayer mcDisp; 9 | private Configuration cfg; 10 | private boolean hasFailed = false; 11 | 12 | @Override 13 | public void open(Configuration cfg) { 14 | this.cfg = cfg; 15 | } 16 | 17 | @Override 18 | public void updateProgress(String text, double percent) { 19 | if (mcDisp == null && !hasFailed) { 20 | try { 21 | mcDisp = new MinecraftDisplayer(); 22 | mcDisp.open(cfg); 23 | } catch (Throwable t) { 24 | System.out.println("Failed to load Minecraft Displayer!"); 25 | t.printStackTrace(); 26 | mcDisp = null; 27 | hasFailed = true; 28 | } 29 | cfg.save(); 30 | } 31 | if (mcDisp != null) mcDisp.updateProgress(text, percent); 32 | } 33 | 34 | @Override 35 | public void close() { 36 | if (mcDisp != null) mcDisp.close(); 37 | } 38 | 39 | public static void playFinishedSound() { 40 | MinecraftDisplayer.playFinishedSound(); 41 | } 42 | 43 | @Override 44 | public void pause() { 45 | if (mcDisp != null) mcDisp.pause(); 46 | } 47 | 48 | @Override 49 | public void resume() { 50 | if (mcDisp != null) mcDisp.resume(); 51 | } 52 | 53 | @Override 54 | public void addFuture(String text, double percent) { 55 | if (mcDisp != null) mcDisp.addFuture(text, percent); 56 | } 57 | 58 | @Override 59 | public void pushProgress() { 60 | if (mcDisp != null) mcDisp.pushProgress(); 61 | } 62 | 63 | @Override 64 | public void popProgress() { 65 | if (mcDisp != null) mcDisp.popProgress(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/render/OpenGlErrorUtil.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | import org.lwjgl.opengl.GL30; 5 | import org.lwjgl.opengl.GL43; 6 | import org.lwjgl.opengl.KHRDebug; 7 | import org.lwjgl.opengl.KHRDebugCallback; 8 | 9 | /** 10 | * Enable by adding the system property "-Dcustom_loading_screen.opengl_error_checking=true" 11 | */ 12 | public class OpenGlErrorUtil { 13 | 14 | private static final String FLAG = "custom_loading_screen.opengl_error_checking"; 15 | 16 | /** Severity levels. */ 17 | private static final int GL_DEBUG_SEVERITY_HIGH = 0x9146, GL_DEBUG_SEVERITY_MEDIUM = 0x9147, 18 | GL_DEBUG_SEVERITY_LOW = 0x9148, GL_DEBUG_SEVERITY_NOTIFICATION = 0x826B; 19 | 20 | /** Sources. */ 21 | private static final int GL_DEBUG_SOURCE_API = 0x8246, GL_DEBUG_SOURCE_WINDOW_SYSTEM = 0x8247, 22 | GL_DEBUG_SOURCE_SHADER_COMPILER = 0x8248, GL_DEBUG_SOURCE_THIRD_PARTY = 0x8249, 23 | GL_DEBUG_SOURCE_APPLICATION = 0x824A, GL_DEBUG_SOURCE_OTHER = 0x824B; 24 | 25 | /** Types. */ 26 | private static final int GL_DEBUG_TYPE_ERROR = 0x824C, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR = 0x824D, 27 | GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR = 0x824E, GL_DEBUG_TYPE_PORTABILITY = 0x824F, 28 | GL_DEBUG_TYPE_PERFORMANCE = 0x8250, GL_DEBUG_TYPE_OTHER = 0x8251, GL_DEBUG_TYPE_MARKER = 0x8268; 29 | 30 | private static void onMessage(int source, int type, int id, int severity, String message) { 31 | 32 | if (id == 131185) { 33 | // NVIDIA buffer creation 34 | return; 35 | } 36 | 37 | String description; 38 | switch (source) { 39 | case GL_DEBUG_SOURCE_API: 40 | description = "API"; 41 | break; 42 | case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 43 | description = "WINDOW SYSTEM"; 44 | break; 45 | case GL_DEBUG_SOURCE_SHADER_COMPILER: 46 | description = "SHADER COMPILER"; 47 | break; 48 | case GL_DEBUG_SOURCE_THIRD_PARTY: 49 | description = "THIRD PARTY"; 50 | break; 51 | case GL_DEBUG_SOURCE_APPLICATION: 52 | description = "APPLICATION"; 53 | // We don't care about application generated messages - CLS has a lot of them, for example 54 | return; 55 | case GL_DEBUG_SOURCE_OTHER: 56 | description = "OTHER"; 57 | break; 58 | default: 59 | description = "UNKNOWN 0x" + Integer.toString(source); 60 | } 61 | String er0 = description; 62 | 63 | switch (type) { 64 | case GL_DEBUG_TYPE_ERROR: 65 | description = "ERROR"; 66 | break; 67 | case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 68 | description = "DEPRECATED BEHAVIOR"; 69 | break; 70 | case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 71 | description = "UNDEFINED BEHAVIOR"; 72 | break; 73 | case GL_DEBUG_TYPE_PORTABILITY: 74 | description = "PORTABILITY"; 75 | break; 76 | case GL_DEBUG_TYPE_PERFORMANCE: 77 | description = "PERFORMANCE"; 78 | break; 79 | case GL_DEBUG_TYPE_OTHER: 80 | description = "OTHER"; 81 | break; 82 | case GL_DEBUG_TYPE_MARKER: 83 | description = "MARKER"; 84 | break; 85 | default: 86 | description = "UNKNOWN 0x" + Integer.toString(type); 87 | } 88 | String er1 = description; 89 | 90 | switch (severity) { 91 | case GL_DEBUG_SEVERITY_HIGH: 92 | description = "HIGH"; 93 | break; 94 | case GL_DEBUG_SEVERITY_MEDIUM: 95 | description = "MEDIUM"; 96 | break; 97 | case GL_DEBUG_SEVERITY_LOW: 98 | description = "LOW"; 99 | break; 100 | case GL_DEBUG_SEVERITY_NOTIFICATION: 101 | description = "NOTIFICATION"; 102 | break; 103 | default: 104 | description = "UNKNOWN 0x" + Integer.toString(severity); 105 | } 106 | String er2 = description; 107 | 108 | String msg = er0 + " " + er1 + " " + er2 + " " + message; 109 | if (severity == KHRDebug.GL_DEBUG_SEVERITY_HIGH) { 110 | new Throwable("OpenGL Error: " + msg).printStackTrace(); 111 | } else { 112 | System.out.println(id + ":" + msg); 113 | } 114 | } 115 | 116 | public static void setupIfFlag() { 117 | if (Boolean.getBoolean(FLAG)) { 118 | setup(); 119 | } 120 | } 121 | 122 | private static void setup() { 123 | int flags = GL11.glGetInteger(GL30.GL_CONTEXT_FLAGS); 124 | System.out.println("debugging context = " + ((flags & GL43.GL_CONTEXT_FLAG_DEBUG_BIT) != 0)); 125 | GL11.glEnable(GL43.GL_DEBUG_OUTPUT); 126 | GL11.glEnable(GL43.GL_DEBUG_OUTPUT_SYNCHRONOUS); 127 | GL43.glDebugMessageControl(GL11.GL_DONT_CARE, GL11.GL_DONT_CARE, GL11.GL_DONT_CARE, null, true); 128 | GL43.glDebugMessageCallback(new KHRDebugCallback(new KHRDebugCallback.Handler() { 129 | @Override 130 | public void handleMessage(int source, int type, int id, int severity, String message) { 131 | onMessage(source, type, id, severity, message); 132 | } 133 | })); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/alexiil/mc/mod/load/render/TextureManagerCLS.java: -------------------------------------------------------------------------------- 1 | package alexiil.mc.mod.load.render; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import net.minecraft.client.renderer.texture.ITextureObject; 9 | import net.minecraft.client.renderer.texture.ITickableTextureObject; 10 | import net.minecraft.client.renderer.texture.TextureManager; 11 | import net.minecraft.client.resources.IResourceManager; 12 | import net.minecraft.util.ResourceLocation; 13 | 14 | import alexiil.mc.mod.load.CLSLog; 15 | import alexiil.mc.mod.load.CustomLoadingScreen; 16 | 17 | public class TextureManagerCLS extends TextureManager { 18 | 19 | /** Map of texture to last access tick. */ 20 | private final Map textures = new HashMap<>(); 21 | // If we're forced to put a full object into the map value, we may as well intern them by only creating them once 22 | private Long currentTime = System.currentTimeMillis(); 23 | 24 | public TextureManagerCLS(IResourceManager resourceManager) { 25 | super(resourceManager); 26 | } 27 | 28 | private void onTextureAccess(ResourceLocation resource) { 29 | textures.put(resource, currentTime); 30 | } 31 | 32 | @Override 33 | public void bindTexture(ResourceLocation resource) { 34 | super.bindTexture(resource); 35 | onTextureAccess(resource); 36 | } 37 | 38 | @Override 39 | public ITextureObject getTexture(ResourceLocation resource) { 40 | ITextureObject obj = super.getTexture(resource); 41 | if (obj != null) { 42 | onTextureAccess(resource); 43 | } 44 | return obj; 45 | } 46 | 47 | @Override 48 | public void deleteTexture(ResourceLocation textureLocation) { 49 | super.deleteTexture(textureLocation); 50 | textures.remove(textureLocation); 51 | } 52 | 53 | @Override 54 | public boolean loadTexture(ResourceLocation textureLocation, ITextureObject textureObj) { 55 | onTextureAccess(textureLocation); 56 | return super.loadTexture(textureLocation, textureObj); 57 | } 58 | 59 | @Override 60 | public boolean loadTickableTexture(ResourceLocation textureLocation, ITickableTextureObject textureObj) { 61 | onTextureAccess(textureLocation); 62 | return super.loadTickableTexture(textureLocation, textureObj); 63 | } 64 | 65 | public void deleteAll() { 66 | for (ResourceLocation location : textures.keySet().toArray(new ResourceLocation[0])) { 67 | deleteTexture(location); 68 | } 69 | } 70 | 71 | public void onFrame() { 72 | if (CustomLoadingScreen.textureClearInterval == 0) { 73 | return; 74 | } 75 | 76 | Long last = currentTime; 77 | long next = System.currentTimeMillis(); 78 | 79 | if (last + 1000 > next) { 80 | return; 81 | } 82 | 83 | currentTime = next; 84 | 85 | long minTime = currentTime - (CustomLoadingScreen.textureClearInterval * 1000); 86 | 87 | List toRemove = new ArrayList<>(); 88 | 89 | for (Map.Entry entry : textures.entrySet()) { 90 | if (entry.getValue() < minTime) { 91 | toRemove.add(entry.getKey()); 92 | } 93 | } 94 | 95 | for (ResourceLocation tex : toRemove) { 96 | if (CustomLoadingScreen.debugResourceLoading) { 97 | CLSLog.info("[debug] Automatically deleting texture " + tex); 98 | } 99 | deleteTexture(tex); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/lang/en_us.lang: -------------------------------------------------------------------------------- 1 | customloadingscreen.modstate.minecraft_init=Minecraft Initializing 2 | customloadingscreen.modstate.construction=Construction 3 | customloadingscreen.modstate.pre_initialization=Pre Initialization 4 | customloadingscreen.modstate.initialization=Initialization 5 | customloadingscreen.modstate.post_initialization=Post Initialization 6 | customloadingscreen.modstate.completed=Completed 7 | customloadingscreen.modstate.reloading_resource_packs=Reloading Resource Packs 8 | customloadingscreen.mcstate.modelloader.items=Loading Item Models 9 | customloadingscreen.mcstate.modelloader.blocks=Loading Block Models 10 | customloadingscreen.mcstate.modelloader.bake=Baking Models 11 | customloadingscreen.mcstate.texture.load=Loading Textures 12 | customloadingscreen.mcstate.texture.stitch=Stitching Textures 13 | customloadingscreen.loading=loading 14 | customloadingscreen.finishing=Finishing 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/lang/ru_ru.lang: -------------------------------------------------------------------------------- 1 | customloadingscreen.modstate.minecraft_init=Инициализация ресурсов Minecraft 2 | customloadingscreen.modstate.construction=Сборка 3 | customloadingscreen.modstate.pre_initialization=Пре-инициализация 4 | customloadingscreen.modstate.initialization=Инициализация 5 | customloadingscreen.modstate.post_initialization=Пост-инициализация 6 | customloadingscreen.modstate.completed=Завершено 7 | customloadingscreen.modstate.reloading_resource_packs=Перезагрузка пакетов ресурсов 8 | customloadingscreen.loading=Загрузка 9 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/action/sound_at_end.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"builtin/sound", 3 | "conditionStart":"false", 4 | "conditionEnd":"true", 5 | "arguments":[ 6 | "'random.levelup'", 7 | "false" 8 | ] 9 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | { 4 | "image": { 5 | "parent": "sample/flat_background", 6 | "colour": "0xFF_00_00_00" 7 | } 8 | }, 9 | "sample/mojang_splash", 10 | "sample/loading_bar_boss", 11 | "sample/loading_bar_boss_percentage", 12 | "sample/text_status", 13 | "sample/text_sub_status", 14 | "sample/text_percentage" 15 | ], 16 | "functions": [ 17 | ], 18 | "factories": [ 19 | ], 20 | "actions": [ 21 | ], 22 | "variables": { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | { 4 | "image": { 5 | "parent": "builtin/panorama", 6 | "image": "textures/gui/title/background/panorama_x.png" 7 | } 8 | }, 9 | "sample/horizontal_stripe", 10 | "sample/loading_bar_bevel", 11 | "sample/loading_bar_bevel_percentage", 12 | "sample/text_status_white", 13 | "sample/text_sub_status_white", 14 | "sample/text_percentage_white" 15 | ], 16 | "functions":[ 17 | 18 | ], 19 | "factories":[ 20 | 21 | ], 22 | "actions":[ 23 | 24 | ], 25 | "variables":{ 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/forge_duplicate.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | "sample/mojang_splash" 4 | ], 5 | "functions": [ 6 | 7 | ], 8 | "variables": { 9 | "bar_count": "forge_progress_bar_count" 10 | }, 11 | "factories": [ 12 | { 13 | "parent": "builtin/change", 14 | "change": "factory_count < bar_count", 15 | "to_create": [ 16 | { 17 | "should_render": "factory_index < bar_count", 18 | "image": { 19 | "parent": "builtin/text", 20 | "image": "textures/font/ascii.png", 21 | "position_type": "BOTTOM_LEFT", 22 | "offset_pos": "BOTTOM_LEFT", 23 | "text": "forge_progress_bar_title(factory_index) + ': ' + forge_progress_bar_message(factory_index)", 24 | "position": { 25 | "x": "30", 26 | "y": "(factory_index - bar_count) * 16 - 4" 27 | }, 28 | "colour": "0xFF_00_00_00" 29 | } 30 | } 31 | ] 32 | } 33 | ], 34 | "actions": [ 35 | 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/generic_error.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/default", 3 | "renders": [ 4 | "sample/text_generic_error" 5 | ], 6 | "functions":[ 7 | 8 | ], 9 | "factories":[ 10 | 11 | ], 12 | "actions":[ 13 | 14 | ], 15 | "variables":{ 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/panorama_lower.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | "sample/panorama", 4 | { 5 | "image": { 6 | "parent": "sample/dirt_background", 7 | "position_type": "BOTTOM_CENTER", 8 | "offset_pos": "BOTTOM_CENTER", 9 | "position": { 10 | "height": "2 * 16" 11 | }, 12 | "texture": { 13 | "height": "4" 14 | } 15 | } 16 | }, 17 | { 18 | "image": { 19 | "parent": "sample/bottom_bar", 20 | "position_type": "BOTTOM_LEFT", 21 | "offset_pos": "BOTTOM_LEFT", 22 | "colour": "0xFF_00_00_00", 23 | "position": { 24 | "width": "screen_width", 25 | "y": "-32" 26 | } 27 | } 28 | }, 29 | { 30 | "image": { 31 | "parent": "sample/bottom_bar", 32 | "position_type": "BOTTOM_LEFT", 33 | "offset_pos": "BOTTOM_LEFT", 34 | "colour": "0xFF_33_55_FF", 35 | "position": { 36 | "y": "-32" 37 | } 38 | } 39 | }, 40 | { 41 | "image": { 42 | "parent": "builtin/text", 43 | "text": "status", 44 | "position_type": "BOTTOM_LEFT", 45 | "offset_pos": "BOTTOM_LEFT", 46 | "position": { "x": 10, "y": -16 } 47 | } 48 | }, 49 | { 50 | "image": { 51 | "parent": "builtin/text", 52 | "text": "sub_status", 53 | "position_type": "BOTTOM_LEFT", 54 | "offset_pos": "BOTTOM_LEFT", 55 | "position": { "x": 10, "y": -4 } 56 | } 57 | }, 58 | { 59 | "image": { 60 | "parent": "builtin/text", 61 | "text": "(floor(percentage * 100)) + '%'", 62 | "scale": 2, 63 | "position_type": "BOTTOM_RIGHT", 64 | "offset_pos": "BOTTOM_RIGHT", 65 | "position": { "x": -10, "y": -5 } 66 | } 67 | }, 68 | { 69 | "image": { 70 | "parent": "builtin/text", 71 | "text": "has_tips() ? tip(floor(time / 8)) : ''", 72 | "position_type": "BOTTOM_CENTER", 73 | "offset_pos": "BOTTOM_CENTER", 74 | "position": { "x": 0, "y": -10 } 75 | } 76 | } 77 | ], 78 | "functions": [ 79 | 80 | ], 81 | "variables": { 82 | 83 | }, 84 | "factories": [ 85 | 86 | ], 87 | "actions": [ 88 | 89 | ] 90 | } 91 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/rotating_cakes.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | "sample/rotating_cake_top_left", 4 | "sample/rotating_cake_top_right", 5 | "sample/rotating_cake_bottom_left", 6 | "sample/rotating_cake_bottom_right", 7 | "sample/block_cake_side_4_wide", 8 | "sample/block_cake_inner_4_wide", 9 | "sample/text_status", 10 | "sample/text_percentage" 11 | ], 12 | "variables": { 13 | "item_rotation": "time * 50" 14 | }, 15 | "functions": [ 16 | ], 17 | "factories": [ 18 | ], 19 | "actions": [ 20 | ] 21 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/scrolling.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | "sample/dirt_background", 4 | "sample/text_percentage_scrolling", 5 | { 6 | "image": { 7 | "parent": "sample/bottom_bar", 8 | "colour": "0xFF_00_00_00", 9 | "position": { "width": "screen_width" } 10 | } 11 | }, 12 | { 13 | "image": { 14 | "parent": "sample/bottom_bar", 15 | "colour": "0xFF_11_44_CC" 16 | } 17 | } 18 | ], 19 | "functions": [ 20 | 21 | ], 22 | "variables": { 23 | "max_scroll_count": "screen_height / (2 * 16)", 24 | "scroll_text": "status + (is_reloading ? '' : (' - ' + sub_status))" 25 | }, 26 | "factories":[ 27 | { 28 | "parent": "builtin/change", 29 | "change": "scroll_text", 30 | "variables": { 31 | "factory_age" : "factory_count - factory_index" 32 | }, 33 | "kept_variables": { 34 | "factory_status": "scroll_text" 35 | }, 36 | "to_create": { 37 | "should_render": "factory_age < max_scroll_count", 38 | "image": { 39 | "parent": "builtin/text", 40 | "image": "textures/font/ascii.png", 41 | "position_type": "BOTTOM_LEFT", 42 | "offset_pos": "BOTTOM_LEFT", 43 | "text": "factory_status + (factory_age == 1 ? ( is_reloading ? ' - ' + sub_status : '') : '')", 44 | "position": { 45 | "x": "30", 46 | "y": "(factory_index - factory_count) * 16 - 4" 47 | }, 48 | "colour": "0xFF_00_00_00 | (0x01_01_01 * (0xFF - 0xFF * factory_age / max_scroll_count).max(0x20))" 49 | } 50 | } 51 | } 52 | ], 53 | "actions":[ 54 | 55 | ] 56 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/scrolling_detailed.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | "sample/dirt_background", 4 | "sample/text_percentage_scrolling", 5 | { 6 | "image": { 7 | "parent": "sample/bottom_bar", 8 | "colour": "0xFF_00_00_00", 9 | "position": { "width": "screen_width" } 10 | } 11 | }, 12 | { 13 | "image": { 14 | "parent": "sample/bottom_bar", 15 | "colour": "0xFF_11_44_CC" 16 | } 17 | }, 18 | { 19 | "image": { 20 | "parent": "builtin/text", 21 | "image": "textures/font/ascii.png", 22 | "position_type": "TOP_LEFT", 23 | "offset_pos": "TOP_LEFT", 24 | "text": "'Memory Alotted :'", 25 | "position": { 26 | "x": 10, "y": 10 27 | } 28 | } 29 | }, 30 | { 31 | "image": { 32 | "parent": "builtin/text", 33 | "image": "textures/font/ascii.png", 34 | "position_type": "TOP_LEFT", 35 | "offset_pos": "TOP_RIGHT", 36 | "text": "memory_total() + ' MiB'", 37 | "position": { 38 | "x": 180, "y": 10 39 | } 40 | } 41 | }, 42 | { 43 | "image": { 44 | "parent": "builtin/text", 45 | "image": "textures/font/ascii.png", 46 | "position_type": "TOP_LEFT", 47 | "offset_pos": "TOP_LEFT", 48 | "text": "'Memory Utilized : -'", 49 | "position": { 50 | "x": 10, "y": 24 51 | } 52 | } 53 | }, 54 | { 55 | "image": { 56 | "parent": "builtin/text", 57 | "image": "textures/font/ascii.png", 58 | "position_type": "TOP_LEFT", 59 | "offset_pos": "TOP_RIGHT", 60 | "text": "memory_used() + ' MiB'", 61 | "position": { 62 | "x": 180, "y": 24 63 | } 64 | } 65 | }, 66 | { 67 | "image": { 68 | "parent": "builtin/text", 69 | "image": "textures/font/ascii.png", 70 | "position_type": "TOP_LEFT", 71 | "offset_pos": "TOP_LEFT", 72 | "text": "'________'", 73 | "position": { 74 | "x": 132, "y": 27 75 | } 76 | } 77 | }, 78 | { 79 | "image": { 80 | "parent": "builtin/text", 81 | "image": "textures/font/ascii.png", 82 | "position_type": "TOP_LEFT", 83 | "offset_pos": "TOP_LEFT", 84 | "text": "'Memory Free :'", 85 | "position": { 86 | "x": 10, "y": 38 87 | } 88 | } 89 | }, 90 | { 91 | "image": { 92 | "parent": "builtin/text", 93 | "image": "textures/font/ascii.png", 94 | "position_type": "TOP_LEFT", 95 | "offset_pos": "TOP_RIGHT", 96 | "text": "memory_free() + ' MiB'", 97 | "position": { 98 | "x": 180, "y": 38 99 | } 100 | } 101 | }, 102 | { 103 | "image": { 104 | "parent": "builtin/text", 105 | "image": "textures/font/ascii.png", 106 | "position_type": "TOP_LEFT", 107 | "offset_pos": "TOP_LEFT", 108 | "text": "'[ ' + memory_max() + ' MiB Maximum ]'", 109 | "position": { 110 | "x": 10, "y": 54 111 | } 112 | } 113 | }, 114 | { 115 | "image": { 116 | "parent": "builtin/text", 117 | "image": "textures/font/ascii.png", 118 | "position_type": "TOP_LEFT", 119 | "offset_pos": "TOP_LEFT", 120 | "text": "'[ ' + floor(time * 10) / 10.0 + ' Seconds Elapsed ]'", 121 | "position": { 122 | "x": 10, "y": 66 123 | } 124 | } 125 | } 126 | ], 127 | "functions": [ 128 | 129 | ], 130 | "variables": { 131 | "max_scroll_count": "screen_height / (5 * 8)", 132 | "scroll_text": "status + (is_reloading ? '' : (' - ' + sub_status))" 133 | }, 134 | "factories": [ 135 | { 136 | "parent": "builtin/change", 137 | "change": "scroll_text", 138 | "variables": { 139 | "factory_age" : "factory_count - factory_index" 140 | }, 141 | "kept_variables": { 142 | "factory_status": "scroll_text" 143 | }, 144 | "to_create": { 145 | "should_render": "factory_age < max_scroll_count", 146 | "image": { 147 | "parent": "builtin/text", 148 | "image": "textures/font/ascii.png", 149 | "position_type": "BOTTOM_LEFT", 150 | "offset_pos": "BOTTOM_LEFT", 151 | "text": "factory_status + (factory_age == 1 ? ( is_reloading ? ' - ' + sub_status : '') : '')", 152 | "position": { 153 | "x": "35", 154 | "y": "(factory_index - factory_count) * 16 - 4" 155 | }, 156 | "colour": "0xFF_00_00_00 | (0x01_01_01 * (0xFF - 0xFF * factory_age / max_scroll_count).max(0x20))" 157 | } 158 | } 159 | } 160 | ], 161 | "actions": [ 162 | 163 | ] 164 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/slideshow.json: -------------------------------------------------------------------------------- 1 | { 2 | "constants": { 3 | "image_interval": 3.0, 4 | "transition_duration": 0.5, 5 | "tip_interval": 8.0, 6 | "random_slide_order": false, 7 | 8 | "tip_seed": "generate_seed()", 9 | "slideshow_seed": "generate_seed()" 10 | }, 11 | "functions": { 12 | "slideshow_frame_inner(float timeSub)": "floor((time - timeSub) / image_interval)", 13 | "slideshow_frame(float timeSub, int count)": "random_slide_order ? ( random_int( slideshow_seed, slideshow_frame_inner(timeSub), count ) ) : slideshow_frame_inner(timeSub)" 14 | }, 15 | "variables": { 16 | }, 17 | "renders": [ 18 | { 19 | "image": { 20 | "parent": "builtin/slideshow", 21 | "image": "config:slideshow_#.png", 22 | "frame": "slideshow_frame(transition_duration, frame_count)", 23 | "position_type": "CENTER", 24 | "offset_pos": "CENTER", 25 | "colour": "0xFF_FF_FF_FF", 26 | "position": { 27 | "x": "0", 28 | "y": "0", 29 | "width": "screen_width", 30 | "height": "screen_height" 31 | }, 32 | "texture": { 33 | "x": "0", 34 | "y": "0", 35 | "width": "1", 36 | "height": "1" 37 | } 38 | } 39 | }, 40 | { 41 | "image": { 42 | "parent": "builtin/slideshow", 43 | "image": "config:slideshow_#.png", 44 | "frame": "slideshow_frame(0, frame_count)", 45 | "position_type": "CENTER", 46 | "offset_pos": "CENTER", 47 | "colour": "0xFF_FF_FF | (0xFF_00_00_00 & (0x01_00_00_00 * floor(0xFF * min(1, ((transition_duration <= 0.01) ? (0) : (time/transition_duration)) % image_interval ))))", 48 | "position": { 49 | "x": "0", 50 | "y": "0", 51 | "width": "screen_width", 52 | "height": "screen_height" 53 | }, 54 | "texture": { 55 | "x": "0", 56 | "y": "0", 57 | "width": "1", 58 | "height": "1" 59 | } 60 | } 61 | }, 62 | { 63 | "image": { 64 | "parent": "sample/dirt_background", 65 | "position_type": "BOTTOM_CENTER", 66 | "offset_pos": "BOTTOM_CENTER", 67 | "position": { 68 | "height": "2 * 16" 69 | }, 70 | "texture": { 71 | "height": "4" 72 | } 73 | } 74 | }, 75 | { 76 | "image": { 77 | "parent": "sample/bottom_bar", 78 | "position_type": "BOTTOM_LEFT", 79 | "offset_pos": "BOTTOM_LEFT", 80 | "colour": "0xFF_00_00_00", 81 | "position": { 82 | "width": "screen_width", 83 | "y": "-32" 84 | } 85 | } 86 | }, 87 | { 88 | "image": { 89 | "parent": "sample/bottom_bar", 90 | "position_type": "BOTTOM_LEFT", 91 | "offset_pos": "BOTTOM_LEFT", 92 | "colour": "0xFF_33_55_FF", 93 | "position": { 94 | "y": "-32" 95 | } 96 | } 97 | }, 98 | { 99 | "image": { 100 | "parent": "builtin/text", 101 | "text": "status", 102 | "position_type": "BOTTOM_LEFT", 103 | "offset_pos": "BOTTOM_LEFT", 104 | "position": { "x": 10, "y": -16 } 105 | } 106 | }, 107 | { 108 | "image": { 109 | "parent": "builtin/text", 110 | "text": "sub_status", 111 | "position_type": "BOTTOM_LEFT", 112 | "offset_pos": "BOTTOM_LEFT", 113 | "position": { "x": 10, "y": -4 } 114 | } 115 | }, 116 | { 117 | "image": { 118 | "parent": "builtin/text", 119 | "text": "(floor(percentage * 100)) + '%'", 120 | "scale": 2, 121 | "position_type": "BOTTOM_RIGHT", 122 | "offset_pos": "BOTTOM_RIGHT", 123 | "position": { "x": -10, "y": -5 } 124 | } 125 | }, 126 | { 127 | "image": { 128 | "parent": "builtin/text", 129 | "text": "(has_tips() & tip_interval > 0) ? tip(random_int(tip_seed, floor(time / tip_interval), tip_count())) : ''", 130 | "position_type": "BOTTOM_CENTER", 131 | "offset_pos": "BOTTOM_CENTER", 132 | "position": { "x": 0, "y": -10 } 133 | } 134 | } 135 | ], 136 | "factories": [ 137 | 138 | ], 139 | "actions": [ 140 | 141 | ] 142 | } 143 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/white.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | { 4 | "image": { 5 | "parent": "sample/flat_background", 6 | "colour": "dark_mode ? 0xFF_00_00_00 : 0xFF_FF_FF_FF" 7 | } 8 | }, 9 | { 10 | "image": "sample/mojang_splash", 11 | "should_render": "!dark_mode" 12 | }, 13 | { 14 | "image": "sample/mojang_splash_dark", 15 | "should_render": "dark_mode" 16 | }, 17 | "sample/loading_bar_boss", 18 | "sample/loading_bar_boss_percentage", 19 | { 20 | "image": { 21 | "parent": "sample/text_status", 22 | "colour": "dark_mode ? 0xFF_FF_FF_FF : 0xFF_00_00_00" 23 | } 24 | }, 25 | { 26 | "image": { 27 | "parent": "sample/text_sub_status", 28 | "colour": "dark_mode ? 0xFF_FF_FF_FF : 0xFF_00_00_00" 29 | } 30 | }, 31 | { 32 | "image": { 33 | "parent": "sample/text_percentage", 34 | "colour": "dark_mode ? 0xFF_FF_FF_FF : 0xFF_00_00_00" 35 | } 36 | } 37 | ], 38 | "functions": [ 39 | ], 40 | "factories": [ 41 | ], 42 | "actions": [ 43 | ], 44 | "variables": { 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/config/worldload.json: -------------------------------------------------------------------------------- 1 | { 2 | "renders": [ 3 | "sample/panorama", 4 | { 5 | "image": { 6 | "parent": "sample/dirt_background", 7 | "position_type": "BOTTOM_CENTER", 8 | "offset_pos": "BOTTOM_CENTER", 9 | "position": { 10 | "height": "4 * 16" 11 | }, 12 | "texture": { 13 | "height": "4" 14 | } 15 | } 16 | }, 17 | { 18 | "image": { 19 | "parent": "sample/bottom_bar", 20 | "position_type": "BOTTOM_LEFT", 21 | "offset_pos": "BOTTOM_LEFT", 22 | "colour": "0xFF_00_00_00", 23 | "position": { 24 | "width": "screen_width", 25 | "y": "-64" 26 | } 27 | } 28 | }, 29 | { 30 | "image": { 31 | "parent": "sample/bottom_bar", 32 | "position_type": "BOTTOM_LEFT", 33 | "offset_pos": "BOTTOM_LEFT", 34 | "colour": "0xFF_33_55_FF", 35 | "position": { 36 | "y": "-64" 37 | } 38 | } 39 | }, 40 | { 41 | "image": { 42 | "parent": "builtin/text", 43 | "text": "'hello'", 44 | "position": { "x": 0, "y": 0 } 45 | } 46 | } 47 | ], 48 | "functions": [ 49 | 50 | ], 51 | "variables": { 52 | 53 | }, 54 | "factories": [ 55 | 56 | ], 57 | "actions": [ 58 | 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/function/interpolate.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"interpolate", 3 | "function":"", 4 | "arguments":[ 5 | "min", 6 | "max", 7 | "time", 8 | "", 9 | "smoothen_start", 10 | "smoothen_end" 11 | ] 12 | } 13 | // Usage: interpolate(0,15,10,1) 14 | // Would interpolate between 0 and 15 over 10 seconds, from time, using smoothen as the power for each end -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/function/item_rotation.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "item_rotation", 3 | "function": "time * 50" 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/block_4_wide.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "position_type": "CENTER", 4 | "offset_pos": "CENTER", 5 | "texture": { 6 | "x": "0", 7 | "y": "0", 8 | "width": "4", 9 | "height": "1" 10 | }, 11 | "position": { 12 | "x": "0", 13 | "y": "-16", 14 | "width": "256", 15 | "height": "64" 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/block_4_wide_percentage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/block_4_wide", 3 | "texture": { 4 | "width": "4 * percentage" 5 | }, 6 | "position": { 7 | "x": "percentage * 128 - 128", 8 | "width": "128*2 * percentage" 9 | } 10 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/block_cake_inner_4_wide.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/block_4_wide_percentage", 3 | "image":"textures/blocks/cake_inner.png" 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/block_cake_side_4_wide.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/block_4_wide", 3 | "image":"textures/blocks/cake_side.png" 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/bottom_bar.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image": "customloadingscreen:textures/generic/white.png", 4 | "position_type": "BOTTOM_LEFT", 5 | "offset_pos": "BOTTOM_LEFT", 6 | "colour": "0xFF_77_77_FF", 7 | "position": { 8 | "x": "0", 9 | "y": "0", 10 | "width": "screen_width * percentage", 11 | "height": "5" 12 | }, 13 | "texture": { 14 | "x": "0", 15 | "y": "0", 16 | "width": "1", 17 | "height": "1" 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/cake.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/item", 3 | "image": "textures/items/cake.png", 4 | "position": { 5 | "x": "0", 6 | "y": "0", 7 | "width": "64", 8 | "height": "64" 9 | } 10 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/cake_bottom_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/cake", 3 | "position_type":"BOTTOM_LEFT", 4 | "offset_pos":"BOTTOM_LEFT" 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/cake_bottom_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/cake", 3 | "position_type":"BOTTOM_RIGHT", 4 | "offset_pos":"BOTTOM_RIGHT" 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/cake_top_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/cake", 3 | "position_type":"TOP_LEFT", 4 | "offset_pos":"TOP_LEFT" 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/cake_top_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/cake", 3 | "position_type":"TOP_RIGHT", 4 | "offset_pos":"TOP_RIGHT" 5 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/dirt_background.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image": "textures/blocks/dirt.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "colour": "0xFF_40_40_40", 7 | "position": { 8 | "x": "0", 9 | "y": "0", 10 | "width": "64 * 16", 11 | "height": "64 * 16" 12 | }, 13 | "texture": { 14 | "x": "0", 15 | "y": "0", 16 | "width": "64", 17 | "height": "64" 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/flat_background.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image": "customloadingscreen:textures/generic/white.png", 4 | "position_type": "TOP_LEFT", 5 | "offset_pos": "TOP_LEFT", 6 | "colour": "0xFF_40_40_40", 7 | "position": { 8 | "x": "0", 9 | "y": "0", 10 | "width": "screen_width", 11 | "height": "screen_height" 12 | }, 13 | "texture": { 14 | "x": "0", 15 | "y": "0", 16 | "width": "1", 17 | "height": "1" 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/horizontal_stripe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image": "customloadingscreen:textures/generic/darkened_blur_horizontal_strip.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "position": { 7 | "x": "0", 8 | "y": "0", 9 | "width": "screen_width", 10 | "height": "100" 11 | }, 12 | "texture": { 13 | "x": "0", 14 | "y": "0", 15 | "width": "1", 16 | "height": "1" 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/item.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "texture": { 4 | "x": "0", 5 | "y": "0", 6 | "width": "1", 7 | "height": "1" 8 | }, 9 | "shouldRender": "true", 10 | "frame": "0" 11 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/loading_bar_bevel.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/loading_bar_standard", 3 | "position":{ 4 | "y":"20", 5 | "height":"20", 6 | "width":"super * 2" 7 | }, 8 | "texture":{ 9 | "x": "0", 10 | "y": "70 / 256.0", 11 | "height": "10 / 256.0" 12 | } 13 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/loading_bar_bevel_percentage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/loading_bar_standard_percentage", 3 | "position":{ 4 | "x":"super * 2", 5 | "y":"20", 6 | "height":"20", 7 | "width":"super * 2" 8 | }, 9 | "texture":{ 10 | "x":"0", 11 | "y":"80 / 256.0", 12 | "height":"10 / 256.0" 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/loading_bar_boss.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/loading_bar_standard", 3 | "texture": { 4 | "y": "10 / 256.0" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/loading_bar_boss_percentage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"sample/loading_bar_standard_percentage", 3 | "texture": { 4 | "y": "15 / 256.0" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/loading_bar_standard.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image": "customloadingscreen:textures/progress_bars.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "position": { 7 | "x": "0", 8 | "y": "50", 9 | "width": "182", 10 | "height": "5" 11 | }, 12 | "texture": { 13 | "x": "0", 14 | "y": "0", 15 | "width": "182 / 256.0", 16 | "height": "5 / 256.0" 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/loading_bar_standard_percentage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image": "customloadingscreen:textures/progress_bars.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "position": { 7 | "x": "(percentage * 91) - 91", 8 | "y": "50", 9 | "width": "percentage * 182", 10 | "height": "5" 11 | }, 12 | "texture": { 13 | "x": "0", 14 | "y": "5 / 256.0", 15 | "width": "percentage * 182 / 256.0", 16 | "height": "5 / 256.0" 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/mojang_splash.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image":"textures/gui/title/mojang.png", 4 | "position_type":"CENTER", 5 | "offset_pos":"CENTER", 6 | "texture":{ 7 | "x":"0", 8 | "y":"0", 9 | "width":"1", 10 | "height":"1" 11 | }, 12 | "position":{ 13 | "x":"0", 14 | "y":"0", 15 | "width":"256", 16 | "height":"256" 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/mojang_splash_dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/image", 3 | "image":"textures/gui/title/mojang_dark.png", 4 | "position_type":"CENTER", 5 | "offset_pos":"CENTER", 6 | "texture":{ 7 | "x":"0", 8 | "y":"0", 9 | "width":"1", 10 | "height":"1" 11 | }, 12 | "position":{ 13 | "x":"0", 14 | "y":"0", 15 | "width":"256", 16 | "height":"256" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/panorama.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/panorama", 3 | "image": "textures/gui/title/background/panorama_x.png" 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_generic_error.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/text", 3 | "image": "textures/font/ascii.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "text": "error_message", 7 | "position": { 8 | "x": "0", 9 | "y": "40" 10 | }, 11 | "colour":"0xFF_FF_44_44" 12 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_percentage.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/text", 3 | "image": "textures/font/ascii.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "text": "(floor(percentage * 100)) + '%'", 7 | "position": { 8 | "x": "0", 9 | "y": "40", 10 | "width": "0", 11 | "height": "0" 12 | }, 13 | "colour":"0xFF000000" 14 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_percentage_scrolling.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/text_percentage", 3 | "position_type": "BOTTOM_LEFT", 4 | "offset_pos": "BOTTOM_LEFT", 5 | "position": { 6 | "x": "5", 7 | "y": "-20" 8 | }, 9 | "colour": "0xFFFFFFFF" 10 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_percentage_white.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/text_percentage", 3 | "position": { 4 | "y": "-10" 5 | }, 6 | "colour": "0xFFFFFFFF" 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/text", 3 | "image": "textures/font/ascii.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "text": "is_reloading ? status : (status + ': ' + sub_status)", 7 | "position": { 8 | "x": "0", 9 | "y": "30", 10 | "width": "0", 11 | "height": "0" 12 | }, 13 | "colour":"0xFF_00_00_00" 14 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_status_white.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/text_status", 3 | "position": { 4 | "y": "-20" 5 | }, 6 | "colour": "0xFF_FF_FF_FF" 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_sub_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "builtin/text", 3 | "image": "textures/font/ascii.png", 4 | "position_type": "CENTER", 5 | "offset_pos": "CENTER", 6 | "text": "is_reloading ? sub_status : ''", 7 | "position": { 8 | "x": "0", 9 | "y": "60", 10 | "width": "0", 11 | "height": "0" 12 | }, 13 | "colour":"0xFF_00_00_00" 14 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/image/text_sub_status_white.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sample/text_sub_status", 3 | "position": { 4 | "y": "0" 5 | }, 6 | "colour": "0xFF_FF_FF_FF" 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/imagemeta/rotating_cake_bottom_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "sample/cake_bottom_left", 3 | "instructions": [ 4 | "sample/item_rotate_clockwise" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/imagemeta/rotating_cake_bottom_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "sample/cake_bottom_right", 3 | "instructions": [ 4 | "sample/item_rotate_anti_clockwise" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/imagemeta/rotating_cake_top_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "sample/cake_top_left", 3 | "instructions": [ 4 | "sample/item_rotate_clockwise" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/imagemeta/rotating_cake_top_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "sample/cake_top_right", 3 | "instructions": [ 4 | "sample/item_rotate_anti_clockwise" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/instruction/item_rotate_anti_clockwise.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"builtin/rotate", 3 | "angle": "item_rotation / 10", 4 | "x": "0", 5 | "y": "0", 6 | "z": "-1" 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/sample/instruction/item_rotate_clockwise.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent":"builtin/rotate", 3 | "angle": "item_rotation / 10", 4 | "x": "0", 5 | "y": "0", 6 | "z": "1" 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/textures/generic/darkened_blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/assets/customloadingscreen/textures/generic/darkened_blur.png -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/textures/generic/darkened_blur_horizontal_strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/assets/customloadingscreen/textures/generic/darkened_blur_horizontal_strip.png -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/textures/generic/darkened_blur_vertical_strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/assets/customloadingscreen/textures/generic/darkened_blur_vertical_strip.png -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/textures/generic/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/assets/customloadingscreen/textures/generic/white.png -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/textures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/assets/customloadingscreen/textures/logo.png -------------------------------------------------------------------------------- /src/main/resources/assets/customloadingscreen/textures/progress_bars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/assets/customloadingscreen/textures/progress_bars.png -------------------------------------------------------------------------------- /src/main/resources/changelog/1.4.0.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIIL/CustomLoadingScreen/9855e14fba2787e6ff24949bde168a402fafa431/src/main/resources/changelog/1.4.0.txt -------------------------------------------------------------------------------- /src/main/resources/changelog/1.4.1.txt: -------------------------------------------------------------------------------- 1 | Changes: 2 | 3 | * Added compat for SplashAnimation. 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/changelog/1.5.1.txt: -------------------------------------------------------------------------------- 1 | Changes: 2 | 3 | * Added various random number functions: 4 | * generate_seed(): Generates a new (48 bit integer) seed for use in other functions. (This should be saved in constants). 5 | * random(seed): calls random_seeded(seed, 0) 6 | * random(seed, index): returns a random number (between 0 and 1) based on both the seed and index - the idea being that you'd keep the seed the same, and pass an ever-increasing index to grab the next value for that seed. 7 | * random_int(seed, max): calls random_int(seed, 0, max) 8 | * random_int(seed, index, max): returns a random integer between 0 and max-1. Internally this is just min(max - 1, random(seed, index) * max), but it's a lot easier to type this way. 9 | * Added "constants" as a root object to config.json 10 | * Unlike "variables" these are evaluated once only rather than once per frame. 11 | * These are ideal for storing random number seeds 12 | * Added "functions": 13 | * These are in the form "name(ArgType1 arg1, ArgType2 arg2)": "arg1 + arg2". 14 | * Updated "sample/slideshow" to use all 3 of the above features. In particular a few variables have been extracted out to the top of the file: 15 | * "image_interval", the number of seconds to display each slide for 16 | * "transition_duration", the number of seconds to transition from one slide to another. 17 | * "tip_interval", the number of seconds to wait between changing what tip is displayed. 18 | * "random_slide_order", This should be "true" to use a random slide each time rather than going sequentially. 19 | -------------------------------------------------------------------------------- /src/main/resources/changelog/1.5.3.txt: -------------------------------------------------------------------------------- 1 | Bug Fixes: 2 | 3 | * Fix non-constant colour handling treating components as either fully bright or off, rather than values ranging from 255 (100% brightness) to 0 (dark). 4 | -------------------------------------------------------------------------------- /src/main/resources/changelog/1.5.4.txt: -------------------------------------------------------------------------------- 1 | Bug Fixes: 2 | 3 | * Fix constant colours sometimes not applying properly. 4 | * Add a new function: "translate". This takes 1 string argument, and can be used to localize custom language strings (in addition to the built-in ones). 5 | * Print debug information about language paths when loading them. 6 | * Fix a NullPointerException being thrown when json resources aren't found. 7 | * Improve namespace handling for json resources. 8 | -------------------------------------------------------------------------------- /src/main/resources/changelog/1.5.5.txt: -------------------------------------------------------------------------------- 1 | Changes: 2 | 3 | * Now CLS creates an empty tips file ("config/customloadingscreen_tips.txt") if it doesn't already exist. 4 | * Stopped a few rendering parts from sharing state with the main thread. 5 | * Removed the warning when CLS fails to find a RENDERING_PART type but finds an IMAGE instead. 6 | -------------------------------------------------------------------------------- /src/main/resources/changelog/1.5.6.txt: -------------------------------------------------------------------------------- 1 | Changes: 2 | 3 | * Added always-created "example.json" json config, always added to config/customloadingscreen if it's not present. 4 | * You can use this by setting the "screen_config" setting to "config/example" 5 | * [#72] Theoretically fixed a crash while uploading textures. 6 | * CLS now de-allocates any RAM used for it's resources after minecraft has finished loading. 7 | * Added slightly better error messages when loading or baking "Area"s 8 | -------------------------------------------------------------------------------- /src/main/resources/changelog/1.5.9.txt: -------------------------------------------------------------------------------- 1 | Bug Fixes: 2 | 3 | - Fixed incorrect usage of OpenGL, causing "OpenGL Error 1280 GL_INVALID_ENUM" error messages to be generated. 4 | - Fixed the texture deletion system somtimes turning itself off, leading to out-of-memory errors. 5 | - This generally only happened when using slideshows with thousands of images (like for videos) 6 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "customloadingscreen", 4 | "name": "Custom Loading Screen", 5 | "description": "Simple mod that shows you the stage forge is at while loading minecraft", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "", 9 | "updateUrl": "", 10 | "authorList": ["AlexIIL"], 11 | "credits": "", 12 | "logoFile": "", 13 | "screenshots": [], 14 | "dependencies": [] 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /src/test/java/alexiil/mods/load/test/BasicTestMod.java: -------------------------------------------------------------------------------- 1 | package alexiil.mods.load.test; 2 | 3 | import net.minecraftforge.fml.common.Mod; 4 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 5 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 6 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 7 | 8 | @Mod(modid = "empty_test_mod_x") 9 | public class BasicTestMod { 10 | 11 | @Mod.EventHandler 12 | public void onPreInit(FMLPreInitializationEvent event) { 13 | TestModHelper.preInit(this, event); 14 | } 15 | 16 | @Mod.EventHandler 17 | public void onInit(FMLInitializationEvent event) { 18 | TestModHelper.preInit(this, event); 19 | } 20 | 21 | @Mod.EventHandler 22 | public void onPostInit(FMLPostInitializationEvent event) { 23 | TestModHelper.postInit(this, event); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/alexiil/mods/load/test/TestModHelper.java: -------------------------------------------------------------------------------- 1 | package alexiil.mods.load.test; 2 | 3 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 4 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 5 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 6 | 7 | public class TestModHelper { 8 | public static void preInit(Object mod, FMLPreInitializationEvent event) { 9 | // sleep(1000); 10 | } 11 | 12 | public static void preInit(Object mod, FMLInitializationEvent event) { 13 | // sleep(1000); 14 | } 15 | 16 | public static void postInit(Object mod, FMLPostInitializationEvent event) { 17 | // sleep(1000); 18 | } 19 | 20 | private static void sleep(int millis) { 21 | try { 22 | Thread.sleep(millis); 23 | } catch (InterruptedException e) { 24 | throw new Error(e); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/alexiil/mods/load/test/TestModVars.java: -------------------------------------------------------------------------------- 1 | package alexiil.mods.load.test; 2 | 3 | public class TestModVars { 4 | 5 | } 6 | --------------------------------------------------------------------------------