So close to reading from embedded files...
BlitzMax Forums/BlitzMax Beginners Area/So close to reading from embedded files...
| ||
Hi, everyone! So, I'm Incbin-ing some graphics and sounds one fine day and I think to myself "Why don't I embed my custom-made data files, too?" Well, I do, and I make a collection of functions for gleaning Byte, Short, Int and String values from the now incbin-ed custom files. Everything seems to go along swimmingly, but then weird bugs start popping up in my game. A little digging, and I find this out about my custom file for storing data about in-game items: The first value in the file, an integer, loads perfectly. So do all the Short and String values, but all subsequent Int values don't load right. Here's the code.: Any thoughts? Thank you so much for listening. :-D |
| ||
A Byte Ptr is, literally, a pointer to a Byte. If you deference it (`bf[bf_e]`), you are only retrieving the eight-bit value at that offset. To read a 32-bit value, you need to cast the pointer, so that the right kind of read operation happens at all:Local i:Int = (Int Ptr(bf))[bf_e] Casting the result of the read through a byte ptr won't make the read operation draw 32-bits; it already happened by that point. Same goes for Short, and any other data types. Also, a character in an internal BlitzMax string is two bytes long, as BlitzMax uses UCS-2 encoding (this may not be relevant to your packed data type, of course: if you only wrote one byte then reading that much back is valid, but it does mean that you won't be able to store most non-English strings accurately). |
| ||
Thank you, Yasha! (Reads post very carefully) Now, I know for sure I have no idea what I'm doing. Can what I'm trying to do even be done? If so, can anyone point me to a good tutorial on using pointers? i need deeply fundamental help. T_T |
| ||
Can what I'm trying to do even be done? Sure, just make the change indicated in the codeblock in post #2. You were very nearly right first time, you just have the parentheses in slightly the wrong place. All a pointer is is a location in memory. You can, if you like, think of it as an index into an array where the array is your whole process space. Since, fundamentally, everything is a sequence of bits somewhere in memory, a pointer can represent literally anything. Therefore, BlitzMax can't tell you what kind of data it will find based simply on the address. In the same way that both a float and an int are a sequence of 32 bits, and variables must be tagged to indicate which one is the valid interpretation of the bit pattern, variables holding pointers must also be tagged to indicate what kind of thing they could be pointing at. So when you dereference a pointer as in `bf[N]`, BlitzMax uses the type of `bf` to determine what the deref operation actually entails. If `bf` has type Byte Ptr it will read a byte. If it has type Float Ptr it will read a float. If you need to change the read operation, you can cast the pointer to another type of pointer just as you can cast a number to another type of number: Int Ptr(bf) 'dereference this and it will read and return 32 bits Float Ptr(bf) 'dereference this and it will read and return 32 bits as a float Short Ptr(bf) 'dereference this and it will read and return 16 bits Long Ptr(bf) 'dereference this and it will read and return 64 bits The value of the pointer itself never changes. The only thing that changes is what BlitzMax is tagged as allowed to do though it. (You can also cast a pointer to Int if you want to display/examine it for debugging purposes.) The error in the code above is that you never cast the pointer itself to tag it as returning a value larger than a byte. The code still compiled because it's legal (just unnecessary) to cast a byte - the value being returned - to a short or int. Your original code: Pointer tagged to read one byte -> read one byte -> convert one byte to four bytes My code in post #2: Pointer tagged to read one byte -> same pointer retagged to read four bytes -> read four bytes |
| ||
I think I found something to start on. If anyone else out there is stuck on pointers and stumbled onto this post, maybe you'd find this interesting?: http://www.blitzbasic.com/Community/posts.php?topic=54348 I'll try to avoid wasting anyone else's time. I'm sorry. Thanks again. |
| ||
Oh! You type fast! All right. I've entered that code block like you showed me, (Int Ptr(bf))[bf_e]. I used it on the other types too. I must have done something wrong, because the program displays the first integer from the file, then seems to freeze afterward. ... What did I mess up? Is it the variable I use for dereferencing the pointers? (Thinks about it) Probably. I should probably try again in the morning. Thanks again, Yasha. You have been a huge help! |
| ||
A Float is four bytes. |
| ||
You can open an incbinned file as a stream and read data that way. Code to create test data: Code to read incbinned data: you can also use banks if you need to access the data directly There is nothing wrong with the way you are doing it, just doesn't seem necessary to reinvent the wheel. |
| ||
And the day is saved! Thank you Tom Toad! A Float is four bytes. ... It sure is! I must have gotten my Floats and Doubles mixed. Thanks for the heads up,Floyd! Oh, this gets my game so close to done! I can't wait to show everyone the demo later. XD Thank you all again! |