Depending on how good of a programer, and in what language, can play a huge role in weather you use Visual Basic (VB) or Visual C# (C#). If you have never done any kind of programing befor, I would suggest starting with VB. If you have done programing befor but never done C# I would still recomend VB, but if you have done C# then you should stick with that. Once you have decided weather your are going to use VB or C# please continue to the next step.
2)Gathering Utilities
Visual Basic, Visual C# - Download Page
Once you have downloaded and installed VB or C# please proced to the Planning section
3)Planning
Here is where your Halo 2 App Comes to life. Firts we need to have a purpose for this app, most of you have allready thought of that. Please for the sake of god, DO NOT make a map resigner, pretty much every app has a built in one and there are many more scattered around. Secound you must think about how your app will look and added features. If your app will be used a lot like Entity, you might not want a white backround. If your up at 3 in the morning dead tired it will hurt your eyes so much and its bad for you. Here is a sample of a UI I designed:

As you can see its very dark, but light enough that you can read the text fine. Next Button layout, you defenity don want a million buttons or a million sidebars with dropdown boxes. I would suggest if you are making a lot of features, to use a hide/unhide system like Entity has with RAW data. This will save space and keep everything organized. Also send some samples of running beta's to your friends, I sent the beta of my app to about 10 people to get there opion. They liked it so I kept it. But dont change somehting just because one person doesent like it, if you like it then keep it. Now if your app will take longer then a day to make, dont tell people about it. Prometheus is an example, it has been in development for I think 2 years now, and still no public release other than a beta. It will defently be a kickass programe, but some people are very impatient and get angry, these people are know as Tarts. They have no idea what it takes to make good apps and why it takes so long so they bitch because they dont understand why it takes a while.
3)Design
Lets start with simple button features. On your main form, you dont want a million small things taking up space. Instead make the smaller things there own form, or put them all in one form depending on what they are/do. Here is some simple code that displays a new form when button1 is clicked:
Code: Select all
VB
Private Sub btnForm2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnForm2.Click
        Form2.Show()
    End Sub
You might want to put exstensions infront of the name of your form objects. If I have a textbox for the name of the map I would name it btnMapName for button Map Name. This helps you to not get confused with other form objects.
TabControls - Tab Controls are good if you are limeted to space and need to display information on mutiple things. But one of the bad things is there disabled state. It will disable everything on that tab, wich looks horible. Instead use TabControl1.Hide() untile needed, it will hide the tab so you cant see it, then when needed use TabControl1.Show().
4)Coding
Variables - A variable is a chunk of memery that contins information such as the name of something or numbers. There are a cuple diffrent ways to declear variables and many diffrent types of variables.
Constants - A Constant is a variable that has a set value and will never change. You must declear a Constant befor any subs in your class:
Code: Select all
VB
Public Class Form2
    Const MyAge As Integer = 14
End ClassCode: Select all
C#
class myclass1
    {
        const int myinteger = 14;
    }Code: Select all
VB
Public Class Form2
    Dim MyAge As Integer
End ClassCode: Select all
C#
class myclass1
    {
        private int myinteger;
    }Code: Select all
VB
Public Class Form2
    Public MyAge As Integer
End ClassCode: Select all
C#
class myclass1
    {
        public int myinteger;
    }Code: Select all
VB
Public Class Form2
    Public MyAge As Integer = 14
End ClassCode: Select all
C#
class myclass1
    {
        public int myinteger = 14;
    }Variable Types
Decimal - dec - Decimal
Short - srt - 16 bit integers
Long - lng - 64 bit integers
Integer - int - 32 bit integers
String - str - more than one letter
Char - chr - one letter
Byte - byt - byte
Boolean - bln - True or False
There are more but there not that important.
Binary Reading and Writing - Binary Readers/Writes are what reads and write info to and from the halo 2 map or any other file. Once you understand when to use a Binary Reader/Write and XML, it will help you make process much easer. To open a Binary Reader you need one thing, the location of the file you are opening. This is done like so:
Code: Select all
VB
Dim MapLocation As String
Dim BR As New BinaryReader(New FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read))Code: Select all
C#
string MapLocation
BinaryReader BR = new BinaryReader(new FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read));Code: Select all
VB
BR.BaseStream.Position = 2Code: Select all
C#
BR.BaseStream.Position = 2;Code: Select all
VB
Imports System.IO
Public Class Form1
    Private Sub btnForm2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnForm2.Click
        Dim MapLocation As String
        Dim MapName As String
        Dim BR As New BinaryReader(New FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read))
        BR.BaseStream.Position = 408
        MapName = BR.ReadChars(20)
        BR.Close()
    End Sub
End ClassCode: Select all
C#
using System.IO;
public void Read()
{
      string MapLocation;
      string MapName;
      BinaryReader BR = new BinaryReader(new FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read));
      BR.BaseStream.Poistion = 408;
      MapName = BR.ReadChars(20);
      BR.Close();
}Code: Select all
Dim BR As New BinaryReader(New FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read))Code: Select all
BR.BaseStream.Position = 408
        MapName = BR.ReadChars(20)Code: Select all
MapName = BR.ReadChars(20)BinaryWriters - BinaryWriters are almost the same as Binary Readers except to decleare a new BinaryWriter you would use FileAcsess.Write, FileShare.Write instead of .Read. When writing information you would want to use this:
Code: Select all
BW.Write(MapName)Code: Select all
BW.Write(MapName);Classes - A Class is a blank code page that you can use to do what ever you want. Classes will become your best friend soon.
Message Boxes
A Message box is a little window that pops up and displays anything you want it to. Here is how you would display a message box when a button is pressed:
Code: Select all
VB
Private Sub btnForm2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnForm2.Click
        MsgBox("Hi")
    End SubCode: Select all
 public void Button1_click()
{
    MessageBox.Show("Hi");
}
You can also customize you message box to change the headline, make it an information box or criticle error box:
Code: Select all
Private Sub btnForm2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnForm2.Click
        MsgBox("Hi", MsgBoxStyle.Critical, "Error")
    End Sub
The formula for message boxes is
Code: Select all
VB
msgbox("Headline Text", MessageBoxStyle, "Form Text")Code: Select all
C#
MessageBox.Show("Headline Text", MessageBox Style, "Form Text");The If, Then statment does exactly what you would guess. Here is an example:
Code: Select all
VB
Dim TagSelected As Boolean
        If TagSelected = False Then
            MsgBox("Select a Tag first!", MsgBoxStyle.Critical, "Error")
        End IfCode: Select all
C#
{ 
    bool TagSelected; 
    if (TagSelected == false) { 
        Interaction.MsgBox("Select a Tag first!", MsgBoxStyle.Critical, "Error"); 
    } 
} ElseIf Command to start another If, Then statement:
Code: Select all
VB
Dim TagSelected As Boolean = False
        If TagSelected = False Then
            MsgBox("Select a Tag first!", MsgBoxStyle.Critical, "Error")
        ElseIf TagSelected = True Then
            LoadDependancys()
        End IfCode: Select all
C#
{ 
    bool TagSelected = false; 
    if (TagSelected == false) { 
        Interaction.MsgBox("Select a Tag first!", MsgBoxStyle.Critical, "Error"); 
    } 
    else if (TagSelected == true) { 
        LoadDependancys(); 
    } 
} Code: Select all
VB
Dim Number As Integer
        If Number = 1 Then
            MsgBox("1")
        Else
            MsgBox("Not Number 1")
        End IfCode: Select all
C#
{ 
    int Number; 
    if (Number == 1) { 
        Interaction.MsgBox("1"); 
    } 
    else { 
        Interaction.MsgBox("Not Number 1"); 
    } 
} The Case Select statment is for detriming the value of something that could have many values:
Code: Select all
VB
Dim Number As Integer
        Select Case Number
            Case Is = 0
                MsgBox("0")
            Case Is = 1
                MsgBox("1")
            Case Is = 2
                MsgBox("2")
            Case Is = 3
                MsgBox("3")
            Case Is = 4
                MsgBox("4")
            Case Is = 5
                MsgBox("5")
        End SelectCode: Select all
C#
{ 
    int Number; 
    switch (Number) { 
        case 0: 
            Interaction.MsgBox("0"); 
            break; 
        case 1: 
            Interaction.MsgBox("1"); 
            break; 
        case 2: 
            Interaction.MsgBox("2"); 
            break; 
        case 3: 
            Interaction.MsgBox("3"); 
            break; 
        case 4: 
            Interaction.MsgBox("4"); 
            break; 
        case 5: 
            Interaction.MsgBox("5"); 
            break; 
    } 
} 5)Coding For Exceptions
Now if you have ever used Entity you will notice it is fairly easy to get an exception. This can easy be bypassed by coding errors for the exception. Lets say you have a map open, you dont have any tags selected and you hit the dependancy's button. Normally a null refrence exception would be thrown, but you could easly change this by coding an error for it. Now most errors would be displayed in a message box. Lets say I have a boolean(True or False) for TagSelected, and if its null and I click the dependacy's button and TagSelected is false, a null refrence exception would be thrown. Heres an example on how to fix this.
Code: Select all
VB
Private Sub btnForm2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnForm2.Click
        Dim TagSelected As Boolean
        If TagSelected = False Then
            MsgBox("Select a Tag first!", MsgBoxStyle.Critical, "Error")
        ElseIf TagSelected = True Then
            ReadDependancys()
        End If
    End SubCode: Select all
C#
private void btnForm2_Click(object sender, System.EventArgs e) 
{ 
    bool TagSelected; 
    if (TagSelected == false) { 
        Interaction.MsgBox("Select a Tag first!", MsgBoxStyle.Critical, "Error"); 
    } 
    else if (TagSelected == true) { 
        ReadDependancys(); 
    } 
} 
5)Coding For Halo 2
Now that you have learned what coding is all about, you are ready to start coding for halo 2.
Map Structure
Thanks to -DeToX- for this.
Halo 2 Map Structure by -DeToX-
Index - Element Name - Type
_____________________________
0 Map Header Table
1 Sound Raw Raw
2 Model Raw 1&2 Raw
-----------------------------
3 BSP 1 Raw 1
4 BSP 2 Raw 2
5 LightMap Raw
6 BSP 3 Raw 3
7 BSP 4 Raw 4
-----------------------------
8 Decorator Raw
9 Weather Raw
10 Particle Model Raw
11 Collision Raw
12 Animation Raw
-----------------------------
13 BSP Meta
14 LightMap Meta
-----------------------------
15 StringID128 Table
16 StringID Index Table
17 StringID Table Table
18 FileTabel Table
19 FileIndex Table
20 Unicode Index Table
21 ugh! (crazy) Raw
22 Unicode Table
23 Bitmap Raw
24 Index Header Table
25 Metas Meta
26 Padding Padding
------------------------------
sorry abount the spacing cant fix it.
Header
The Header is the very beginning of the file. For Halo 2 the Header is 1024 byts if I remember correctly. In the Header for Halo 2 you will find Map name, Map scenario, Map build, and a lot of info for the tags and string ID's. Now that you know your basics in coding, im going to be very brief about simple stuff, but I will explain what it does.
First create a new project in VB or VC#. Now im going to use a fairly poor meathod as the better meathod takes to long to go through. Add a new class to your project called Halo 2 Map. It should look like this:
Code: Select all
VB
Imports System.IO
Public Class EntReader
End ClassCode: Select all
 C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Visual_Marker_Placement_Tool.Halo_2
{
    class ModelMeta
    {
    }
}
Code: Select all
VB
Imports System.IO
Public Class Halo_2_Map
    Public Structure Halo_2_Map
    End Structure
    Public Structure H2Tag
    End Structure
