Subversion Repositories display

Rev

Rev 252 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2007 Steve Ratcliffe
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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.
 *
 *
 * Author: Steve Ratcliffe
 * Create date: Dec 16, 2007
 */

package test.display;

import uk.me.parabola.imgfmt.Utils;

/**
 * Standalone program to display a TDB file.
 *
 * @author Steve Ratcliffe
 */

public class TdbDisplay extends CommonDisplay {
        private long nextStart;

        protected void print() {
                while (reader.position() < filelen) {
                        printBlock();
                }
        }

        private void printBlock() {
                byte bid = peek();
                switch (bid) {
                case 0x42:
                        printOverviewBlock();
                        break;
                case 0x44:
                        printCopyrightBlock();
                        break;
                case 0x4c:
                        printDetailBlock();
                        break;
                case 0x50:
                        printHeaderBlock();
                        break;
                case 'T':
                        printTBlock();
                        break;
                default:
                        printUnknown();
                        break;
                }
        }

        private void printTBlock() {
                Displayer d = new Displayer(reader);
                String text = "T block";
                d.setTitle(text);
                blockId(d, text);

                // All unknown, but A,B,C,D appear to be more important in that if you
                // change them it will break.
                d.charValue("unk1 %04x");
                d.byteValue("A %02x");
                d.int3Value("unk2 %06x");
                d.int3Value("unk3 %06x");
                d.byteValue("B %02x");
                d.charValue("unk4 %04x");
                d.byteValue("C %02x");
                d.intValue("unk5 %08x");
                d.byteValue("D %02x");
                d.charValue("unk6 %04x");
                d.print(outStream);
                outStream.flush();
        }

        private byte peek() {
                long pos = reader.position();
                byte b = reader.get();
                reader.position(pos);
                return b;
        }

        private void printHeaderBlock() {
                Displayer d = new Displayer(reader);
                String text = "Header block";
                d.setTitle(text);

                blockId(d, text);

                d.charValue("Product ID %d");
                d.charValue("Family ID %d");
                d.charValue("TDB version %d");
                d.zstringValue("Series name: %s");
                d.charValue("Product version %d");
                d.zstringValue("Family name: %s");

                d.byteValue("unk %d");
                d.byteValue("lowest map level?? %d");
                d.byteValue("unk %d");
                d.byteValue("unk %d");
                d.byteValue("unk %d");
                d.intValue("unk %d");
                d.byteValue("unk %d");
                d.byteValue("highest routable?? %d");
                d.intValue("unk %d");
                d.intValue("unk %d");
                d.intValue("unk %d");
                d.intValue("unk %d");
                d.int3Value("unk %d");
                d.intValue("codepage %d");
                d.intValue("unk %d");
                d.byteValue("unk %d");
                d.charValue("unk %d");

                printRemainder(d);

                d.print(outStream);
                outStream.flush();
        }

        private void printDetailBlock() {
                Displayer d = new Displayer(reader);
                String text = "Detail block";
                d.setTitle(text);

                long start = reader.position();

                int len = mapBlockCommon(d, text);

                d.charValue("?");
                int n = d.charValue("n");

                d.intValue("TRE size %d");
                d.intValue("RGN size %d");
                d.intValue("LBL size %d");
                if (n > 3) d.intValue("NET size %d");
                if (n > 4) d.intValue("NOD size %d");

                if (len > 66) {
                        //d.rawValue(7, "intro");
                        d.rawValue(2, "01 01");
                        d.byteValue("intro flag");
                        d.intValue("intro %d");
                        d.zstringValue("%s");
                        d.zstringValue("%s");
                        d.zstringValue("%s");
                        if (n > 3) d.zstringValue("%s");
                        if (n > 4) d.zstringValue("%s");
                }
                d.rawValue((int) (len - (reader.position() - start - 3)));
                d.print(outStream);
        }

        private void printOverviewBlock() {
                Displayer d = new Displayer(reader);
                String text = "Overview block";
                d.setTitle(text);

                mapBlockCommon(d, text);

                d.print(outStream);
        }

        private int mapBlockCommon(Displayer d, String text) {
                int len = blockId(d, text);
                //d.rawValue(len);
                d.intValue("Map number %08d");
                d.intValue("Parent map %08d");

                DisplayItem item = d.item();
                int f = item.setBytes(reader.getInt());
                item.addText("North %.4f", Utils.toDegrees(f >> 8));

                item = d.item();
                f = item.setBytes(reader.getInt());
                item.addText("East %.4f", Utils.toDegrees(f >> 8));

                item = d.item();
                f = item.setBytes(reader.getInt());
                item.addText("South %.4f", Utils.toDegrees(f >> 8));

                item = d.item();
                f = item.setBytes(reader.getInt());
                item.addText("West %.4f", Utils.toDegrees(f >> 8));

                d.zstringValue("Description: %s");
                return len;
        }

        private void printCopyrightBlock() {
                Displayer d = new Displayer(reader);
                String text = "Copyright block";
                d.setTitle(text);

                int len = blockId(d, text);
                d.print(outStream);
                printCopyrightSegment(d, len);
        }

        private void printCopyrightSegment(Displayer d, int len) {
                d.setTitle("Copyright segment");
                int remain = len;

                while (remain > 0) {
                        d.byteValue("~");
                        d.byteValue("~");
                        d.charValue("~");
                        remain -= 4;
                        remain -= d.zstringValue("text %s").length();
                        remain--;
                        d.print(outStream);
                }
        }

        private void printUnknown() {
                Displayer d = new Displayer(reader);
                String text = "Unknown block";
                d.setTitle(text);

                int len = blockId(d, text);
                d.rawValue(len);

                d.print(outStream);
        }

        private void printRemainder(Displayer d) {
                if (nextStart > reader.position()) {
                        d.rawValue((int) (nextStart - reader.position()));
                }
        }

        private int blockId(Displayer d, String text) {
                d.byteValue(text);

                int len = d.charValue("block len %d");

                nextStart = reader.position() + len;
                return len;
        }

        public static void main(String[] args) {
                if (args.length < 1) {
                        System.err.println("Usage: tdbdisplay <filename>");
                        System.exit(1);
                }

                CommonDisplay td = new TdbDisplay();
                td.display(args[0]);
        }
}