Subversion Repositories display

Rev

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

/*
 * Copyright (C) 2009.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 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.
 */

package test.display;

import java.io.PrintStream;

import uk.me.parabola.imgfmt.app.ImgFileReader;

/**
 * Use to display the MDR 1 sub files.  They have a header containing pointers into
 * the sub file.
 */

public class Mdr1SubFileDisplay {
        private final ImgFileReader reader;
        private final PrintStream outStream;
        private final MdrDisplay.MapInfo mapInfo;
        private static final String END_OF_SECTION = "END OF SECTION";

        public Mdr1SubFileDisplay(ImgFileReader reader, PrintStream out, MdrDisplay.MapInfo mapInfo) {
                this.reader = reader;
                outStream = out;
                this.mapInfo = mapInfo;
        }

        void print() {
                int suboff = mapInfo.offset;

                Displayer d = new Displayer(reader);

                d.setSectStart(suboff);
                d.setTitle("Sect 1, map " + mapInfo.mapIndex + ": " + mapInfo.mapid);

                reader.position(suboff);

                SectList subSectList = new SectList();

                int hl1 = d.charValue("Header len %d");
                int ind = 0;
                int num = 0;

                while (ind < 8 && reader.position() < suboff + hl1) {
                        ind++;
                        int off = d.intValue("sub" + ind + "(" + subToMdr(ind) + ") start 0x%x");
                        if(ind != 2) {
                                // section 2 seems to have the same length as the section before
                                num = d.intValue("sub" + ind + " number of records  %d");
                        }
                        int nextOff = reader.get4();
                        reader.position(reader.position() - 4);
                        subSectList.add(createSubSect(off, nextOff, num, ind));
                }

                d.print(outStream);

                // add fake entry for analysis
                subSectList.add(new Section(END_OF_SECTION, mapInfo.sublen, 0));
                subSectList.analyze(outStream);
                d.setTitle(null);
                d.print(outStream);

                int subsectNumber = 1;
                for (Section sect : subSectList) {
                        if (END_OF_SECTION.equals(sect.getName()))
                                break;
                        d.setTitle("Sect 1, map " + mapInfo.mapIndex + ": " + mapInfo.mapid + " sub " + subsectNumber);
                        print1(d, sect, subsectNumber++);
                        d.print(outStream);
                }
        }
       
        private static Section createSubSect(int off, int nextOff, int numRecs, int sNum) {
                String mdrName = subToMdr(sNum);
                String name = "sub" + sNum + " (" + mdrName + ")";
                int len = nextOff - off;
                Section s = new Section(name, off, len);
                if (numRecs != 0) {
                        assert len % numRecs == 0;
                        s.setRecordSize(len / numRecs);
                }
                return s;
        }

        public static String subToMdr(int sub) {
                String[] subs = new String[] {
                                "n/a",
                                "mdr11", "mdr10", "mdr7", "mdr5",
                                "mdr6", "mdr20", "mdr21", "mdr22"
                };
                if (sub >= subs.length)
                        return "unk";
                return subs[sub];
        }

        private static void print1(Displayer d, Section subsect, int subNumber) {
                int len = subsect.getLen();
                int recsize = subsect.getRecordSize();
               
                if (len < 0 || recsize < 0 || (len != 0 && recsize > len)) {
                        d.item().addText("INVALID LENGTH OR RECSIZE!! %d %d", len, recsize);
                        return;
                }
                if (len == 0) {
                        d.item().addText("NO LENGTH!! %d %d", len, recsize);
                        return;
                }
                d.rawValue(subsect.getLen(), "data for sub" + subNumber + " (" + subToMdr(subNumber) + ")");
        }
}