/*
** 2011 April 5
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
*/
package info.ata4.bspsrc.modules;
import info.ata4.bsplib.BspFileReader;
import info.ata4.bsplib.app.SourceAppID;
import info.ata4.bspsrc.BspSource;
import info.ata4.bspsrc.BspSourceConfig;
import info.ata4.bspsrc.VmfWriter;
import info.ata4.bspsrc.modules.entity.EntitySource;
import info.ata4.bspsrc.modules.geom.BrushMode;
import info.ata4.bspsrc.modules.geom.BrushSource;
import info.ata4.bspsrc.modules.geom.FaceSource;
import info.ata4.bspsrc.modules.texture.TextureSource;
import info.ata4.bspsrc.util.WindingFactory;
import info.ata4.log.LogUtils;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Main decompiling module.
*
* @author Nico Bergemann <barracuda415 at yahoo.de>
*/
public class BspDecompiler extends ModuleDecompile {
// logger
private static final Logger L = LogUtils.getLogger();
// sub-modules
private final BspSourceConfig config;
private final TextureSource texsrc;
private final BrushSource brushsrc;
private final FaceSource facesrc;
private final EntitySource entsrc;
private final BspProtection bspprot;
private final VmfMeta vmfmeta;
public BspDecompiler(BspFileReader reader, VmfWriter writer, BspSourceConfig config) {
super(reader, writer);
WindingFactory.clearCache();
this.config = config;
texsrc = new TextureSource(reader);
bspprot = new BspProtection(reader, texsrc);
vmfmeta = new VmfMeta(reader, writer);
brushsrc = new BrushSource(reader, writer, config, texsrc, bspprot, vmfmeta);
facesrc = new FaceSource(reader, writer, config, texsrc, vmfmeta);
entsrc = new EntitySource(reader, writer, config, brushsrc, facesrc,
texsrc, bspprot, vmfmeta);
}
/**
* Starts the decompiling process
*/
public void start() {
// fix texture names
texsrc.setFixTextureNames(config.fixCubemapTextures);
// VTBM has too many crucial game-specific tool textures that would break,
// so override the user selection
if (bspFile.getSourceApp().getAppID() == SourceAppID.VAMPIRE_BLOODLINES) {
texsrc.setFixToolTextures(false);
} else {
texsrc.setFixToolTextures(config.fixToolTextures);
}
// check for protection and warn if the map has been protected
if (!config.skipProt) {
checkProtection();
}
// set comment
vmfmeta.setComment("Decompiled by BSPSource v" + BspSource.VERSION + " from " + bspFile.getName());
// start worldspawn
vmfmeta.writeWorldHeader();
// write brushes and displacements
if (config.writeWorldBrushes) {
writeBrushes();
}
// end worldspawn
vmfmeta.writeWorldFooter();
// write entities
if (config.isWriteEntities()) {
writeEntities();
}
// write visgroups
if (config.writeVisgroups) {
vmfmeta.writeVisgroups();
}
// write cameras
if (config.writeCameras) {
vmfmeta.writeCameras();
}
}
private void checkProtection() {
if (!bspprot.check()) {
return;
}
L.log(Level.WARNING, "{0} contains anti-decompiling flags or is obfuscated!", reader.getBspFile().getName());
L.log(Level.WARNING, "Detected methods:");
List<String> methods = bspprot.getProtectionMethods();
for (String method : methods) {
L.warning(method);
}
}
private void writeBrushes() {
switch (config.brushMode) {
case BRUSHPLANES:
brushsrc.writeBrushes();
break;
case ORIGFACE:
facesrc.writeOrigFaces();
break;
case ORIGFACE_PLUS:
facesrc.writeOrigFacesPlus();
break;
case SPLITFACE:
facesrc.writeFaces();
break;
default:
break;
}
// add faces with displacements
// face modes don't need to do this separately
if (config.brushMode == BrushMode.BRUSHPLANES) {
facesrc.writeDispFaces();
}
}
private void writeEntities() {
if (config.isWriteEntities()) {
entsrc.writeEntities();
}
if (config.writeBrushEntities && config.writeDetails
&& config.brushMode == BrushMode.BRUSHPLANES) {
entsrc.writeDetails();
}
if (config.writePointEntities) {
if (config.writeOverlays) {
entsrc.writeOverlays();
}
if (config.writeStaticProps) {
entsrc.writeStaticProps();
}
if (config.writeCubemaps) {
entsrc.writeCubemaps();
}
if (config.writeLadders) {
entsrc.writeLadders();
}
}
}
}