End ClassCode: Select all
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Programing_For_Halo_2
{
    class Halo_2_Map
    {
        public struct Halo_2_Map
        {
        }
        public struct H2Tag
        {
        }
    }
}
Code: Select all
VB
'Header Info
        Public MapLocation As String
        Public MapName As String
        Public MapScenario As String
        Public MapBuild As String
        Public IndexOffset As Long
        Public IndexSize As Long
        Public MetaStart As Long
        Public MetaSize As Long
        Public FileTableCount As Long
        Public FileTableOffset As Long
        Public FileTableSize As Long
        Public FileTableIndexOffset As Long
        Public CrazyOffset As Long
        Public CrazySize As Long
        Public firstStringNamesOffset As Long
        Public scriptReferenceCount As Long
        Public scriptReferenceSize As Long
        Public scriptIndexOffset As Long
        Public secondStringNamesOffset As Long
C#
//Header info
            public string MapLocation;
            public string MapName;
            public string MapScenario;
            public string MapBuild;
            public long IndexOffset;
            public long IndexSize;
            public long MetaStart;
            public long MetaSize;
            public long FileTableCount;
            public long FileTableOffset;
            public long FileTableSize;
            public long FileTableIndexOffset;
            public long CrazyOffset;
            public long CrazySize;
            public long firstStringNamesOffset;
            public long scriptReferenceCount;
            public long scriptReferenceSize;
            public long scriptIndexOffset;
            public long secondStringNamesOffset;
Code: Select all
VB
Imports System.IO
Public Class Halo_2_Map
    Public Structure Halo_2_Map
        'Header Info
        Public MapLocation As String
        Public MapName As String
        Public MapScenario As String
        Public MapBuild As String
        Public IndexOffset As Long
        Public IndexSize As Long
        Public MetaStart As Long
        Public MetaSize As Long
        Public FileTableCount As Long
        Public FileTableOffset As Long
        Public FileTableSize As Long
        Public FileTableIndexOffset As Long
        Public CrazyOffset As Long
        Public CrazySize As Long
        Public firstStringNamesOffset As Long
        Public scriptReferenceCount As Long
        Public scriptReferenceSize As Long
        Public scriptIndexOffset As Long
        Public secondStringNamesOffset As Long
        Public Sub ReadHeader()
            Dim BR As New BinaryReader(New FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read))
        End Sub
    End Structure
    Public Structure H2Tag
        Public TagPath As String
        Public TagClass As String
        Public TagID As Long
        Public MetaOffset As Long
        Public MetaSize As Long
    End Structure
End Class
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Programing_For_Halo_2
{
    class Halo_2_Map
    {
        public struct Halo2Map
        {
            //Header info
            public string MapLocation;
            public string MapName;
            public string MapScenario;
            public string MapBuild;
            public long IndexOffset;
            public long IndexSize;
            public long MetaStart;
            public long MetaSize;
            public long FileTableCount;
            public long FileTableOffset;
            public long FileTableSize;
            public long FileTableIndexOffset;
            public long CrazyOffset;
            public long CrazySize;
            public long firstStringNamesOffset;
            public long scriptReferenceCount;
            public long scriptReferenceSize;
            public long scriptIndexOffset;
            public long secondStringNamesOffset;
            public void ReadHeader()
            {
                BinaryReader BR = new BinaryReader(new FileStream(MapLocation, FileMode.Open, FileAccess.Read, FileShare.Read));
            }
        }
        public struct H2Tag
        {
            public string TagClass;
            public string TagPath;
            public long TagID;
            public long MetaOffset;
            public long MetaSize;
        }
    }
}
Code: Select all
VB
       'Go to the header start
            BR.BaseStream.Position = 16
            'Read The IndexOffset
            IndexOffset = BR.ReadInt32()
            'Read our IndexSize
            IndexSize = BR.ReadInt32()
            'Read Our MetaSize and MetaStart
            MetaSize = BR.ReadInt32()
            MetaStart = BR.ReadInt32()
            BR.BaseStream.Position = 288
            'Read the MapBuild
            MapBuild = BR.ReadChars(20)
            BR.BaseStream.Position = 344
            'Read the CrazyOffset and CrazySize
            CrazyOffset = BR.ReadInt32()
            CrazySize = BR.ReadInt32()
            'string ID stuff
            BR.BaseStream.Position = 352
            firstStringNamesOffset = BR.ReadInt32() '352 
            scriptReferenceCount = BR.ReadInt32() '356 
            scriptReferenceSize = BR.ReadInt32() '360 
            scriptIndexOffset = BR.ReadInt32() '364 
            secondStringNamesOffset = BR.ReadInt32() '368 
            BR.BaseStream.Position = 408
            'Read the MapName
            MapName = BR.ReadChars(20)
            BR.BaseStream.Position = 444
            'Read the MapScenario
            MapScenario = BR.ReadChars(80)
            BR.BaseStream.Position = 704
            'Read the FileTableOffset
            FileTableCount = BR.ReadInt32()
            FileTableOffset = BR.ReadInt32()
            FileTableSize = BR.ReadInt32()
            FileTableIndexOffset = BR.ReadInt32()
            BR.Close()
C#----------------------------
    char chr;
                //Go to the header start 
                BR.BaseStream.Position = 16;
                //Read The IndexOffset - start of the index 
                IndexOffset = BR.ReadInt32();
                //Read our IndexSize - size of the index 
                IndexSize = BR.ReadInt32();
                //Read Our MetaSize and MetaStart - meta for the tags 
                MetaSize = BR.ReadInt32();
                MetaStart = BR.ReadInt32();
                BR.BaseStream.Position = 288;
                //MapBuild
                MapBuild = "";
                while ((chr = BR.ReadChar()) != '\0')
                    MapBuild += chr;
                BR.BaseStream.Position = 344;
                //Read the CrazyOffset and CrazySize - size of the crazy raw 
                CrazyOffset = BR.ReadInt32();
                CrazySize = BR.ReadInt32();
              
                //string ID stuff 
                BR.BaseStream.Position = 352;
                firstStringNamesOffset = BR.ReadInt32();
                //352 
                scriptReferenceCount = BR.ReadInt32();
                //356 
                scriptReferenceSize = BR.ReadInt32();
                //360 
                scriptIndexOffset = BR.ReadInt32();
                //364 
                secondStringNamesOffset = BR.ReadInt32();
                //368 
                
                BR.BaseStream.Position = 408;
                //MapName
                MapName = "";
                while ((chr = BR.ReadChar()) != '\0')
                    MapName += chr;
                BR.BaseStream.Position = 444;
                //MapScenario
                MapScenario = "";
                while ((chr = BR.ReadChar()) != '\0')
                    MapScenario += chr;
                BR.BaseStream.Position = 708;
                //FileTable - tags strings etc
                FileTableCount = BR.ReadInt32();
                FileTableOffset = BR.ReadInt32();
                FileTableSize = BR.ReadInt32();
                FileTableIndexOffset = BR.ReadInt32();
                BR.Close();Code: Select all
VB
'Index Info
Public PrimaryMagicConstant As Long 
Public MapPrimaryMagic As Long 
Public SecondaryMagicConstant As Long 
Public MapSecondaryMagic As Long 
Public ObjectIndexOffset As Long 
Public ObjectIndexPointer As Long 
Public ObjectCount As Long 
C#
        public long PrimaryMagicConstant;
        public long MapPrimaryMagic;
        public long SecondaryMagicConstant;
        public long MapSecondaryMagic;
        public long ObjectIndexOffset;
        public long ObjectIndexPointer;
        public long ObjectCount;









 well I have only been using C# for one day but I still have a lot to learn. But thanks for pointing tat out. Ill fix it when I get home.
 well I have only been using C# for one day but I still have a lot to learn. But thanks for pointing tat out. Ill fix it when I get home.