Rev 521 |
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
;
private int codePage =
1252;
protected void print
() {
while (reader.
position() < filelen
) {
printBlock
();
}
}
private void printBlock
() {
byte bid = peek
();
switch (bid
) {
case 0x42:
// B
printOverviewBlock
();
break;
case 0x44:
// D
printCopyrightBlock
();
break;
case 0x4c:
// L
printDetailBlock
();
break;
case 0x50:
// P
printHeaderBlock
();
break;
case 0x54:
// T
printTBlock
();
break;
case 0x52:
// R
printRBlock
();
break;
case 0x53:
// S
printSBlock
();
break;
default:
printUnknown
();
break;
}
}
private void printSBlock
() {
Displayer d =
new Displayer
(reader
);
String text =
"Region block";
d.
setTitle(text
);
int len = blockId
(d, text
);
long end = reader.
position() + len
;
while (reader.
position() < end
) {
d.
byteValue("Region %d?");
d.
byteValue("Subregion %d");
d.
zstringValue("name: %s");
}
d.
print(outStream
);
outStream.
flush();
}
private void printRBlock
() {
Displayer d =
new Displayer
(reader
);
String text =
"Area block";
d.
setTitle(text
);
blockId
(d, text
);
d.
byteValue("region %d");
d.
zstringValue("name: %s");
d.
print(outStream
);
outStream.
flush();
}
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");
codePage = 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");
int count =
1;
d.
intValue("file" + count++ +
" size %d");
d.
intValue("file" + count++ +
" size %d");
d.
intValue("file" + count++ +
" size %d");
if (n
> 3) d.
intValue("file" + count++ +
" size %d");
if (n
> 4) d.
intValue("file" + count++ +
" size %d");
if (n
> 5) d.
intValue("file" + count++ +
" size %d");
if (n
> 6) d.
intValue("file" + count +
" size %d");
if (len
> 66) {
//d.rawValue(7, "intro");
d.
byteValue("detail unk1 %d");
d.
byteValue("region %d?");
d.
byteValue("subregion %d");
d.
intValue("?size %d");
count =
1;
d.
zstringValue("file" + count++ +
" %s");
d.
zstringValue("file" + count++ +
" %s");
d.
zstringValue("file" + count++ +
" %s");
if (n
> 3) d.
zstringValue("file" + count++ +
" %s");
if (n
> 4) d.
zstringValue("file" + count++ +
" %s");
if (n
> 5) d.
zstringValue("file" + count++ +
" %s");
if (n
> 6) d.
zstringValue("file" + count +
" %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
);
}
double toDegrees
(int tdbUnits
) {
return tdbUnits
* 45.0 /
(1 << 29);
}
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.
intItem();
double n = toDegrees
(item.
getValue());
item.
addText("North %.7f",
(n
));
item = d.
intItem();
double e = toDegrees
(item.
getValue());
item.
addText("East %.7f",
(e
));
item = d.
intItem();
double s = toDegrees
(item.
getValue());
item.
addText("South %.7f",
(s
));
item = d.
intItem();
double w = toDegrees
(item.
getValue());
item.
addText("West %.7f",
(w
));
d.
item().
addText("Area %f",
(n - s
) * (e-w
));
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");
long end = reader.
position() + len
;
while (reader.
position() < end
) {
d.
byteValue("~");
d.
byteValue("~");
d.
charValue("~");
d.
zstringValue("text %s",
"cp" + codePage
).
length();
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 +
" %c");
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]);
}
}