public static void main(String[] args) throws IOException { // Take Dungeon Keeper 2 root folder as parameter if (args.length != 2 || !new File(args[0]).exists()) { throw new RuntimeException( "Please provide Dungeon Keeper II main folder as a first parameter! Second parameter is the extraction target folder!"); } // Form the data path String dataDirectory = args[0]; if (!dataDirectory.endsWith(File.separator)) { dataDirectory = dataDirectory.concat(File.separator); } dataDirectory = dataDirectory .concat("Data") .concat(File.separator) .concat("Text") .concat(File.separator) .concat("Default") .concat(File.separator); // And the destination String destination = args[1]; if (!destination.endsWith(File.separator)) { destination = destination.concat(File.separator); } // Find all the font files final List<File> bf4Files = new ArrayList<>(); File dataDir = new File(dataDirectory); Files.walkFileTree( dataDir.toPath(), new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { // Get all the BF4 files if (attrs.isRegularFile() && file.getFileName().toString().toLowerCase().endsWith(".bf4")) { bf4Files.add(file.toFile()); } // Always continue return FileVisitResult.CONTINUE; } }); // Extract the fonts bitmaps for (File file : bf4Files) { Bf4File bf4 = new Bf4File(file); for (Bf4Entry entry : bf4) { if (entry.getImage() != null) { String baseDir = destination .concat(ConversionUtils.stripFileName(file.getName())) .concat(File.separator); new File(baseDir).mkdirs(); ImageIO.write( entry.getImage(), "png", new File( baseDir.concat( ConversionUtils.stripFileName(entry.toString()) .concat("_") .concat(Integer.toString(entry.getCharacter())) .concat(".png")))); } } } }