Page 1 of 2
lul' I can has header XD
Posted: Sun Feb 17, 2008 7:58 am
by JacksonCougar
With plenty of annoying question towards SuperModder911, and some more towards DeToX I figured out how to get my app to read, and display the header information ;p
The only ones I know are right are the head, foot, MapName, and ScenarioPath XD
Code for teh shits in giggle:
Code: Select all
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace CougarTest
{
public class Map
{
private mapHeader _header;
public mapHeader Header
{
get { return _header; }
set { _header = value; }
}
public Map(string FileName)
{
FileStream fs = new FileStream(FileName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
this.Header = new mapHeader(br);
}
}
public class mapHeader
{
public char[] head;
public int version;
public int filesize;
public int zero;
public int indexOffset;
public int metaStart;
public int unknown;
public char[] mapOrigin;
public byte[]unknown1;
public char[] build;
public byte[] unknown2;
public int unknown3;
public int offsetToStrangeFileStrings;
public int unknown4;
public int offsetToSomething;
public int scriptReferenceCount;
public int sizeOfScriptReference;
public int offsetToScriptReferenceIndex;
public int offsetToScriptReferenceStrings;
public byte[] unknown5;
public char[] mapName;
public int zero1;
public char[] scenarioPath;
public byte[] zero2;
public int unknown6;
public int fileCount;
public int fileTableOffset;
public int fileTableSize;
public int filesIndex;
public int signature;
public byte[] zero3;
public char[] foot;
public mapHeader(BinaryReader br)
{
br.BaseStream.Position = 0;
this.head = System.Text.UnicodeEncoding.UTF8.GetChars(br.ReadBytes(4));
this.version = br.ReadInt32();
this.filesize = br.ReadInt32();
this.zero = br.ReadInt32();
this.indexOffset = br.ReadInt32();
this.metaStart = br.ReadInt32();
this.unknown = br.ReadInt32();
this.mapOrigin = System.Text.UnicodeEncoding.UTF8.GetChars(br.ReadBytes(32));
this.unknown1 = br.ReadBytes(224);
this.build = System.Text.UnicodeEncoding.UTF8.GetChars(br.ReadBytes(32));
this.unknown2 = br.ReadBytes(20);
this.unknown3 = br.ReadInt32();
this.offsetToStrangeFileStrings = br.ReadInt32();
this.unknown4 = br.ReadInt32();
this.offsetToSomething = br.ReadInt32();
this.scriptReferenceCount = br.ReadInt32();
this.sizeOfScriptReference = br.ReadInt32();
this.offsetToScriptReferenceIndex = br.ReadInt32();
this.offsetToScriptReferenceStrings = br.ReadInt32();
this.unknown5 = br.ReadBytes(36);
br.BaseStream.Position = 408;
this.mapName = System.Text.UnicodeEncoding.UTF8.GetChars(br.ReadBytes(32));
this.zero1 = br.ReadInt32();
br.BaseStream.Position = 444;
this.scenarioPath = System.Text.UnicodeEncoding.UTF8.GetChars(br.ReadBytes(64));
this.zero2 = br.ReadBytes(192);
this.unknown6 = br.ReadInt32();
this.fileCount = br.ReadInt32();
this.fileTableOffset = br.ReadInt32();
this.fileTableSize = br.ReadInt32();
this.filesIndex = br.ReadInt32();
this.signature = br.ReadInt32();
this.zero3 = br.ReadBytes(1320);
this.foot = System.Text.UnicodeEncoding.UTF8.GetChars(br.ReadBytes(4));
}
}
}
lul' I can has header XD
Posted: Sun Feb 17, 2008 3:17 pm
by Grimdoomer
I belive its IndexOffset, then IndexSize?!? and for the mapname, scenario and buiddate use this,
Code: Select all
chat TempChar;
while ((TempChar = BR.ReadChar) != '\0')
MapName += TempChar;
It will only read the decodable characters.
Other then that looks great

lul' I can has header XD
Posted: Sun Feb 17, 2008 5:22 pm
by OwnZ joO
Grim, his way is better, and your way doesn't make it only read decodable characters, it just waits for a termination character. Also yours is not as good because strings are immutable and += many times is a performance bottleneck. The only other way I might recommend doing it, which the way he did already was fine and probably better in this case, is
Code: Select all
new string(br.ReadChars(36)).trim();
lul' I can has header XD
Posted: Sun Feb 17, 2008 5:33 pm
by JacksonCougar
I guess posting the code that outputs the values could have cleared that up ;p
Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace CougarTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"My Documents";
ofd.Filter = "Halo 2 Map (.map)|*.map";
if(ofd.ShowDialog() == DialogResult.OK)
{
this.Enabled = false;
Map map = new Map(ofd.FileName);
string headerHead = string.Format("Head: {0}", new string(map.Header.head));
string headerVersion = string.Format("Version: {0}", map.Header.version);
string headerIndexOffset = string.Format("IndexOffset: {0}", map.Header.indexOffset);
string headerMetaStart = string.Format("MetaStart: {0}", map.Header.metaStart);
string headerMapOrigin = string.Format("MapOrigin: {0}", new string(map.Header.mapOrigin)).Replace("\0", "");
string headerBuild = string.Format("Build: {0}", new string(map.Header.build)).Replace("\0", ""); ;
string headerOTSFS = string.Format("OTSFS: {0}", map.Header.offsetToStrangeFileStrings);
string headerOTS = string.Format("OTS: {0}", map.Header.offsetToSomething);
string headerSRC = string.Format("SRC: {0}", map.Header.scriptReferenceCount);
string headerSOSR = string.Format("SOSR: {0}", map.Header.sizeOfScriptReference);
string headerOTSRI = string.Format("OTSRI: {0}", map.Header.offsetToScriptReferenceIndex);
string headerOTSRS = string.Format("OTSRS: {0}", map.Header.offsetToScriptReferenceStrings);
string headerMapName = string.Format("MapName: {0}", new string(map.Header.mapName)).Replace("\0", ""); ;
string headerScenarioPath = string.Format("ScenarioPath: {0}", new string(map.Header.scenarioPath)).Replace("\0", ""); ;
string headerFileCount = string.Format("FileCount: {0}", map.Header.fileCount);
string headerFileTableOffset = string.Format("FileTableOffset: {0}", map.Header.fileTableOffset);
string headerFileTableSize = string.Format("FileTableSize: {0}", map.Header.fileTableSize);
string headerFilesIndex = string.Format("FilesIndex: {0}", map.Header.filesIndex);
string headerSignature = string.Format("Signature: {0}", map.Header.signature);
string headerFoot = string.Format("Foot: {0}", new string(map.Header.foot)).Replace("\0", "");
this.Text = string.Format("{0}: {1}", "Reader", headerMapName).Replace("MapName:", "");
this.richTextBox1.Text = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n{9}\n{10}\n{11}\n{12}\n{13}\n{14}\n{15}\n{16}\n{17}\n{18}\n{19}", headerHead, headerVersion, headerIndexOffset, headerMetaStart, headerMapOrigin, headerBuild, headerOTSFS, headerOTS, headerSRC, headerSOSR, headerOTSRI, headerOTSRS, headerMapName, headerScenarioPath, headerFileCount, headerFileTableOffset, headerFileTableSize, headerFilesIndex, headerSignature, headerFoot);
this.Enabled = true;
}
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("For experimenting with the Halo 2 map file");
}
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Yes please!");
}
private void button1_Click(object sender, EventArgs e)
{
/*Map.mapHeader mapHeader = new Map.mapHeader();
BinaryReader br = new BinaryReader(File.Open(ofd.FileName, FileMode.Open));
MessageBox.Show(new string(br.ReadBytes(mapHeader.head)));*/
}
private void button1_Click_1(object sender, EventArgs e)
{
Application.Exit();
}
}
}
lul' I can has header XD
Posted: Sun Feb 17, 2008 5:37 pm
by Aumaan Anubis
JacksonCougar wrote:Code: Select all
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Yes please!");
}
XD
lul' I can has header XD
Posted: Sun Feb 17, 2008 5:58 pm
by Grimdoomer
OwnZ joO wrote:Grim, his way is better, and your way doesn't make it only read decodable characters, it just waits for a termination character. Also yours is not as good because strings are immutable and += many times is a performance bottleneck. The only other way I might recommend doing it, which the way he did already was fine and probably better in this case, is
Code: Select all
new string(br.ReadChars(36)).trim();
Yes but if you have numbers behind the string befor the 32nd character, you could get an exception, easy to fix but just saying.
lul' I can has header XD
Posted: Sun Feb 17, 2008 6:12 pm
by JacksonCougar
Code: Select all
string headerMapOrigin = string.Format("MapOrigin: {0}", new string(map.Header.mapOrigin)).Replace("\0", "");
Also its nice to know that a char is 7bits >_<
lul' I can has header XD
Posted: Sun Feb 17, 2008 6:27 pm
by NotZachary82
Aumaan Anubis wrote:JacksonCougar wrote:Code: Select all
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Yes please!");
}
XD
lol
lul' I can has header XD
Posted: Sun Feb 17, 2008 7:33 pm
by XZodia
you should see my header reader code >_>
it looks crazy but works like a dream XD
except for somre reason the sbsp didn't seem to like my primary magic...
sbsp offsets are got from: raw offset - primary magic
yes/no?
lul' I can has header XD
Posted: Sun Feb 17, 2008 10:27 pm
by Supermodder911
Jackson you didn't need to declare new strings in your form...
You Could simply call it like...
lul' I can has header XD
Posted: Mon Feb 18, 2008 6:01 am
by JacksonCougar
Oh... yea... I was writing this code at 3:00am...
But when I started to code, yes I did need to declare new strings ;p
lul' I can has header XD
Posted: Mon Feb 18, 2008 6:11 am
by OwnZ joO
Grimdoomer wrote:OwnZ joO wrote:Grim, his way is better, and your way doesn't make it only read decodable characters, it just waits for a termination character. Also yours is not as good because strings are immutable and += many times is a performance bottleneck. The only other way I might recommend doing it, which the way he did already was fine and probably better in this case, is
Code: Select all
new string(br.ReadChars(36)).trim();
Yes but if you have numbers behind the string befor the 32nd character, you could get an exception, easy to fix but just saying.
Did I not say the way he did it was fine/probably better???
lul' I can has header XD
Posted: Mon Feb 18, 2008 7:43 am
by Supermodder911
OwnZ joO wrote:Grimdoomer wrote:OwnZ joO wrote:Grim, his way is better, and your way doesn't make it only read decodable characters, it just waits for a termination character. Also yours is not as good because strings are immutable and += many times is a performance bottleneck. The only other way I might recommend doing it, which the way he did already was fine and probably better in this case, is
Code: Select all
new string(br.ReadChars(36)).trim();
Yes but if you have numbers behind the string befor the 32nd character, you could get an exception, easy to fix but just saying.
Did I not say the way he did it was fine/probably better???
:p
lul' I can has header XD
Posted: Mon Feb 18, 2008 8:31 pm
by Prey
Lets clear a few things up here.. on holiday for 2 days and having to clear things up already.. =x
Reading strings...
Jack's way > Grim's way, as has been said.. although the best way would just be to read a char, stop if it's null, add to a StringBuilder if it's not, and stop once specified length is reached.. at least that's how I do it..
xzodia ,sbsp offsets are obtained from within the scnr meta..
Jack remember to close your fileStream, do it via the BinaryReader..
and after, refactor your code!.. I dislike it...
lul' I can has header XD
Posted: Mon Feb 18, 2008 11:24 pm
by XZodia
Prey wrote:xzodia ,sbsp offsets are obtained from within the scnr meta..
I was talking about calculating reflexive offsets not the start of the sbsp......although come to think of it I never fixed the start offsets >_<
lul' I can has header XD
Posted: Tue Feb 19, 2008 5:20 am
by JacksonCougar
Code: Select all
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex != -1)
{
int index = map.FindIndexNumber("shad", listBox1.SelectedItem.ToString());
map.OpenIO();
map.br.BaseStream.Position = (map.IndexItems[index].Offset + 32); //Start reading offset 32 of the shader tag ;p.
int chunkCount_1 = map.br.ReadInt32();//Read int32, this is chunk count//first chunk count.
int chunkOffset_1 = map.br.ReadInt32() - map.SecondaryMagic;//calculate some number from another int32 after the first one ;p
int chunkPointer_1 = chunkCount_1;
if (chunkCount_1 == 1)
{
chunkPointer_1 = chunkOffset_1;
}
else if (chunkCount_1 > 1)
{
chunkPointer_1 = ((chunkCount_1 * 124) + chunkOffset_1);
}
else
{
MessageBox.Show("Error - Chunk Size wrong, just very very wrong...");
}
map.br.BaseStream.Position = (chunkPointer_1 + 60);//why s this doubled?
int w = map.br.ReadInt32();// read chunk #... function
if (w > 0)
{
comboBox1.Enabled = true;
comboBox1.Items.Clear();
for (int i = 0; i < w; i++)
{
string chunklist = string.Format("{0} {1}", "Chunk:", i);// lols ;p
comboBox1.Items.Add(chunklist);
}
comboBox1.Text = "Chunk: 0";
textBox1.Enabled = true;
textBox2.Enabled = true;
textBox3.Enabled = true;
textBox4.Enabled = true;
textBox5.Enabled = true;
textBox6.Enabled = true;
textBox7.Enabled = true;
textBox8.Enabled = true;
textBox9.Enabled = true;
}
else if (w == 0)
{
comboBox1.Enabled = false;
comboBox1.Text = "";
textBox1.Enabled = false;
textBox2.Enabled = false;
textBox3.Enabled = false;
textBox4.Enabled = false;
textBox5.Enabled = false;
textBox6.Enabled = false;
textBox7.Enabled = false;
textBox8.Enabled = false;
textBox9.Enabled = false;
}
else
{
MessageBox.Show("Your map is probably corrupt...");
}
//new ref
map.br.BaseStream.Position = (chunkPointer_1 + 60);//dwd2w
int chunkCount_2 = map.br.ReadInt32();
int chunkOffset_2 = (map.br.ReadInt32() - map.SecondaryMagic);
int chunkPointer_2 = chunkCount_2; // wtf... I think this is my test line ;p
if (chunkCount_2 == 1)//false
{
chunkPointer_2 = chunkOffset_2;
}
else if (chunkCount_2 > 1)//true
{
chunkPointer_2 = ((chunkCount_2 * 1) + chunkOffset_2);
}
else
{
MessageBox.Show("Error - Chunk Size wrong, just very very wrong...");
}
map.br.BaseStream.Position = (chunkPointer_2 + 12);
int q = map.br.ReadInt32();
if (q > 0)
{
}
else if (q == 0)
{
}
else
{
MessageBox.Show(q.ToString());
}
richTextBox1.Text = q.ToString();
map.CloseIO();
}
}
}
Had more help; got further. But now it won't read the second reflexive right :S
This bit here is where the problem is; it does not calculate the second chunk size properly

