SprintfCat

On the train to Cardiff yesterday, I was creating a fixed function shader generator for the Athena engine. I kept using strcat() with if statements, and in a lot of places I kept using sprintf() then copying that in with strcat().

So I decided to make SprintfCat(), all the wonderful joy of sprintf, with the ability to concatenate with a already existant string like strcat.

//
//
size_t ath::SprintfCat( char * inoutBuffer, const size_t inBufferSize, const char * inFormat, ... )
{
	const size_t offset = StrLen( inoutBuffer );
	size_t ret = 0;
	va_list arg;
 
	//
	va_start( arg, inFormat );
	{
		ret = VSprintf( inoutBuffer + offset, inBufferSize - offset, inFormat, arg );
	}
	va_end( arg );
 
	//
	return offset + ret;
}

I had already created my own wrappers around strlen() and vsprintf(), the reason being the fault of Microsoft. With their implementation of the standard library, they decided to deprecate non-safe versions complain at you until you either used their own _s variants, or defined a certain preprocessor.

//
//
size_t ath::VSprintf( char * outBuffer, const size_t inBufferSize, const char * inFormat, va_list inArgs )
{
#ifndef ATH_PLATFORM_WINDOWS
	return vsnprintf( outBuffer, inBufferSize, inFormat, inArgs );
#else
	return vsprintf_s( outBuffer, inBufferSize, inFormat, inArgs );
#endif
}
 
//
//
size_t ath::StrLen( const char * inString )
{
	return strlen( inString );
}

While I do prefer to have safe versions, their _s variants are not present in the standard and so it makes the code not portable.

I’m still not quite sure about my naming convention for a variable that is an input and an output. While I do like the in or out prefix, I don’t think inout looks right, being slightly too long. I wasn’t a fan of io either. I have however grown to like the truncation of Athena namespace to ath.

OpenGL Shader Debugging

One thing that always annoys me with using glGetShaderInfoLog(), is that when compiling OpenGL shaders multiple sources can be used. Because of this, the line numbers get shifted, and trying to find line 123 where a syntax error exists is a length process.

So I made a function that will take the sources list and output the lines with line numbers.

void OutputWithLineNumbers( const char ** inSources, const unsigned int inCount )
{
	bool unendedLineNo = false;
	int lineNumber = 1;
 
	for( unsigned int i = 0; i < inCount; ++i )
	{
		const char * cur = inSources[i];
		const char * next = NULL;
 
		do
		{
			//
			if( !unendedLineNo )
			{
				printf( "%04d: ", lineNumber );
			}
 
			//
			next = strchr( cur, '\r' );
 
			//
			if( next )
			{
				size_t len = ( next - cur );
				char * lineText = (char *)alloca( len );
				memcpy( lineText, cur, len );
				lineText[len] = 0;
 
				printf( "%s\n", lineText );
 
				unendedLineNo = false;
				++lineNumber;
			}
			else
			{
				printf( "%s", cur );
				unendedLineNo = true;
			}
 
			//
			cur = next + 2;
		} while( next );
	}
 
	if( unendedLineNo )
	{
		printf( "\n" );
	}
}

This code requires the source files to have a carriage return as well as a new line character.

XCode4 Build Rules for iOS

For a while now I have been manually compiling files since my asset conversion pipeline tool is not quite finished yet.

So I took at look into Build Rules in XCode. My main trouble within using them was finding the environment variables, even googling them doesn’t turn up much information.

I think the output files act as an error check, if the output file fails to appear then the tool failed.

One other thing I had an issue with was the source files list. I tried comma and semi colon delimiters, and spaces, but the TGA file kept giving the warning on Tree1.tga. I have yet t0 find the a way to do this without multiple entries. And I’m thinking a separate tool for building files may be easier.

 

LONG_MAX on 64bit OSX

hartnell-sensorites
Some Sensorites have been known to be dicks

I came by an annoying problem when I was adding some asserts to my FBX to Athena tool. I was basically adding a check to my vertex buffer size to make sure it was not larger than a GLsizeiptr (defined as a long in iOS5 SDK).

I’ve always assumed chars to be 8, shorts to be 16, longs to be 32 and ints to be whatever the system wants it to be (most likely the register size for an atomic copy). However, my tool is setup using 64bit OSX project, and the long comes out as 8 bytes, so the value given by LONG_MAX is huge, while the int remains at 4 bytes.

I wouldn’t have even noticed that my assert would have never been hit if it had not been for the warning the IDE gave after writing the statement, “Comparison is always true due to limited range of data type”.

In the end I just replaced LONG_MAX with INT32_MAX (stdint.h). And after a bit of googling, I found this on wikipedia.

The sizes of short, int, and long in C/C++ are dependent upon the implementation of the language:

  • On older, 16-bit operating systems, int was 16-bit and long was 32-bit.
  • On 32-bit Unix, DOS, and Windows, int and long are 32-bits, while long long is 64-bits. This is also true for 64-bit processors running 32-bit programs.
  • On 64-bit Unix, int is 32-bits, while long and long long are 64-bits.

While this does sound kinda familiar to me, I do not think I’ve ever had a situation where it has appeared to me until now.