Andrew Bennett's Blog

Just another WordPress.com site

Converting any file at compile time to a c string in XCode

with one comment

I’ve been writing some code which is compiled at run-time, however I’d rather avoid having to copy this source code into my resources. Additionally I’d like to make this code maintainable and have syntax highlighting.

The desire for syntax highlighting means I can’t do something like this:

const char * mySourceCode = "int prng(void) {return 4;}";

However if I write this in another file I will get syntax highlighting, but then how do I include it? This doesn’t work (and adds data):

const char * mySourceCode = "\
#include "mySourceCode.c"
\";

The solution I found was to add a new build rule to Xcode, so when Xcode tries to compile files matching your file pattern ("*.vert" in my case), it runs a preprocessing script of your choice.

cd "$INPUT_FILE_DIR"
xxd -i "$INPUT_FILE_NAME" "$DERIVED_SOURCES_DIR/$INPUT_FILE_NAME.c"

This outputs a c file containing an array of characters and an integer with its length. This is is put into the derived sources dir and so XCode will automatically compile it.

To use this go into your project settings and add a new rule like this:
Screen Shot 2013-02-14 at 6.25.04 PM

Once this is done you can access that data by simply creating an external reference to that data, be careful when treating the data as a string as it is not necessarily null terminated. The variable is named after the file with invalid symbols replaced with underscores.

extern const unsigned char myfilename_ext[];
extern const unsigned int  myfilename_ext_len;

If using Objective-C you can also use it to get data like this:

NSData   * data   = [NSData dataWithBytesNoCopy: myfilename_ext
                                         length: myfilename_ext_len
                                   freeWhenDone: NO];

You can also get a NSString like this:

NSString * string = [[NSString alloc] initWithBytesNoCopy: myfilename_ext
                                                   length: myfilename_ext_len
                                                 encoding: NSUTF8StringEncoding
                                             freeWhenDone: NO];

This all works for me in Xcode 4.6, but I think build rules have been around for ages, and should be for ages more, so it should work in most Xcode versions.

Advertisements

Written by therealbnut

February 15, 2013 at 9:21 am

Posted in Uncategorized

Does my path intersect with my circle?

leave a comment »

I was writing some code to select a bezier path with a cursor/tap, the problem is that CoreGraphics didn’t seem to have any functions for doing this. There are methods like NSIntersectsRect that check for the intersection of two NSRects, and methods like CGPathContainsPoint that see if a point is inside a closed path, but nothing to see if a circle overlaps a path.

An exact solution (overkill) for the intersection point(s) can be efficiently found by treating the curve as a series of linear segments and subdividing the segments near the circle until the desired accuracy is met. This can be applied to a CGPathRef by using the CGPathApply function to iterate over the path’s elements and applying the iterative approach. This is still overkill for this particular problem as I only need to know YES/NO.

Then I remembered a trick I learnt from a collision detection method, where you are trying to check if a sphere intersects with other static geometry. You can do this efficiently by treating the sphere as a point and making the other geometry fatter by the sphere’s radius. This diagram may help explain, or it may just be a crazy collection of shapes:

Converting from a sphere intersection test to a point intersection test

Using this approach I can use the CGPathCreateCopyByStrokingPath method to make a closed path equivalent to a stroked version of the original, then use CGPathContainsPoint to check whether the point intersects.

BOOL CGPathIntersectsCircle(CGPathRef path, CGPoint center, CGFloat radius)
{
    CGPathRef fuzzyPath;
    fuzzyPath = CGPathCreateCopyByStrokingPath(path, NULL, radius,
                                               kCGLineCapRound,
                                               kCGLineJoinRound, 0.0);
    if (CGPathContainsPoint(fuzzyPath, NULL, center, NO))
    {
        CGPathRelease(fuzzyPath);
        return YES;
    }
    CGPathRelease(fuzzyPath);
    return NO;
}

I haven’t timed this method, but it I haven’t had any issues so far, depending on how you want to use it you could cache the fuzzyPath, or alternatively use CGPathGetBoundingBox to do an initial level of culling prior to checking against the fuzzyPath, like so:

BOOL CGPathIntersectsCircle(CGPathRef path, CGPoint center, CGFloat radius)
{
    if (NSPointInRect(center, NSInsetRect(CGPathGetBoundingBox(path), -radius, -radius)))
    {
        CGPathRef fuzzyPath;
        fuzzyPath = CGPathCreateCopyByStrokingPath(path, NULL, radius,
                                                   kCGLineCapRound,
                                                   kCGLineJoinRound, 0.0);
        if (CGPathContainsPoint(fuzzyPath, NULL, center, NO))
        {
            CGPathRelease(fuzzyPath);
            return YES;
        }
        CGPathRelease(fuzzyPath);
    }
    return NO;
}

Written by therealbnut

October 30, 2012 at 2:05 am

Processing Items

leave a comment »

With Apple’s new 15-inch MacBook Pro having a high resolution “Retina” display the excitement is understandably oriented around the screen. However it wasn’t until my new laptop was in my cart that I realised the coolest feature of all, something Apple coyly slid across the table, unmentioned, and seemingly unnoticed. I have noticed, and I am excited! I’ve added a screenshot of a shopping cart here, the new feature is easy to miss so I’ve circled it, of course I’m not talking about the keyboard, but the backlit user’s guide!

Back Lit User's Guide

Apple certainly don’t disappoint, they are rethinking everything, creating all new markets and innovating where we least expect it, etcetera. I haven’t seen any pictures of the backlit user’s guide yet, but my imagination is doing a pretty good job. Apple like glowy things and I expect this m*ther fu**er will light up the sky.

Apple Likes Glowy things

I know what you’re all thinking, no really, but Apple hasn’t stolen this from anywhere else. The only references to “backlit user’s guide” I could find were dodgy English misspellings or grammar on user’s guides for backlit displays or black lights. Not to say that black lights aren’t cool, or glowy, but they’re not the same as a backlit f**ken user’s guide!

I apologise for my language, I am understandably quite excited. No one has put this much effort into users guides since computer games in 1980s. Back-in-the-day you relied heavily on the user’s manual or cover art to discern what those 11 tiny dancing non-retina pixels were meant to be.

Low Res High Five!

Anyway, I digress, my point was that I’m really excited for both my new laptop and my backlit user’s guide to arrive. So excited. Anyway, until someone else catches on and posts a picture of their delivered user’s guide I will have to settle for my terrible fan art:

Fabulous Backlit Gosh Darn User's Guide!

Written by therealbnut

June 17, 2012 at 3:00 am

Setting XCode 4.0 Environment Variables from a Script

with 8 comments

I have struggled for quite a while with XCode 4, it is excellent for Cocoa development, but if you’re trying to do anything lower level I often find myself pining after XCode 3.x or wanting to use a Makefile or something instead. However there are many advantages to an IDE, like code completion and integrated debugging tools, so it’s always nice to use things how they are designed. However there are some things XCode 4 does not do nicely, this article describes one such thing and the solution I’ve come up with. I don’t think XCode 3.x did this particular thing well either, so perhaps my solution might actually be useful to someone else.

The Problem

Often I want a bit more control over how I compile and link things than XCode allows. Tools like llvm-config allow you to get the compiler settings for your local build of llvm api, which is very useful. If I run something like:

llvm-config --ldflags

Then the command will output something like:

-L/usr/local/lib -lpthread -lm

To use this with XCode what you might consider doing is setting the OTHER_LD_FLAGS environment variable (“Other Linker Flags” in the Build Settings) to something like this:

`llvm-config --ldflags`

However if you look in the build transcript (Expanding the link section in the Navigator Log, command+7), you will find that it puts double quotation marks around the space separated parts of the command and ld is forced to interpret it as a file. I have tried for hours to fix this, on many different occasions, but I could not find a satisfactory portable solution. That is until now.

The Solution

The solution in short is to create an Xcode Configuration file from a script build phase and then set that as the base configuration for all of your targets dependent on the build settings. You can do this in “5 Simple Steps”!

Step 1

This script will create the xcode configuration file in your project directory, place it in a script build phase in your project. Make sure that you do this before the “Compile Sources” phase so it is made before the settings are needed.

Automatically Generating the XCode Configuration File

Automatically Generating the XCode Configuration File

Of course this script only applies to llvm, but I will put it here in case anyone wants it:

LLVM_XCCONFIG="llvm.xcconfig"
LLVM_CFLAGS=`/usr/local/bin/llvm-config --cflags`
LLVM_LDFLAGS=`/usr/local/bin/llvm-config --ldflags`" "`/usr/local/bin/llvm-config --libs cbackend jit x86 linker`
echo "// Configuration file for LLVM settings, generated as a build phase." > $LLVM_XCCONFIG
echo "LLVM_CFLAGS = $LLVM_CFLAGS" >> $LLVM_XCCONFIG
echo "LLVM_LDFLAGS = $LLVM_LDFLAGS" >> $LLVM_XCCONFIG

Step 2

Build the project and the XCode Configuration file should be created, add this file to the project. If you’re not sure how to do this you can find it in Finder and then drag it into the project’s file navigator (Or by pressing command+option+a, and selecting the file).

Add the XCode Configuration file to the project

Add the XCode Configuration file to the project

Step 3

Now you have to set this configuration file as the base configuration of each target that uses it, to do this select the project in the file  navigator. Selecting the project if the target is selected and then go to the Info tab. Within the info tab set the configuration file to the file you just added for each relevant target.

Setting the Target's base Configuration File

Setting the Target’s base Configuration File

Step 4

Now all you need to do is use the new environment variables in your project settings, of course you could have called them OTHER_LDFLAGS or similar to avoid this step, but I thought it was cleaner to do it this way.

Using the new Environment Variables in the the Build Settings

Using the new Environment Variables in the the Build Settings

Step 5

Build your project and hopefully everything is working as you wanted it to.

Edit (4 March 2012)

I recently made some changes to the script to only update the xcconfig when changes are made, I’m not sure if this is the best way to do it, but it works for me. By moving the parameters to a separate file you can check the date modified on it and the xcconfig to know when the xcconfig needs updating.

I also specified each file in the appropriate script input/output section using the same paths as in the script, I think these two actions prevent unnecessary rebuilds.

The new script:

LLVM_XCCONFIG_FILE="${PROJECT_DIR}/llvm-config/llvm.xcconfig"
LLVM_COMPONENTS_FILE="${PROJECT_DIR}/llvm-config/llvm-components.txt"

date_params=$((`stat -f "%m" $LLVM_COMPONENTS_FILE`))
date_config=$((`stat -f "%m" $LLVM_XCCONFIG_FILE`))
if [ $date_params -gt $date_config ]; then
    echo "llvm.xcconfig parameter changes detected"

    LLVM_COMPONENTS=`/bin/cat $LLVM_COMPONENTS_FILE`
    LLVM_CFLAGS=`/usr/local/bin/llvm-config --cflags`
    LLVM_LDFLAGS=`/usr/local/bin/llvm-config --ldflags`" "`/usr/local/bin/llvm-config --libs $LLVM_COMPONENTS`

    echo "// Configuration file for LLVM settings, generated as a build phase." > $LLVM_XCCONFIG_FILE
    echo "// $LLVM_COMPONENTS" >> $LLVM_XCCONFIG_FILE
    echo "LLVM_CFLAGS = $LLVM_CFLAGS" >> $LLVM_XCCONFIG_FILE
    echo "LLVM_LDFLAGS = $LLVM_LDFLAGS" >> $LLVM_XCCONFIG_FILE
fi

This script is based on the xcconfig and the parameters file being under the specified folder (./llvm-config/ under the project directory). The parameter file is basically a one line text file containing the parameters:

cbackend jit x86 linker ipo

Written by therealbnut

January 1, 2012 at 5:08 am

Community Driven Development

leave a comment »

My apologies, I’ve been struggling to find a way to concisely summarise what I’ve been thinking about recently, but this post may have turned into a rant. I’ve been trying to think of a good development workflow that would support open source and community driven projects. Here’s a rant-free diagrammatic summary, feel free to read further if you’re interested:

Summary

Is this actually simpler?

Rant

The problem with community driven not-for-profit projects in my opinion is that they often don’t have the funding or the focus they need to make a cohesive polished product.  Projects are often forked in so many ways by having different people working on them with different goals, levels of commitment, design methodologies and technological biases. I’m not saying diversity is a bad thing, but when someone wants something new they often seem to either start from scratch or completely fork a project.

Documentation

Documentation seems to be one of the big problems here. You need someone with the skills to document something for people completely unfamiliar with a technology, you need them to be accepted inside that community, and then you need them to have incentives to help. There needs to be introductory high level documentation, that allows new users to easily gauge what they can do and then there needs to be lower level documentation to show them how to do it. There needs to be a clear separation between user and contributor documentation, as it is so important that people know how to contribute but not to scare away or confuse users.