lul' I can has header XD
Posted: Tue Feb 19, 2008 2:42 pm
by XZodia
thats the biggest load of garbage i've ever seen
Code: Select all
if (chunkCount_2 == 1)//false
{
chunkPointer_2 = chunkOffset_2;
}
else if (chunkCount_2 > 1)//true
{
chunkPointer_2 = ((chunkCount_2 * 1) + chunkOffset_2);
}
wat is that even for?
and why are you multiplying by 1?
Code: Select all
int chunkCount_2 = map.br.ReadInt32();
int chunkOffset_2 = (map.br.ReadInt32() - map.SecondaryMagic);
thats all you need to get the offset of the 1st chunk and the chunk count
lul' I can has header XD
Posted: Tue Feb 19, 2008 3:01 pm
by JacksonCougar
*Hides*
"DeToX told me to do it...mb..."
lul' I can has header XD
Posted: Tue Feb 19, 2008 3:03 pm
by JacksonCougar
DP sue me;
Um; it should be getting multiplied my 60 on that second one, not 1.
Also I used the if, if else, if statement because thats how my mind work, and nobody told be how to do it another way o.o
Finally it really should work but it simply does not find the third chunk size >_<
lul' I can has header XD
Posted: Tue Feb 19, 2008 5:12 pm
by XZodia
what are you trying to do?
lul' I can has header XD
Posted: Tue Feb 19, 2008 7:09 pm
by JacksonCougar
Read the shader effects reflexive, mainly the nested reflexive within that reflexive though ;p
lul' I can has header XD
Posted: Tue Feb 19, 2008 7:28 pm
by XZodia
then y do u seem to be trying to calculate the chunk size

