/**
* @file GMXFileWriter.java
* @brief Class implementing a GMX file writer.
*
* @section License
*
* Copyright (C) 2013-2015 Robert B. Colton
* This file is a part of the LateralGM IDE.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
package org.lateralgm.file;
import static org.lateralgm.main.Util.deRef;
import java.awt.Color;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.JProgressBar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.lateralgm.components.impl.ResNode;
import org.lateralgm.file.iconio.ICOFile;
import org.lateralgm.main.LGM;
import org.lateralgm.main.Util;
import org.lateralgm.messages.Messages;
import org.lateralgm.resources.Background;
import org.lateralgm.resources.Background.PBackground;
import org.lateralgm.resources.Constants;
import org.lateralgm.resources.Font;
import org.lateralgm.resources.Font.PFont;
import org.lateralgm.resources.GameInformation.PGameInformation;
import org.lateralgm.resources.GameSettings;
import org.lateralgm.resources.GameSettings.PGameSettings;
import org.lateralgm.resources.GmObject;
import org.lateralgm.resources.GmObject.PGmObject;
import org.lateralgm.resources.InstantiableResource;
import org.lateralgm.resources.Path;
import org.lateralgm.resources.Path.PPath;
import org.lateralgm.resources.Resource;
import org.lateralgm.resources.ResourceReference;
import org.lateralgm.resources.Room;
import org.lateralgm.resources.Room.PRoom;
import org.lateralgm.resources.Script;
import org.lateralgm.resources.Script.PScript;
import org.lateralgm.resources.Shader;
import org.lateralgm.resources.Shader.PShader;
import org.lateralgm.resources.Sound;
import org.lateralgm.resources.Sound.PSound;
import org.lateralgm.resources.Sprite;
import org.lateralgm.resources.Sprite.PSprite;
import org.lateralgm.resources.Timeline;
import org.lateralgm.resources.library.LibAction;
import org.lateralgm.resources.sub.Action;
import org.lateralgm.resources.sub.ActionContainer;
import org.lateralgm.resources.sub.Argument;
import org.lateralgm.resources.sub.BackgroundDef;
import org.lateralgm.resources.sub.BackgroundDef.PBackgroundDef;
import org.lateralgm.resources.sub.CharacterRange;
import org.lateralgm.resources.sub.CharacterRange.PCharacterRange;
import org.lateralgm.resources.sub.Constant;
import org.lateralgm.resources.sub.Event;
import org.lateralgm.resources.sub.GlyphMetric;
import org.lateralgm.resources.sub.GlyphMetric.PGlyphMetric;
import org.lateralgm.resources.sub.Instance;
import org.lateralgm.resources.sub.Instance.PInstance;
import org.lateralgm.resources.sub.MainEvent;
import org.lateralgm.resources.sub.Moment;
import org.lateralgm.resources.sub.PathPoint;
import org.lateralgm.resources.sub.ShapePoint;
import org.lateralgm.resources.sub.Tile;
import org.lateralgm.resources.sub.Tile.PTile;
import org.lateralgm.resources.sub.View;
import org.lateralgm.resources.sub.View.PView;
import org.lateralgm.util.PropertyMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
public final class GMXFileWriter
{
private static DocumentBuilderFactory documentBuilderFactory;
private static DocumentBuilder documentBuilder;
private GMXFileWriter()
{
}
// Workaround for Parameter limit
private static class ProjectFileContext
{
ProjectFile f;
Document dom;
public ProjectFileContext(ProjectFile f, Document d)
{
this.f = f;
this.dom = d;
}
public ProjectFileContext copy()
{
return new ProjectFileContext(f,dom);
}
}
public static void writeProjectFile(OutputStream os, ProjectFile f, ResNode rootRes, int ver)
throws IOException,GmFormatException,TransformerException
{
f.format = ProjectFile.FormatFlavor.getVersionFlavor(ver);
long savetime = System.currentTimeMillis();
if (documentBuilderFactory == null)
documentBuilderFactory = DocumentBuilderFactory.newInstance();
if (documentBuilder == null)
try
{
documentBuilder = documentBuilderFactory.newDocumentBuilder();
}
catch (ParserConfigurationException pce)
{
throw new GmFormatException(f,pce);
}
Document dom = documentBuilder.newDocument();
JProgressBar progressBar = LGM.getProgressDialogBar();
progressBar.setMaximum(160);
LGM.setProgressTitle(Messages.getString("ProgressDialog.GMX_SAVING")); //$NON-NLS-1$
ProjectFileContext c = new ProjectFileContext(f,dom);
Element root = dom.createElement("assets"); //$NON-NLS-1$
LGM.setProgress(0,Messages.getString("ProgressDialog.SETTINGS")); //$NON-NLS-1$
writeConfigurations(c,root,savetime);
LGM.setProgress(10,Messages.getString("ProgressDialog.SPRITES")); //$NON-NLS-1$
writeSprites(c,root);
LGM.setProgress(20,Messages.getString("ProgressDialog.SOUNDS")); //$NON-NLS-1$
writeSounds(c,root);
LGM.setProgress(30,Messages.getString("ProgressDialog.BACKGROUNDS")); //$NON-NLS-1$
writeBackgrounds(c,root);
LGM.setProgress(40,Messages.getString("ProgressDialog.PATHS")); //$NON-NLS-1$
writePaths(c,root);
LGM.setProgress(50,Messages.getString("ProgressDialog.SCRIPTS")); //$NON-NLS-1$
writeScripts(c,root);
LGM.setProgress(60,Messages.getString("ProgressDialog.SHADERS")); //$NON-NLS-1$
writeShaders(c,root);
LGM.setProgress(70,Messages.getString("ProgressDialog.FONTS")); //$NON-NLS-1$
writeFonts(c,root);
LGM.setProgress(80,Messages.getString("ProgressDialog.TIMELINES")); //$NON-NLS-1$
writeTimelines(c,root);
LGM.setProgress(90,Messages.getString("ProgressDialog.OBJECTS")); //$NON-NLS-1$
writeGmObjects(c,root);
LGM.setProgress(100,Messages.getString("ProgressDialog.ROOMS")); //$NON-NLS-1$
writeRooms(c,root);
LGM.setProgress(110,Messages.getString("ProgressDialog.INCLUDEFILES")); //$NON-NLS-1$
//writeIncludedFiles(c, root);
LGM.setProgress(120,Messages.getString("ProgressDialog.PACKAGES")); //$NON-NLS-1$
//writePackages(c, root);
LGM.setProgress(130,Messages.getString("ProgressDialog.CONSTANTS")); //$NON-NLS-1$
writeDefaultConstants(c, root);
LGM.setProgress(140,Messages.getString("ProgressDialog.EXTENSIONS")); //$NON-NLS-1$
//writeExtensions(c, root);
LGM.setProgress(150,Messages.getString("ProgressDialog.GAMEINFORMATION")); //$NON-NLS-1$
writeGameInformation(c,root);
dom.appendChild(root);
// Now take the serialized XML data and format and write it to the actual file
LGM.setProgress(150,Messages.getString("ProgressDialog.DOCUMENT")); //$NON-NLS-1$
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
tr.transform(new DOMSource(dom),new StreamResult(os));
}
catch (TransformerException te)
{
throw new GmFormatException(f,te);
}
finally
{
// close up the stream and release the lock on the file
os.close();
}
LGM.setProgress(160,Messages.getString("ProgressDialog.FINISHED")); //$NON-NLS-1$
}
private static Element createElement(Document dom, String name, String value)
{
Element ret = dom.createElement(name);
ret.setTextContent(value);
return ret;
}
// This is used to obtain the primary node for a resource type.
// TODO: This is rather ugly and doesn't allow multiple primary nodes.
private static ResNode getPrimaryNode(ResNode first)
{
while (first.status != ResNode.STATUS_PRIMARY)
first = (ResNode) first.getParent();
return first;
}
// This is used to store booleans since GMX uses -1 and 0 and other times false and true
private static String boolToString(boolean bool)
{
return bool ? "-1" : "0"; //$NON-NLS-1$ //$NON-NLS-2$
}
public static <R extends Resource<R,?>> String getName(ResourceReference<R> ref)
{
return getName(ref,"<undefined>"); //$NON-NLS-1$
}
public static <R extends Resource<R,?>> String getName(ResourceReference<R> ref, String noneval)
{
Resource<?,?> res = deRef(ref);
if (res != null && res instanceof InstantiableResource<?,?>)
return ((InstantiableResource<?,?>) res).getName();
else
return noneval;
}
public static <R extends Resource<R,?>> int getId(ResourceReference<R> ref)
{
return getId(ref,-1);
}
public static <R extends Resource<R,?>> int getId(ResourceReference<R> ref, int noneval)
{
Resource<?,?> res = deRef(ref);
if (res != null && res instanceof InstantiableResource<?,?>)
return ((InstantiableResource<?,?>) res).getId();
else
return noneval;
}
public static void writeConfigurations(ProjectFileContext c, Element root, long savetime) throws IOException,
TransformerException
{
Document mdom = c.dom;
ProjectFile f = c.f;
Element conNode = mdom.createElement("Configs"); //$NON-NLS-1$
conNode.setAttribute("name","configs"); //$NON-NLS-1$//$NON-NLS-2$
root.appendChild(conNode);
for (GameSettings gs : LGM.currentFile.gameSettings) {
Element setNode = mdom.createElement("Config"); //$NON-NLS-1$
setNode.setTextContent("Configs\\" + gs.getName()); //$NON-NLS-1$
conNode.appendChild(setNode);
Document dom = documentBuilder.newDocument();
Element nconNode = dom.createElement("Config"); //$NON-NLS-1$
dom.appendChild(nconNode);
Element optNode = dom.createElement("Options"); //$NON-NLS-1$
nconNode.appendChild(optNode);
// For some odd reason these two settings are combined together.
// 2147483649 - Both
// 2147483648 - Software Vertex Processing only
// 1 - Synchronization Only
// 0 - None
long syncvertex = 0;
if (gs.get(PGameSettings.USE_SYNCHRONIZATION))
{
syncvertex += 1;
}
if (gs.get(PGameSettings.FORCE_SOFTWARE_VERTEX_PROCESSING))
{
syncvertex += 2147483648L;
}
optNode.appendChild(createElement(dom,"option_sync_vertex",Long.toString(syncvertex))); //$NON-NLS-1$
optNode.appendChild(createElement(dom,"option_fullscreen", //$NON-NLS-1$
gs.get(PGameSettings.START_FULLSCREEN).toString()));
optNode.appendChild(createElement(dom,"option_sizeable", //$NON-NLS-1$
gs.get(PGameSettings.ALLOW_WINDOW_RESIZE).toString()));
optNode.appendChild(createElement(dom,"option_stayontop", //$NON-NLS-1$
gs.get(PGameSettings.ALWAYS_ON_TOP).toString()));
optNode.appendChild(createElement(dom,"option_aborterrors", //$NON-NLS-1$
gs.get(PGameSettings.ABORT_ON_ERROR).toString()));
optNode.appendChild(createElement(dom,"option_noscreensaver", //$NON-NLS-1$
gs.get(PGameSettings.DISABLE_SCREENSAVERS).toString()));
optNode.appendChild(createElement(dom,"option_showcursor", //$NON-NLS-1$
gs.get(PGameSettings.DISPLAY_CURSOR).toString()));
optNode.appendChild(createElement(dom,"option_displayerrors", //$NON-NLS-1$
gs.get(PGameSettings.DISPLAY_ERRORS).toString()));
optNode.appendChild(createElement(dom,"option_noborder", //$NON-NLS-1$
gs.get(PGameSettings.DONT_DRAW_BORDER).toString()));
optNode.appendChild(createElement(dom,"option_nobuttons", //$NON-NLS-1$
gs.get(PGameSettings.DONT_SHOW_BUTTONS).toString()));
optNode.appendChild(createElement(dom,"option_argumenterrors", //$NON-NLS-1$
gs.get(PGameSettings.ERROR_ON_ARGS).toString()));
optNode.appendChild(createElement(dom,"option_freeze", //$NON-NLS-1$
gs.get(PGameSettings.FREEZE_ON_LOSE_FOCUS).toString()));
optNode.appendChild(createElement(dom,"option_colordepth", //$NON-NLS-1$
ProjectFile.GS_DEPTH_CODE.get(gs.get(PGameSettings.COLOR_DEPTH)).toString()));
optNode.appendChild(createElement(dom,"option_frequency", //$NON-NLS-1$
ProjectFile.GS_FREQ_CODE.get(gs.get(PGameSettings.FREQUENCY)).toString()));
optNode.appendChild(createElement(dom,"option_resolution", //$NON-NLS-1$
ProjectFile.GS_RESOL_CODE.get(gs.get(PGameSettings.RESOLUTION)).toString()));
optNode.appendChild(createElement(dom,"option_changeresolution", //$NON-NLS-1$
gs.get(PGameSettings.SET_RESOLUTION).toString()));
optNode.appendChild(createElement(
dom,
"option_priority", //$NON-NLS-1$
ProjectFile.GS_PRIORITY_CODE.get(gs.get(PGameSettings.GAME_PRIORITY)).toString()));
optNode.appendChild(createElement(dom,"option_closeesc", //$NON-NLS-1$
gs.get(PGameSettings.LET_ESC_END_GAME).toString()));
optNode.appendChild(createElement(dom,"option_interpolate", //$NON-NLS-1$
gs.get(PGameSettings.INTERPOLATE).toString()));
optNode.appendChild(createElement(dom,"option_scale", //$NON-NLS-1$
gs.get(PGameSettings.SCALING).toString()));
optNode.appendChild(createElement(dom,"option_closeesc", //$NON-NLS-1$
gs.get(PGameSettings.TREAT_CLOSE_AS_ESCAPE).toString()));
gs.put(PGameSettings.LAST_CHANGED,ProjectFile.longTimeToGmTime(savetime));
optNode.appendChild(createElement(dom,"option_lastchanged", //$NON-NLS-1$
gs.get(PGameSettings.LAST_CHANGED).toString()));
optNode.appendChild(createElement(dom,"option_gameid", //$NON-NLS-1$
gs.get(PGameSettings.GAME_ID).toString()));
String guid = HexBin.encode((byte[]) gs.get(PGameSettings.GAME_GUID));
optNode.appendChild(createElement(dom,"option_gameguid", //$NON-NLS-1$
'{' + guid.substring(0,8) + '-' + guid.substring(8,12) + '-' + guid.substring(12,16) + '-'
+ guid.substring(16,20) + '-' + guid.substring(20,32) + '}'));
optNode.appendChild(createElement(dom,"option_author", //$NON-NLS-1$
(String) gs.get(PGameSettings.AUTHOR)));
optNode.appendChild(createElement(dom,"option_version_company", //$NON-NLS-1$
(String) gs.get(PGameSettings.COMPANY)));
optNode.appendChild(createElement(dom,"option_version_copyright", //$NON-NLS-1$
(String) gs.get(PGameSettings.COPYRIGHT)));
optNode.appendChild(createElement(dom,"option_version_description", //$NON-NLS-1$
(String) gs.get(PGameSettings.DESCRIPTION)));
optNode.appendChild(createElement(dom,"option_version_product", //$NON-NLS-1$
(String) gs.get(PGameSettings.PRODUCT)));
optNode.appendChild(createElement(dom,"option_information", //$NON-NLS-1$
(String) gs.get(PGameSettings.INFORMATION)));
optNode.appendChild(createElement(dom,"option_version", //$NON-NLS-1$
gs.get(PGameSettings.VERSION).toString()));
optNode.appendChild(createElement(dom,"option_version_build", //$NON-NLS-1$
gs.get(PGameSettings.VERSION_BUILD).toString()));
optNode.appendChild(createElement(dom,"option_version_major", //$NON-NLS-1$
gs.get(PGameSettings.VERSION_MAJOR).toString()));
optNode.appendChild(createElement(dom,"option_version_minor", //$NON-NLS-1$
gs.get(PGameSettings.VERSION_MINOR).toString()));
optNode.appendChild(createElement(dom,"option_version_release", //$NON-NLS-1$
gs.get(PGameSettings.VERSION_RELEASE).toString()));
Element cce = dom.createElement("ConfigConstants"); //$NON-NLS-1$
writeConstants(gs.constants, dom, cce);
nconNode.appendChild(cce);
String icoPath = "Configs\\Default\\windows\\runner_icon.ico"; //$NON-NLS-1$
optNode.appendChild(createElement(dom,"option_windows_game_icon",icoPath)); //$NON-NLS-1$
icoPath = f.getDirectory() + '\\' + icoPath;
File file = new File(Util.getPOSIXPath(icoPath)).getParentFile();
file.mkdirs();
FileOutputStream fos = new FileOutputStream(Util.getPOSIXPath(icoPath));
((ICOFile) gs.get(PGameSettings.GAME_ICON)).write(fos);
fos.close();
fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
file = new File(Util.getPOSIXPath(f.getDirectory() + "/Configs")); //$NON-NLS-1$
file.mkdir();
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(f.getDirectory() + "/Configs/" + gs.getName() + ".config.gmx")); //$NON-NLS-1$ //$NON-NLS-2$
tr.transform(new DOMSource(dom),new StreamResult(fos));
}
finally
{
fos.close();
}
}
return;
}
public static void writeTriggers(ProjectFile f, ResNode root, int ver) throws IOException
{
// TODO: Implement
}
public static void writeConstants(Constants cnsts, Document dom, Element node) throws IOException
{
Element base = dom.createElement("constants"); //$NON-NLS-1$
base.setAttribute("number",Integer.toString(cnsts.constants.size())); //$NON-NLS-1$
for (Constant cnst : cnsts.constants) {
Element celement = dom.createElement("constant"); //$NON-NLS-1$
celement.setAttribute("name",cnst.name); //$NON-NLS-1$
celement.setTextContent(cnst.value);;
base.appendChild(celement);
}
node.appendChild(base);
}
public static void writeDefaultConstants(ProjectFileContext c, Element root) throws IOException
{
writeConstants(c.f.defaultConstants, c.dom, root);
}
private static void iterateSprites(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("sprites"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateSprites(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("sprites"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateSprites(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Sprite spr = (Sprite) resNode.getRes().get();
res = dom.createElement("sprite"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\sprites\\"; //$NON-NLS-1$
res.setTextContent("sprites\\" + spr.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(fname + "\\images")); //$NON-NLS-1$
file.mkdirs();
Document doc = documentBuilder.newDocument();
Element sprroot = doc.createElement("sprite"); //$NON-NLS-1$
doc.appendChild(sprroot);
sprroot.appendChild(createElement(doc,"xorig",spr.get(PSprite.ORIGIN_X).toString())); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"yorigin",spr.get(PSprite.ORIGIN_Y).toString())); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"colkind", //$NON-NLS-1$
ProjectFile.SPRITE_MASK_CODE.get(spr.get(PSprite.SHAPE)).toString()));
sprroot.appendChild(createElement(doc,"sepmasks", //$NON-NLS-1$
boolToString((Boolean) spr.get(PSprite.SEPARATE_MASK))));
sprroot.appendChild(createElement(doc,"bbox_left",spr.get(PSprite.BB_LEFT).toString())); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"bbox_right",spr.get(PSprite.BB_RIGHT).toString())); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"bbox_top",spr.get(PSprite.BB_TOP).toString())); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"bbox_bottom",spr.get(PSprite.BB_BOTTOM).toString())); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"bboxmode", //$NON-NLS-1$
ProjectFile.SPRITE_BB_CODE.get(spr.get(PSprite.BB_MODE)).toString()));
sprroot.appendChild(createElement(doc,"coltolerance", //$NON-NLS-1$
spr.get(PSprite.ALPHA_TOLERANCE).toString()));
sprroot.appendChild(createElement(doc,"HTile", //$NON-NLS-1$
boolToString((Boolean) spr.get(PSprite.TILE_HORIZONTALLY))));
sprroot.appendChild(createElement(doc,"VTile", //$NON-NLS-1$
boolToString((Boolean) spr.get(PSprite.TILE_VERTICALLY))));
// TODO: Write texture groups
sprroot.appendChild(createElement(doc,"For3D", //$NON-NLS-1$
boolToString((Boolean) spr.get(PSprite.FOR3D))));
int width = spr.getWidth(),
height = spr.getHeight();
sprroot.appendChild(createElement(doc,"width",Integer.toString(width))); //$NON-NLS-1$
sprroot.appendChild(createElement(doc,"height",Integer.toString(height))); //$NON-NLS-1$
Element frameroot = doc.createElement("frames"); //$NON-NLS-1$
for (int j = 0; j < spr.subImages.size(); j++)
{
String framefname = "images\\" + spr.getName() + ' ' + j + ".png"; //$NON-NLS-1$//$NON-NLS-2$
File outputfile = new File(Util.getPOSIXPath(fname + framefname));
Element frameNode = createElement(doc,"frame",framefname); //$NON-NLS-1$
frameNode.setAttribute("index",Integer.toString(j)); //$NON-NLS-1$
frameroot.appendChild(frameNode);
BufferedImage sub = spr.subImages.get(j);
// GMX does have a backwards compatibility property for transparency pixel so we write
// the image with the transparency removed when that setting is checked
ImageIO.write(
(Boolean) spr.get(PSprite.TRANSPARENT) ? Util.getTransparentImage(sub) : sub,
"png",outputfile); //$NON-NLS-1$
}
sprroot.appendChild(frameroot);
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + spr.getName() + ".sprite.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeSprites(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("sprites"); //$NON-NLS-1$
node.setAttribute("name","sprites"); //$NON-NLS-1$//$NON-NLS-2$
root.appendChild(node);
ResourceList<Sprite> sprList = c.f.resMap.getList(Sprite.class);
if (sprList.size() == 0)
{
return;
}
iterateSprites(c,getPrimaryNode(sprList.first().getNode()),node);
}
private static void iterateSounds(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("sounds"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateSounds(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("sounds"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateSounds(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Sound snd = (Sound) resNode.getRes().get();
res = dom.createElement("sound"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\sound\\"; //$NON-NLS-1$
res.setTextContent("sound\\" + snd.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(fname + "\\audio")); //$NON-NLS-1$
file.mkdirs();
Document doc = documentBuilder.newDocument();
Element sndroot = doc.createElement("sound"); //$NON-NLS-1$
doc.appendChild(sndroot);
// GMX uses double nested tags for volume, bit rate, sample rate, type, and bit depth
// There is an exception to this however. In every one of those tags after volume the
// nested tag is singular, where its parent is plural.
String ftype = snd.get(PSound.FILE_TYPE).toString();
sndroot.appendChild(createElement(doc,"extension",ftype)); //$NON-NLS-1$
sndroot.appendChild(createElement(doc,"origname",snd.get(PSound.FILE_NAME).toString())); //$NON-NLS-1$
sndroot.appendChild(createElement(doc,"kind", //$NON-NLS-1$
ProjectFile.SOUND_KIND_CODE.get(snd.get(PSound.KIND)).toString()));
Element volumeRoot = doc.createElement("volume"); //$NON-NLS-1$
volumeRoot.appendChild(createElement(doc,"volume", snd.get(PSound.VOLUME).toString())); //$NON-NLS-1$
sndroot.appendChild(volumeRoot);
Element bitRateRoot = doc.createElement("bitRates"); //$NON-NLS-1$
bitRateRoot.appendChild(createElement(doc,"bitRate", //$NON-NLS-1$
snd.get(PSound.BIT_RATE).toString()));
sndroot.appendChild(bitRateRoot);
Element sampleRateRoot = doc.createElement("sampleRates"); //$NON-NLS-1$
sampleRateRoot.appendChild(createElement(doc,"sampleRate", //$NON-NLS-1$
snd.get(PSound.SAMPLE_RATE).toString()));
sndroot.appendChild(sampleRateRoot);
Element typesRoot = doc.createElement("types"); //$NON-NLS-1$
typesRoot.appendChild(createElement(doc,"type", //$NON-NLS-1$
ProjectFile.SOUND_TYPE_CODE.get(snd.get(PSound.TYPE)).toString()));
sndroot.appendChild(typesRoot);
Element bitDepthRoot = doc.createElement("bitDepths"); //$NON-NLS-1$
bitDepthRoot.appendChild(createElement(doc,"bitDepth", //$NON-NLS-1$
snd.get(PSound.BIT_DEPTH).toString()));
sndroot.appendChild(bitDepthRoot);
sndroot.appendChild(createElement(doc,"pan",snd.get(PSound.PAN).toString())); //$NON-NLS-1$
sndroot.appendChild(createElement(doc,"preload", //$NON-NLS-1$
boolToString((Boolean) snd.get(PSound.PRELOAD))));
sndroot.appendChild(createElement(doc,"compressed", //$NON-NLS-1$
boolToString((Boolean) snd.get(PSound.COMPRESSED))));
sndroot.appendChild(createElement(doc,"streamed", //$NON-NLS-1$
boolToString((Boolean) snd.get(PSound.STREAMED))));
sndroot.appendChild(createElement(doc,"uncompressOnLoad", //$NON-NLS-1$
boolToString((Boolean) snd.get(PSound.DECOMPRESS_ON_LOAD))));
int effects = 0;
int n = 1;
for (PSound k : ProjectFile.SOUND_FX_FLAGS)
{
if (snd.get(k)) effects |= n;
n <<= 1;
}
sndroot.appendChild(createElement(doc,"effects",Integer.toString(effects))); //$NON-NLS-1$
sndroot.appendChild(createElement(doc,"data",snd.getName() + ftype)); //$NON-NLS-1$
Util.writeBinaryFile(fname + "audio\\" + snd.getName() + ftype,snd.data); //$NON-NLS-1$
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + resNode.getUserObject().toString()
+ ".sound.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeSounds(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("sounds"); //$NON-NLS-1$
node.setAttribute("name","sound"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Sound> sndList = c.f.resMap.getList(Sound.class);
if (sndList.size() == 0)
{
return;
}
iterateSounds(c,getPrimaryNode(sndList.first().getNode()),node);
}
private static void iterateBackgrounds(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("backgrounds"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateBackgrounds(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("backgrounds"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateBackgrounds(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Background bkg = (Background) resNode.getRes().get();
res = dom.createElement("background"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\background\\"; //$NON-NLS-1$
res.setTextContent("background\\" + bkg.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(fname + "\\images")); //$NON-NLS-1$
file.mkdirs();
Document doc = documentBuilder.newDocument();
Element bkgroot = doc.createElement("background"); //$NON-NLS-1$
doc.appendChild(bkgroot);
bkgroot.appendChild(createElement(doc,"istileset", //$NON-NLS-1$
boolToString((Boolean) bkg.get(PBackground.USE_AS_TILESET))));
bkgroot.appendChild(createElement(doc,"tilewidth", //$NON-NLS-1$
bkg.get(PBackground.TILE_WIDTH).toString()));
bkgroot.appendChild(createElement(doc,"tileheight", //$NON-NLS-1$
bkg.get(PBackground.TILE_HEIGHT).toString()));
bkgroot.appendChild(createElement(doc,"tilexoff",bkg.get(PBackground.H_OFFSET).toString())); //$NON-NLS-1$
bkgroot.appendChild(createElement(doc,"tileyoff",bkg.get(PBackground.V_OFFSET).toString())); //$NON-NLS-1$
bkgroot.appendChild(createElement(doc,"tilehsep",bkg.get(PBackground.H_SEP).toString())); //$NON-NLS-1$
bkgroot.appendChild(createElement(doc,"tilevsep",bkg.get(PBackground.V_SEP).toString())); //$NON-NLS-1$
bkgroot.appendChild(createElement(doc,"HTile", //$NON-NLS-1$
boolToString((Boolean) bkg.get(PBackground.TILE_HORIZONTALLY))));
bkgroot.appendChild(createElement(doc,"VTile", //$NON-NLS-1$
boolToString((Boolean) bkg.get(PBackground.TILE_VERTICALLY))));
// TODO: Write texture groups
bkgroot.appendChild(createElement(doc,"For3D", //$NON-NLS-1$
boolToString((Boolean) bkg.get(PBackground.FOR3D))));
int width = bkg.getWidth(),
height = bkg.getHeight();
bkgroot.appendChild(createElement(doc,"width",Integer.toString(width))); //$NON-NLS-1$
bkgroot.appendChild(createElement(doc,"height",Integer.toString(height))); //$NON-NLS-1$
bkgroot.appendChild(createElement(doc,"data","images\\" + bkg.getName() + ".png")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (width > 0 && height > 0)
{
File outputfile = new File(Util.getPOSIXPath(fname + "images\\" + bkg.getName() + ".png")); //$NON-NLS-1$ //$NON-NLS-2$
ImageIO.write(bkg.getBackgroundImage(),"png",outputfile); //$NON-NLS-1$
}
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + resNode.getUserObject().toString()
+ ".background.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeBackgrounds(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("backgrounds"); //$NON-NLS-1$
node.setAttribute("name","background"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Background> bkgList = c.f.resMap.getList(Background.class);
if (bkgList.size() == 0)
{
return;
}
iterateBackgrounds(c,getPrimaryNode(bkgList.first().getNode()),node);
}
private static void iteratePaths(ProjectFileContext c, ResNode root, Element node)
throws TransformerException,IOException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("paths"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iteratePaths(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("paths"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iteratePaths(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Path path = (Path) resNode.getRes().get();
res = dom.createElement("path"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\paths\\"; //$NON-NLS-1$
res.setTextContent("paths\\" + path.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(f.getDirectory() + "/paths")); //$NON-NLS-1$
file.mkdir();
Document doc = documentBuilder.newDocument();
Element pathroot = doc.createElement("path"); //$NON-NLS-1$
doc.appendChild(pathroot);
int kind = path.get(PPath.SMOOTH) ? 1 : 0;
pathroot.appendChild(createElement(doc,"kind",Integer.toString(kind))); //$NON-NLS-1$
int closed = path.get(PPath.CLOSED) ? -1 : 0;
pathroot.appendChild(createElement(doc,"closed",Integer.toString(closed))); //$NON-NLS-1$
pathroot.appendChild(createElement(doc,"precision",path.get(PPath.PRECISION).toString())); //$NON-NLS-1$
pathroot.appendChild(createElement(doc,"backroom", //$NON-NLS-1$
Integer.toString(getId((ResourceReference<?>)path.get(PPath.BACKGROUND_ROOM)))));
pathroot.appendChild(createElement(doc,"hsnap",path.get(PPath.SNAP_X).toString())); //$NON-NLS-1$
pathroot.appendChild(createElement(doc,"vsnap",path.get(PPath.SNAP_Y).toString())); //$NON-NLS-1$
Element rootpoint = doc.createElement("points"); //$NON-NLS-1$
pathroot.appendChild(rootpoint);
for (PathPoint p : path.points)
{
rootpoint.appendChild(createElement(doc,"point", //$NON-NLS-1$
p.getX() + "," + p.getY() + ',' + p.getSpeed())); //$NON-NLS-1$
}
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + path.getName() + ".path.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writePaths(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("paths"); //$NON-NLS-1$
node.setAttribute("name","paths"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Path> pthList = c.f.resMap.getList(Path.class);
if (pthList.size() == 0)
{
return;
}
iteratePaths(c,getPrimaryNode(pthList.first().getNode()),node);
}
private static void iterateScripts(ProjectFileContext c, ResNode root, Element node)
throws IOException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("scripts"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateScripts(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("scripts"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateScripts(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Script scr = (Script) resNode.getRes().get();
res = dom.createElement("script"); //$NON-NLS-1$
String fname = "scripts\\" + scr.getName() + ".gml"; //$NON-NLS-1$ //$NON-NLS-2$
res.setTextContent(fname);
File file = new File(Util.getPOSIXPath(f.getDirectory() + "/scripts")); //$NON-NLS-1$
file.mkdir();
Writer out = null;
try
{
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
Util.getPOSIXPath(f.getDirectory() + '/' + Util.getPOSIXPath(fname))),"UTF-8")); //$NON-NLS-1$
out.write((String) scr.properties.get(PScript.CODE));
}
finally
{
out.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeScripts(ProjectFileContext c, Element root) throws IOException
{
Document dom = c.dom;
Element node = dom.createElement("scripts"); //$NON-NLS-1$
node.setAttribute("name","scripts"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Script> scrList = c.f.resMap.getList(Script.class);
if (scrList.size() == 0)
{
return;
}
iterateScripts(c,getPrimaryNode(scrList.first().getNode()),node);
}
private static void iterateShaders(ProjectFileContext c, ResNode root, Element node)
throws IOException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("shaders"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateShaders(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("shaders"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateShaders(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Shader shr = (Shader) resNode.getRes().get();
res = dom.createElement("shader"); //$NON-NLS-1$
String fname = "shaders\\" + shr.getName() + ".shader"; //$NON-NLS-1$ //$NON-NLS-2$
res.setTextContent(fname);
res.setAttribute("type",shr.properties.get(PShader.TYPE).toString()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(f.getDirectory() + "/shaders")); //$NON-NLS-1$
file.mkdir();
Writer out = null;
try
{
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
Util.getPOSIXPath(f.getDirectory() + '/' + fname)),"UTF-8"));
String code = shr.properties.get(PShader.VERTEX)
+ ('\n' + GMXFileReader.STUPID_SHADER_MARKER)
+ shr.properties.get(PShader.FRAGMENT);
out.write(code);
}
finally
{
out.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeShaders(ProjectFileContext c, Element root) throws IOException
{
Document dom = c.dom;
Element node = dom.createElement("shaders"); //$NON-NLS-1$
node.setAttribute("name","shaders"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Shader> shrList = c.f.resMap.getList(Shader.class);
if (shrList.size() == 0)
{
return;
}
iterateShaders(c,getPrimaryNode(shrList.first().getNode()),node);
}
private static void iterateFonts(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("fonts"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateFonts(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("fonts"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateFonts(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Font fnt = (Font) resNode.getRes().get();
res = dom.createElement("font"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\fonts\\"; //$NON-NLS-1$
res.setTextContent("fonts\\" + fnt.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(fname));
file.mkdirs();
Document doc = documentBuilder.newDocument();
Element fntroot = doc.createElement("font"); //$NON-NLS-1$
doc.appendChild(fntroot);
fntroot.appendChild(createElement(doc,"name",fnt.get(PFont.FONT_NAME).toString())); //$NON-NLS-1$
fntroot.appendChild(createElement(doc,"size",fnt.get(PFont.SIZE).toString())); //$NON-NLS-1$
fntroot.appendChild(createElement(doc,"bold",boolToString((Boolean) fnt.get(PFont.BOLD)))); //$NON-NLS-1$
fntroot.appendChild(createElement(doc,"italic", //$NON-NLS-1$
boolToString((Boolean) fnt.get(PFont.ITALIC))));
fntroot.appendChild(createElement(doc,"charset",fnt.get(PFont.CHARSET).toString())); //$NON-NLS-1$
fntroot.appendChild(createElement(doc,"aa",fnt.get(PFont.ANTIALIAS).toString())); //$NON-NLS-1$
Element rangeroot = doc.createElement("ranges"); //$NON-NLS-1$
fntroot.appendChild(rangeroot);
for (CharacterRange cr : fnt.characterRanges)
{
rangeroot.appendChild(createElement(
doc,
"range0", //$NON-NLS-1$
cr.properties.get(PCharacterRange.RANGE_MIN) + "," //$NON-NLS-1$
+ cr.properties.get(PCharacterRange.RANGE_MAX)));
}
Element glyphroot = doc.createElement("glyphs"); //$NON-NLS-1$
fntroot.appendChild(glyphroot);
for (GlyphMetric gm : fnt.glyphMetrics)
{
Element gelement = doc.createElement("glyph"); //$NON-NLS-1$
gelement.setAttribute("character",gm.properties.get(PGlyphMetric.CHARACTER).toString()); //$NON-NLS-1$
gelement.setAttribute("x",gm.properties.get(PGlyphMetric.X).toString()); //$NON-NLS-1$
gelement.setAttribute("y",gm.properties.get(PGlyphMetric.Y).toString()); //$NON-NLS-1$
gelement.setAttribute("w",gm.properties.get(PGlyphMetric.W).toString()); //$NON-NLS-1$
gelement.setAttribute("h",gm.properties.get(PGlyphMetric.H).toString()); //$NON-NLS-1$
gelement.setAttribute("shift",gm.properties.get(PGlyphMetric.SHIFT).toString()); //$NON-NLS-1$
gelement.setAttribute("offset",gm.properties.get(PGlyphMetric.OFFSET).toString()); //$NON-NLS-1$
glyphroot.appendChild(gelement);
}
// TODO: Move glyph renderer from the plugin to LGM and write glyphs here
fntroot.appendChild(createElement(doc,"image",fnt.getName() + ".png")); //$NON-NLS-1$ //$NON-NLS-2$
//File outputfile = new File(getUnixPath(fname + fnt.getName() + ".png"));
/*
try
{
ImageIO.write(fnt.getBackgroundImage(), "png", outputfile);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + fnt.getName() + ".font.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeFonts(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("fonts"); //$NON-NLS-1$
node.setAttribute("name","fonts"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Font> fntList = c.f.resMap.getList(Font.class);
if (fntList.size() == 0)
{
return;
}
iterateFonts(c,getPrimaryNode(fntList.first().getNode()),node);
}
private static void iterateTimelines(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("timelines"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateTimelines(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("timelines"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateTimelines(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Timeline timeline = (Timeline) resNode.getRes().get();
res = dom.createElement("timeline"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\timelines\\"; //$NON-NLS-1$
res.setTextContent("timelines\\" + timeline.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(f.getDirectory() + "/timelines")); //$NON-NLS-1$
file.mkdir();
Document doc = documentBuilder.newDocument();
Element tmlroot = doc.createElement("timeline"); //$NON-NLS-1$
doc.appendChild(tmlroot);
for (Moment mom : timeline.moments)
{
Element entroot = doc.createElement("entry"); //$NON-NLS-1$
tmlroot.appendChild(entroot);
entroot.appendChild(createElement(doc,"step",Integer.toString(mom.stepNo))); //$NON-NLS-1$
Element evtroot = doc.createElement("event"); //$NON-NLS-1$
entroot.appendChild(evtroot);
writeActions(doc,evtroot,mom);
}
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + timeline.getName() + ".timeline.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeTimelines(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("timelines"); //$NON-NLS-1$
node.setAttribute("name","timelines"); //$NON-NLS-1$//$NON-NLS-2$
root.appendChild(node);
ResourceList<Timeline> tmlList = c.f.resMap.getList(Timeline.class);
if (tmlList.size() == 0)
{
return;
}
iterateTimelines(c,getPrimaryNode(tmlList.first().getNode()),node);
}
private static void iterateGmObjects(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("objects"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateGmObjects(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("objects"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateGmObjects(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
GmObject object = (GmObject) resNode.getRes().get();
res = dom.createElement("object"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\objects\\"; //$NON-NLS-1$
res.setTextContent("objects\\" + object.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(f.getDirectory() + "/objects")); //$NON-NLS-1$
file.mkdir();
Document doc = documentBuilder.newDocument();
Element objroot = doc.createElement("object"); //$NON-NLS-1$
doc.appendChild(objroot);
objroot.appendChild(createElement(doc,"spriteName", //$NON-NLS-1$
getName((ResourceReference<?>)object.get(PGmObject.SPRITE))));
objroot.appendChild(createElement(doc,"solid", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.SOLID))));
objroot.appendChild(createElement(doc,"visible", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.VISIBLE))));
objroot.appendChild(createElement(doc,"depth",object.get(PGmObject.DEPTH).toString())); //$NON-NLS-1$
objroot.appendChild(createElement(doc,"persistent", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.PERSISTENT))));
objroot.appendChild(createElement(doc,"maskName", //$NON-NLS-1$
getName((ResourceReference<?>)object.get(PGmObject.MASK))));
objroot.appendChild(createElement(doc,"parentName", //$NON-NLS-1$
getName((ResourceReference<?>)object.get(PGmObject.PARENT))));
Element evtroot = doc.createElement("events"); //$NON-NLS-1$
for (int i = 0; i < object.mainEvents.size(); i++)
{
MainEvent me = object.mainEvents.get(i);
for (int k = me.events.size(); k > 0; k--)
{
Event ev = me.events.get(k - 1);
Element evtelement = doc.createElement("event"); //$NON-NLS-1$
evtelement.setAttribute("eventtype",Integer.toString(ev.mainId)); //$NON-NLS-1$
if (ev.mainId == MainEvent.EV_COLLISION)
{
evtelement.setAttribute("ename", //$NON-NLS-1$
getName((ResourceReference<GmObject>)ev.other));
}
else
{
evtelement.setAttribute("enumb",Integer.toString(ev.id)); //$NON-NLS-1$
}
evtroot.appendChild(evtelement);
writeActions(doc,evtelement,ev);
}
}
objroot.appendChild(evtroot);
// Physics Properties
objroot.appendChild(createElement(doc,"PhysicsObject", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.PHYSICS_OBJECT))));
objroot.appendChild(createElement(doc,"PhysicsObjectSensor", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.PHYSICS_SENSOR))));
objroot.appendChild(createElement(doc,"PhysicsObjectShape", //$NON-NLS-1$
ProjectFile.SHAPE_CODE.get(object.get(PGmObject.PHYSICS_SHAPE)).toString()));
objroot.appendChild(createElement(doc,"PhysicsObjectDensity", //$NON-NLS-1$
Double.toString((Double) object.get(PGmObject.PHYSICS_DENSITY))));
objroot.appendChild(createElement(doc,"PhysicsObjectRestitution", //$NON-NLS-1$
Double.toString((Double) object.get(PGmObject.PHYSICS_RESTITUTION))));
objroot.appendChild(createElement(doc,"PhysicsObjectGroup", //$NON-NLS-1$
Integer.toString((Integer) object.get(PGmObject.PHYSICS_GROUP))));
objroot.appendChild(createElement(doc,"PhysicsObjectLinearDamping", //$NON-NLS-1$
Double.toString((Double) object.get(PGmObject.PHYSICS_DAMPING_LINEAR))));
objroot.appendChild(createElement(doc,"PhysicsObjectAngularDamping", //$NON-NLS-1$
Double.toString((Double) object.get(PGmObject.PHYSICS_DAMPING_ANGULAR))));
objroot.appendChild(createElement(doc,"PhysicsObjectFriction", //$NON-NLS-1$
Double.toString((Double) object.get(PGmObject.PHYSICS_FRICTION))));
objroot.appendChild(createElement(doc,"PhysicsObjectAwake", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.PHYSICS_AWAKE))));
objroot.appendChild(createElement(doc,"PhysicsObjectKinematic", //$NON-NLS-1$
boolToString((Boolean) object.get(PGmObject.PHYSICS_KINEMATIC))));
Element pointsroot = doc.createElement("PhysicsShapePoints"); //$NON-NLS-1$
for (ShapePoint point : object.shapePoints)
{
pointsroot.appendChild(createElement(doc,"point",point.getX() + "," + point.getY())); //$NON-NLS-1$ //$NON-NLS-2$
}
objroot.appendChild(pointsroot);
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + object.getName() + ".object.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeGmObjects(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("objects"); //$NON-NLS-1$
node.setAttribute("name","objects"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<GmObject> objList = c.f.resMap.getList(GmObject.class);
if (objList.size() == 0)
{
return;
}
iterateGmObjects(c,getPrimaryNode(objList.first().getNode()),node);
}
private static void iterateRooms(ProjectFileContext c, ResNode root, Element node)
throws IOException,TransformerException
{
ProjectFile f = c.f;
Document dom = c.dom;
Vector<ResNode> children = root.getChildren();
if (children == null)
{
return;
}
for (Object obj : children)
{
if (!(obj instanceof ResNode))
{
continue;
}
ResNode resNode = (ResNode) obj;
Element res = null;
switch (resNode.status)
{
case ResNode.STATUS_PRIMARY:
res = dom.createElement("rooms"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString().toLowerCase()); //$NON-NLS-1$
iterateRooms(c,resNode,res);
break;
case ResNode.STATUS_GROUP:
res = dom.createElement("rooms"); //$NON-NLS-1$
res.setAttribute("name",resNode.getUserObject().toString()); //$NON-NLS-1$
iterateRooms(c,resNode,res);
break;
case ResNode.STATUS_SECONDARY:
Room room = (Room) resNode.getRes().get();
res = dom.createElement("room"); //$NON-NLS-1$
String fname = f.getDirectory() + "\\rooms\\"; //$NON-NLS-1$
res.setTextContent("rooms\\" + room.getName()); //$NON-NLS-1$
File file = new File(Util.getPOSIXPath(f.getDirectory() + "/rooms")); //$NON-NLS-1$
file.mkdir();
Document doc = documentBuilder.newDocument();
Element roomroot = doc.createElement("room"); //$NON-NLS-1$
doc.appendChild(roomroot);
roomroot.appendChild(createElement(doc,"caption",room.get(PRoom.CAPTION).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"width",room.get(PRoom.WIDTH).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"height",room.get(PRoom.HEIGHT).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"hsnap",room.get(PRoom.SNAP_X).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"vsnap",room.get(PRoom.SNAP_Y).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"isometric", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.ISOMETRIC))));
roomroot.appendChild(createElement(doc,"speed",room.get(PRoom.SPEED).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"persistent", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.PERSISTENT))));
roomroot.appendChild(createElement(doc,"colour", //$NON-NLS-1$
Integer.toString(Util.getGmColor((Color) room.get(PRoom.BACKGROUND_COLOR)))));
roomroot.appendChild(createElement(doc,"showcolour", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.DRAW_BACKGROUND_COLOR))));
roomroot.appendChild(createElement(doc,"code",room.get(PRoom.CREATION_CODE).toString())); //$NON-NLS-1$
roomroot.appendChild(createElement(doc,"enableViews", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.VIEWS_ENABLED))));
roomroot.appendChild(createElement(doc,"clearViewBackground", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.VIEWS_CLEAR))));
// Write the maker settings, or basically the settings of the editor.
Element mkeroot = doc.createElement("makerSettings"); //$NON-NLS-1$
mkeroot.appendChild(createElement(doc,"isSet", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.REMEMBER_WINDOW_SIZE))));
mkeroot.appendChild(createElement(doc,"w",room.get(PRoom.EDITOR_WIDTH).toString())); //$NON-NLS-1$
mkeroot.appendChild(createElement(doc,"h",room.get(PRoom.EDITOR_HEIGHT).toString())); //$NON-NLS-1$
mkeroot.appendChild(createElement(doc,"showGrid", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.SHOW_GRID))));
mkeroot.appendChild(createElement(doc,"showObjects", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.SHOW_OBJECTS))));
mkeroot.appendChild(createElement(doc,"showTiles", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.SHOW_TILES))));
mkeroot.appendChild(createElement(doc,"showBackgrounds", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.SHOW_BACKGROUNDS))));
mkeroot.appendChild(createElement(doc,"showForegrounds", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.SHOW_FOREGROUNDS))));
mkeroot.appendChild(createElement(doc,"showViews", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.SHOW_VIEWS))));
mkeroot.appendChild(createElement(doc,"deleteUnderlyingObj", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.DELETE_UNDERLYING_OBJECTS))));
mkeroot.appendChild(createElement(doc,"deleteUnderlyingTiles", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.DELETE_UNDERLYING_TILES))));
mkeroot.appendChild(createElement(doc,"page",room.get(PRoom.CURRENT_TAB).toString())); //$NON-NLS-1$
mkeroot.appendChild(createElement(doc,"xoffset",room.get(PRoom.SCROLL_BAR_X).toString())); //$NON-NLS-1$
mkeroot.appendChild(createElement(doc,"yoffset",room.get(PRoom.SCROLL_BAR_Y).toString())); //$NON-NLS-1$
roomroot.appendChild(mkeroot);
// Write Backgrounds
Element backroot = doc.createElement("backgrounds"); //$NON-NLS-1$
roomroot.appendChild(backroot);
for (BackgroundDef back : room.backgroundDefs)
{
PropertyMap<PBackgroundDef> props = back.properties;
Element bckelement = doc.createElement("background"); //$NON-NLS-1$
backroot.appendChild(bckelement);
bckelement.setAttribute("visible", //$NON-NLS-1$
boolToString((Boolean) props.get(PBackgroundDef.VISIBLE)));
bckelement.setAttribute("foreground", //$NON-NLS-1$
boolToString((Boolean) props.get(PBackgroundDef.FOREGROUND)));
bckelement.setAttribute("name", //$NON-NLS-1$
getName((ResourceReference<?>)props.get(PBackgroundDef.BACKGROUND),""));
bckelement.setAttribute("x",Integer.toString((Integer) props.get(PBackgroundDef.X))); //$NON-NLS-1$
bckelement.setAttribute("y",Integer.toString((Integer) props.get(PBackgroundDef.Y))); //$NON-NLS-1$
bckelement.setAttribute("htiled", //$NON-NLS-1$
boolToString((Boolean) props.get(PBackgroundDef.TILE_HORIZ)));
bckelement.setAttribute("vtiled", //$NON-NLS-1$
boolToString((Boolean) props.get(PBackgroundDef.TILE_VERT)));
bckelement.setAttribute("hspeed", //$NON-NLS-1$
Integer.toString((Integer) props.get(PBackgroundDef.H_SPEED)));
bckelement.setAttribute("vspeed", //$NON-NLS-1$
Integer.toString((Integer) props.get(PBackgroundDef.V_SPEED)));
bckelement.setAttribute("stretch", //$NON-NLS-1$
boolToString((Boolean) props.get(PBackgroundDef.STRETCH)));
}
// Write Views
Element viewroot = doc.createElement("views"); //$NON-NLS-1$
roomroot.appendChild(viewroot);
for (View view : room.views)
{
PropertyMap<PView> props = view.properties;
Element vwelement = doc.createElement("view"); //$NON-NLS-1$
viewroot.appendChild(vwelement);
vwelement.setAttribute("visible",boolToString((Boolean) props.get(PView.VISIBLE))); //$NON-NLS-1$
vwelement.setAttribute("objName", //$NON-NLS-1$
getName((ResourceReference<?>) props.get(PView.OBJECT)));
vwelement.setAttribute("xview",Integer.toString((Integer) props.get(PView.VIEW_X))); //$NON-NLS-1$
vwelement.setAttribute("yview",Integer.toString((Integer) props.get(PView.VIEW_Y))); //$NON-NLS-1$
vwelement.setAttribute("wview",Integer.toString((Integer) props.get(PView.VIEW_W))); //$NON-NLS-1$
vwelement.setAttribute("hview",Integer.toString((Integer) props.get(PView.VIEW_H))); //$NON-NLS-1$
vwelement.setAttribute("xport",Integer.toString((Integer) props.get(PView.PORT_X))); //$NON-NLS-1$
vwelement.setAttribute("yport",Integer.toString((Integer) props.get(PView.PORT_Y))); //$NON-NLS-1$
vwelement.setAttribute("wport",Integer.toString((Integer) props.get(PView.PORT_W))); //$NON-NLS-1$
vwelement.setAttribute("hport",Integer.toString((Integer) props.get(PView.PORT_H))); //$NON-NLS-1$
vwelement.setAttribute("hborder",Integer.toString((Integer) props.get(PView.BORDER_H))); //$NON-NLS-1$
vwelement.setAttribute("vborder",Integer.toString((Integer) props.get(PView.BORDER_V))); //$NON-NLS-1$
vwelement.setAttribute("hspeed",Integer.toString((Integer) props.get(PView.SPEED_H))); //$NON-NLS-1$
vwelement.setAttribute("vspeed",Integer.toString((Integer) props.get(PView.SPEED_V))); //$NON-NLS-1$
}
// Write instances
Element insroot = doc.createElement("instances"); //$NON-NLS-1$
roomroot.appendChild(insroot);
for (Instance in : room.instances)
{
Element inselement = doc.createElement("instance"); //$NON-NLS-1$
insroot.appendChild(inselement);
inselement.setAttribute("objName", //$NON-NLS-1$
getName((ResourceReference<?>) in.properties.get(PInstance.OBJECT)));
inselement.setAttribute("x",Integer.toString(in.getPosition().x)); //$NON-NLS-1$
inselement.setAttribute("y",Integer.toString(in.getPosition().y)); //$NON-NLS-1$
inselement.setAttribute("name",in.getName()); //$NON-NLS-1$
inselement.setAttribute("id",Integer.toString(in.getID())); //$NON-NLS-1$
inselement.setAttribute("locked",boolToString(in.isLocked())); //$NON-NLS-1$
inselement.setAttribute("code",in.getCreationCode()); //$NON-NLS-1$
inselement.setAttribute("scaleX",Double.toString(in.getScale().getX())); //$NON-NLS-1$
inselement.setAttribute("scaleY",Double.toString(in.getScale().getY())); //$NON-NLS-1$
String color = Long.toString(Util.getInstanceColorWithAlpha(in.getColor(),in.getAlpha()));
inselement.setAttribute("colour",color); // default white //$NON-NLS-1$
inselement.setAttribute("rotation",Double.toString(in.getRotation())); //$NON-NLS-1$
}
// Write Tiles
Element tileroot = doc.createElement("tiles"); //$NON-NLS-1$
roomroot.appendChild(tileroot);
for (Tile tile : room.tiles)
{
PropertyMap<PTile> props = tile.properties;
Element tileelement = doc.createElement("tile"); //$NON-NLS-1$
tileroot.appendChild(tileelement);
tileelement.setAttribute("bgName", //$NON-NLS-1$
getName((ResourceReference<?>) props.get(PTile.BACKGROUND),""));
tileelement.setAttribute("x",Integer.toString((Integer) props.get(PTile.ROOM_X))); //$NON-NLS-1$
tileelement.setAttribute("y",Integer.toString((Integer) props.get(PTile.ROOM_Y))); //$NON-NLS-1$
tileelement.setAttribute("w",Integer.toString((Integer) props.get(PTile.WIDTH))); //$NON-NLS-1$
tileelement.setAttribute("h",Integer.toString((Integer) props.get(PTile.HEIGHT))); //$NON-NLS-1$
tileelement.setAttribute("xo",Integer.toString((Integer) props.get(PTile.BG_X))); //$NON-NLS-1$
tileelement.setAttribute("yo",Integer.toString((Integer) props.get(PTile.BG_Y))); //$NON-NLS-1$
tileelement.setAttribute("id",Integer.toString((Integer) props.get(PTile.ID))); //$NON-NLS-1$
tileelement.setAttribute("name",(String) props.get(PTile.NAME)); //$NON-NLS-1$
tileelement.setAttribute("depth",Integer.toString(tile.getDepth())); //$NON-NLS-1$
tileelement.setAttribute("locked",boolToString(tile.isLocked())); //$NON-NLS-1$
Point2D scale = tile.getScale();
tileelement.setAttribute("scaleX",Double.toString(scale.getX())); //$NON-NLS-1$
tileelement.setAttribute("scaleY",Double.toString(scale.getY())); //$NON-NLS-1$
tileelement.setAttribute("colour",Long.toString(tile.getColor())); //$NON-NLS-1$
}
// Physics properties
roomroot.appendChild(createElement(doc,"PhysicsWorld", //$NON-NLS-1$
boolToString((Boolean) room.get(PRoom.PHYSICS_WORLD))));
roomroot.appendChild(createElement(doc,"PhysicsWorldTop", //$NON-NLS-1$
Integer.toString((Integer) room.get(PRoom.PHYSICS_TOP))));
roomroot.appendChild(createElement(doc,"PhysicsWorldLeft", //$NON-NLS-1$
Integer.toString((Integer) room.get(PRoom.PHYSICS_LEFT))));
roomroot.appendChild(createElement(doc,"PhysicsWorldRight", //$NON-NLS-1$
Integer.toString((Integer) room.get(PRoom.PHYSICS_RIGHT))));
roomroot.appendChild(createElement(doc,"PhysicsWorldBottom", //$NON-NLS-1$
Integer.toString((Integer) room.get(PRoom.PHYSICS_BOTTOM))));
roomroot.appendChild(createElement(doc,"PhysicsWorldGravityX", //$NON-NLS-1$
Double.toString((Double) room.get(PRoom.PHYSICS_GRAVITY_X))));
roomroot.appendChild(createElement(doc,"PhysicsWorldGravityY", //$NON-NLS-1$
Double.toString((Double) room.get(PRoom.PHYSICS_GRAVITY_Y))));
roomroot.appendChild(createElement(doc,"PhysicsWorldPixToMeters", //$NON-NLS-1$
Double.toString((Double) room.get(PRoom.PHYSICS_PIXTOMETERS))));
FileOutputStream fos = null;
try
{
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT,"yes"); //$NON-NLS-1$
tr.setOutputProperty(OutputKeys.METHOD,"xml"); //$NON-NLS-1$
;
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2"); //$NON-NLS-1$ //$NON-NLS-2$
// send DOM to file
fos = new FileOutputStream(Util.getPOSIXPath(fname + room.getName() + ".room.gmx")); //$NON-NLS-1$
tr.transform(new DOMSource(doc),new StreamResult(fos));
}
finally
{
fos.close();
}
break;
}
node.appendChild(res);
}
}
public static void writeRooms(ProjectFileContext c, Element root) throws IOException,
TransformerException
{
Document dom = c.dom;
Element node = dom.createElement("rooms"); //$NON-NLS-1$
node.setAttribute("name","rooms"); //$NON-NLS-1$ //$NON-NLS-2$
root.appendChild(node);
ResourceList<Room> rmnList = c.f.resMap.getList(Room.class);
if (rmnList.size() == 0)
{
return;
}
iterateRooms(c,getPrimaryNode(rmnList.first().getNode()),node);
}
public static void writeIncludedFiles(ProjectFileContext c, Element root) throws IOException
{
// TODO: Implement
}
public static void writePackages(ProjectFileContext c, Element root) throws IOException
{
// TODO: Implement
}
public static void writeGameInformation(ProjectFileContext c, Element root)
throws FileNotFoundException
{
Document dom = c.dom;
ProjectFile f = c.f;
Element helpNode = dom.createElement("help"); //$NON-NLS-1$
Element rtfNode = dom.createElement("rtf"); //$NON-NLS-1$
rtfNode.setTextContent("help.rtf"); //$NON-NLS-1$
helpNode.appendChild(rtfNode);
PrintWriter out = null;
try
{
out = new PrintWriter(Util.getPOSIXPath(f.getDirectory() + "/help.rtf")); //$NON-NLS-1$
out.println(f.gameInfo.properties.get(PGameInformation.TEXT));
}
finally
{
out.close();
}
root.appendChild(helpNode);
}
public static void writeActions(Document doc, Element root, ActionContainer container)
{
for (Action act : container.actions)
{
Element actelement = doc.createElement("action"); //$NON-NLS-1$
root.appendChild(actelement);
LibAction la = act.getLibAction();
actelement.appendChild(createElement(doc,"libid", //$NON-NLS-1$
Integer.toString(la.parent != null ? la.parent.id : la.parentId)));
actelement.appendChild(createElement(doc,"id",Integer.toString(la.id))); //$NON-NLS-1$
actelement.appendChild(createElement(doc,"kind",Integer.toString(la.actionKind))); //$NON-NLS-1$
actelement.appendChild(createElement(doc,"userelative",boolToString(la.allowRelative))); //$NON-NLS-1$
actelement.appendChild(createElement(doc,"useapplyto",boolToString(la.canApplyTo))); //$NON-NLS-1$
actelement.appendChild(createElement(doc,"isquestion",boolToString(la.question))); //$NON-NLS-1$
actelement.appendChild(createElement(doc,"exetype",Integer.toString(la.execType))); //$NON-NLS-1$
String execinfo = "";
if (la.execType == Action.EXEC_FUNCTION)
{
execinfo = la.execInfo;
}
actelement.appendChild(createElement(doc,"functionname",execinfo)); //$NON-NLS-1$
execinfo = ""; //$NON-NLS-1$
if (la.execType == Action.EXEC_CODE)
{
execinfo = la.execInfo;
}
actelement.appendChild(createElement(doc,"codestring",execinfo)); //$NON-NLS-1$
ResourceReference<GmObject> at = act.getAppliesTo();
if (at != null)
{
if (at == GmObject.OBJECT_OTHER)
actelement.appendChild(createElement(doc,"whoName","other")); //$NON-NLS-1$ //$NON-NLS-2$
else if (at == GmObject.OBJECT_SELF)
actelement.appendChild(createElement(doc,"whoName","self")); //$NON-NLS-1$ //$NON-NLS-2$
else
actelement.appendChild(createElement(doc,"whoName",getName(at))); //$NON-NLS-1$
}
else
actelement.appendChild(createElement(doc,"whoName","self")); //$NON-NLS-1$ //$NON-NLS-2$
actelement.appendChild(createElement(doc,"relative",boolToString(act.isRelative()))); //$NON-NLS-1$
actelement.appendChild(createElement(doc,"isnot",boolToString(act.isNot()))); //$NON-NLS-1$
// Now we write the arguments
Element argsroot = doc.createElement("arguments"); //$NON-NLS-1$
actelement.appendChild(argsroot);
List<Argument> args = act.getArguments();
for (Argument arg : args)
{
Element argelement = doc.createElement("argument"); //$NON-NLS-1$
argsroot.appendChild(argelement);
argelement.appendChild(createElement(doc,"kind",Integer.toString(arg.kind))); //$NON-NLS-1$
Class<? extends Resource<?,?>> kind = Argument.getResourceKind(arg.kind);
if (kind != null && InstantiableResource.class.isAssignableFrom(kind))
{
argelement.appendChild(createElement(doc,Resource.kindNames.get(kind).toLowerCase(),
getName((ResourceReference<?>)arg.getRes())));
}
else
{
argelement.appendChild(createElement(doc,"string",arg.getVal())); //$NON-NLS-1$
}
}
}
}
}