├── .gitattributes ├── .gitignore ├── EaglerBinaryTools.jar ├── LICENSE ├── README.md ├── build.gradle ├── generate_mdl_samples.bat ├── generate_mdl_samples.sh ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── samples ├── eagler-bmp-gen │ ├── eagler_moon.png │ ├── eagler_moon_brightness.png │ ├── eagler_moon_normals.png │ ├── lens_ghosts.png │ └── lens_streaks.png ├── ebp-encode │ ├── readme.txt │ └── textures │ │ ├── blocks │ │ ├── bed_feet_end_s.png │ │ ├── bed_feet_side_s.png │ │ ├── bed_feet_top_s.png │ │ ├── bed_head_end_s.png │ │ ├── bed_head_side_s.png │ │ ├── bed_head_top_s.png │ │ ├── bedrock_s.png │ │ ├── bookshelf_s.png │ │ ├── brewing_stand_base_s.png │ │ ├── brewing_stand_s.png │ │ ├── brick_s.png │ │ ├── cake_inner_s.png │ │ ├── cake_side_s.png │ │ ├── cake_top_s.png │ │ ├── coal_ore_s.png │ │ ├── coarse_dirt_s.png │ │ ├── cobblestone_mossy_s.png │ │ ├── cobblestone_s.png │ │ ├── comparator_off_s.png │ │ ├── comparator_on_s.png │ │ ├── crafting_table_front_s.png │ │ ├── crafting_table_side_s.png │ │ ├── crafting_table_top_s.png │ │ ├── diamond_block_s.png │ │ ├── diamond_ore_s.png │ │ ├── dirt_podzol_side_s.png │ │ ├── dirt_podzol_top_s.png │ │ ├── dirt_s.png │ │ ├── dispenser_front_horizontal_s.png │ │ ├── dispenser_front_vertical_s.png │ │ ├── door_acacia_lower_s.png │ │ ├── door_acacia_upper_s.png │ │ ├── door_birch_lower_s.png │ │ ├── door_birch_upper_s.png │ │ ├── door_dark_oak_lower_s.png │ │ ├── door_dark_oak_upper_s.png │ │ ├── door_jungle_lower_s.png │ │ ├── door_jungle_upper_s.png │ │ ├── door_spruce_lower_s.png │ │ ├── door_spruce_upper_s.png │ │ ├── door_wood_lower_s.png │ │ ├── door_wood_upper_s.png │ │ ├── dropper_front_horizontal_s.png │ │ ├── dropper_front_vertical_s.png │ │ ├── emerald_block_s.png │ │ ├── emerald_ore_s.png │ │ ├── enchanting_table_bottom_s.png │ │ ├── enchanting_table_side_s.png │ │ ├── enchanting_table_top_s.png │ │ ├── end_stone_s.png │ │ ├── endframe_side_s.png │ │ ├── endframe_top_s.png │ │ ├── farmland_dry_s.png │ │ ├── farmland_wet_s.png │ │ ├── furnace_front_off_s.png │ │ ├── furnace_front_on_s.png │ │ ├── furnace_side_s.png │ │ ├── furnace_top_s.png │ │ ├── gold_block_s.png │ │ ├── gold_ore_s.png │ │ ├── grass_side_overlay_s.png │ │ ├── grass_side_s.png │ │ ├── grass_side_snowed_s.png │ │ ├── grass_top_s.png │ │ ├── gravel_s.png │ │ ├── iron_block_s.png │ │ ├── iron_ore_s.png │ │ ├── lapis_block_s.png │ │ ├── lapis_ore_s.png │ │ ├── log_acacia_s.png │ │ ├── log_acacia_top_s.png │ │ ├── log_big_oak_s.png │ │ ├── log_big_oak_top_s.png │ │ ├── log_birch_s.png │ │ ├── log_birch_top_s.png │ │ ├── log_jungle_s.png │ │ ├── log_jungle_top_s.png │ │ ├── log_oak_s.png │ │ ├── log_oak_top_s.png │ │ ├── log_spruce_s.png │ │ ├── log_spruce_top_s.png │ │ ├── netherrack_s.png │ │ ├── obsidian_s.png │ │ ├── piston_bottom_s.png │ │ ├── piston_inner_s.png │ │ ├── piston_side_s.png │ │ ├── piston_top_normal_s.png │ │ ├── piston_top_sticky_s.png │ │ ├── planks_acacia_s.png │ │ ├── planks_big_oak_s.png │ │ ├── planks_birch_s.png │ │ ├── planks_jungle_s.png │ │ ├── planks_oak_s.png │ │ ├── planks_spruce_s.png │ │ ├── prismarine_bricks_s.png │ │ ├── prismarine_dark_s.png │ │ ├── prismarine_rough_s.png │ │ ├── pumpkin_face_off_s.png │ │ ├── pumpkin_face_on_s.png │ │ ├── quartz_block_bottom_s.png │ │ ├── quartz_block_chiseled_s.png │ │ ├── quartz_block_chiseled_top_s.png │ │ ├── quartz_block_lines_s.png │ │ ├── quartz_block_lines_top_s.png │ │ ├── quartz_block_side_s.png │ │ ├── quartz_block_top_s.png │ │ ├── quartz_ore_s.png │ │ ├── rail_activator_powered_s.png │ │ ├── rail_activator_s.png │ │ ├── rail_detector_powered_s.png │ │ ├── rail_detector_s.png │ │ ├── rail_golden_powered_s.png │ │ ├── rail_golden_s.png │ │ ├── rail_normal_s.png │ │ ├── rail_normal_turned_s.png │ │ ├── redstone_lamp_off_s.png │ │ ├── redstone_lamp_on_s.png │ │ ├── redstone_ore_s.png │ │ ├── redstone_torch_off_s.png │ │ ├── redstone_torch_on_s.png │ │ ├── repeater_off_s.png │ │ ├── repeater_on_s.png │ │ ├── sand_s.png │ │ ├── sandstone_bottom_s.png │ │ ├── sandstone_carved_s.png │ │ ├── sandstone_normal_s.png │ │ ├── sandstone_smooth_s.png │ │ ├── sandstone_top_s.png │ │ ├── soul_sand_s.png │ │ ├── stone_andesite_s.png │ │ ├── stone_andesite_smooth_s.png │ │ ├── stone_diorite_s.png │ │ ├── stone_diorite_smooth_s.png │ │ ├── stone_granite_s.png │ │ ├── stone_granite_smooth_s.png │ │ ├── stone_s.png │ │ ├── stone_slab_side_s.png │ │ ├── stone_slab_top_s.png │ │ ├── stonebrick_carved_s.png │ │ ├── stonebrick_cracked_s.png │ │ ├── stonebrick_mossy_s.png │ │ ├── stonebrick_s.png │ │ ├── tnt_bottom_s.png │ │ ├── tnt_side_s.png │ │ ├── tnt_top_s.png │ │ ├── torch_on_s.png │ │ ├── trapdoor_s.png │ │ └── trip_wire_source_s.png │ │ └── items │ │ ├── bow_pulling_0_s.png │ │ ├── bow_pulling_1_s.png │ │ ├── bow_pulling_2_s.png │ │ ├── bow_standby_s.png │ │ ├── brewing_stand_s.png │ │ ├── bucket_lava_s.png │ │ ├── bucket_milk_s.png │ │ ├── bucket_water_s.png │ │ ├── carrot_on_a_stick_s.png │ │ ├── clock_s.png │ │ ├── compass_s.png │ │ ├── diamond_axe_s.png │ │ ├── diamond_hoe_s.png │ │ ├── diamond_pickaxe_s.png │ │ ├── diamond_shovel_s.png │ │ ├── diamond_sword_s.png │ │ ├── fishing_rod_cast_s.png │ │ ├── fishing_rod_uncast_s.png │ │ ├── flint_and_steel_s.png │ │ ├── gold_axe_s.png │ │ ├── gold_hoe_s.png │ │ ├── gold_pickaxe_s.png │ │ ├── gold_shovel_s.png │ │ ├── gold_sword_s.png │ │ ├── iron_axe_s.png │ │ ├── iron_hoe_s.png │ │ ├── iron_pickaxe_s.png │ │ ├── iron_shovel_s.png │ │ ├── iron_sword_s.png │ │ ├── minecart_chest_s.png │ │ ├── minecart_command_block_s.png │ │ ├── minecart_furnace_s.png │ │ ├── minecart_tnt_s.png │ │ ├── shears_s.png │ │ ├── stone_axe_s.png │ │ ├── stone_hoe_s.png │ │ ├── stone_pickaxe_s.png │ │ ├── stone_shovel_s.png │ │ └── stone_sword_s.png ├── light-mesh-gen │ └── light_point_mesh.obj ├── obj2mdl-fnaw │ ├── charles.png │ ├── charles0.obj │ ├── charles1.obj │ ├── charles2_eyes.obj │ ├── laxativedude.png │ ├── laxativedude0.obj │ ├── laxativedude1.obj │ ├── laxativedude2.obj │ ├── laxativedude3_eyes.obj │ ├── longarms.png │ ├── longarms0.obj │ ├── longarms1.obj │ ├── longarms2_eyes.obj │ ├── weirdclimber.png │ ├── weirdclimber0.obj │ ├── weirdclimber1.obj │ ├── weirdclimber2_eyes.obj │ ├── winston.png │ ├── winston0.obj │ └── winston1_eyes.obj └── skybox-gen │ ├── skybox_bottom.obj │ └── skybox_top.obj ├── settings.gradle └── src ├── main └── java │ └── net │ └── lax1dude │ └── eaglercraft │ └── bintools │ ├── EBPFileDecoder.java │ ├── EBPFileEncoder.java │ ├── EPKCompiler.java │ ├── EPKCompilerLegacy.java │ ├── EPKDecompiler.java │ ├── EaglerBMPGen.java │ ├── EaglerBinaryTools.java │ ├── LightMeshGen.java │ ├── OBJConverter.java │ ├── OptimizedOBJConverter.java │ ├── SkyboxGen.java │ └── utils │ ├── EPKDecompilerSP.java │ ├── GZIPOutputStream2.java │ ├── IEEE754.java │ ├── IOUtils.java │ └── LabPBR2Eagler.java └── test └── java └── net └── lax1dude └── eaglercraft └── bintools └── TestOptimizedOBJConverter.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | 5 | *.bat text eol=crlf 6 | *.sh text eol=lf 7 | gradlew text eol=lf 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | bin 4 | 5 | .idea 6 | samples/obj2mdl-fnaw/output 7 | samples/obj2mdl-fnaw/tests 8 | build 9 | .gradle 10 | -------------------------------------------------------------------------------- /EaglerBinaryTools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/EaglerBinaryTools.jar -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2022-2024 lax1dude. All Rights Reserved. 3 | 4 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 5 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 6 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 7 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 8 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 9 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 10 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 11 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 12 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 13 | POSSIBILITY OF SUCH DAMAGE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eagler Binary Tools 2 | 3 | ### Open source tools for working with the various binary file formats invented for Eaglercraft (EPK, EBP, MDL, etc.) 4 | 5 | ### Previously unreleased source files for generating some official assets are included in this repository 6 | 7 | **(Including the original FNAW skins in OBJ format)** 8 | 9 | ## How to Use 10 | 11 | This is meant to be used from the command line. The minimum required Java version is 8 and it is recommended to add it to your PATH before continuing. Functions in this JAR file can also easily be called from other Java programs in order to program automation more easily. 12 | 13 | Download [EaglerBinaryTools.jar](https://github.com/lax1dude/eagler-binary-tools/raw/main/EaglerBinaryTools.jar) into a folder and run it by typing `java -jar EaglerBinaryTools.jar` into command prompt in that folder. Here is the default help message: 14 | 15 | ``` 16 | Usage: java -jar EaglerBinaryTools.jar [args...] 19 | - 'epkcompiler': Compile an EPK file from a folder 20 | - 'legacy-epkcompiler': Compile an EPK file in legacy format 21 | - 'epkdecompiler': Decompile an EPK file into a folder 22 | - 'obj2mdl-1.5': Compile FNAW skin MDL file for 1.5 23 | - 'obj2mdl-1.8': Compile FNAW skin MDL file for 1.8 24 | - 'ebp-encode': Encode EBP file from PNG 25 | - 'ebp-decode': Decode EBP file to PNG 26 | - 'skybox-gen': Generate skybox.dat from OBJ for shader packs 27 | - 'light-mesh-gen': Generate light_point_mesh.dat from OBJ for shader packs 28 | - 'eagler-bmp-gen': Generate moon and lens flare BMP textures from PNG 29 | for shader packs 30 | ``` 31 | 32 | ## 'epkcompiler': Compile an EPK file from a folder 33 | 34 | This is the same EPKCompiler included in Eaglercraft 1.5 and EaglercraftX 1.8 except modified to be more verbose and not require JZLib to work. 35 | 36 | The default compression type is `gzip` and the default file-type is `epk/resources`, eagler 1.5 worlds use compression `none` file-type `epk/world152` and eagler 1.8 worlds use compression `none` file-type `epk/world188`. This 'epkcompiler' prompt does not support Eaglercraft Beta 1.3, use 'legacy-epkcompiler' instead for that version. 37 | 38 | ``` 39 | Usage: epkcompiler [gzip|zlib|none] [file-type] 40 | ``` 41 | 42 | ## 'legacy-epkcompiler': Compile an EPK file in legacy format 43 | 44 | This is the EPKCompiler used in Eaglercraft Beta 1.3 and older versions of Eaglercraft 1.5 45 | 46 | Setting the compression type and headers is not part of the legacy format, the Eaglercraft Beta 1.3 client will load any EPK generated via this command regardless of its contents. 47 | 48 | ``` 49 | Usage: legacy-epkcompiler 50 | ``` 51 | 52 | ## 'epkdecompiler': Decompile an EPK file into a folder 53 | 54 | Up to this point you've probably been using ayunWebEPK whenever you need to decompile an EPK file, Eagler Binary Tools now includes the EPK reader class from the Eaglercraft 1.5 client and allows you to decompile an EPK file in your command prompt. Both modern and legacy EPK files are supported, the file type is detected automatically. 55 | 56 | ``` 57 | Usage: epkdecompiler 58 | ``` 59 | 60 | ## 'obj2mdl-1.5', 'obj2mdl-1.8': Compile FNAW skin MDL file 61 | 62 | If you would like to make resource packs to replace the FNAW skins with your own 3D models you can use the 'obj2mdl' prompt to generate Eaglercraft MDL files from Wavefront OBJ files. Most of the models are broken up into multiple parts in order to make simple animations easier to program. 63 | 64 | **The original FNAW skins are located in the "samples/obj2mdl-fnaw" folder on OBJ format** 65 | 66 | ``` 67 | Usage: obj2mdl-1.8 68 | Input file format is Wavefront OBJ file exported from your 3D modeling program 69 | Texture mode can be 'true' or 'false' to enable/disable exporting texture UV coordinates 70 | ``` 71 | 72 | Due to some limitations, there are two different versions of this format for Eaglercraft 1.5 and EaglercraftX 1.8 73 | 74 | If "texture mode" is `true`, the vertex position, normals, and UV coordinates will be exported with the mesh, use this for the body and arm parts of each model. 75 | 76 | If "texture mode" is `false`, only the vertex position and normals will be exported, use this for the eye parts of each model. 77 | 78 | The input mesh can only contain triangles, if you use Blender you can apply the "Triangulate" modifier to your mesh to tessellate all polygons with more than 3 sides into triangles. I believe there is also a checkbox in modern versions of Blender where you can do this automatically whenever you export the OBJ file. 79 | 80 | There are limits on the number of unique vertices a model can have, and large models can take up lots of VRAM, so make sure you reduce the poly count of your models as much as possible first. Blender has a "Decimate" modifier for reducing poly count automatically by merging a certain percentage of the neighboring faces together. 81 | 82 | Yes, you can use the Eaglercraft FNAW models to in your fan game. Please give credit to lax1dude though if possible. 83 | 84 | ## 'ebp-encode': Encode EBP file from PNG 85 | 86 | Eagler Bitwise Packed is a lossless indexed raster image format designed for compressing textures with a limited number of colors, the format allows for less than 8 bits per pixel to be used to store textures which leads to massive savings when the texture is using indexed color and has only has a few unique colors. The encoded files are then compressed a second time by distributing them inside a compressed EPK file or a ZIP file. The format is meant to be used in EaglercraftX 1.8 for storing the default PBR material resource pack, so there is no alpha channel, just RGB. 87 | 88 | **The default PBR material textures are located in the "samples/ebp-encode" folder in PNG format** 89 | 90 | ``` 91 | Usage: ebp-encode [--labPBR] "); 92 | ebp-encode [--labPBR] -r [output directory]"); 93 | ``` 94 | 95 | In the EaglercraftX 1.8 client, the EBP files for the default PBR resource pack are located in the "assets/eagler/glsl/deferred/assets_pbr" folder in the EPK. 96 | 97 | **EBP compression will often be ineffective unless you manually use image editing software to posterize the texture to between 2 and 7 colors. The fewer colors the better.** 98 | 99 | Do not make resource packs to replace these files because they will just be ignored, if you would like to make a PBR material resource pack for Eaglercraft you must use PNG files in the labPBR format and place them in "assets/minecraft/textures" instead. THE INCLUDED PNG FILES IN THIS REPOSITORY ARE NOT IN LabPBR FORMAT AND WILL NOT WORK FOR A RESOURCE PACK! 100 | 101 | If you are trying to compile PNG material texture files in labPBR format to EBP you can pass the `--labPBR` flag as the first argument to convert from labPBR to Eagler's internal format automatically. **Use this if you're compiling a vanilla labPBR resource pack to EBP** 102 | 103 | To obtain the default material texture pack in labPBR format, use `ebp-decode` on a copy of EaglercraftX 1.8's assets_pbr folder with the `--labPBR` option. This will allow you to correctly make a resource pack with the default PBR resource pack textures. 104 | 105 | ## 'ebp-decode': Decode EBP file to PNG 106 | 107 | This works the same as 'ebp-encode' except it can be used to convert EBP files back to PNG files for debug/exploration. 108 | 109 | ``` 110 | Usage: ebp-decode [--labPBR] 111 | ebp-decode [--labPBR] -r [output directory] 112 | ``` 113 | 114 | If you use the `--labPBR` option, the EBP files will automatically be converted to PNG files in labPBR format that can be used to make a resource pack for EaglercraftX 1.8 or the vanilla Optifine. 115 | 116 | ## 'skybox-gen': Generate skybox.dat from OBJ for shader packs 117 | 118 | EaglercraftX 1.8 clients include a file called "skybox.dat" in the deferred shaders folder. This file contains the special mesh used for the skybox used whenever shaders are enabled, along with a special lookup texture that is used when caching atmospheric scattering data. It's not as much of a "skybox" as it is a "skydome" in order to use per-vertex shading to interpolate between cached atmospheric scattering values. 119 | 120 | ``` 121 | Usage: skybox-gen 122 | Input file format is Wavefront OBJ file exported from your 3D modeling program 123 | The top and bottom shapes should combine to form one seamless dome/sphere when 124 | both are rendered in the same position. Make sure to flip the normals! 125 | ``` 126 | 127 | **The default skybox top and bottom are located in "samples/skybox-gen" in OBJ format** 128 | 129 | To generate your own skybox, you must break the mesh into a top and bottom half, and flip the normals so they are facing inward instead of outward. The mesh can only contain triangles, same deal as the FNAW models. 130 | 131 | Make sure the origin point of the mesh (0, 0, 0) is in the center where the player is meant to view the inside of the skybox from. 132 | 133 | ## 'light-mesh-gen': Generate light_point_mesh.dat from OBJ for shader packs 134 | 135 | One of the tricks EaglercraftX 1.8 uses to speed up dynamic lighting in shaders is to draw a spherical mesh on the screen using a matrix that rescales it to only cover the pixels affected by the current dynamic light being rendered, and then only calculate lighting on those pixels. The mesh used for this trick is stored in a file called "light_point_mesh.dat". 136 | 137 | ``` 138 | Usage: light-mesh-gen [mesh name] 139 | Input file format is Wavefront OBJ file exported from your 3D modeling program 140 | The only mesh name currently used by eagler is "light_point_mesh" 141 | ``` 142 | 143 | **The file used to generate "light_point_mesh.dat" is located in "samples/light-mesh-gen" in OBJ format** 144 | 145 | The mesh can only contain triangles and the maximum number of unique vertices is limited. 146 | 147 | ## 'eagler-bmp-gen': Generate moon and lens flare BMP textures from PNG for shader packs 148 | 149 | The files generated by this prompt are usually much larger than the input PNG file and are meant to be distributed inside a compressed EPK file or ZIP file. EPK, PNG, and ZIP files are all based on the same compression so it makes a lot of sense to not redundantly compress this file's contents multiple times if its gonna be distributed in a compressed archive anyway. 150 | 151 | ``` 152 | Usage: eagler-bmp-gen <--red|--rgba> 153 | The texture's width and height must be a power of 2! 154 | ``` 155 | 156 | **The files required to generate lens_streaks.bmp, lens_ghosts.bmp, and eagler_moon.bmp are located in "samples/eagler-bmp-gen" in PNG format** 157 | 158 | For lens_streaks.bmp and lens_ghosts.bmp, run the command with `--red` to generate grayscale Eagler BMP textures from the red channel of the PNG files. 159 | 160 | For eagler_moon.bmp, run the command with `--rgba` to generate RGBA Eagler BMP files from the PNG files. 161 | 162 | Mipmap levels will be generated automatically and embedded in the Eagler BMP file. 163 | 164 | ## Compiling and Contributing 165 | 166 | The code in the `src/main/java` folder is written in plain Java. There are no dependencies besides what is already included by default in the JRE & JUnit for tests. Minimum required Java version is 8, just run `gradlew build`. 167 | 168 | **For a PR:** Tabs, not spaces, and format the code like the Eclipse auto format tool on factory settings. -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | group = 'net.lax1dude.eaglercraft.bintools' 6 | version = '' 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | sourceSets { 13 | main { 14 | java { 15 | srcDir 'src/main/java' 16 | } 17 | } 18 | } 19 | 20 | dependencies { 21 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' 22 | testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.2' 23 | testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.2' 24 | } 25 | 26 | java { 27 | sourceCompatibility = JavaVersion.VERSION_1_8 28 | targetCompatibility = JavaVersion.VERSION_1_8 29 | } 30 | 31 | jar { 32 | compileJava.options.encoding = 'UTF-8' 33 | javadoc.options.encoding = 'UTF-8' 34 | javadoc.options.addStringOption('Xdoclint:none', '-quiet') 35 | 36 | manifest { 37 | attributes( 38 | 'Main-Class': 'net.lax1dude.eaglercraft.bintools.EaglerBinaryTools' 39 | ) 40 | } 41 | } 42 | 43 | test { 44 | useJUnitPlatform() 45 | } -------------------------------------------------------------------------------- /generate_mdl_samples.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title Generate_MDLs 3 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/charles0.obj samples/obj2mdl-fnaw/output/charles0.mdl true 4 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/charles1.obj samples/obj2mdl-fnaw/output/charles1.mdl true 5 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/charles2_eyes.obj samples/obj2mdl-fnaw/output/charles2.mdl false 6 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude0.obj samples/obj2mdl-fnaw/output/laxativedude0.mdl true 7 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude1.obj samples/obj2mdl-fnaw/output/laxativedude1.mdl true 8 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude2.obj samples/obj2mdl-fnaw/output/laxativedude2.mdl true 9 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude3_eyes.obj samples/obj2mdl-fnaw/output/laxativedude3.mdl false 10 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/longarms0.obj samples/obj2mdl-fnaw/output/longarms0.mdl true 11 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/longarms1.obj samples/obj2mdl-fnaw/output/longarms1.mdl true 12 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/longarms2_eyes.obj samples/obj2mdl-fnaw/output/longarms2.mdl false 13 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/weirdclimber0.obj samples/obj2mdl-fnaw/output/weirdclimber0.mdl true 14 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/weirdclimber1.obj samples/obj2mdl-fnaw/output/weirdclimber1.mdl true 15 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/weirdclimber2_eyes.obj samples/obj2mdl-fnaw/output/weirdclimber2.mdl false 16 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/winston0.obj samples/obj2mdl-fnaw/output/winston0.mdl true 17 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/winston1_eyes.obj samples/obj2mdl-fnaw/output/winston1.mdl false 18 | pause -------------------------------------------------------------------------------- /generate_mdl_samples.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/charles0.obj samples/obj2mdl-fnaw/output/charles0.mdl true 3 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/charles1.obj samples/obj2mdl-fnaw/output/charles1.mdl true 4 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/charles2_eyes.obj samples/obj2mdl-fnaw/output/charles2.mdl false 5 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude0.obj samples/obj2mdl-fnaw/output/laxativedude0.mdl true 6 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude1.obj samples/obj2mdl-fnaw/output/laxativedude1.mdl true 7 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude2.obj samples/obj2mdl-fnaw/output/laxativedude2.mdl true 8 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/laxativedude3_eyes.obj samples/obj2mdl-fnaw/output/laxativedude3.mdl false 9 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/longarms0.obj samples/obj2mdl-fnaw/output/longarms0.mdl true 10 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/longarms1.obj samples/obj2mdl-fnaw/output/longarms1.mdl true 11 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/longarms2_eyes.obj samples/obj2mdl-fnaw/output/longarms2.mdl false 12 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/weirdclimber0.obj samples/obj2mdl-fnaw/output/weirdclimber0.mdl true 13 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/weirdclimber1.obj samples/obj2mdl-fnaw/output/weirdclimber1.mdl true 14 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/weirdclimber2_eyes.obj samples/obj2mdl-fnaw/output/weirdclimber2.mdl false 15 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/winston0.obj samples/obj2mdl-fnaw/output/winston0.mdl true 16 | java -jar EaglerBinaryTools.jar obj2mdl1.8 samples/obj2mdl-fnaw/winston1_eyes.obj samples/obj2mdl-fnaw/output/winston1.mdl false 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jun 20 10:14:47 CDT 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /samples/eagler-bmp-gen/eagler_moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/eagler-bmp-gen/eagler_moon.png -------------------------------------------------------------------------------- /samples/eagler-bmp-gen/eagler_moon_brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/eagler-bmp-gen/eagler_moon_brightness.png -------------------------------------------------------------------------------- /samples/eagler-bmp-gen/eagler_moon_normals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/eagler-bmp-gen/eagler_moon_normals.png -------------------------------------------------------------------------------- /samples/eagler-bmp-gen/lens_ghosts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/eagler-bmp-gen/lens_ghosts.png -------------------------------------------------------------------------------- /samples/eagler-bmp-gen/lens_streaks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/eagler-bmp-gen/lens_streaks.png -------------------------------------------------------------------------------- /samples/ebp-encode/readme.txt: -------------------------------------------------------------------------------- 1 | DO NOT USE THESE IN YOUR EAGLERCRAFT RESOURCE PACK, THEY WILL NOT RENDER CORRECTLY! 2 | 3 | EAGLERCRAFT EXPECTS PNGs IN RESOURCE PACKS TO BE IN LabPBR FORMAT! 4 | 5 | These are meant to be encoded to EBP and placed in the "assets/eagler/glsl/deferred/assets_pbr" directory of assets.epk 6 | 7 | Only for client development! 8 | -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bed_feet_end_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bed_feet_end_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bed_feet_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bed_feet_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bed_feet_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bed_feet_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bed_head_end_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bed_head_end_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bed_head_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bed_head_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bed_head_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bed_head_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bedrock_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bedrock_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/bookshelf_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/bookshelf_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/brewing_stand_base_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/brewing_stand_base_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/brewing_stand_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/brewing_stand_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/brick_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/brick_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/cake_inner_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/cake_inner_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/cake_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/cake_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/cake_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/cake_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/coal_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/coal_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/coarse_dirt_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/coarse_dirt_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/cobblestone_mossy_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/cobblestone_mossy_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/cobblestone_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/cobblestone_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/comparator_off_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/comparator_off_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/comparator_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/comparator_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/crafting_table_front_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/crafting_table_front_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/crafting_table_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/crafting_table_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/crafting_table_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/crafting_table_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/diamond_block_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/diamond_block_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/diamond_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/diamond_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dirt_podzol_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dirt_podzol_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dirt_podzol_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dirt_podzol_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dirt_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dirt_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dispenser_front_horizontal_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dispenser_front_horizontal_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dispenser_front_vertical_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dispenser_front_vertical_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_acacia_lower_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_acacia_lower_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_acacia_upper_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_acacia_upper_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_birch_lower_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_birch_lower_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_birch_upper_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_birch_upper_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_dark_oak_lower_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_dark_oak_lower_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_dark_oak_upper_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_dark_oak_upper_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_jungle_lower_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_jungle_lower_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_jungle_upper_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_jungle_upper_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_spruce_lower_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_spruce_lower_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_spruce_upper_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_spruce_upper_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_wood_lower_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_wood_lower_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/door_wood_upper_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/door_wood_upper_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dropper_front_horizontal_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dropper_front_horizontal_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/dropper_front_vertical_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/dropper_front_vertical_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/emerald_block_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/emerald_block_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/emerald_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/emerald_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/enchanting_table_bottom_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/enchanting_table_bottom_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/enchanting_table_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/enchanting_table_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/enchanting_table_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/enchanting_table_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/end_stone_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/end_stone_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/endframe_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/endframe_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/endframe_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/endframe_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/farmland_dry_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/farmland_dry_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/farmland_wet_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/farmland_wet_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/furnace_front_off_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/furnace_front_off_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/furnace_front_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/furnace_front_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/furnace_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/furnace_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/furnace_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/furnace_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/gold_block_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/gold_block_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/gold_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/gold_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/grass_side_overlay_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/grass_side_overlay_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/grass_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/grass_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/grass_side_snowed_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/grass_side_snowed_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/grass_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/grass_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/gravel_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/gravel_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/iron_block_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/iron_block_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/iron_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/iron_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/lapis_block_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/lapis_block_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/lapis_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/lapis_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_acacia_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_acacia_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_acacia_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_acacia_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_big_oak_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_big_oak_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_big_oak_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_big_oak_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_birch_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_birch_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_birch_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_birch_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_jungle_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_jungle_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_jungle_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_jungle_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_oak_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_oak_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_oak_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_oak_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_spruce_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_spruce_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/log_spruce_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/log_spruce_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/netherrack_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/netherrack_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/obsidian_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/obsidian_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/piston_bottom_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/piston_bottom_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/piston_inner_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/piston_inner_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/piston_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/piston_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/piston_top_normal_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/piston_top_normal_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/piston_top_sticky_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/piston_top_sticky_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/planks_acacia_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/planks_acacia_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/planks_big_oak_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/planks_big_oak_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/planks_birch_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/planks_birch_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/planks_jungle_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/planks_jungle_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/planks_oak_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/planks_oak_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/planks_spruce_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/planks_spruce_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/prismarine_bricks_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/prismarine_bricks_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/prismarine_dark_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/prismarine_dark_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/prismarine_rough_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/prismarine_rough_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/pumpkin_face_off_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/pumpkin_face_off_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/pumpkin_face_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/pumpkin_face_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_bottom_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_bottom_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_chiseled_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_chiseled_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_chiseled_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_chiseled_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_lines_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_lines_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_lines_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_lines_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_block_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_block_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/quartz_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/quartz_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_activator_powered_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_activator_powered_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_activator_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_activator_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_detector_powered_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_detector_powered_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_detector_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_detector_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_golden_powered_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_golden_powered_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_golden_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_golden_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_normal_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_normal_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/rail_normal_turned_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/rail_normal_turned_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/redstone_lamp_off_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/redstone_lamp_off_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/redstone_lamp_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/redstone_lamp_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/redstone_ore_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/redstone_ore_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/redstone_torch_off_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/redstone_torch_off_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/redstone_torch_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/redstone_torch_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/repeater_off_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/repeater_off_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/repeater_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/repeater_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/sand_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/sand_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/sandstone_bottom_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/sandstone_bottom_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/sandstone_carved_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/sandstone_carved_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/sandstone_normal_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/sandstone_normal_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/sandstone_smooth_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/sandstone_smooth_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/sandstone_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/sandstone_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/soul_sand_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/soul_sand_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_andesite_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_andesite_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_andesite_smooth_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_andesite_smooth_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_diorite_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_diorite_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_diorite_smooth_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_diorite_smooth_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_granite_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_granite_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_granite_smooth_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_granite_smooth_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_slab_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_slab_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stone_slab_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stone_slab_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stonebrick_carved_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stonebrick_carved_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stonebrick_cracked_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stonebrick_cracked_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stonebrick_mossy_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stonebrick_mossy_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/stonebrick_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/stonebrick_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/tnt_bottom_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/tnt_bottom_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/tnt_side_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/tnt_side_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/tnt_top_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/tnt_top_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/torch_on_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/torch_on_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/trapdoor_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/trapdoor_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/blocks/trip_wire_source_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/blocks/trip_wire_source_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bow_pulling_0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bow_pulling_0_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bow_pulling_1_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bow_pulling_1_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bow_pulling_2_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bow_pulling_2_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bow_standby_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bow_standby_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/brewing_stand_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/brewing_stand_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bucket_lava_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bucket_lava_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bucket_milk_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bucket_milk_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/bucket_water_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/bucket_water_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/carrot_on_a_stick_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/carrot_on_a_stick_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/clock_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/clock_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/compass_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/compass_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/diamond_axe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/diamond_axe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/diamond_hoe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/diamond_hoe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/diamond_pickaxe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/diamond_pickaxe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/diamond_shovel_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/diamond_shovel_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/diamond_sword_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/diamond_sword_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/fishing_rod_cast_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/fishing_rod_cast_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/fishing_rod_uncast_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/fishing_rod_uncast_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/flint_and_steel_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/flint_and_steel_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/gold_axe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/gold_axe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/gold_hoe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/gold_hoe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/gold_pickaxe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/gold_pickaxe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/gold_shovel_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/gold_shovel_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/gold_sword_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/gold_sword_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/iron_axe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/iron_axe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/iron_hoe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/iron_hoe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/iron_pickaxe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/iron_pickaxe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/iron_shovel_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/iron_shovel_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/iron_sword_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/iron_sword_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/minecart_chest_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/minecart_chest_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/minecart_command_block_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/minecart_command_block_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/minecart_furnace_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/minecart_furnace_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/minecart_tnt_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/minecart_tnt_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/shears_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/shears_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/stone_axe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/stone_axe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/stone_hoe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/stone_hoe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/stone_pickaxe_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/stone_pickaxe_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/stone_shovel_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/stone_shovel_s.png -------------------------------------------------------------------------------- /samples/ebp-encode/textures/items/stone_sword_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/ebp-encode/textures/items/stone_sword_s.png -------------------------------------------------------------------------------- /samples/light-mesh-gen/light_point_mesh.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.93.0 OBJ File: '' 2 | # www.blender.org 3 | mtllib eagler point mesh.mtl 4 | o Icosphere 5 | v 0.000000 -1.000000 0.000000 6 | v 0.723607 -0.447220 0.525725 7 | v -0.276388 -0.447220 0.850649 8 | v -0.894426 -0.447216 0.000000 9 | v -0.276388 -0.447220 -0.850649 10 | v 0.723607 -0.447220 -0.525725 11 | v 0.276388 0.447220 0.850649 12 | v -0.723607 0.447220 0.525725 13 | v -0.723607 0.447220 -0.525725 14 | v 0.276388 0.447220 -0.850649 15 | v 0.894426 0.447216 0.000000 16 | v 0.000000 1.000000 0.000000 17 | v -0.162456 -0.850654 0.499995 18 | v 0.425323 -0.850654 0.309011 19 | v 0.262869 -0.525738 0.809012 20 | v 0.850648 -0.525736 0.000000 21 | v 0.425323 -0.850654 -0.309011 22 | v -0.525730 -0.850652 0.000000 23 | v -0.688189 -0.525736 0.499997 24 | v -0.162456 -0.850654 -0.499995 25 | v -0.688189 -0.525736 -0.499997 26 | v 0.262869 -0.525738 -0.809012 27 | v 0.951058 0.000000 0.309013 28 | v 0.951058 0.000000 -0.309013 29 | v 0.000000 0.000000 1.000000 30 | v 0.587786 0.000000 0.809017 31 | v -0.951058 0.000000 0.309013 32 | v -0.587786 0.000000 0.809017 33 | v -0.587786 0.000000 -0.809017 34 | v -0.951058 0.000000 -0.309013 35 | v 0.587786 0.000000 -0.809017 36 | v 0.000000 0.000000 -1.000000 37 | v 0.688189 0.525736 0.499997 38 | v -0.262869 0.525738 0.809012 39 | v -0.850648 0.525736 0.000000 40 | v -0.262869 0.525738 -0.809012 41 | v 0.688189 0.525736 -0.499997 42 | v 0.162456 0.850654 0.499995 43 | v 0.525730 0.850652 0.000000 44 | v -0.425323 0.850654 0.309011 45 | v -0.425323 0.850654 -0.309011 46 | v 0.162456 0.850654 -0.499995 47 | vt 0.181819 0.000000 48 | vt 0.136365 0.078731 49 | vt 0.227273 0.078731 50 | vt 0.272728 0.157461 51 | vt 0.363637 0.157461 52 | vt 0.318182 0.078731 53 | vt 0.909091 0.000000 54 | vt 0.863636 0.078731 55 | vt 0.954545 0.078731 56 | vt 0.727273 0.000000 57 | vt 0.681818 0.078731 58 | vt 0.772727 0.078731 59 | vt 0.545455 0.000000 60 | vt 0.500000 0.078731 61 | vt 0.590909 0.078731 62 | vt 0.318182 0.236191 63 | vt 0.090910 0.157461 64 | vt 0.136365 0.236191 65 | vt 0.181819 0.157461 66 | vt 0.818182 0.157461 67 | vt 0.863636 0.236191 68 | vt 0.909091 0.157461 69 | vt 0.636364 0.157461 70 | vt 0.681818 0.236191 71 | vt 0.727273 0.157461 72 | vt 0.454546 0.157461 73 | vt 0.500000 0.236191 74 | vt 0.545455 0.157461 75 | vt 0.227273 0.236191 76 | vt 0.045455 0.236191 77 | vt 0.772727 0.236191 78 | vt 0.590909 0.236191 79 | vt 0.409092 0.236191 80 | vt 0.181819 0.314921 81 | vt 0.227273 0.393651 82 | vt 0.272728 0.314921 83 | vt 0.000000 0.314921 84 | vt 0.045455 0.393651 85 | vt 0.090910 0.314921 86 | vt 0.727273 0.314921 87 | vt 0.772727 0.393651 88 | vt 0.818182 0.314921 89 | vt 0.545455 0.314921 90 | vt 0.590909 0.393651 91 | vt 0.636364 0.314921 92 | vt 0.363637 0.314921 93 | vt 0.409092 0.393651 94 | vt 0.454546 0.314921 95 | vt 0.454546 0.472382 96 | vt 0.500000 0.393651 97 | vt 0.636364 0.472382 98 | vt 0.681818 0.393651 99 | vt 0.818182 0.472382 100 | vt 0.863636 0.393651 101 | vt 0.909091 0.314921 102 | vt 0.090910 0.472382 103 | vt 0.136365 0.393651 104 | vt 0.272728 0.472382 105 | vt 0.318182 0.393651 106 | vt 0.954545 0.236191 107 | vt 1.000000 0.157461 108 | vt 0.409092 0.078731 109 | vt 0.363637 0.000000 110 | vn -0.1024 0.9435 -0.3151 111 | vn -0.7002 0.6617 -0.2680 112 | vn 0.2680 0.9435 -0.1947 113 | vn 0.2680 0.9435 0.1947 114 | vn -0.1024 0.9435 0.3151 115 | vn -0.9050 0.3304 -0.2680 116 | vn -0.0247 0.3304 -0.9435 117 | vn 0.8897 0.3304 -0.3151 118 | vn 0.5746 0.3304 0.7488 119 | vn -0.5346 0.3304 0.7779 120 | vn -0.8026 0.1256 -0.5831 121 | vn 0.3066 0.1256 -0.9435 122 | vn 0.9921 0.1256 0.0000 123 | vn 0.3066 0.1256 0.9435 124 | vn -0.8026 0.1256 0.5831 125 | vn -0.4089 -0.6617 -0.6284 126 | vn 0.4713 -0.6617 -0.5831 127 | vn 0.7002 -0.6617 0.2680 128 | vn -0.0385 -0.6617 0.7488 129 | vn -0.7240 -0.6617 0.1947 130 | vn -0.2680 -0.9435 0.1947 131 | vn -0.4911 -0.7947 0.3568 132 | vn -0.4089 -0.6617 0.6284 133 | vn 0.1024 -0.9435 0.3151 134 | vn 0.1876 -0.7947 0.5773 135 | vn 0.4713 -0.6617 0.5831 136 | vn 0.3313 -0.9435 0.0000 137 | vn 0.6071 -0.7947 0.0000 138 | vn 0.7002 -0.6617 -0.2680 139 | vn 0.1024 -0.9435 -0.3151 140 | vn 0.1876 -0.7947 -0.5773 141 | vn -0.0385 -0.6617 -0.7488 142 | vn -0.2680 -0.9435 -0.1947 143 | vn -0.4911 -0.7947 -0.3568 144 | vn -0.7240 -0.6617 -0.1947 145 | vn -0.8897 -0.3304 0.3151 146 | vn -0.7947 -0.1876 0.5773 147 | vn -0.5746 -0.3304 0.7488 148 | vn 0.0247 -0.3304 0.9435 149 | vn 0.3035 -0.1876 0.9342 150 | vn 0.5346 -0.3304 0.7779 151 | vn 0.9050 -0.3304 0.2680 152 | vn 0.9822 -0.1876 0.0000 153 | vn 0.9050 -0.3304 -0.2680 154 | vn 0.5346 -0.3304 -0.7779 155 | vn 0.3035 -0.1876 -0.9342 156 | vn 0.0247 -0.3304 -0.9435 157 | vn -0.5746 -0.3304 -0.7488 158 | vn -0.7947 -0.1876 -0.5773 159 | vn -0.8897 -0.3304 -0.3151 160 | vn -0.3066 -0.1256 0.9435 161 | vn -0.3035 0.1876 0.9342 162 | vn -0.0247 0.3304 0.9435 163 | vn 0.8026 -0.1256 0.5831 164 | vn 0.7947 0.1876 0.5773 165 | vn 0.8897 0.3304 0.3151 166 | vn 0.8026 -0.1256 -0.5831 167 | vn 0.7947 0.1876 -0.5773 168 | vn 0.5746 0.3304 -0.7488 169 | vn -0.3066 -0.1256 -0.9435 170 | vn -0.3035 0.1876 -0.9342 171 | vn -0.5346 0.3304 -0.7779 172 | vn -0.9921 -0.1256 0.0000 173 | vn -0.9822 0.1876 0.0000 174 | vn -0.9050 0.3304 0.2680 175 | vn -0.4713 0.6617 0.5831 176 | vn -0.1876 0.7947 0.5773 177 | vn 0.0385 0.6617 0.7488 178 | vn 0.4089 0.6617 0.6284 179 | vn 0.4911 0.7947 0.3568 180 | vn 0.7240 0.6617 0.1947 181 | vn 0.7240 0.6617 -0.1947 182 | vn 0.4911 0.7947 -0.3568 183 | vn 0.4089 0.6617 -0.6284 184 | vn -0.7002 0.6617 0.2680 185 | vn -0.6071 0.7947 0.0000 186 | vn -0.3313 0.9435 0.0000 187 | vn 0.0385 0.6617 -0.7488 188 | vn -0.1876 0.7947 -0.5773 189 | vn -0.4713 0.6617 -0.5831 190 | usemtl None 191 | s off 192 | f 1/1/1 13/2/1 14/3/1 193 | f 2/4/2 16/5/2 14/6/2 194 | f 1/7/3 18/8/3 13/9/3 195 | f 1/10/4 20/11/4 18/12/4 196 | f 1/13/5 17/14/5 20/15/5 197 | f 2/4/6 23/16/6 16/5/6 198 | f 3/17/7 25/18/7 15/19/7 199 | f 4/20/8 27/21/8 19/22/8 200 | f 5/23/9 29/24/9 21/25/9 201 | f 6/26/10 31/27/10 22/28/10 202 | f 2/4/11 26/29/11 23/16/11 203 | f 3/17/12 28/30/12 25/18/12 204 | f 4/20/13 30/31/13 27/21/13 205 | f 5/23/14 32/32/14 29/24/14 206 | f 6/26/15 24/33/15 31/27/15 207 | f 7/34/16 38/35/16 33/36/16 208 | f 8/37/17 40/38/17 34/39/17 209 | f 9/40/18 41/41/18 35/42/18 210 | f 10/43/19 42/44/19 36/45/19 211 | f 11/46/20 39/47/20 37/48/20 212 | f 39/47/21 12/49/21 42/50/21 213 | f 39/47/22 42/50/22 37/48/22 214 | f 37/48/23 42/50/23 10/43/23 215 | f 42/44/24 12/51/24 41/52/24 216 | f 42/44/25 41/52/25 36/45/25 217 | f 36/45/26 41/52/26 9/40/26 218 | f 41/41/27 12/53/27 40/54/27 219 | f 41/41/28 40/54/28 35/42/28 220 | f 35/42/29 40/54/29 8/55/29 221 | f 40/38/30 12/56/30 38/57/30 222 | f 40/38/31 38/57/31 34/39/31 223 | f 34/39/32 38/57/32 7/34/32 224 | f 38/35/33 12/58/33 39/59/33 225 | f 38/35/34 39/59/34 33/36/34 226 | f 33/36/35 39/59/35 11/46/35 227 | f 24/33/36 11/46/36 37/48/36 228 | f 24/33/37 37/48/37 31/27/37 229 | f 31/27/38 37/48/38 10/43/38 230 | f 32/32/39 10/43/39 36/45/39 231 | f 32/32/40 36/45/40 29/24/40 232 | f 29/24/41 36/45/41 9/40/41 233 | f 30/31/42 9/40/42 35/42/42 234 | f 30/31/43 35/42/43 27/21/43 235 | f 27/21/44 35/42/44 8/55/44 236 | f 28/30/45 8/37/45 34/39/45 237 | f 28/30/46 34/39/46 25/18/46 238 | f 25/18/47 34/39/47 7/34/47 239 | f 26/29/48 7/34/48 33/36/48 240 | f 26/29/49 33/36/49 23/16/49 241 | f 23/16/50 33/36/50 11/46/50 242 | f 31/27/51 10/43/51 32/32/51 243 | f 31/27/52 32/32/52 22/28/52 244 | f 22/28/53 32/32/53 5/23/53 245 | f 29/24/54 9/40/54 30/31/54 246 | f 29/24/55 30/31/55 21/25/55 247 | f 21/25/56 30/31/56 4/20/56 248 | f 27/21/57 8/55/57 28/60/57 249 | f 27/21/58 28/60/58 19/22/58 250 | f 19/22/59 28/60/59 3/61/59 251 | f 25/18/60 7/34/60 26/29/60 252 | f 25/18/61 26/29/61 15/19/61 253 | f 15/19/62 26/29/62 2/4/62 254 | f 23/16/63 11/46/63 24/33/63 255 | f 23/16/64 24/33/64 16/5/64 256 | f 16/5/65 24/33/65 6/26/65 257 | f 17/14/66 6/26/66 22/28/66 258 | f 17/14/67 22/28/67 20/15/67 259 | f 20/15/68 22/28/68 5/23/68 260 | f 20/11/69 5/23/69 21/25/69 261 | f 20/11/70 21/25/70 18/12/70 262 | f 18/12/71 21/25/71 4/20/71 263 | f 18/8/72 4/20/72 19/22/72 264 | f 18/8/73 19/22/73 13/9/73 265 | f 13/9/74 19/22/74 3/61/74 266 | f 16/5/75 6/26/75 17/62/75 267 | f 16/5/76 17/62/76 14/6/76 268 | f 14/6/77 17/62/77 1/63/77 269 | f 13/2/78 3/17/78 15/19/78 270 | f 13/2/79 15/19/79 14/3/79 271 | f 14/3/80 15/19/80 2/4/80 272 | -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/charles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/obj2mdl-fnaw/charles.png -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/charles2_eyes.obj: -------------------------------------------------------------------------------- 1 | # Blender v3.1.2 OBJ File: '' 2 | # www.blender.org 3 | o Icosphere.003 4 | v -0.346525 1.767899 -0.426693 5 | v -0.328209 1.781891 -0.421344 6 | v -0.353521 1.781891 -0.418039 7 | v -0.369165 1.781891 -0.426693 8 | v -0.353521 1.781891 -0.435347 9 | v -0.328209 1.781891 -0.432041 10 | v -0.339529 1.804531 -0.418039 11 | v -0.364841 1.804531 -0.421344 12 | v -0.364841 1.804531 -0.432041 13 | v -0.339529 1.804531 -0.435347 14 | v -0.323885 1.804531 -0.426693 15 | v -0.346525 1.818523 -0.426693 16 | v 0.409699 1.746245 -0.423378 17 | v 0.428745 1.760796 -0.417816 18 | v 0.402424 1.760796 -0.414379 19 | v 0.386156 1.760796 -0.423378 20 | v 0.402424 1.760796 -0.432378 21 | v 0.428745 1.760796 -0.428940 22 | v 0.416974 1.784338 -0.414379 23 | v 0.390652 1.784338 -0.417816 24 | v 0.390652 1.784338 -0.428940 25 | v 0.416974 1.784338 -0.432378 26 | v 0.433241 1.784338 -0.423378 27 | v 0.409699 1.798889 -0.423378 28 | vt 0.181819 0.000000 29 | vt 0.272728 0.157461 30 | vt 0.090910 0.157461 31 | vt 0.363637 0.000000 32 | vt 0.454546 0.157461 33 | vt 0.909091 0.000000 34 | vt 1.000000 0.157461 35 | vt 0.818182 0.157461 36 | vt 0.727273 0.000000 37 | vt 0.636364 0.157461 38 | vt 0.545455 0.000000 39 | vt 0.363637 0.314921 40 | vt 0.181819 0.314921 41 | vt 0.909091 0.314921 42 | vt 0.727273 0.314921 43 | vt 0.545455 0.314921 44 | vt 0.000000 0.314921 45 | vt 0.272728 0.472382 46 | vt 0.090910 0.472382 47 | vt 0.818182 0.472382 48 | vt 0.636364 0.472382 49 | vt 0.454546 0.472382 50 | vt 0.181819 0.000000 51 | vt 0.272728 0.157461 52 | vt 0.090910 0.157461 53 | vt 0.363637 0.000000 54 | vt 0.454546 0.157461 55 | vt 0.909091 0.000000 56 | vt 1.000000 0.157461 57 | vt 0.818182 0.157461 58 | vt 0.727273 0.000000 59 | vt 0.636364 0.157461 60 | vt 0.545455 0.000000 61 | vt 0.363637 0.314921 62 | vt 0.181819 0.314921 63 | vt 0.909091 0.314921 64 | vt 0.727273 0.314921 65 | vt 0.545455 0.314921 66 | vt 0.000000 0.314921 67 | vt 0.272728 0.472382 68 | vt 0.090910 0.472382 69 | vt 0.818182 0.472382 70 | vt 0.636364 0.472382 71 | vt 0.454546 0.472382 72 | vn 0.0057 -1.0000 0.0000 73 | vn 0.6829 -0.4221 0.5963 74 | vn -0.1911 -0.3092 0.9316 75 | vn 0.6829 -0.4221 -0.5963 76 | vn -0.8970 -0.4421 -0.0000 77 | vn -0.1911 -0.3092 -0.9316 78 | vn 0.8970 0.4421 0.0000 79 | vn 0.1911 0.3092 0.9316 80 | vn -0.6829 0.4221 0.5963 81 | vn -0.6829 0.4221 -0.5963 82 | vn 0.1911 0.3092 -0.9316 83 | vn -0.0057 1.0000 0.0000 84 | s 1 85 | f 1/1/1 2/2/2 3/3/3 86 | f 2/2/2 1/4/1 6/5/4 87 | f 1/6/1 3/7/3 4/8/5 88 | f 1/9/1 4/8/5 5/10/6 89 | f 1/11/1 5/10/6 6/5/4 90 | f 2/2/2 6/5/4 11/12/7 91 | f 3/3/3 2/2/2 7/13/8 92 | f 4/8/5 3/7/3 8/14/9 93 | f 5/10/6 4/8/5 9/15/10 94 | f 6/5/4 5/10/6 10/16/11 95 | f 2/2/2 11/12/7 7/13/8 96 | f 3/3/3 7/13/8 8/17/9 97 | f 4/8/5 8/14/9 9/15/10 98 | f 5/10/6 9/15/10 10/16/11 99 | f 6/5/4 10/16/11 11/12/7 100 | f 7/13/8 11/12/7 12/18/12 101 | f 8/17/9 7/13/8 12/19/12 102 | f 9/15/10 8/14/9 12/20/12 103 | f 10/16/11 9/15/10 12/21/12 104 | f 11/12/7 10/16/11 12/22/12 105 | f 13/23/1 14/24/2 15/25/3 106 | f 14/24/2 13/26/1 18/27/4 107 | f 13/28/1 15/29/3 16/30/5 108 | f 13/31/1 16/30/5 17/32/6 109 | f 13/33/1 17/32/6 18/27/4 110 | f 14/24/2 18/27/4 23/34/7 111 | f 15/25/3 14/24/2 19/35/8 112 | f 16/30/5 15/29/3 20/36/9 113 | f 17/32/6 16/30/5 21/37/10 114 | f 18/27/4 17/32/6 22/38/11 115 | f 14/24/2 23/34/7 19/35/8 116 | f 15/25/3 19/35/8 20/39/9 117 | f 16/30/5 20/36/9 21/37/10 118 | f 17/32/6 21/37/10 22/38/11 119 | f 18/27/4 22/38/11 23/34/7 120 | f 19/35/8 23/34/7 24/40/12 121 | f 20/39/9 19/35/8 24/41/12 122 | f 21/37/10 20/36/9 24/42/12 123 | f 22/38/11 21/37/10 24/43/12 124 | f 23/34/7 22/38/11 24/44/12 125 | -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/laxativedude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/obj2mdl-fnaw/laxativedude.png -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/laxativedude3_eyes.obj: -------------------------------------------------------------------------------- 1 | # Blender v3.1.2 OBJ File: '' 2 | # www.blender.org 3 | o Icosphere 4 | v -0.307924 3.061744 -0.320357 5 | v -0.284527 3.079618 -0.313525 6 | v -0.316861 3.079618 -0.309302 7 | v -0.336845 3.079618 -0.320357 8 | v -0.316861 3.079618 -0.331413 9 | v -0.284527 3.079618 -0.327190 10 | v -0.298987 3.108539 -0.309302 11 | v -0.331322 3.108539 -0.313525 12 | v -0.331322 3.108539 -0.327190 13 | v -0.298987 3.108539 -0.331413 14 | v -0.279003 3.108539 -0.320357 15 | v -0.307924 3.126413 -0.320357 16 | v 0.456597 3.047686 -0.319034 17 | v 0.479994 3.065560 -0.312201 18 | v 0.447660 3.065560 -0.307979 19 | v 0.427676 3.065560 -0.319034 20 | v 0.447660 3.065560 -0.330089 21 | v 0.479994 3.065560 -0.325866 22 | v 0.465534 3.094481 -0.307979 23 | v 0.433199 3.094481 -0.312201 24 | v 0.433199 3.094481 -0.325866 25 | v 0.465534 3.094481 -0.330089 26 | v 0.485518 3.094481 -0.319034 27 | v 0.456597 3.112355 -0.319034 28 | vt 0.181819 0.000000 29 | vt 0.272728 0.157461 30 | vt 0.090910 0.157461 31 | vt 0.363637 0.000000 32 | vt 0.454546 0.157461 33 | vt 0.909091 0.000000 34 | vt 1.000000 0.157461 35 | vt 0.818182 0.157461 36 | vt 0.727273 0.000000 37 | vt 0.636364 0.157461 38 | vt 0.545455 0.000000 39 | vt 0.363637 0.314921 40 | vt 0.181819 0.314921 41 | vt 0.909091 0.314921 42 | vt 0.727273 0.314921 43 | vt 0.545455 0.314921 44 | vt 0.000000 0.314921 45 | vt 0.272728 0.472382 46 | vt 0.090910 0.472382 47 | vt 0.818182 0.472382 48 | vt 0.636364 0.472382 49 | vt 0.454546 0.472382 50 | vt 0.181819 0.000000 51 | vt 0.272728 0.157461 52 | vt 0.090910 0.157461 53 | vt 0.363637 0.000000 54 | vt 0.454546 0.157461 55 | vt 0.909091 0.000000 56 | vt 1.000000 0.157461 57 | vt 0.818182 0.157461 58 | vt 0.727273 0.000000 59 | vt 0.636364 0.157461 60 | vt 0.545455 0.000000 61 | vt 0.363637 0.314921 62 | vt 0.181819 0.314921 63 | vt 0.909091 0.314921 64 | vt 0.727273 0.314921 65 | vt 0.545455 0.314921 66 | vt 0.000000 0.314921 67 | vt 0.272728 0.472382 68 | vt 0.090910 0.472382 69 | vt 0.818182 0.472382 70 | vt 0.636364 0.472382 71 | vt 0.454546 0.472382 72 | vn 0.0057 -1.0000 -0.0000 73 | vn 0.6829 -0.4221 0.5963 74 | vn -0.1911 -0.3092 0.9316 75 | vn 0.6829 -0.4221 -0.5963 76 | vn -0.8970 -0.4421 0.0000 77 | vn -0.1911 -0.3092 -0.9316 78 | vn 0.8970 0.4421 0.0000 79 | vn 0.1911 0.3092 0.9316 80 | vn -0.6829 0.4221 0.5963 81 | vn -0.6829 0.4221 -0.5963 82 | vn 0.1911 0.3092 -0.9316 83 | vn -0.0057 1.0000 0.0000 84 | s 1 85 | f 1/1/1 2/2/2 3/3/3 86 | f 2/2/2 1/4/1 6/5/4 87 | f 1/6/1 3/7/3 4/8/5 88 | f 1/9/1 4/8/5 5/10/6 89 | f 1/11/1 5/10/6 6/5/4 90 | f 2/2/2 6/5/4 11/12/7 91 | f 3/3/3 2/2/2 7/13/8 92 | f 4/8/5 3/7/3 8/14/9 93 | f 5/10/6 4/8/5 9/15/10 94 | f 6/5/4 5/10/6 10/16/11 95 | f 2/2/2 11/12/7 7/13/8 96 | f 3/3/3 7/13/8 8/17/9 97 | f 4/8/5 8/14/9 9/15/10 98 | f 5/10/6 9/15/10 10/16/11 99 | f 6/5/4 10/16/11 11/12/7 100 | f 7/13/8 11/12/7 12/18/12 101 | f 8/17/9 7/13/8 12/19/12 102 | f 9/15/10 8/14/9 12/20/12 103 | f 10/16/11 9/15/10 12/21/12 104 | f 11/12/7 10/16/11 12/22/12 105 | f 13/23/1 14/24/2 15/25/3 106 | f 14/24/2 13/26/1 18/27/4 107 | f 13/28/1 15/29/3 16/30/5 108 | f 13/31/1 16/30/5 17/32/6 109 | f 13/33/1 17/32/6 18/27/4 110 | f 14/24/2 18/27/4 23/34/7 111 | f 15/25/3 14/24/2 19/35/8 112 | f 16/30/5 15/29/3 20/36/9 113 | f 17/32/6 16/30/5 21/37/10 114 | f 18/27/4 17/32/6 22/38/11 115 | f 14/24/2 23/34/7 19/35/8 116 | f 15/25/3 19/35/8 20/39/9 117 | f 16/30/5 20/36/9 21/37/10 118 | f 17/32/6 21/37/10 22/38/11 119 | f 18/27/4 22/38/11 23/34/7 120 | f 19/35/8 23/34/7 24/40/12 121 | f 20/39/9 19/35/8 24/41/12 122 | f 21/37/10 20/36/9 24/42/12 123 | f 22/38/11 21/37/10 24/43/12 124 | f 23/34/7 22/38/11 24/44/12 125 | -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/longarms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/obj2mdl-fnaw/longarms.png -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/longarms2_eyes.obj: -------------------------------------------------------------------------------- 1 | # Blender v3.1.2 OBJ File: '' 2 | # www.blender.org 3 | o Icosphere 4 | v -0.331400 1.968648 -0.388224 5 | v -0.308003 1.986522 -0.381392 6 | v -0.340337 1.986522 -0.377169 7 | v -0.360321 1.986522 -0.388224 8 | v -0.340337 1.986522 -0.399280 9 | v -0.308003 1.986522 -0.395057 10 | v -0.322463 2.015443 -0.377169 11 | v -0.354797 2.015443 -0.381392 12 | v -0.354797 2.015443 -0.395057 13 | v -0.322463 2.015443 -0.399280 14 | v -0.302479 2.015443 -0.388224 15 | v -0.331400 2.033317 -0.388224 16 | v 0.323070 1.978580 -0.384941 17 | v 0.346467 1.996454 -0.378109 18 | v 0.314133 1.996454 -0.373886 19 | v 0.294149 1.996454 -0.384941 20 | v 0.314133 1.996454 -0.395997 21 | v 0.346467 1.996454 -0.391774 22 | v 0.332007 2.025375 -0.373886 23 | v 0.299673 2.025375 -0.378109 24 | v 0.299673 2.025375 -0.391774 25 | v 0.332007 2.025375 -0.395997 26 | v 0.351991 2.025375 -0.384941 27 | v 0.323070 2.043249 -0.384941 28 | vt 0.181819 0.000000 29 | vt 0.272728 0.157461 30 | vt 0.090910 0.157461 31 | vt 0.363637 0.000000 32 | vt 0.454546 0.157461 33 | vt 0.909091 0.000000 34 | vt 1.000000 0.157461 35 | vt 0.818182 0.157461 36 | vt 0.727273 0.000000 37 | vt 0.636364 0.157461 38 | vt 0.545455 0.000000 39 | vt 0.363637 0.314921 40 | vt 0.181819 0.314921 41 | vt 0.909091 0.314921 42 | vt 0.727273 0.314921 43 | vt 0.545455 0.314921 44 | vt 0.000000 0.314921 45 | vt 0.272728 0.472382 46 | vt 0.090910 0.472382 47 | vt 0.818182 0.472382 48 | vt 0.636364 0.472382 49 | vt 0.454546 0.472382 50 | vt 0.181819 0.000000 51 | vt 0.272728 0.157461 52 | vt 0.090910 0.157461 53 | vt 0.363637 0.000000 54 | vt 0.454546 0.157461 55 | vt 0.909091 0.000000 56 | vt 1.000000 0.157461 57 | vt 0.818182 0.157461 58 | vt 0.727273 0.000000 59 | vt 0.636364 0.157461 60 | vt 0.545455 0.000000 61 | vt 0.363637 0.314921 62 | vt 0.181819 0.314921 63 | vt 0.909091 0.314921 64 | vt 0.727273 0.314921 65 | vt 0.545455 0.314921 66 | vt 0.000000 0.314921 67 | vt 0.272728 0.472382 68 | vt 0.090910 0.472382 69 | vt 0.818182 0.472382 70 | vt 0.636364 0.472382 71 | vt 0.454546 0.472382 72 | vn 0.0057 -1.0000 0.0000 73 | vn 0.6829 -0.4221 0.5963 74 | vn -0.1911 -0.3092 0.9316 75 | vn 0.6829 -0.4221 -0.5963 76 | vn -0.8970 -0.4421 0.0000 77 | vn -0.1911 -0.3092 -0.9316 78 | vn 0.8970 0.4421 0.0000 79 | vn 0.1911 0.3092 0.9316 80 | vn -0.6829 0.4221 0.5963 81 | vn -0.6829 0.4221 -0.5963 82 | vn 0.1911 0.3092 -0.9316 83 | vn -0.0057 1.0000 0.0000 84 | s 1 85 | f 1/1/1 2/2/2 3/3/3 86 | f 2/2/2 1/4/1 6/5/4 87 | f 1/6/1 3/7/3 4/8/5 88 | f 1/9/1 4/8/5 5/10/6 89 | f 1/11/1 5/10/6 6/5/4 90 | f 2/2/2 6/5/4 11/12/7 91 | f 3/3/3 2/2/2 7/13/8 92 | f 4/8/5 3/7/3 8/14/9 93 | f 5/10/6 4/8/5 9/15/10 94 | f 6/5/4 5/10/6 10/16/11 95 | f 2/2/2 11/12/7 7/13/8 96 | f 3/3/3 7/13/8 8/17/9 97 | f 4/8/5 8/14/9 9/15/10 98 | f 5/10/6 9/15/10 10/16/11 99 | f 6/5/4 10/16/11 11/12/7 100 | f 7/13/8 11/12/7 12/18/12 101 | f 8/17/9 7/13/8 12/19/12 102 | f 9/15/10 8/14/9 12/20/12 103 | f 10/16/11 9/15/10 12/21/12 104 | f 11/12/7 10/16/11 12/22/12 105 | f 13/23/1 14/24/2 15/25/3 106 | f 14/24/2 13/26/1 18/27/4 107 | f 13/28/1 15/29/3 16/30/5 108 | f 13/31/1 16/30/5 17/32/6 109 | f 13/33/1 17/32/6 18/27/4 110 | f 14/24/2 18/27/4 23/34/7 111 | f 15/25/3 14/24/2 19/35/8 112 | f 16/30/5 15/29/3 20/36/9 113 | f 17/32/6 16/30/5 21/37/10 114 | f 18/27/4 17/32/6 22/38/11 115 | f 14/24/2 23/34/7 19/35/8 116 | f 15/25/3 19/35/8 20/39/9 117 | f 16/30/5 20/36/9 21/37/10 118 | f 17/32/6 21/37/10 22/38/11 119 | f 18/27/4 22/38/11 23/34/7 120 | f 19/35/8 23/34/7 24/40/12 121 | f 20/39/9 19/35/8 24/41/12 122 | f 21/37/10 20/36/9 24/42/12 123 | f 22/38/11 21/37/10 24/43/12 124 | f 23/34/7 22/38/11 24/44/12 125 | -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/weirdclimber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/obj2mdl-fnaw/weirdclimber.png -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/weirdclimber2_eyes.obj: -------------------------------------------------------------------------------- 1 | # Blender v3.1.2 OBJ File: '' 2 | # www.blender.org 3 | o Icosphere.001 4 | v 0.420598 3.531252 0.045839 5 | v 0.438023 3.535470 0.059452 6 | v 0.413942 3.532996 0.061394 7 | v 0.399059 3.539472 0.056310 8 | v 0.413942 3.545948 0.051226 9 | v 0.438023 3.543474 0.053168 10 | v 0.427253 3.546297 0.078336 11 | v 0.403173 3.548770 0.076393 12 | v 0.403173 3.556775 0.070109 13 | v 0.427253 3.559249 0.068167 14 | v 0.442137 3.552773 0.073251 15 | v 0.420598 3.560993 0.083722 16 | v -0.270216 3.534683 0.030489 17 | v -0.253066 3.538834 0.043886 18 | v -0.276767 3.536399 0.045798 19 | v -0.291414 3.542773 0.040794 20 | v -0.276767 3.549146 0.035790 21 | v -0.253066 3.546712 0.037701 22 | v -0.263666 3.549489 0.062472 23 | v -0.287366 3.551924 0.060560 24 | v -0.287366 3.559802 0.054375 25 | v -0.263666 3.562237 0.052464 26 | v -0.249018 3.555863 0.057468 27 | v -0.270216 3.563954 0.067773 28 | vt 0.181819 0.000000 29 | vt 0.272728 0.157461 30 | vt 0.090910 0.157461 31 | vt 0.363637 0.000000 32 | vt 0.454546 0.157461 33 | vt 0.909091 0.000000 34 | vt 1.000000 0.157461 35 | vt 0.818182 0.157461 36 | vt 0.727273 0.000000 37 | vt 0.636364 0.157461 38 | vt 0.545455 0.000000 39 | vt 0.363637 0.314921 40 | vt 0.181819 0.314921 41 | vt 0.909091 0.314921 42 | vt 0.727273 0.314921 43 | vt 0.545455 0.314921 44 | vt 0.000000 0.314921 45 | vt 0.272728 0.472382 46 | vt 0.090910 0.472382 47 | vt 0.818182 0.472382 48 | vt 0.636364 0.472382 49 | vt 0.454546 0.472382 50 | vt 0.181819 0.000000 51 | vt 0.272728 0.157461 52 | vt 0.090910 0.157461 53 | vt 0.363637 0.000000 54 | vt 0.454546 0.157461 55 | vt 0.909091 0.000000 56 | vt 1.000000 0.157461 57 | vt 0.818182 0.157461 58 | vt 0.727273 0.000000 59 | vt 0.636364 0.157461 60 | vt 0.545455 0.000000 61 | vt 0.363637 0.314921 62 | vt 0.181819 0.314921 63 | vt 0.909091 0.314921 64 | vt 0.727273 0.314921 65 | vt 0.545455 0.314921 66 | vt 0.000000 0.314921 67 | vt 0.272728 0.472382 68 | vt 0.090910 0.472382 69 | vt 0.818182 0.472382 70 | vt 0.636364 0.472382 71 | vt 0.454546 0.472382 72 | vn 0.0057 -0.6175 -0.7866 73 | vn 0.6829 -0.7296 0.0362 74 | vn -0.1911 -0.9237 0.3321 75 | vn 0.6829 0.2084 -0.7002 76 | vn -0.8970 -0.2730 -0.3478 77 | vn -0.1911 0.5418 -0.8185 78 | vn 0.8970 0.2730 0.3478 79 | vn 0.1911 -0.5418 0.8185 80 | vn -0.6829 -0.2084 0.7002 81 | vn -0.6829 0.7296 -0.0362 82 | vn 0.1911 0.9237 -0.3321 83 | vn -0.0057 0.6175 0.7865 84 | vn 0.0057 -0.6175 -0.7865 85 | vn -0.8969 -0.2730 -0.3478 86 | vn -0.1911 0.5419 -0.8185 87 | vn 0.1911 -0.5419 0.8185 88 | s 1 89 | f 1/1/1 2/2/2 3/3/3 90 | f 2/2/2 1/4/1 6/5/4 91 | f 1/6/1 3/7/3 4/8/5 92 | f 1/9/1 4/8/5 5/10/6 93 | f 1/11/1 5/10/6 6/5/4 94 | f 2/2/2 6/5/4 11/12/7 95 | f 3/3/3 2/2/2 7/13/8 96 | f 4/8/5 3/7/3 8/14/9 97 | f 5/10/6 4/8/5 9/15/10 98 | f 6/5/4 5/10/6 10/16/11 99 | f 2/2/2 11/12/7 7/13/8 100 | f 3/3/3 7/13/8 8/17/9 101 | f 4/8/5 8/14/9 9/15/10 102 | f 5/10/6 9/15/10 10/16/11 103 | f 6/5/4 10/16/11 11/12/7 104 | f 7/13/8 11/12/7 12/18/12 105 | f 8/17/9 7/13/8 12/19/12 106 | f 9/15/10 8/14/9 12/20/12 107 | f 10/16/11 9/15/10 12/21/12 108 | f 11/12/7 10/16/11 12/22/12 109 | f 13/23/13 14/24/2 15/25/3 110 | f 14/24/2 13/26/13 18/27/4 111 | f 13/28/13 15/29/3 16/30/14 112 | f 13/31/13 16/30/14 17/32/15 113 | f 13/33/13 17/32/15 18/27/4 114 | f 14/24/2 18/27/4 23/34/7 115 | f 15/25/3 14/24/2 19/35/16 116 | f 16/30/14 15/29/3 20/36/9 117 | f 17/32/15 16/30/14 21/37/10 118 | f 18/27/4 17/32/15 22/38/11 119 | f 14/24/2 23/34/7 19/35/16 120 | f 15/25/3 19/35/16 20/39/9 121 | f 16/30/14 20/36/9 21/37/10 122 | f 17/32/15 21/37/10 22/38/11 123 | f 18/27/4 22/38/11 23/34/7 124 | f 19/35/16 23/34/7 24/40/12 125 | f 20/39/9 19/35/16 24/41/12 126 | f 21/37/10 20/36/9 24/42/12 127 | f 22/38/11 21/37/10 24/43/12 128 | f 23/34/7 22/38/11 24/44/12 129 | -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/winston.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lax1dude/eagler-binary-tools/6697fb13ae3e8a34972f764f2be23be94f1ff059/samples/obj2mdl-fnaw/winston.png -------------------------------------------------------------------------------- /samples/obj2mdl-fnaw/winston1_eyes.obj: -------------------------------------------------------------------------------- 1 | # Blender v3.1.2 OBJ File: '' 2 | # www.blender.org 3 | o Icosphere.003 4 | v -0.445340 1.202246 -0.408453 5 | v -0.429465 1.214374 -0.403817 6 | v -0.451403 1.214374 -0.400952 7 | v -0.464962 1.214374 -0.408453 8 | v -0.451403 1.214374 -0.415954 9 | v -0.429465 1.214374 -0.413088 10 | v -0.439276 1.233996 -0.400952 11 | v -0.461215 1.233996 -0.403817 12 | v -0.461215 1.233996 -0.413088 13 | v -0.439276 1.233996 -0.415954 14 | v -0.425717 1.233996 -0.408453 15 | v -0.445340 1.246124 -0.408453 16 | v 0.467658 1.340403 -0.408705 17 | v 0.482474 1.351722 -0.404379 18 | v 0.461999 1.351722 -0.401704 19 | v 0.449344 1.351722 -0.408705 20 | v 0.461999 1.351722 -0.415706 21 | v 0.482474 1.351722 -0.413032 22 | v 0.473317 1.370036 -0.401704 23 | v 0.452842 1.370036 -0.404379 24 | v 0.452842 1.370036 -0.413032 25 | v 0.473317 1.370036 -0.415706 26 | v 0.485972 1.370036 -0.408705 27 | v 0.467658 1.381355 -0.408705 28 | vt 0.181819 0.000000 29 | vt 0.272728 0.157461 30 | vt 0.090910 0.157461 31 | vt 0.363637 0.000000 32 | vt 0.454546 0.157461 33 | vt 0.909091 0.000000 34 | vt 1.000000 0.157461 35 | vt 0.818182 0.157461 36 | vt 0.727273 0.000000 37 | vt 0.636364 0.157461 38 | vt 0.545455 0.000000 39 | vt 0.363637 0.314921 40 | vt 0.181819 0.314921 41 | vt 0.909091 0.314921 42 | vt 0.727273 0.314921 43 | vt 0.545455 0.314921 44 | vt 0.000000 0.314921 45 | vt 0.272728 0.472382 46 | vt 0.090910 0.472382 47 | vt 0.818182 0.472382 48 | vt 0.636364 0.472382 49 | vt 0.454546 0.472382 50 | vt 0.181819 0.000000 51 | vt 0.272728 0.157461 52 | vt 0.090910 0.157461 53 | vt 0.363637 0.000000 54 | vt 0.454546 0.157461 55 | vt 0.909091 0.000000 56 | vt 1.000000 0.157461 57 | vt 0.818182 0.157461 58 | vt 0.727273 0.000000 59 | vt 0.636364 0.157461 60 | vt 0.545455 0.000000 61 | vt 0.363637 0.314921 62 | vt 0.181819 0.314921 63 | vt 0.909091 0.314921 64 | vt 0.727273 0.314921 65 | vt 0.545455 0.314921 66 | vt 0.000000 0.314921 67 | vt 0.272728 0.472382 68 | vt 0.090910 0.472382 69 | vt 0.818182 0.472382 70 | vt 0.636364 0.472382 71 | vt 0.454546 0.472382 72 | vn 0.0057 -1.0000 -0.0000 73 | vn 0.6829 -0.4221 0.5963 74 | vn -0.1911 -0.3092 0.9316 75 | vn 0.6829 -0.4221 -0.5963 76 | vn -0.8969 -0.4421 -0.0000 77 | vn -0.1911 -0.3092 -0.9316 78 | vn 0.8970 0.4421 0.0000 79 | vn 0.1911 0.3092 0.9316 80 | vn -0.6829 0.4221 0.5963 81 | vn -0.6829 0.4221 -0.5963 82 | vn 0.1911 0.3092 -0.9316 83 | vn -0.0057 1.0000 0.0000 84 | s 1 85 | f 1/1/1 2/2/2 3/3/3 86 | f 2/2/2 1/4/1 6/5/4 87 | f 1/6/1 3/7/3 4/8/5 88 | f 1/9/1 4/8/5 5/10/6 89 | f 1/11/1 5/10/6 6/5/4 90 | f 2/2/2 6/5/4 11/12/7 91 | f 3/3/3 2/2/2 7/13/8 92 | f 4/8/5 3/7/3 8/14/9 93 | f 5/10/6 4/8/5 9/15/10 94 | f 6/5/4 5/10/6 10/16/11 95 | f 2/2/2 11/12/7 7/13/8 96 | f 3/3/3 7/13/8 8/17/9 97 | f 4/8/5 8/14/9 9/15/10 98 | f 5/10/6 9/15/10 10/16/11 99 | f 6/5/4 10/16/11 11/12/7 100 | f 7/13/8 11/12/7 12/18/12 101 | f 8/17/9 7/13/8 12/19/12 102 | f 9/15/10 8/14/9 12/20/12 103 | f 10/16/11 9/15/10 12/21/12 104 | f 11/12/7 10/16/11 12/22/12 105 | f 13/23/1 14/24/2 15/25/3 106 | f 14/24/2 13/26/1 18/27/4 107 | f 13/28/1 15/29/3 16/30/5 108 | f 13/31/1 16/30/5 17/32/6 109 | f 13/33/1 17/32/6 18/27/4 110 | f 14/24/2 18/27/4 23/34/7 111 | f 15/25/3 14/24/2 19/35/8 112 | f 16/30/5 15/29/3 20/36/9 113 | f 17/32/6 16/30/5 21/37/10 114 | f 18/27/4 17/32/6 22/38/11 115 | f 14/24/2 23/34/7 19/35/8 116 | f 15/25/3 19/35/8 20/39/9 117 | f 16/30/5 20/36/9 21/37/10 118 | f 17/32/6 21/37/10 22/38/11 119 | f 18/27/4 22/38/11 23/34/7 120 | f 19/35/8 23/34/7 24/40/12 121 | f 20/39/9 19/35/8 24/41/12 122 | f 21/37/10 20/36/9 24/42/12 123 | f 22/38/11 21/37/10 24/43/12 124 | f 23/34/7 22/38/11 24/44/12 125 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EaglerBinaryTools' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EBPFileDecoder.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | 11 | import javax.imageio.ImageIO; 12 | 13 | import net.lax1dude.eaglercraft.bintools.utils.LabPBR2Eagler; 14 | 15 | /** 16 | * Copyright (c) 2023-2024 lax1dude. All Rights Reserved. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | * 29 | */ 30 | public class EBPFileDecoder { 31 | 32 | private static int getFromBits(int idxx, int bits, byte[] bytes) { 33 | int startByte = idxx >> 3; 34 | int endByte = (idxx + bits - 1) >> 3; 35 | if(startByte == endByte) { 36 | return (((int)bytes[startByte] & 0xff) >> (8 - (idxx & 7) - bits)) & ((1 << bits) - 1); 37 | }else { 38 | return (((((int)bytes[startByte] & 0xff) << 8) | ((int)bytes[endByte] & 0xff)) >> (16 - (idxx & 7) - bits)) & ((1 << bits) - 1); 39 | } 40 | } 41 | 42 | public static void _main(String[] args) throws IOException { 43 | boolean labPBR = false; 44 | if(args.length > 1 && args[0].equalsIgnoreCase("--labPBR")) { 45 | labPBR = true; 46 | String[] e = new String[args.length - 1]; 47 | System.arraycopy(args, 1, e, 0, e.length); 48 | args = e; 49 | } 50 | if(args.length > 1 && args.length < 4 && args[0].equalsIgnoreCase("-r")) { 51 | File input = new File(args[1]); 52 | if(!input.isDirectory()) { 53 | System.err.println("Error: Not a directory: " + input.getAbsolutePath()); 54 | System.exit(-1); 55 | return; 56 | } 57 | convertDir(input, args.length == 3 ? new File(args[2]) : input, labPBR); 58 | }else if(args.length == 2) { 59 | System.out.println("Reading input file..."); 60 | BufferedImage img; 61 | try(InputStream is = new FileInputStream(new File(args[0]))) { 62 | img = readEBP(is); 63 | } 64 | if(labPBR) { 65 | System.out.println("Converting from Eagler to LabPBR..."); 66 | LabPBR2Eagler.convertEaglerToLabPBR(img, img); 67 | } 68 | File output = new File(args[1]); 69 | System.out.println("Writing PNG: " + output.getAbsolutePath()); 70 | ImageIO.write(img, "PNG", output); 71 | }else { 72 | System.out.println("Usage: ebp-decode [--labPBR] "); 73 | System.out.println(" ebp-decode [--labPBR] -r [output directory]"); 74 | } 75 | } 76 | 77 | public static void convertDir(File inputDir, File outputDir) throws IOException { 78 | convertDir(inputDir, outputDir, false); 79 | } 80 | 81 | public static void convertDir(File inputDir, File outputDir, boolean labPBR) throws IOException { 82 | if(!outputDir.isDirectory() && !outputDir.mkdirs()) { 83 | throw new IOException("Could not create directory: " + outputDir.getAbsolutePath()); 84 | } 85 | File[] f = inputDir.listFiles(); 86 | for(int i = 0; i < f.length; ++i) { 87 | String name = f[i].getName(); 88 | if(f[i].isDirectory()) { 89 | convertDir(f[i], new File(outputDir, name), labPBR); 90 | continue; 91 | } 92 | if(!name.toLowerCase().endsWith(".ebp")) { 93 | continue; 94 | } 95 | File ff = new File(outputDir, name.substring(0, name.length() - 3) + "png"); 96 | System.out.println(f[i].getAbsolutePath()); 97 | BufferedImage img; 98 | try(InputStream is = new FileInputStream(f[i])) { 99 | img = readEBP(is); 100 | } 101 | if(labPBR) { 102 | LabPBR2Eagler.convertEaglerToLabPBR(img, img); 103 | } 104 | ImageIO.write(img, "PNG", ff); 105 | } 106 | } 107 | 108 | public static BufferedImage readEBP(InputStream is) throws IOException { 109 | if(is.read() != '%' || is.read() != 'E' || is.read() != 'B' || is.read() != 'P') { 110 | throw new IOException("Not an EBP file!"); 111 | } 112 | int v = is.read(); 113 | if(v != 1) { 114 | throw new IOException("Unknown EBP version: " + v); 115 | } 116 | v = is.read(); 117 | if(v != 3) { 118 | throw new IOException("Invalid component count: " + v); 119 | } 120 | int w = is.read() | (is.read() << 8); 121 | int h = is.read() | (is.read() << 8); 122 | BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 123 | v = is.read(); 124 | if(v == 0) { 125 | for(int i = 0, l = w * h; i < l; ++i) { 126 | img.setRGB(i % w, i / w, (is.read() << 16) | (is.read() << 8) | is.read() | 0xFF000000); 127 | } 128 | }else if(v == 1) { 129 | int paletteSize = is.read(); 130 | int[] palette = new int[paletteSize + 1]; 131 | palette[0] = 0xFF000000; 132 | for(int i = 0; i < paletteSize; ++i) { 133 | palette[i + 1] = (is.read() << 16) | (is.read() << 8) | is.read() | 0xFF000000; 134 | } 135 | int bpp = is.read(); 136 | byte[] readSet = new byte[is.read() | (is.read() << 8) | (is.read() << 16)]; 137 | is.read(readSet); 138 | for(int i = 0, l = w * h; i < l; ++i) { 139 | img.setRGB(i % w, i / w, palette[getFromBits(i * bpp, bpp, readSet)]); 140 | } 141 | }else { 142 | throw new IOException("Unknown EBP storage type: " + v); 143 | } 144 | if(is.read() != ':' || is.read() != '>') { 145 | throw new IOException("Invalid footer! (:>)"); 146 | } 147 | return img; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EBPFileEncoder.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.File; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.OutputStream; 8 | import java.util.HashMap; 9 | import java.util.HashSet; 10 | import java.util.Iterator; 11 | import java.util.Map; 12 | import java.util.Set; 13 | 14 | import javax.imageio.ImageIO; 15 | 16 | import net.lax1dude.eaglercraft.bintools.utils.LabPBR2Eagler; 17 | 18 | /** 19 | * Copyright (c) 2023-2024 lax1dude. All Rights Reserved. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | public class EBPFileEncoder { 34 | 35 | private static void setBit(int idx, boolean v, byte[] bytes) { 36 | int idx2 = idx >> 3; 37 | if(v) { 38 | bytes[idx2] |= (1 << (7 - (idx & 7))); 39 | }else { 40 | bytes[idx2] &= (-1 ^ (1 << (7 - (idx & 7)))); 41 | } 42 | } 43 | 44 | public static void _main(String[] args) throws IOException { 45 | boolean labPBR = false; 46 | if(args.length > 1 && args[0].equalsIgnoreCase("--labPBR")) { 47 | labPBR = true; 48 | String[] e = new String[args.length - 1]; 49 | System.arraycopy(args, 1, e, 0, e.length); 50 | args = e; 51 | } 52 | if(args.length > 1 && args.length < 4 && args[0].equalsIgnoreCase("-r")) { 53 | File input = new File(args[1]); 54 | if(!input.isDirectory()) { 55 | System.err.println("Error: Not a directory: " + input.getAbsolutePath()); 56 | System.exit(-1); 57 | return; 58 | } 59 | convertDir(input, args.length == 3 ? new File(args[2]) : input, labPBR); 60 | }else if(args.length == 2) { 61 | System.out.println("Reading input file..."); 62 | BufferedImage img = ImageIO.read(new File(args[0])); 63 | File output = new File(args[1]); 64 | if(labPBR) { 65 | System.out.println("Converting from LabPBR to Eagler..."); 66 | LabPBR2Eagler.convertLabPBRToEagler(img, img); 67 | } 68 | System.out.println("Encoding EBP: " + output.getAbsolutePath()); 69 | try(OutputStream os = new FileOutputStream(output)) { 70 | writeEBP(img, os); 71 | } 72 | }else { 73 | System.out.println("Usage: ebp-encode [--labPBR] "); 74 | System.out.println(" ebp-encode [--labPBR] -r [output directory]"); 75 | } 76 | } 77 | 78 | public static void convertDir(File inputDir, File outputDir) throws IOException { 79 | convertDir(inputDir, outputDir, false); 80 | } 81 | 82 | public static void convertDir(File inputDir, File outputDir, boolean labPBR) throws IOException { 83 | if(!outputDir.isDirectory() && !outputDir.mkdirs()) { 84 | throw new IOException("Could not create directory: " + outputDir.getAbsolutePath()); 85 | } 86 | File[] f = inputDir.listFiles(); 87 | for(int i = 0; i < f.length; ++i) { 88 | String name = f[i].getName(); 89 | if(f[i].isDirectory()) { 90 | convertDir(f[i], new File(outputDir, name), labPBR); 91 | continue; 92 | } 93 | if(!name.toLowerCase().endsWith(".png")) { 94 | continue; 95 | } 96 | File ff = new File(outputDir, name.substring(0, name.length() - 3) + "ebp"); 97 | System.out.println(f[i].getAbsolutePath()); 98 | BufferedImage img = ImageIO.read(f[i]); 99 | if(labPBR) { 100 | LabPBR2Eagler.convertLabPBRToEagler(img, img); 101 | } 102 | try(OutputStream os = new FileOutputStream(ff)) { 103 | writeEBP(img, os); 104 | } 105 | } 106 | } 107 | 108 | public static void writeEBP(BufferedImage img, OutputStream fos) throws IOException { 109 | fos.write(new byte[] { '%', 'E', 'B', 'P'}); 110 | fos.write(1); // v1 111 | fos.write(3); // 3 component 112 | int w = img.getWidth(); 113 | int h = img.getHeight(); 114 | fos.write(w & 0xFF); 115 | fos.write((w >> 8) & 0xFF); 116 | fos.write(h & 0xFF); 117 | fos.write((h >> 8) & 0xFF); 118 | 119 | int[] pixels = img.getRGB(0, 0, w, h, null, 0, w); 120 | 121 | Set colorPalette = new HashSet(); 122 | for(int i = 0; i < pixels.length; ++i) { 123 | if((pixels[i] & 0xFF000000) == 0) { 124 | pixels[i] = 0; 125 | }else { 126 | pixels[i] &= 0xFFFFFF; 127 | } 128 | if(pixels[i] == 0) { 129 | continue; 130 | } 131 | colorPalette.add(pixels[i]); 132 | } 133 | 134 | if(colorPalette.size() > 255) { 135 | fos.write(0); // type is no palette 136 | for(int i = 0; i < pixels.length; ++i) { 137 | fos.write((pixels[i] >> 16) & 0xFF); 138 | fos.write((pixels[i] >> 8) & 0xFF); 139 | fos.write(pixels[i] & 0xFF); 140 | } 141 | }else { 142 | Map paletteHelper = new HashMap(); 143 | fos.write(1); // type is palette 144 | fos.write(colorPalette.size()); // write palette size 145 | Iterator paletteItr = colorPalette.iterator(); 146 | int paletteIdx = 0; 147 | paletteHelper.put(0, 0); 148 | while(paletteItr.hasNext()) { 149 | int j = paletteItr.next().intValue(); 150 | paletteHelper.put(j, ++paletteIdx); 151 | fos.write((j >> 16) & 0xFF); 152 | fos.write((j >> 8) & 0xFF); 153 | fos.write(j & 0xFF); 154 | } 155 | int bpp = 1; 156 | while((paletteIdx >> bpp) != 0) { 157 | ++bpp; 158 | } 159 | fos.write(bpp); // write bpp 160 | int totalBits = pixels.length * bpp; 161 | byte[] completedBitSet = new byte[(totalBits & 7) == 0 ? (totalBits >> 3) : ((totalBits >> 3) + 1)]; 162 | int bsi = 0; 163 | for(int i = 0; i < pixels.length; ++i) { 164 | int wr = paletteHelper.get(pixels[i]); 165 | for(int j = bpp - 1; j >= 0; --j) { 166 | setBit(bsi++, ((wr >> j) & 1) != 0, completedBitSet); 167 | } 168 | } 169 | fos.write(completedBitSet.length & 0xFF); // write expect length (as 24 bits not 32) 170 | fos.write((completedBitSet.length >> 8) & 0xFF); 171 | fos.write((completedBitSet.length >> 16) & 0xFF); 172 | fos.write(completedBitSet); // write the bits 173 | } 174 | fos.write(new byte[] { ':', '>' }); 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EPKCompiler.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | import java.nio.charset.StandardCharsets; 11 | import java.text.SimpleDateFormat; 12 | import java.util.ArrayList; 13 | import java.util.Date; 14 | import java.util.zip.CRC32; 15 | import java.util.zip.Deflater; 16 | import java.util.zip.DeflaterOutputStream; 17 | 18 | import net.lax1dude.eaglercraft.bintools.utils.GZIPOutputStream2; 19 | 20 | /** 21 | * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | public class EPKCompiler { 36 | 37 | public static void _main(String[] args) throws IOException { 38 | if (args.length < 2 || args.length > 4) { 39 | System.out.println("Usage: epkcompiler [gzip|zlib|none] [file-type]"); 40 | return; 41 | } 42 | 43 | File root = new File(args[0]); 44 | File output = new File(args[1]); 45 | char compressionType; 46 | 47 | if (args.length > 2) { 48 | if (args[2].equalsIgnoreCase("gzip")) { 49 | compressionType = 'G'; 50 | } else if (args[2].equalsIgnoreCase("zlib")) { 51 | compressionType = 'Z'; 52 | } else if (args[2].equalsIgnoreCase("none")) { 53 | compressionType = '0'; 54 | } else { 55 | throw new IllegalArgumentException("Unknown compression method: " + args[2]); 56 | } 57 | } else { 58 | compressionType = 'G'; 59 | } 60 | 61 | System.out.println("Scanning input directory..."); 62 | 63 | ArrayList files = new ArrayList(); 64 | listDirectory(root, files); 65 | ByteArrayOutputStream osb = new ByteArrayOutputStream(); 66 | String start = root.getAbsolutePath(); 67 | 68 | System.out.println("Compiling: " + output.getAbsolutePath()); 69 | 70 | osb.write("EAGPKG$$".getBytes(StandardCharsets.US_ASCII)); 71 | 72 | String chars = "ver2.0"; 73 | osb.write(chars.length()); 74 | osb.write(chars.getBytes(StandardCharsets.US_ASCII)); 75 | 76 | Date d = new Date(); 77 | 78 | String comment = "\n\n # Eagler EPK v2.0 - Generated by EaglerBinaryTools\n" + " # update: on " 79 | + (new SimpleDateFormat("MM/dd/yyyy")).format(d) + " at " 80 | + (new SimpleDateFormat("hh:mm:ss aa")).format(d) + "\n\n"; 81 | 82 | String nm = output.getName(); 83 | osb.write(nm.length()); 84 | osb.write(nm.getBytes(StandardCharsets.US_ASCII)); 85 | 86 | writeShort(comment.length(), osb); 87 | osb.write(comment.getBytes(StandardCharsets.US_ASCII)); 88 | 89 | writeLong(d.getTime(), osb); 90 | writeInt(files.size() + 1, osb); 91 | 92 | osb.write(compressionType); 93 | 94 | OutputStream os; 95 | 96 | if (compressionType == 'G') { 97 | System.out.println("Using GZIP compression"); 98 | os = new GZIPOutputStream2(osb, 9, 16384, true); 99 | } else if (compressionType == 'Z') { 100 | System.out.println("Using ZLIB (DEFLATE) compression"); 101 | os = new DeflaterOutputStream(osb, new Deflater(9), 16384, true); 102 | } else { 103 | System.out.println("Using no compression"); 104 | os = osb; 105 | } 106 | 107 | os.write("HEAD".getBytes(StandardCharsets.US_ASCII)); 108 | String key = "file-type"; 109 | os.write(key.length()); 110 | os.write(key.getBytes(StandardCharsets.US_ASCII)); 111 | String value; 112 | if (args.length > 3) { 113 | value = args[3]; 114 | } else { 115 | value = "epk/resources"; 116 | } 117 | writeInt(value.length(), os); 118 | os.write(value.getBytes(StandardCharsets.US_ASCII)); 119 | os.write('>'); 120 | 121 | CRC32 checkSum = new CRC32(); 122 | for (File f : files) { 123 | InputStream stream = new FileInputStream(f); 124 | byte[] targetArray = new byte[(int) f.length()]; 125 | stream.read(targetArray); 126 | stream.close(); 127 | 128 | checkSum.reset(); 129 | checkSum.update(targetArray, 0, targetArray.length); 130 | int ch = (int) checkSum.getValue(); 131 | 132 | os.write("FILE".getBytes(StandardCharsets.US_ASCII)); 133 | 134 | String p = f.getAbsolutePath().replace(start, "").replace('\\', '/'); 135 | if (p.startsWith("/")) { 136 | p = p.substring(1); 137 | } 138 | os.write(p.length()); 139 | os.write(p.getBytes(StandardCharsets.US_ASCII)); 140 | writeInt(targetArray.length + 5, os); 141 | writeInt(ch, os); 142 | 143 | os.write(targetArray); 144 | os.write(':'); 145 | os.write('>'); 146 | } 147 | 148 | os.write("END$".getBytes(StandardCharsets.US_ASCII)); 149 | os.close(); 150 | 151 | osb.write(":::YEE:>".getBytes(StandardCharsets.US_ASCII)); 152 | 153 | System.out.println("Compiled " + files.size() + " files into the EPK"); 154 | System.out.println("Writing to disk..."); 155 | 156 | FileOutputStream out = new FileOutputStream(output); 157 | out.write(osb.toByteArray()); 158 | out.close(); 159 | } 160 | 161 | public static void writeShort(int i, OutputStream os) throws IOException { 162 | os.write((i >> 8) & 0xFF); 163 | os.write(i & 0xFF); 164 | } 165 | 166 | public static void writeInt(int i, OutputStream os) throws IOException { 167 | os.write((i >> 24) & 0xFF); 168 | os.write((i >> 16) & 0xFF); 169 | os.write((i >> 8) & 0xFF); 170 | os.write(i & 0xFF); 171 | } 172 | 173 | public static void writeLong(long i, OutputStream os) throws IOException { 174 | os.write((int) ((i >> 56) & 0xFF)); 175 | os.write((int) ((i >> 48) & 0xFF)); 176 | os.write((int) ((i >> 40) & 0xFF)); 177 | os.write((int) ((i >> 32) & 0xFF)); 178 | os.write((int) ((i >> 24) & 0xFF)); 179 | os.write((int) ((i >> 16) & 0xFF)); 180 | os.write((int) ((i >> 8) & 0xFF)); 181 | os.write((int) (i & 0xFF)); 182 | } 183 | 184 | public static void listDirectory(File dir, ArrayList files) { 185 | for (File f : dir.listFiles()) { 186 | if (f.isDirectory()) { 187 | listDirectory(f, files); 188 | } else { 189 | files.add(f); 190 | } 191 | } 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EPKCompilerLegacy.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.DataOutputStream; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.nio.charset.StandardCharsets; 11 | import java.security.MessageDigest; 12 | import java.security.NoSuchAlgorithmException; 13 | import java.util.ArrayList; 14 | import java.util.zip.Deflater; 15 | import java.util.zip.DeflaterOutputStream; 16 | 17 | /** 18 | * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | */ 32 | public class EPKCompilerLegacy { 33 | 34 | public static void _main(String[] args) throws IOException, NoSuchAlgorithmException { 35 | if (args.length != 2) { 36 | System.out.print("Usage: legacy-epkcompiler "); 37 | return; 38 | } 39 | File root = new File(args[0]); 40 | ArrayList files = new ArrayList(); 41 | System.out.println("Scanning input directory..."); 42 | listDirectory(root, files); 43 | ByteArrayOutputStream osb = new ByteArrayOutputStream(); 44 | DataOutputStream os = new DataOutputStream(osb); 45 | String start = root.getAbsolutePath(); 46 | File output = new File(args[1]); 47 | System.out.println("Compiling: " + output.getAbsolutePath()); 48 | os.write("EAGPKG!!".getBytes(StandardCharsets.UTF_8)); 49 | os.writeUTF( 50 | "\n\n # eaglercraft package file - assets copyright mojang ab\n # eagler eagler eagler eagler eagler eagler eagler\n\n"); 51 | Deflater d = new Deflater(9); 52 | os = new DataOutputStream(new DeflaterOutputStream(osb, d)); 53 | MessageDigest md = MessageDigest.getInstance("SHA-1"); 54 | for (File f : files) { 55 | os.writeUTF(""); 56 | String p = f.getAbsolutePath().replace(start, "").replace('\\', '/'); 57 | if (p.startsWith("/")) 58 | p = p.substring(1); 59 | os.writeUTF(p); 60 | 61 | InputStream stream = new FileInputStream(f); 62 | byte[] targetArray = new byte[stream.available()]; 63 | stream.read(targetArray); 64 | stream.close(); 65 | 66 | os.write(md.digest(targetArray)); 67 | os.writeInt(targetArray.length); 68 | os.write(targetArray); 69 | os.writeUTF(""); 70 | } 71 | os.writeUTF(" end"); 72 | os.flush(); 73 | os.close(); 74 | 75 | System.out.println("Compiled " + files.size() + " files into the EPK"); 76 | System.out.println("Writing to disk..."); 77 | 78 | FileOutputStream out = new FileOutputStream(output); 79 | out.write(osb.toByteArray()); 80 | out.close(); 81 | } 82 | 83 | public static void listDirectory(File dir, ArrayList files) { 84 | for (File f : dir.listFiles()) { 85 | if (f.isDirectory()) { 86 | listDirectory(f, files); 87 | } else { 88 | files.add(f); 89 | } 90 | } 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EPKDecompiler.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.nio.charset.StandardCharsets; 8 | 9 | import net.lax1dude.eaglercraft.bintools.utils.EPKDecompilerSP; 10 | 11 | /** 12 | * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 | * POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | */ 26 | public class EPKDecompiler { 27 | 28 | public static void _main(String[] args) throws IOException { 29 | if (args.length != 2) { 30 | System.out.print("Usage: epkdecompiler "); 31 | return; 32 | } 33 | File input = new File(args[0]); 34 | if(!input.isFile()) { 35 | System.err.println("Input file does not exist!"); 36 | return; 37 | } 38 | System.out.println("Decompiling: " + input.getAbsolutePath()); 39 | File output = new File(args[1]); 40 | byte[] inputBytes = new byte[(int)input.length()]; 41 | try(FileInputStream fis = new FileInputStream(input)) { 42 | fis.read(inputBytes); 43 | } 44 | EPKDecompilerSP epkDecompiler = new EPKDecompilerSP(inputBytes); 45 | if(epkDecompiler.isOld()) { 46 | System.out.println("Detected legacy EPK format!"); 47 | } 48 | int filesWritten = 0; 49 | try { 50 | EPKDecompilerSP.FileEntry f = null; 51 | while((f = epkDecompiler.readFile()) != null) { 52 | if(f.type.equals("HEAD")) { 53 | System.out.println("Skipping HEAD: \"" + f.name + "\": \"" + (new String(f.data, StandardCharsets.US_ASCII)) + "\""); 54 | }else if(f.type.equals("FILE")) { 55 | String safeName = f.name.replace('\\', '/'); 56 | if(safeName.startsWith("../") || safeName.contains("/../") || safeName.endsWith("/..") || safeName.equals("..")) { 57 | System.out.println("Skipping unsafe relative path: \"" + f.name + "\""); 58 | }else { 59 | File destFile = new File(output, safeName); 60 | File parent = destFile.getParentFile(); 61 | if(!parent.isDirectory()) { 62 | if(!parent.mkdirs()) { 63 | throw new IOException("Could not create directory: " + parent.getAbsolutePath()); 64 | } 65 | } 66 | try(FileOutputStream fos = new FileOutputStream(destFile)) { 67 | fos.write(f.data); 68 | ++filesWritten; 69 | } 70 | } 71 | }else { 72 | System.err.println("Skipping unknown entry type \"" + f.type + "\" name \"" + f.name + "\", data is " + f.data.length + " bytes"); 73 | } 74 | } 75 | }finally { 76 | epkDecompiler.close(); 77 | } 78 | System.out.println("Extracted " + filesWritten + " from the EPK"); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EaglerBMPGen.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Graphics2D; 5 | import java.awt.RenderingHints; 6 | import java.awt.image.BufferedImage; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.DataOutputStream; 9 | import java.io.File; 10 | import java.io.FileOutputStream; 11 | import java.io.IOException; 12 | import java.io.OutputStream; 13 | 14 | import javax.imageio.ImageIO; 15 | 16 | /** 17 | * Copyright (c) 2023-2024 lax1dude. All Rights Reserved. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | public class EaglerBMPGen { 32 | 33 | public static void _main(String[] args) throws IOException { 34 | if(args.length != 3 || (!args[0].equalsIgnoreCase("--red") && !args[0].equalsIgnoreCase("--rgba"))) { 35 | System.out.println("Usage: eagler-bmp-gen <--red|--rgba> "); 36 | System.out.println("The texture's width and height must be a power of 2!"); 37 | return; 38 | } 39 | System.out.println("Reading input file..."); 40 | BufferedImage img = ImageIO.read(new File(args[1])); 41 | File output = new File(args[2]); 42 | System.out.println("Encoding Eagler BMP: " + output.getAbsolutePath()); 43 | int lvls; 44 | try(FileOutputStream fs = new FileOutputStream(output)) { 45 | ByteArrayOutputStream bao = new ByteArrayOutputStream(0x7FFF); 46 | lvls = encode(img, args[0].equalsIgnoreCase("--rgba"), bao); 47 | fs.write(bao.toByteArray()); 48 | } 49 | System.out.println("Wrote " + lvls + " mipmap levels"); 50 | } 51 | 52 | public static int encode(BufferedImage input, boolean rgba, OutputStream os) throws IOException { 53 | boolean invalid = false; 54 | if(!isPowOf2(input.getWidth())) { 55 | System.err.println("The image's width is not a power of 2!"); 56 | invalid = true; 57 | } 58 | if(!isPowOf2(input.getHeight())) { 59 | System.err.println("The image's height is not a power of 2!"); 60 | invalid = true; 61 | } 62 | if(invalid) { 63 | throw new IOException("The image has invalid dimensions!"); 64 | } 65 | DataOutputStream dos = new DataOutputStream(os); 66 | int lvls = 0; 67 | while(true) { 68 | ++lvls; 69 | dos.write('E'); 70 | dos.writeShort(input.getWidth()); 71 | dos.writeShort(input.getHeight()); 72 | for(int y = 0; y < input.getHeight(); ++y) { 73 | for(int x = 0; x < input.getWidth(); ++x) { 74 | int c = input.getRGB(x, input.getHeight() - y - 1); 75 | dos.write((c >>> 16) & 0xFF); 76 | if(rgba) { 77 | dos.write((c >>> 8) & 0xFF); 78 | dos.write((c >>> 0) & 0xFF); 79 | dos.write((c >>> 24) & 0xFF); 80 | } 81 | } 82 | } 83 | if(input.getWidth() > 1 && input.getHeight() > 1) { 84 | BufferedImage img2 = new BufferedImage(input.getWidth() >> 1, input.getHeight() >> 1, BufferedImage.TYPE_INT_ARGB); 85 | Graphics g = img2.getGraphics(); 86 | ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 87 | g.drawImage(input, 0, 0, img2.getWidth(), img2.getHeight(), 0, 0, input.getWidth(), input.getHeight(), null); 88 | g.dispose(); 89 | input = img2; 90 | }else { 91 | dos.write(0); 92 | break; 93 | } 94 | } 95 | return lvls; 96 | } 97 | 98 | private static boolean isPowOf2(int x) { 99 | return (x & (x - 1)) == 0; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/EaglerBinaryTools.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | /** 4 | * Copyright (c) 2024 lax1dude. All Rights Reserved. 5 | * 6 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 7 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 8 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 9 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 10 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 11 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 12 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 13 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 14 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15 | * POSSIBILITY OF SUCH DAMAGE. 16 | * 17 | */ 18 | public class EaglerBinaryTools { 19 | 20 | public static void main(String[] args) throws Throwable { 21 | if(args.length < 1) { 22 | usage(); 23 | return; 24 | } 25 | String[] argz = new String[args.length - 1]; 26 | System.arraycopy(args, 1, argz, 0, argz.length); 27 | switch(args[0].toLowerCase()) { 28 | case "epkcompiler": 29 | case "epkcompile": 30 | EPKCompiler._main(argz); 31 | return; 32 | case "legacy-epkcompiler": 33 | case "legacyepkcompiler": 34 | case "legacy-epkcompile": 35 | case "legacyepkcompile": 36 | EPKCompilerLegacy._main(argz); 37 | return; 38 | case "epkdecompiler": 39 | EPKDecompiler._main(argz); 40 | return; 41 | case "obj2mdl-1.5-old": 42 | case "obj2mdl-1.5old": 43 | case "obj2mdl1.5-old": 44 | case "obj2mdl1.5old": 45 | OBJConverter._main(argz, false); 46 | return; 47 | case "obj2mdl-1.8-old": 48 | case "obj2mdl-1.8old": 49 | case "obj2mdl1.8-old": 50 | case "obj2mdl-old": 51 | case "obj2mdlold": 52 | OBJConverter._main(argz, true); 53 | return; 54 | case "obj2mdl-1.5-new": 55 | case "obj2mdl-1.5new": 56 | case "obj2mdl1.5-new": 57 | case "obj2mdl1.5new": 58 | case "obj2mdl-1.5": 59 | case "obj2mdl1.5": 60 | OptimizedOBJConverter._main(argz, false); 61 | return; 62 | case "obj2mdl-1.8-new": 63 | case "obj2mdl-1.8new": 64 | case "obj2mdl1.8-new": 65 | case "obj2mdl1.8new": 66 | case "obj2mdl-new": 67 | case "obj2mdlnew": 68 | case "obj2mdl-1.8": 69 | case "obj2mdl1.8": 70 | case "obj2mdl": 71 | OptimizedOBJConverter._main(argz, true); 72 | return; 73 | case "ebp-encode": 74 | case "ebpencode": 75 | case "ebp-encoder": 76 | case "ebpencoder": 77 | EBPFileEncoder._main(argz); 78 | return; 79 | case "ebp-decode": 80 | case "ebpdecode": 81 | case "ebp-decoder": 82 | case "ebpdecoder": 83 | EBPFileDecoder._main(argz); 84 | return; 85 | case "skybox-gen": 86 | case "skyboxgen": 87 | SkyboxGen._main(argz); 88 | return; 89 | case "light-mesh-gen": 90 | case "lightmeshgen": 91 | LightMeshGen._main(argz); 92 | return; 93 | case "eagler-bmp-gen": 94 | case "eaglerbmpgen": 95 | EaglerBMPGen._main(argz); 96 | return; 97 | default: 98 | usage(); 99 | return; 100 | } 101 | } 102 | 103 | private static void usage() { 104 | System.out.println("Usage: java -jar EaglerBinaryTools.jar [args...]"); 105 | System.out.println(" - 'epkcompiler': Compile an EPK file from a folder"); 106 | System.out.println(" - 'legacy-epkcompiler': Compile an EPK file in legacy format"); 107 | System.out.println(" - 'epkdecompiler': Decompile an EPK file into a folder"); 108 | System.out.println(" - 'obj2mdl-1.5': Compile FNAW skin MDL file for 1.5"); 109 | System.out.println(" - 'obj2mdl-1.8': Compile FNAW skin MDL file for 1.8"); 110 | System.out.println(" - 'obj2mdl-1.5-old': Compile FNAW skin MDL file for 1.5 using the old OBJ converter"); 111 | System.out.println(" - 'obj2mdl-1.8-old': Compile FNAW skin MDL file for 1.8 using the old OBJ converter"); 112 | System.out.println(" - 'ebp-encode': Encode EBP file from PNG"); 113 | System.out.println(" - 'ebp-decode': Decode EBP file to PNG"); 114 | System.out.println(" - 'skybox-gen': Generate skybox.dat from OBJ for shader packs"); 115 | System.out.println(" - 'light-mesh-gen': Generate light_point_mesh.dat from OBJ for shader packs"); 116 | System.out.println(" - 'eagler-bmp-gen': Generate moon and lens flare BMP textures from PNG for shader packs"); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/LightMeshGen.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.DataOutputStream; 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | import net.lax1dude.eaglercraft.bintools.utils.IEEE754; 17 | 18 | /** 19 | * Copyright (c) 2023-2024 lax1dude. All Rights Reserved. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | public class LightMeshGen { 34 | 35 | public static void _main(String[] args) throws IOException { 36 | if(args.length != 2 && args.length != 3) { 37 | System.out.println("Usage: light-mesh-gen [mesh name]"); 38 | System.out.println("Input file format is Wavefront OBJ file exported from your 3D modeling program"); 39 | System.out.println("The only mesh name currently used by eagler is \"light_point_mesh\""); 40 | return; 41 | } 42 | System.out.println("Reading input file..."); 43 | List lns = new ArrayList(); 44 | try(BufferedReader bu = new BufferedReader(new FileReader(new File(args[0])))) { 45 | String s; 46 | while((s = bu.readLine()) != null) { 47 | lns.add(s); 48 | } 49 | } 50 | File output = new File(args[1]); 51 | System.out.println("Exporting light mesh: " + output.getAbsolutePath()); 52 | try(FileOutputStream fs = new FileOutputStream(output)) { 53 | convertModel(lns, args.length == 3 ? args[2] : "light_point_mesh", fs); 54 | } 55 | System.out.println("Light mesh export complete!"); 56 | } 57 | 58 | public static void convertModel(Collection lines, String name, OutputStream out) throws IOException { 59 | 60 | List vertexes = new ArrayList(); 61 | List faces = new ArrayList(); 62 | List vboentries = new ArrayList(); 63 | List vboentriesF = new ArrayList(); 64 | List indexablevboentries = new ArrayList(); 65 | List indexbuffer = new ArrayList(); 66 | for(String ul : lines) { 67 | String[] l = ul.split(" "); 68 | if(l[0].equals("v")) { 69 | vertexes.add(new float[] {Float.parseFloat(l[1]), Float.parseFloat(l[2]), Float.parseFloat(l[3])}); 70 | } 71 | if(l[0].equals("f")) { 72 | if(l.length != 4) { 73 | OBJConverter.printTriangulationMessage(); 74 | throw new IOException("Incompatible model! (This can be fixed)"); 75 | } 76 | String[] v1 = l[1].split("/"); 77 | String[] v2 = l[2].split("/"); 78 | String[] v3 = l[3].split("/"); 79 | faces.add(new int[][] { 80 | {Integer.parseInt(v1[0]), Integer.parseInt(v1[1]), Integer.parseInt(v1[2])}, 81 | {Integer.parseInt(v2[0]), Integer.parseInt(v2[1]), Integer.parseInt(v2[2])}, 82 | {Integer.parseInt(v3[0]), Integer.parseInt(v3[1]), Integer.parseInt(v3[2])} 83 | }); 84 | } 85 | } 86 | 87 | int w = 32; 88 | int h = 16; 89 | int[] normalsLookupTexture = new int[w * h]; 90 | int normalsId = 0; 91 | 92 | 93 | for(int[][] f : faces) { 94 | 95 | for(int i = 0; i < 3; i++) { 96 | byte[] b = new byte[6]; 97 | 98 | float[] v = vertexes.get(f[i][0]-1); 99 | 100 | int ix = IEEE754.encodeHalfFloat(v[0]); 101 | int iy = IEEE754.encodeHalfFloat(v[1]); 102 | int iz = IEEE754.encodeHalfFloat(v[2]); 103 | 104 | int idx = 0; 105 | 106 | b[idx++] = (byte)(ix); b[idx++] = (byte)(ix >> 8); 107 | b[idx++] = (byte)(iy); b[idx++] = (byte)(iy >> 8); 108 | b[idx++] = (byte)(iz); b[idx++] = (byte)(iz >> 8); 109 | 110 | vboentries.add(b); 111 | vboentriesF.add(v); 112 | } 113 | } 114 | 115 | for(int j = 0; j < vboentries.size(); ++j) { 116 | byte v[] = vboentries.get(j); 117 | int l = indexablevboentries.size(); 118 | boolean flag = true; 119 | for(int i = 0; i < l; i++) { 120 | if(Arrays.equals(v, indexablevboentries.get(i))) { 121 | indexbuffer.add(i); 122 | flag = false; 123 | break; 124 | } 125 | } 126 | if(flag) { 127 | if(l > 255) { 128 | throw new UnsupportedOperationException("Too many vertices!"); 129 | } 130 | indexbuffer.add(l); 131 | indexablevboentries.add(v); 132 | } 133 | } 134 | 135 | DataOutputStream o = new DataOutputStream(out); 136 | o.write(0xEE); 137 | o.write(0xAA); 138 | o.write(0x66); 139 | o.write('%'); 140 | o.write(name.length()); 141 | o.write(name.getBytes(StandardCharsets.US_ASCII)); 142 | o.writeInt(indexablevboentries.size()); 143 | for(int i = 0; i < indexablevboentries.size(); ++i) { 144 | byte[] b = indexablevboentries.get(i); 145 | o.write(b, 0, b.length); 146 | } 147 | 148 | o.writeInt(indexbuffer.size()); 149 | o.write(1); // 1 = byte, 2 = short, 4 = int 150 | 151 | for(int i : indexbuffer) { 152 | o.write(i & 0xFF); 153 | } 154 | 155 | o.close(); 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/OBJConverter.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.DataOutputStream; 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.Collection; 14 | import java.util.List; 15 | 16 | /** 17 | * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | */ 31 | @Deprecated 32 | public class OBJConverter { 33 | 34 | public static void _main(String[] args, boolean v1_8) throws IOException { 35 | if(args.length != 3) { 36 | System.out.println("Usage: obj2mdl-" + (v1_8 ? "1.8" : "1.5") + " "); 37 | System.out.println("Input file format is Wavefront OBJ file exported from your 3D modeling program"); 38 | System.out.println("Texture mode can be 'true' or 'false' to enable/disable exporting texture UV coordinates"); 39 | return; 40 | } 41 | System.out.println("Reading input file..."); 42 | List lns = new ArrayList(); 43 | try(BufferedReader bu = new BufferedReader(new FileReader(new File(args[0])))) { 44 | String s; 45 | while((s = bu.readLine()) != null) { 46 | lns.add(s); 47 | } 48 | } 49 | File output = new File(args[1]); 50 | System.out.println("Exporting " + (v1_8 ? "1.8" : "1.5") + " MDL: " + output.getAbsolutePath()); 51 | boolean tex = args[2].equalsIgnoreCase("true") || args[2].equals("1"); 52 | if (!output.exists()) { 53 | if (output.getParentFile() != null) 54 | if (!output.getParentFile().exists()) 55 | if (!output.getParentFile().mkdirs()) 56 | throw new RuntimeException("Failed to create parent dir!"); 57 | if (!output.createNewFile()) 58 | throw new RuntimeException("Failed to create file!"); 59 | } 60 | try(FileOutputStream fs = new FileOutputStream(output, false)) { 61 | convertModel(lns, fs, tex, v1_8); 62 | } 63 | if(tex) { 64 | System.out.println("Export with UVs completed!"); 65 | }else { 66 | System.out.println("Export without UVs competed!"); 67 | } 68 | } 69 | 70 | public static void convertModel(Collection lines, OutputStream out, boolean textureMode, boolean v1_8) throws IOException { 71 | List vertexes = new ArrayList(); 72 | List normals = new ArrayList(); 73 | List texcoords = new ArrayList(); 74 | List faces = new ArrayList(); 75 | List vboentries = new ArrayList(); 76 | List indexablevboentries = new ArrayList(); 77 | List indexbuffer = new ArrayList(); 78 | for(String ul : lines) { 79 | String[] l = ul.split(" "); 80 | if(l[0].equals("v")) { 81 | vertexes.add(new float[] {Float.parseFloat(l[1]), Float.parseFloat(l[2]), Float.parseFloat(l[3])}); 82 | } 83 | if(l[0].equals("vn")) { 84 | int dumb = v1_8 ? 0 : 127; 85 | normals.add(new byte[] {(byte)((int)(Float.parseFloat(l[1]) * 127.0F) + dumb), (byte)((int)(Float.parseFloat(l[2]) * 127.0F) + dumb), (byte)((int)(Float.parseFloat(l[3]) * 127.0F) + dumb), (byte)0}); 86 | } 87 | if(textureMode) { 88 | if(l[0].equals("vt")) { 89 | texcoords.add(new float[] {Float.parseFloat(l[1]), 1.0f - Float.parseFloat(l[2])}); 90 | } 91 | } 92 | if(l[0].equals("f")) { 93 | if(l.length != 4) { 94 | printTriangulationMessage(); 95 | throw new IOException("Incompatible model! (This can be fixed)"); 96 | } 97 | String[] v1 = l[1].split("/"); 98 | String[] v2 = l[2].split("/"); 99 | String[] v3 = l[3].split("/"); 100 | faces.add(new int[][] { 101 | {Integer.parseInt(v1[0]), Integer.parseInt(v1[1]), Integer.parseInt(v1[2])}, 102 | {Integer.parseInt(v2[0]), Integer.parseInt(v2[1]), Integer.parseInt(v2[2])}, 103 | {Integer.parseInt(v3[0]), Integer.parseInt(v3[1]), Integer.parseInt(v3[2])} 104 | }); 105 | } 106 | } 107 | 108 | for(int[][] f : faces) { 109 | 110 | for(int i = 0; i < 3; i++) { 111 | byte[] b = new byte[textureMode ? 24 : 16]; 112 | 113 | float[] v = vertexes.get(f[i][0]-1); 114 | 115 | int ix = Float.floatToRawIntBits(v[0]); 116 | int iy = Float.floatToRawIntBits(v[1]); 117 | int iz = Float.floatToRawIntBits(v[2]); 118 | 119 | int idx = 0; 120 | 121 | b[idx++] = (byte)(ix); b[idx++] = (byte)(ix >> 8); b[idx++] = (byte)(ix >> 16); b[idx++] = (byte)(ix >> 24); 122 | b[idx++] = (byte)(iy); b[idx++] = (byte)(iy >> 8); b[idx++] = (byte)(iy >> 16); b[idx++] = (byte)(iy >> 24); 123 | b[idx++] = (byte)(iz); b[idx++] = (byte)(iz >> 8); b[idx++] = (byte)(iz >> 16); b[idx++] = (byte)(iz >> 24); 124 | 125 | byte[] n = normals.get(f[i][2]-1); 126 | 127 | b[idx++] = n[0]; 128 | b[idx++] = n[1]; 129 | b[idx++] = n[2]; 130 | b[idx++] = n[3]; 131 | 132 | if(textureMode) { 133 | float[] t = texcoords.get(f[i][1]-1); 134 | int ix3 = Float.floatToRawIntBits(t[0]); 135 | int iy3 = Float.floatToRawIntBits(t[1]); 136 | 137 | b[idx++] = (byte)(ix3); b[idx++] = (byte)(ix3 >> 8); b[idx++] = (byte)(ix3 >> 16); b[idx++] = (byte)(ix3 >> 24); 138 | b[idx++] = (byte)(iy3); b[idx++] = (byte)(iy3 >> 8); b[idx++] = (byte)(iy3 >> 16); b[idx++] = (byte)(iy3 >> 24); 139 | } 140 | 141 | vboentries.add(b); 142 | } 143 | } 144 | 145 | for(int j = 0; j < vboentries.size(); ++j) { 146 | byte v[] = vboentries.get(j); 147 | int l = indexablevboentries.size(); 148 | boolean flag = true; 149 | for(int i = 0; i < l; i++) { 150 | if(Arrays.equals(v, indexablevboentries.get(i))) { 151 | indexbuffer.add(i); 152 | flag = false; 153 | break; 154 | } 155 | } 156 | if(flag) { 157 | if(l > 65535) { 158 | throw new IOException("Too many vertices!"); 159 | } 160 | indexbuffer.add(l); 161 | indexablevboentries.add(v); 162 | } 163 | } 164 | 165 | DataOutputStream o = new DataOutputStream(out); 166 | o.write((v1_8 ? "!EAG$mdl" : "!EAG%mdl").getBytes(StandardCharsets.US_ASCII)); 167 | o.write(textureMode ? (byte)'T' : (byte)'C'); 168 | 169 | o.writeUTF("\n\nthis file was generated with EaglerBinaryTools\n\n"); 170 | 171 | o.writeInt(indexablevboentries.size()); 172 | o.writeInt(indexbuffer.size()); 173 | for(int i = 0; i < indexablevboentries.size(); ++i) { 174 | byte[] b = indexablevboentries.get(i); 175 | o.write(b, 0, b.length); 176 | } 177 | for(int i : indexbuffer) { 178 | o.write((byte)i); 179 | o.write((byte)(i >> 8)); 180 | } 181 | o.write("_:>+".getBytes(StandardCharsets.US_ASCII)); 182 | 183 | o.close(); 184 | } 185 | 186 | static void printTriangulationMessage() { 187 | System.err.println("====================================="); 188 | System.err.println("THIS OBJ FILE IS NOT COMPATIBLE WITH EAGLERCRAFT!"); 189 | System.err.println(); 190 | System.err.println("Eaglercraft meshes can only have triangles in them."); 191 | System.err.println(); 192 | System.err.println("If you're using Blender, add the \"triangulate\""); 193 | System.err.println("modifier to the mesh before exporting to fix"); 194 | System.err.println("====================================="); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/OptimizedOBJConverter.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.*; 4 | import java.nio.charset.StandardCharsets; 5 | import java.util.*; 6 | 7 | public class OptimizedOBJConverter { 8 | 9 | public static void _main(String[] args, boolean v1_8) throws IOException { 10 | if(args.length != 3) { 11 | System.out.println("Usage: obj2mdl-" + (v1_8 ? "1.8" : "1.5") + " "); 12 | System.out.println("Input file format is Wavefront OBJ file exported from your 3D modeling program"); 13 | System.out.println("Texture mode can be 'true' or 'false' to enable/disable exporting texture UV coordinates"); 14 | return; 15 | } 16 | System.out.println("Reading input file..."); 17 | List lns = new ArrayList(); 18 | try(BufferedReader bu = new BufferedReader(new FileReader(new File(args[0])))) { 19 | String s; 20 | while((s = bu.readLine()) != null) { 21 | lns.add(s); 22 | } 23 | } 24 | File output = new File(args[1]); 25 | System.out.println("Exporting " + (v1_8 ? "1.8" : "1.5") + " MDL: " + output.getAbsolutePath()); 26 | boolean tex = args[2].equalsIgnoreCase("true") || args[2].equals("1"); 27 | if (!output.exists()) { 28 | if (output.getParentFile() != null) 29 | if (!output.getParentFile().exists()) 30 | if (!output.getParentFile().mkdirs()) 31 | throw new RuntimeException("Failed to create parent dir!"); 32 | if (!output.createNewFile()) 33 | throw new RuntimeException("Failed to create file!"); 34 | } 35 | try(FileOutputStream fs = new FileOutputStream(output)) { 36 | convertModel(lns, fs, tex, v1_8); 37 | } 38 | if(tex) { 39 | System.out.println("Export with UVs completed!"); 40 | }else { 41 | System.out.println("Export without UVs competed!"); 42 | } 43 | } 44 | 45 | public static void convertModel(Collection lines, OutputStream out, boolean textureMode, boolean v1_8) throws IOException { 46 | List vertexes = new ArrayList(); 47 | List normals = new ArrayList(); 48 | List texcoords = new ArrayList(); 49 | List faces = new ArrayList(); 50 | List vboentries = new ArrayList(); 51 | IndexLinkedHashSet indexablevboentries = new IndexLinkedHashSet<>(); 52 | List indexbuffer = new ArrayList(); 53 | for(String ul : lines) { 54 | String[] l = ul.split(" "); 55 | if(l[0].equals("v")) { 56 | vertexes.add(new float[] {Float.parseFloat(l[1]), Float.parseFloat(l[2]), Float.parseFloat(l[3])}); 57 | } 58 | if(l[0].equals("vn")) { 59 | int dumb = v1_8 ? 0 : 127; 60 | normals.add(new byte[] {(byte)((int)(Float.parseFloat(l[1]) * 127.0F) + dumb), (byte)((int)(Float.parseFloat(l[2]) * 127.0F) + dumb), (byte)((int)(Float.parseFloat(l[3]) * 127.0F) + dumb), (byte)0}); 61 | } 62 | if(textureMode) { 63 | if(l[0].equals("vt")) { 64 | texcoords.add(new float[] {Float.parseFloat(l[1]), 1.0f - Float.parseFloat(l[2])}); 65 | } 66 | } 67 | if(l[0].equals("f")) { 68 | if(l.length != 4) { 69 | printTriangulationMessage(); 70 | throw new IOException("Incompatible model! (This can be fixed)"); 71 | } 72 | String[] v1 = l[1].split("/"); 73 | String[] v2 = l[2].split("/"); 74 | String[] v3 = l[3].split("/"); 75 | faces.add(new int[][] { 76 | {Integer.parseInt(v1[0]), Integer.parseInt(v1[1]), Integer.parseInt(v1[2])}, 77 | {Integer.parseInt(v2[0]), Integer.parseInt(v2[1]), Integer.parseInt(v2[2])}, 78 | {Integer.parseInt(v3[0]), Integer.parseInt(v3[1]), Integer.parseInt(v3[2])} 79 | }); 80 | } 81 | } 82 | 83 | for(int[][] f : faces) { 84 | 85 | for(int i = 0; i < 3; i++) { 86 | byte[] b = new byte[textureMode ? 24 : 16]; 87 | 88 | float[] v = vertexes.get(f[i][0]-1); 89 | 90 | int ix = Float.floatToRawIntBits(v[0]); 91 | int iy = Float.floatToRawIntBits(v[1]); 92 | int iz = Float.floatToRawIntBits(v[2]); 93 | 94 | int idx = 0; 95 | 96 | b[idx++] = (byte)(ix); b[idx++] = (byte)(ix >> 8); b[idx++] = (byte)(ix >> 16); b[idx++] = (byte)(ix >> 24); 97 | b[idx++] = (byte)(iy); b[idx++] = (byte)(iy >> 8); b[idx++] = (byte)(iy >> 16); b[idx++] = (byte)(iy >> 24); 98 | b[idx++] = (byte)(iz); b[idx++] = (byte)(iz >> 8); b[idx++] = (byte)(iz >> 16); b[idx++] = (byte)(iz >> 24); 99 | 100 | byte[] n = normals.get(f[i][2]-1); 101 | 102 | b[idx++] = n[0]; 103 | b[idx++] = n[1]; 104 | b[idx++] = n[2]; 105 | b[idx++] = n[3]; 106 | 107 | if(textureMode) { 108 | float[] t = texcoords.get(f[i][1]-1); 109 | int ix3 = Float.floatToRawIntBits(t[0]); 110 | int iy3 = Float.floatToRawIntBits(t[1]); 111 | 112 | b[idx++] = (byte)(ix3); b[idx++] = (byte)(ix3 >> 8); b[idx++] = (byte)(ix3 >> 16); b[idx++] = (byte)(ix3 >> 24); 113 | b[idx++] = (byte)(iy3); b[idx++] = (byte)(iy3 >> 8); b[idx++] = (byte)(iy3 >> 16); b[idx++] = (byte)(iy3 >> 24); 114 | } 115 | 116 | vboentries.add(b); 117 | } 118 | } 119 | 120 | for (byte[] v : vboentries) { 121 | int l = indexablevboentries.size(); 122 | 123 | // HashSet is amortized constant time for contains 124 | // (IndexLinkedHashSet is backed by an arraylist for indices and a HashSet for performance) 125 | if (indexablevboentries.contains(ByteArray.of(v))) { 126 | indexbuffer.add(indexablevboentries.indexOf(ByteArray.of(v))); 127 | } else { 128 | if (l > 65535) 129 | throw new RuntimeException("Too many vertices!"); 130 | indexbuffer.add(l); 131 | indexablevboentries.add(ByteArray.of(v)); 132 | } 133 | } 134 | 135 | DataOutputStream o = new DataOutputStream(out); 136 | o.write((v1_8 ? "!EAG$mdl" : "!EAG%mdl").getBytes(StandardCharsets.US_ASCII)); 137 | o.write(textureMode ? (byte)'T' : (byte)'C'); 138 | 139 | o.writeUTF("\n\nthis file was generated with EaglerBinaryTools\n\n"); 140 | 141 | o.writeInt(indexablevboentries.size()); 142 | o.writeInt(indexbuffer.size()); 143 | for(int i = 0; i < indexablevboentries.size(); ++i) { 144 | byte[] b = indexablevboentries.get(i).array; 145 | o.write(b, 0, b.length); 146 | } 147 | for(int i : indexbuffer) { 148 | o.write((byte)i); 149 | o.write((byte)(i >> 8)); 150 | } 151 | o.write("_:>+".getBytes(StandardCharsets.US_ASCII)); 152 | 153 | o.close(); 154 | } 155 | 156 | static void printTriangulationMessage() { 157 | System.err.println("====================================="); 158 | System.err.println("THIS OBJ FILE IS NOT COMPATIBLE WITH EAGLERCRAFT!"); 159 | System.err.println(); 160 | System.err.println("Eaglercraft meshes can only have triangles in them."); 161 | System.err.println(); 162 | System.err.println("If you're using Blender, add the \"triangulate\""); 163 | System.err.println("modifier to the mesh before exporting to fix"); 164 | System.err.println("====================================="); 165 | } 166 | 167 | /* 168 | * Copied from https://stackoverflow.com/a/77179230 169 | * */ 170 | public static final class IndexLinkedHashSet implements Set { 171 | private final ArrayList list = new ArrayList<>( ); 172 | private final HashSet set = new HashSet<> ( ); 173 | 174 | public synchronized boolean add(E e) { 175 | if ( set.add(e) ) { 176 | return list.add(e); 177 | } 178 | return false; 179 | } 180 | 181 | public synchronized boolean remove(Object o) { 182 | if ( set.remove(o) ) { 183 | return list.remove(o); 184 | } 185 | return false; 186 | } 187 | 188 | @Override 189 | public boolean containsAll(Collection c) { 190 | return set.containsAll(c); 191 | } 192 | 193 | public synchronized void clear() { 194 | set.clear(); 195 | list.clear(); 196 | } 197 | 198 | public synchronized E get(int index) { 199 | return list.get(index); 200 | } 201 | 202 | 203 | // Added this function 204 | public synchronized int indexOf(E element) { 205 | return list.indexOf(element); 206 | } 207 | // 208 | 209 | public synchronized boolean removeAll(Collection c) { 210 | if ( set.removeAll(c) ) { 211 | return list.removeAll(c); 212 | } 213 | return true; 214 | } 215 | 216 | public synchronized boolean retainAll(Collection c) { 217 | if ( set.retainAll(c) ) { 218 | return list.retainAll(c); 219 | } 220 | return false; 221 | } 222 | 223 | public synchronized boolean addAll(Collection c) { 224 | boolean modified = false; 225 | for (E e : c) 226 | if (add(e)) 227 | modified = true; 228 | return modified; 229 | } 230 | 231 | @Override 232 | public synchronized int size() { 233 | return set.size(); 234 | } 235 | 236 | @Override 237 | public synchronized boolean isEmpty() { 238 | return set.isEmpty(); 239 | } 240 | 241 | @Override 242 | public synchronized boolean contains(Object o) { 243 | return set.contains(o); 244 | } 245 | 246 | @Override 247 | public synchronized Iterator iterator() { 248 | return list.iterator(); 249 | } 250 | 251 | @Override 252 | public synchronized Object[] toArray() { 253 | return list.toArray(); 254 | } 255 | 256 | @Override 257 | public synchronized T[] toArray(T[] a) { 258 | return list.toArray(a); 259 | } 260 | } 261 | 262 | public static class ByteArray { 263 | public final byte[] array; 264 | 265 | public ByteArray(byte[] array) { 266 | this.array = array; 267 | } 268 | 269 | @Override 270 | public boolean equals(Object o) { 271 | if (this == o) return true; 272 | if (o == null || getClass() != o.getClass()) return false; 273 | ByteArray byteArray = (ByteArray) o; 274 | return Arrays.equals(array, byteArray.array); 275 | } 276 | 277 | @Override 278 | public int hashCode() { 279 | return Arrays.hashCode(array); 280 | } 281 | 282 | public static ByteArray of(byte... bytes) { 283 | return new ByteArray(bytes); 284 | } 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/SkyboxGen.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.DataOutputStream; 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.ArrayList; 12 | import java.util.Collection; 13 | import java.util.List; 14 | 15 | import net.lax1dude.eaglercraft.bintools.utils.IEEE754; 16 | 17 | /** 18 | * Copyright (c) 2023-2024 lax1dude. All Rights Reserved. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | */ 32 | public class SkyboxGen { 33 | 34 | public static void _main(String[] args) throws IOException { 35 | if(args.length != 3) { 36 | System.out.println("Usage: skybox-gen "); 37 | System.out.println("Input file format is Wavefront OBJ file exported from your 3D modeling program"); 38 | System.out.println("The top and bottom shapes should combine to form one seamless dome/sphere when"); 39 | System.out.println("both are rendered in the same position. Make sure to flip the normals!"); 40 | return; 41 | } 42 | System.out.println("Reading top half..."); 43 | List lnsTop = new ArrayList(); 44 | try(BufferedReader bu = new BufferedReader(new FileReader(new File(args[0])))) { 45 | String s; 46 | while((s = bu.readLine()) != null) { 47 | lnsTop.add(s); 48 | } 49 | } 50 | System.out.println("Reading bottom half..."); 51 | List lnsBottom = new ArrayList(); 52 | try(BufferedReader bu = new BufferedReader(new FileReader(new File(args[1])))) { 53 | String s; 54 | while((s = bu.readLine()) != null) { 55 | lnsBottom.add(s); 56 | } 57 | } 58 | File output = new File(args[2]); 59 | System.out.println("Exporting skybox.dat: " + output.getAbsolutePath()); 60 | try(FileOutputStream fs = new FileOutputStream(output)) { 61 | convertModel(lnsTop, lnsBottom, fs); 62 | } 63 | System.out.println("Skybox export complete!"); 64 | } 65 | 66 | public static void convertModel(Collection linesTop, Collection linesBottom, OutputStream out) throws IOException { 67 | 68 | List vertexes = new ArrayList(); 69 | List faces = new ArrayList(); 70 | List vboentriesTop = new ArrayList(); 71 | List vboentriesFTop = new ArrayList(); 72 | List indexablevboentries = new ArrayList(); 73 | List indexbuffer = new ArrayList(); 74 | for(String ul : linesTop) { 75 | String[] l = ul.split(" "); 76 | if(l[0].equals("v")) { 77 | vertexes.add(new float[] {Float.parseFloat(l[1]), Float.parseFloat(l[2]), Float.parseFloat(l[3])}); 78 | } 79 | if(l[0].equals("f")) { 80 | if(l.length != 4) { 81 | OBJConverter.printTriangulationMessage(); 82 | throw new IOException("Incompatible top model! (This can be fixed)"); 83 | } 84 | String[] v1 = l[1].split("/"); 85 | String[] v2 = l[2].split("/"); 86 | String[] v3 = l[3].split("/"); 87 | faces.add(new int[][] { 88 | {Integer.parseInt(v1[0]), Integer.parseInt(v1[1]), Integer.parseInt(v1[2])}, 89 | {Integer.parseInt(v2[0]), Integer.parseInt(v2[1]), Integer.parseInt(v2[2])}, 90 | {Integer.parseInt(v3[0]), Integer.parseInt(v3[1]), Integer.parseInt(v3[2])} 91 | }); 92 | } 93 | } 94 | 95 | 96 | for(int[][] f : faces) { 97 | 98 | for(int i = 0; i < 3; i++) { 99 | byte[] b = new byte[6]; 100 | 101 | float[] v = vertexes.get(f[i][0]-1); 102 | 103 | int ix = IEEE754.encodeHalfFloat(v[0]); 104 | int iy = IEEE754.encodeHalfFloat(v[1]); 105 | int iz = IEEE754.encodeHalfFloat(v[2]); 106 | 107 | int idx = 0; 108 | 109 | b[idx++] = (byte)(ix); b[idx++] = (byte)(ix >> 8); 110 | b[idx++] = (byte)(iy); b[idx++] = (byte)(iy >> 8); 111 | b[idx++] = (byte)(iz); b[idx++] = (byte)(iz >> 8); 112 | 113 | vboentriesTop.add(b); 114 | vboentriesFTop.add(v); 115 | } 116 | } 117 | 118 | vertexes.clear(); 119 | faces.clear(); 120 | List vboentriesBottom = new ArrayList(); 121 | List vboentriesFBottom = new ArrayList(); 122 | 123 | for(String ul : linesBottom) { 124 | String[] l = ul.split(" "); 125 | if(l[0].equals("v")) { 126 | vertexes.add(new float[] {Float.parseFloat(l[1]), Float.parseFloat(l[2]), Float.parseFloat(l[3])}); 127 | } 128 | if(l[0].equals("f")) { 129 | if(l.length != 4) { 130 | OBJConverter.printTriangulationMessage(); 131 | throw new IOException("Incompatible bottom model! (This can be fixed)"); 132 | } 133 | String[] v1 = l[1].split("/"); 134 | String[] v2 = l[2].split("/"); 135 | String[] v3 = l[3].split("/"); 136 | faces.add(new int[][] { 137 | {Integer.parseInt(v1[0]), Integer.parseInt(v1[1]), Integer.parseInt(v1[2])}, 138 | {Integer.parseInt(v2[0]), Integer.parseInt(v2[1]), Integer.parseInt(v2[2])}, 139 | {Integer.parseInt(v3[0]), Integer.parseInt(v3[1]), Integer.parseInt(v3[2])} 140 | }); 141 | } 142 | } 143 | 144 | 145 | for(int[][] f : faces) { 146 | 147 | for(int i = 0; i < 3; i++) { 148 | byte[] b = new byte[6]; 149 | 150 | float[] v = vertexes.get(f[i][0]-1); 151 | 152 | int ix = IEEE754.encodeHalfFloat(v[0]); 153 | int iy = IEEE754.encodeHalfFloat(v[1]); 154 | int iz = IEEE754.encodeHalfFloat(v[2]); 155 | 156 | int idx = 0; 157 | 158 | b[idx++] = (byte)(ix); b[idx++] = (byte)(ix >> 8); 159 | b[idx++] = (byte)(iy); b[idx++] = (byte)(iy >> 8); 160 | b[idx++] = (byte)(iz); b[idx++] = (byte)(iz >> 8); 161 | 162 | vboentriesBottom.add(b); 163 | vboentriesFBottom.add(v); 164 | } 165 | } 166 | 167 | int w = 32; 168 | int h = 16; 169 | int[] normalsLookupTexture = new int[w * h]; 170 | int normalsId = 0; 171 | 172 | for(int j = 0; j < vboentriesTop.size(); ++j) { 173 | byte v[] = vboentriesTop.get(j); 174 | int l = indexablevboentries.size(); 175 | boolean flag = true; 176 | e: for(int i = 0; i < l; i++) { 177 | byte[] bb = indexablevboentries.get(i); 178 | for(int k = 0; k < v.length; ++k) { 179 | if(bb[k] != v[k]) { 180 | continue e; 181 | } 182 | } 183 | indexbuffer.add(i); 184 | flag = false; 185 | break; 186 | } 187 | if(flag) { 188 | if(l > 65535) { 189 | throw new IOException("Too many vertices!"); 190 | } 191 | indexbuffer.add(l); 192 | byte[] vboWithLUT = new byte[v.length + 2]; 193 | vboWithLUT[v.length + 0] = (byte)(int)(((normalsId % w) + 0.5f) / (float)w * 255.0f); 194 | vboWithLUT[v.length + 1] = (byte)(int)(((normalsId / w) + 0.5f) / (float)h * 255.0f); 195 | System.arraycopy(v, 0, vboWithLUT, 0, v.length); 196 | 197 | float[] vv = vboentriesFTop.get(j); 198 | float xx = vv[0]; 199 | float yy = vv[1]; 200 | float zz = vv[2]; 201 | float len = (float) Math.sqrt(xx * xx + yy * yy + zz * zz); 202 | xx /= len; 203 | yy /= len; 204 | zz /= len; 205 | 206 | normalsLookupTexture[normalsId] = 0xFF000000 | ((int)((xx + 1.0f) * 0.5f * 255.0f) << 16) | ((int)((yy + 1.0f) * 0.5f * 255.0f) << 8) | (int)((zz + 1.0f) * 0.5f * 255.0f); 207 | 208 | indexablevboentries.add(vboWithLUT); 209 | ++normalsId; 210 | } 211 | } 212 | 213 | for(int j = 0; j < vboentriesBottom.size(); ++j) { 214 | byte v[] = vboentriesBottom.get(j); 215 | int l = indexablevboentries.size(); 216 | boolean flag = true; 217 | e: for(int i = 0; i < l; i++) { 218 | byte[] bb = indexablevboentries.get(i); 219 | for(int k = 0; k < v.length; ++k) { 220 | if(bb[k] != v[k]) { 221 | continue e; 222 | } 223 | } 224 | indexbuffer.add(i); 225 | flag = false; 226 | break; 227 | } 228 | if(flag) { 229 | if(l > 65535) { 230 | throw new IOException("Too many vertices!"); 231 | } 232 | indexbuffer.add(l); 233 | byte[] vboWithLUT = new byte[v.length + 2]; 234 | vboWithLUT[v.length + 0] = (byte)(int)(((normalsId % w) + 0.5f) / (float)w * 255.0f); 235 | vboWithLUT[v.length + 1] = (byte)(int)(((normalsId / w) + 0.5f) / (float)h * 255.0f); 236 | System.arraycopy(v, 0, vboWithLUT, 0, v.length); 237 | 238 | float[] vv = vboentriesFBottom.get(j); 239 | float xx = vv[0]; 240 | float yy = vv[1]; 241 | float zz = vv[2]; 242 | float len = (float) Math.sqrt(xx * xx + yy * yy + zz * zz); 243 | xx /= len; 244 | yy /= len; 245 | zz /= len; 246 | 247 | normalsLookupTexture[normalsId] = 0xFF000000 | ((int)((xx + 1.0f) * 0.5f * 255.0f) << 16) | ((int)((yy + 1.0f) * 0.5f * 255.0f) << 8) | (int)((zz + 1.0f) * 0.5f * 255.0f); 248 | 249 | indexablevboentries.add(vboWithLUT); 250 | ++normalsId; 251 | } 252 | } 253 | 254 | 255 | DataOutputStream o = new DataOutputStream(out); 256 | o.write(0xEE); 257 | o.write(0xAA); 258 | o.write(0x66); 259 | o.write('%'); 260 | o.write(6); 261 | o.write("skybox".getBytes(StandardCharsets.US_ASCII)); 262 | o.writeShort(w); 263 | o.writeShort(h); 264 | for(int i = 0; i < normalsLookupTexture.length; ++i) { 265 | o.write((normalsLookupTexture[i] >> 16) & 0xFF); 266 | o.write((normalsLookupTexture[i] >> 8) & 0xFF); 267 | o.write(normalsLookupTexture[i] & 0xFF); 268 | o.write((normalsLookupTexture[i] >> 24) & 0xFF); 269 | } 270 | 271 | o.writeInt(0); 272 | o.writeInt(vboentriesTop.size()); 273 | o.writeInt(vboentriesTop.size()); 274 | o.writeInt(vboentriesBottom.size()); 275 | 276 | o.writeInt(indexablevboentries.size()); 277 | 278 | for(int i = 0; i < indexablevboentries.size(); ++i) { 279 | byte[] b = indexablevboentries.get(i); 280 | o.write(b, 0, b.length); 281 | } 282 | 283 | o.writeInt(indexbuffer.size()); 284 | o.write(2); // 1 = byte, 2 = short, 4 = int 285 | 286 | for(int i : indexbuffer) { 287 | o.write(i & 0xFF); 288 | o.write((i >> 8) & 0xFF); 289 | } 290 | 291 | o.close(); 292 | } 293 | 294 | } 295 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/utils/EPKDecompilerSP.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools.utils; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.DataInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.security.MessageDigest; 8 | import java.security.NoSuchAlgorithmException; 9 | import java.util.Arrays; 10 | import java.util.zip.CRC32; 11 | import java.util.zip.GZIPInputStream; 12 | import java.util.zip.InflaterInputStream; 13 | 14 | /** 15 | * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | */ 29 | public class EPKDecompilerSP { 30 | 31 | public static class FileEntry { 32 | public final String type; 33 | public final String name; 34 | public final byte[] data; 35 | protected FileEntry(String type, String name, byte[] data) { 36 | this.type = type; 37 | this.name = name; 38 | this.data = data; 39 | } 40 | } 41 | 42 | private ByteArrayInputStream in2; 43 | private DataInputStream in; 44 | private InputStream zis; 45 | private MessageDigest dg; 46 | private CRC32 crc32; 47 | private int numFiles; 48 | private boolean isFinished = false; 49 | private boolean isOldFormat = false; 50 | 51 | /** 52 | * This class is from the Eaglercraft 1.5 client, with a few modifications 53 | */ 54 | public EPKDecompilerSP(byte[] data) throws IOException { 55 | in2 = new ByteArrayInputStream(data); 56 | 57 | byte[] header = new byte[8]; 58 | in2.read(header); 59 | 60 | if(Arrays.equals(header, new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)36,(byte)36})) { 61 | byte[] endCode = new byte[] { (byte)':', (byte)':', (byte)':', (byte)'Y', 62 | (byte)'E', (byte)'E', (byte)':', (byte)'>' }; 63 | for(int i = 0; i < 8; ++i) { 64 | if(data[data.length - 8 + i] != endCode[i]) { 65 | throw new IOException("EPK file is missing EOF code (:::YEE:>)"); 66 | } 67 | } 68 | in2 = new ByteArrayInputStream(data, 8, data.length - 16); 69 | initNew(); 70 | }else if(Arrays.equals(header, new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)33,(byte)33})) { 71 | initOld(); 72 | } 73 | 74 | } 75 | 76 | public boolean isOld() { 77 | return isOldFormat; 78 | } 79 | 80 | public FileEntry readFile() throws IOException { 81 | if(!isOldFormat) { 82 | return readFileNew(); 83 | }else { 84 | return readFileOld(); 85 | } 86 | } 87 | 88 | private void initNew() throws IOException { 89 | InputStream is = in2; 90 | 91 | String vers = readASCII(is); 92 | if(!vers.startsWith("ver2.")) { 93 | throw new IOException("Unknown or invalid EPK version: " + vers); 94 | } 95 | 96 | is.skip(is.read()); // skip filename 97 | is.skip(loadShort(is)); // skip comment 98 | is.skip(8); // skip millis date 99 | 100 | numFiles = loadInt(is); 101 | 102 | char compressionType = (char)is.read(); 103 | 104 | switch(compressionType) { 105 | case 'G': 106 | zis = new GZIPInputStream(is); 107 | break; 108 | case 'Z': 109 | zis = new InflaterInputStream(is); 110 | break; 111 | case '0': 112 | zis = is; 113 | break; 114 | default: 115 | throw new IOException("Invalid or unsupported EPK compression: " + compressionType); 116 | } 117 | 118 | crc32 = new CRC32(); 119 | 120 | } 121 | 122 | private FileEntry readFileNew() throws IOException { 123 | if(isFinished) { 124 | return null; 125 | } 126 | 127 | byte[] typeBytes = new byte[4]; 128 | IOUtils.readFully(zis, typeBytes); 129 | String type = readASCII(typeBytes); 130 | 131 | if(numFiles == 0) { 132 | if(!"END$".equals(type)) { 133 | throw new IOException("EPK file is missing END code (END$)"); 134 | } 135 | zis.close(); 136 | isFinished = true; 137 | return null; 138 | }else { 139 | if("END$".equals(type)) { 140 | throw new IOException("Unexpected END when there are still " + numFiles + " files remaining"); 141 | }else { 142 | String name = readASCII(zis); 143 | int len = loadInt(zis); 144 | byte[] data; 145 | 146 | if("FILE".equals(type)) { 147 | if(len < 5) { 148 | throw new IOException("File '" + name + "' is incomplete (no crc)"); 149 | } 150 | 151 | int loadedCrc = loadInt(zis); 152 | 153 | data = new byte[len - 5]; 154 | IOUtils.readFully(zis, data); 155 | 156 | crc32.reset(); 157 | crc32.update(data, 0, data.length); 158 | if((int)crc32.getValue() != loadedCrc) { 159 | throw new IOException("File '" + name + "' has an invalid checksum"); 160 | } 161 | 162 | if(zis.read() != ':') { 163 | throw new IOException("File '" + name + "' is incomplete"); 164 | } 165 | }else { 166 | data = new byte[len]; 167 | IOUtils.readFully(zis, data); 168 | } 169 | 170 | if(zis.read() != '>') { 171 | throw new IOException("Object '" + name + "' is incomplete"); 172 | } 173 | 174 | --numFiles; 175 | return new FileEntry(type, name, data); 176 | } 177 | } 178 | } 179 | 180 | private static final int loadShort(InputStream is) throws IOException { 181 | return (is.read() << 8) | is.read(); 182 | } 183 | 184 | private static final int loadInt(InputStream is) throws IOException { 185 | return (is.read() << 24) | (is.read() << 16) | (is.read() << 8) | is.read(); 186 | } 187 | 188 | public static final String readASCII(byte[] bytesIn) throws IOException { 189 | char[] charIn = new char[bytesIn.length]; 190 | for(int i = 0; i < bytesIn.length; ++i) { 191 | charIn[i] = (char)((int)bytesIn[i] & 0xFF); 192 | } 193 | return new String(charIn); 194 | } 195 | 196 | private static final String readASCII(InputStream bytesIn) throws IOException { 197 | int len = bytesIn.read(); 198 | char[] charIn = new char[len]; 199 | for(int i = 0; i < len; ++i) { 200 | charIn[i] = (char)(bytesIn.read() & 0xFF); 201 | } 202 | return new String(charIn); 203 | } 204 | 205 | private void initOld() throws IOException { 206 | isOldFormat = true; 207 | try { 208 | dg = MessageDigest.getInstance("SHA-1"); 209 | }catch(NoSuchAlgorithmException ex) { 210 | throw new RuntimeException("SHA-1 is not supported in this JRE!", ex); 211 | } 212 | in = new DataInputStream(in2); 213 | in.readUTF(); 214 | in = new DataInputStream(new InflaterInputStream(in2)); 215 | } 216 | 217 | private FileEntry readFileOld() throws IOException { 218 | if(isFinished) { 219 | return null; 220 | } 221 | String s = in.readUTF(); 222 | if(s.equals(" end")) { 223 | isFinished = true; 224 | in.close(); 225 | return null; 226 | }else if(!s.equals("")) { 227 | throw new IOException("invalid epk file"); 228 | } 229 | String path = in.readUTF(); 230 | byte[] digest = new byte[20]; 231 | IOUtils.readFully(in, digest); 232 | int len = in.readInt(); 233 | byte[] file = new byte[len]; 234 | IOUtils.readFully(in, file); 235 | byte[] digest2 = dg.digest(file); 236 | if(!Arrays.equals(digest, digest2)) throw new IOException("invalid file hash for "+path); 237 | if(!"".equals(in.readUTF())) throw new IOException("invalid epk file"); 238 | return new FileEntry("FILE", path, file); 239 | } 240 | 241 | // Avoid Inflater memleak 242 | public void close() throws IOException { 243 | if(zis != null) { 244 | zis.close(); 245 | } 246 | if(in != null) { 247 | in.close(); 248 | } 249 | isFinished = true; 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/utils/GZIPOutputStream2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. 3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 | * 5 | * 6 | * 7 | * 8 | * 9 | * 10 | * 11 | * 12 | * 13 | * 14 | * 15 | * 16 | * 17 | * 18 | * 19 | * 20 | * 21 | * 22 | * 23 | * 24 | */ 25 | 26 | package net.lax1dude.eaglercraft.bintools.utils; 27 | 28 | import java.io.IOException; 29 | import java.io.OutputStream; 30 | import java.util.zip.CRC32; 31 | import java.util.zip.Deflater; 32 | import java.util.zip.DeflaterOutputStream; 33 | 34 | /** 35 | * GZIP output stream class that allows you to set the compression level 36 | */ 37 | public class GZIPOutputStream2 extends DeflaterOutputStream { 38 | 39 | protected CRC32 crc = new CRC32(); 40 | 41 | private final static int GZIP_MAGIC = 0x8b1f; 42 | 43 | private final static int TRAILER_SIZE = 8; 44 | 45 | public GZIPOutputStream2(OutputStream out, int compressionLevel, int size, boolean syncFlush) throws IOException { 46 | super(out, new Deflater(compressionLevel, true), size, syncFlush); 47 | writeHeader(); 48 | crc.reset(); 49 | } 50 | 51 | public synchronized void write(byte[] buf, int off, int len) throws IOException { 52 | super.write(buf, off, len); 53 | crc.update(buf, off, len); 54 | } 55 | 56 | public void finish() throws IOException { 57 | if (!def.finished()) { 58 | try { 59 | def.finish(); 60 | while (!def.finished()) { 61 | int len = def.deflate(buf, 0, buf.length); 62 | if (def.finished() && len <= buf.length - TRAILER_SIZE) { 63 | // last deflater buffer. Fit trailer at the end 64 | writeTrailer(buf, len); 65 | len = len + TRAILER_SIZE; 66 | out.write(buf, 0, len); 67 | return; 68 | } 69 | if (len > 0) 70 | out.write(buf, 0, len); 71 | } 72 | // if we can't fit the trailer at the end of the last 73 | // deflater buffer, we write it separately 74 | byte[] trailer = new byte[TRAILER_SIZE]; 75 | writeTrailer(trailer, 0); 76 | out.write(trailer); 77 | } catch (IOException e) { 78 | def.end(); 79 | throw e; 80 | } 81 | } 82 | } 83 | 84 | private void writeHeader() throws IOException { 85 | out.write(new byte[] { (byte) GZIP_MAGIC, // Magic number (short) 86 | (byte) (GZIP_MAGIC >> 8), // Magic number (short) 87 | Deflater.DEFLATED, // Compression method (CM) 88 | 0, // Flags (FLG) 89 | 0, // Modification time MTIME (int) 90 | 0, // Modification time MTIME (int) 91 | 0, // Modification time MTIME (int) 92 | 0, // Modification time MTIME (int) 93 | 0, // Extra flags (XFLG) 94 | 0 // Operating system (OS) 95 | }); 96 | } 97 | 98 | private void writeTrailer(byte[] buf, int offset) throws IOException { 99 | writeInt((int) crc.getValue(), buf, offset); // CRC-32 of uncompr. data 100 | writeInt(def.getTotalIn(), buf, offset + 4); // Number of uncompr. bytes 101 | } 102 | 103 | private void writeInt(int i, byte[] buf, int offset) throws IOException { 104 | writeShort(i & 0xffff, buf, offset); 105 | writeShort((i >> 16) & 0xffff, buf, offset + 2); 106 | } 107 | 108 | private void writeShort(int s, byte[] buf, int offset) throws IOException { 109 | buf[offset] = (byte) (s & 0xff); 110 | buf[offset + 1] = (byte) ((s >> 8) & 0xff); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/utils/IEEE754.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools.utils; 2 | 3 | public class IEEE754 { 4 | 5 | // source: https://stackoverflow.com/questions/6162651/half-precision-floating-point-in-java 6 | 7 | public static int encodeHalfFloat(float fval) { 8 | int fbits = Float.floatToIntBits(fval); 9 | int sign = fbits >>> 16 & 0x8000; // sign only 10 | int val = (fbits & 0x7fffffff) + 0x1000; // rounded value 11 | 12 | if (val >= 0x47800000) // might be or become NaN/Inf 13 | { // avoid Inf due to rounding 14 | if ((fbits & 0x7fffffff) >= 0x47800000) { // is or must become NaN/Inf 15 | if (val < 0x7f800000) // was value but too large 16 | return sign | 0x7c00; // make it +/-Inf 17 | return sign | 0x7c00 | // remains +/-Inf or NaN 18 | (fbits & 0x007fffff) >>> 13; // keep NaN (and Inf) bits 19 | } 20 | return sign | 0x7bff; // unrounded not quite Inf 21 | } 22 | if (val >= 0x38800000) // remains normalized value 23 | return sign | val - 0x38000000 >>> 13; // exp - 127 + 15 24 | if (val < 0x33000000) // too small for subnormal 25 | return sign; // becomes +/-0 26 | val = (fbits & 0x7fffffff) >>> 23; // tmp exp for subnormal calc 27 | return sign | ((fbits & 0x7fffff | 0x800000) // add subnormal bit 28 | + (0x800000 >>> val - 102) // round depending on cut off 29 | >>> 126 - val); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/utils/IOUtils.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools.utils; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * Copyright (c) 2024 lax1dude. All Rights Reserved. 8 | * 9 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 10 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 13 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 14 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 15 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 16 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 17 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 18 | * POSSIBILITY OF SUCH DAMAGE. 19 | * 20 | */ 21 | public class IOUtils { 22 | 23 | public static int readFully(InputStream is, byte[] out) throws IOException { 24 | int i = 0, j; 25 | while(i < out.length && (j = is.read(out, i, out.length - i)) != -1) { 26 | i += j; 27 | } 28 | return i; 29 | } 30 | 31 | public static long skipFully(InputStream is, long skip) throws IOException { 32 | long i = 0, j; 33 | while(i < skip && (j = is.skip(skip - i)) != 0) { 34 | i += j; 35 | } 36 | return i; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/lax1dude/eaglercraft/bintools/utils/LabPBR2Eagler.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools.utils; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | /** 6 | * Copyright (c) 2024 lax1dude. All Rights Reserved. 7 | * 8 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 9 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 10 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 11 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 12 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 13 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 14 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 15 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 16 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 17 | * POSSIBILITY OF SUCH DAMAGE. 18 | * 19 | */ 20 | public class LabPBR2Eagler { 21 | 22 | /** 23 | * See net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.texture.PBRTextureMapUtils 24 | */ 25 | public static void convertLabPBRToEagler(BufferedImage input, BufferedImage output) { 26 | for(int w = input.getWidth(), x = 0; x < w; ++x) { 27 | for(int h = input.getHeight(), y = 0; y < h; ++y) { 28 | int pixel = input.getRGB(x, y); 29 | int a = (pixel >>> 24) & 0xFF; 30 | if(a == 0xFF) a = 0; 31 | output.setRGB(x, y, (pixel & 0x00FFFF00) | Math.min(a << 2, 0xFF) | 0xFF000000); 32 | } 33 | } 34 | } 35 | 36 | public static void convertEaglerToLabPBR(BufferedImage input, BufferedImage output) { 37 | for(int w = input.getWidth(), x = 0; x < w; ++x) { 38 | for(int h = input.getHeight(), y = 0; y < h; ++y) { 39 | int pixel = input.getRGB(x, y); 40 | int a = (pixel >>> 2) & 0x3F; 41 | if(a == 0) a = 0xFF; 42 | output.setRGB(x, y, (pixel & 0x00FFFF00) | (a << 24)); 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/net/lax1dude/eaglercraft/bintools/TestOptimizedOBJConverter.java: -------------------------------------------------------------------------------- 1 | package net.lax1dude.eaglercraft.bintools; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.platform.commons.annotation.Testable; 6 | 7 | import java.io.FileInputStream; 8 | import java.io.IOException; 9 | 10 | @Testable 11 | public class TestOptimizedOBJConverter { 12 | @Test 13 | @SuppressWarnings("ConstantConditions") 14 | public void test() throws IOException { 15 | String[] paramz = { 16 | "samples/obj2mdl-fnaw/laxativedude1.obj", "samples/obj2mdl-fnaw/tests/output/laxativedude1.mdl", "true" 17 | }; 18 | OBJConverter._main(paramz, true); 19 | paramz[1] = "samples/obj2mdl-fnaw/tests/output/o_laxativedude1.mdl"; 20 | OptimizedOBJConverter._main(paramz, true); 21 | 22 | try (FileInputStream optimizedProgramOutput = new FileInputStream(paramz[1]); 23 | FileInputStream originalProgramOutput = new FileInputStream( "samples/obj2mdl-fnaw/tests/output/laxativedude1.mdl")) { 24 | 25 | int o; 26 | int r; 27 | 28 | while ((o = optimizedProgramOutput.read()) != -2 && (r = originalProgramOutput.read()) != -2) { 29 | if (o == r && r == -1) 30 | break; 31 | 32 | if (o != r) 33 | Assertions.fail("Output is not the same!"); 34 | } 35 | } catch (Exception e) { 36 | Assertions.fail(e.getMessage()); 37 | } 38 | } 39 | } 40 | --------------------------------------------------------------------------------