diff --git a/tools/dmitool/dmitool.jar b/tools/dmitool/dmitool.jar index f0fc1dc17b..c7df4d8b7f 100644 Binary files a/tools/dmitool/dmitool.jar and b/tools/dmitool/dmitool.jar differ diff --git a/tools/dmitool/dmitool.py b/tools/dmitool/dmitool.py index f24ce2c590..390f0d745f 100644 --- a/tools/dmitool/dmitool.py +++ b/tools/dmitool/dmitool.py @@ -8,7 +8,7 @@ _JAVA_PATH = ["java"] _DMITOOL_CMD = ["-jar", "dmitool.jar"] def _dmitool_call(*dmitool_args, **popen_args): - return Popen(_JAVA_PATH + _DMITOOL_CMD + list(dmitool_args), **popen_args) + return Popen(_JAVA_PATH + _DMITOOL_CMD + [str(arg) for arg in dmitool_args], **popen_args) def _safe_parse(dict, key, deferred_value): try: @@ -19,12 +19,14 @@ def _safe_parse(dict, key, deferred_value): return False def version(): - """ Prints the version to stdout. """ - return _dmitool_call("version") + """ Returns the version as a string. """ + stdout, stderr = _dmitool_call("version", stdout=PIPE).communicate() + return str(stdout).strip() def help(): - """ Prints the help text to stdout. """ - return _dmitool_call("help") + """ Returns the help text as a string. """ + stdout, stderr = _dmitool_call("help", stdout=PIPE).communicate() + return str(stdout).strip() def info(filepath): """ Totally not a hack that parses the output from dmitool into a dictionary. @@ -68,11 +70,11 @@ def extract_state(input_path, output_path, icon_state, direction=None, frame=Non If provided frame should be a frame number or a string of two frame number separated by a dash. """ args = ["extract", input_path, icon_state, output_path] - if direction: args.extend(("direction" , str(direction))) - if frame: args.extend(("frame" , str(frame))) + if direction is not None: args.extend(("direction" , str(direction))) + if frame is not None: args.extend(("frame" , str(frame))) return _dmitool_call(*args) -def import_state(target_path, input_path, icon_state, replace=False, delays=None, rewind=False, loop=None, ismovement=False, direction=None): +def import_state(target_path, input_path, icon_state, replace=False, delays=None, rewind=False, loop=None, ismovement=False, direction=None, frame=None): """ Inserts an input png given by the input_path into the target_path. """ args = ["import", target_path, icon_state, input_path] @@ -81,7 +83,8 @@ def import_state(target_path, input_path, icon_state, replace=False, delays=None if rewind: args.append("rewind") if ismovement: args.append("movement") if delays: args.extend(("delays", ",".join(delays))) - if direction: args.extend(("direction", direction)) + if direction is not None: args.extend(("direction", direction)) + if frame is not None: args.extend(("frame", frame)) if loop in ("inf", "infinity"): args.append("loop") diff --git a/tools/dmitool/src/main/java/dmitool/IconState.java b/tools/dmitool/src/main/java/dmitool/IconState.java index ee31b13792..2a2202c71c 100644 --- a/tools/dmitool/src/main/java/dmitool/IconState.java +++ b/tools/dmitool/src/main/java/dmitool/IconState.java @@ -203,7 +203,7 @@ public class IconState { px[bY][bX + 3]); } } - images[imageY + imageX*dirs] = new NonPalettedImage(w, h, pixels); + images[_getIndex(imageY, imageX, dirs)] = new NonPalettedImage(w, h, pixels); } } @@ -214,9 +214,35 @@ public class IconState { //Converts a desired dir and frame to an index into the images array. public int getIndex(int dir, int frame) { - return dir + frame*dirs; + return _getIndex(dir, frame, dirs); } + private static int _getIndex(int dir, int frame, int totalDirs) { + return dir + frame*totalDirs; + } + + public void insertDir(int dir, Image[] splice) { + int maxFrame = frames < splice.length? frames: splice.length; + for(int frameIdx = 0; frameIdx < maxFrame; frameIdx++) { + insertImage(dir, frameIdx, splice[frameIdx]); + } + } + + public void insertFrame(int frame, Image[] splice) { + int maxDir = dirs < splice.length? dirs: splice.length; + for(int dirIdx = 0; dirIdx < maxDir; dirIdx++) { + insertImage(dirIdx, frame, splice[dirIdx]); + } + } + + public void insertImage(int dir, int frame, Image splice) { + if(frame < 0 || frame >= frames) + throw new IllegalArgumentException("Provided frame is out of range: " + frame); + if(dir < 0 || dir >= dirs) + throw new IllegalArgumentException("Provided dir is out of range: " + dir); + + images[getIndex(dir, frame)] = splice; + } } diff --git a/tools/dmitool/src/main/java/dmitool/Main.java b/tools/dmitool/src/main/java/dmitool/Main.java index 55b453098e..fe6048ca3b 100644 --- a/tools/dmitool/src/main/java/dmitool/Main.java +++ b/tools/dmitool/src/main/java/dmitool/Main.java @@ -272,6 +272,7 @@ public class Main { String hotspot = null; float[] delays = null; String replaceDir = null; + String replaceFrame = null; while(!argq.isEmpty()) { String s = argq.pollFirst(); switch(s.toLowerCase()) { @@ -352,6 +353,15 @@ public class Main { return; } break; + case "f": + case "frame": + if(!argq.isEmpty()) { + replaceFrame = argq.pollFirst(); + } else { + System.out.println("Argument '" + s + "' requires a frame argument following it!"); + return; + } + break; default: System.out.println("Unknown import argument '" + s + "', ignoring."); break; @@ -363,26 +373,39 @@ public class Main { if(VERBOSITY >= 0) toImportTo.printInfo(); IconState is = IconState.importFromPNG(toImportTo, new FileInputStream(pngFile), stateName, delays, rewind, loop, hotspot, movement); - //If replaceDir is set, attempt to find an IconState with the same name. - //Then if nodup is set, replace the specified direction of that IconState with the (first direction) of the imported IconState. - //If nodup is not set, create a copy of the source IconState and apply the replace operation on that. - IconState targetIs; - if(replaceDir != null && (targetIs = toImportTo.getIconState(stateName)) != null) { - int dirToReplace = parseDir(replaceDir, targetIs); - int numFrames = is.frames < targetIs.frames? is.frames : targetIs.frames; + //image insertion + if(replaceDir != null || replaceFrame != null) { - if(noDup) { - for(int frameIdx = 0; frameIdx < numFrames; frameIdx++) { - targetIs.images[targetIs.getIndex(dirToReplace, frameIdx)] = is.images[is.getIndex(0, frameIdx)]; - } - } else { - targetIs = targetIs.clone(); - for(int frameIdx = 0; frameIdx < numFrames; frameIdx++) { - targetIs.images[targetIs.getIndex(dirToReplace, frameIdx)] = is.images[is.getIndex(0, frameIdx)]; - } - toImportTo.addIconState(null, targetIs); + IconState targetIs = toImportTo.getIconState(stateName); + if(targetIs == null) { + System.out.println("'direction' or 'frame' specified and no icon state '" + stateName + "' found, aborting!"); + return; } - } else { + if(is.images.length == 0) { + System.out.println("'direction' or 'frame' specified and imported is empty, aborting!"); + return; + } + + if(!noDup) targetIs = targetIs.clone(); + + int dirToReplace, frameToReplace; + if(replaceDir != null && replaceFrame != null) { + frameToReplace = parseFrame(replaceFrame, targetIs); + dirToReplace = parseDir(replaceDir, targetIs); + targetIs.insertImage(dirToReplace, frameToReplace, is.images[0]); + } + else if(replaceDir != null) { + dirToReplace = parseDir(replaceDir, targetIs); + targetIs.insertDir(dirToReplace, is.images); + } + else if(replaceFrame != null) { + frameToReplace = parseFrame(replaceFrame, targetIs); + targetIs.insertFrame(frameToReplace, is.images); + } + + if(!noDup) toImportTo.addIconState(null, targetIs); + } + else { if(noDup) { if(!toImportTo.setIconState(is)) { toImportTo.addIconState(null, is);