Tuesday, May 29, 2012

Strings to numbers

As I'm working away on my program, sans STL, I realized that I have a need to read a file and use the data within for various means. However this presented a problem because I didn't have a string to number converter, and as I didn't want to use STL I would need to write one.

Researching the problem of string to floats I found out just how complicated the issue could get. To do things properly the function needs to be able to handle all manner of different inputs, and still produce a useable float, naturally. But looking at strings and how error prone they can be that's where the real challenge lays I thought.

I did find online documentation that broke the problem down into a very handy intermediate step by using a so called "triad", or an int array with three elements: [sign][number][exponent], and as long as these three are populated properly, reconstructing the float is trivial. 

Started writing this I decided to put it in my string class to make use of it's functionality instead of in math or somewhere else, and that made things a bit easier.

First find either "nan" or "inf" and return the appropriate result, which in itself is rather interesting. How do you define a not-a-number, or infinite float? 0/0 isn't a number, but it won't compile either ;) It's only through cleaver casting of strange values is it achieved.

if(input.findTextNoCase("nan") >= 0)
{
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
return (*(const float *) __nan);
}

if(input.findTextNoCase("inf") >= 0)
{
static const int value = 0x7f800000;
return *(float*)&value;
}
The rest involved locating the negative / positive sign, locating any exponents (is 'e' is present), and finally converting regular numeric characters into a number.

for(int i = 0; i < inLen; i++)
{
if(input.isNumeric(input[i]))
{
valueStruct[1] = (valueStruct[1] * 10) + charToInt(input[i]);
}
}

Finally as the last step it's all added and multiplied into the resulting float.

float result = int, if there is a negative sign multiply by -1, and if there is an exponent, either keep multiplying or dividing by 10 until the necessary value is reached. Now while my method probably won't handle everything that gets thrown at it, I just need it to handle values I give it, and it seems to do that without problem, woot! 

Thats it for now! :)

Thursday, May 24, 2012

Next gen star gen

After studying id's Doom3 source and libraries for a while and working on my own stuff, one thing led to another and I started working on StarGen 4, lol. Amazingly I decided to do a complete rewrite of everything I had done before and start from scratch.

One of the biggest things I've learned while writing RenLib is a good (proper?) use of classes, OOP, and functional programming. The fact that I now go back and look at StarGen 1, 2 and 3 and have a hard time figuring out just what is going on says something. And it was that same procedural code that made the previous star generators so unportable and difficult to modify. Sure version 3 was "better" in the same way you add modern car controls to a steam powered car, but it's a far cry from what version 4 is turning out to be.

OOP is also changing the whole core functionality of the program as well, and how my data is created, organized, and sent back to the user. I'm floored! I mean, I'm sure this is all common sense to a regular programmer, but I'm just a technical artist creating this stuff, so to me it's practically magic ;)

Getting back to RenLib for a second; while most of the functionality is done (for what I need to do with it at the moment), I'm proud that I managed to avoid using STL and intrinsic as much as possible. Even when it comes to math functions like square roots and logarithms. Mainly thanks to the combines knowledge of the internet, but still :)

Assembly optimization is also very fun once I see some concrete and working examples of how to do things. The only thing that still eludes me is Intel's AVX, but since I don't have a compatible processor, and it's still very new, I'll let that slide for now ;) For now it's satisfying enough to have working SSE code that doesn't cause runtime exceptions all the time.

That's it for now! StarGen4 is still a long ways away, so nothing to show yet. My hope, however, is that I am able to create something as beautiful as the Space Engine, albeit prerendered.

Tuesday, May 15, 2012

Learning libraries

Looking at the Doom 3 source code I found that id wrote some of their own libraries to handle data. Things like strings, lists, dictionaries, vectors, etc. And talking to a friend of mine he said that a lot of it was due to the fact that the standard template libraries, while they work as intended, are usually not well suited to tightly controlled resource management that games require.

This interested me, so I decided to write my own little library, one that wouldn't require STL at all (As much as I could get away with that is). So far it's been an interesting experience in C++. I've become so used to using regular features like lists and such in Python, but never considered using them in lower level languages. They were there, but for some reason STL's notation can be so difficult to understand.

Take strings for example, it's just a char array, but the function descriptions can be so confusing with so many namespaces and shorthand variable names. But thanks to id's source code, I now have my own personal STL free string library that mimics some Python's functionality. Not to mention some assembly optimized functions too :)

So where is this going, you may ask. I never did get to look at ray-tracing (yet), but it got me thinking about the star gen version 4 I've been planning. In the past month or so I've learned a lot more about classes, OOP, and functional programming, that it's making me realize just how I want to write the next iteration and make it even more modular than before.

As for assembly optimization, I know there are intrinsics I could use, but again that requires including external includes, and this whole exerciser is all about learning how things are done. Though MMX and SSE assembly seems much more finicky than simple scalar stuff, but it's a start :)

That's it for now! Oh and Mass Effect 3 is awesome! ;)