So what does main do?

Extensibility

From a programming point of view I really like OpenGL and OpenCL, they have clear low level and fairly extendable programming interfaces.  For me one of the most important things in community driven projects is well designed APIs.  In my opinion beyond normal design practices a good API needs two things:

It must be extremely modular

For example, if I want to look at your arithmetic coder I won’t come back an hour after getting it to fetch dependencies to find it has downloaded half of KDE. Yes, this happened.  Ideally dependencies should be minimised, modules should be compact and be able to be run with fewer features if dependent modules are missing.

It must be easily extensible

Blender is something I use a lot, as an artist, but as a programmer I’ve never been able to make much progress.  Recently however they’ve made drastic improvements to the API and UI allowing plugins to seamlessly integrate themselves into the Application without a recompile.  Ideally the creation of these plugins is well documented and then they can be easily integrated into the base system.

Community Funding

Minecraft Money ShotYou would not believe how many posts there are on the Minecraft forums.  Notch made the initial release of Minecraft in a week and the community has now driven it to the point where he is a multimillionaire from the pre-purchases of a game that was still in beta.  This next bit is a brainspasm, let’s call this freewriting. Often software companies gather usage statistics on their users, I think it’d be really interesting to optionally tell users statistics of what went into what they use. For example, 1000 users use spend one hour on 10 of the features of your program, and it took 5 programmers $500 worth of time and resources to implement those features. Your program could then credit those programmers and say they each donated $100 of their time to providing those features, $0 has been payed for so far and you are responsible for 0.1% of the total usage of those features. Perhaps you’d like to donate 50c or more?

User driven features

Often implementers are awful at design and aesthetics, as well as predicting what users want from their product and even how they will use it.  I love the idea of user devised features, as it gives implementers well discussed, often clearly defined, and above all, popular goals.  I’d really like to see a polished open source community driven feature request system, tied into something like the SPP, where implementers could set a minimum cost of producing a feature and when donations reach the required amount to make it happen the feature can be implemented.

Just another use case

</Rant>

This whole rant started when I read an appeal from Wikipedia founder Jimmy Wales, asking for donations to keep wikipedia going.  I use wikipedia all the time as a first stop summary of things I’m unfamiliar with and would probably be curled up in a corner in the foetal position if it went under. Just FYI, that banner is HUGE!

HUGE!

Written by therealbnut

November 26, 2010 at 3:11 am

Memory Games

with 6 comments

Some friends have been using this website http://andys.org.uk/countryquiz/ to (perhaps) improve their memory by seeing how many of the 192 UN Member States they can name in 10 minutes.  I tried it and only managed to get 16 in the two minutes I had before I realised I was meant to be elsewhere.

After coming back from elsewhere I decided to analyse the problem.  I wasn’t sure if without time restriction I could name anywhere near that many states.  I wasn’t sure if I could type that many states within the time restriction and if I could do the above two, I certainly wouldn’t be able to spell them all flawlessly.

Here, have a cookie.

So I cheated.  I copied all the countries from the website’s list and then pasted them back one by one, this meant I was typing 5 fixed keyboard commands for each state in contrast to approximately 8.56 varied characters to type each individually.  To do this successfully you’d have to average 33 words per minute, where the average is 19 words per minute for composition, and exactly 33 as well for just typing.  So even cheating I was about 12 states short when time ran out, so I needed to cheat more.

To do this I wrote a Bookmarklet, a small piece of code which you enter in place of a URL in your browser, it can do just about anything to the client-side representation of a website.  Essentially this script finds the input text field, enters a state into it, tells the website you’ve typed one in, then begins on the next state.

javascript: (function() {for(var s in states) {document.getElementsByTagName("input")[1].value = states[s];  checkStates(document.getElementsByTagName("input")[1]);}})();

My Bookmarklet worked!  I received the coveted Alert Box of Success, having written my code and executed it within the allotted 10 minutes. However there was a bitterness to my victory, certainly not that I cheated, but that my script had to be run several times sequentially to get all the states validated.  I suspect this was because my script was running faster than the User Interface could handle, but I’m not entirely sure.

The coveted Alert Box of Success!

So I decided to make a version that more closely resembled what a real person would do, or more simply, I made it wait a bit after entering each state.  This initially seems trivial, except that JavaScript does not seem to have a function to pause your code for a short duration, and it all has to be written in one line of code.

javascript: (check = new function() {this.foo = states.slice(0);this.go = function() {document.getElementsByTagName("input")[1].value = this.foo.pop();checkStates(document.getElementsByTagName("input")[1]);if (this.foo.length != 0) setTimeout("check.go()", 2);};this.go();})();

I did this by creating a global Functor which periodically updates then yields until it is complete.  This new code worked and got all of the states in 3 seconds with only one run of the Bookmarklet. Success!  Some of you might be thinking, why not just hack the program and tell it you’ve won, bypassing the User Interface, well that’d be cheating.  Furthermore, what I did here is much more likely to teach me something, and will work in an AJAX/Server driven version.

javascript: window.alert("You did it!");

Written by therealbnut

November 16, 2010 at 2:04 am

Computer Game Revenue Model 2.0

with 8 comments

I was discussing this with Jess on the bus home and thought I should blog it, and I needed a blog to do this, so welcome!

Motivation

Recently I have been discussing game revenue models with my friends, we are basically all in agreement that current revenue models are broken, but have been unable to find a better alternative.  The problem seems to be that computer game companies are often forced to charge a lot, and put digital rights management (DRM) in their games.  This is all to make a profit in the first few months of sales, before “everyone” pirates them. This discourages patching games, fostering a community and leads to a rift between distributers and players.

Thanks Wikipedia!

DRM put into games is often crippling enough to put off potential customers, or to ruin the user experience or playability for those that do pay for it.  Personally I have used cracked versions of games I own for the convenience of installation and usage. When it comes down to it, gamers should have the right to play games they pay for, and DRM often removes that right.

Steam is Valve Corporation’s content delivery and digital rights management software which allows users to buy, download, and play games all from its interface.  In many ways it is very convenient as all you need is an internet connection to download and play your games.  Often you will need this internet connection anyway as many of the popular titles on Steam are multiplayer online games.  The point being that the convenience Steam offers outweighs the advantages of piracy for many people I know, despite its DRM.

Revenue Model 2.0

What I would like to see in future is a content delivery system like Steam, where all games are free, but to use them you would have to pay a monthly subscription fee. This subscription fee would be charged in week long blocks, for each week you use the service. This means that people that game infrequently would not be charged excessively, and hardcore gamers would not be charged more than they would with existing models.

For Gamers

Hardcore gamers would have access to the latest and greatest games for free. This is definitely a win for gamers, as they would have access to every game for free, and only have to pay as they play.

For Publisher

From a publisher’s point of view, they can monitor and manage usage of their games to target customer’s, make new suggestions and foster a community around their games.  A fairly open and easy to join platform would make distribution easy and developers flock to the label.

For Developers

Mac App Store Icon

Finally, from a developer’s point of view, I would propose something similar to Apple’s App Store model.  Anyone would be able to develop for this distributer, they would just have to meet the minimum quality requirements to be associated with the label.

After shipping their game a rather large, say 70% of the monthly subscriptions would be distributed to developers based on the percentage of sales. This percentage would be calculated by summing the hours (or part thereof) that players are using a game, then dividing this by the total number of hours across all games.  Once a title reaches a certain level of revenue per user, or it drops off the radar then the developer would be encouraged to release their game for free to foster the

community and to allow removal of any DRM or online restrictions the game imposes.

Implementation
Unity LogoA great way to do this would be on top of a platform like The Unity Game Engine which has a huge following of developers.  The distributer would add social tools for community interactions and a unified multiplayer framework.  This would mean that a developer can simply import a package then use it to aid their development. When they are finished developing their game, it will be ready to upload and distribute. Likewise by targeting a Unity supported platform like the Wii, or even creating a platform like Apple’s iMac it would be easy to know the system requirements of the users machine.  A console like platform also has the advantage that the console itself could be rented as part of the subscription model to ensure that hardware is always up to date.

Comments are welcome, I think this would be a great model, obviously it doesn’t address all the problems with current systems, but it would be an excellent stepping stone to a more open revenue model where everybody happy!

Written by therealbnut

August 26, 2010 at 6:00 am

%d bloggers like this: