371 lines
13 KiB
Java
371 lines
13 KiB
Java
/*
|
|
*
|
|
* Copyright (C) 2003 Kent Hansen.
|
|
*
|
|
* This file is part of Tile Molester.
|
|
*
|
|
* Tile Molester 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 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Tile Molester 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.
|
|
*
|
|
*/
|
|
|
|
package tm;
|
|
|
|
import tm.colorcodecs.*;
|
|
import tm.tilecodecs.*;
|
|
import tm.fileselection.*;
|
|
import tm.utils.*;
|
|
import java.util.StringTokenizer;
|
|
import java.util.Vector;
|
|
import org.w3c.dom.Document;
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.NodeList;
|
|
import org.w3c.dom.Node;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import org.xml.sax.SAXException;
|
|
|
|
/**
|
|
*
|
|
* This class has methods for reading an XML document containing specifications
|
|
* for the various program resources.
|
|
*
|
|
**/
|
|
|
|
public class TMSpecReader {
|
|
|
|
private static Vector colorcodecs;
|
|
private static Vector tilecodecs;
|
|
private static Vector filefilters;
|
|
private static Vector palettefilters;
|
|
private static Vector filelisteners;
|
|
private static Element tmspec;
|
|
|
|
/**
|
|
*
|
|
* Reads specs from the specified file.
|
|
*
|
|
**/
|
|
|
|
public static void readSpecsFromFile(File file)
|
|
throws SAXException, ParserConfigurationException, IOException {
|
|
colorcodecs = new Vector();
|
|
tilecodecs = new Vector();
|
|
filefilters = new Vector();
|
|
palettefilters = new Vector();
|
|
filelisteners = new Vector();
|
|
Document doc = null;
|
|
try {
|
|
doc = XMLParser.parse(file);
|
|
} catch (SAXException e) {
|
|
throw e;
|
|
}
|
|
catch (ParserConfigurationException e) {
|
|
throw e;
|
|
}
|
|
catch (IOException e) {
|
|
throw e;
|
|
}
|
|
if (doc == null) return;
|
|
|
|
tmspec = doc.getDocumentElement(); // root element (<tmspec> tag)
|
|
|
|
readDirectColorFormats();
|
|
readIndexedColorFormats();
|
|
|
|
readPlanarTileFormats();
|
|
readLinearTileFormats();
|
|
readDirectColorTileFormats();
|
|
readCompositeTileFormats();
|
|
|
|
readFileFilters();
|
|
readPaletteFilters();
|
|
readFileListeners();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the directcolor format tags and creates directcolorcodecs for them.
|
|
*
|
|
**/
|
|
|
|
private static void readDirectColorFormats() {
|
|
NodeList directColorTags = tmspec.getElementsByTagName("directcolor");
|
|
for (int i=0; i<directColorTags.getLength(); i++) {
|
|
Element dc = (Element)directColorTags.item(i);
|
|
String id = dc.getAttribute("id");
|
|
int bpp = Integer.parseInt(dc.getAttribute("bpp"));
|
|
int rmask = (int)Long.parseLong(dc.getAttribute("rmask"), 16);
|
|
int gmask = (int)Long.parseLong(dc.getAttribute("gmask"), 16);
|
|
int bmask = (int)Long.parseLong(dc.getAttribute("bmask"), 16);
|
|
int amask = 0;
|
|
if (!dc.getAttribute("amask").equals(""))
|
|
amask = (int)Long.parseLong(dc.getAttribute("amask"), 16);
|
|
String desc = XMLParser.getNodeValue(dc.getElementsByTagName("description").item(0));
|
|
colorcodecs.add(new DirectColorCodec(id, bpp, rmask, gmask, bmask, amask, desc));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the indexedcolor format tags and creates indexedcolorcodecs for them.
|
|
*
|
|
**/
|
|
|
|
private static void readIndexedColorFormats() {
|
|
NodeList indexedColorTags = tmspec.getElementsByTagName("indexedcolor");
|
|
for (int i=0; i<indexedColorTags.getLength(); i++) {
|
|
Element ic = (Element)indexedColorTags.item(i);
|
|
String id = ic.getAttribute("id");
|
|
int bpp = Integer.parseInt(ic.getAttribute("bpp"));
|
|
String desc = XMLParser.getNodeValue(ic.getElementsByTagName("description").item(0));
|
|
int endianness = ic.getAttribute("endianness").equals("little") ? ColorCodec.LITTLE_ENDIAN : ColorCodec.BIG_ENDIAN;
|
|
String hexString = XMLParser.getNodeValue(ic.getElementsByTagName("data").item(0));
|
|
byte[] data = HexStringConverter.hexStringToBytes(hexString);
|
|
|
|
// pack the data into array of 32-bit ARGB ints
|
|
DirectColorCodec codec = new DirectColorCodec("", 24, 0xFF0000, 0x00FF00, 0x0000FF, 0, "");
|
|
codec.setEndianness(endianness);
|
|
int[] entries = new int[data.length / codec.getBytesPerPixel()];
|
|
for (int j=0; j<entries.length; j++) {
|
|
entries[j] = codec.fromBytes(data, j * codec.getBytesPerPixel());
|
|
}
|
|
|
|
colorcodecs.add(new IndexedColorCodec(id, bpp, entries, desc));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the planartile format tags and creates planartilecodecs for them.
|
|
*
|
|
**/
|
|
|
|
private static void readPlanarTileFormats() {
|
|
NodeList planarTileTags = tmspec.getElementsByTagName("planartile");
|
|
for (int i=0; i<planarTileTags.getLength(); i++) {
|
|
Element plc = (Element)planarTileTags.item(i);
|
|
String id = plc.getAttribute("id");
|
|
int bpp = Integer.parseInt(plc.getAttribute("bpp"));
|
|
String desc = XMLParser.getNodeValue(plc.getElementsByTagName("description").item(0));
|
|
StringTokenizer st = new StringTokenizer(plc.getAttribute("planeorder"), ",");
|
|
int[] ofs = new int[st.countTokens()];
|
|
for (int j=0; j<ofs.length; j++) {
|
|
ofs[j] = Integer.parseInt(st.nextToken());
|
|
}
|
|
tilecodecs.add(new PlanarTileCodec(id, ofs, desc));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the lineartile tags and creates lineartilecodecs for them.
|
|
*
|
|
**/
|
|
|
|
private static void readLinearTileFormats() {
|
|
NodeList linearTileTags = tmspec.getElementsByTagName("lineartile");
|
|
for (int i=0; i<linearTileTags.getLength(); i++) {
|
|
Element lnc = (Element)linearTileTags.item(i);
|
|
String id = lnc.getAttribute("id");
|
|
int bpp = Integer.parseInt(lnc.getAttribute("bpp"));
|
|
int ordering = LinearTileCodec.IN_ORDER;
|
|
if(lnc.getAttribute("ordering").equals("reverse"))
|
|
ordering = LinearTileCodec.REVERSE_ORDER;
|
|
String desc = XMLParser.getNodeValue(lnc.getElementsByTagName("description").item(0));
|
|
tilecodecs.add(new LinearTileCodec(id, bpp, ordering, desc));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the directcolortile tags and creates directcolortilecodecs for them.
|
|
*
|
|
**/
|
|
|
|
private static void readDirectColorTileFormats() {
|
|
NodeList directColorTileTags = tmspec.getElementsByTagName("directcolortile");
|
|
for (int i=0; i<directColorTileTags.getLength(); i++) {
|
|
Element dcc = (Element)directColorTileTags.item(i);
|
|
String id = dcc.getAttribute("id");
|
|
// String formatID = dcc.getAttribute("colorformat"); TODO
|
|
int bpp = Integer.parseInt(dcc.getAttribute("bpp"));
|
|
int rmask = (int)Long.parseLong(dcc.getAttribute("rmask"), 16);
|
|
int gmask = (int)Long.parseLong(dcc.getAttribute("gmask"), 16);
|
|
int bmask = (int)Long.parseLong(dcc.getAttribute("bmask"), 16);
|
|
int amask = 0;
|
|
if (!dcc.getAttribute("amask").equals(""))
|
|
amask = (int)Long.parseLong(dcc.getAttribute("amask"), 16);
|
|
String desc = XMLParser.getNodeValue(dcc.getElementsByTagName("description").item(0));
|
|
tilecodecs.add(new DirectColorTileCodec(id, bpp, rmask, gmask, bmask, amask, desc));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the compositetile tags and creates compositetilecodecs for them.
|
|
*
|
|
**/
|
|
|
|
private static void readCompositeTileFormats() {
|
|
NodeList compositeTileTags = tmspec.getElementsByTagName("compositetile");
|
|
for (int i=0; i<compositeTileTags.getLength(); i++) {
|
|
Element cpc = (Element)compositeTileTags.item(i);
|
|
String id = cpc.getAttribute("id");
|
|
String desc = XMLParser.getNodeValue(cpc.getElementsByTagName("description").item(0));
|
|
// build array of planar codecs
|
|
StringTokenizer st = new StringTokenizer(cpc.getAttribute("formats"), ",");
|
|
TileCodec[] codecs = new TileCodec[st.countTokens()];
|
|
int cc=0;
|
|
int bpp=0;
|
|
for (int j=0; j<codecs.length; j++) {
|
|
String cid = st.nextToken();
|
|
// find the codec with correct id
|
|
for (int k=0; k<tilecodecs.size(); k++) {
|
|
TileCodec tc = (TileCodec)tilecodecs.get(k);
|
|
if (tc.getID().equals(cid)) {
|
|
codecs[j] = tc;
|
|
cc++;
|
|
bpp += tc.getBitsPerPixel();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (cc != codecs.length) continue; // one or more codec IDs invalid
|
|
tilecodecs.add(new CompositeTileCodec(id, bpp, codecs, desc));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the filefilter tags and creates TMTileCodecFilters for them.
|
|
*
|
|
**/
|
|
|
|
private static void readFileFilters() {
|
|
NodeList fftags = tmspec.getElementsByTagName("filefilter");
|
|
for (int i=0; i<fftags.getLength(); i++) {
|
|
Element ff = (Element)fftags.item(i);
|
|
String extlist = ff.getAttribute("extensions");
|
|
String desc = XMLParser.getNodeValue(ff.getElementsByTagName("description").item(0));
|
|
String codecID = ff.getAttribute("tileformat");
|
|
int defaultMode = TileCodec.MODE_1D;
|
|
if (ff.getAttribute("mode").equals("2D"))
|
|
defaultMode = TileCodec.MODE_2D;
|
|
filefilters.add(new TMTileCodecFileFilter(extlist, desc, codecID, defaultMode));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the palettefilter tags and creates TMPaletteFilters for them.
|
|
*
|
|
**/
|
|
|
|
private static void readPaletteFilters() {
|
|
NodeList pftags = tmspec.getElementsByTagName("palettefilter");
|
|
for (int i=0; i<pftags.getLength(); i++) {
|
|
Element pf = (Element)pftags.item(i);
|
|
String extlist = pf.getAttribute("extensions");
|
|
String desc = XMLParser.getNodeValue(pf.getElementsByTagName("description").item(0));
|
|
String codecID = pf.getAttribute("colorformat");
|
|
int size = Integer.parseInt(pf.getAttribute("size"));
|
|
int offset = Integer.parseInt(pf.getAttribute("offset"));
|
|
int endianness = ColorCodec.LITTLE_ENDIAN;
|
|
if (pf.getAttribute("endianness").equals("big")) {
|
|
endianness = ColorCodec.BIG_ENDIAN;
|
|
}
|
|
palettefilters.add(new TMPaletteFileFilter(extlist, desc, codecID, size, offset, endianness));
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Reads the filelistener tags and creates TMFileListeners for them.
|
|
*
|
|
**/
|
|
|
|
private static void readFileListeners() {
|
|
ClassLoader loader = ClassLoader.getSystemClassLoader();
|
|
NodeList fltags = tmspec.getElementsByTagName("filelistener");
|
|
for (int i=0; i<fltags.getLength(); i++) {
|
|
Element fl = (Element)fltags.item(i);
|
|
String extlist = fl.getAttribute("extensions");
|
|
String classname = fl.getAttribute("classname");
|
|
Class c;
|
|
try {
|
|
c = loader.loadClass(classname);
|
|
}
|
|
catch (Exception e) {
|
|
continue;
|
|
}
|
|
Object o;
|
|
try {
|
|
o = c.newInstance();
|
|
}
|
|
catch (Exception e) {
|
|
continue;
|
|
}
|
|
filelisteners.add(o);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the vector of color codecs that's been created based on the XML.
|
|
*
|
|
**/
|
|
|
|
public static Vector getColorCodecs() {
|
|
return colorcodecs;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the vector of tile codecs that's been created based on the XML.
|
|
*
|
|
**/
|
|
|
|
public static Vector getTileCodecs() {
|
|
return tilecodecs;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the vector of file filters that's been created based on the XML.
|
|
*
|
|
**/
|
|
|
|
public static Vector getFileFilters() {
|
|
return filefilters;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the vector of palette filters that's been created based on the XML.
|
|
*
|
|
**/
|
|
|
|
public static Vector getPaletteFilters() {
|
|
return palettefilters;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the vector of file listeners that's been created based on the XML.
|
|
*
|
|
**/
|
|
|
|
public static Vector getFileListeners() {
|
|
return filelisteners;
|
|
}
|
|
|
|
} |