iPhone Default User Settings Null?

June 22nd, 2009

I wanted to set default values for my application using a Settings.bundle and I ran into an interesting issue with iPhone SDK 2.2. If you don’t run the Settings application before your application runs for the first time, then the default settings are not set. It turns out that you’ll need to manually set them on the first time the application is run.

Setting defaults to the default value…

I’m not sure why there isn’t a function that can set the values for me, but after digging I found someone who ran into the same dilema. I don’t want to have multiple locations with default values (code and a Settings.bundle), so I found a programmatic way to set all the default values if they haven’t been set.

- (void)registerDefaultsFromSettingsBundle {
    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
    if(!settingsBundle) {
        NSLog(@"Could not find Settings.bundle");
        return;
    }
 
    NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
    NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
 
    NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
    for(NSDictionary *prefSpecification in preferences) {
        NSString *key = [prefSpecification objectForKey:@"Key"];
        if(key) {
            [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
        }
    }
    [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
    [defaultsToRegister release];
}

All you have to do is call the above function if one of your Standard User Defaults returns null. Make the call once your application finishes loading like so:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
	// Get the application user default values
	NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
	NSString *server = [user stringForKey:@"server_address"];
	if(!server) {
		// If the default value doesn't exist then we need to manually set them.
		[self registerDefaultsFromSettingsBundle];
		server = [[NSUserDefaults standardUserDefaults] stringForKey:@"server_address"];
	}
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}

References:

Using SCM with SVN 1.6 and Xcode 3.1.2

April 22nd, 2009

Version control software is very important to use to keep track of changes. Today I was testing out the Xcode SCM (Software Configuration Management) integrated tools with SVN today and I had a few issues.

1. Xcode is trying to use the wrong dynamic libraries for SVN, if you update your SVN version to 1.6+. Since it’s referencing the wrong libraries you will get an error similar to this one:

Error: 155021 (Unsupported working copy format) please get a
newer Subversion client

I’ve seen this type of error when I upgraded my SVN and tried to use other SCM GUI software. To fix it I googled around and found some useful information at: Blind Genius Weblog

cd /usr/lib
sudo mkdir oldSVN
sudo mv libap*-1.dylib oldSVN
sudo mv libsvn*-1.dylib oldSVN
sudo mv libap*-1.0.dylib oldSVN
sudo mv libsvn*-1.0.dylib oldSVN
sudo ln -s /opt/subversion/lib/*-1.0.dylib .
sudo ln -s /opt/subversion/lib/*-1.dylib .

Instead of removing the library files, I moved them into a new directory as backup.

2. Now Xcode can use the correct updated libraries from SVN 1.6+, so I moved on to the next task of adding an existing project to the SVN repository. The tutorial at jms1.net was helpful in refreshing my memory for the SVN commands.

Make a project in Xcode and then use Terminal and execute the commands. If you aren’t familar with SVN check out the documentation.

cd LOCAL_PROJECT_PATH
svn mkdir SVN_REPOSITORY_LOCATION/PROJECT_NAME
svn co SVN_REPOSITORY_LOCATION/PROJECT_NAME .
svn add *
svn revert --recursive build
svn ps svn:ignore build .
svn ci

The commands create a folder in your SVN repository. Next it checks out the remote repository folder into the local project folder and add all of the project files. Once the files are “added” you’ll want to remove the build directory and ignore it from your SVN repository. Lastly it’ll commit the changes and you’re project is in the repository.

3. The project is in the repository and Xcode is using the latest version of SVN. You can use the SCM tools in Xcode to manage the project.

Player/Stage, MacPorts, and iPhone

April 10th, 2009

Today I worked on setting up Player/Stage on my Macbook Pro with Leopard 10.5.6 and I ran into a few issues.

I was using Macports 1.710 and I was attempting to install player-stage-player (2.1.2) and player-stage-stage (2.1.1) following a short guide at http://bentham.k2.t.u-tokyo.ac.jp/notebook/?p=247

I used the command: (Which took 2+ hours to download/build/install dependencies)

$ sudo port install playerstage-player playerstage-stage

However it errored out at the end with the message:

$ sudo port install playerstage-player playerstage-stage
--->  Building playerstage-player
Error: Target org.macports.build returned: shell command " cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_science_playerstage-player/work/player-2.0.4" && make all " returned error 2
Command output: building '_playerc' extension
swigging playerc.i to playerc_wrap.c
swig -python -o playerc_wrap.c playerc.i
playerc.i:44: Warning(124): Specifying the language name in %typemap is deprecated - use #ifdef SWIG<LANG> instead.
playerc.i:82: Warning(124): Specifying the language name in %typemap is deprecated - use #ifdef SWIG<LANG> instead.
playerc.i:121: Warning(124): Specifying the language name in %typemap is deprecated - use #ifdef SWIG<LANG> instead.
playerc.i:127: Warning(124): Specifying the language name in %typemap is deprecated - use #ifdef SWIG<LANG> instead.
gcc -fno-strict-aliasing -Wno-long-double -no-cpp-precomp -mno-fused-madd -fno-common -dynamic -DNDEBUG -g -Os -Wall -Wstrict-prototypes -DMACOSX -I/usr/include/ffi -DENABLE_DTRACE -arch i386 -arch ppc -pipe -I./../.. -I../../../.. -I/System/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5 -c playerc_wrap.c -o build/temp.macosx-10.5-i386-2.5/playerc_wrap.o
playerc_wrap.c: In function '_wrap_playerc_mclient_client_set':
playerc_wrap.c:40301: warning: assignment from incompatible pointer type
playerc_wrap.c: In function '_wrap_playerc_mclient_addclient':
playerc_wrap.c:40504: warning: passing argument 2 of 'playerc_mclient_addclient' from incompatible pointer type
playerc_wrap.c: In function '_wrap_playerc_mclient_client_set':
playerc_wrap.c:40301: warning: assignment from incompatible pointer type
playerc_wrap.c: In function '_wrap_playerc_mclient_addclient':
playerc_wrap.c:40504: warning: passing argument 2 of 'playerc_mclient_addclient' from incompatible pointer type
gcc -Wl,-F. -bundle -undefined dynamic_lookup -arch i386 -arch ppc build/temp.macosx-10.5-i386-2.5/playerc_wrap.o -L./../../.libs -L../../../../libplayerxdr/.libs -L../../../../libplayercore/.libs -L../../../../libplayerjpeg/.libs -lplayerxdr -lplayerc -lplayerjpeg -ljpeg -lplayererror -o build/lib.macosx-10.5-i386-2.5/_playerc.so
ld: library not found for -ljpeg
collect2: ld returned 1 exit status
ld: library not found for -ljpeg
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccI9TvVp.out
(No such file or directory)
error: command 'gcc' failed with exit status 1
make[6]: *** [pythonbuild] Error 1
make[5]: *** [all] Error 2
make[4]: *** [all-recursive] Error 1
make[3]: *** [all-recursive] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

Error: Status 1 encountered during processing.

So I searched around the MacPorts website and I came across the ticket #18891, which basically said to run the following command to change the version of python being used from 3.0 to 2.5.

$ sudo port install python_select && sudo python_select python25
Skipping org.macports.activate (python_select +darwin_9) since this
port is already active
--->  Cleaning python_select
Selecting version "python25" for python

Following that command I was able to finish installing Player/Stage via MacPorts by using the orginal port command.

$ sudo port install playerstage-player playerstage-stage
--->  Building playerstage-player
--->  Staging playerstage-player into destroot
--->  Installing playerstage-player @2.0.4_2
--->  Activating playerstage-player @2.0.4_2
--->  Cleaning playerstage-player
--->  Fetching playerstage-stage
--->  Attempting to fetch stage-2.0.3.tar.bz2 from
http://voxel.dl.sourceforge.net/playerstage
--->  Verifying checksum(s) for playerstage-stage
--->  Extracting playerstage-stage
--->  Configuring playerstage-stage
--->  Building playerstage-stage
--->  Staging playerstage-stage into destroot
--->  Installing playerstage-stage @2.0.3_0
--->  Activating playerstage-stage @2.0.3_0
--->  Cleaning playerstage-stage

I tried to use player stage from MacPorts.

$ player /opt/local/var/macports/software/playerstage-stage\
/*/opt/local/share/stage/worlds/simple.cfg

And I received the error:

rr: unable to open color database /usr/X11R6/lib/X11/rgb.txt
 : No such file or directory (stage.c stg_lookup_color)

Following the advice from http://bentham.k2.t.u-tokyo.ac.jp/notebook/?cat=5 I added the following link.

$ sudo ln -s /usr/X11/share/X11/rgb.txt /usr/X11R6/lib/X11/rgb.txt

Now I am able to create a player server and connect with a client with the commands:

$ player /opt/local/var/macports/software/playerstage-stage\
/*/opt/local/share/stage/worlds/simple.cfg

/opt/local/var/macports/software/playerstage-player\
/*/opt/local/share/player/examples/libplayerc++/laserobstacleavoid

With the ability to run player/stage I will post again on my progress as I use an iPhone to run the Player client, rather than my Macbook Pro.

Player client running on iPhone with Player/Stage.

Player client running on iPhone with Player/Stage.

Sorting Object Pointers in C++

January 13th, 2009

Today I was working on my computer animation project using C++, Boost, STL, and OpenGL. I ran into a few hitches related to pointers and the STL (Standard Template Library) and I decided to blog about it.

Problem: You can’t override the default operator<  for the pointer type, so you have to make a class/structure that defines an operator() function, which is the function pointer. Any attempt to create a operator< (const Frame *lhs, const Frame *rhs) will be ignored. You might find yourself wondering why objects are being sorted by memory address (pointer address), rather than your defined method. Here’s an excerpt from my code. (Thanks to CopySourceAsHTML)

// Frame.h

/** A compare class used for Frame pointers.*/

class FrameComparer {

public:

bool operator() ( const Frame *lhs, const Frame *rhs) {

return (*lhs).getTime() < (*rhs).getTime();

}

};

//FrameViewer.cpp

/** Adds frames to be viewed at a later time */

void FrameViewer::addFrames(std::vector<Frame *> frames) {

// Append the new frames to current frames

_frames.insert(_frames.end(), frames.begin(), frames.end());

// Sort

std::sort(_frames.begin(), _frames.end(), FrameComparer());

}

Summary:

I had a STL vector full of pointer objects, but the only way I was comparing was by pointer address until I created the FrameComparer class. With the class and an compare object defined I’m able to override the sort methods comparison behavior. This way will correctly sort the Frame objects by time value, rather than pointer address.

References:

Function pointers

XNA 3.0 Content Pipeline

January 1st, 2009

I spent all day researching the XNA Content Pipeline in XNA 3.0. The MSDN documentation is a little sparse/dense on how things work together; so I pulled together some resources that I found helpful when trying to understand it.

There’s 4 main components in the Content Pipeline: Importers, Processors, Writers, and Readers. Read the 2nd point to understand how they work together or go through the tutorial in my 1st point to get your hands dirty. The 3rd point is another tutorial to help you understand creating a new game asset from start to finish.

Read more…

Categories: Computer Science, Mac, XNA Tags:

Gears of War 2 != 9/10

December 22nd, 2008

I recently acquired Gears of War 2 as an early Christmas present and had the opportunity to play it in cooperative mode with my roommate. It didn’t quite live up to my expectations and it failed to fix some of the game play mechanics that I hated from the first Gears of War (GOW) game. I’m not sure how it was given a 9/10 on Gamespot.com’s website, but I certainly do not agree with them. Here’s my breakdown on the single player/coop experience.

Read more…

Macbook Pro + Windows + Dual Monitors = Painful

September 14th, 2008

I didn’t think it would be so hard to just get my taskbar and icons on a second monitor using Windows on my Macbook Pro. It doesn’t seem like a whole lot of people run Windows on the Mac, so there isn’t a whole lot of resources if you get stuck. It takes a lot of digging to find the real answers. Turns out the display drivers from NVIDIA/Apple for Windows don’t support making an external monitor as a primary monitor. It only gives the option of making the laptop display primary. This limitation is very painful and kept me up for hours/days searching for registry hacks, hacked drivers, and more. Here’s what I found that didn’t work and what did: Read more…

PAX 10

September 3rd, 2008

Wow. I just got back from the PAX 10 competition sponsored by Penny Arcade (penny-arcade.com). It’s a competition for the top 10 games developed by independent game developers.

I worked on Impulse with a group of students from RIT and my brother. It’s a physics based game around movement. You use magnetism and impulse forces to get around the level. It was a 10 week project, so it’s still missing some of the game elements to make it into a full game, but it’s a great prototype.

We’re now working on it to get it to a point where it will be able to be distributed.

For the game I worked on the particle effects to give the player a sense of what’s happening and to make it look pretty. I’m looking to revamp the system now that I have time to design and structure it for more complex, yet pretty effects. I’m also working on a level editor to make level creation a whole lot less painful.

Categories: Computer Science, News Tags:

End of the Year and Summer

May 11th, 2008

It’s week 10 at RIT; only one more week of class and then finals! I’m excited because once I finish up here I’ll be heading home and then out to California to work for Apple!

Categories: Uncategorized Tags:

Life Changing Event

January 24th, 2008

My life has changed thanks to Joe.

Suddenly my tab key is more useful on my Macbook. I can now tab through my dialog option buttons. There’s an obscure setting in the System Preferences > Keyboard and Mouse > Keyboard Shortcuts > Full Keyboard Access (set to All Controls). Or you can press ctrl-F7.

This makes so many things much easier to do with out having to constantly use the mouse to move to a button and click.

Love it!

Categories: Computer Science, Life at RIT, Mac Tags: