mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 13:21:07 +00:00
using less memory when playing sounds
This commit is contained in:
@@ -103,6 +103,7 @@ import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RenderContext;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
import com.jpexs.decompiler.flash.timeline.AS2Package;
|
||||
@@ -290,6 +291,9 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
@Internal
|
||||
private Cache<String, SerializableImage> frameCache = Cache.getInstance(false, false, "frame");
|
||||
|
||||
@Internal
|
||||
private Cache<SoundTag, byte[]> soundCache = Cache.getInstance(false, false, "sound");
|
||||
|
||||
@Internal
|
||||
private final Cache<ASMSource, CachedScript> as2Cache = Cache.getInstance(true, false, "as2");
|
||||
|
||||
@@ -336,6 +340,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
as2Cache.clear();
|
||||
as3Cache.clear();
|
||||
frameCache.clear();
|
||||
soundCache.clear();
|
||||
|
||||
timeline = null;
|
||||
clearDumpInfo(dumpInfo);
|
||||
@@ -2075,12 +2080,23 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] getFromCache(SoundTag soundTag) {
|
||||
if (soundCache.contains(soundTag)) {
|
||||
return soundCache.get(soundTag);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void putToCache(String key, SerializableImage img) {
|
||||
if (Configuration.useFrameCache.get()) {
|
||||
frameCache.put(key, img);
|
||||
}
|
||||
}
|
||||
|
||||
public void putToCache(SoundTag soundTag, byte[] data) {
|
||||
soundCache.put(soundTag, data);
|
||||
}
|
||||
|
||||
public void clearImageCache() {
|
||||
frameCache.clear();
|
||||
DefineSpriteTag.clearCache();
|
||||
|
||||
+801
-797
File diff suppressed because it is too large
Load Diff
@@ -1,167 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings;
|
||||
import com.jpexs.decompiler.flash.flv.AUDIODATA;
|
||||
import com.jpexs.decompiler.flash.flv.FLVOutputStream;
|
||||
import com.jpexs.decompiler.flash.flv.FLVTAG;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundExporter {
|
||||
|
||||
public List<File> exportSounds(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final SoundExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File foutdir = new File(outdir);
|
||||
Path.createDirectorySafe(foutdir);
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("sound", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final SoundTag st = (SoundTag) t;
|
||||
|
||||
String ext = "wav";
|
||||
SoundFormat fmt = st.getSoundFormat();
|
||||
switch (fmt.getNativeExportFormat()) {
|
||||
case SoundFormat.EXPORT_MP3:
|
||||
if (settings.mode.hasMP3()) {
|
||||
ext = "mp3";
|
||||
}
|
||||
break;
|
||||
case SoundFormat.EXPORT_FLV:
|
||||
if (settings.mode.hasFlv()) {
|
||||
ext = "flv";
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (settings.mode == SoundExportMode.FLV) {
|
||||
ext = "flv";
|
||||
}
|
||||
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName()) + "." + ext);
|
||||
new RetryTask(() -> {
|
||||
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||
exportSound(os, st, settings.mode);
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("sound", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte[] exportSound(SoundTag t, SoundExportMode mode) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
exportSound(baos, t, mode);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public void exportSound(OutputStream fos, SoundTag st, SoundExportMode mode) throws IOException {
|
||||
SoundFormat fmt = st.getSoundFormat();
|
||||
int nativeFormat = fmt.getNativeExportFormat();
|
||||
|
||||
if (nativeFormat == SoundFormat.EXPORT_MP3 && mode.hasMP3()) {
|
||||
List<byte[]> datas = st.getRawSoundData();
|
||||
for (byte[] data : datas) {
|
||||
fos.write(data);
|
||||
}
|
||||
} else if ((nativeFormat == SoundFormat.EXPORT_FLV && mode.hasFlv()) || mode == SoundExportMode.FLV) {
|
||||
if (st instanceof DefineSoundTag) {
|
||||
FLVOutputStream flv = new FLVOutputStream(fos);
|
||||
flv.writeHeader(true, false);
|
||||
List<byte[]> datas = st.getRawSoundData();
|
||||
for (byte[] data : datas) {
|
||||
flv.writeTag(new FLVTAG(0, new AUDIODATA(st.getSoundFormatId(), st.getSoundRate(), st.getSoundSize(), st.getSoundType(), data)));
|
||||
}
|
||||
} else if (st instanceof SoundStreamHeadTypeTag) {
|
||||
SoundStreamHeadTypeTag sh = (SoundStreamHeadTypeTag) st;
|
||||
FLVOutputStream flv = new FLVOutputStream(fos);
|
||||
flv.writeHeader(true, false);
|
||||
List<SoundStreamBlockTag> blocks = sh.getBlocks();
|
||||
|
||||
int ms = (int) (1000.0f / ((float) ((Tag) st).getSwf().frameRate));
|
||||
for (int b = 0; b < blocks.size(); b++) {
|
||||
byte[] data = blocks.get(b).streamSoundData.getRangeData();
|
||||
if (st.getSoundFormatId() == 2) { //MP3
|
||||
data = Arrays.copyOfRange(data, 4, data.length);
|
||||
}
|
||||
flv.writeTag(new FLVTAG(ms * b, new AUDIODATA(st.getSoundFormatId(), st.getSoundRate(), st.getSoundSize(), st.getSoundType(), data)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<byte[]> soundData = st.getRawSoundData();
|
||||
SWF swf = ((Tag) st).getSwf();
|
||||
List<SWFInputStream> siss = new ArrayList<>();
|
||||
for (byte[] data : soundData) {
|
||||
siss.add(new SWFInputStream(swf, data));
|
||||
}
|
||||
fmt.createWav(siss, fos);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters;
|
||||
|
||||
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.RetryTask;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings;
|
||||
import com.jpexs.decompiler.flash.flv.AUDIODATA;
|
||||
import com.jpexs.decompiler.flash.flv.FLVOutputStream;
|
||||
import com.jpexs.decompiler.flash.flv.FLVTAG;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SoundExporter {
|
||||
|
||||
public List<File> exportSounds(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final SoundExportSettings settings, EventListener evl) throws IOException {
|
||||
List<File> ret = new ArrayList<>();
|
||||
if (tags.isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File foutdir = new File(outdir);
|
||||
Path.createDirectorySafe(foutdir);
|
||||
|
||||
int count = 0;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundTag) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int currentIndex = 1;
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof SoundTag) {
|
||||
if (evl != null) {
|
||||
evl.handleExportingEvent("sound", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
final SoundTag st = (SoundTag) t;
|
||||
|
||||
String ext = "wav";
|
||||
SoundFormat fmt = st.getSoundFormat();
|
||||
switch (fmt.getNativeExportFormat()) {
|
||||
case SoundFormat.EXPORT_MP3:
|
||||
if (settings.mode.hasMP3()) {
|
||||
ext = "mp3";
|
||||
}
|
||||
break;
|
||||
case SoundFormat.EXPORT_FLV:
|
||||
if (settings.mode.hasFlv()) {
|
||||
ext = "flv";
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (settings.mode == SoundExportMode.FLV) {
|
||||
ext = "flv";
|
||||
}
|
||||
|
||||
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName()) + "." + ext);
|
||||
new RetryTask(() -> {
|
||||
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||
exportSound(os, st, settings.mode);
|
||||
}
|
||||
}, handler).run();
|
||||
|
||||
ret.add(file);
|
||||
|
||||
if (evl != null) {
|
||||
evl.handleExportedEvent("sound", currentIndex, count, t.getName());
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte[] exportSound(SoundTag t, SoundExportMode mode) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
exportSound(baos, t, mode);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public void exportSound(OutputStream fos, SoundTag st, SoundExportMode mode) throws IOException {
|
||||
SoundFormat fmt = st.getSoundFormat();
|
||||
int nativeFormat = fmt.getNativeExportFormat();
|
||||
|
||||
if (nativeFormat == SoundFormat.EXPORT_MP3 && mode.hasMP3()) {
|
||||
List<ByteArrayRange> datas = st.getRawSoundData();
|
||||
for (ByteArrayRange data : datas) {
|
||||
fos.write(data.getRangeData());
|
||||
}
|
||||
} else if ((nativeFormat == SoundFormat.EXPORT_FLV && mode.hasFlv()) || mode == SoundExportMode.FLV) {
|
||||
if (st instanceof DefineSoundTag) {
|
||||
FLVOutputStream flv = new FLVOutputStream(fos);
|
||||
flv.writeHeader(true, false);
|
||||
List<ByteArrayRange> datas = st.getRawSoundData();
|
||||
for (ByteArrayRange data : datas) {
|
||||
flv.writeTag(new FLVTAG(0, new AUDIODATA(st.getSoundFormatId(), st.getSoundRate(), st.getSoundSize(), st.getSoundType(), data.getRangeData())));
|
||||
}
|
||||
} else if (st instanceof SoundStreamHeadTypeTag) {
|
||||
SoundStreamHeadTypeTag sh = (SoundStreamHeadTypeTag) st;
|
||||
FLVOutputStream flv = new FLVOutputStream(fos);
|
||||
flv.writeHeader(true, false);
|
||||
List<SoundStreamBlockTag> blocks = sh.getBlocks();
|
||||
|
||||
int ms = (int) (1000.0f / ((float) ((Tag) st).getSwf().frameRate));
|
||||
for (int b = 0; b < blocks.size(); b++) {
|
||||
byte[] data = blocks.get(b).streamSoundData.getRangeData();
|
||||
if (st.getSoundFormatId() == 2) { //MP3
|
||||
data = Arrays.copyOfRange(data, 4, data.length);
|
||||
}
|
||||
flv.writeTag(new FLVTAG(ms * b, new AUDIODATA(st.getSoundFormatId(), st.getSoundRate(), st.getSoundSize(), st.getSoundType(), data)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<ByteArrayRange> soundData = st.getRawSoundData();
|
||||
SWF swf = ((Tag) st).getSwf();
|
||||
List<SWFInputStream> siss = new ArrayList<>();
|
||||
for (ByteArrayRange data : soundData) {
|
||||
siss.add(new SWFInputStream(swf, data.getRangeData()));
|
||||
}
|
||||
fmt.createWav(siss, fos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
@@ -116,7 +117,10 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
cachedImage = ret;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
@@ -178,7 +179,10 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
|
||||
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (bitmapAlphaData.getLength() == 0) {
|
||||
cachedImage = img;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = img;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
@@ -189,7 +193,10 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
|
||||
pixels[i] = multiplyAlpha((pixels[i] & 0xffffff) | (a << 24));
|
||||
}
|
||||
|
||||
cachedImage = img;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = img;
|
||||
}
|
||||
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
@@ -182,7 +183,10 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
|
||||
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (bitmapAlphaData.getLength() == 0) {
|
||||
cachedImage = img;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = img;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
@@ -193,7 +197,10 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
|
||||
pixels[i] = multiplyAlpha((pixels[i] & 0xffffff) | (a << 24));
|
||||
}
|
||||
|
||||
cachedImage = img;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = img;
|
||||
}
|
||||
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
@@ -268,7 +269,10 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
|
||||
}
|
||||
}
|
||||
|
||||
cachedImage = bi;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = bi;
|
||||
}
|
||||
|
||||
return bi;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.AloneTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
@@ -239,7 +240,10 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
}
|
||||
|
||||
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_RGB, pixels);
|
||||
cachedImage = bi;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = bi;
|
||||
}
|
||||
|
||||
return bi;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
@@ -128,7 +129,10 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
cachedImage = ret;
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
|
||||
@@ -330,14 +330,14 @@ public class DefineSoundTag extends CharacterTag implements SoundTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
public List<ByteArrayRange> getRawSoundData() {
|
||||
List<ByteArrayRange> ret = new ArrayList<>();
|
||||
if (soundFormat == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(soundData.getRangeData(2, soundData.getLength() - 2));
|
||||
ret.add(soundData.getSubRange(2, soundData.getLength() - 2));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.add(soundData.getRangeData());
|
||||
ret.add(soundData);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
actionBytes = new ByteArrayRange(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -158,7 +158,7 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
actionBytes = new ByteArrayRange(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -221,14 +221,15 @@ public class SoundStreamHead2Tag extends Tag implements SoundStreamHeadTypeTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
public List<ByteArrayRange> getRawSoundData() {
|
||||
List<ByteArrayRange> ret = new ArrayList<>();
|
||||
List<SoundStreamBlockTag> blocks = getBlocks();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
ByteArrayRange data = block.streamSoundData;
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(block.streamSoundData.getRangeData(4, block.streamSoundData.getLength() - 4));
|
||||
ret.add(data.getSubRange(4, data.getLength() - 4));
|
||||
} else {
|
||||
ret.add(block.streamSoundData.getRangeData());
|
||||
ret.add(data);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -244,14 +244,15 @@ public class SoundStreamHeadTag extends Tag implements SoundStreamHeadTypeTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRawSoundData() {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
public List<ByteArrayRange> getRawSoundData() {
|
||||
List<ByteArrayRange> ret = new ArrayList<>();
|
||||
List<SoundStreamBlockTag> blocks = getBlocks();
|
||||
for (SoundStreamBlockTag block : blocks) {
|
||||
ByteArrayRange data = block.streamSoundData;
|
||||
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {
|
||||
ret.add(block.streamSoundData.getRangeData(4, block.streamSoundData.getLength() - 4));
|
||||
ret.add(data.getSubRange(4, data.getLength() - 4));
|
||||
} else {
|
||||
ret.add(block.streamSoundData.getRangeData());
|
||||
ret.add(data);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -521,7 +521,7 @@ public abstract class Tag implements NeedsCharacters, Exportable, Serializable {
|
||||
byte[] tagData = new byte[data.length + headerData.length];
|
||||
System.arraycopy(headerData, 0, tagData, 0, headerData.length);
|
||||
System.arraycopy(data, 0, tagData, headerData.length, data.length);
|
||||
originalRange = new ByteArrayRange(tagData, 0, tagData.length);
|
||||
originalRange = new ByteArrayRange(tagData);
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.␍ */
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@@ -36,7 +38,7 @@ public interface SoundTag extends TreeItem {
|
||||
|
||||
public boolean getSoundType();
|
||||
|
||||
public List<byte[]> getRawSoundData();
|
||||
public List<ByteArrayRange> getRawSoundData();
|
||||
|
||||
public int getSoundFormatId();
|
||||
|
||||
|
||||
@@ -1,340 +1,340 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Actions to execute at particular button events
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class BUTTONCONDACTION implements ASMSource, Serializable {
|
||||
|
||||
private final SWF swf;
|
||||
|
||||
private final Tag tag;
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
return swf;
|
||||
}
|
||||
|
||||
// Constructor for Generic tag editor. TODO:Handle this somehow better
|
||||
public BUTTONCONDACTION() {
|
||||
swf = null;
|
||||
tag = null;
|
||||
}
|
||||
|
||||
public BUTTONCONDACTION(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
int condActionSize = sis.readUI16("condActionSize");
|
||||
isLast = condActionSize <= 0;
|
||||
condIdleToOverDown = sis.readUB(1, "condIdleToOverDown") == 1;
|
||||
condOutDownToIdle = sis.readUB(1, "condOutDownToIdle") == 1;
|
||||
condOutDownToOverDown = sis.readUB(1, "condOutDownToOverDown") == 1;
|
||||
condOverDownToOutDown = sis.readUB(1, "condOverDownToOutDown") == 1;
|
||||
condOverDownToOverUp = sis.readUB(1, "condOverDownToOverUp") == 1;
|
||||
condOverUpToOverDown = sis.readUB(1, "condOverUpToOverDown") == 1;
|
||||
condOverUpToIddle = sis.readUB(1, "condOverUpToIddle") == 1;
|
||||
condIdleToOverUp = sis.readUB(1, "condIdleToOverUp") == 1;
|
||||
condKeyPress = (int) sis.readUB(7, "condKeyPress");
|
||||
condOverDownToIdle = sis.readUB(1, "condOverDownToIdle") == 1;
|
||||
actionBytes = sis.readByteRangeEx(condActionSize <= 0 ? sis.available() : condActionSize - 4, "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this BUTTONCONDACTION last in the list?
|
||||
*/
|
||||
@Internal
|
||||
public boolean isLast;
|
||||
|
||||
/**
|
||||
* Idle to OverDown
|
||||
*/
|
||||
public boolean condIdleToOverDown;
|
||||
|
||||
/**
|
||||
* OutDown to Idle
|
||||
*/
|
||||
public boolean condOutDownToIdle;
|
||||
|
||||
/**
|
||||
* OutDown to OverDown
|
||||
*/
|
||||
public boolean condOutDownToOverDown;
|
||||
|
||||
/**
|
||||
* OverDown to OutDown
|
||||
*/
|
||||
public boolean condOverDownToOutDown;
|
||||
|
||||
/**
|
||||
* OverDown to OverUp
|
||||
*/
|
||||
public boolean condOverDownToOverUp;
|
||||
|
||||
/**
|
||||
* OverUp to OverDown
|
||||
*/
|
||||
public boolean condOverUpToOverDown;
|
||||
|
||||
/**
|
||||
* OverUp to Idle
|
||||
*/
|
||||
public boolean condOverUpToIddle;
|
||||
|
||||
/**
|
||||
* Idle to OverUp
|
||||
*/
|
||||
public boolean condIdleToOverUp;
|
||||
|
||||
/**
|
||||
* @since SWF 4 key code
|
||||
*/
|
||||
@SWFType(value = BasicType.UB, count = 7)
|
||||
@Conditional(minSwfVersion = 4)
|
||||
public int condKeyPress;
|
||||
|
||||
/**
|
||||
* OverDown to Idle
|
||||
*/
|
||||
public boolean condOverDownToIdle;
|
||||
|
||||
/**
|
||||
* Actions to perform
|
||||
*/
|
||||
//public List<Action> actions;
|
||||
/**
|
||||
* Actions to perform in byte array
|
||||
*/
|
||||
@Internal
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
/**
|
||||
* Sets actions associated with this object
|
||||
*
|
||||
* @param actions Action list
|
||||
*/
|
||||
/*public void setActions(List<Action> actions) {
|
||||
this.actions = actions;
|
||||
}*/
|
||||
/**
|
||||
* Returns a string representation of the object
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BUTTONCONDACTION";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns actions associated with this object
|
||||
*
|
||||
* @return List of actions
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, swf.version, prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
if (tag != null) {
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (tag != null) {
|
||||
return tag.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private String getHeader(boolean asFilename) {
|
||||
List<String> events = new ArrayList<>();
|
||||
if (condOverUpToOverDown) {
|
||||
events.add("press");
|
||||
}
|
||||
if (condOverDownToOverUp) {
|
||||
events.add("release");
|
||||
}
|
||||
if (condOutDownToIdle) {
|
||||
events.add("releaseOutside");
|
||||
}
|
||||
if (condIdleToOverUp) {
|
||||
events.add("rollOver");
|
||||
}
|
||||
if (condOverUpToIddle) {
|
||||
events.add("rollOut");
|
||||
}
|
||||
if (condOverDownToOutDown) {
|
||||
events.add("dragOut");
|
||||
}
|
||||
if (condOutDownToOverDown) {
|
||||
events.add("dragOver");
|
||||
}
|
||||
if (condKeyPress > 0) {
|
||||
if (asFilename) {
|
||||
events.add("keyPress " + Helper.makeFileName(CLIPACTIONRECORD.keyToString(condKeyPress).replace("<", "").replace(">", "")) + "");
|
||||
} else {
|
||||
events.add("keyPress \"" + CLIPACTIONRECORD.keyToString(condKeyPress) + "\"");
|
||||
}
|
||||
}
|
||||
String onStr = "";
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
if (i > 0) {
|
||||
onStr += ", ";
|
||||
}
|
||||
onStr += events.get(i);
|
||||
}
|
||||
return "on(" + onStr + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
writer.appendNoHilight(getHeader(false));
|
||||
writer.appendNoHilight("{").newLine();
|
||||
return writer.indent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
writer.unindent();
|
||||
return writer.appendNoHilight("}").newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return Helper.unindentRows(1, 1, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFileName() {
|
||||
return getHeader(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Actions to execute at particular button events
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class BUTTONCONDACTION implements ASMSource, Serializable {
|
||||
|
||||
private final SWF swf;
|
||||
|
||||
private final Tag tag;
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
return swf;
|
||||
}
|
||||
|
||||
// Constructor for Generic tag editor. TODO:Handle this somehow better
|
||||
public BUTTONCONDACTION() {
|
||||
swf = null;
|
||||
tag = null;
|
||||
}
|
||||
|
||||
public BUTTONCONDACTION(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
int condActionSize = sis.readUI16("condActionSize");
|
||||
isLast = condActionSize <= 0;
|
||||
condIdleToOverDown = sis.readUB(1, "condIdleToOverDown") == 1;
|
||||
condOutDownToIdle = sis.readUB(1, "condOutDownToIdle") == 1;
|
||||
condOutDownToOverDown = sis.readUB(1, "condOutDownToOverDown") == 1;
|
||||
condOverDownToOutDown = sis.readUB(1, "condOverDownToOutDown") == 1;
|
||||
condOverDownToOverUp = sis.readUB(1, "condOverDownToOverUp") == 1;
|
||||
condOverUpToOverDown = sis.readUB(1, "condOverUpToOverDown") == 1;
|
||||
condOverUpToIddle = sis.readUB(1, "condOverUpToIddle") == 1;
|
||||
condIdleToOverUp = sis.readUB(1, "condIdleToOverUp") == 1;
|
||||
condKeyPress = (int) sis.readUB(7, "condKeyPress");
|
||||
condOverDownToIdle = sis.readUB(1, "condOverDownToIdle") == 1;
|
||||
actionBytes = sis.readByteRangeEx(condActionSize <= 0 ? sis.available() : condActionSize - 4, "actionBytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this BUTTONCONDACTION last in the list?
|
||||
*/
|
||||
@Internal
|
||||
public boolean isLast;
|
||||
|
||||
/**
|
||||
* Idle to OverDown
|
||||
*/
|
||||
public boolean condIdleToOverDown;
|
||||
|
||||
/**
|
||||
* OutDown to Idle
|
||||
*/
|
||||
public boolean condOutDownToIdle;
|
||||
|
||||
/**
|
||||
* OutDown to OverDown
|
||||
*/
|
||||
public boolean condOutDownToOverDown;
|
||||
|
||||
/**
|
||||
* OverDown to OutDown
|
||||
*/
|
||||
public boolean condOverDownToOutDown;
|
||||
|
||||
/**
|
||||
* OverDown to OverUp
|
||||
*/
|
||||
public boolean condOverDownToOverUp;
|
||||
|
||||
/**
|
||||
* OverUp to OverDown
|
||||
*/
|
||||
public boolean condOverUpToOverDown;
|
||||
|
||||
/**
|
||||
* OverUp to Idle
|
||||
*/
|
||||
public boolean condOverUpToIddle;
|
||||
|
||||
/**
|
||||
* Idle to OverUp
|
||||
*/
|
||||
public boolean condIdleToOverUp;
|
||||
|
||||
/**
|
||||
* @since SWF 4 key code
|
||||
*/
|
||||
@SWFType(value = BasicType.UB, count = 7)
|
||||
@Conditional(minSwfVersion = 4)
|
||||
public int condKeyPress;
|
||||
|
||||
/**
|
||||
* OverDown to Idle
|
||||
*/
|
||||
public boolean condOverDownToIdle;
|
||||
|
||||
/**
|
||||
* Actions to perform
|
||||
*/
|
||||
//public List<Action> actions;
|
||||
/**
|
||||
* Actions to perform in byte array
|
||||
*/
|
||||
@Internal
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
/**
|
||||
* Sets actions associated with this object
|
||||
*
|
||||
* @param actions Action list
|
||||
*/
|
||||
/*public void setActions(List<Action> actions) {
|
||||
this.actions = actions;
|
||||
}*/
|
||||
/**
|
||||
* Returns a string representation of the object
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BUTTONCONDACTION";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns actions associated with this object
|
||||
*
|
||||
* @return List of actions
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, swf.version, prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
if (tag != null) {
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (tag != null) {
|
||||
return tag.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private String getHeader(boolean asFilename) {
|
||||
List<String> events = new ArrayList<>();
|
||||
if (condOverUpToOverDown) {
|
||||
events.add("press");
|
||||
}
|
||||
if (condOverDownToOverUp) {
|
||||
events.add("release");
|
||||
}
|
||||
if (condOutDownToIdle) {
|
||||
events.add("releaseOutside");
|
||||
}
|
||||
if (condIdleToOverUp) {
|
||||
events.add("rollOver");
|
||||
}
|
||||
if (condOverUpToIddle) {
|
||||
events.add("rollOut");
|
||||
}
|
||||
if (condOverDownToOutDown) {
|
||||
events.add("dragOut");
|
||||
}
|
||||
if (condOutDownToOverDown) {
|
||||
events.add("dragOver");
|
||||
}
|
||||
if (condKeyPress > 0) {
|
||||
if (asFilename) {
|
||||
events.add("keyPress " + Helper.makeFileName(CLIPACTIONRECORD.keyToString(condKeyPress).replace("<", "").replace(">", "")) + "");
|
||||
} else {
|
||||
events.add("keyPress \"" + CLIPACTIONRECORD.keyToString(condKeyPress) + "\"");
|
||||
}
|
||||
}
|
||||
String onStr = "";
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
if (i > 0) {
|
||||
onStr += ", ";
|
||||
}
|
||||
onStr += events.get(i);
|
||||
}
|
||||
return "on(" + onStr + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
writer.appendNoHilight(getHeader(false));
|
||||
writer.appendNoHilight("{").newLine();
|
||||
return writer.indent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
writer.unindent();
|
||||
return writer.appendNoHilight("}").newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return Helper.unindentRows(1, 1, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFileName() {
|
||||
return getHeader(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,293 +1,293 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Event handler
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CLIPACTIONRECORD implements ASMSource, Serializable {
|
||||
|
||||
public static String keyToString(int key) {
|
||||
if ((key < CLIPACTIONRECORD.KEYNAMES.length) && (key > 0) && (CLIPACTIONRECORD.KEYNAMES[key] != null)) {
|
||||
return CLIPACTIONRECORD.KEYNAMES[key];
|
||||
} else {
|
||||
return "" + (char) key;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String[] KEYNAMES = {
|
||||
null,
|
||||
"<Left>",
|
||||
"<Right>",
|
||||
"<Home>",
|
||||
"<End>",
|
||||
"<Insert>",
|
||||
"<Delete>",
|
||||
null,
|
||||
"<Backspace>",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"<Enter>",
|
||||
"<Up>",
|
||||
"<Down>",
|
||||
"<PageUp>",
|
||||
"<PageDown>",
|
||||
"<Tab>",
|
||||
"<Escape>",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"<Space>"
|
||||
};
|
||||
|
||||
@Internal
|
||||
private final SWF swf;
|
||||
|
||||
@Internal
|
||||
private final Tag tag;
|
||||
|
||||
// Constructor for Generic tag editor. TODO:Handle this somehow better
|
||||
public CLIPACTIONRECORD() {
|
||||
swf = null;
|
||||
tag = null;
|
||||
eventFlags = new CLIPEVENTFLAGS();
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public CLIPACTIONRECORD(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
eventFlags = sis.readCLIPEVENTFLAGS("eventFlags");
|
||||
if (eventFlags.isClear()) {
|
||||
return;
|
||||
}
|
||||
long actionRecordSize = sis.readUI32("actionRecordSize");
|
||||
if (eventFlags.clipEventKeyPress) {
|
||||
keyCode = sis.readUI8("keyCode");
|
||||
actionRecordSize--;
|
||||
}
|
||||
actionBytes = sis.readByteRangeEx(actionRecordSize, "actionBytes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
return swf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Events to which this handler applies
|
||||
*/
|
||||
public CLIPEVENTFLAGS eventFlags;
|
||||
|
||||
/**
|
||||
* If EventFlags contain ClipEventKeyPress: Key code to trap
|
||||
*/
|
||||
@Conditional("eventFlags.clipEventKeyPress")
|
||||
public int keyCode;
|
||||
|
||||
/**
|
||||
* Actions to perform
|
||||
*/
|
||||
//public List<Action> actions;
|
||||
@Internal
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
/**
|
||||
* Returns a string representation of the object
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return eventFlags.getHeader(keyCode, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns header with events converted to string
|
||||
*
|
||||
* @return String representation of events
|
||||
*/
|
||||
public String getHeader() {
|
||||
String ret;
|
||||
ret = eventFlags.toString();
|
||||
if (eventFlags.clipEventKeyPress) {
|
||||
ret = ret.replace("keyPress", "keyPress<" + keyCode + ">");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, swf.version, prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(CLIPACTIONRECORD.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
if (tag != null) {
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (tag != null) {
|
||||
return tag.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
writer.appendNoHilight(eventFlags.getHeader(keyCode, false));
|
||||
writer.appendNoHilight("{").newLine();
|
||||
return writer.indent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
writer.unindent();
|
||||
return writer.appendNoHilight("}").newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return Helper.unindentRows(1, 1, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFileName() {
|
||||
return eventFlags.getHeader(keyCode, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Conditional;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Event handler
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CLIPACTIONRECORD implements ASMSource, Serializable {
|
||||
|
||||
public static String keyToString(int key) {
|
||||
if ((key < CLIPACTIONRECORD.KEYNAMES.length) && (key > 0) && (CLIPACTIONRECORD.KEYNAMES[key] != null)) {
|
||||
return CLIPACTIONRECORD.KEYNAMES[key];
|
||||
} else {
|
||||
return "" + (char) key;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String[] KEYNAMES = {
|
||||
null,
|
||||
"<Left>",
|
||||
"<Right>",
|
||||
"<Home>",
|
||||
"<End>",
|
||||
"<Insert>",
|
||||
"<Delete>",
|
||||
null,
|
||||
"<Backspace>",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"<Enter>",
|
||||
"<Up>",
|
||||
"<Down>",
|
||||
"<PageUp>",
|
||||
"<PageDown>",
|
||||
"<Tab>",
|
||||
"<Escape>",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"<Space>"
|
||||
};
|
||||
|
||||
@Internal
|
||||
private final SWF swf;
|
||||
|
||||
@Internal
|
||||
private final Tag tag;
|
||||
|
||||
// Constructor for Generic tag editor. TODO:Handle this somehow better
|
||||
public CLIPACTIONRECORD() {
|
||||
swf = null;
|
||||
tag = null;
|
||||
eventFlags = new CLIPEVENTFLAGS();
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
public CLIPACTIONRECORD(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
eventFlags = sis.readCLIPEVENTFLAGS("eventFlags");
|
||||
if (eventFlags.isClear()) {
|
||||
return;
|
||||
}
|
||||
long actionRecordSize = sis.readUI32("actionRecordSize");
|
||||
if (eventFlags.clipEventKeyPress) {
|
||||
keyCode = sis.readUI8("keyCode");
|
||||
actionRecordSize--;
|
||||
}
|
||||
actionBytes = sis.readByteRangeEx(actionRecordSize, "actionBytes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
return swf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Events to which this handler applies
|
||||
*/
|
||||
public CLIPEVENTFLAGS eventFlags;
|
||||
|
||||
/**
|
||||
* If EventFlags contain ClipEventKeyPress: Key code to trap
|
||||
*/
|
||||
@Conditional("eventFlags.clipEventKeyPress")
|
||||
public int keyCode;
|
||||
|
||||
/**
|
||||
* Actions to perform
|
||||
*/
|
||||
//public List<Action> actions;
|
||||
@Internal
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
/**
|
||||
* Returns a string representation of the object
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return eventFlags.getHeader(keyCode, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns header with events converted to string
|
||||
*
|
||||
* @return String representation of events
|
||||
*/
|
||||
public String getHeader() {
|
||||
String ret;
|
||||
ret = eventFlags.toString();
|
||||
if (eventFlags.clipEventKeyPress) {
|
||||
ret = ret.replace("keyPress", "keyPress<" + keyCode + ">");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts actions to ASM source
|
||||
*
|
||||
* @param exportMode PCode or hex?
|
||||
* @param writer
|
||||
* @param actions
|
||||
* @return ASM source
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public GraphTextWriter getASMSource(ScriptExportMode exportMode, GraphTextWriter writer, ActionList actions) throws InterruptedException {
|
||||
if (actions == null) {
|
||||
actions = getActions();
|
||||
}
|
||||
return Action.actionsToString(listeners, 0, actions, swf.version, exportMode, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this object contains ASM source
|
||||
*
|
||||
* @return True when contains
|
||||
*/
|
||||
@Override
|
||||
public boolean containsSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionList getActions() throws InterruptedException {
|
||||
try {
|
||||
int prevLength = actionBytes.getPos();
|
||||
SWFInputStream rri = new SWFInputStream(swf, actionBytes.getArray());
|
||||
if (prevLength != 0) {
|
||||
rri.seek(prevLength);
|
||||
}
|
||||
|
||||
ActionList list = ActionListReader.readActionListTimeout(listeners, rri, swf.version, prevLength, prevLength + actionBytes.getLength(), toString()/*FIXME?*/);
|
||||
return list;
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(CLIPACTIONRECORD.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ActionList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActions(List<Action> actions) {
|
||||
byte[] bytes = Action.actionsToBytes(actions, true, swf.version);
|
||||
actionBytes = new ByteArrayRange(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getActionBytes() {
|
||||
return actionBytes.getRangeData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = new ByteArrayRange(actionBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified() {
|
||||
if (tag != null) {
|
||||
tag.setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
if (tag != null) {
|
||||
return tag.isModified();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer) {
|
||||
return Helper.byteArrayToHexWithHeader(writer, actionBytes.getRangeData());
|
||||
}
|
||||
|
||||
List<DisassemblyListener> listeners = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
|
||||
writer.appendNoHilight(eventFlags.getHeader(keyCode, false));
|
||||
writer.appendNoHilight("{").newLine();
|
||||
return writer.indent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTextWriter getActionSourceSuffix(GraphTextWriter writer) {
|
||||
writer.unindent();
|
||||
return writer.appendNoHilight("}").newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrefixLineCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String removePrefixAndSuffix(String source) {
|
||||
return Helper.unindentRows(1, 1, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportFileName() {
|
||||
return eventFlags.getHeader(keyCode, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getSourceTag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user