lul' I can has header XD
Posted: Wed Feb 20, 2008 4:12 pm
by Prey
xzodia, each bsp has a different magic as their meta is located in a different part of the map from everything else.. can't remember where or how you get the magic's exactly though, my mind is full of Halo 3 stuff.. just decompile my Prophet source or something..
..didn't fully read through your code Jack, but remember that chunk sizes are not stored within the map file.. only the count of chunks in a reflexive, and a pointer to the first chunk, are..
lul' I can has header XD
Posted: Wed Feb 20, 2008 9:58 pm
by Supermodder911
Prey wrote:xzodia, each bsp has a different magic as their meta is located in a different part of the map from everything else.. can't remember where or how you get the magic's exactly though, my mind is full of Halo 3 stuff.. just decompile my Prophet source or something..
..didn't fully read through your code Jack, but remember that chunk sizes are not stored within the map file.. only the count of chunks in a reflexive, and a pointer to the first chunk, are..
Code: Select all
Chunkpointers: (ChunkNumber * ReflexiveSize) + Translation
I think...?
Re: lul' I can has header XD
Posted: Thu Feb 21, 2008 4:48 pm
by Prey
Yeah.. only it's the size of the chunk, not the entire reflexive.. although I guess you probably meant that.
Code: Select all
OffsetOfChunk = Translation + (ChunkIndex * ChunkSize)