I can't seem to figure out what I did wrong
-
Friday, August 17, 2012 5:48 PM
Hello again!
I'm currently creating an application based on ideas from the game Minecraft; an application that lets you store step-by-step building instructions for a certain construction (trees (by this I mean those you find in forests)) to a file on your computer, so you can pick it back up later.
Here's the clue - the file I'm saving ranges from 197,179 bytes to 211,714 bytes (depending on the amount of steps ("layers") on the blueprint.
This file can be divided into 6 fundamental pieces:
- The first is the name of the project and ranges from byte 0 to 255 in the file.
- The second is the project's author name and ranges from byte 256 to 511.
- The third is a picture preview of the project and ranges from byte 512 to 197,119.
- The fourth is a "flag" byte determining the type of tree the we're talking about. 0 = Oak tree, 1 = Spruce tree, 2 = Birch tree and 3 = Jungle tree. This is a single byte located at 197,120.
- The fifth is a byte telling how many layers the tree consists of. This value ranges from 0 to 255 and is a single byte located at index 197,121.
- The sixth are the building layers, each representing 57 bytes. There can be up to 256 layers. Ranges from 197,122 and on to the end of the file.
The application saves and opens the file in this format using the following code:
Open:
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then TextBox1.Text = OpenFileDialog1.FileName Dim treeData As New TreeInfo(My.Computer.FileSystem.ReadAllBytes(OpenFileDialog1.FileName)) Dim treeName As String = treeData.BytesToString(treeData.GetBytesFromIndex(0, 256)) TextBox2.Text = treeName Dim treeAuth As String = treeData.BytesToString(treeData.GetBytesFromIndex(256, 256)) TextBox3.Text = treeAuth Dim treePrev As Bitmap = treeData.BytesToBitmap(treeData.GetBytesFromIndex(512, 196608), New Size(256, 256)) treePrev.RotateFlip(RotateFlipType.Rotate90FlipNone) PictureBox1.Image = treePrev Dim treeType As TreeType = CType(treeData.GetBytesFromIndex(197120, 1)(0), TreeType) Application.DoEvents() Dim treeStpi As Byte = treeData.GetBytesFromIndex(197121, 1)(0) Dim TMP_treestep As Integer = 197122 Dim treeSteps(treeStpi - 1) As TreeBlueprint For i = 0 To treeStpi - 1 'If entry 29 is 255 and all others 0, this is part of the trunk with no leaves. 'If entry 35 is 4 and all others 0, something went horribly wrong when saving. treeSteps(i) = New TreeBlueprint(treeData.GetBytesFromIndex(TMP_treestep, 57), treeType) TMP_treestep += 57 Next mTreeSteps = treeSteps PictureBox2.Image = treeSteps(0).ToBitmap() If mTreeSteps.Count > 1 Then Button2.Enabled = True End IfSave (TrBps is an array of TreeBlueprint (see below)):
If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then Dim saveArray(197121) As Byte Dim lbt As Integer = 512 Dim newName As String = TextBox2.Text.PadRight(256, " "c) Dim newAuth As String = TextBox3.Text.PadRight(256, " "c) For i = 0 To 255 saveArray(i) = Convert.ToByte(newName(i)) Next For i = 0 To 255 saveArray(i + 256) = Convert.ToByte(newAuth(i)) Next Dim pbbitmap As New Bitmap(PictureBox1.Image) For i = 0 To 255 For j = 0 To 255 saveArray(lbt) = pbbitmap.GetPixel(i, j).R lbt += 1 saveArray(lbt) = pbbitmap.GetPixel(i, j).G lbt += 1 saveArray(lbt) = pbbitmap.GetPixel(i, j).B lbt += 1 Next Next saveArray(197120) = CByte(curTreetype) lbt += 1 saveArray(197121) = CByte(Label5.Text) lbt += 1 For i = 0 To TrBps.Count - 1 ReDim Preserve saveArray(saveArray.Count + 56) For Each SaveByte As Byte In TrBps(i).GetBytesForSaving() saveArray(lbt) = SaveByte lbt += 1 Next Next My.Computer.FileSystem.WriteAllBytes(SaveFileDialog1.FileName, saveArray, False) End IfHow tree block data is converted to bytes (saving):
Dim nState(56) As Byte Dim curByte As Byte = 0 For i = 0 To 55 nState(i) = 0 nState(i) += CByte(64 * State(curByte)) curByte += 1 nState(i) += CByte(16 * State(curByte)) curByte += 1 nState(i) += CByte(4 * State(curByte)) curByte += 1 nState(i) += State(curByte) curByte += 1 Next nState(56) += CByte(64 * State(curByte)) ReDim Preserve TrBps(TrBps.Count) TrBps(TrBps.Count - 1) = New TreeBlueprint(nState, curTreetype) Label5.Text = (CInt(Label5.Text) + 1).ToString() If Label5.Text = "256" Then Button2.Enabled = FalseAs you can see from this code I'm using several custom classes. I'm not bothering to post them out here in this topic, but you can download the project at the bottom of this post. They're located at the bottom of the Form1.vb file.
On to the actual problem:
I've been struggling with, either, how the file is saved, how it's loaded or how a blueprint layer is rendered into a picture (TreeBlueprint.ToBitmap()).
I'm saving a tree that looks like this:

And when I load it up again it looks like this:

Notice the big difference in the tree blueprint grid to the right - many of the cells are shifted.
I'm wondering what I've overseen in my code. It could be anything that has to do with saving, loading or rendering. I would really appreciate if anyone was willing to take a look at it, for I'm completely stuck.
Here is the project download link:
http://mol.b2910.ftp.sh:8080/24396Hidden/VisualBasicNet/McTreeSched.zipTo make this work you also need the following file:
http://mol.b2910.ftp.sh:8080/24396Hidden/VisualBasicNet/tree.pngClick in the box saying Tree preview when you make a tree and open this file.
INFO: The file host was down for updates from 6:31 PM to 6:38 PM GMT on Aug 17, if you tried to download then, try again now. Sorry for this, but just noticed crucial updates to the host was neccessary D:
Thank you a lot for your help, even if you just try to figure it out.
Ask me if you have any questions.
Thank you,
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!- Edited by bilde2910 Friday, August 17, 2012 6:48 PM
All Replies
-
Sunday, August 19, 2012 7:38 PM
Any chance I could get a helping hand on this?
No one replied in 2 days :(- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far! -
Sunday, August 19, 2012 7:42 PMModerator
Without a deep investigation into your problem, you say the problem is that many of the cells are shifted, and this may because you are storing whatever values that pertain to those cell in an array, and when accessing that array you may have somewhere in your code forgotten that the first index in a list/array is zero, which means the highest index in the array/list is the .count property minus one.
btw, impressive topic ;-)
Notice how the "misdrawn cells" are all shifted down one extra cooridinate?
If you want something you've never had, you need to do something you've never done.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Sunday, August 19, 2012 7:44 PM
-
Sunday, August 19, 2012 7:56 PMModeratorI also want to suggest, if your problem persists to be difficult to find, comment each line of your source explaining what you intended to do(and post it here), it may help to easier reveal the problem.
If you want something you've never had, you need to do something you've never done.
-
Sunday, August 19, 2012 8:45 PMIn your save routine, you have these lines of code that lead me to believe lbt is expected to be in sync with the values 197120 and 197121, as the next lines after these update bytes using lbt.saveArray(197120) = CByte(curTreetype)
lbt += 1saveArray(197121) = CByte(Label5.Text)
lbt += 1Are you sure about the value of "lbt" before the loop in the save code (For i = 0 to TrBps.Count - 1)? If I look at your code correctly, the value at this point should be 66048.
--
Mike -
Sunday, August 19, 2012 9:51 PMAre you sure about the value of "lbt" before the loop in the save code (For i = 0 to TrBps.Count - 1)? If I look at your code correctly, the value at this point should be 66048.
This line is in the Load
Dim TMP_treestep As Integer = 197122
but there is no equivalent in the save. -
Monday, August 20, 2012 5:47 AMModeratorJust out of curiosity, what is the format for the "mct" file format, is it your own, or is there a binary specification somewhere that I can look at?
If you want something you've never had, you need to do something you've never done.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Monday, August 20, 2012 5:49 AM
-
Monday, August 20, 2012 5:48 AM
Thank you all for the replies :)
@Paul Ishak:
I don't think I've forgotten that .Count is first index 0, as the picture part works all fine, as with the other parts. The only thing that's going wrong are the blueprint layers (the grid). And yes, I noticed that the cells are also shifted down.
I will comment each of the lines and reupload the project, but I'll first do that in some 6 hours because I'm going to school soon. Do you want me to comment on every line in the whole project, or just in spesific ones? Also, thanks (@impressive topic)!
@Family Tree Mike:
Yes indeed, lbt is a value indicating which byte index to next save at. But you're wrong in that the value is 66048:

@Acamar:
The equivalent in saving is lbt.
Thanks all for the replies (again), will look more into this after school!
Sincerely yours,
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!- Edited by bilde2910 Monday, August 20, 2012 5:49 AM Typo
-
Monday, August 20, 2012 5:53 AMModerator
Do you want me to comment on every line in the whole project, or just in spesific ones?
I would say comment in the areas that are most likely related to your error, most likely being the areas of save file/ load file. But if you feel so inclined to comment all of your code, it may help you gain a perspective to what you have so far, and some insight to optimize your code as well. Sometimes I find that if I have an error, and I go back and comment my code, the error will reveal itself to me(this is of course totally backwards to 'planning a project')
If you want something you've never had, you need to do something you've never done.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Monday, August 20, 2012 5:55 AM
-
Monday, August 20, 2012 9:47 AMModerator
Try this file format for your file:
Example Usage:
Option Strict On Imports System.IO Public Class Form2 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Make sure your form has a background image! ' ' ' ' 'Generate some dummy Layer Data Dim LayerCount As Integer = 22 'Create a byte array for holding 22 layers of data at 57 bytes per layer Dim Layers22((LayerCount * 57) - 1) As Byte 'randomize the timer Randomize() 'Create a random number generator Dim R As New Random 'Iterate through each byte in the layers22 array For I = 0 To (LayerCount * 57) - 1 'assign each element in the array a random bye Layers22(I) = CByte(R.Next(0, 256)) 'Next Next 'Create a new MCTFile Dim A As New MCTFile("Test Project22", "Paul Ishak", Me.BackgroundImage, MCTFile.TreeType.Birch, Layers22) 'Save the file to the desktop A.SaveFile(My.Computer.FileSystem.SpecialDirectories.Desktop & "\test.MCT") 'verify the properties of the file 'Unicode byte length of the project name string MsgBox(A.File.LengthOfProjectName) 'project name MsgBox(A.File.ProjectName) 'Unicode byte length of the project author name MsgBox(A.File.LengthOfAuthorName) 'project author name MsgBox(A.File.ProjectAuthorname) 'byte length of the preview picture MsgBox(A.File.LegnthOfPreviewPicture) 'test the picture PictureBox1.BackgroundImage = Image.FromStream(New MemoryStream(A.File.PreviewPicture)) PictureBox1.BackgroundImageLayout = ImageLayout.Stretch 'tree type MsgBox(A.File.TreeType) 'layer count MsgBox(A.File.LayerCount) 'Total bytes in the layerdata array MsgBox(A.File.LayerData.Count) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 'Make sure your form has a background image! ' ' ' ' 'Generate some dummy data, different than the data we saved in button1 Dim nineLayers((9 * 57)) As Byte Randomize() Dim R As New Random For I = 0 To (9 * 57) - 1 nineLayers(I) = CByte(R.Next(0, 256)) Next 'create a new MCTFile Dim A As New MCTFile("Test Project9", "Some Dude", Me.BackgroundImage, MCTFile.TreeType.Birch, nineLayers) 'Overwrite all the data we just created by opening a file A.OpenFile(My.Computer.FileSystem.SpecialDirectories.Desktop & "\test.MCT") 'verify the properties of the file 'Unicode byte length of the project name string MsgBox(A.File.LengthOfProjectName) 'project name MsgBox(A.File.ProjectName) 'Unicode byte length of the project author name MsgBox(A.File.LengthOfAuthorName) 'project author name MsgBox(A.File.ProjectAuthorname) 'byte length of the preview picture MsgBox(A.File.LegnthOfPreviewPicture) 'test the picture PictureBox1.BackgroundImage = Image.FromStream(New MemoryStream(A.File.PreviewPicture)) PictureBox1.BackgroundImageLayout = ImageLayout.Stretch 'tree type MsgBox(A.File.TreeType) 'layer count MsgBox(A.File.LayerCount) 'Total bytes in the layerdata array MsgBox(A.File.LayerData.Count) End Sub End Class
Class
Option Strict On Imports System.Text Imports System.IO Public Class MCTFile Public File As New MCTStruct Class MCTStruct #Region "Private Properties" 'Property Name Data Length Offset to Data Formula ' ' ' Public Property _LengthOfProjectName As UInt32 ' 4 Bytes 0 Public Property _ProjectName As String ' _LengthOfProjectName 4 Public Property _LengthOfAuthorName As UInt32 ' 4 Bytes 4 + _LengthOfProjectName Public Property _ProjectAuthorname As String ' _LengthOfAuthorName 4 + _LengthOfProjectName + 4 Public Property _LegnthOfPreviewPicture As UInt64 '8 Bytes 4 + _LengthOfProjectName + 4 + _LengthOfAuthorName Public Property _PreviewPicture As Byte() ' _LegnthOfPreviewPicture 4 + _LengthOfProjectName + 4 + _LengthOfAuthorName + 8 Public Property _TreeType As TreeType ' 1 Byte 4 + _LengthOfProjectName + 4 + _LengthOfAuthorName + 8 + PicturePreview.Count Public Property _LayerCount As UInt32 ' 4 Bytes 4 + _LengthOfProjectName + 4 + _LengthOfAuthorName + 8 + PicturePreview.Count + 1 Public Property _LayerData As Byte() ' LayerCount * 57 4 + _LengthOfProjectName + 4 + _LengthOfAuthorName + 8 + PicturePreview.Count + 1 + 4 #End Region #Region "Public Properties" Public ReadOnly Property LengthOfProjectName As UInt32 'Dword Get Return _LengthOfProjectName End Get End Property Public Property ProjectName As String Get Return _ProjectName End Get Set(ByVal value As String) 'Set ProjectName, Calculate and set LengthOfProjectName _ProjectName = value _LengthOfProjectName = Convert.ToUInt32(Encoding.Unicode.GetBytes(value.ToCharArray).Count) End Set End Property Public ReadOnly Property LengthOfAuthorName As UInt32 'Dword Get Return _LengthOfAuthorName End Get End Property Public Property ProjectAuthorname As String Get Return _ProjectAuthorname End Get Set(ByVal value As String) 'Set Project Author Name, Calculate and set LengthOfauthorname _ProjectAuthorname = value _LengthOfAuthorName = Convert.ToUInt32(Encoding.Unicode.GetBytes(value.ToCharArray).Count) End Set End Property Public ReadOnly Property LegnthOfPreviewPicture As UInt64 'Qword Get Return _LegnthOfPreviewPicture End Get End Property Public Property PreviewPicture As Byte() Get Return _PreviewPicture End Get Set(ByVal value As Byte()) 'Set bytes, set length of bytes _PreviewPicture = value _LegnthOfPreviewPicture = CULng(value.Count) End Set End Property Public Property TreeType As TreeType Get Return _TreeType End Get Set(ByVal value As TreeType) 'set treetype(converts to predefined integer) _TreeType = value End Set End Property Public ReadOnly Property LayerCount As UInt32 'Dword Get Return _LayerCount End Get End Property Public Property LayerData As Byte() Get Return _LayerData End Get Set(ByVal value As Byte()) 'Set layer data, and count of layer data _LayerData = value _LayerCount = Convert.ToUInt32(value.Count \ 57) End Set End Property #End Region End Class Sub OpenFile(ByVal FileName As String) 'Read all the bytes of the file Dim RawBytes As Byte() = My.Computer.FileSystem.ReadAllBytes(FileName) 'calculate offsets, convert and set values Dim Offset1 As UInt32 = 0 Me.File._LengthOfProjectName = BitConverter.ToUInt32(GetByteRange(RawBytes, Offset1, 4), 0) Dim Offset2 As UInt32 = 4 Me.File._ProjectName = Encoding.Unicode.GetString(GetByteRange(RawBytes, Offset2, Me.File.LengthOfProjectName)) Dim Offset3 As UInt32 = Convert.ToUInt32(Offset2 + Me.File.LengthOfProjectName) Me.File._LengthOfAuthorName = BitConverter.ToUInt32(GetByteRange(RawBytes, Offset3, 4), 0) Dim Offset4 As UInt32 = Convert.ToUInt32(Offset3 + 4) Me.File._ProjectAuthorname = Encoding.Unicode.GetString(GetByteRange(RawBytes, Offset4, Me.File.LengthOfAuthorName)) Dim Offset5 As UInt32 = Convert.ToUInt32(Offset4 + Me.File.LengthOfAuthorName) Me.File._LegnthOfPreviewPicture = BitConverter.ToUInt64(GetByteRange(RawBytes, Offset5, 8), 0) Dim Offset6 As UInt32 = Convert.ToUInt32(Offset5 + 8) Me.File._PreviewPicture = GetByteRange(RawBytes, Offset6, Convert.ToUInt32(Me.File.LegnthOfPreviewPicture)) Dim Offset7 As UInt32 = Convert.ToUInt32(Offset6 + Me.File.PreviewPicture.Count) Me.File._TreeType = CType(GetByteRange(RawBytes, Offset7, 1)(0), TreeType) Dim Offset8 As UInt32 = Convert.ToUInt32(Offset7 + 1) Dim LayerCountBytes As Byte() = GetByteRange(RawBytes, Offset8, 4) Me.File._LayerCount = BitConverter.ToUInt32(ReverseByteOrder(LayerCountBytes), 0) Dim Offset9 As UInt32 = Convert.ToUInt32(Offset8 + 4) Me.File._LayerData = GetByteRange(RawBytes, Offset9, CUInt((Me.File.LayerCount * 57))) End Sub Function ReverseByteOrder(ByVal Bytes() As Byte) As Byte() Dim Result(Bytes.Count - 1) As Byte Dim Counter As Integer = -1 For I = Bytes.Count - 1 To 0 Step -1 Counter = Counter + 1 Result(Counter) = Bytes(I) Next Return Result End Function Sub SaveFile(ByVal FileName As String) My.Computer.FileSystem.WriteAllBytes(FileName, Me.GetBytes, False) End Sub Sub New(ByVal ProjectName As String, ByVal AuthorName As String, ByVal PreviewPicture As Image, ByVal TreeType As TreeType, ByVal LayerData As Byte()) Me.File.ProjectName = ProjectName Me.File.ProjectAuthorname = AuthorName Me.File.PreviewPicture = ImageToByte(PreviewPicture) Me.File.TreeType = TreeType Me.File.LayerData = LayerData End Sub Function GetBytes() As Byte() Dim RawData As Byte() = BitConverter.GetBytes(File.LengthOfProjectName) RawData = CombineArrays(RawData, Encoding.Unicode.GetBytes(File.ProjectName.ToCharArray)) RawData = CombineArrays(RawData, BitConverter.GetBytes(File.LengthOfAuthorName)) RawData = CombineArrays(RawData, Encoding.Unicode.GetBytes(File.ProjectAuthorname.ToCharArray)) RawData = CombineArrays(RawData, BitConverter.GetBytes(File.LegnthOfPreviewPicture)) RawData = CombineArrays(RawData, File.PreviewPicture) RawData = CombineArrays(RawData, BitConverter.GetBytes(File.TreeType)) RawData = CombineArrays(RawData, BitConverter.GetBytes(File.LayerCount)) RawData = CombineArrays(RawData, File.LayerData) Return RawData End Function Function CombineArrays(ByVal Array1 As Byte(), ByVal Array2 As Byte()) As Byte() Dim Merged((Array1.Length + Array2.Length) - 1) As Byte Array1.CopyTo(Merged, 0) Array2.CopyTo(Merged, Array1.Length) Return Merged End Function Function GetByteRange(ByVal Bytes As Byte(), ByVal Offset As UInt32, ByVal Length As UInt32) As Byte() Dim Results As New List(Of Byte) For I As UInt32 = Offset To CUInt((Offset + Length) - 1) Results.Add(Bytes(CInt(I))) Next Return Results.ToArray End Function Public Shared Function ImageToByte(ByVal img As Image) As Byte() Dim imgStream As MemoryStream = New MemoryStream() img.Save(imgStream, System.Drawing.Imaging.ImageFormat.Jpeg) imgStream.Close() Dim byteArray As Byte() = imgStream.ToArray() imgStream.Dispose() Return byteArray End Function Enum TreeType Oak = 0 Spruce = 1 Birch = 2 Jungle = 3 End Enum End Class
If you want something you've never had, you need to do something you've never done.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Monday, August 20, 2012 10:20 AM
-
Monday, August 20, 2012 3:29 PM
Updating the project with comments is now done.
Here is the download link:
http://mol.b2910.ftp.sh:8080/24396Hidden/VisualBasicNet/McTreeSched.zip@Paul Ishak:
The version of the code you provided yielded the same results, but the cells were even more shifted. Might not be as obvious since you made a completely random blueprint, but when setting the blueprint to something organized it failed. But that might just as well be an error on my part.
Sincerely yours,
- bilde2910If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far! -
Monday, August 20, 2012 8:06 PMModerator
Please answer this:
Is there a standard format that the "MCT" file must conform to? or are you using your own proposed format? Please let me know... I have been unable to locate the cause of your error as of yet, still looking(downloaded your commented source)
took me a little while to realize that although when you create a new tree, you can edit the grid, that no first layer will exist until you add one. so I was stuck getting an error for that:
Suggestion: add the first layer automatically when the user clicks "new tree".
If you want something you've never had, you need to do something you've never done.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Monday, August 20, 2012 8:54 PM
-
Tuesday, August 21, 2012 5:51 AM
@Paul Ishak:
Hmm.. somehow I've forgotten to say that. Let's clear things up :)
- The MCT format is a random file format I came up with, and I confirmed on fileinfo.com that no such format was being popularly used. This means it can be in any way I prefer.
- Yes, you have to add a layer first, thought that would be obvious (who creates a blueprint with no papers?), but I'll add in a warning dialogue. This will also ask you to get a picture for your blueprint.
- Your suggestion sounds good, but I don't really like the idea, because if the user wants the first layer changed (jungle trees spesifically have a trunk size of 2x2 logs instead of everything else with 1x1), that can't be done.
I must though really say that I am a fan of your file format, since it opens up for a lot of possibilities (including being able to select any picture instead of it having to be 256x256), I'm sure I can add that in on my own. Also I like how you can have a file name nearly infinite (from a regular user's perspective, that is) but the name hardly exceeds 256 characters anyway. Same applies with author.
I also noticed, if you take a look at the pictures above, the original holds 21 tiles, but the shifted one holds just 17. This is a loss of four.
Also, if you shift the tiles back in place, this number increases to 5. The missing tiles after shifting are highlighted in blue.

