Question Hex based templates > modifiable in ASCII > export Hex

Timbab

New member
Joined
Oct 31, 2013
Messages
1
Programming Experience
Beginner
Okay, I know only the very basics of VB, so bare with me please. I'm not here begging for others to do the work for me, but it would be fantastic if some of you could point me in the right directions. I'm a graphics guy, so this is fairly new territory for me.

I've been modifying a game (Star Wars Galaxies and yes, it's legal) over the past few years and in the recent days, after looking at terrain files, I've figured out a way frankenstein a really simple 'ghetto' terrain builder. The only problem, even though I know exactly what I need, I'm not sure how to exactly do it in VB.

To cut a long story short, this is what I'd like to do:

The game .trn files I can edit right now manually with a hex editor and an .iff file type editor that can display the contents of the .trn in a .iff like FORM/chunk node structure. The contents are displayed as hex.

Here are 2 examples of the two:

In a hex editor: http://i.imgur.com/SreJTj9.png
In the .iff type editor: http://i.imgur.com/xqhX109.png

Basically the terrain is generated in a procedural way (Patent about it, if anyone is curious), so really in the end, it's a bunch of the same file structures used over and over again, slightly modified depending on what it does, Boundary chunk structures for example have a DATA chunk that stores coordinates.

Now, here is the part I need to be able to create. I want to create a fairly simple program, where I can save these 'templates' in for each specific chunk structure (Shader Filter, Flora Constant, Boundary Constant, etc, but they all have the identical structure with a different DATA chunk and 2 of the FORM's are different), which I can pull from a drop down menu, that then lets me modify a couple of the key values, (like if you look in the hex editor screenshot, after the DATA chunk, you have 00 00 00 14 and then a 0D, which is 13, which is the flora ID) in a textbox as a regular decimal number, so instead of having to enter the correct hex value, if I wanted to change 0D, I'd type in 12, instead of 0C. There are also a couple of float values (that are in reverse, inside the file) that I would also want to have a modifier for.

After I'd be done editing the template, I'd be able to export it either directly at the end of the .trn, or simply a new file where I can copy the hex values from and add them in manually.

I hope this isn't too confusing and it is doable.

Basically summarize it shortly: Have a set of stored templates that I pulled from the hex values inside of my .trn inside of the program, be able to select a template, have modifiers for specific locations of the template, be able to export it as copyable hex values.



Could you guys point me in the right directions for something like this? I wouldn't ask if I wasn't under time pressure, I got a project coming up unrelated to this and wouldn't be able to do this/learn VB fully for a couple of months.



A more advanced version of that, would be to have a treeview of the chunk structures that you've created from the templates in the side, that let you rearrange the nodes, like in the .iff like editor in the screenshot.

Thanks so much in advance!
 
I'll go over a bit of basic background that you're probably already aware of but it will set the scene for an explanation of what you want to do.

Files are stored as a series of bytes, where a byte is an 8-bit number that can have a value in the range 0 to 255. A hex editor displays those bytes as hexadecimal numbers, which is convenient because each byte becomes a 2-digit number in the range 00 to FF.

When you read a file in .NET, you read the bytes. A Byte in .NET is an 8-bit number and, while they are physically stored in binary form, their default representation, just like all numeric types in .NET, is decimal. As such, your numbers are decimal by default and you actually have to do extra work to represent them in hexadecimal format.

Now, if you want to store these "templates" then you're basically going to be storing a series of bytes. The best way to do that depends on how they're going to be stored. You might choose to store each template in its own file, in which case you'd store the raw bytes. You could load and save a template with the File.ReadAllBytes and File.WriteAllBytes methods, which load and save a Byte array respectively. By using individual files you have the freedom to add and delete templates, but they are also easily accessible from outside the application, which may or may not be desirable. You might choose to store the templates in a database, which still allows freedom to add and delete but makes security a bit easier. If the number of templates is not going to change then you might store them in My.Settings or My.Resources. My.Settings will allow you to edit and save the templates while My.Resources would require a recompile to change them.

If you do choose to use My.Settings then I would suggest storing the data as a base-64 string. In that case, you can load the data into a Byte array like this:
Dim bytes As Byte() = Convert.FromBase64String(My.Settings.Data)
and save it like this:
My.Settings.Data = Convert.ToBase64String(bytes)
Regardless of the source, once you have a Byte array, you can index it to get any particular Byte. Like I said, its default format for display is decimal so, if you call ToString on a Byte, you get a String containing its decimal representation. Here's a code snippet that will display a Byte in decimal and hexadecimal format:
Private Sub DisplayByte(b As Byte)
    Dim dec = b.ToString()
    Dim hex = Convert.ToString(b, 16)

    MessageBox.Show(hex, dec)
End Sub
Note that that Convert.ToString method also works with bases 2, 8 and 10. There are a number of complementary methods that will convert from Strings in base 2, 8, 10 and 16 to numeric data types, e.g. Convert.ToByte. Here's a code snippet that contains methods to convert a Byte array to a series of decimal and hexadecimal numbers separated by spaces and back again:
Private Function ToDecimal(data As Byte()) As String
    Return String.Join(" ", data.Select(Function(b) b.ToString()))
End Function

Private Function FromDecimal(text As String) As Byte()
    Return text.Split(" "c).Select(Function(s) Convert.ToByte(s)).ToArray()
End Function

Private Function ToHexadecimal(data As Byte()) As String
    Return String.Join(" ", data.Select(Function(b) b.ToString("X2")))
End Function

Private Function FromHexadecimal(text As String) As Byte()
    Return text.Split(" "c).Select(Function(s) Convert.ToByte(s, 16)).ToArray()
End Function
Note that calling ToString on a Byte and passing "X2" as the format specifier will result in a 2-digit, upper-case, hexadecimal String. That code contains no validation so that's something to consider. That ToHexadecimal method would give you text that you could paste into a hex editor. You could even use the Clipboard class to copy to the Clipboard in code. The FromHexadecimal method would convert text that you copied from a hex editor.

Now, with regards to editing individual Bytes, I would suggest using a NumericUpDown control. You can configure it to only display valid Byte values, i.e. a range of 0 to 255 and no decimal places. It's Value property is type Decimal so you can assign a Byte directly and use CByte to get a value back. It provides buttons to scroll up and down through the range of values or you can type directly into it.

Hopefully that covers all the pieces and you can now just put them together in a way that suits you.
 
Back
Top