/******************************************************************************* * Copyright (c) 2015 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *******************************************************************************/ package jsettlers.common.texturegeneration; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; /** * This program compiles all textures into the needed format for graphics * * @author michael */ public class TextureCompiler implements Runnable, TextureIndex { private DataOutputStream textureIndexOut; private int textureCounter = 0; private PrintWriter textureConstantsOut; private int imageIndexCounter; private final Hashtable<String, Integer> imageIndexes = new Hashtable<String, Integer>(); private final Object imageIndexMutex = new Object(); private final Object textureCounterMutex = new Object(); private File resourceDirectory; private File genDirectory; public TextureCompiler() { this(null, null); } public TextureCompiler(File resourceDirectory, File genDirectory) { this.setResourceDirectory(resourceDirectory); this.setGenDirectory(genDirectory); } public static void main(String[] args) { if (args.length < 3) { throw new IllegalArgumentException("Usage: compiler <intput dir> <gen dir>"); } new TextureCompiler(new File(args[1]), new File(args[2])).run(); } // For ant public void execute() throws IOException { if (genDirectory == null) { throw new RuntimeException("please use genDirectory=\"...\""); } if (resourceDirectory == null) { throw new RuntimeException("please use resourceDirectory=\"...\""); } genDirectory.mkdirs(); openTextureIndex(); File rawDirectory = new File(getResourceDirectory(), "textures_raw"); File outDirectory = new File(getResourceDirectory(), "images"); TextureGenerator gen = new TextureGenerator(this, rawDirectory, outDirectory); gen.start(); String[] files = rawDirectory.list(); for (String file : files) { if (file.matches(".*\\.png")) { String name = file.replaceAll("\\.png", ""); gen.addTexturesByName(Collections.singletonList(name)); } } gen.join(); closeTextureIndex(); } @Override public void run() { try { execute(); } catch (IOException e) { e.printStackTrace(); } } private void openTextureIndex() throws IOException { File imagesOut = new File(getResourceDirectory(), "images"); textureIndexOut = new DataOutputStream(new FileOutputStream(new File(imagesOut, "texturemap"))); textureIndexOut.write(new byte[] { 'T', 'E', 'X', '1' }); File packageDir = new File(new File(new File(getGenDirectory(), "jsettlers"), "common"), "images"); packageDir.mkdirs(); textureConstantsOut = new PrintWriter(new File(packageDir, "TextureMap.java")); textureConstantsOut.println("package jsettlers.common.images;"); textureConstantsOut.println("import java.util.Arrays;"); textureConstantsOut.println(); textureConstantsOut.println("// DO NOT EDIT THIS FILE, IT IS GENERATED"); textureConstantsOut.println(); textureConstantsOut.println("public final class TextureMap {"); textureConstantsOut.println(" private TextureMap() {}"); textureConstantsOut.println(); textureConstantsOut.println(" public static int getIndex(String name) {"); textureConstantsOut.println(" int arrindex = Arrays.binarySearch(names, name);"); textureConstantsOut.println(" if (arrindex < 0) {"); textureConstantsOut.println(" throw new IllegalArgumentException(\"Could not find \" + name + \" in image map.\");"); textureConstantsOut.println(" }"); textureConstantsOut.println(" return indexes[arrindex];"); textureConstantsOut.println(" }"); textureConstantsOut.println(); System.out.println("Opened texture index"); } private void closeTextureIndex() throws IOException { ArrayList<String> sortedIndexes = new ArrayList<String>( imageIndexes.keySet()); Collections.sort(sortedIndexes); textureIndexOut.close(); textureConstantsOut.println(" private static final String[] names = new String[] {"); for (String n : sortedIndexes) { textureConstantsOut.println(" \"" + n + "\","); } textureConstantsOut.println(" };"); textureConstantsOut.println(" private static final int[] indexes = new int[] {"); for (String n : sortedIndexes) { textureConstantsOut.println(" " + imageIndexes.get(n) + ","); } textureConstantsOut.println(" };"); textureConstantsOut.println("}"); textureConstantsOut.close(); System.out.println("Closed texture index"); } @Override public void registerTexture(String name, int textureFile, int offsetx, int offsety, int width, int height, boolean hasTorso, TexturePosition position) throws IOException { synchronized (imageIndexMutex) { String safename = name.replaceAll("[^a-zA-Z0-9._]", "_"); imageIndexes.put(safename, imageIndexCounter); textureIndexOut.writeShort(offsetx); textureIndexOut.writeShort(offsety); textureIndexOut.writeShort(width); textureIndexOut.writeShort(height); textureIndexOut.writeShort(hasTorso ? textureFile | 0x8000 : textureFile); textureIndexOut.writeShort(toShort(position.getLeft())); textureIndexOut.writeShort(toShort(position.getTop())); textureIndexOut.writeShort(toShort(position.getRight())); textureIndexOut.writeShort(toShort(position.getBottom())); System.out.println("Added image " + imageIndexCounter + " to texture " + textureFile + " and added to constant index as " + safename); imageIndexCounter++; } } private static int toShort(float left) { return (int) (left * 0x7fff); } @Override public int getNextTextureIndex() { synchronized (textureCounterMutex) { return textureCounter++; } } public File getResourceDirectory() { return resourceDirectory; } public void setResourceDirectory(File resourceDirectory) { this.resourceDirectory = resourceDirectory; } public File getGenDirectory() { return genDirectory; } public void setGenDirectory(File genDirectory) { this.genDirectory = genDirectory; } }