diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fd9a8f41..6fc33ca67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,11 @@ All notable changes to this project will be documented in this file. ### Fixed - [#1960] Hide tag tree root handles as it was in previous versions - [#1964] Freezing on releasing mouse while shape transforming (deadlock) +- [#1961] Characters can use characterId 0, PlaceObject can use depth 0 ### Changed - [#1960] Quick search does not search in SWF name or folder names +- [#1961] SoundStreamHead on main timeline is exported/imported with identifier "-1" ## [18.3.4] - 2023-01-30 ### Added @@ -2939,6 +2941,7 @@ All notable changes to this project will be documented in this file. [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#1960]: https://www.free-decompiler.com/flash/issues/1960 [#1964]: https://www.free-decompiler.com/flash/issues/1964 +[#1961]: https://www.free-decompiler.com/flash/issues/1961 [#1029]: https://www.free-decompiler.com/flash/issues/1029 [#1948]: https://www.free-decompiler.com/flash/issues/1948 [#1941]: https://www.free-decompiler.com/flash/issues/1941 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 68b65603e..4c413f5aa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -989,10 +989,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { logger.log(Level.SEVERE, "SWF already contains characterId={0}", characterId); } - if (characterId != 0) { - characters.put(characterId, (CharacterTag) t); - characterIdTags.put(characterId, new ArrayList<>()); - } + characters.put(characterId, (CharacterTag) t); + characterIdTags.put(characterId, new ArrayList<>()); } else if (characterIdTags.containsKey(characterId)) { characterIdTags.get(characterId).add((CharacterIdTag) t); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java index 8b0096cf6..7cd305487 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHead2Tag.java @@ -75,7 +75,7 @@ public class SoundStreamHead2Tag extends SoundStreamHeadTypeTag { public int latencySeek; @Internal - private int virtualCharacterId = 0; + private int virtualCharacterId = -1; /** * Constructor @@ -251,7 +251,7 @@ public class SoundStreamHead2Tag extends SoundStreamHeadTypeTag { @Override public String toString() { - return getName() + (virtualCharacterId > 0 ? " (" + virtualCharacterId + ")" : ""); + return getName() + " (" + virtualCharacterId + ")"; } //getNeededCharacters intentionally not defined diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java index 6b58f78a5..ad8945b94 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/SoundStreamHeadTag.java @@ -32,7 +32,6 @@ import com.jpexs.decompiler.flash.types.sound.SoundExportFormat; import com.jpexs.decompiler.flash.types.sound.SoundFormat; import com.jpexs.helpers.ByteArrayRange; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -85,7 +84,7 @@ public class SoundStreamHeadTag extends SoundStreamHeadTypeTag { public int latencySeek; @Internal - private int virtualCharacterId = 0; + private int virtualCharacterId = -1; /** * Constructor @@ -261,7 +260,7 @@ public class SoundStreamHeadTag extends SoundStreamHeadTypeTag { @Override public String toString() { - return getName() + (virtualCharacterId > 0 ? " (" + virtualCharacterId + ")" : ""); + return getName() + " (" + virtualCharacterId + ")"; } //getNeededCharacters intentionally not defined diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java index 4728c9272..0fd8379ca 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalStreamSound.java @@ -70,7 +70,7 @@ public class DefineExternalStreamSound extends Tag implements CharacterIdTag, So public static final int SOUND_FORMAT_WAV = 0; @Internal - private int virtualCharacterId = 0; + private int virtualCharacterId = -1; /** * Gets data bytes @@ -243,7 +243,7 @@ public class DefineExternalStreamSound extends Tag implements CharacterIdTag, So @Override public String toString() { - return getName() + (virtualCharacterId > 0 ? " (" + virtualCharacterId + ")" : ""); + return getName() + " (" + virtualCharacterId + ")"; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index 933c359c9..4840f642b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -439,14 +439,14 @@ public class Timeline { createASPackages(); if (timelined instanceof SWF) { // popuplate only for main timeline - populateSoundStreamBlocks(0, timelined.getTags()); + populateSoundStreamBlocks(-1, timelined.getTags()); } initialized = true; } private synchronized void detectTweens() { - for (int d = 1; d <= maxDepth; d++) { + for (int d = 0; d <= maxDepth; d++) { int characterId = -1; String charClassName = null; int len = 0; @@ -486,7 +486,7 @@ public class Timeline { private synchronized void calculateMaxDepthFrames() { depthMaxFrame.clear(); - for (int d = 1; d <= maxDepth; d++) { + for (int d = 0; d <= maxDepth; d++) { for (int f = frames.size() - 1; f >= 0; f--) { if (frames.get(f).layers.get(d) != null) { depthMaxFrame.put(d, f); @@ -1037,7 +1037,7 @@ public class Timeline { int maxDepth = getMaxDepth(); int clipCount = 0; - for (int i = 1; i <= maxDepth; i++) { + for (int i = 0; i <= maxDepth; i++) { boolean clipChanged = clipCount != clips.size(); for (int c = 0; c < clips.size(); c++) { if (clips.get(c).depth < i) { @@ -1200,7 +1200,7 @@ public class Timeline { int maxDepth = getMaxDepth(); int clipCount = 0; Element clipGroup = null; - for (int i = 1; i <= maxDepth; i++) { + for (int i = 0; i <= maxDepth; i++) { boolean clipChanged = clipCount != clips.size(); for (int c = 0; c < clips.size(); c++) { if (clips.get(c).depth < i) { @@ -1422,7 +1422,7 @@ public class Timeline { public boolean isSingleFrame(int frame) { Frame frameObj = getFrame(frame); - for (int i = 1; i <= maxDepth; i++) { + for (int i = 0; i <= maxDepth; i++) { if (!frameObj.layers.containsKey(i)) { continue; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java index fc69da6ea..42cb014e4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java @@ -1017,7 +1017,7 @@ public class XFLConverter { return layer; } - private static int getLayerCount(ReadOnlyTagList tags) { + private static int getMaxDepth(ReadOnlyTagList tags) { int maxDepth = 0; for (Tag t : tags) { if (t instanceof PlaceObjectTypeTag) { @@ -2944,7 +2944,7 @@ public class XFLConverter { index++; } - int layerCount = getLayerCount(timelineTags); + int maxDepth = getMaxDepth(timelineTags); List clipFrameSplitters = new ArrayList<>(); List clipPlaces = new ArrayList<>(); @@ -2995,13 +2995,13 @@ public class XFLConverter { clipPlaces.add(null); Map> depthToFramesList = new HashMap<>(); - for (int d = layerCount; d >= 1; d--) { + for (int d = maxDepth; d >= 0; d--) { depthToFramesList.put(d, new ArrayList<>()); for (int i = 0; i < frameCount; i++) { depthToFramesList.get(d).add(i); } } - for (int d = layerCount; d >= 1; d--) { + for (int d = maxDepth; d >= 0; d--) { for (int p = 0; p < clipPlaces.size() - 1; p++) { PlaceObjectTypeTag po = clipPlaces.get(p); @@ -3054,8 +3054,8 @@ public class XFLConverter { } } - int soundLayerIndex = layerCount; - layerCount++; + int soundLayerIndex = maxDepth; + maxDepth++; convertSoundLayer(soundLayerIndex, timelineTags, files, writer); writer.writeEndElement(); writer.writeEndElement(); diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index c19a1ac24..422c28a18 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -549,11 +549,12 @@ public class CommandLineArgumentParser { if (filter == null || filter.equals("replace")) { out.println(" " + (cnt++) + ") -replace (|) [nofill] ([][]) [(|) [nofill] ([][])]..."); - out.println(" ...replaces the data of the specified BinaryData, Image, Shape, Text, DefineSound tag or Script"); + out.println(" ...replaces the data of the specified BinaryData, Image, Shape, Text, Sound tag or Script"); out.println(" ...nofill parameter can be specified only for shape replace"); out.println(" ... parameter can be specified for Image and Shape tags"); out.println(" ...valid formats: lossless, lossless2, jpeg2, jpeg3, jpeg4"); out.println(" ... parameter should be specified if and only if the imported entity is an AS3 P-Code"); + out.println(" ...use -1 as characterId to replace main timeline SoundStreamHead"); out.println(" " + (cnt++) + ") -replace "); out.println(" ... same as -replace command, but the rest of arguments is read as lines from a text file "); @@ -3180,7 +3181,7 @@ public class CommandLineArgumentParser { SoundStreamHeadTypeTag soundStreamHead = null; CharacterTag characterTag = null; - if (characterId == 0) { + if (characterId == -1) { //replacing soundstreamhead on main timeline } else if (swf.getCharacters().containsKey(characterId)) { characterTag = swf.getCharacter(characterId); diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 0be181a70..dc809a20c 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -3425,7 +3425,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay { first = false; CharacterTag c = ds.getCharacter(); ret.append(c.toString()); - if (ds.depth > 0) { + if (ds.depth > -1) { ret.append(" "); ret.append(AppStrings.translate("imagePanel.depth")); ret.append(" ");