Thank you for willing to spend time on this! It's really encouraging me to work!
Sincerely yours,
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!- Edited by bilde2910 Tuesday, August 21, 2012 5:53 AM
-
Tuesday, August 21, 2012 6:11 AMModerator
- Yes, you have to add a layer first, thought that would be obvious (who creates a blueprint with no papers?), but I'll add in a warning dialogue. This will also ask you to get a picture for your blueprint.
The main reason I bring this up, is because of 2 things:
1.) You have not handled the error.
2.) You still allow the user to edit a layer that has not been added.
I am glad that you have seen some of the advantages to coming up with a planned file specification, and I think you should consider writing a class to hold and implement your specification, the main advantage being that once you have your class written right, you could easily port it to future versions of your program. As far as the 2x2 log issue goes, I would think that would be a matter of brush size in your designer(an not file format), seeing as trunk being 2x2 cells wide would still constitute a total of 4 cells.
If you want something you've never had, you need to do something you've never done.
-
Tuesday, August 21, 2012 4:21 PM
I actually figured out what went wrong.
Have a look at this. This code is for rendering the blueprint. See what I did wrong?
'Get what the fourth block is 'If the value is >= to 3 If tempbyte - 3 >= 0 Then 'Subtract this from the byte, and... tempbyte = CByte(tempbyte - 3) '... set the FOURTH block to be 3 ("nothing"). block(3) = 3 ElseIf tempbyte - 2 >= 0 Then 'If it's not >= 3, is it >= 2? 'If it is, subtract this from the byte and... tempbyte = CByte(tempbyte - 2) '... set the fourth block to be 2 (leaves). block(2) = 2 ElseIf tempbyte - 1 >= 0 Then 'If it's not >= 2, is it >= 1? 'If it is, subtract this from the byte and... tempbyte = CByte(tempbyte - 1) '... set the fourth block to be 1 (log). block(1) = 1 End If 'If it's not >= 1 at all, the fourth block should be 0 (a blank tile). 'This value was preset from the initialization of block, so do nothing.Somehow I had managed to try to update block number three and two instead of number four, depending on whether it was a leaf or log block.
What's weird is that when I went about commenting every line, I didn't notice this. Perhaps I thought it was how it was supposed to be, without further insight?
I would, though, like to thank you for your great help - I've taken your tips into consideration, have made an own class holding everything. You can have a look at it here:
http://mol.b2910.ftp.sh:8080/24396Hidden/VisualBasicNet/MCT.vb
I fixed the code and now it works great!
Loading the file:
'Get a file. If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then Dim mctF As New MCT.MCTFile(OpenFileDialog1.FileName) TextBox2.Text = mctF.ProjectName TextBox3.Text = mctF.ProjectAuthor PictureBox1.Image = mctF.PreviewImage PictureBox2.Image = mctF.TreeLayers(0).ToBitmap() End IfSaving the file:
'Get where to save the file. If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
'Will add in dialogs here (like "you must select a screenshot!") later.
'PS. TrBps was changed from TreeBlueprint to MCT.MCTLayerBlueprint, if you were to wonder :) Dim mctF As New MCT.MCTFile(TextBox2.Text, TextBox3.Text, CType(DomainUpDown1.SelectedIndex, TreeType), PictureBox1.Image, TrBps) mctF.Save(SaveFileDialog1.FileName) End IfI also thought about what you said - having a layer ready for the user. I initially misunderstood what you ment - but now I will now proceed in letting the user work on the first layer and if they need an additional one, they just press the "Add" button which I've renamed to "Add new layer".
Thank you a LOT for your help!
Sincerely yours,
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far! -
Tuesday, August 21, 2012 4:55 PMModeratorYou're welcome, am glad you found your error!" You should update us on new downloads as this project advances. I find it very interesting.
If you want something you've never had, you need to do something you've never done.
-
Tuesday, August 21, 2012 7:01 PM
You're welcome, am glad you found your error!" You should update us on new downloads as this project advances. I find it very interesting.
If you want something you've never had, you need to do something you've never done.
Of course, I can put up downloads of this if you want!
Are you gonna have any use of it, or just in matter of code?
Sincerely yours,
- bilde2910If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far! -
Tuesday, August 21, 2012 7:23 PMModerator
You're welcome, am glad you found your error!" You should update us on new downloads as this project advances. I find it very interesting.
If you want something you've never had, you need to do something you've never done.
Of course, I can put up downloads of this if you want!
Are you gonna have any use of it, or just in matter of code?
Sincerely yours,
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!
Well, I just find certain things to be interesting, and I'm interested to see where you go with it, as far as are you going to have a 3d rotatable preview? I just think its neat basically... ;)If you want something you've never had, you need to do something you've never done.
-
Wednesday, August 22, 2012 5:57 AM
Well, I just find certain things to be interesting, and I'm interested to see where you go with it, as far as are you going to have a 3d rotatable preview? I just think its neat basically... ;)
If you want something you've never had, you need to do something you've never done.
Sure, I can see what I get :)
But when it comes as far as to a 3D preview (that can be rotated), I don't think I would add that in. Well, if I could figure out how, that would be great, but I don't even have an idea where to begin. I'm sure I can google around, but how complex this code will be I'm not sure (probably very complicated).
At any rate, I can add other functions, like I'm also considering a new file format (*.tbx), capable of holding 256 block types instead of 4.
I'll see what I can reach :D
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far! -
Wednesday, August 22, 2012 6:07 AMModeratorYou mean for creating things other than trees? nice, and you never know where it may lead you if you keep working on it. "mindcraft"
If you want something you've never had, you need to do something you've never done.
-
Wednesday, August 22, 2012 1:16 PM
You mean for creating things other than trees? nice, and you never know where it may lead you if you keep working on it. "mindcraft"
If you want something you've never had, you need to do something you've never done.
Nope, but seeing a lot of things being added to Minecraft trees nowadays...
Minecraft 1.3.2
+ Added sideways logs in treesMinecraft 1.3.1
+ Added cocoa beans to junglesThis causes me having to add in compability for sideways logs and cocoa beans, but there is not enough capacity in the code for more than 4 block types (because it saves 4 blocks per byte), but if I can reduce that to 1 block per byte (that's easy!) I can have 256 block types, which makes me more prepared for things to come in the future.
Compability is a nice thing, but I openly forgot that there were more than logs and leaves on trees in Minecraft these days...
But making things other than trees is also a tempting idea! Interesting if you want to make 3D pixel arts and similar stuff!
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!- Edited by bilde2910 Wednesday, August 22, 2012 1:18 PM
-
Wednesday, August 22, 2012 3:33 PMModerator
Take a look at this, I know its insane, but it could provide much room for forward compatibility, or give you further ideas at the least.
Field Name Data Type Data Size Offset Formula MCTFileStructure_ LengthOfProjectName UInt32 DWORD Offset1 = 0 ProjectName String Byte(LengthOfProjectName-1) Offset2 = Offset1 + 4 LengthOfAuthorName UInt32 DWORD Offset3 = Offset2 + LengthOfProjectName AuthorName String Byte(LengthOfAuthorName-1) Offset4 = Offset3 + 4 LengthOfPicturePreview UInt64 QWORD Offset5 = Offset4 + LengthOfAuthorName PreviewPicture Byte() Byte(LengthOfPicturePreview-1) Offset6 = Offset5 + 8 TreeType Byte 1 Byte Offset7 = Offset6 + LengthOfPicturePreview LengthOfLayerData UInt32 DWORD Offset8 = Offset7 + 1 LayerCollection LayerCollection Byte(LengthOfLayerData-1) Offset9 = Offset8 + 4 'You can change this to a collection of images...(similar to the layer collection and cell collection layout) LengthLogImage UInt64 QWORD Offset10 = Offset9 + LengthOfLayerData LogImage Byte() Byte(LengthLogImage-1) Offset11 = Offest10 + 8 LengthOfLeavesImage UInt64 QWORD Offset12 = Offset11 + LengthLogImage LeavesImage Byte() Byte(LengthOfLeavesImage-1) Offset13 = Offset12 + 8 Structure LayerCollectionStructure LayerCount UInt32 DWORD Offset1 = 0 Layer1DataLength UInt32 DWORD Offset2 = Offset1 + 4 Layer1Data LayerData Bytes(Layer1DataLength) Offset3 = Offset2 + 4 Layer2DataLength UInt32 DWORD Offset4 = Offset3 + Layer1DataLength Layer2Data LayerData Bytes(Layer2DataLength) Offset5 = Offset3 + 4 Layer2DataLength UInt32 DWORD Offset4 = Offset3 + Layer1DataLength Layer2Data LayerData Bytes(Layer2DataLength) Offset5 = Offset3 + 4 Layer2DataLength UInt32 DWORD Offset4 = Offset3 + Layer1DataLength Layer2Data LayerData Bytes(Layer2DataLength) Offset5 = Offset3 + 4 etc... etc... Structure LayerDataStructure LayerNumber UInt16 WORD Offset1 = 0 CellCollectionLength UIint32 DWORD Offset2 = Offset1 + 2 CellCollectionData CellCollectionData Byte(CellCollectionLength) Offset3 = Offset2 + CellCollectionLength Structure CellCollectionStructure CellCount UInt32 DWORD Offset1 = 0 Cell1DataLength UInt32 DWORD Offset2 = Offset1 + 4 Cell1Data Cell Byte(Cell1DataLength) Offset3 = Offset2 + 4 Cell2DataLength UInt32 DWORD Offset4 = Offset3 + Cell1DataLength Cell2Data Cell Byte(Cell2DataLength) Offset5 = Offset4 + 4 etc... ect... Structure CellDataStructure X UInt16 WORD Offset1 = 0 Y UInt16 WORD Offset2 = Offset1 + 2 TreeImageType TreeImageType 1 Byte Offset3 = Offset2 + 2 Structure EnumTreeImageType 1 = Log Byte 1 Byte N/A 2 = Leaves Byte 1 Byte N/A 'Forward Compatible up to 256 "image types" Enum EnumTreeType 1 = Oak Byte 1 Byte N/A 2 = Spruce Byte 1 Byte N/A 3 = Birch Byte 1 Byte N/A 4 = Jungle Byte 1 Byte N/A 'Forward Compatible up to 256 "image types" Enum
If you want something you've never had, you need to do something you've never done.
-
Thursday, August 23, 2012 6:39 PM
Took some time to consider what you've said above here...
What you've written does allow for much better compability. But it's gonna take long to implement. Also a few questions - what are WORD, DWORD and QWORD?
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far! -
Thursday, August 23, 2012 6:46 PMModerator
Took some time to consider what you've said above here...
What you've written does allow for much better compability. But it's gonna take long to implement. Also a few questions - what are WORD, DWORD and QWORD?
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!Those are terminology that refers to the a given datalength
A byte is 8 bits, A word is 2 bytes, a double word (dword) is 4 bytes, a quadruple word(qword) is 8 bytes. and there also exists such thing as a nibble which is half a byte
In hex a byte looks like this
&hFF for instance
but in binary, that would look like this:
11111111b
The reason different byte lengths are assigned to the fields is depending on the potential data size.
If you use a single byte to describe the length of a field, you will top off at 256 characters.
If you want something you've never had, you need to do something you've never done.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Thursday, August 23, 2012 6:46 PM
-
Thursday, August 23, 2012 6:49 PMModerator
I wrote the following class for the listed format, but I have not had an ability to test it due to not writing the rest of the program. but if you can figure out how to implement it, its yours ;)
Option Strict On Imports System.Text Imports System.IO Public Class MCTClass #Region "Class Properties" Public File As FileData #End Region Sub New(ByVal Options As MCTData) 'Will skip if called fromfile If Not CType(Options.InteralParameter, String) = "Skip Load" Then If Options.ProjectName = Nothing Then Throw New Exception("Project must have a Name.") If Options.AuthorName = Nothing Then Throw New Exception("Project must have an Author.") If Options.PreviewPicture Is Nothing Then Throw New Exception("Project must have a Preview Image.") If Options.TreeType = Nothing Then Throw New Exception("Project must have a Tree Image Family Type.") If Options.LayersCollection Is Nothing Then Throw New Exception("Project must have a Layer Collection.") If Options.LogImage Is Nothing Then Throw New Exception("Project must have a Log Image.") If Options.LeavesImage Is Nothing Then Throw New Exception("Project must have a Leaves Image.") If Options.ImageFormat Is Nothing Then Options.ImageFormat = Imaging.ImageFormat.Png Me.File.ProjectName = Options.ProjectName Me.File.Author = Options.AuthorName Me.File.PreviewPicture = Options.PreviewPicture Me.File.TreeType = Options.TreeType Me.File.LayerCollection = Options.LayersCollection Me.File.LogImage = Options.LogImage Me.File.LeavesImage = Options.LeavesImage Me.File.ImageFormat = Options.ImageFormat End If End Sub Public Shared Function FromFile(ByVal FileName As String) As MCTClass Dim BlankOptions As New MCTData BlankOptions.InteralParameter = CType("Skip Load", Object) Dim LoadedFile As New MCTClass(BlankOptions) Dim RawBytes As Byte() = My.Computer.FileSystem.ReadAllBytes(FileName) Dim Offset1 As UInt32 = 0 'Offset1 = 0 Dim LengthOfProjectName As UInt32 = BitConverter.ToUInt32(GetByteRange(RawBytes, Offset1, DWORD), 0) Dim Offset2 As UInt32 = Offset1 + Convert.ToUInt32(DWORD) 'Offset2 = Offset1 + 4 LoadedFile.File.ProjectName = Encoding.Unicode.GetString(GetByteRange(RawBytes, Offset2, LengthOfProjectName)) Dim Offset3 As UInt32 = Offset2 + LoadedFile.File.LengthOfProjectName 'Offset3 = Offset2 + LengthOfProjectName Dim LengthOfAuthorName As UInt32 = BitConverter.ToUInt32(GetByteRange(RawBytes, Offset3, DWORD), 0) Dim Offset4 As UInt32 = Offset3 + Convert.ToUInt32(DWORD) 'Offset4 = Offset3 + 4 LoadedFile.File.Author = Encoding.Unicode.GetString(GetByteRange(RawBytes, Offset4, LengthOfAuthorName)) Dim Offset5 As UInt32 = Offset4 + LengthOfAuthorName 'Offset5 = Offset4 + LengthOfAuthorName Dim LengthOfPicturePreview As UInt32 = BitConverter.ToUInt32(GetByteRange(RawBytes, Offset5, QWORD), 0) Dim Offset6 As UInt32 = Offset5 + Convert.ToUInt32(QWORD) 'Offset6 = Offset5 + 8 LoadedFile.File.PreviewPicture = Image.FromStream(New MemoryStream(GetByteRange(RawBytes, Offset6, LengthOfPicturePreview))) Dim Offset7 As UInt32 = Offset6 + LengthOfPicturePreview 'Offset7 = Offset6 + LengthOfPicturePreview LoadedFile.File.TreeType = CType(CInt(GetByteRange(RawBytes, Offset7, 1)(0)), TreeImageFamily) Dim Offset8 As UInt32 = Offset7 + Convert.ToUInt32(1) 'Offset8 = Offset7 + 1 Dim LengthOfLayerData As UInt32 = BitConverter.ToUInt32(GetByteRange(RawBytes, Offset8, DWORD), 0) Dim Offset9 As UInt32 = Offset8 + Convert.ToUInt32(DWORD) 'Offset9 = Offset8 + 4 Dim LayerCollection As Byte() = GetByteRange(RawBytes, Offset9, LengthOfLayerData) LoadedFile.File.LayerCollection = LayerCollection Dim Offset10 As UInt32 = Offset9 + LengthOfLayerData 'Offset10 = Offset9 + LengthOfLayerData Dim LengthOfLogImage As UInt64 = BitConverter.ToUInt64(GetByteRange(RawBytes, Offset10, QWORD), 0) Dim Offset11 As UInt32 = Offset10 + Convert.ToUInt32(QWORD) 'Offset11 = Offest10 + 8 LoadedFile.File.LogImage = Image.FromStream(New MemoryStream(GetByteRange(RawBytes, Offset11, Convert.ToUInt32(LengthOfLogImage)))) Dim Offset12 As UInt32 = Offset11 + Convert.ToUInt32(LengthOfLogImage) 'Offset12 = Offset11 + LengthLogImage Dim LengthOfLeavesImage As UInt64 = BitConverter.ToUInt64(GetByteRange(RawBytes, Offset12, QWORD), 0) Dim Offset13 As UInt32 = Offset12 + Convert.ToUInt32(QWORD) 'Offset13 = Offset12 + 8 LoadedFile.File.LeavesImage = Image.FromStream(New MemoryStream(GetByteRange(RawBytes, Offset13, Convert.ToUInt32(LengthOfLeavesImage)))) Return LoadedFile End Function Sub Save(ByVal FileName As String) My.Computer.FileSystem.WriteAllBytes(FileName, GetBytes, False) End Sub Public Function GetBytes() As Byte() Dim RawBytes As Byte() = BitConverter.GetBytes(Me.File.LengthOfProjectName) RawBytes = CombineArrays(RawBytes, Encoding.Unicode.GetBytes(Me.File.ProjectName)) RawBytes = CombineArrays(RawBytes, BitConverter.GetBytes(Me.File.LengthOfAuthorName)) RawBytes = CombineArrays(RawBytes, Encoding.Unicode.GetBytes(Me.File.Author)) RawBytes = CombineArrays(RawBytes, BitConverter.GetBytes(Me.File.LengthOfPicturePreview)) RawBytes = CombineArrays(RawBytes, ImageBytes(Me.File.PreviewPicture, Me.File.ImageFormat)) RawBytes = CombineArrays(RawBytes, {CByte(Me.File.TreeType)}) RawBytes = CombineArrays(RawBytes, BitConverter.GetBytes(Me.File.LengthOfLayerCollection)) RawBytes = CombineArrays(RawBytes, Me.File.LayerCollection) RawBytes = CombineArrays(RawBytes, BitConverter.GetBytes(Me.File.LengthOfLogImage)) RawBytes = CombineArrays(RawBytes, ImageBytes(Me.File.LogImage, Me.File.ImageFormat)) RawBytes = CombineArrays(RawBytes, BitConverter.GetBytes(Me.File.LengthOfLeavesImage)) RawBytes = CombineArrays(RawBytes, ImageBytes(Me.File.LeavesImage, Me.File.ImageFormat)) Return RawBytes End Function #Region "File Data Structure(Main structure)" 'Field Name Data Type Data Size Offset Formula ' Class FileData ' LengthOfProjectName UInt32 DWORD Offset1 = 0 ' ProjectName String Byte(LengthOfProjectName-1) Offset2 = Offset1 + 4 ' LengthOfAuthorName UInt32 DWORD Offset3 = Offset2 + LengthOfProjectName ' AuthorName String Byte(LengthOfAuthorName-1) Offset4 = Offset3 + 4 ' LengthOfPicturePreview UInt64 QWORD Offset5 = Offset4 + LengthOfAuthorName ' PreviewPicture Byte() Byte(LengthOfPicturePreview-1) Offset6 = Offset5 + 8 ' TreeType Byte 1 Byte Offset7 = Offset6 + LengthOfPicturePreview ' LengthOfLayerData UInt32 DWORD Offset8 = Offset7 + 1 ' LayerCollection LayerCollection Byte(LengthOfLayerData-1) Offset9 = Offset8 + 4 ' LengthLogImage UInt64 QWORD Offset10 = Offset9 + LengthOfLayerData ' LogImage Byte() Byte(LengthLogImage-1) Offset11 = Offest10 + 8 ' LengthOfLeavesImage UInt64 QWORD Offset12 = Offset11 + LengthLogImage ' LeavesImage Byte() Byte(LengthOfLeavesImage-1) Offset13 = Offset12 + 8 'Structure Public ImageFormat As Imaging.ImageFormat Private Property _LengthOfProjectName As UInt32 Private Property _ProjectName As String Private Property _LengthOfAuthorName As UInt32 Private Property _Author As String Private Property _LengthOfPicturePreview As UInt64 Private Property _PreviewPicture As Image Private Property _TreeType As TreeImageFamily Private Property _LengthOfLayerCollection As UInt32 Private Property _LayerCollection As Byte() Private Property _LengthOfLogImage As UInt64 Private Property _LogImage As Image Private Property _LengthOfLeavesImage As UInt64 Private Property _LeavesImage As Image Public ReadOnly Property LengthOfProjectName As UInt32 Get Return _LengthOfProjectName End Get End Property Public Property ProjectName As String Get Return _ProjectName End Get Set(ByVal value As String) Dim Bytes As Byte() = Encoding.Unicode.GetBytes(value) _ProjectName = value _LengthOfProjectName = Convert.ToUInt32(Bytes.Count) End Set End Property Public ReadOnly Property LengthOfAuthorName As UInt32 Get Return _LengthOfAuthorName End Get End Property Public Property Author As String Get Return _Author End Get Set(ByVal value As String) Dim Bytes As Byte() = Encoding.Unicode.GetBytes(value) _Author = value _LengthOfAuthorName = Convert.ToUInt32(Bytes.Count) End Set End Property Public ReadOnly Property LengthOfPicturePreview As UInt64 Get Return _LengthOfPicturePreview End Get End Property Public Property PreviewPicture As Image Get Return _PreviewPicture End Get Set(ByVal value As Image) Dim Bytes As Byte() = ImageBytes(value, Me.ImageFormat) _PreviewPicture = value _LengthOfPicturePreview = Convert.ToUInt64(Bytes.Count) End Set End Property Public Property TreeType As TreeImageFamily Get Return _TreeType End Get Set(ByVal value As TreeImageFamily) _TreeType = value End Set End Property Public ReadOnly Property LengthOfLayerCollection As UInt32 Get Return _LengthOfLayerCollection End Get End Property Public Property LayerCollection As Byte() Get Return _LayerCollection End Get Set(ByVal value As Byte()) _LayerCollection = value _LengthOfLayerCollection = Convert.ToUInt32(value.Count) End Set End Property Public ReadOnly Property LengthOfLogImage As UInt64 Get Return _LengthOfLogImage End Get End Property Public Property LogImage As Image Get Return _LogImage End Get Set(ByVal value As Image) _LogImage = value Dim Bytes As Byte() = ImageBytes(value, Me.ImageFormat) _LengthOfLogImage = Convert.ToUInt64(Bytes.Count) End Set End Property Public ReadOnly Property LengthOfLeavesImage As UInt64 Get Return _LengthOfLeavesImage End Get End Property Public Property LeavesImage As Image Get Return _LeavesImage End Get Set(ByVal value As Image) _LeavesImage = value Dim Bytes As Byte() = ImageBytes(value, Me.ImageFormat) _LengthOfLeavesImage = Convert.ToUInt64(Bytes.Count) End Set End Property End Class #End Region #Region "Layer Collection Strucutre" Public Class LayerCollectionStructure ' LayerCount UInt32 DWORD Offset1 = 0 ' Layer1DataLength UInt32 DWORD Offset2 = Offset1 + 4 ' Layer1Data LayerData Bytes(Layer1DataLength) Offset3 = Offset2 + 4 ' Layer2DataLength UInt32 DWORD Offset4 = Offset3 + Layer1DataLength ' Layer2Data LayerData Bytes(Layer2DataLength) Offset5 = Offset3 + 4 ' etc... Public Property Layers As List(Of LayerDataStructure) Public Bytes As Byte() Sub New(ByVal Options As LayerCollectionStructureOptions) If Not CType(Options.InteralParameter, String) = "Skip Load" Then Me.Layers = Options.Layers Dim LayerCount As UInt32 = Convert.ToUInt32(Options.Layers.Count) Dim RawBytes As Byte() = BitConverter.GetBytes(LayerCount) For Each Layer As LayerDataStructure In Options.Layers Dim LayerDataLength As Byte() = BitConverter.GetBytes(Convert.ToUInt16(Layer.Bytes.Count)) Dim LayerData As Byte() = Layer.Bytes RawBytes = CombineArrays(RawBytes, LayerDataLength) RawBytes = CombineArrays(RawBytes, LayerData) Next Bytes = RawBytes End If End Sub Public Shared Function FromBytes(ByVal Bytes As Byte()) As LayerCollectionStructure Dim BlankOptions As New LayerCollectionStructureOptions BlankOptions.InteralParameter = CType("Skip Load", Object) Dim LayerCollectionData As Byte() = GetByteRange(Bytes, 4, Convert.ToUInt32(Bytes.Count) - Convert.ToUInt32(4)) Dim LoadedLayerCollectionStructure As New LayerCollectionStructure(BlankOptions) Dim TMPLayers As New List(Of LayerDataStructure) Dim LayerCount As UInt32 = BitConverter.ToUInt32(GetByteRange(Bytes, 0, DWORD), 0) Dim Count As Integer = 0 Dim Offset As UInt32 = 0 Do Count = Count + 1 Dim DataLength As UInt32 = BitConverter.ToUInt32(GetByteRange(LayerCollectionData, Offset, DWORD), 0) Dim Data As Byte() = GetByteRange(LayerCollectionData, Offset + DWORD, DataLength) TMPLayers.Add(LayerDataStructure.FromBytes(Data)) Offset = Offset + DWORD + DataLength Loop Until Count = LayerCount LoadedLayerCollectionStructure.Layers = TMPLayers LoadedLayerCollectionStructure.Bytes = Bytes Return LoadedLayerCollectionStructure End Function End Class #End Region #Region "Layer Data Strucutre" Public Class LayerDataStructure ' LayerNumber UInt16 WORD Offset1 = 0 ' CellCollectionLength UIint32 DWORD Offset2 = Offset1 + 2 ' CellCollectionData CellCollectionData Byte(CellCollectionLength) Offset3 = Offset2 + CellCollectionLength Public Property Bytes As Byte() Public Property LayerNumber As UInt16 Public Property CellCollectionLength As UInt32 Public CellCollectionData As Byte() Public LayerCell As CellCollectionStructure Sub New(ByVal Options As LayerDataStructureOptions) If Not CType(Options.InteralParameter, String) = "Skip Load" Then Me.LayerNumber = Options.LayerNumber Me.LayerCell = Options.LayerCells Me.CellCollectionLength = Convert.ToUInt32(Options.LayerCells.Bytes.Count) Me.CellCollectionData = Options.LayerCells.Bytes Dim RawBytes As Byte() 'Append Layer Number RawBytes = BitConverter.GetBytes(Options.LayerNumber) 'Append Cell Collection Length RawBytes = CombineArrays(RawBytes, BitConverter.GetBytes(Me.CellCollectionLength)) 'Append Cell Collection Data RawBytes = CombineArrays(RawBytes, Me.CellCollectionData) Bytes = RawBytes End If End Sub Public Shared Function FromBytes(ByVal Bytes As Byte()) As LayerDataStructure Dim Options As New LayerDataStructureOptions Options.InteralParameter = CType("Skip Load", Object) Dim LoadedLayerDataStructure As New LayerDataStructure(Options) ' LayerNumber UInt16 WORD Offset1 = 0 ' CellCollectionLength UIint32 DWORD Offset2 = Offset1 + 2 ' CellCollectionData CellCollectionData Byte(CellCollectionLength) Offset3 = Offset2 + CellCollectionLength Dim Offset1 As UInt32 = 0 LoadedLayerDataStructure.LayerNumber = BitConverter.ToUInt16(GetByteRange(Bytes, Offset1, WORD), 0) Dim Offset2 As UInt32 = Offset1 + WORD LoadedLayerDataStructure.CellCollectionLength = BitConverter.ToUInt32(GetByteRange(Bytes, Offset2, DWORD), 0) Dim Offset3 As UInt32 = Offset2 + LoadedLayerDataStructure.CellCollectionLength LoadedLayerDataStructure.CellCollectionData = GetByteRange(Bytes, Offset3, LoadedLayerDataStructure.CellCollectionLength) LoadedLayerDataStructure.LayerCell = CellCollectionStructure.FromBytes(LoadedLayerDataStructure.CellCollectionData) LoadedLayerDataStructure.Bytes = Bytes Return LoadedLayerDataStructure End Function End Class #End Region #Region "Cell Collection Structure" Public Class CellCollectionStructure Public Cell As List(Of CellDataStructure) Public Property Bytes As Byte() Sub New(ByVal Options As CellCollectionStructureOptions) If Not CType(Options.InteralParameter, String) = "Skip Load" Then Me.Cell = Options.Cells Dim RawBytes As Byte() = Nothing ' CellCount UInt32 DWORD Offset1 = 0 Dim CellCount As UInt32 = Convert.ToUInt32(Options.Cells.Count) For Each Cell As CellDataStructure In Options.Cells Dim Tmp2 As Byte() = BitConverter.GetBytes(Cell.X) Dim Tmp3 As Byte() = BitConverter.GetBytes(Cell.Y) Dim Tmp4(0) As Byte 'Generate CellData Tmp4(0) = CByte(Cell.TreeImageType) RawBytes = CombineArrays(RawBytes, Tmp2) RawBytes = CombineArrays(RawBytes, Tmp3) RawBytes = CombineArrays(RawBytes, Tmp4) 'Get Cell Data Length, append to front of collection Dim Tmp1 As Byte() = BitConverter.GetBytes(Convert.ToUInt32(RawBytes.Count)) RawBytes = CombineArrays(Tmp1, RawBytes) 'Append cellcount to front of array RawBytes = CombineArrays(BitConverter.GetBytes(CellCount), RawBytes) Bytes = RawBytes Next End If End Sub Public Shared Function FromBytes(ByVal Bytes As Byte()) As CellCollectionStructure Dim Options As New CellCollectionStructureOptions Options.InteralParameter = CType("Skip Load", Object) Dim LoadedCellCollectionStructure As New CellCollectionStructure(Options) LoadedCellCollectionStructure.Bytes = Bytes Dim TMPCells As New List(Of CellDataStructure) Dim CellOptions As New CellDataStructureOptions CellOptions.InteralParameter = CType("Skip Load", Object) For I = 0 To Bytes.Count Step 5 Dim TMPCell As New CellDataStructure(CellOptions) Dim CurrentBytes As Byte() = GetByteRange(Bytes, Convert.ToUInt32(I), 5) TMPCell.X = BitConverter.ToUInt16(GetByteRange(CurrentBytes, 0, WORD), 0) TMPCell.Y = BitConverter.ToUInt16(GetByteRange(CurrentBytes, 2, WORD), 0) TMPCell.TreeImageType = CType(GetByteRange(CurrentBytes, 4, 1)(0), CellTreeImageType) TMPCells.Add(TMPCell) Next LoadedCellCollectionStructure.Cell = TMPCells Return LoadedCellCollectionStructure End Function End Class #End Region #Region "Cell Data Strucure" Public Class CellDataStructure Public X As UInt16 Public Y As UInt16 Public TreeImageType As CellTreeImageType Sub New(ByVal Options As CellDataStructureOptions) If Not CType(Options.InteralParameter, String) = "Skip Load" Then ' X UInt16 WORD Offset1 = 0 Me.X = Options.X ' Y UInt16 WORD Offset2 = Offset1 + 2 Me.Y = Options.Y ' TreeImageType TreeImageType 1 Byte Offset3 = Offset2 + 2 Me.TreeImageType = Options.TreeImageType End If End Sub Shared Function FromBytes(ByVal Bytes() As Byte) As CellDataStructure Dim BlankOptions As New CellDataStructureOptions BlankOptions.InteralParameter = CType("Skip Load", Object) Dim LoadedCellDataStructure As New CellDataStructure(BlankOptions) LoadedCellDataStructure.X = BitConverter.ToUInt16(GetByteRange(Bytes, 0, WORD), 0) LoadedCellDataStructure.Y = BitConverter.ToUInt16(GetByteRange(Bytes, 2, WORD), 0) LoadedCellDataStructure.TreeImageType = CType(BitConverter.ToUInt16(GetByteRange(Bytes, 4, 1), 0), CellTreeImageType) Return LoadedCellDataStructure End Function End Class #End Region #Region "Enumerations" Public Enum CellTreeImageType ' 0 = Blank Blank = 0 ' 1 = Log Byte 1 Byte N/A Log = 1 ' 2 = Leaves Byte 1 Byte N/A Leaves = 2 End Enum Public Enum TreeImageFamily Oak = 0 Spruce = 1 Birch = 2 Jungle = 3 End Enum #End Region #Region "Shared Functions" Public Shared Function CombineArrays(ByVal Array1 As Byte(), ByVal Array2 As Byte()) As Byte() Dim Merged((Array1.Length + Array2.Length) - 1) As Byte Array1.CopyTo(Merged, 0) Array2.CopyTo(Merged, Array1.Length) Return Merged End Function Public Shared Function ReverseByteOrder(ByVal Bytes() As Byte) As Byte() Dim Result(Bytes.Count - 1) As Byte Dim Counter As Integer = -1 For I = Bytes.Count - 1 To 0 Step -1 Counter = Counter + 1 Result(Counter) = Bytes(I) Next Return Result End Function Public Shared Function ImageBytes(ByVal Image As Image, ByVal Format As Imaging.ImageFormat) As Byte() Dim Stream As MemoryStream = New MemoryStream() Image.Save(Stream, Format) Stream.Close() Dim byteArray As Byte() = Stream.ToArray() Stream.Dispose() Return byteArray End Function Public Shared Function GetByteRange(ByVal Bytes As Byte(), ByVal Offset As UInt32, ByVal Length As UInt32) As Byte() Dim Results As New List(Of Byte) For I As UInt32 = Offset To (Offset + Length) - Convert.ToUInt32(1) Results.Add(Bytes(CInt(I))) Next Return Results.ToArray End Function #End Region #Region "Structure Options" Public Const WORD As UInt32 = 2 Public Const DWORD As UInt32 = 4 Public Const QWORD As UInt32 = 8 Public Structure LayerCollectionStructureOptions Public Layers As List(Of LayerDataStructure) Public InteralParameter As Object End Structure Public Structure LayerDataStructureOptions Public LayerNumber As UInt16 Public LayerCells As CellCollectionStructure Public InteralParameter As Object End Structure Public Structure CellCollectionStructureOptions Public Cells As List(Of CellDataStructure) Public InteralParameter As Object End Structure Public Structure CellDataStructureOptions Public X As UInt16 Public Y As UInt16 Public TreeImageType As CellTreeImageType Public InteralParameter As Object End Structure Public Structure MCTData Public ProjectName As String Public AuthorName As String Public PreviewPicture As Image Public TreeType As TreeImageFamily Public LayersCollection As Byte() Public LogImage As Image Public LeavesImage As Image Public ImageFormat As Imaging.ImageFormat 'Using this paramater(InternalParameter) may cause errors. Do not delete this parameter. Public InteralParameter As Object End Structure #End Region End Class
If you want something you've never had, you need to do something you've never done.
-
Thursday, August 23, 2012 7:10 PMModerator
Did you notice I used things such as Uint16,Uint32,uint64... Etc
This is what they mean:
U-nsigned(non-negative) int-eger 16-bits(2 bytes) or 1 WORD
U-nsigned(non-negative) int-eger 32-bits(4 bytes) or 1 DWORD
U-nsigned(non-negative) int-eger 64-bits(8 bytes) or 1 QWORD
Look at wiki, they have a great article about data types:
http://en.wikipedia.org/wiki/Integer_%28computer_science%29
You will see −2,147,483,648 to 2,147,483,647 the values(this is a 32 bit signed integer) if you notice, it can go one number more negative that it can go positive, this is because of the binary calculation is that when going positive, the final bit will reset every bit in every column, but the carry will not be processed, making it go to zero... but the carry makes it overflow. but when going negative, this does not happen, this is for any singed data type so you know.... not too important, just interesting.
If you want something you've never had, you need to do something you've never done.
-
Thursday, August 23, 2012 7:37 PM
if you know how to do xml you can write to collada format some of your values for your picture of a tree in 3d and display with xna. Hmm, seem to remember an xna viewer on codeplex with code heres one viewer i found on codeplex out of many with code for viewing 3d models:
http://modelviewer.codeplex.com/SourceControl/list/changesets
I can help with conversion from c# to vb.net manually when im available as i have started learning how to do basic xna things manually in code but still trying to learn somethings. Im sure theirs code to help also with the creation of an collada file (*. dae) in vb.net code. you ca use collada.org as reference though if needed.
Edit: found this nice piece of code libraries that does the loading and saving of collada files with code but look into the model viewer above also:
Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth. - "Sherlock holmes" "speak softly and carry a big stick" - theodore roosevelt. Fear leads to anger, anger leads to hate, hate leads to suffering - Yoda. Blog - http://www.computerprofessions.co.nr
- Edited by The Thinker Thursday, August 23, 2012 7:37 PM

